{"version":3,"sources":["webpack:///./src/Frontend/app/components/product-teaser/product-teaser.tsx","webpack:///./src/Frontend/app/components/product-review-slider/product-review-item/product-review-item.tsx","webpack:///./src/Frontend/app/components/product-review-slider/product-review-slider.tsx","webpack:///./src/Frontend/app/components/author-featured-product/author-featured-product.tsx","webpack:///./src/Frontend/app/views/author-featured-product/author-featured-product-view.tsx","webpack:///./src/Frontend/app/components/icons/icon.tsx","webpack:///./src/Frontend/app/components/anchor/anchor.tsx","webpack:///./src/Frontend/app/components/content-section/content-section.tsx","webpack:///./src/Frontend/app/components/cta-button/cta-button.tsx","webpack:///./src/Frontend/app/utils/breakpoint-utils.ts","webpack:///./src/Frontend/app/components/tag/tag.tsx","webpack:///./src/Frontend/app/utils/tracking-utils.ts","webpack:///./src/Frontend/app/components/product-image/product-image.tsx","webpack:///./src/Frontend/app/components/product-authors/product-authors.tsx","webpack:///./src/Frontend/app/components/swiper/swiper-button.tsx","webpack:///./src/Frontend/app/components/show-more/show-more.tsx","webpack:///./src/Frontend/app/components/swiper/slider-swiper.tsx"],"names":["product","splashLabel","splashText","featuredLabel","ctaLink","autogeneratedCtaLink","enableShowMoreDescription","showMoreButton","showLessButton","props","title","authors","description","imageFallbackSrc","imageSrcSet","productId","url","baseClass","image","fallbackSrc","srcSet","sizes","alt","trackingParams","trackingList","trackingPosition","triggerOnce","ref","inView","clickTrackingEvent","className","type","href","onClick","dangerouslySetInnerHTML","__html","maxLines","minHeight","btnLabelShowMore","btnLabelShowLess","link","isLarge","item","labels","reviewSectionRef","source","rating","ratingIconList","range","ratingRange","i","isCurrentIconInactive","iconClasses","push","iconId","key","getVisualRatingIcons","ratingLabel","showMoreMinHeight","showLess","showMore","review","productReviews","headline","swiperSettings","slidesToShow","swipeToSlide","lazyLoad","initialSlide","responsive","breakpoint","cat","settings","wolf","length","map","index","render","this","contextModel","spriteUrl","viewBox","preserveAspectRatio","xmlnsXlink","xlinkHref","id","anchorId","hasNoMarginTop","hasNoMarginBottom","componentClasses","children","isInverted","isSecondary","breakpoints","rat","rabbit","dog","lion","horse","rhino","elephant","mediaQueries","Object","keys","reduce","queryStrings","currentMediaQueries","handleMediaMatch","isMatching","forEach","mediaQuery","matchMedia","matches","addListener","event","tagTypeClassMap","NEWS","SPOT","BESTSELLER","BOOK_OF_THE_MONTH","UPCOMING","classModifier","rootClasses","shape","EventTypes","CurrencyCodes","TrackingDimensions","ensureDataLayer","window","dataLayer","pushEcommerenceTrackingEvent","trackingEvent","pushTrackingEvent","pushClickTrackingEvent","CLICK","ecommerce","click","actionField","list","products","name","position","pushDetailViewTrackingEvent","DETAIL_VIEW","detail","pushImpressionViewTrackingEvent","IMPRESSION_VIEW","impressions","ProductImage","loading","src","classes","Wrapper","lines","author","direction","tabIndex","state","showMoreHasOverflow","showMoreIsOpen","componentDidMount","addEventListener","handleResize","bind","componentWillUnmount","removeEventListener","disableOnBreakpoint","disableOverflow","hasOverflow","childrenWrapper","clientHeight","setState","toggleMore","containerClasses","setAnimateToMinHeight","btnText","height","duration","node","buttonClasses","buttonClassName","nextArrow","prevArrow","draggable","infinite","speed"],"mappings":"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","file":"11.c4e9d7acc4d6fb4d8a3f.js","sourcesContent":["import * as React from \"react\";\r\nimport { IProduct } from \"../../types/product\";\r\n// import { IButtonAddToBasketProps } from \"~/components/button-add-to-basket/button-add-to-basket\";\r\nimport CtaButton from \"../cta-button/cta-button\";\r\n// import ProductPrice, { IProductPriceProps } from \"../product-price/product-price\";\r\nimport ShowMore from \"../show-more/show-more\";\r\nimport { pushImpressionViewTrackingEvent, pushClickTrackingEvent } from \"~/utils/tracking-utils\";\r\nimport { useInView } from \"react-intersection-observer\";\r\nimport Tag from \"../tag/tag\";\r\nimport ProductAuthors from \"../product-authors/product-authors\";\r\n// import InfoSection from \"../info-section/info-section\";\r\n// import ProductDiscountSplash from \"../product-discount-splash/product-discount-splash\";\r\nimport ProductImage from \"../product-image/product-image\";\r\nimport ContentSection from \"../content-section/content-section\";\r\n\r\nexport interface IProductTeaserProps {\r\n    product: IProduct;\r\n    splashLabel?: string;\r\n    splashText?: string;\r\n    ctaLink?: string;\r\n    autogeneratedCtaLink?: string;\r\n    productPriceAddToBasketLabel?: string;\r\n    enableShowMoreDescription?: boolean;\r\n    showMoreButton?: string;\r\n    showLessButton?: string;\r\n    featuredLabel?: string;\r\n    anchorId?: string;\r\n    hasNoMarginTop?: boolean;\r\n    hasNoMarginBottom?: boolean;\r\n}\r\n\r\nconst ProductTeaser: React.FC<IProductTeaserProps> = ({\r\n    product,\r\n    // productPriceAddToBasketLabel,\r\n    // primaryPriceLabel,\r\n    // secondaryPriceLabel,\r\n    // addToBasketWebApiUrl,\r\n    splashLabel,\r\n    splashText,\r\n    featuredLabel,\r\n    ctaLink,\r\n    autogeneratedCtaLink,\r\n    enableShowMoreDescription,\r\n    showMoreButton,\r\n    showLessButton,\r\n    ...props\r\n}) => {\r\n    const {\r\n        title,\r\n        authors,\r\n        description,\r\n        imageFallbackSrc,\r\n        imageSrcSet,\r\n        productId,\r\n        // priceType,\r\n        // primaryPrice,\r\n        // secondaryPrice,\r\n        url\r\n        // materialType,\r\n        // discount\r\n    } = product;\r\n    const baseClass = \"product-teaser\";\r\n\r\n    const image = imageFallbackSrc && imageSrcSet && (\r\n        <ProductImage fallbackSrc={imageFallbackSrc} srcSet={imageSrcSet} sizes=\"240px\" alt={title} />\r\n    );\r\n\r\n    const trackingParams = {\r\n        productId,\r\n        title,\r\n        trackingList: \"Product Teaser\",\r\n        trackingPosition: 1\r\n    };\r\n\r\n    const [ref, inView] = useInView({\r\n        triggerOnce: true\r\n    });\r\n\r\n    React.useEffect(() => {\r\n        if (inView) {\r\n            pushImpressionViewTrackingEvent([trackingParams]);\r\n        }\r\n    }, [inView]);\r\n\r\n    const clickTrackingEvent = () => pushClickTrackingEvent(trackingParams);\r\n\r\n    return (\r\n        <ContentSection className={baseClass} type=\"full\" {...props}>\r\n            <div className={`${baseClass}__inner`} ref={ref}>\r\n                <div className={`${baseClass}__image-section-wrapper`}>\r\n                    <div className={`${baseClass}__image-section`}>\r\n                        {imageFallbackSrc && url && (\r\n                            <a href={url} onClick={clickTrackingEvent}>\r\n                                {image}\r\n                            </a>\r\n                        )}\r\n                        {imageFallbackSrc && !url && image}\r\n                        {(splashLabel || splashText) && (\r\n                            <div className={`${baseClass}__splash-wrapper`}>\r\n                                <div className={`${baseClass}__splash`}>\r\n                                    {splashLabel && (\r\n                                        <div\r\n                                            className={`${baseClass}__splash-label`}\r\n                                            dangerouslySetInnerHTML={{ __html: splashLabel }}\r\n                                        />\r\n                                    )}\r\n                                    {splashText && (\r\n                                        <div\r\n                                            className={`${baseClass}__splash-text`}\r\n                                            dangerouslySetInnerHTML={{ __html: splashText }}\r\n                                        />\r\n                                    )}\r\n                                </div>\r\n                            </div>\r\n                        )}\r\n                        {/* {discount && <ProductDiscountSplash discount={discount} />} */}\r\n                    </div>\r\n                </div>\r\n                <div className={`${baseClass}__content-wrapper`}>\r\n                    {featuredLabel ? (\r\n                        <Tag className={`${baseClass}__featured-tag`}>{featuredLabel}</Tag>\r\n                    ) : null}\r\n\r\n                    {url ? (\r\n                        <h2 className={`${baseClass}__title h2-style`}>\r\n                            <a className=\"reset-a\" href={url} onClick={clickTrackingEvent}>\r\n                                {title}\r\n                            </a>\r\n                        </h2>\r\n                    ) : (\r\n                        <h2 className={`${baseClass}__title h2-style`}>{title}</h2>\r\n                    )}\r\n\r\n                    <ProductAuthors\r\n                        className={`${baseClass}__product-authors`}\r\n                        authors={authors}\r\n                        maxLines={2}\r\n                    />\r\n\r\n                    {/* {materialType && <div className={`${baseClass}__material-type`}>{materialType}</div>} */}\r\n                    {description && (\r\n                        <>\r\n                            {enableShowMoreDescription && showMoreButton && showLessButton ? (\r\n                                <ShowMore\r\n                                    className={`${baseClass}__rich-text-show-more-wrapper`}\r\n                                    minHeight={140}\r\n                                    btnLabelShowMore={showMoreButton}\r\n                                    btnLabelShowLess={showLessButton}\r\n                                >\r\n                                    <div\r\n                                        className=\"content-rich-text\"\r\n                                        dangerouslySetInnerHTML={{\r\n                                            __html: description\r\n                                        }}\r\n                                    />\r\n                                </ShowMore>\r\n                            ) : (\r\n                                <div\r\n                                    className={`${baseClass}__rich-text content-rich-text`}\r\n                                    dangerouslySetInnerHTML={{ __html: description }}\r\n                                />\r\n                            )}\r\n                        </>\r\n                    )}\r\n\r\n                    {ctaLink && <CtaButton link={ctaLink} isLarge />}\r\n                    {autogeneratedCtaLink && <CtaButton link={autogeneratedCtaLink} isLarge />}\r\n                    {/* <div className={`${baseClass}__price-wrapper`}> */}\r\n                    {/* <ProductPrice\r\n                            primaryPriceLabel={primaryPriceLabel}\r\n                            secondaryPriceLabel={secondaryPriceLabel}\r\n                            priceType={priceType}\r\n                            primaryPrice={primaryPrice}\r\n                            secondaryPrice={secondaryPrice}\r\n                        >\r\n                            {ctaLink ? (\r\n                                <CtaButton link={ctaLink} isLarge />\r\n                            ) : (\r\n                                <>\r\n                                    {addToBasketWebApiUrl && (\r\n                                        <ButtonAddToBasket\r\n                                            addToBasketWebApiUrl={addToBasketWebApiUrl}\r\n                                            productId={productId}\r\n                                            trackingList=\"Product Teaser\"\r\n                                            isLarge\r\n                                        >\r\n                                            {productPriceAddToBasketLabel}\r\n                                        </ButtonAddToBasket>\r\n                                    )}\r\n                                </>\r\n                            )}\r\n                        </ProductPrice> */}\r\n                    {/* </div> */}\r\n                    {/* {product.stockStatusLabel && (\r\n                        <InfoSection iconId=\"32_information\" label={product.stockStatusLabel} />\r\n                    )}\r\n                    {product.deliveryLabel && (\r\n                        <InfoSection iconId=\"32_truck-in-motion\" label={product.deliveryLabel} />\r\n                    )} */}\r\n                </div>\r\n            </div>\r\n        </ContentSection>\r\n    );\r\n};\r\n\r\nexport default ProductTeaser;\r\n","import * as React from \"react\";\r\nimport Icon from \"~/components/icons/icon\";\r\nimport classNames from \"classnames\";\r\nimport ShowMore from \"~/components/show-more/show-more\";\r\n\r\nexport interface ProductReviewItemProps {\r\n    item: {\r\n        review?: string;\r\n        source?: string;\r\n        rating?: number;\r\n        ratingRange?: number;\r\n        ratingLabel?: string;\r\n    };\r\n    labels: {\r\n        showMore: string;\r\n        showLess: string;\r\n    };\r\n}\r\n\r\nconst ProductReviewItem: React.FC<ProductReviewItemProps> = ({ item, labels }) => {\r\n    const baseClass = \"product-review-item\";\r\n    const reviewSectionRef = React.useRef<HTMLDivElement>(null);\r\n\r\n    const getVisualRatingIcons = () => {\r\n        if (!item.rating) {\r\n            return;\r\n        }\r\n\r\n        const ratingIconList = [];\r\n        const range = item.ratingRange || 6;\r\n\r\n        for (let i = 0; i < range; i++) {\r\n            const isCurrentIconInactive = i >= item.rating;\r\n\r\n            const iconClasses = classNames(`${baseClass}__rating-icon`, {\r\n                [`${baseClass}__rating-icon--is-inactive`]: isCurrentIconInactive\r\n            });\r\n\r\n            ratingIconList.push(<Icon iconId=\"24_star\" className={iconClasses} key={i} />);\r\n        }\r\n\r\n        return ratingIconList;\r\n    };\r\n\r\n    const showMoreMinHeight = 300;\r\n    const ratingSectionHeight = 74;\r\n\r\n    const showMoreMinHeightWithoutRatingSection = showMoreMinHeight + ratingSectionHeight;\r\n\r\n    return (\r\n        <div className={baseClass}>\r\n            <div className={`${baseClass}__content`}>\r\n                {item.source && (\r\n                    <div\r\n                        className={`${baseClass}__source`}\r\n                        dangerouslySetInnerHTML={{ __html: item.source }}\r\n                    />\r\n                )}\r\n                <div className={`${baseClass}__rating-section`}>\r\n                    {!!item.rating && (\r\n                        <>\r\n                            <div className={`${baseClass}__rating`}>{getVisualRatingIcons()}</div>\r\n                            {item.ratingLabel && (\r\n                                <div className={`${baseClass}__rating-label`}>{item.ratingLabel}</div>\r\n                            )}\r\n                        </>\r\n                    )}\r\n                </div>\r\n            </div>\r\n            <ShowMore\r\n                minHeight={!item.rating ? showMoreMinHeightWithoutRatingSection : showMoreMinHeight}\r\n                className={`${baseClass}__expand-btn`}\r\n                btnLabelShowLess={labels.showLess}\r\n                btnLabelShowMore={labels.showMore}\r\n            >\r\n                <div\r\n                    ref={reviewSectionRef}\r\n                    className={`${baseClass}__review-section`}\r\n                    dangerouslySetInnerHTML={{ __html: item.review ?? \"\" }}\r\n                />\r\n            </ShowMore>\r\n        </div>\r\n    );\r\n};\r\n\r\nexport default ProductReviewItem;\r\n","import * as React from \"react\";\r\nimport ProductReviewItem, {\r\n    ProductReviewItemProps\r\n} from \"~/components/product-review-slider/product-review-item/product-review-item\";\r\nimport SliderSwiper from \"~/components/swiper/slider-swiper\";\r\nimport { breakpoints } from \"~/utils/breakpoint-utils\";\r\nimport { Settings } from \"react-slick\";\r\nimport ContentSection from \"../content-section/content-section\";\r\n\r\nexport interface ProductReviewSliderProps {\r\n    headline: string;\r\n    showMore: string;\r\n    showLess: string;\r\n    productReviews: ProductReviewItemProps[\"item\"][];\r\n}\r\n\r\nconst ProductReviewSlider: React.FC<ProductReviewSliderProps> = ({\r\n    productReviews,\r\n    showMore,\r\n    showLess,\r\n    headline\r\n}) => {\r\n    const baseClass = \"product-review-slider\";\r\n    const swiperSettings: Settings = {\r\n        slidesToShow: 3,\r\n        swipeToSlide: true,\r\n        lazyLoad: \"ondemand\",\r\n        initialSlide: 0,\r\n        responsive: [\r\n            {\r\n                breakpoint: breakpoints.cat,\r\n                settings: {\r\n                    slidesToShow: 1\r\n                }\r\n            },\r\n            {\r\n                breakpoint: breakpoints.wolf,\r\n                settings: {\r\n                    slidesToShow: 2\r\n                }\r\n            }\r\n        ]\r\n    };\r\n\r\n    const labels = {\r\n        showMore,\r\n        showLess\r\n    };\r\n\r\n    return (\r\n        <ContentSection className={baseClass}>\r\n            <h2 className=\"text-align-center h1-style\">{headline}</h2>\r\n            <div className={`${baseClass}__inner`}>\r\n                {productReviews.length > 0 && (\r\n                    <SliderSwiper settings={swiperSettings} className=\"slider-swiper--hasPaddingBottom\">\r\n                        {productReviews.map((item, index) => (\r\n                            <ProductReviewItem key={index} item={item} labels={labels} />\r\n                        ))}\r\n                    </SliderSwiper>\r\n                )}\r\n            </div>\r\n        </ContentSection>\r\n    );\r\n};\r\n\r\nexport default ProductReviewSlider;\r\n","import * as React from \"react\";\r\nimport ProductTeaser, { IProductTeaserProps } from \"../product-teaser/product-teaser\";\r\nimport ProductReviewSlider, {\r\n    ProductReviewSliderProps\r\n} from \"../product-review-slider/product-review-slider\";\r\n\r\nexport type AuthorFeaturedProductProps = IProductTeaserProps & ProductReviewSliderProps;\r\n\r\nconst AuthorFeaturedProduct: React.FC<AuthorFeaturedProductProps> = props => {\r\n    return (\r\n        <div className=\"author-featured-product\">\r\n            <ProductTeaser {...props} />\r\n            {props.productReviews.length > 0 && <ProductReviewSlider {...props} />}\r\n        </div>\r\n    );\r\n};\r\n\r\nexport default AuthorFeaturedProduct;\r\n","import * as React from \"react\";\r\nimport AuthorFeaturedProduct, {\r\n    AuthorFeaturedProductProps\r\n} from \"~/components/author-featured-product/author-featured-product\";\r\n\r\nexport interface AuthorFeaturedProductViewProps {\r\n    contextModel: AuthorFeaturedProductProps;\r\n}\r\n\r\nclass AuthorFeaturedProductView extends React.Component<AuthorFeaturedProductViewProps> {\r\n    public render() {\r\n        return <AuthorFeaturedProduct {...this.props.contextModel} />;\r\n    }\r\n}\r\n\r\nexport default AuthorFeaturedProductView;\r\n","import * as React from \"react\";\r\nimport classNames from \"classnames\";\r\n\r\nexport type TIconNames =\r\n    | \"24_expand\"\r\n    | \"24_play\"\r\n    | \"24_star\"\r\n    | \"24_trash\"\r\n    | \"32_add-user\"\r\n    | \"32_basket\"\r\n    | \"32_checkmark-circle\"\r\n    | \"32_checkmark\"\r\n    | \"32_error\"\r\n    | \"32_information\"\r\n    | \"32_katalog\"\r\n    | \"32_search\"\r\n    | \"32_truck-in-motion\"\r\n    | \"32_user\"\r\n    | \"32_warning\"\r\n    | \"icon_16_arrow-down\"\r\n    | \"icon_16_arrow-left\"\r\n    | \"icon_16_arrow-right-bold\"\r\n    | \"icon_16_arrow-right\"\r\n    | \"icon_16_arrow-up\"\r\n    | \"icon_28_close\"\r\n    | \"icon_32_thumbs-up\"\r\n    | \"icon_80x41_quotation-mark-gyldendal-dk\"\r\n    | \"icon_80x48_quotation-mark\"\r\n    | \"icon_checkbox-black\"\r\n    | \"icon_checkmark-black\"\r\n    | \"icon_download\"\r\n    | \"icon_herringbone-narrow\"\r\n    | \"icon_herringbone-wide\"\r\n    | \"icon_placeholder-email\"\r\n    | \"icon_placeholder-lock\"\r\n    | \"icon_placeholder-phone-small\"\r\n    | \"icon_placeholder-vip-white\"\r\n    | \"icon_placeholder_basket\"\r\n    | \"icon_placeholder_checkmark\"\r\n    | \"icon_placeholder_eye-closed\"\r\n    | \"icon_placeholder_eye\"\r\n    | \"icon_placeholder_facebook\"\r\n    | \"icon_placeholder_filtering\"\r\n    | \"icon_placeholder_hamburger\"\r\n    | \"icon_placeholder_instagram\"\r\n    | \"icon_placeholder_phone\"\r\n    | \"icon_placeholder_user\"\r\n    | \"icon_read\"\r\n    | \"icon_listen\";\r\n\r\nexport interface IIconProps {\r\n    iconId: TIconNames;\r\n    spriteUrl?: string;\r\n    viewBox?: string;\r\n    className?: string;\r\n    onClick?: () => void;\r\n}\r\n\r\nconst Icon: React.FC<IIconProps> = props => {\r\n    const spriteUrl = props.spriteUrl || \"\";\r\n    const viewBox = props.viewBox || \"0 0 32 32\";\r\n\r\n    return (\r\n        <svg\r\n            viewBox={viewBox}\r\n            className={classNames(props.className, \"icon\", `icon-${props.iconId}`)}\r\n            preserveAspectRatio=\"xMidYMid\"\r\n            onClick={() => props.onClick && props.onClick()}\r\n        >\r\n            <use xmlnsXlink=\"http://www.w3.org/1999/xlink\" xlinkHref={`${spriteUrl}#${props.iconId}`} />\r\n        </svg>\r\n    );\r\n};\r\n\r\nexport default Icon;\r\n","import * as React from \"react\";\r\n\r\nexport interface AnchorProps {\r\n    id?: string;\r\n}\r\n\r\nconst Anchor = ({ id }: AnchorProps) => {\r\n    return <div className=\"anchor\" id={id} />;\r\n};\r\n\r\nexport default Anchor;\r\n","import classNames from \"classnames\";\r\nimport * as React from \"react\";\r\nimport Anchor from \"../anchor/anchor\";\r\n\r\nexport interface ContentSectionProps {\r\n    className?: string;\r\n    type?: \"default\" | \"full\";\r\n    anchorId?: string;\r\n    hasNoMarginTop?: boolean;\r\n    hasNoMarginBottom?: boolean;\r\n}\r\n\r\nconst ContentSection: React.FC<ContentSectionProps> = ({\r\n    className,\r\n    type = \"default\",\r\n    anchorId,\r\n    hasNoMarginTop,\r\n    hasNoMarginBottom,\r\n    ...props\r\n}) => {\r\n    const baseClass = \"content-section\";\r\n    const componentClasses = classNames(baseClass, className, {\r\n        [`${baseClass}--full`]: type === \"full\",\r\n        \"anchor-wrapper\": !!anchorId,\r\n        \"content-no-margin-top\": hasNoMarginTop,\r\n        \"content-no-margin-bottom\": hasNoMarginBottom\r\n    });\r\n    return (\r\n        <section className={componentClasses}>\r\n            {anchorId && <Anchor id={anchorId} />}\r\n            {props.children}\r\n        </section>\r\n    );\r\n};\r\n\r\nexport default ContentSection;\r\n","import * as React from \"react\";\r\nimport classNames from \"classnames\";\r\n\r\nexport interface ICtaButtonProps {\r\n    className?: string;\r\n    isLarge?: boolean;\r\n    isInverted?: boolean;\r\n    isSecondary?: boolean;\r\n    link: string;\r\n    onClick?(): void;\r\n}\r\n\r\nconst CtaButton = ({ className, isLarge, isInverted, isSecondary, link, onClick }: ICtaButtonProps) => {\r\n    const baseClass = \"cta-button\";\r\n    const componentClasses = classNames(className, baseClass, {\r\n        [`${baseClass}--large`]: isLarge,\r\n        [`${baseClass}--inverted`]: isInverted,\r\n        [`${baseClass}--secondary`]: isSecondary\r\n    });\r\n\r\n    return <div onClick={onClick} className={componentClasses} dangerouslySetInnerHTML={{ __html: link }} />;\r\n};\r\n\r\nexport default CtaButton;\r\n","interface IBreakpoints {\r\n    [key: string]: number;\r\n}\r\n\r\ninterface IMediaQueryStrings {\r\n    [key: string]: string;\r\n}\r\n\r\nexport type IMatchingQueries = { [key in Breakpoints]?: boolean };\r\n\r\nexport type Breakpoints =\r\n    | \"ratMin\"\r\n    | \"ratMax\"\r\n    | \"rabbitMin\"\r\n    | \"rabbitMax\"\r\n    | \"catMin\"\r\n    | \"catMax\"\r\n    | \"dogMin\"\r\n    | \"dogMax\"\r\n    | \"wolfMin\"\r\n    | \"wolfMax\"\r\n    | \"lionMin\"\r\n    | \"horseMin\"\r\n    | \"horseMax\"\r\n    | \"rhinoMin\"\r\n    | \"rhinoMax\"\r\n    | \"elephantMin\"\r\n    | \"elephantMax\";\r\n\r\nexport const breakpoints: IBreakpoints = {\r\n    rat: 360,\r\n    rabbit: 480,\r\n    cat: 640,\r\n    dog: 768,\r\n    wolf: 1024,\r\n    lion: 1100,\r\n    horse: 1400,\r\n    rhino: 1520,\r\n    elephant: 1670\r\n};\r\n\r\nconst mediaQueries: IMediaQueryStrings = Object.keys(breakpoints).reduce(\r\n    (queryStrings: IMediaQueryStrings, key) => {\r\n        queryStrings[`${key}Min`] = `(min-width: ${breakpoints[key]}px)`;\r\n        queryStrings[`${key}Max`] = `(max-width: ${breakpoints[key] - 1}px)`;\r\n        return queryStrings;\r\n    },\r\n    {}\r\n);\r\n\r\nconst setupMediaQueryListeners = () => {\r\n    Object.keys(mediaQueries).forEach((key: string) => {\r\n        const mediaQuery = matchMedia(mediaQueries[key]);\r\n\r\n        handleMediaMatch(mediaQuery.matches, key as Breakpoints); // Initial values\r\n        mediaQuery.addListener(event => handleMediaMatch(event.matches, key as Breakpoints));\r\n    });\r\n};\r\n\r\nconst currentMediaQueries: IMatchingQueries = {};\r\nconst handleMediaMatch = (isMatching: boolean, key: Breakpoints) => (currentMediaQueries[key] = isMatching);\r\n\r\nif (!__SERVER__) {\r\n    setupMediaQueryListeners();\r\n}\r\n\r\nexport { currentMediaQueries };\r\n","import * as React from \"react\";\r\nimport classNames from \"classnames\";\r\nimport { ProductStatus } from \"~/types/product\";\r\n\r\nexport interface ITagProps {\r\n    type?: ProductStatus;\r\n    children: React.ReactNode;\r\n    className?: string;\r\n    shape?: \"pill\" | \"square\";\r\n}\r\n\r\nexport const tagTypeClassMap: { [key in ProductStatus]: string } = {\r\n    NEWS: \"news\",\r\n    SPOT: \"spot\",\r\n    BESTSELLER: \"bestseller\",\r\n    BOOK_OF_THE_MONTH: \"botm\",\r\n    UPCOMING: \"upcoming\"\r\n};\r\n\r\nconst Tag: React.FC<ITagProps> = props => {\r\n    const classModifier = props.type && tagTypeClassMap[props.type];\r\n    const rootClasses = classNames(\"tag\", props.className, `tag--shape-${props.shape || \"pill\"}`, {\r\n        [`tag--${classModifier}`]: props.type\r\n    });\r\n\r\n    return (\r\n        <div className={rootClasses}>\r\n            <span className=\"tag__label\">{props.children}</span>\r\n        </div>\r\n    );\r\n};\r\n\r\nexport default Tag;\r\n","import { MembershipType } from \"~/types/membership\";\r\nimport { IBasketProduct, IProduct } from \"~/types/product\";\r\n// import { IBasketSummationProps } from \"~/components/basket-summation/basket-summation\";\r\nimport { IProductTileProps } from \"~/components/product-tile/product-tile\";\r\n\r\nenum EventTypes {\r\n    SIGNUP = \"eec.signup\",\r\n    PURCHASE = \"eec.purchase\",\r\n    CHECKOUT = \"eec.checkout\",\r\n    ADD_TO_BASKET = \"eec.add\",\r\n    REMOVE_FROM_BASKET = \"eec.remove\",\r\n    CLICK = \"eec.impressionClick\",\r\n    DETAIL_VIEW = \"eec.detail\",\r\n    IMPRESSION_VIEW = \"eec.impressionView\",\r\n    PROMO_VIEW = \"eec.promotionView\",\r\n    PROMO_CLICK = \"eec.promotionClick\",\r\n    VOUCHER = \"eec.voucher\"\r\n}\r\n\r\nenum CurrencyCodes {\r\n    DKK = \"DKK\"\r\n}\r\n\r\nenum TrackingDimensions {\r\n    CAMPAIGN_ID = \"dimension2\",\r\n    MEMBERSHIP_TYPE = \"dimension3\",\r\n    PAYMENT_PERIOD = \"dimension4\",\r\n    DISCOUNT_SPLASH = \"dimension5\"\r\n}\r\n\r\ninterface ITrackingProduct {\r\n    name?: string;\r\n    id?: string;\r\n    price?: number;\r\n    quantity?: number;\r\n    [TrackingDimensions.MEMBERSHIP_TYPE]?: MembershipType | string;\r\n    [TrackingDimensions.PAYMENT_PERIOD]?: string;\r\n    [TrackingDimensions.DISCOUNT_SPLASH]?: string;\r\n}\r\n\r\ninterface IProductImpression extends ITrackingProduct {\r\n    list?: string;\r\n    position: number | undefined;\r\n}\r\n\r\ninterface ICheckoutActionField {\r\n    step: string;\r\n    [TrackingDimensions.CAMPAIGN_ID]?: string;\r\n    option?: string;\r\n    coupon?: string;\r\n}\r\n\r\ninterface IEcommerceTrackingEvent<T> {\r\n    event: EventTypes;\r\n    ecommerce: T & { currencyCode?: CurrencyCodes };\r\n}\r\n\r\ninterface ITrackingEvent {\r\n    event: \"trackEvent\";\r\n    eventData: {\r\n        category: string;\r\n        action: string;\r\n        label: string;\r\n    };\r\n}\r\n\r\nconst mapProductsToTrackingProducts = (\r\n    { title, primaryPriceNumber, productId, quantityNumber, discounts }: IBasketProduct,\r\n    membershipType?: MembershipType,\r\n    paymentPeriod?: string\r\n): ITrackingProduct => {\r\n    const product: ITrackingProduct = {\r\n        name: title,\r\n        price: primaryPriceNumber,\r\n        quantity: quantityNumber || 1,\r\n        [TrackingDimensions.MEMBERSHIP_TYPE]: membershipType || \"\",\r\n        [TrackingDimensions.PAYMENT_PERIOD]: paymentPeriod || \"\",\r\n        [TrackingDimensions.DISCOUNT_SPLASH]: discounts?.map(discount => discount.label).join(\" | \") || \"\"\r\n    };\r\n\r\n    if (productId) {\r\n        product.id = productId;\r\n    }\r\n\r\n    return product;\r\n};\r\n\r\nexport interface ISignupTrackingParams {\r\n    campaignId?: string;\r\n    membershipType?: MembershipType;\r\n    currentStepIndex: number;\r\n    paymentPeriod?: string;\r\n    miniBasketProducts?: IBasketProduct[];\r\n}\r\n\r\ninterface ISignupTrackingEvent\r\n    extends IEcommerceTrackingEvent<{\r\n        checkout: {\r\n            actionField: ICheckoutActionField;\r\n            products: ITrackingProduct[];\r\n        };\r\n    }> {}\r\n\r\nconst generateSignupTrackingEvent = ({\r\n    membershipType,\r\n    campaignId,\r\n    miniBasketProducts,\r\n    currentStepIndex,\r\n    paymentPeriod\r\n}: ISignupTrackingParams): ISignupTrackingEvent => {\r\n    const actionField: ICheckoutActionField = {\r\n        step: (currentStepIndex + 1).toString(),\r\n        option: currentStepIndex > 0 ? paymentPeriod : \"\"\r\n    };\r\n\r\n    actionField[TrackingDimensions.CAMPAIGN_ID] = campaignId || \"\";\r\n\r\n    const products: ITrackingProduct[] = miniBasketProducts\r\n        ? miniBasketProducts.map(product =>\r\n              mapProductsToTrackingProducts(product, membershipType, paymentPeriod)\r\n          )\r\n        : [];\r\n\r\n    const signupTrackingEvent = {\r\n        event: EventTypes.SIGNUP,\r\n        ecommerce: {\r\n            checkout: {\r\n                actionField,\r\n                products\r\n            }\r\n        }\r\n    };\r\n\r\n    return signupTrackingEvent;\r\n};\r\n\r\ninterface ICheckoutTrackingParams {\r\n    products?: IBasketProduct[];\r\n    paymentMethod?: string;\r\n    step: number;\r\n}\r\n\r\ninterface ICheckoutTrackingEvent\r\n    extends IEcommerceTrackingEvent<{\r\n        checkout: {\r\n            actionField: ICheckoutActionField;\r\n            products: ITrackingProduct[];\r\n        };\r\n    }> {}\r\n\r\nconst generateCheckoutTrackingEvent = ({\r\n    products,\r\n    step,\r\n    paymentMethod\r\n}: ICheckoutTrackingParams): ICheckoutTrackingEvent => {\r\n    const actionField: ICheckoutActionField = {\r\n        step: `${step}`\r\n    };\r\n\r\n    if (paymentMethod) {\r\n        actionField.option = paymentMethod;\r\n    }\r\n\r\n    const mappedProducts: ITrackingProduct[] = products\r\n        ? products.map(product => mapProductsToTrackingProducts(product))\r\n        : [];\r\n\r\n    return {\r\n        event: EventTypes.CHECKOUT,\r\n        ecommerce: {\r\n            checkout: {\r\n                actionField,\r\n                products: mappedProducts\r\n            }\r\n        }\r\n    };\r\n};\r\n\r\ninterface IPurchaseTrackingParams {\r\n    membershipType?: MembershipType;\r\n    miniBasketProducts?: IBasketProduct[];\r\n    // miniBasketSummation?: IBasketSummationProps;\r\n    orderId?: string;\r\n    campaignId?: string;\r\n}\r\n\r\ninterface IPurchaseActionField {\r\n    [TrackingDimensions.CAMPAIGN_ID]?: string;\r\n    coupon?: string;\r\n    revenue?: number;\r\n    shipping?: number;\r\n    tax?: number;\r\n    id?: string;\r\n}\r\n\r\ninterface IPurchaseTrackingEvent\r\n    extends IEcommerceTrackingEvent<{\r\n        purchase: {\r\n            actionField: IPurchaseActionField;\r\n            products: ITrackingProduct[];\r\n        };\r\n    }> {}\r\n\r\nconst generatePurchaseTrackingEvent = ({\r\n    membershipType,\r\n    miniBasketProducts,\r\n    // miniBasketSummation,\r\n    orderId,\r\n    campaignId\r\n}: IPurchaseTrackingParams): IPurchaseTrackingEvent => {\r\n    const actionField: IPurchaseActionField = {};\r\n\r\n    if (orderId) {\r\n        actionField.id = orderId;\r\n    }\r\n\r\n    actionField[TrackingDimensions.CAMPAIGN_ID] = campaignId || \"\";\r\n\r\n    // if (miniBasketSummation) {\r\n    //     actionField.tax = miniBasketSummation.vatNumber;\r\n    //     actionField.revenue = miniBasketSummation.totalPriceNumber;\r\n\r\n    //     if (miniBasketSummation.shippingFee) {\r\n    //         actionField.shipping = miniBasketSummation.shippingFeeNumber;\r\n    //     }\r\n    //     if (miniBasketSummation.voucherDiscount) {\r\n    //         actionField.coupon = miniBasketSummation.voucherDiscount;\r\n    //     }\r\n    // }\r\n\r\n    const products: ITrackingProduct[] = miniBasketProducts\r\n        ? miniBasketProducts.map(product => mapProductsToTrackingProducts(product, membershipType))\r\n        : [];\r\n\r\n    const purchaseTrackingEvent = {\r\n        event: EventTypes.PURCHASE,\r\n        ecommerce: {\r\n            currencyCode: CurrencyCodes.DKK,\r\n            purchase: {\r\n                actionField,\r\n                products\r\n            }\r\n        }\r\n    };\r\n\r\n    return purchaseTrackingEvent;\r\n};\r\n\r\ninterface IClickActionField {\r\n    list: string;\r\n}\r\n\r\ninterface IClickTrackingParams\r\n    extends Pick<IProductTileProps, \"trackingList\" | \"trackingPosition\" | \"productId\" | \"title\"> {}\r\n\r\ninterface IClickTrackingEvent\r\n    extends IEcommerceTrackingEvent<{\r\n        click: {\r\n            actionField: IClickActionField;\r\n            products: IProductImpression[];\r\n        };\r\n    }> {}\r\n\r\nconst generateClickTrackingEvent = ({\r\n    trackingList,\r\n    trackingPosition,\r\n    productId,\r\n    title\r\n}: IClickTrackingParams): IClickTrackingEvent => {\r\n    return {\r\n        event: EventTypes.CLICK,\r\n        ecommerce: {\r\n            click: {\r\n                actionField: {\r\n                    list: trackingList\r\n                },\r\n                products: [\r\n                    {\r\n                        id: productId,\r\n                        name: title,\r\n                        position: trackingPosition\r\n                    }\r\n                ]\r\n            }\r\n        }\r\n    };\r\n};\r\n\r\ninterface IDetailActionField {\r\n    list: string;\r\n}\r\n\r\ninterface IDetailViewTrackingParams extends Pick<IProduct, \"title\" | \"productId\"> {\r\n    trackingList: string;\r\n}\r\n\r\ninterface IDetailViewTrackingEvent\r\n    extends IEcommerceTrackingEvent<{\r\n        detail: {\r\n            actionField: IDetailActionField;\r\n            products: ITrackingProduct[];\r\n        };\r\n    }> {}\r\n\r\nconst generateDetailViewTrackingEvent = ({\r\n    title,\r\n    productId,\r\n    trackingList\r\n}: IDetailViewTrackingParams): IDetailViewTrackingEvent => {\r\n    return {\r\n        event: EventTypes.DETAIL_VIEW,\r\n        ecommerce: {\r\n            detail: {\r\n                actionField: {\r\n                    list: trackingList\r\n                },\r\n                products: [\r\n                    {\r\n                        id: productId,\r\n                        name: title\r\n                    }\r\n                ]\r\n            }\r\n        }\r\n    };\r\n};\r\n\r\ninterface IBasketTrackingParams {\r\n    products?: IBasketProduct[];\r\n    trackingList: string;\r\n}\r\n\r\ninterface IAddToBasketTrackingEvent\r\n    extends IEcommerceTrackingEvent<{\r\n        add: {\r\n            actionField: { list: string };\r\n            products: ITrackingProduct[] | undefined;\r\n        };\r\n    }> {}\r\n\r\nconst generateAddToBasketTrackingEvent = ({\r\n    products,\r\n    trackingList\r\n}: IBasketTrackingParams): IAddToBasketTrackingEvent => {\r\n    const basketProducts = products && products.map(product => mapProductsToTrackingProducts(product));\r\n\r\n    return {\r\n        event: EventTypes.ADD_TO_BASKET,\r\n        ecommerce: {\r\n            add: {\r\n                actionField: { list: trackingList },\r\n                products: basketProducts\r\n            }\r\n        }\r\n    };\r\n};\r\n\r\ninterface IRemoveFromBasketTrackingEvent\r\n    extends IEcommerceTrackingEvent<{\r\n        remove: {\r\n            actionField: { list: string };\r\n            products: ITrackingProduct[] | undefined;\r\n        };\r\n    }> {}\r\n\r\nconst generateRemoveFromBasketTrackingEvent = ({\r\n    products,\r\n    trackingList\r\n}: IBasketTrackingParams): IRemoveFromBasketTrackingEvent => {\r\n    const basketProducts = products && products.map(product => mapProductsToTrackingProducts(product));\r\n\r\n    return {\r\n        event: EventTypes.REMOVE_FROM_BASKET,\r\n        ecommerce: {\r\n            remove: {\r\n                actionField: { list: trackingList },\r\n                products: basketProducts\r\n            }\r\n        }\r\n    };\r\n};\r\n\r\ninterface IVoucherTrackingParams {\r\n    // summation?: IBasketSummationProps;\r\n    caller: string;\r\n    action: string;\r\n}\r\ninterface IVoucherTrackingEvent\r\n    extends IEcommerceTrackingEvent<{\r\n        // summation?: IBasketSummationProps;\r\n        caller: string;\r\n        action: string;\r\n    }> {}\r\n\r\nconst generateVoucherTrackingEvent = (props: IVoucherTrackingParams): IVoucherTrackingEvent => {\r\n    return {\r\n        event: EventTypes.VOUCHER,\r\n        ecommerce: {\r\n            // summation: props.summation,\r\n            caller: props.caller,\r\n            action: props.action\r\n        }\r\n    };\r\n};\r\n\r\ninterface IImpressionViewTrackingParams\r\n    extends Required<Pick<IProductTileProps, \"trackingList\" | \"trackingPosition\" | \"productId\" | \"title\">> {}\r\n\r\ninterface IImpressionViewTrackingEvent\r\n    extends IEcommerceTrackingEvent<{\r\n        impressions: IProductImpression[];\r\n    }> {}\r\n\r\nconst generateImpressionViewTrackingEvent = (\r\n    products: IImpressionViewTrackingParams[]\r\n): IImpressionViewTrackingEvent => {\r\n    return {\r\n        event: EventTypes.IMPRESSION_VIEW,\r\n        ecommerce: {\r\n            impressions: products.map(product => {\r\n                return {\r\n                    list: product.trackingList,\r\n                    position: product.trackingPosition,\r\n                    id: product.productId,\r\n                    name: product.title\r\n                };\r\n            })\r\n        }\r\n    };\r\n};\r\n\r\ninterface IPromoViewTrackingEvent\r\n    extends IEcommerceTrackingEvent<{\r\n        promoView: {\r\n            promotions: Array<{\r\n                id: string;\r\n                name: string;\r\n                creative: string;\r\n                position: string;\r\n            }>;\r\n        };\r\n    }> {}\r\n\r\nconst generatePromoViewTrackingEvent = (): IPromoViewTrackingEvent => {\r\n    return {\r\n        event: EventTypes.PROMO_VIEW,\r\n        ecommerce: {\r\n            promoView: {\r\n                promotions: [\r\n                    {\r\n                        id: \"\",\r\n                        name: \"Splash\",\r\n                        creative: \"\",\r\n                        position: \"\"\r\n                    }\r\n                ]\r\n            }\r\n        }\r\n    };\r\n};\r\n\r\ninterface IPromoClickTrackingEvent\r\n    extends IEcommerceTrackingEvent<{\r\n        promoClick: {\r\n            promotions: Array<{\r\n                id: string;\r\n                name: string;\r\n                creative: string;\r\n                position: string;\r\n            }>;\r\n        };\r\n    }> {}\r\n\r\nconst generatePromoClickTrackingEvent = (): IPromoClickTrackingEvent => {\r\n    return {\r\n        event: EventTypes.PROMO_CLICK,\r\n        ecommerce: {\r\n            promoClick: {\r\n                promotions: [\r\n                    {\r\n                        id: \"\",\r\n                        name: \"Splash\",\r\n                        creative: \"\",\r\n                        position: \"\"\r\n                    }\r\n                ]\r\n            }\r\n        }\r\n    };\r\n};\r\n\r\nconst ensureDataLayer = () => {\r\n    if (typeof window === \"undefined\") {\r\n        return false;\r\n    }\r\n\r\n    window.dataLayer = window.dataLayer || [];\r\n    return true;\r\n};\r\n\r\nconst pushEcommerenceTrackingEvent = (trackingEvent: IEcommerceTrackingEvent<unknown>) => {\r\n    if (ensureDataLayer()) window.dataLayer.push(trackingEvent);\r\n};\r\n\r\nexport const pushTrackingEvent = (trackingEvent: ITrackingEvent) => {\r\n    if (ensureDataLayer()) window.dataLayer.push(trackingEvent);\r\n};\r\n\r\nexport const pushAddToBasketTrackingEvent = (props: IBasketTrackingParams) =>\r\n    pushEcommerenceTrackingEvent(generateAddToBasketTrackingEvent(props));\r\n\r\nexport const pushRemoveFromBasketTrackingEvent = (props: IBasketTrackingParams) =>\r\n    pushEcommerenceTrackingEvent(generateRemoveFromBasketTrackingEvent(props));\r\n\r\nexport const pushSignupTrackingEvent = (props: ISignupTrackingParams) =>\r\n    pushEcommerenceTrackingEvent(generateSignupTrackingEvent(props));\r\n\r\nexport const pushCheckoutTrackingEvent = (props: ICheckoutTrackingParams) =>\r\n    pushEcommerenceTrackingEvent(generateCheckoutTrackingEvent(props));\r\n\r\nexport const pushPurchaseTrackingEvent = (props: IPurchaseTrackingParams) =>\r\n    pushEcommerenceTrackingEvent(generatePurchaseTrackingEvent(props));\r\n\r\nexport const pushClickTrackingEvent = (props: IClickTrackingParams) =>\r\n    pushEcommerenceTrackingEvent(generateClickTrackingEvent(props));\r\n\r\nexport const pushDetailViewTrackingEvent = (props: IDetailViewTrackingParams) =>\r\n    pushEcommerenceTrackingEvent(generateDetailViewTrackingEvent(props));\r\n\r\nexport const pushImpressionViewTrackingEvent = (props: IImpressionViewTrackingParams[]) =>\r\n    pushEcommerenceTrackingEvent(generateImpressionViewTrackingEvent(props));\r\n\r\nexport const pushPromoViewTrackingEvent = () =>\r\n    pushEcommerenceTrackingEvent(generatePromoViewTrackingEvent());\r\n\r\nexport const pushPromoClickTrackingEvent = () =>\r\n    pushEcommerenceTrackingEvent(generatePromoClickTrackingEvent());\r\n\r\nexport const pushVoucherTrackingEvent = (props: IVoucherTrackingParams) =>\r\n    pushEcommerenceTrackingEvent(generateVoucherTrackingEvent(props));\r\n","import * as React from \"react\";\r\n\r\nexport interface ProductImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, \"src\" | \"srcSet\"> {\r\n    className?: string;\r\n    fallbackSrc?: string;\r\n    srcSet: string;\r\n    sizes?: string;\r\n    loading?: React.ImgHTMLAttributes<HTMLImageElement>[\"loading\"];\r\n    ref?: React.Ref<HTMLImageElement>;\r\n    width?: string | number;\r\n    height?: string | number;\r\n}\r\n\r\nconst ProductImage: React.FC<ProductImageProps> = React.forwardRef(\r\n    ({ fallbackSrc, loading = \"lazy\", ...props }, ref) => {\r\n        return <img ref={ref} src={fallbackSrc} loading={loading} {...props} />;\r\n    }\r\n);\r\n\r\nexport default ProductImage;\r\n","import * as React from \"react\";\r\nimport { IProductAuthor } from \"~/types/product\";\r\nimport TruncateMarkup from \"react-truncate-markup\";\r\nimport classNames from \"classnames\";\r\n\r\ninterface IProductAuthorProps {\r\n    authors?: IProductAuthor[];\r\n    maxLines?: number;\r\n    className?: string;\r\n}\r\n\r\nconst ProductAuthors: React.FC<IProductAuthorProps> = ({ authors, className, maxLines }) => {\r\n    if (!authors?.length) {\r\n        return null;\r\n    }\r\n\r\n    const baseClass = \"product-authors\";\r\n    const classes = classNames(baseClass, className);\r\n\r\n    const Wrapper: React.FC = ({ children }) =>\r\n        maxLines ? (\r\n            <TruncateMarkup lines={maxLines}>{children}</TruncateMarkup>\r\n        ) : (\r\n            <React.Fragment>{children}</React.Fragment>\r\n        );\r\n\r\n    return (\r\n        <Wrapper>\r\n            <ul className={classes}>\r\n                {authors.map((author, index) => {\r\n                    return (\r\n                        <li key={index} className={`${baseClass}__item`}>\r\n                            {author.url ? (\r\n                                <a href={author.url} title={author.name}>\r\n                                    {author.name}\r\n                                </a>\r\n                            ) : (\r\n                                <span>{author.name}</span>\r\n                            )}\r\n                        </li>\r\n                    );\r\n                })}\r\n            </ul>\r\n        </Wrapper>\r\n    );\r\n};\r\n\r\nexport default ProductAuthors;\r\n","import * as React from \"react\";\r\nimport Icon, { TIconNames } from \"~/components/icons/icon\";\r\nimport classNames from \"classnames\";\r\n\r\ninterface ISwiperButtonProps {\r\n    className?: string;\r\n    direction: \"LEFT\" | \"RIGHT\";\r\n    onClick?: () => void;\r\n}\r\n\r\nconst SwiperButton: React.SFC<ISwiperButtonProps> = ({ className, direction, onClick }) => {\r\n    const baseClass = \"swiper-button\";\r\n    const classes = classNames(baseClass, className, {\r\n        [`${baseClass}--right`]: direction === \"RIGHT\",\r\n        [`${baseClass}--left`]: direction === \"LEFT\"\r\n    });\r\n    const iconId: TIconNames = direction === \"RIGHT\" ? \"icon_16_arrow-right\" : \"icon_16_arrow-left\";\r\n\r\n    return (\r\n        <button tabIndex={0} className={classes} onClick={onClick}>\r\n            <Icon className=\"swiper-button__icon\" iconId={iconId} />\r\n        </button>\r\n    );\r\n};\r\n\r\nexport default SwiperButton;\r\n","import * as React from \"react\";\r\nimport classNames from \"classnames\";\r\nimport AnimateHeight from \"react-animate-height\";\r\nimport { currentMediaQueries, Breakpoints } from \"~/utils/breakpoint-utils\";\r\n\r\nexport interface IShowMoreProps {\r\n    minHeight: number;\r\n    btnLabelShowMore?: string;\r\n    btnLabelShowLess?: string;\r\n    className?: string;\r\n    disableOnBreakpoint?: Breakpoints;\r\n}\r\ninterface IShowMoreState {\r\n    showMoreHasOverflow: boolean;\r\n    showMoreIsOpen: boolean;\r\n}\r\n\r\nclass ShowMore extends React.Component<IShowMoreProps, IShowMoreState> {\r\n    private childrenWrapper: HTMLDivElement | null;\r\n\r\n    public state = {\r\n        showMoreHasOverflow: true,\r\n        showMoreIsOpen: false\r\n    };\r\n\r\n    public componentDidMount() {\r\n        window.addEventListener(\"resize\", this.handleResize.bind(this));\r\n        this.handleResize();\r\n    }\r\n\r\n    public componentWillUnmount() {\r\n        window.removeEventListener(\"resize\", this.handleResize.bind(this));\r\n    }\r\n\r\n    public handleResize() {\r\n        const { disableOnBreakpoint, minHeight } = this.props;\r\n        const disableOverflow = disableOnBreakpoint && currentMediaQueries[disableOnBreakpoint];\r\n        const hasOverflow = this.childrenWrapper && this.childrenWrapper.clientHeight > minHeight;\r\n\r\n        if (!disableOverflow && hasOverflow) {\r\n            this.setState({ showMoreHasOverflow: true });\r\n        } else {\r\n            this.setState({ showMoreHasOverflow: false });\r\n        }\r\n    }\r\n\r\n    private toggleMore() {\r\n        this.setState({ showMoreIsOpen: !this.state.showMoreIsOpen });\r\n    }\r\n\r\n    public render() {\r\n        const { className, minHeight, btnLabelShowLess, btnLabelShowMore, children } = this.props;\r\n        const baseClass = \"show-more\";\r\n        const containerClasses = classNames(className, baseClass, {\r\n            [`${baseClass}--hasOverflow`]: this.state.showMoreHasOverflow,\r\n            [`${baseClass}--isClosed`]: this.state.showMoreHasOverflow && !this.state.showMoreIsOpen\r\n        });\r\n        const setAnimateToMinHeight = this.state.showMoreHasOverflow && !this.state.showMoreIsOpen;\r\n        const btnText = this.state.showMoreIsOpen ? btnLabelShowLess : btnLabelShowMore;\r\n\r\n        return (\r\n            <div className={containerClasses}>\r\n                <AnimateHeight height={setAnimateToMinHeight ? minHeight : \"auto\"} duration={300}>\r\n                    <div ref={node => (this.childrenWrapper = node)}>{children}</div>\r\n                </AnimateHeight>\r\n\r\n                <button className=\"show-more-button\" onClick={() => this.toggleMore()}>\r\n                    {btnText}\r\n                </button>\r\n            </div>\r\n        );\r\n    }\r\n}\r\n\r\nexport default ShowMore;\r\n","import * as React from \"react\";\r\nimport Slider, { Settings } from \"react-slick\";\r\nimport SwiperButton from \"~/components/swiper/swiper-button\";\r\nimport classNames from \"classnames\";\r\n\r\ninterface ISliderSwiperProps {\r\n    settings: Settings;\r\n    className?: string;\r\n    buttonClassName?: string;\r\n}\r\n\r\nconst SliderSwiper: React.FC<ISliderSwiperProps> = props => {\r\n    const buttonBaseClass = \"custom-slick-arrow\";\r\n    const buttonClasses = classNames(buttonBaseClass, props.buttonClassName);\r\n\r\n    return (\r\n        <div className=\"slider-swiper slider-swiper--hasPaddingBottom\">\r\n            <Slider\r\n                nextArrow={<SwiperButton className={buttonClasses} direction=\"RIGHT\" />}\r\n                prevArrow={<SwiperButton className={buttonClasses} direction=\"LEFT\" />}\r\n                draggable\r\n                infinite={false}\r\n                speed={300}\r\n                {...props.settings}\r\n            >\r\n                {props.children}\r\n            </Slider>\r\n        </div>\r\n    );\r\n};\r\n\r\nexport default SliderSwiper;\r\n"],"sourceRoot":""}