@clickview/reports 0.85.0-rc.1 → 0.85.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/.vite/manifest.json +284 -284
  2. package/dist/bundles.json +1 -1
  3. package/dist/en.json +1 -1
  4. package/dist/scripts/{DMI-Lxl02.chunk.js → BCcIdtcy2.chunk.js} +2 -2
  5. package/dist/scripts/{DMI-Lxl02.chunk.js.map → BCcIdtcy2.chunk.js.map} +1 -1
  6. package/dist/scripts/{ClOZ7MLV.chunk.js → BIlepbnA.chunk.js} +2 -2
  7. package/dist/scripts/{ClOZ7MLV.chunk.js.map → BIlepbnA.chunk.js.map} +1 -1
  8. package/dist/scripts/{3EzrYsbw2.chunk.js → BX5YDJVD2.chunk.js} +2 -2
  9. package/dist/scripts/{3EzrYsbw2.chunk.js.map → BX5YDJVD2.chunk.js.map} +1 -1
  10. package/dist/scripts/{Bua2prVk2.chunk.js → BY9ZIRoW2.chunk.js} +2 -2
  11. package/dist/scripts/{Bua2prVk2.chunk.js.map → BY9ZIRoW2.chunk.js.map} +1 -1
  12. package/dist/scripts/{CowZxgkl2.chunk.js → BkkPVinl2.chunk.js} +2 -2
  13. package/dist/scripts/{CowZxgkl2.chunk.js.map → BkkPVinl2.chunk.js.map} +1 -1
  14. package/dist/scripts/{Udxe63DQ.chunk.js → BsAss53i.chunk.js} +2 -2
  15. package/dist/scripts/{Udxe63DQ.chunk.js.map → BsAss53i.chunk.js.map} +1 -1
  16. package/dist/scripts/{CJIwkABI.chunk.js → BsTmrvS_.chunk.js} +2 -2
  17. package/dist/scripts/{CJIwkABI.chunk.js.map → BsTmrvS_.chunk.js.map} +1 -1
  18. package/dist/scripts/{1pdbKMyH.chunk.js → BzSZm3J1.chunk.js} +2 -2
  19. package/dist/scripts/{1pdbKMyH.chunk.js.map → BzSZm3J1.chunk.js.map} +1 -1
  20. package/dist/scripts/{c7dUmf3R.chunk.js → C5k6lVOP.chunk.js} +2 -2
  21. package/dist/scripts/{c7dUmf3R.chunk.js.map → C5k6lVOP.chunk.js.map} +1 -1
  22. package/dist/scripts/{DTy5e0Yv2.chunk.js → CPp4jaPB2.chunk.js} +2 -2
  23. package/dist/scripts/{DTy5e0Yv2.chunk.js.map → CPp4jaPB2.chunk.js.map} +1 -1
  24. package/dist/scripts/{r-dVoZ7W2.chunk.js → Cdlk0Qkj2.chunk.js} +2 -2
  25. package/dist/scripts/{r-dVoZ7W2.chunk.js.map → Cdlk0Qkj2.chunk.js.map} +1 -1
  26. package/dist/scripts/ClX2mOw_.chunk.js +1 -0
  27. package/dist/scripts/{CMKPCLR42.chunk.js → D0fFZDhm2.chunk.js} +2 -2
  28. package/dist/scripts/{CMKPCLR42.chunk.js.map → D0fFZDhm2.chunk.js.map} +1 -1
  29. package/dist/scripts/{B9S_LeFP.chunk.js → DMuXCE-z.chunk.js} +2 -2
  30. package/dist/scripts/{B9S_LeFP.chunk.js.map → DMuXCE-z.chunk.js.map} +1 -1
  31. package/dist/scripts/{3q7nyVif2.chunk.js → DNZvrGV22.chunk.js} +2 -2
  32. package/dist/scripts/{3q7nyVif2.chunk.js.map → DNZvrGV22.chunk.js.map} +1 -1
  33. package/dist/scripts/{2MxiB_er.chunk.js → DUzAx5n_.chunk.js} +2 -2
  34. package/dist/scripts/{2MxiB_er.chunk.js.map → DUzAx5n_.chunk.js.map} +1 -1
  35. package/dist/scripts/DaBzvZF9.chunk.js +1 -0
  36. package/dist/scripts/{Cpm-LpwK.chunk.js → DkhktXkG.chunk.js} +2 -2
  37. package/dist/scripts/{Cpm-LpwK.chunk.js.map → DkhktXkG.chunk.js.map} +1 -1
  38. package/dist/scripts/{Bx5qk-PZ.chunk.js → DtSAu9Xt.chunk.js} +3 -3
  39. package/dist/scripts/{Bx5qk-PZ.chunk.js.map → DtSAu9Xt.chunk.js.map} +1 -1
  40. package/dist/scripts/{ktNy7dHM2.chunk.js → DvxtrAxT2.chunk.js} +2 -2
  41. package/dist/scripts/{ktNy7dHM2.chunk.js.map → DvxtrAxT2.chunk.js.map} +1 -1
  42. package/dist/scripts/{BvNaANAO2.chunk.js → DxD2uVzf2.chunk.js} +2 -2
  43. package/dist/scripts/{BvNaANAO2.chunk.js.map → DxD2uVzf2.chunk.js.map} +1 -1
  44. package/dist/scripts/{DgPadkLi2.chunk.js → I9MVVxo82.chunk.js} +2 -2
  45. package/dist/scripts/{DgPadkLi2.chunk.js.map → I9MVVxo82.chunk.js.map} +1 -1
  46. package/dist/scripts/{BnfA2fln.chunk.js → IH7D3jLI.chunk.js} +2 -2
  47. package/dist/scripts/{BnfA2fln.chunk.js.map → IH7D3jLI.chunk.js.map} +1 -1
  48. package/dist/scripts/{CKRKdk5U.chunk.js → OU_kRJz_.chunk.js} +2 -2
  49. package/dist/scripts/{CKRKdk5U.chunk.js.map → OU_kRJz_.chunk.js.map} +1 -1
  50. package/dist/scripts/{n2iCrpxU.chunk.js → P4zTQoDZ.chunk.js} +2 -2
  51. package/dist/scripts/{n2iCrpxU.chunk.js.map → P4zTQoDZ.chunk.js.map} +1 -1
  52. package/dist/scripts/{CqCz1X85.chunk.js → PZOjj17O.chunk.js} +2 -2
  53. package/dist/scripts/{CqCz1X85.chunk.js.map → PZOjj17O.chunk.js.map} +1 -1
  54. package/dist/scripts/{CCLDpjnt2.chunk.js → XgwoBT6z2.chunk.js} +2 -2
  55. package/dist/scripts/{CCLDpjnt2.chunk.js.map → XgwoBT6z2.chunk.js.map} +1 -1
  56. package/dist/scripts/{app-BigOHyYp.js → app-m6P7KXE1.js} +3 -3
  57. package/dist/scripts/{app-BigOHyYp.js.map → app-m6P7KXE1.js.map} +1 -1
  58. package/dist/scripts/{BpzXy-5d.chunk.js → bNV2NeSi.chunk.js} +2 -2
  59. package/dist/scripts/{BpzXy-5d.chunk.js.map → bNV2NeSi.chunk.js.map} +1 -1
  60. package/dist/scripts/{BKW2JeVr.chunk.js → fIFpt-kC.chunk.js} +2 -2
  61. package/dist/scripts/{BKW2JeVr.chunk.js.map → fIFpt-kC.chunk.js.map} +1 -1
  62. package/dist/scripts/{CKVaLGJC.chunk.js → fOHWXn7-.chunk.js} +2 -2
  63. package/dist/scripts/{CKVaLGJC.chunk.js.map → fOHWXn7-.chunk.js.map} +1 -1
  64. package/dist/scripts/{BfhdSOSX2.chunk.js → jXHCFC1j2.chunk.js} +2 -2
  65. package/dist/scripts/{BfhdSOSX2.chunk.js.map → jXHCFC1j2.chunk.js.map} +1 -1
  66. package/package.json +1 -1
  67. package/dist/scripts/Bs1YLdQb.chunk.js +0 -1
  68. package/dist/scripts/Cah5ISd-.chunk.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"r-dVoZ7W2.chunk.js","names":[],"sources":["../../../../libs/shared/src/hooks/UseLazyLoad.ts","../../../../libs/shared/src/components/lazy-image/lazy-image.module.scss","../../../../libs/shared/src/components/lazy-image/LazyImage.tsx","../../../../libs/shared/src/components/image/image.module.scss","../../../../libs/shared/src/components/image/BaseImage.tsx","../../../../libs/shared/src/constants/ColourClassNames.ts","../../../../libs/shared/src/images/svg/actions/PlaySvg.tsx","../../../../libs/shared/src/images/svg/objects/ImageSvg.tsx","../../../../libs/shared/src/images/svg/objects/SeriesSvg.tsx","../../../../libs/shared/src/utils/getBgColorClass.ts","../../../../libs/shared/src/components/image/image-fallback.module.scss","../../../../libs/shared/src/components/image/ImageFallback.tsx"],"sourcesContent":["import { useInView } from 'react-intersection-observer';\n\ninterface LazyUtils {\n ref: (node?: Element) => void | null;\n inView: boolean;\n\n /**\n * Use this if you want to hide something on start\n * and then show it as something else leaves the window\n * e.g. The student feed floating jump to button\n */\n initialized: boolean;\n}\n\ninterface UseLazyLoadOptions {\n prevent?: boolean;\n /**\n * See rootMagin here: https://www.npmjs.com/package/react-intersection-observer#api\n * Thow allows us to have items load ahead of coming into the viewport\n * for example thumbnail images as we scroll\n */\n rootMargin?: string;\n triggerOnce?: boolean;\n}\n\nexport function useLazyLoad(options: UseLazyLoadOptions = {}): LazyUtils {\n const { prevent, rootMargin, triggerOnce = true } = options;\n\n // eslint-disable-next-line\n let [ ref, inView, entry ] = useInView({ triggerOnce, rootMargin: rootMargin });\n\n if (prevent === true || typeof (window as any).IntersectionObserver === 'undefined') {\n inView = true;\n ref = null;\n }\n\n return { ref, inView, initialized: !!entry };\n}\n",":local {\n .image {\n width: 100%;\n height: 100%;\n }\n}\n","import * as React from 'react';\n\nimport { useLazyLoad } from 'libs/shared/hooks/UseLazyLoad';\n\nimport styles from './lazy-image.module.scss';\n\n/**\n * This value means we will load images 500px above\n * or below the viewport so that they are loaded\n * by the time they come into the viewport\n */\nconst PRELOAD_DISTANCE = '500px';\n/**\n * Atomically small blank GIF as placeholder for image src to prevent w3 validator error\n */\nconst PLACEHOLDER_SRC = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';\n\ninterface LazyImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n forceLoad?: boolean;\n preventLoad?: boolean;\n extraClasses?: string;\n errorFallbackImageSrc?: string;\n errorFallbackImageClassName?: string;\n}\n\nexport const LazyImage = React.memo(function(props: LazyImageProps): React.ReactElement {\n const { forceLoad, extraClasses = '', errorFallbackImageSrc, preventLoad = false, errorFallbackImageClassName, src, alt, ...propsWithoutSrc } = props;\n \n const { ref, inView } = useLazyLoad({ rootMargin: PRELOAD_DISTANCE });\n const [ error, setError ] = React.useState(false);\n\n React.useEffect(() => {\n if ((!forceLoad && !inView) || preventLoad)\n return;\n \n // https://stackoverflow.com/questions/2342132/waiting-for-image-to-load-in-javascript\n const img = new Image();\n\n img.onerror = () => {\n setError(true);\n \n if (errorFallbackImageSrc)\n img.src = errorFallbackImageSrc;\n };\n\n img.src = src;\n return () => img.onerror = null;\n }, [ inView, preventLoad ]);\n\n function getSrc(): string {\n if (error && errorFallbackImageSrc)\n return errorFallbackImageSrc;\n\n return props.src;\n }\n\n if (error && !errorFallbackImageSrc)\n return <></>;\n\n if (!ref) {\n return (\n <img\n className={`${styles.image} ${extraClasses} ${error ? errorFallbackImageClassName || '' : ''}`}\n alt={alt}\n src={getSrc()}\n {...propsWithoutSrc}\n />\n );\n }\n\n const imgProps: React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement> = {\n alt,\n ...propsWithoutSrc,\n ...(((inView || forceLoad) && !preventLoad) ? { src: getSrc() } : { src: PLACEHOLDER_SRC })\n };\n\n if (!forceLoad)\n imgProps.ref = ref;\n\n return (\n <img className={`${styles.image} ${extraClasses} ${error ? errorFallbackImageClassName || '' : ''}`} {...imgProps} />\n );\n});\n",":local {\n .image {\n position: relative;\n width: 100%;\n height: 100%;\n\n :global(img) {\n position: absolute;\n top: 0; \n bottom: 0; \n left: 0; \n right: 0;\n }\n }\n\n // Aspect Ratios\n .thumbnail {\n padding-bottom: 56.25%;\n }\n\n .tallPoster {\n padding-bottom: 177.77778%;\n }\n\n .cover {\n padding-bottom: 100%;\n }\n\n .banner {\n padding-bottom: 18.50%\n }\n\n .poster {\n padding-bottom: 150%;\n }\n\n .pdf {\n :global(img) {\n height: auto;\n }\n }\n\n .link {\n :global(img) {\n width: auto;\n margin: 0 auto;\n }\n }\n}","import * as React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AnalyticsOptions, HashObject } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { LazyImage } from 'libs/shared/components/lazy-image/LazyImage';\nimport { ImageType } from 'libs/shared/enums/Images';\nimport { Image } from 'libs/shared/interfaces';\nimport { ImageHelper, ImageOptions } from 'libs/shared/utils/ImageHelper';\n\nimport styles from './image.module.scss';\n\nfunction getImageClassName(props: BaseImageProps): string {\n let className = styles.image;\n\n let imageTypeClassName = '';\n\n if (props.imageType === ImageType.Thumbnails)\n imageTypeClassName = `thumbnail ${styles.thumbnail}`;\n\n if (props.imageType === ImageType.TallPosters)\n imageTypeClassName = styles.tallPoster;\n\n if (props.imageType === ImageType.Covers)\n imageTypeClassName = styles.cover;\n\n if (props.imageType === ImageType.Banners)\n imageTypeClassName = styles.banner;\n\n if (props.imageType === ImageType.Posters)\n imageTypeClassName = styles.poster;\n\n if (props.imageType === ImageType.Pdf)\n imageTypeClassName = styles.pdf;\n\n if (props.imageType === ImageType.Link)\n imageTypeClassName = styles.link;\n\n if (imageTypeClassName)\n className += ` ${imageTypeClassName}`;\n\n if (props.className)\n className += ` ${props.className}`;\n\n return className;\n}\n\ninterface BaseImageProps {\n data: Image | string;\n imageOptions?: ImageOptions;\n appLink?: Core.AppLink;\n imageType?: ImageType;\n className?: string;\n imageClassName?: string;\n imageStyle?: HashObject;\n preload?: boolean;\n preventLoad?: boolean;\n analyticsData?: HashObject;\n analyticsOptions?: AnalyticsOptions;\n errorFallbackImageSrc?: string;\n errorFallbackImageClassName?: string;\n alt?: string;\n preventFocus?: boolean;\n appLinkClassName?: string;\n onClick?: () => void;\n onLoad?: () => void;\n openInNewTab?: boolean;\n forcePageLoad?: boolean;\n}\n\nexport function BaseImage(props: React.PropsWithChildren<BaseImageProps>): React.ReactElement {\n const {\n data,\n imageOptions,\n appLink,\n preload,\n preventLoad,\n analyticsOptions,\n analyticsData,\n imageClassName,\n alt\n } = props;\n\n let url = '';\n\n if (typeof data === 'string') {\n url = data;\n } else if (ObjectHelper.isObject(data)) {\n url = data.url;\n }\n\n const imageUrl = (url && imageOptions) ? ImageHelper.createUrl(url, imageOptions) : url;\n\n return (\n <div className={getImageClassName(props)} style={props.imageStyle}>\n <AppLink\n appLink={appLink}\n analyticsData={analyticsData}\n analyticsOptions={analyticsOptions}\n onClick={props.onClick}\n preventFocus={props.preventFocus}\n className={props.appLinkClassName}\n openInNewTab={props.openInNewTab}\n forcePageLoad={props.forcePageLoad}\n >\n {props.children}\n {imageUrl && (\n <LazyImage\n src={imageUrl}\n alt={alt}\n forceLoad={preload}\n preventLoad={preventLoad}\n extraClasses={imageClassName}\n errorFallbackImageSrc={props.errorFallbackImageSrc}\n errorFallbackImageClassName={props.errorFallbackImageClassName}\n onLoad={props.onLoad}\n />\n )}\n </AppLink>\n </div>\n );\n}\n\n","/**\n * Use this instead of the list below if you need to render the clickview logo\n * on the background you're rendering.\n */\nexport const LOGO_SAFE_BG_CLASS_NAMES = [\n 'bg-green',\n 'bg-cyan',\n 'bg-teal',\n 'bg-blue',\n 'bg-indigo',\n 'bg-purple'\n];\n\nexport const BG_COLOUR_CLASS_NAMES = [\n 'bg-pink',\n 'bg-orange',\n ...LOGO_SAFE_BG_CLASS_NAMES\n];\n","import React from 'react';\n\nexport function PlaySvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fill='currentColor'\n fillRule='evenodd'\n d='M7.76 6.078a.5.5 0 0 0-.76.427v11a.5.5 0 0 0 .76.426l9.003-5.5a.5.5 0 0 0 0-.853z'\n clipRule='evenodd'\n />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function ImageSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props} viewBox='0 0 24 21'>\n <path\n d='M22.5 1A1.5 1.5 0 0 1 24 2.5v18a1.5 1.5 0 0 1-1.5 1.5h-21A1.5 1.5 0 0 1 0 20.5v-18A1.5 1.5 0 0 1 1.5 1zm0 1.5h-21v18h21zm-8.21 4.092 5.84 9a.75.75 0 0 1-1.26.816L13.638 8.34l-2.523 3.591a.75.75 0 0 1-1.144.1l-.889-.89L5.1 16.45a.75.75 0 0 1-1.2-.9l4.5-6a.75.75 0 0 1 1.13-.08l.87.869 2.648-3.77a.75.75 0 0 1 1.243.023M6 4.75a2.25 2.25 0 1 1 0 4.5 2.25 2.25 0 0 1 0-4.5m0 1.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5'\n fill='currentColor'\n />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function SeriesSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fill='currentColor'\n d='M20.283 4C21.229 4 22 4.745 22 5.66v8.74c0 .726-.478 1.338-1.151 1.565l.088-10.22a.657.657 0 0 0-.664-.66H6.351A1.71 1.71 0 0 1 7.951 4zm-2.059 1.933c.947 0 1.718.745 1.718 1.65v8.74c.01.726-.479 1.339-1.142 1.565l.088-10.24a.647.647 0 0 0-.664-.64H4.293a1.7 1.7 0 0 1 1.6-1.075zM16.05 7.95c.946 0 1.707.744 1.707 1.659v8.74c0 .915-.77 1.65-1.707 1.65H3.707C2.761 20 2 19.255 2 18.35V9.61c0-.915.77-1.66 1.707-1.66zm-.01 1.084H3.717a.647.647 0 0 0-.663.64v8.609c0 .358.292.641.663.641H16.03c.371 0 .664-.283.664-.641V9.676c.01-.358-.283-.641-.654-.641M8.546 12.39v3.178c0 .17.205.264.342.17l2.254-1.594c.117-.085.117-.255 0-.33l-2.264-1.593c-.137-.095-.332 0-.332.17'\n />\n </svg>\n );\n}\n","export function getBgColorClass(name: string, classNames: string[]): string {\n return classNames[name.charCodeAt(0) % classNames.length];\n}\n\nexport function getDeterministicBgColorClass(name: string, classNames: string[]): string {\n const sum = name\n .split('')\n .reduce(\n (acc, char) => acc + char.charCodeAt(0),\n 0\n );\n \n return classNames[sum % classNames.length];\n}\n",":local {\n .baseFallbackContainer {\n position: absolute;\n width: 100%;\n height: 100%;\n }\n\n .svgFallbackContainer {\n @extend .baseFallbackContainer;\n background-color: $gray-100;\n }\n\n .subjectFallbackContainer {\n background-color: $gray-100;\n height: 100%;\n border-top-left-radius: $border-radius-lg;\n border-bottom-left-radius: $border-radius-lg;\n\n position: absolute;\n top: 0;\n left: 0;\n\n &Small {\n width: 2rem;\n }\n\n &Large {\n width: 5rem;\n }\n }\n\n .seriesItemFallback, .playlistItemFallback {\n @extend %icon;\n width: 3.75rem;\n height: 3.75rem;\n }\n\n .playlistFallback,\n .posterFallback { // poster fallback is used by series' & and subjects tall poster's\n @extend %icon;\n width: 7.5rem;\n height: 7.5rem;\n\n svg {\n width: 100%;\n height: 100%;\n }\n }\n\n .subjectFallback {\n @extend %icon;\n }\n\n %icon {\n position: absolute;\n top: 50%;\n left: 50%;\n color: $gray-400;\n transform: translate3D(-50%, -50%, 0);\n transition: opacity 100ms ease-in-out;\n }\n\n .fallbackThumbnailImage {\n padding: map-get($spacers, 1);\n background-size: cover;\n background-position: center;\n background-repeat: no-repeat;\n width: 100%;\n height: 100%;\n }\n\n .videoFallback,\n .folderFallback {\n position: absolute;\n width: 100%;\n height: 100%;\n }\n}","import * as React from 'react';\n\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { BG_COLOUR_CLASS_NAMES } from 'libs/shared/constants/ColourClassNames';\nimport { PlaySvg } from 'libs/shared/images/svg/actions/PlaySvg';\nimport { FileImgSvg } from 'libs/shared/images/svg/objects/FileImgSvg';\nimport { ImageSvg } from 'libs/shared/images/svg/objects/ImageSvg';\nimport { SeriesSvg } from 'libs/shared/images/svg/objects/SeriesSvg';\nimport { getBgColorClass } from 'libs/shared/utils/getBgColorClass';\n\nimport styles from './image-fallback.module.scss';\n\nexport enum ImageFallbackType {\n Playlist,\n PlaylistThumbnail,\n Series,\n SeriesThumbnail,\n Subject,\n TallSubject,\n Video,\n Folder\n}\n\nexport enum ImageFallbackMediaType {\n Svg,\n Image\n}\n\nexport enum ContainerClassSize {\n Large,\n Small\n}\n\nfunction getContainerClass(\n type: ImageFallbackMediaType,\n objectType: ImageFallbackType,\n containerClassSize: ContainerClassSize\n): string {\n if (objectType === ImageFallbackType.Subject) {\n const containerSizeClass = containerClassSize === ContainerClassSize.Large ?\n styles.subjectFallbackContainerLarge :\n styles.subjectFallbackContainerSmall;\n\n return `${styles.subjectFallbackContainer} ${containerSizeClass}`;\n }\n\n if (type === ImageFallbackMediaType.Svg) {\n if (objectType === ImageFallbackType.SeriesThumbnail || objectType === ImageFallbackType.PlaylistThumbnail)\n return `${styles.svgFallbackContainer} rounded-3`;\n \n return styles.svgFallbackContainer;\n }\n\n return styles.baseFallbackContainer;\n}\n\nfunction getClassByType(type: ImageFallbackType): string {\n if (type === ImageFallbackType.SeriesThumbnail)\n return styles.seriesItemFallback;\n\n if (type === ImageFallbackType.PlaylistThumbnail)\n return styles.playlistItemFallback;\n\n if (type === ImageFallbackType.Playlist)\n return styles.playlistFallback;\n\n if (type === ImageFallbackType.Series || type === ImageFallbackType.TallSubject)\n return styles.posterFallback;\n\n if (type === ImageFallbackType.Subject)\n return `${styles.subjectFallback} svg-container d-inline-block`;\n\n return '';\n}\n\nfunction getMedia(type: ImageFallbackType) {\n if (type === ImageFallbackType.SeriesThumbnail || type === ImageFallbackType.PlaylistThumbnail)\n return PlaySvg;\n\n if (type === ImageFallbackType.Playlist)\n return ImageSvg;\n\n if (type === ImageFallbackType.Series)\n return SeriesSvg;\n\n if (type === ImageFallbackType.Subject || type === ImageFallbackType.TallSubject)\n return FileImgSvg;\n\n return null;\n}\n\nfunction getSize(type: ImageFallbackType): SvgContainerSize {\n if (type === ImageFallbackType.Subject)\n return SvgContainerSize.ExtraLarge;\n\n return SvgContainerSize.Standard;\n}\n\ninterface ImageFallbackProps {\n type: ImageFallbackType;\n mediaType?: ImageFallbackMediaType;\n extraClasses?: string;\n svgContainerClassName?: string;\n name?: string;\n containerClassSize?: ContainerClassSize;\n}\n\nImageFallback.defaultProps = {\n mediaType: ImageFallbackMediaType.Svg,\n containerClassSize: ContainerClassSize.Large\n};\n\nexport function ImageFallback(props: ImageFallbackProps): JSX.Element {\n const { type, mediaType, extraClasses, containerClassSize } = props;\n\n if (type === ImageFallbackType.Video)\n return <div className={`${styles.videoFallback} ${props.extraClasses} bg-light-blue`} />;\n\n if (type === ImageFallbackType.Folder)\n return <div className={`${styles.folderFallback} ${props.extraClasses} ${getBgColorClass(props.name, BG_COLOUR_CLASS_NAMES)}`} />;\n\n const typeClass = getClassByType(type);\n const media = getMedia(type);\n const size = getSize(type);\n\n let className = `${getContainerClass(mediaType, type, containerClassSize)}`;\n\n if (extraClasses)\n className += ` ${props.extraClasses}`;\n\n return (\n <div className={className}>\n {mediaType === ImageFallbackMediaType.Svg ?\n (\n <SvgContainer\n svg={media}\n className={`${typeClass} ${props.svgContainerClassName ?? ''}`}\n tagName='div'\n size={size}\n />\n ) : (\n <div className={styles.fallbackThumbnailImage} style={{ backgroundImage: `url('${media}')` }} />\n )\n }\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"Cdlk0Qkj2.chunk.js","names":[],"sources":["../../../../libs/shared/src/hooks/UseLazyLoad.ts","../../../../libs/shared/src/components/lazy-image/lazy-image.module.scss","../../../../libs/shared/src/components/lazy-image/LazyImage.tsx","../../../../libs/shared/src/components/image/image.module.scss","../../../../libs/shared/src/components/image/BaseImage.tsx","../../../../libs/shared/src/constants/ColourClassNames.ts","../../../../libs/shared/src/images/svg/actions/PlaySvg.tsx","../../../../libs/shared/src/images/svg/objects/ImageSvg.tsx","../../../../libs/shared/src/images/svg/objects/SeriesSvg.tsx","../../../../libs/shared/src/utils/getBgColorClass.ts","../../../../libs/shared/src/components/image/image-fallback.module.scss","../../../../libs/shared/src/components/image/ImageFallback.tsx"],"sourcesContent":["import { useInView } from 'react-intersection-observer';\n\ninterface LazyUtils {\n ref: (node?: Element) => void | null;\n inView: boolean;\n\n /**\n * Use this if you want to hide something on start\n * and then show it as something else leaves the window\n * e.g. The student feed floating jump to button\n */\n initialized: boolean;\n}\n\ninterface UseLazyLoadOptions {\n prevent?: boolean;\n /**\n * See rootMagin here: https://www.npmjs.com/package/react-intersection-observer#api\n * Thow allows us to have items load ahead of coming into the viewport\n * for example thumbnail images as we scroll\n */\n rootMargin?: string;\n triggerOnce?: boolean;\n}\n\nexport function useLazyLoad(options: UseLazyLoadOptions = {}): LazyUtils {\n const { prevent, rootMargin, triggerOnce = true } = options;\n\n // eslint-disable-next-line\n let [ ref, inView, entry ] = useInView({ triggerOnce, rootMargin: rootMargin });\n\n if (prevent === true || typeof (window as any).IntersectionObserver === 'undefined') {\n inView = true;\n ref = null;\n }\n\n return { ref, inView, initialized: !!entry };\n}\n",":local {\n .image {\n width: 100%;\n height: 100%;\n }\n}\n","import * as React from 'react';\n\nimport { useLazyLoad } from 'libs/shared/hooks/UseLazyLoad';\n\nimport styles from './lazy-image.module.scss';\n\n/**\n * This value means we will load images 500px above\n * or below the viewport so that they are loaded\n * by the time they come into the viewport\n */\nconst PRELOAD_DISTANCE = '500px';\n/**\n * Atomically small blank GIF as placeholder for image src to prevent w3 validator error\n */\nconst PLACEHOLDER_SRC = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';\n\ninterface LazyImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n forceLoad?: boolean;\n preventLoad?: boolean;\n extraClasses?: string;\n errorFallbackImageSrc?: string;\n errorFallbackImageClassName?: string;\n}\n\nexport const LazyImage = React.memo(function(props: LazyImageProps): React.ReactElement {\n const { forceLoad, extraClasses = '', errorFallbackImageSrc, preventLoad = false, errorFallbackImageClassName, src, alt, ...propsWithoutSrc } = props;\n \n const { ref, inView } = useLazyLoad({ rootMargin: PRELOAD_DISTANCE });\n const [ error, setError ] = React.useState(false);\n\n React.useEffect(() => {\n if ((!forceLoad && !inView) || preventLoad)\n return;\n \n // https://stackoverflow.com/questions/2342132/waiting-for-image-to-load-in-javascript\n const img = new Image();\n\n img.onerror = () => {\n setError(true);\n \n if (errorFallbackImageSrc)\n img.src = errorFallbackImageSrc;\n };\n\n img.src = src;\n return () => img.onerror = null;\n }, [ inView, preventLoad ]);\n\n function getSrc(): string {\n if (error && errorFallbackImageSrc)\n return errorFallbackImageSrc;\n\n return props.src;\n }\n\n if (error && !errorFallbackImageSrc)\n return <></>;\n\n if (!ref) {\n return (\n <img\n className={`${styles.image} ${extraClasses} ${error ? errorFallbackImageClassName || '' : ''}`}\n alt={alt}\n src={getSrc()}\n {...propsWithoutSrc}\n />\n );\n }\n\n const imgProps: React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement> = {\n alt,\n ...propsWithoutSrc,\n ...(((inView || forceLoad) && !preventLoad) ? { src: getSrc() } : { src: PLACEHOLDER_SRC })\n };\n\n if (!forceLoad)\n imgProps.ref = ref;\n\n return (\n <img className={`${styles.image} ${extraClasses} ${error ? errorFallbackImageClassName || '' : ''}`} {...imgProps} />\n );\n});\n",":local {\n .image {\n position: relative;\n width: 100%;\n height: 100%;\n\n :global(img) {\n position: absolute;\n top: 0; \n bottom: 0; \n left: 0; \n right: 0;\n }\n }\n\n // Aspect Ratios\n .thumbnail {\n padding-bottom: 56.25%;\n }\n\n .tallPoster {\n padding-bottom: 177.77778%;\n }\n\n .cover {\n padding-bottom: 100%;\n }\n\n .banner {\n padding-bottom: 18.50%\n }\n\n .poster {\n padding-bottom: 150%;\n }\n\n .pdf {\n :global(img) {\n height: auto;\n }\n }\n\n .link {\n :global(img) {\n width: auto;\n margin: 0 auto;\n }\n }\n}","import * as React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AnalyticsOptions, HashObject } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { LazyImage } from 'libs/shared/components/lazy-image/LazyImage';\nimport { ImageType } from 'libs/shared/enums/Images';\nimport { Image } from 'libs/shared/interfaces';\nimport { ImageHelper, ImageOptions } from 'libs/shared/utils/ImageHelper';\n\nimport styles from './image.module.scss';\n\nfunction getImageClassName(props: BaseImageProps): string {\n let className = styles.image;\n\n let imageTypeClassName = '';\n\n if (props.imageType === ImageType.Thumbnails)\n imageTypeClassName = `thumbnail ${styles.thumbnail}`;\n\n if (props.imageType === ImageType.TallPosters)\n imageTypeClassName = styles.tallPoster;\n\n if (props.imageType === ImageType.Covers)\n imageTypeClassName = styles.cover;\n\n if (props.imageType === ImageType.Banners)\n imageTypeClassName = styles.banner;\n\n if (props.imageType === ImageType.Posters)\n imageTypeClassName = styles.poster;\n\n if (props.imageType === ImageType.Pdf)\n imageTypeClassName = styles.pdf;\n\n if (props.imageType === ImageType.Link)\n imageTypeClassName = styles.link;\n\n if (imageTypeClassName)\n className += ` ${imageTypeClassName}`;\n\n if (props.className)\n className += ` ${props.className}`;\n\n return className;\n}\n\ninterface BaseImageProps {\n data: Image | string;\n imageOptions?: ImageOptions;\n appLink?: Core.AppLink;\n imageType?: ImageType;\n className?: string;\n imageClassName?: string;\n imageStyle?: HashObject;\n preload?: boolean;\n preventLoad?: boolean;\n analyticsData?: HashObject;\n analyticsOptions?: AnalyticsOptions;\n errorFallbackImageSrc?: string;\n errorFallbackImageClassName?: string;\n alt?: string;\n preventFocus?: boolean;\n appLinkClassName?: string;\n onClick?: () => void;\n onLoad?: () => void;\n openInNewTab?: boolean;\n forcePageLoad?: boolean;\n}\n\nexport function BaseImage(props: React.PropsWithChildren<BaseImageProps>): React.ReactElement {\n const {\n data,\n imageOptions,\n appLink,\n preload,\n preventLoad,\n analyticsOptions,\n analyticsData,\n imageClassName,\n alt\n } = props;\n\n let url = '';\n\n if (typeof data === 'string') {\n url = data;\n } else if (ObjectHelper.isObject(data)) {\n url = data.url;\n }\n\n const imageUrl = (url && imageOptions) ? ImageHelper.createUrl(url, imageOptions) : url;\n\n return (\n <div className={getImageClassName(props)} style={props.imageStyle}>\n <AppLink\n appLink={appLink}\n analyticsData={analyticsData}\n analyticsOptions={analyticsOptions}\n onClick={props.onClick}\n preventFocus={props.preventFocus}\n className={props.appLinkClassName}\n openInNewTab={props.openInNewTab}\n forcePageLoad={props.forcePageLoad}\n >\n {props.children}\n {imageUrl && (\n <LazyImage\n src={imageUrl}\n alt={alt}\n forceLoad={preload}\n preventLoad={preventLoad}\n extraClasses={imageClassName}\n errorFallbackImageSrc={props.errorFallbackImageSrc}\n errorFallbackImageClassName={props.errorFallbackImageClassName}\n onLoad={props.onLoad}\n />\n )}\n </AppLink>\n </div>\n );\n}\n\n","/**\n * Use this instead of the list below if you need to render the clickview logo\n * on the background you're rendering.\n */\nexport const LOGO_SAFE_BG_CLASS_NAMES = [\n 'bg-green',\n 'bg-cyan',\n 'bg-teal',\n 'bg-blue',\n 'bg-indigo',\n 'bg-purple'\n];\n\nexport const BG_COLOUR_CLASS_NAMES = [\n 'bg-pink',\n 'bg-orange',\n ...LOGO_SAFE_BG_CLASS_NAMES\n];\n","import React from 'react';\n\nexport function PlaySvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fill='currentColor'\n fillRule='evenodd'\n d='M7.76 6.078a.5.5 0 0 0-.76.427v11a.5.5 0 0 0 .76.426l9.003-5.5a.5.5 0 0 0 0-.853z'\n clipRule='evenodd'\n />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function ImageSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props} viewBox='0 0 24 21'>\n <path\n d='M22.5 1A1.5 1.5 0 0 1 24 2.5v18a1.5 1.5 0 0 1-1.5 1.5h-21A1.5 1.5 0 0 1 0 20.5v-18A1.5 1.5 0 0 1 1.5 1zm0 1.5h-21v18h21zm-8.21 4.092 5.84 9a.75.75 0 0 1-1.26.816L13.638 8.34l-2.523 3.591a.75.75 0 0 1-1.144.1l-.889-.89L5.1 16.45a.75.75 0 0 1-1.2-.9l4.5-6a.75.75 0 0 1 1.13-.08l.87.869 2.648-3.77a.75.75 0 0 1 1.243.023M6 4.75a2.25 2.25 0 1 1 0 4.5 2.25 2.25 0 0 1 0-4.5m0 1.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5'\n fill='currentColor'\n />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function SeriesSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fill='currentColor'\n d='M20.283 4C21.229 4 22 4.745 22 5.66v8.74c0 .726-.478 1.338-1.151 1.565l.088-10.22a.657.657 0 0 0-.664-.66H6.351A1.71 1.71 0 0 1 7.951 4zm-2.059 1.933c.947 0 1.718.745 1.718 1.65v8.74c.01.726-.479 1.339-1.142 1.565l.088-10.24a.647.647 0 0 0-.664-.64H4.293a1.7 1.7 0 0 1 1.6-1.075zM16.05 7.95c.946 0 1.707.744 1.707 1.659v8.74c0 .915-.77 1.65-1.707 1.65H3.707C2.761 20 2 19.255 2 18.35V9.61c0-.915.77-1.66 1.707-1.66zm-.01 1.084H3.717a.647.647 0 0 0-.663.64v8.609c0 .358.292.641.663.641H16.03c.371 0 .664-.283.664-.641V9.676c.01-.358-.283-.641-.654-.641M8.546 12.39v3.178c0 .17.205.264.342.17l2.254-1.594c.117-.085.117-.255 0-.33l-2.264-1.593c-.137-.095-.332 0-.332.17'\n />\n </svg>\n );\n}\n","export function getBgColorClass(name: string, classNames: string[]): string {\n return classNames[name.charCodeAt(0) % classNames.length];\n}\n\nexport function getDeterministicBgColorClass(name: string, classNames: string[]): string {\n const sum = name\n .split('')\n .reduce(\n (acc, char) => acc + char.charCodeAt(0),\n 0\n );\n \n return classNames[sum % classNames.length];\n}\n",":local {\n .baseFallbackContainer {\n position: absolute;\n width: 100%;\n height: 100%;\n }\n\n .svgFallbackContainer {\n @extend .baseFallbackContainer;\n background-color: $gray-100;\n }\n\n .subjectFallbackContainer {\n background-color: $gray-100;\n height: 100%;\n border-top-left-radius: $border-radius-lg;\n border-bottom-left-radius: $border-radius-lg;\n\n position: absolute;\n top: 0;\n left: 0;\n\n &Small {\n width: 2rem;\n }\n\n &Large {\n width: 5rem;\n }\n }\n\n .seriesItemFallback, .playlistItemFallback {\n @extend %icon;\n width: 3.75rem;\n height: 3.75rem;\n }\n\n .playlistFallback,\n .posterFallback { // poster fallback is used by series' & and subjects tall poster's\n @extend %icon;\n width: 7.5rem;\n height: 7.5rem;\n\n svg {\n width: 100%;\n height: 100%;\n }\n }\n\n .subjectFallback {\n @extend %icon;\n }\n\n %icon {\n position: absolute;\n top: 50%;\n left: 50%;\n color: $gray-400;\n transform: translate3D(-50%, -50%, 0);\n transition: opacity 100ms ease-in-out;\n }\n\n .fallbackThumbnailImage {\n padding: map-get($spacers, 1);\n background-size: cover;\n background-position: center;\n background-repeat: no-repeat;\n width: 100%;\n height: 100%;\n }\n\n .videoFallback,\n .folderFallback {\n position: absolute;\n width: 100%;\n height: 100%;\n }\n}","import * as React from 'react';\n\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { BG_COLOUR_CLASS_NAMES } from 'libs/shared/constants/ColourClassNames';\nimport { PlaySvg } from 'libs/shared/images/svg/actions/PlaySvg';\nimport { FileImgSvg } from 'libs/shared/images/svg/objects/FileImgSvg';\nimport { ImageSvg } from 'libs/shared/images/svg/objects/ImageSvg';\nimport { SeriesSvg } from 'libs/shared/images/svg/objects/SeriesSvg';\nimport { getBgColorClass } from 'libs/shared/utils/getBgColorClass';\n\nimport styles from './image-fallback.module.scss';\n\nexport enum ImageFallbackType {\n Playlist,\n PlaylistThumbnail,\n Series,\n SeriesThumbnail,\n Subject,\n TallSubject,\n Video,\n Folder\n}\n\nexport enum ImageFallbackMediaType {\n Svg,\n Image\n}\n\nexport enum ContainerClassSize {\n Large,\n Small\n}\n\nfunction getContainerClass(\n type: ImageFallbackMediaType,\n objectType: ImageFallbackType,\n containerClassSize: ContainerClassSize\n): string {\n if (objectType === ImageFallbackType.Subject) {\n const containerSizeClass = containerClassSize === ContainerClassSize.Large ?\n styles.subjectFallbackContainerLarge :\n styles.subjectFallbackContainerSmall;\n\n return `${styles.subjectFallbackContainer} ${containerSizeClass}`;\n }\n\n if (type === ImageFallbackMediaType.Svg) {\n if (objectType === ImageFallbackType.SeriesThumbnail || objectType === ImageFallbackType.PlaylistThumbnail)\n return `${styles.svgFallbackContainer} rounded-3`;\n \n return styles.svgFallbackContainer;\n }\n\n return styles.baseFallbackContainer;\n}\n\nfunction getClassByType(type: ImageFallbackType): string {\n if (type === ImageFallbackType.SeriesThumbnail)\n return styles.seriesItemFallback;\n\n if (type === ImageFallbackType.PlaylistThumbnail)\n return styles.playlistItemFallback;\n\n if (type === ImageFallbackType.Playlist)\n return styles.playlistFallback;\n\n if (type === ImageFallbackType.Series || type === ImageFallbackType.TallSubject)\n return styles.posterFallback;\n\n if (type === ImageFallbackType.Subject)\n return `${styles.subjectFallback} svg-container d-inline-block`;\n\n return '';\n}\n\nfunction getMedia(type: ImageFallbackType) {\n if (type === ImageFallbackType.SeriesThumbnail || type === ImageFallbackType.PlaylistThumbnail)\n return PlaySvg;\n\n if (type === ImageFallbackType.Playlist)\n return ImageSvg;\n\n if (type === ImageFallbackType.Series)\n return SeriesSvg;\n\n if (type === ImageFallbackType.Subject || type === ImageFallbackType.TallSubject)\n return FileImgSvg;\n\n return null;\n}\n\nfunction getSize(type: ImageFallbackType): SvgContainerSize {\n if (type === ImageFallbackType.Subject)\n return SvgContainerSize.ExtraLarge;\n\n return SvgContainerSize.Standard;\n}\n\ninterface ImageFallbackProps {\n type: ImageFallbackType;\n mediaType?: ImageFallbackMediaType;\n extraClasses?: string;\n svgContainerClassName?: string;\n name?: string;\n containerClassSize?: ContainerClassSize;\n}\n\nImageFallback.defaultProps = {\n mediaType: ImageFallbackMediaType.Svg,\n containerClassSize: ContainerClassSize.Large\n};\n\nexport function ImageFallback(props: ImageFallbackProps): JSX.Element {\n const { type, mediaType, extraClasses, containerClassSize } = props;\n\n if (type === ImageFallbackType.Video)\n return <div className={`${styles.videoFallback} ${props.extraClasses} bg-light-blue`} />;\n\n if (type === ImageFallbackType.Folder)\n return <div className={`${styles.folderFallback} ${props.extraClasses} ${getBgColorClass(props.name, BG_COLOUR_CLASS_NAMES)}`} />;\n\n const typeClass = getClassByType(type);\n const media = getMedia(type);\n const size = getSize(type);\n\n let className = `${getContainerClass(mediaType, type, containerClassSize)}`;\n\n if (extraClasses)\n className += ` ${props.extraClasses}`;\n\n return (\n <div className={className}>\n {mediaType === ImageFallbackMediaType.Svg ?\n (\n <SvgContainer\n svg={media}\n className={`${typeClass} ${props.svgContainerClassName ?? ''}`}\n tagName='div'\n size={size}\n />\n ) : (\n <div className={styles.fallbackThumbnailImage} style={{ backgroundImage: `url('${media}')` }} />\n )\n }\n </div>\n );\n}\n"],"mappings":"mRAyBA,SAAgB,EAAY,EAA8B,EAAE,CAAa,CACvE,GAAM,CAAE,UAAS,aAAY,cAAc,IAAS,EAGhD,CAAE,EAAK,EAAQ,GAAU,EAAU,CAAE,cAAyB,aAAY,CAAC,CAO/E,OALI,IAAY,IAAgB,OAAe,uBAAyB,UACtE,EAAS,GACT,EAAM,MAGD,CAAE,MAAK,SAAQ,YAAa,CAAC,CAAC,EAAO,+CEzBxC,EAAmB,QAInB,EAAkB,6DAUX,EAAA,EAAkB,KAAK,SAAS,EAA2C,CACtF,GAAM,CAAE,YAAW,eAAe,GAAI,wBAAuB,cAAc,GAAO,8BAA6B,MAAK,MAAK,GAAG,GAAoB,EAE1I,CAAE,MAAK,UAAW,EAAY,CAAE,WAAY,EAAkB,CAAC,CAC/D,CAAE,EAAO,GAAA,EAAmB,SAAS,GAAM,CAEjD,EAAM,cAAgB,CACpB,GAAK,CAAC,GAAa,CAAC,GAAW,EAC7B,OAGF,IAAM,EAAM,IAAI,MAUhB,MARA,GAAI,YAAgB,CAClB,EAAS,GAAK,CAEV,IACF,EAAI,IAAM,IAGd,EAAI,IAAM,MACG,EAAI,QAAU,MAC1B,CAAE,EAAQ,EAAa,CAAC,CAE3B,SAAS,GAAiB,CAIxB,OAHI,GAAS,EACJ,EAEF,EAAM,IAGf,GAAI,GAAS,CAAC,EACZ,OAAO,EAAA,EAAA,KAAA,EAAA,SAAA,EAAK,CAAA,CAEd,GAAI,CAAC,EACH,OACE,EAAA,EAAA,KAAC,MAAD,CACE,UAAW,GAAG,EAAO,MAAM,GAAG,EAAa,GAAG,GAAQ,GAAoC,KACrF,MACL,IAAK,GAAQ,CACb,GAAI,EACJ,CAAA,CAIN,IAAM,EAAiG,CACrG,MACA,GAAG,EACH,IAAM,GAAU,IAAc,CAAC,EAAe,CAAE,IAAK,GAAQ,CAAE,CAAG,CAAE,IAAK,EAAA,CAC1E,CAKD,OAHK,IACH,EAAS,IAAM,IAGf,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,GAAG,EAAO,MAAM,GAAG,EAAa,GAAG,GAAQ,GAAoC,KAAM,GAAI,EAAY,CAAA,EAEvH,oNEnEF,SAAS,EAAkB,EAA+B,CACxD,IAAI,EAAY,EAAO,MAEnB,EAAqB,GA6BzB,OA3BI,EAAM,YAAc,EAAU,aAChC,EAAqB,aAAa,EAAO,aAEvC,EAAM,YAAc,EAAU,cAChC,EAAqB,EAAO,YAE1B,EAAM,YAAc,EAAU,SAChC,EAAqB,EAAO,OAE1B,EAAM,YAAc,EAAU,UAChC,EAAqB,EAAO,QAE1B,EAAM,YAAc,EAAU,UAChC,EAAqB,EAAO,QAE1B,EAAM,YAAc,EAAU,MAChC,EAAqB,EAAO,KAE1B,EAAM,YAAc,EAAU,OAChC,EAAqB,EAAO,MAE1B,IACF,GAAa,IAAI,KAEf,EAAM,YACR,GAAa,IAAI,EAAM,aAElB,EA0BT,SAAgB,EAAU,EAAoE,CAC5F,GAAM,CACJ,OACA,eACA,UACA,UACA,cACA,mBACA,gBACA,iBACA,OACE,EAEA,EAAM,GAEN,OAAO,GAAS,SAClB,EAAM,EACG,EAAa,SAAS,EAAK,GACpC,EAAM,EAAK,KAGb,IAAM,EAAY,GAAO,EAAgB,EAAY,UAAU,EAAK,EAAa,CAAG,EAEpF,OACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,EAAkB,EAAM,CAAE,MAAO,EAAM,qBACrD,EAAA,EAAA,MAAC,EAAD,CACW,UACM,gBACG,mBAClB,QAAS,EAAM,QACf,aAAc,EAAM,aACpB,UAAW,EAAM,iBACjB,aAAc,EAAM,aACpB,cAAe,EAAM,uBARvB,CAUG,EAAM,SACN,IACC,EAAA,EAAA,KAAC,EAAD,CACE,IAAK,EACA,MACL,UAAW,EACE,cACb,aAAc,EACd,sBAAuB,EAAM,sBAC7B,4BAA6B,EAAM,4BACnC,OAAQ,EAAM,OACd,CAAA,CAAA,GAGF,CAAA,CC7GV,IAAa,EAAwB,CACnC,UACA,YACA,GAZsC,CACtC,WACA,UACA,UACA,UACA,YACA,YACD,CAMA,CCfD,SAAgB,EAAQ,EAAsC,CAC5D,OACE,EAAA,EAAA,KAAC,MAAD,CAAK,GAAI,YACP,EAAA,EAAA,KAAC,OAAD,CACE,KAAK,eACL,SAAS,UACT,EAAE,oFACF,SAAS,UACT,CAAA,CACE,CAAA,CCTV,SAAgB,EAAS,EAAsC,CAC7D,OACE,EAAA,EAAA,KAAC,MAAD,CAAK,GAAI,EAAO,QAAQ,sBACtB,EAAA,EAAA,KAAC,OAAD,CACE,EAAE,8ZACF,KAAK,eACL,CAAA,CACE,CAAA,CCPV,SAAgB,EAAU,EAAsC,CAC9D,OACE,EAAA,EAAA,KAAC,MAAD,CAAK,GAAI,YACP,EAAA,EAAA,KAAC,OAAD,CACE,KAAK,eACL,EAAE,6pBACF,CAAA,CACE,CAAA,CCTV,SAAgB,EAAgB,EAAc,EAA8B,CAC1E,OAAO,EAAW,EAAK,WAAW,EAAE,CAAG,EAAW,gsBEWxC,EAAL,SAAA,EAAA,OACL,GAAA,EAAA,SAAA,GAAA,WACA,EAAA,EAAA,kBAAA,GAAA,oBACA,EAAA,EAAA,OAAA,GAAA,SACA,EAAA,EAAA,gBAAA,GAAA,kBACA,EAAA,EAAA,QAAA,GAAA,UACA,EAAA,EAAA,YAAA,GAAA,cACA,EAAA,EAAA,MAAA,GAAA,QACA,EAAA,EAAA,OAAA,GAAA,eACD,CAEW,EAAL,SAAA,EAAA,OACL,GAAA,EAAA,IAAA,GAAA,MACA,EAAA,EAAA,MAAA,GAAA,cACD,CAEW,EAAL,SAAA,EAAA,OACL,GAAA,EAAA,MAAA,GAAA,QACA,EAAA,EAAA,MAAA,GAAA,cACD,CAED,SAAS,EACP,EACA,EACA,EACQ,CACR,GAAI,IAAe,EAAkB,QAAS,CAC5C,IAAM,EAAqB,IAAuB,EAAmB,MACnE,EAAO,8BACP,EAAO,8BAET,MAAO,GAAG,EAAO,yBAAyB,GAAG,IAU/C,OAPI,IAAS,EAAuB,IAC9B,IAAe,EAAkB,iBAAmB,IAAe,EAAkB,kBAChF,GAAG,EAAO,qBAAqB,YAEjC,EAAO,qBAGT,EAAO,sBAGhB,SAAS,EAAe,EAAiC,CAgBvD,OAfI,IAAS,EAAkB,gBACtB,EAAO,mBAEZ,IAAS,EAAkB,kBACtB,EAAO,qBAEZ,IAAS,EAAkB,SACtB,EAAO,iBAEZ,IAAS,EAAkB,QAAU,IAAS,EAAkB,YAC3D,EAAO,eAEZ,IAAS,EAAkB,QACtB,GAAG,EAAO,gBAAgB,+BAE5B,GAGT,SAAS,EAAS,EAAyB,CAazC,OAZI,IAAS,EAAkB,iBAAmB,IAAS,EAAkB,kBACpE,EAEL,IAAS,EAAkB,SACtB,EAEL,IAAS,EAAkB,OACtB,EAEL,IAAS,EAAkB,SAAW,IAAS,EAAkB,YAC5D,EAEF,KAGT,SAAS,EAAQ,EAA2C,CAI1D,OAHI,IAAS,EAAkB,QACtB,EAAiB,WAEnB,EAAiB,SAY1B,EAAc,aAAe,CAC3B,UAAW,EAAuB,IAClC,mBAAoB,EAAmB,MACxC,CAED,SAAgB,EAAc,EAAwC,CACpE,GAAM,CAAE,OAAM,YAAW,eAAc,sBAAuB,EAE9D,GAAI,IAAS,EAAkB,MAC7B,OAAO,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,GAAG,EAAO,cAAc,GAAG,EAAM,aAAa,gBAAmB,CAAA,CAE1F,GAAI,IAAS,EAAkB,OAC7B,OAAO,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,GAAG,EAAO,eAAe,GAAG,EAAM,aAAa,GAAG,EAAgB,EAAM,KAAM,EAAsB,GAAM,CAAA,CAEnI,IAAM,EAAY,EAAe,EAAK,CAChC,EAAQ,EAAS,EAAK,CACtB,EAAO,EAAQ,EAAK,CAEtB,EAAY,GAAG,EAAkB,EAAW,EAAM,EAAmB,GAKzE,OAHI,IACF,GAAa,IAAI,EAAM,iBAGvB,EAAA,EAAA,KAAC,MAAD,CAAgB,qBACb,IAAc,EAAuB,KAElC,EAAA,EAAA,KAAC,EAAD,CACE,IAAK,EACL,UAAW,GAAG,EAAU,GAAG,EAAM,uBAAyB,KAC1D,QAAQ,MACF,OACN,CAAA,EAEF,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,EAAO,uBAAwB,MAAO,CAAE,gBAAiB,QAAQ,EAAM,IAAA,CAAS,CAAA,CAGhG,CAAA"}
@@ -0,0 +1 @@
1
+ import{n as e}from"./PZOjj17O.chunk.js";export{e as GenerateReportView};
@@ -1,2 +1,2 @@
1
- import{P as e,nn as t,st as n}from"./CM0wW4AE.chunk.js";import{v as r}from"./B01-hGyk.chunk.js";import{d as i,n as a}from"./dUFTODMz.chunk.js";import{t as o}from"./CjM_tQvd.chunk.js";import{r as s,t as c}from"./NaTUzw6f.chunk.js";import{t as l}from"./I5Dnl_eN.chunk.js";import{n as u,r as d,t as f}from"./H5KLIhR_.chunk.js";import{t as p}from"./DIAxWspB.chunk.js";import{r as m}from"./app-BigOHyYp.js";import{t as h}from"./ktNy7dHM2.chunk.js";import{i as g,n as _,o as v,r as y,s as b,t as x}from"./CCLDpjnt2.chunk.js";var S={image:`_image_1a110_1`};n();var C=e(),w=l.encloseNamespace(`shared.streamsBarChartCardEmptyState`);function T(){return(0,C.jsxs)(p,{className:`flex-grow-1 justify-content-center`,children:[(0,C.jsx)(p.Image,{src:f.EmptyStates.Shared.BagQuestionOrange,className:S.image}),(0,C.jsx)(p.Heading,{className:`h6`,children:w(`heading`)}),(0,C.jsx)(p.Info,{className:`w-100`,children:w(`description`)})]})}var E=c(),D=`shared.streamsBarChartCard`,O=l.encloseNamespace(D);function k(e){let n=m(`video-views`),o=_(i(e.videoId?h.videoAggregation(e.videoId,e.type,n):h.aggregation(e.type,n)).data,y(e.type)),s=o?.reduce((e,t)=>e+t.y,0);return(0,C.jsx)(`div`,{className:`d-flex flex-column h-100 bg-white overflow-hidden rounded pt-3 px-3`,children:o?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`div`,{className:`d-flex justify-content-between`,children:[(0,C.jsx)(`h2`,{className:`h6 mb-1`,children:(0,C.jsx)(a,{namespace:D,phrase:`totalViews`,options:{views:s}})}),e.appLink&&e.appLinkText&&(0,C.jsx)(r,{appLink:e.appLink,className:`text-info`,children:e.appLinkText})]}),o.length?(0,C.jsx)(E.Scrollbars,{className:`position-relative`,children:(0,C.jsx)(`div`,{className:`position-absolute w-100 pe-2`,children:(0,C.jsx)(b,{data:o,labelAnnotations:{"Classroom views":{onClick:()=>{t.trigger({application:d.DEFAULT,action:u.Default.CLASSROOM_VIEWS_POPUP})},tooltip:O(`classroomViewsSettings`)}}})})}):(0,C.jsx)(T,{})]}):(0,C.jsx)(`div`,{className:`partial-loading-background d-block w-50`,children:`\xA0`})})}var A={MONTH:35,YEAR:365},j={day:`YYYY-MM-DD`,month:`YYYY-MM`,year:`YYYY`},M={day:`D MMM`,month:`MMM`,year:`YYYY`};function N(e){let t=o.diffBetween(e.end,e.start,`day`);return t>A.YEAR?`year`:t>A.MONTH?`month`:`day`}function P(e,t){let n=[],r=o.convertUTCToLocal(e.start),i=o.convertUTCToLocal(e.end),a=o.format(r,j[t]);for(;!o.isAfter(a,i,t);)n.push(a),a=o.format(o.add(a,1,t),j[t]);return n}function F(e,t,n){if(!e)return null;let r=N(t),i=P(t,r),a=new Map;e.forEach(e=>{let t=o.format(o.convertUTCToLocal(e.dateStreamed),j[r]),n=[s.System,`255`].includes(e.name)?null:e.name,i=a.get(n);i||a.set(n,i=new Map);let c=i.get(t)??0;i.set(t,c+e.count)});let c=[...a.keys()];if(!c.length)return{categories:i.map(e=>o.format(e,M[r])),data:[]};let l=y(n);return{categories:i.map(e=>o.format(e,M[r])),data:c.map(e=>({name:l(e),type:`line`,data:i.map(t=>a.get(e).get(t)??0),color:g(e)})).sort((e,t)=>v(e.name,t.name))}}var I=`reportsShared.streamsChartCard`,L=l.encloseNamespace(I);function R(e){let n=m(`video-views`),r=F(i(e.videoId?h.videoAggregationChart(e.videoId,e.type,n):h.aggregationChart(e.type,n)).data,n,e.type);return(0,C.jsx)(`div`,{className:`d-flex flex-column h-100 bg-white rounded p-3 position-relative`,children:r?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(`h2`,{className:`position-absolute h6 mb-1`,children:(0,C.jsx)(a,{namespace:I,phrase:`videoViews`})}),(0,C.jsx)(x,{categories:r.categories,data:r.data,legendAnnotations:{"Classroom views":{onClick:()=>{t.trigger({application:d.DEFAULT,action:u.Default.CLASSROOM_VIEWS_POPUP})},tooltip:L(`classroomViewsSettings`)}}})]}):(0,C.jsx)(`div`,{className:`partial-loading-background w-25`,children:`\xA0`})})}export{k as n,R as t};
2
- //# sourceMappingURL=CMKPCLR42.chunk.js.map
1
+ import{P as e,nn as t,st as n}from"./CM0wW4AE.chunk.js";import{v as r}from"./B01-hGyk.chunk.js";import{d as i,n as a}from"./dUFTODMz.chunk.js";import{t as o}from"./CjM_tQvd.chunk.js";import{r as s,t as c}from"./NaTUzw6f.chunk.js";import{t as l}from"./I5Dnl_eN.chunk.js";import{n as u,r as d,t as f}from"./H5KLIhR_.chunk.js";import{t as p}from"./DIAxWspB.chunk.js";import{r as m}from"./app-m6P7KXE1.js";import{t as h}from"./DvxtrAxT2.chunk.js";import{i as g,n as _,o as v,r as y,s as b,t as x}from"./XgwoBT6z2.chunk.js";var S={image:`_image_1a110_1`};n();var C=e(),w=l.encloseNamespace(`shared.streamsBarChartCardEmptyState`);function T(){return(0,C.jsxs)(p,{className:`flex-grow-1 justify-content-center`,children:[(0,C.jsx)(p.Image,{src:f.EmptyStates.Shared.BagQuestionOrange,className:S.image}),(0,C.jsx)(p.Heading,{className:`h6`,children:w(`heading`)}),(0,C.jsx)(p.Info,{className:`w-100`,children:w(`description`)})]})}var E=c(),D=`shared.streamsBarChartCard`,O=l.encloseNamespace(D);function k(e){let n=m(`video-views`),o=_(i(e.videoId?h.videoAggregation(e.videoId,e.type,n):h.aggregation(e.type,n)).data,y(e.type)),s=o?.reduce((e,t)=>e+t.y,0);return(0,C.jsx)(`div`,{className:`d-flex flex-column h-100 bg-white overflow-hidden rounded pt-3 px-3`,children:o?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`div`,{className:`d-flex justify-content-between`,children:[(0,C.jsx)(`h2`,{className:`h6 mb-1`,children:(0,C.jsx)(a,{namespace:D,phrase:`totalViews`,options:{views:s}})}),e.appLink&&e.appLinkText&&(0,C.jsx)(r,{appLink:e.appLink,className:`text-info`,children:e.appLinkText})]}),o.length?(0,C.jsx)(E.Scrollbars,{className:`position-relative`,children:(0,C.jsx)(`div`,{className:`position-absolute w-100 pe-2`,children:(0,C.jsx)(b,{data:o,labelAnnotations:{"Classroom views":{onClick:()=>{t.trigger({application:d.DEFAULT,action:u.Default.CLASSROOM_VIEWS_POPUP})},tooltip:O(`classroomViewsSettings`)}}})})}):(0,C.jsx)(T,{})]}):(0,C.jsx)(`div`,{className:`partial-loading-background d-block w-50`,children:`\xA0`})})}var A={MONTH:35,YEAR:365},j={day:`YYYY-MM-DD`,month:`YYYY-MM`,year:`YYYY`},M={day:`D MMM`,month:`MMM`,year:`YYYY`};function N(e){let t=o.diffBetween(e.end,e.start,`day`);return t>A.YEAR?`year`:t>A.MONTH?`month`:`day`}function P(e,t){let n=[],r=o.convertUTCToLocal(e.start),i=o.convertUTCToLocal(e.end),a=o.format(r,j[t]);for(;!o.isAfter(a,i,t);)n.push(a),a=o.format(o.add(a,1,t),j[t]);return n}function F(e,t,n){if(!e)return null;let r=N(t),i=P(t,r),a=new Map;e.forEach(e=>{let t=o.format(o.convertUTCToLocal(e.dateStreamed),j[r]),n=[s.System,`255`].includes(e.name)?null:e.name,i=a.get(n);i||a.set(n,i=new Map);let c=i.get(t)??0;i.set(t,c+e.count)});let c=[...a.keys()];if(!c.length)return{categories:i.map(e=>o.format(e,M[r])),data:[]};let l=y(n);return{categories:i.map(e=>o.format(e,M[r])),data:c.map(e=>({name:l(e),type:`line`,data:i.map(t=>a.get(e).get(t)??0),color:g(e)})).sort((e,t)=>v(e.name,t.name))}}var I=`reportsShared.streamsChartCard`,L=l.encloseNamespace(I);function R(e){let n=m(`video-views`),r=F(i(e.videoId?h.videoAggregationChart(e.videoId,e.type,n):h.aggregationChart(e.type,n)).data,n,e.type);return(0,C.jsx)(`div`,{className:`d-flex flex-column h-100 bg-white rounded p-3 position-relative`,children:r?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(`h2`,{className:`position-absolute h6 mb-1`,children:(0,C.jsx)(a,{namespace:I,phrase:`videoViews`})}),(0,C.jsx)(x,{categories:r.categories,data:r.data,legendAnnotations:{"Classroom views":{onClick:()=>{t.trigger({application:d.DEFAULT,action:u.Default.CLASSROOM_VIEWS_POPUP})},tooltip:L(`classroomViewsSettings`)}}})]}):(0,C.jsx)(`div`,{className:`partial-loading-background w-25`,children:`\xA0`})})}export{k as n,R as t};
2
+ //# sourceMappingURL=D0fFZDhm2.chunk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CMKPCLR42.chunk.js","names":[],"sources":["../../src/shared/views/overview-cards/streams-bar-chart-card/empty-state/total-views-by-group-card-empty-state.module.scss","../../src/shared/views/overview-cards/streams-bar-chart-card/empty-state/StreamsBarChartCardEmptyState.tsx","../../src/shared/views/overview-cards/streams-bar-chart-card/StreamsBarChartCardView.tsx","../../src/shared/views/overview-cards/streams-chart-card/StreamsChartCardViewUtils.ts","../../src/shared/views/overview-cards/streams-chart-card/StreamsChartCardView.tsx"],"sourcesContent":[":local {\n .image {\n width: 12.5rem;\n height: auto;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\n\nimport { ImageUrls } from 'shared/constants/ReportsImageUrls';\n\nconst namespace = 'shared.streamsBarChartCardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nimport styles from './total-views-by-group-card-empty-state.module.scss';\n\nexport function StreamsBarChartCardEmptyState() {\n return (\n <EmptyState className='flex-grow-1 justify-content-center'>\n <EmptyState.Image\n src={ImageUrls.EmptyStates.Shared.BagQuestionOrange}\n className={styles.image}\n />\n <EmptyState.Heading className='h6'>\n {getPhrase('heading')}\n </EmptyState.Heading>\n <EmptyState.Info className='w-100'>\n {getPhrase('description')}\n </EmptyState.Info>\n </EmptyState>\n );\n}\n","import React from 'react';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { GroupedAnalyticsCount } from 'libs/shared/apps/analytics/interfaces/BaseAnalyticsEvent';\nimport { StreamAggregationType } from 'libs/shared/apps/analytics/interfaces/StreamAggregationType';\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport { VerticalBarChart } from 'shared/components/vertical-bar-chart/VerticalBarChart';\nimport { Actions } from 'shared/constants/ReportsActions';\nimport { AppChannels } from 'shared/constants/ReportsRadioChannels';\nimport { VideoViewsV2Requests } from 'shared/flight-requests/VideoViewsV2Requests';\nimport { useGetRequestFilter } from 'shared/hooks/UseGetFilterQueryParams';\nimport { getCountByGroup } from 'shared/utils/BarChartByGroupUtils';\nimport { getLabelMapper } from 'shared/utils/UserUtils';\nimport { StreamsBarChartCardEmptyState } from 'shared/views/overview-cards/streams-bar-chart-card/empty-state/StreamsBarChartCardEmptyState';\n\nconst namespace = 'shared.streamsBarChartCard';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface TotalViewsByGroupViewProps {\n type: StreamAggregationType;\n videoId?: string;\n appLink?: Core.AppLink;\n appLinkText?: string;\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function StreamsBarChartCardView(props: TotalViewsByGroupViewProps) {\n const requestFilter = useGetRequestFilter('video-views');\n\n const chartData = Flight.useBasicFetch<GroupedAnalyticsCount[]>(props.videoId ?\n VideoViewsV2Requests.videoAggregation(props.videoId, props.type, requestFilter) :\n VideoViewsV2Requests.aggregation(props.type, requestFilter));\n\n const grouped = getCountByGroup(\n chartData.data,\n getLabelMapper(props.type)\n );\n const total = grouped?.reduce((acc, group) => (acc + group.y), 0);\n\n return (\n <div className='d-flex flex-column h-100 bg-white overflow-hidden rounded pt-3 px-3'>\n {grouped ?\n <>\n <div className='d-flex justify-content-between'>\n <h2 className='h6 mb-1'><Text namespace={namespace} phrase='totalViews' options={{ views: total }} /></h2>\n {props.appLink && props.appLinkText &&\n <AppLink\n appLink={props.appLink}\n className='text-info'\n >\n {props.appLinkText}\n </AppLink>\n }\n </div>\n\n {grouped.length ?\n <Scrollbars className='position-relative'>\n <div className='position-absolute w-100 pe-2'>\n <VerticalBarChart data={grouped} labelAnnotations={{\n 'Classroom views': {\n onClick: () => {\n Core.AppLinkHelper.trigger({\n application: AppChannels.DEFAULT,\n action: Actions.Default.CLASSROOM_VIEWS_POPUP\n });\n },\n tooltip: getPhrase('classroomViewsSettings')\n }\n }} />\n </div>\n </Scrollbars> :\n <StreamsBarChartCardEmptyState />\n }\n </> :\n <div className='partial-loading-background d-block w-50'>&nbsp;</div>\n }\n </div >\n );\n}\n","import { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { GroupedAnalyticsChartCount } from 'libs/shared/apps/analytics/interfaces/BaseAnalyticsEvent';\nimport { StreamAggregationType } from 'libs/shared/apps/analytics/interfaces/StreamAggregationType';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { AnalyticsRequestFilter } from 'libs/shared/interfaces';\n\nimport { compareGroupNames } from 'shared/utils/GroupSortUtils';\nimport { getLabelMapper, mapUserTypeToChartColour } from 'shared/utils/UserUtils';\n\nconst GroupByThresholds = {\n MONTH: 35,\n YEAR: 365\n};\n\nconst DateFormats = {\n day: 'YYYY-MM-DD',\n month: 'YYYY-MM',\n year: 'YYYY'\n};\n\nconst DisplayFormats = {\n day: 'D MMM',\n month: 'MMM',\n year: 'YYYY'\n};\n\ntype GroupBy = 'day' | 'month' | 'year';\n\ninterface ChartData {\n categories: string[];\n data: Highcharts.SeriesLineOptions[];\n}\n\nfunction getGroupBy(requestFilter: AnalyticsRequestFilter): GroupBy {\n const range = DateHelper.diffBetween(requestFilter.end, requestFilter.start, 'day');\n\n if (range > GroupByThresholds.YEAR)\n return 'year';\n\n if (range > GroupByThresholds.MONTH)\n return 'month';\n\n return 'day';\n}\n\nfunction getFullDateRange(requestFilter: AnalyticsRequestFilter, groupBy: GroupBy): string[] {\n const range: string[] = [];\n\n const localStart = DateHelper.convertUTCToLocal(requestFilter.start);\n const localEnd = DateHelper.convertUTCToLocal(requestFilter.end);\n\n let currentDate = DateHelper.format(localStart, DateFormats[groupBy]);\n\n while (!DateHelper.isAfter(currentDate, localEnd, groupBy)) {\n range.push(currentDate);\n currentDate = DateHelper.format(DateHelper.add(currentDate, 1, groupBy), DateFormats[groupBy]);\n }\n\n return range;\n}\n\nexport function getChartData(\n events: GroupedAnalyticsChartCount[],\n requestFilter: AnalyticsRequestFilter,\n type: StreamAggregationType\n): ChartData {\n if (!events) return null;\n\n const groupBy = getGroupBy(requestFilter);\n const fullDateRange = getFullDateRange(requestFilter, groupBy);\n \n const grouped = new Map<string, Map<string, number>>();\n \n events.forEach(ev => {\n const eventDate = DateHelper.format(DateHelper.convertUTCToLocal(ev.dateStreamed), DateFormats[groupBy]);\n \n // Bucketing System user data as Anonymous\n const name = [ UserGroup.System, '255' ].includes(ev.name) ? null : ev.name;\n\n let group = grouped.get(name);\n\n if (!group)\n grouped.set(name, group = new Map<string, number>);\n\n const oldCount = group.get(eventDate) ?? 0;\n group.set(eventDate, oldCount + ev.count);\n });\n\n const roles = [...grouped.keys()] as UserGroup[];\n\n if (!roles.length) return {\n categories: fullDateRange.map(d => DateHelper.format(d, DisplayFormats[groupBy])),\n data: []\n };\n\n const labelMapper = getLabelMapper(type);\n\n return {\n categories: fullDateRange.map(d => DateHelper.format(d, DisplayFormats[groupBy])),\n data:\n roles.map(r => ({\n name: labelMapper(r),\n type: 'line' as const,\n data: fullDateRange.map(d => grouped.get(r).get(d) ?? 0),\n color: mapUserTypeToChartColour(r)\n })).sort((a, b) => compareGroupNames(a.name, b.name))\n };\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { GroupedAnalyticsChartCount } from 'libs/shared/apps/analytics/interfaces/BaseAnalyticsEvent';\nimport { StreamAggregationType } from 'libs/shared/apps/analytics/interfaces/StreamAggregationType';\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport { LineChart } from 'shared/components/line-chart/LineChart';\nimport { Actions } from 'shared/constants/ReportsActions';\nimport { AppChannels } from 'shared/constants/ReportsRadioChannels';\nimport { VideoViewsV2Requests } from 'shared/flight-requests/VideoViewsV2Requests';\nimport { useGetRequestFilter } from 'shared/hooks/UseGetFilterQueryParams';\n\nimport { getChartData } from './StreamsChartCardViewUtils';\n\nconst namespace = 'reportsShared.streamsChartCard';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface StreamsChartCardViewProps {\n type: StreamAggregationType;\n videoId?: string;\n className?: string;\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function StreamsChartCardView(props: StreamsChartCardViewProps) {\n const requestFilter = useGetRequestFilter('video-views');\n\n const viewsByGroup = Flight.useBasicFetch<GroupedAnalyticsChartCount[]>(props.videoId ?\n VideoViewsV2Requests.videoAggregationChart(props.videoId, props.type, requestFilter) :\n VideoViewsV2Requests.aggregationChart(props.type, requestFilter));\n\n const chartData = getChartData(viewsByGroup.data, requestFilter, props.type);\n\n return (\n <div className='d-flex flex-column h-100 bg-white rounded p-3 position-relative'>\n {chartData ?\n <>\n <h2 className='position-absolute h6 mb-1'><Text namespace={namespace} phrase='videoViews' /></h2>\n <LineChart\n categories={chartData.categories}\n data={chartData.data}\n legendAnnotations={{\n 'Classroom views': {\n onClick: () => {\n Core.AppLinkHelper.trigger({\n application: AppChannels.DEFAULT,\n action: Actions.Default.CLASSROOM_VIEWS_POPUP\n });\n },\n tooltip: getPhrase('classroomViewsSettings')\n }\n }}\n />\n </> :\n <div className='partial-loading-background w-25'>&nbsp;</div>\n }\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"D0fFZDhm2.chunk.js","names":[],"sources":["../../src/shared/views/overview-cards/streams-bar-chart-card/empty-state/total-views-by-group-card-empty-state.module.scss","../../src/shared/views/overview-cards/streams-bar-chart-card/empty-state/StreamsBarChartCardEmptyState.tsx","../../src/shared/views/overview-cards/streams-bar-chart-card/StreamsBarChartCardView.tsx","../../src/shared/views/overview-cards/streams-chart-card/StreamsChartCardViewUtils.ts","../../src/shared/views/overview-cards/streams-chart-card/StreamsChartCardView.tsx"],"sourcesContent":[":local {\n .image {\n width: 12.5rem;\n height: auto;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\n\nimport { ImageUrls } from 'shared/constants/ReportsImageUrls';\n\nconst namespace = 'shared.streamsBarChartCardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nimport styles from './total-views-by-group-card-empty-state.module.scss';\n\nexport function StreamsBarChartCardEmptyState() {\n return (\n <EmptyState className='flex-grow-1 justify-content-center'>\n <EmptyState.Image\n src={ImageUrls.EmptyStates.Shared.BagQuestionOrange}\n className={styles.image}\n />\n <EmptyState.Heading className='h6'>\n {getPhrase('heading')}\n </EmptyState.Heading>\n <EmptyState.Info className='w-100'>\n {getPhrase('description')}\n </EmptyState.Info>\n </EmptyState>\n );\n}\n","import React from 'react';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { GroupedAnalyticsCount } from 'libs/shared/apps/analytics/interfaces/BaseAnalyticsEvent';\nimport { StreamAggregationType } from 'libs/shared/apps/analytics/interfaces/StreamAggregationType';\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport { VerticalBarChart } from 'shared/components/vertical-bar-chart/VerticalBarChart';\nimport { Actions } from 'shared/constants/ReportsActions';\nimport { AppChannels } from 'shared/constants/ReportsRadioChannels';\nimport { VideoViewsV2Requests } from 'shared/flight-requests/VideoViewsV2Requests';\nimport { useGetRequestFilter } from 'shared/hooks/UseGetFilterQueryParams';\nimport { getCountByGroup } from 'shared/utils/BarChartByGroupUtils';\nimport { getLabelMapper } from 'shared/utils/UserUtils';\nimport { StreamsBarChartCardEmptyState } from 'shared/views/overview-cards/streams-bar-chart-card/empty-state/StreamsBarChartCardEmptyState';\n\nconst namespace = 'shared.streamsBarChartCard';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface TotalViewsByGroupViewProps {\n type: StreamAggregationType;\n videoId?: string;\n appLink?: Core.AppLink;\n appLinkText?: string;\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function StreamsBarChartCardView(props: TotalViewsByGroupViewProps) {\n const requestFilter = useGetRequestFilter('video-views');\n\n const chartData = Flight.useBasicFetch<GroupedAnalyticsCount[]>(props.videoId ?\n VideoViewsV2Requests.videoAggregation(props.videoId, props.type, requestFilter) :\n VideoViewsV2Requests.aggregation(props.type, requestFilter));\n\n const grouped = getCountByGroup(\n chartData.data,\n getLabelMapper(props.type)\n );\n const total = grouped?.reduce((acc, group) => (acc + group.y), 0);\n\n return (\n <div className='d-flex flex-column h-100 bg-white overflow-hidden rounded pt-3 px-3'>\n {grouped ?\n <>\n <div className='d-flex justify-content-between'>\n <h2 className='h6 mb-1'><Text namespace={namespace} phrase='totalViews' options={{ views: total }} /></h2>\n {props.appLink && props.appLinkText &&\n <AppLink\n appLink={props.appLink}\n className='text-info'\n >\n {props.appLinkText}\n </AppLink>\n }\n </div>\n\n {grouped.length ?\n <Scrollbars className='position-relative'>\n <div className='position-absolute w-100 pe-2'>\n <VerticalBarChart data={grouped} labelAnnotations={{\n 'Classroom views': {\n onClick: () => {\n Core.AppLinkHelper.trigger({\n application: AppChannels.DEFAULT,\n action: Actions.Default.CLASSROOM_VIEWS_POPUP\n });\n },\n tooltip: getPhrase('classroomViewsSettings')\n }\n }} />\n </div>\n </Scrollbars> :\n <StreamsBarChartCardEmptyState />\n }\n </> :\n <div className='partial-loading-background d-block w-50'>&nbsp;</div>\n }\n </div >\n );\n}\n","import { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { GroupedAnalyticsChartCount } from 'libs/shared/apps/analytics/interfaces/BaseAnalyticsEvent';\nimport { StreamAggregationType } from 'libs/shared/apps/analytics/interfaces/StreamAggregationType';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { AnalyticsRequestFilter } from 'libs/shared/interfaces';\n\nimport { compareGroupNames } from 'shared/utils/GroupSortUtils';\nimport { getLabelMapper, mapUserTypeToChartColour } from 'shared/utils/UserUtils';\n\nconst GroupByThresholds = {\n MONTH: 35,\n YEAR: 365\n};\n\nconst DateFormats = {\n day: 'YYYY-MM-DD',\n month: 'YYYY-MM',\n year: 'YYYY'\n};\n\nconst DisplayFormats = {\n day: 'D MMM',\n month: 'MMM',\n year: 'YYYY'\n};\n\ntype GroupBy = 'day' | 'month' | 'year';\n\ninterface ChartData {\n categories: string[];\n data: Highcharts.SeriesLineOptions[];\n}\n\nfunction getGroupBy(requestFilter: AnalyticsRequestFilter): GroupBy {\n const range = DateHelper.diffBetween(requestFilter.end, requestFilter.start, 'day');\n\n if (range > GroupByThresholds.YEAR)\n return 'year';\n\n if (range > GroupByThresholds.MONTH)\n return 'month';\n\n return 'day';\n}\n\nfunction getFullDateRange(requestFilter: AnalyticsRequestFilter, groupBy: GroupBy): string[] {\n const range: string[] = [];\n\n const localStart = DateHelper.convertUTCToLocal(requestFilter.start);\n const localEnd = DateHelper.convertUTCToLocal(requestFilter.end);\n\n let currentDate = DateHelper.format(localStart, DateFormats[groupBy]);\n\n while (!DateHelper.isAfter(currentDate, localEnd, groupBy)) {\n range.push(currentDate);\n currentDate = DateHelper.format(DateHelper.add(currentDate, 1, groupBy), DateFormats[groupBy]);\n }\n\n return range;\n}\n\nexport function getChartData(\n events: GroupedAnalyticsChartCount[],\n requestFilter: AnalyticsRequestFilter,\n type: StreamAggregationType\n): ChartData {\n if (!events) return null;\n\n const groupBy = getGroupBy(requestFilter);\n const fullDateRange = getFullDateRange(requestFilter, groupBy);\n \n const grouped = new Map<string, Map<string, number>>();\n \n events.forEach(ev => {\n const eventDate = DateHelper.format(DateHelper.convertUTCToLocal(ev.dateStreamed), DateFormats[groupBy]);\n \n // Bucketing System user data as Anonymous\n const name = [ UserGroup.System, '255' ].includes(ev.name) ? null : ev.name;\n\n let group = grouped.get(name);\n\n if (!group)\n grouped.set(name, group = new Map<string, number>);\n\n const oldCount = group.get(eventDate) ?? 0;\n group.set(eventDate, oldCount + ev.count);\n });\n\n const roles = [...grouped.keys()] as UserGroup[];\n\n if (!roles.length) return {\n categories: fullDateRange.map(d => DateHelper.format(d, DisplayFormats[groupBy])),\n data: []\n };\n\n const labelMapper = getLabelMapper(type);\n\n return {\n categories: fullDateRange.map(d => DateHelper.format(d, DisplayFormats[groupBy])),\n data:\n roles.map(r => ({\n name: labelMapper(r),\n type: 'line' as const,\n data: fullDateRange.map(d => grouped.get(r).get(d) ?? 0),\n color: mapUserTypeToChartColour(r)\n })).sort((a, b) => compareGroupNames(a.name, b.name))\n };\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { GroupedAnalyticsChartCount } from 'libs/shared/apps/analytics/interfaces/BaseAnalyticsEvent';\nimport { StreamAggregationType } from 'libs/shared/apps/analytics/interfaces/StreamAggregationType';\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport { LineChart } from 'shared/components/line-chart/LineChart';\nimport { Actions } from 'shared/constants/ReportsActions';\nimport { AppChannels } from 'shared/constants/ReportsRadioChannels';\nimport { VideoViewsV2Requests } from 'shared/flight-requests/VideoViewsV2Requests';\nimport { useGetRequestFilter } from 'shared/hooks/UseGetFilterQueryParams';\n\nimport { getChartData } from './StreamsChartCardViewUtils';\n\nconst namespace = 'reportsShared.streamsChartCard';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface StreamsChartCardViewProps {\n type: StreamAggregationType;\n videoId?: string;\n className?: string;\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function StreamsChartCardView(props: StreamsChartCardViewProps) {\n const requestFilter = useGetRequestFilter('video-views');\n\n const viewsByGroup = Flight.useBasicFetch<GroupedAnalyticsChartCount[]>(props.videoId ?\n VideoViewsV2Requests.videoAggregationChart(props.videoId, props.type, requestFilter) :\n VideoViewsV2Requests.aggregationChart(props.type, requestFilter));\n\n const chartData = getChartData(viewsByGroup.data, requestFilter, props.type);\n\n return (\n <div className='d-flex flex-column h-100 bg-white rounded p-3 position-relative'>\n {chartData ?\n <>\n <h2 className='position-absolute h6 mb-1'><Text namespace={namespace} phrase='videoViews' /></h2>\n <LineChart\n categories={chartData.categories}\n data={chartData.data}\n legendAnnotations={{\n 'Classroom views': {\n onClick: () => {\n Core.AppLinkHelper.trigger({\n application: AppChannels.DEFAULT,\n action: Actions.Default.CLASSROOM_VIEWS_POPUP\n });\n },\n tooltip: getPhrase('classroomViewsSettings')\n }\n }}\n />\n </> :\n <div className='partial-loading-background w-25'>&nbsp;</div>\n }\n </div>\n );\n}\n"],"mappings":"ojBCSM,EAAY,EAAgB,iBADhB,uCAC2C,CAI7D,SAAgB,GAAgC,CAC9C,OACE,EAAA,EAAA,MAAC,EAAD,CAAY,UAAU,8CAAtB,EACE,EAAA,EAAA,KAAC,EAAW,MAAZ,CACE,IAAK,EAAU,YAAY,OAAO,kBAClC,UAAW,EAAO,MAClB,CAAA,EACF,EAAA,EAAA,KAAC,EAAW,QAAZ,CAAoB,UAAU,cAC3B,EAAU,UAAU,CACF,CAAA,EACrB,EAAA,EAAA,KAAC,EAAW,KAAZ,CAAiB,UAAU,iBACxB,EAAU,cAAc,CACT,CAAA,CACP,aCLX,EAAY,6BACZ,EAAY,EAAgB,iBAAiB,EAAU,CAU7D,SAAgB,EAAwB,EAAmC,CACzE,IAAM,EAAgB,EAAoB,cAAc,CAMlD,EAAU,EAJE,EAA8C,EAAM,QACpE,EAAqB,iBAAiB,EAAM,QAAS,EAAM,KAAM,EAAc,CAC/E,EAAqB,YAAY,EAAM,KAAM,EAAc,CAAC,CAGlD,KACV,EAAe,EAAM,KAAK,CAC3B,CACK,EAAQ,GAAS,QAAQ,EAAK,IAAW,EAAM,EAAM,EAAI,EAAE,CAEjE,OACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+EACZ,GACC,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,0CAAf,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,oBAAU,EAAA,EAAA,KAAC,EAAD,CAAiB,UAAA,EAAW,OAAO,aAAa,QAAS,CAAE,MAAO,EAAO,CAAI,CAAA,CAAK,CAAA,CACzG,EAAM,SAAW,EAAM,cACtB,EAAA,EAAA,KAAC,EAAD,CACE,QAAS,EAAM,QACf,UAAU,qBAET,EAAM,YACC,CAAA,CAER,GAEL,EAAQ,QACP,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,UAAU,8BACpB,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,yCACb,EAAA,EAAA,KAAC,EAAD,CAAkB,KAAM,EAAS,iBAAkB,CACjD,kBAAmB,CACjB,YAAe,CACb,EAAmB,QAAQ,CACzB,YAAa,EAAY,QACzB,OAAQ,EAAQ,QAAQ,sBACzB,CAAC,EAEJ,QAAS,EAAU,yBAAyB,CAC7C,CACF,CAAI,CAAA,CACD,CAAA,CACK,CAAA,EACb,EAAA,EAAA,KAAC,EAAD,EAAiC,CAAA,CAElC,CAAA,CAAA,EACH,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,mDAA0C,OAAY,CAAA,CAElE,CAAA,CCxEX,IAAM,EAAoB,CACxB,MAAO,GACP,KAAM,IACP,CAEK,EAAc,CAClB,IAAK,aACL,MAAO,UACP,KAAM,OACP,CAEK,EAAiB,CACrB,IAAK,QACL,MAAO,MACP,KAAM,OACP,CASD,SAAS,EAAW,EAAgD,CAClE,IAAM,EAAQ,EAAW,YAAY,EAAc,IAAK,EAAc,MAAO,MAAM,CAQnF,OANI,EAAQ,EAAkB,KACrB,OAEL,EAAQ,EAAkB,MACrB,QAEF,MAGT,SAAS,EAAiB,EAAuC,EAA4B,CAC3F,IAAM,EAAkB,EAAE,CAEpB,EAAa,EAAW,kBAAkB,EAAc,MAAM,CAC9D,EAAW,EAAW,kBAAkB,EAAc,IAAI,CAE5D,EAAc,EAAW,OAAO,EAAY,EAAY,GAAS,CAErE,KAAO,CAAC,EAAW,QAAQ,EAAa,EAAU,EAAQ,EACxD,EAAM,KAAK,EAAY,CACvB,EAAc,EAAW,OAAO,EAAW,IAAI,EAAa,EAAG,EAAQ,CAAE,EAAY,GAAS,CAGhG,OAAO,EAGT,SAAgB,EACd,EACA,EACA,EACW,CACX,GAAI,CAAC,EAAQ,OAAO,KAEpB,IAAM,EAAU,EAAW,EAAc,CACnC,EAAgB,EAAiB,EAAe,EAAQ,CAExD,EAAU,IAAI,IAEpB,EAAO,QAAQ,GAAM,CACnB,IAAM,EAAY,EAAW,OAAO,EAAW,kBAAkB,EAAG,aAAa,CAAE,EAAY,GAAS,CAGlG,EAAO,CAAE,EAAU,OAAQ,MAAO,CAAC,SAAS,EAAG,KAAK,CAAG,KAAO,EAAG,KAEnE,EAAQ,EAAQ,IAAI,EAAK,CAExB,GACH,EAAQ,IAAI,EAAM,EAAQ,IAAI,IAAoB,CAEpD,IAAM,EAAW,EAAM,IAAI,EAAU,EAAI,EACzC,EAAM,IAAI,EAAW,EAAW,EAAG,MAAM,EACzC,CAEF,IAAM,EAAQ,CAAC,GAAG,EAAQ,MAAM,CAAC,CAEjC,GAAI,CAAC,EAAM,OAAQ,MAAO,CACxB,WAAY,EAAc,IAAI,GAAK,EAAW,OAAO,EAAG,EAAe,GAAS,CAAC,CACjF,KAAM,EAAE,CACT,CAED,IAAM,EAAc,EAAe,EAAK,CAExC,MAAO,CACL,WAAY,EAAc,IAAI,GAAK,EAAW,OAAO,EAAG,EAAe,GAAS,CAAC,CACjF,KACE,EAAM,IAAI,IAAM,CACd,KAAM,EAAY,EAAE,CACpB,KAAM,OACN,KAAM,EAAc,IAAI,GAAK,EAAQ,IAAI,EAAE,CAAC,IAAI,EAAE,EAAI,EAAE,CACxD,MAAO,EAAyB,EAAE,CACnC,EAAE,CAAC,MAAM,EAAG,IAAM,EAAkB,EAAE,KAAM,EAAE,KAAK,CAAC,CACxD,CCzFH,IAAM,EAAY,iCACZ,EAAY,EAAgB,iBAAiB,EAAU,CAS7D,SAAgB,EAAqB,EAAkC,CACrE,IAAM,EAAgB,EAAoB,cAAc,CAMlD,EAAY,EAJG,EAAmD,EAAM,QAC5E,EAAqB,sBAAsB,EAAM,QAAS,EAAM,KAAM,EAAc,CACpF,EAAqB,iBAAiB,EAAM,KAAM,EAAc,CAAC,CAEvB,KAAM,EAAe,EAAM,KAAK,CAE5E,OACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,2EACZ,GACC,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,sCAA4B,EAAA,EAAA,KAAC,EAAD,CAAiB,YAAW,OAAO,aAAe,CAAA,CAAK,CAAA,EACjG,EAAA,EAAA,KAAC,EAAD,CACE,WAAY,EAAU,WACtB,KAAM,EAAU,KAChB,kBAAmB,CACjB,kBAAmB,CACjB,YAAe,CACb,EAAmB,QAAQ,CACzB,YAAa,EAAY,QACzB,OAAQ,EAAQ,QAAQ,sBACzB,CAAC,EAEJ,QAAS,EAAU,yBAAyB,CAC7C,CACF,CACD,CAAA,CACD,CAAA,CAAA,EACH,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,2CAAkC,OAAY,CAAA,CAE3D,CAAA"}