{"version":3,"file":"index.es.min.js","sources":["../../../packages/helpers/src/props.helpers.js","../../../packages/helpers/src/utils.ts","../../../packages/helpers/src/assets/js/eventDispatch.js","../../../packages/components/src/constants.mjs","../../../packages/page-builder-sections/src/content-composer/helpers/tracking.js","../../../packages/page-builder-sections/src/content-composer/helpers/renderButtons.js","../../../packages/helpers/src/viewport.helpers.ts","../../../packages/page-builder-sections/src/content-composer/helpers/getImage.js","../../../packages/page-builder-sections/src/content-composer/subcomponents/card.class.js","../../../packages/helpers/src/getCurrency.js","../../../packages/helpers/src/catalog.js","../../../packages/helpers/src/events.helpers.ts","../../../packages/helpers/src/gtmEvents.js","../../../packages/helpers/src/dataLayer.js","../../../packages/helpers/src/cremaDataHelper.js","../../../packages/components/src/sku-coffee/services/index.js","../../../packages/page-builder-sections/src/cross-sell-natural/dataTransform/product.coffee.dto.js","../../../services/plp/services.js","../../../packages/components/src/sku/services/index.js","../../../packages/page-builder-sections/src/content-composer/subcomponents/index.js","../../../packages/page-builder-sections/src/content-composer/subcomponents/video-card/video-card.composer.js","../../../packages/page-builder-sections/src/content-composer/subcomponents/image-card/image-card.composer.js","../../../packages/page-builder-sections/src/content-composer/subcomponents/product-card/product-card.composer.js","../../../packages/page-builder-sections/src/content-composer/subcomponents/product-sku/product-sku.composer.js","../../../packages/page-builder-sections/src/cross-sell-natural/dataTransform/product.dto.js","../../../packages/components/src/sku/constants.mjs","../../../packages/page-builder-sections/src/cross-sell-natural/dataTransform/product.machine.dto.js","../../../packages/page-builder-sections/src/cross-sell-natural/dataTransform/product.accessory.dto.js","../../../packages/page-builder-sections/src/cross-sell-natural/dataTransform/product.giftCard.dto.js","../../../packages/page-builder-sections/src/content-composer/subcomponents/text-card/text-card.composer.js","../../../packages/page-builder-sections/src/content-composer/helpers/columnsSizes.js","../../../packages/helpers/src/swipeEvents.ts","../../../packages/helpers/src/assets/js/scopedKeyboardNav.js","../../../packages/components/src/popin/components/overlay.js","../../../packages/components/src/popin/popin.js","../../../packages/page-builder-sections/src/content-composer/content-composer.js"],"sourcesContent":["const getData = attributes => attributes.find(attribute => attribute.nodeName === 'data')\n\nconst createProps = attributes => {\n    const data = getData([...attributes])\n    const props = [...attributes]\n        .filter(attribute => attribute.nodeName !== 'data')\n        .reduce((all, attr) => {\n            return { ...all, [attr.nodeName]: attr.nodeValue }\n        }, {})\n\n    if (isNil(data)) {\n        return props\n    }\n\n    try {\n        return { ...props, ...JSON.parse(data.nodeValue) }\n    } catch (error) {\n        console.log('ERROR: No data', error, data?.nodeValue)\n    }\n}\n\nconst isNil = obj => obj === undefined || obj === null\n\nexport const parseBool = value => (!value || value === 'false' ? false : true)\n\nexport default createProps\n","export { waitForSelector } from './waitForSelector'\n\nexport const constants = {\n    LEFT: 37,\n    UP: 38,\n    RIGHT: 39,\n    DOWN: 40,\n    ESC: 27,\n    SPACE: 32,\n    ENTER: 13,\n    TAB: 9\n}\n\nexport function capitalize(s = '') {\n    return s[0].toUpperCase() + s.slice(1)\n}\n\nexport const convertToCamelCase = (str: string): string => {\n    const arr = str.match(/[a-z]+|\\d+/gi)\n    if (!arr) { return str }\n    return arr.map((m, i) => {\n        let low = m.toLowerCase()\n        if (i !== 0) {\n            low = low.split('').map((s, k) => (k === 0 ? s.toUpperCase() : s)).join(\"\")\n        }\n        return low\n    }).join(\"\")\n}\n\nexport function slug(s = '') {\n    return s\n        .toLowerCase()\n        .trim()\n        .replace(/\\s+/g, '-') // Replace spaces with -\n        .replace(/[^\\w-]+/g, '') // Remove all non-word chars\n        .replace(/--+/g, '-') // Replace multiple - with single -\n}\n\nexport function pxToEm(target: number, stripedInnerFontSize = 1) {\n    return target / 14 / stripedInnerFontSize + 'em'\n}\n\nexport function percent(target: number) {\n    return target + '%'\n}\n\nexport function parseHTML(str: string) {\n    const tmp = document.implementation.createHTMLDocument('')\n    tmp.body.innerHTML = str\n    return tmp.body.childNodes\n}\n\nexport function stripHTML(str: string) {\n    const tmp = document.implementation.createHTMLDocument('')\n    tmp.body.innerHTML = str\n    return (tmp.body.textContent ?? \"\").replace(RegExp('[\\\\s|\\'|\"]', 'g'), '')\n}\n\nexport function makeId(length: number) {\n    var result = ''\n    var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\n    var charactersLength = characters.length\n    for (var i = 0; i < length; i++) {\n        result += characters.charAt(Math.floor(Math.random() * charactersLength))\n    }\n    return result\n}\n\nexport function removeEmptyValues(obj: { [key: string]: any }): { [key: string]: any } {\n    const findText = [\n        'Default campaign ID (tracking missing in Page Builder export)',\n        'Default campaign name (tracking missing in Page Builder export)',\n        'promoname', \n        'promoid', \n        'promocreative', \n        'undefined'\n    ];\n    \n    for (let key in obj) {\n        const value = obj[key];\n        \n        if (value === null || value === undefined || value === '') {\n            delete obj[key];\n            continue;\n        }\n        \n        if (typeof value === 'string') {\n            for (const text of findText) {\n                if (value.includes(text)) {\n                    delete obj[key];\n                    break;\n                }\n            }\n        }\n    }\n    \n    return obj;\n}\n\nexport function makeHash(str: string) {\n    var hash = 0,\n        i,\n        chr\n    if (!str) {\n        return hash\n    }\n    for (i = 0; i < str.length; i++) {\n        chr = str.charCodeAt(i)\n        hash = (hash << 5) - hash + chr\n        hash |= 0 // Convert to 32bit integer\n    }\n    return 'id-' + hash\n}\n\nexport function getHashLink(link: string) {\n    let linkHash = link\n    let linkNoHash = link\n    if (link.indexOf('#') !== -1) {\n        linkNoHash = link.replace('#', '')\n    } else {\n        linkHash = '#' + link\n    }\n\n    return { linkNoHash, linkHash }\n}\n\nexport function lazyLoad(node: Element, attribute: string, value: any, url: string) {\n    const CLASSNAME_OUT_OF_SCREEN = 'lazy-load'\n    const CLASSNAME_IN_SCREEN = 'lazy-loaded'\n    const CLASSNAME_ON_ERROR = 'lazy-loaded-error'\n\n    const isOldIOS = () => {\n        var agent = window.navigator.userAgent,\n            start = agent.indexOf('OS ')\n        if ((agent.indexOf('iPhone') > -1 || agent.indexOf('iPad') > -1) && start > -1) {\n            return window.Number(agent.substr(start + 3, 3).replace('_', '.')) < 14\n        }\n        return false\n    }\n\n    const inViewPort = (attribute: string, value: any) => {\n        node.setAttribute(attribute, value)\n\n        const cb = () => node.classList.add(CLASSNAME_IN_SCREEN)\n\n        if (url) {\n            const img = new Image()\n            img.src = url\n            img.onload = cb\n            img.onerror = () => {\n                cb()\n                node.classList.add(CLASSNAME_ON_ERROR)\n                throw new Error(`Image ${url} cannot be loaded`)\n            }\n\n            return\n        }\n\n        cb()\n    }\n\n    if (/Trident\\/|MSIE/.test(window.navigator.userAgent) || isOldIOS()) {\n        inViewPort(attribute, value)\n    } else {\n        if ('IntersectionObserver' in window) {\n            node.classList.add(CLASSNAME_OUT_OF_SCREEN)\n            let lazyBackgroundObserver = new IntersectionObserver(function (entries) {\n                entries.forEach(function (entry) {\n                    if (entry.isIntersecting) {\n                        inViewPort(attribute, value)\n                        lazyBackgroundObserver.unobserve(entry.target)\n                    }\n                })\n            })\n            lazyBackgroundObserver.observe(node)\n        } else {\n            inViewPort(attribute, value)\n        }\n    }\n}\n\nexport function lazyLoadCallback(node: Element, cb: () => void) {\n    const isOldIOS = () => {\n        var agent = window.navigator.userAgent,\n            start = agent.indexOf('OS ')\n        if ((agent.indexOf('iPhone') > -1 || agent.indexOf('iPad') > -1) && start > -1) {\n            return window.Number(agent.substr(start + 3, 3).replace('_', '.')) < 14\n        }\n        return false\n    }\n\n    if (/Trident\\/|MSIE/.test(window.navigator.userAgent) || isOldIOS()) {\n        cb()\n    } else {\n        if ('IntersectionObserver' in window) {\n            let lazyBackgroundObserver = new IntersectionObserver(\n                function (entries) {\n                    entries.forEach(function (entry) {\n                        if (entry.isIntersecting) {\n                            cb()\n                            lazyBackgroundObserver.unobserve(entry.target)\n                        }\n                    })\n                },\n                { rootMargin: '150% 0px' }\n            )\n            lazyBackgroundObserver.observe(node)\n        }\n    }\n}\n\n// Debounce\nexport function debounce<T>(func: (v: T) => void, time = 100) {\n    let timer: number\n    return function (event: T) {\n        if (timer) {\n            window.clearTimeout(timer)\n        }\n        timer = window.setTimeout(func, time, event)\n    }\n}\n\n// isIE - to check for internet explorer\nexport function isIE() {\n    let ua = window.navigator.userAgent,\n        isIE = /MSIE|Trident/.test(ua)\n\n    return isIE\n}\n\n// Load external script\nexport const loadExternalScript = ({\n    src,\n    callback = null,\n    async = false,\n    defer = false,\n    module = false,\n    id = ''\n}: {\n    src: string;\n    callback: null | GlobalEventHandlers[\"onload\"]\n    module: boolean,\n    defer: boolean,\n    async: boolean,\n    id: string\n}) => {\n    const script = document.createElement('script')\n    script.type = module ? 'module' : 'text/javascript'\n    script.src = src\n    id ? (script.id = id) : false // add id attribute only if passed\n    if (typeof callback === 'function') {\n        script.onload = callback\n    }\n    script.async = async\n    script.defer = defer\n    document.body.appendChild(script)\n}\n\n// Load external css\nexport const loadExternalCss = ({ src }: { src: string }) => {\n    const script = document.createElement('link')\n    script.rel = 'stylesheet'\n    script.href = src\n    document.body.appendChild(script)\n}\n// Lazy load vendor script\nexport const lazyLoadVendorScript = (handler, el) => {\n    const observer = new IntersectionObserver(handler)\n    observer.observe(el)\n}\n\n/**\n * Replaces variable inside a given string\n * Each variable have to be enclosed between stChr and enChr\n * The values have to be contained in the vars object, they key must match\n * example :\n * txt : 'See {resultsLength} Results'\n * vars : {resultsLength:'30'}\n * stChr : '{'\n * enChr : '}'\n *\n * will return : 'See 30 Results'\n *\n * @param {string} txt\n * @param {object} vars\n * @param {string} stChr\n * @param {string} enChr\n */\nexport function interpolate(txt: string, vars: Record<string, null | undefined | string>, stChr: string, enChr: string) {\n    let curIdx = 0\n\n    while (txt) {\n        const stIdx = txt.indexOf(stChr, curIdx)\n        if (stIdx === -1) {\n            break\n        }\n        const enIdx = txt.indexOf(enChr, stIdx + 1)\n        if (enIdx === -1) {\n            break\n        }\n        const hashId = txt.substring(stIdx + stChr.length, enIdx)\n        if (vars[hashId] != null) {\n            txt = txt.substr(0, stIdx) + vars[hashId] + txt.substr(enIdx + enChr.length)\n            curIdx = stIdx\n        } else {\n            curIdx = enIdx\n        }\n    }\n    return txt\n}\n\n/**\n * Find in container element, add height to equal size of element\n * @param container css path where my element is contain e.g. `.c-container`\n * @param el css path of elements to equalized\n */\nexport const equalHeight = (containerSelector: string, el: string, elementScope: HTMLElement) => {\n    const container = elementScope.querySelector<HTMLElement>(containerSelector)\n    if (!container) {\n        return\n    }\n\n    const items = container.querySelectorAll<HTMLElement>(el)\n    let max = -1\n\n    for (let i = 0; i < [...items].length; i++) {\n        const item = [...items][i]\n        let h = item.offsetHeight\n        max = h > max ? h : max\n    }\n\n    if (max <= 0) {\n        return\n    }\n\n    for (let i = 0; i < [...items].length; i++) {\n        const item = [...items][i]\n        item.style.height = `${max}px`\n    }\n}\n\nexport const stringifyCurlyQuote = (data: {}) => JSON.stringify(data).replace(\"'\", '’')\n\nexport const stringifyForAttribute = (data = {}) => {\n    return escapeHtml(JSON.stringify(data))\n}\n\n/**\n * This function is included instead of sanitizeString because for\n * inserting HTML into innerHTML we need to make sure all HTML\n * entities are escaped.\n */\nexport const escapeHtml = (text: string) => {\n    const map = {\n        '&': '&amp;',\n        '<': '&lt;',\n        '>': '&gt;',\n        '\"': '&quot;',\n        \"'\": '&#039;'\n    } as { [s: string]: string }\n\n    return text.replace(/[&<>\"']/g, (m) => map[m])\n}\n\n/**\n * Because setting attributes escapes more than the characters above and then preact also\n * escapes text we need a more complete way of unescaping all html entities (not just the ones\n * above)\n */\nconst domParser = new DOMParser()\nexport const unescapeHtml = (text: string) => {\n    return domParser.parseFromString(text, \"text/html\").body.textContent\n}\n\nexport const sanitizeString = (data: {}) => {\n    if (!data) {\n        return ''\n    }\n\n    return data.toString().replace(/\"/g, '&quot;').replace(/'/g, '&apos;')\n}\n\nexport const stripTags = (s: string) => {\n    return (s || '').replace(/(<([^>]+)>)/gi, '')\n}\n\nexport const setAttributes = (element: Element, attrs: Record<string, any>) => {\n    for (let key in attrs) {\n        element.setAttribute(key, attrs[key])\n    }\n    return element\n}\n\nexport const getMetaContent = (metaName: string) => {\n    const metaTag = document.querySelector(`meta[name=${metaName}]`)\n    if (!metaTag) {\n        return ''\n    }\n    return metaTag.getAttribute('content')\n}\n\nexport const isObjectEmpty = (obj: {}) => {\n    return Object.keys(obj).length === 0\n}\n","export const dispatchEvent = ({ eventName, args, element }) => {\n    // Use the provided element or fallback to window if available\n    if (!element) {\n        if (typeof window !== 'undefined') {\n            element = window\n        } else {\n            throw new Error(\n                '`element` is not provided and `window` is unavailable. Provide a valid element to dispatch the event.'\n            )\n        }\n    }\n\n    let event\n    if (args) {\n        event = new CustomEvent(eventName, { detail: args, bubbles: true })\n    } else {\n        if (typeof Event === 'function') {\n            event = new Event(eventName)\n        } else {\n            event = document.createEvent('Event')\n            event.initEvent(eventName, true, true)\n        }\n    }\n    element.dispatchEvent(event)\n}\n\nexport const readEvent = e => {\n    if (!e.detail) {\n        return\n    }\n    return e.detail\n}\n","export const MAX_WIDTH_CONTAINER = 1160\n\nexport const BREAKPOINT_XL = 1920\nexport const BREAKPOINT_TABLET = 1024\nexport const BREAKPOINT_L = 996\nexport const BREAKPOINT_M = 768\nexport const BREAKPOINT_S = 750\nexport const BREAKPOINT_XS = 375\n\nexport const CTA_PRIMARY = 'primary'\nexport const CTA_PRIMARY_TRANSPARENT = 'primary_transparent'\nexport const CTA_SUBTLE = 'subtle'\nexport const CTA_LINK = 'link'\nexport const CTA_LINK_UNDERLINE = 'link-underline'\nexport const CTA_LINK_GOLD = 'link-gold'\nexport const CTA_LINK_ADD_TO_CART_SMALL = 'AddToCart_small'\nexport const CTA_LINK_ADD_TO_CART_LARGE = 'AddToCart_large'\n\nexport const EVENT_TAB_CHANGE = 'EVENT_TAB_CHANGE'\n\nexport const EVENT_VIDEO = 'WEB_COMPONENT_VIDEO'\nexport const EVENT_POPIN_OPEN = 'WEB_COMPONENT_POPIN_OPEN'\nexport const EVENT_POPIN_OPENED = 'WEB_COMPONENT_POPIN_OPENED'\nexport const EVENT_POPIN_CLOSE = 'WEB_COMPONENT_POPIN_CLOSE'\nexport const EVENT_POPIN_CLOSED = 'WEB_COMPONENT_POPIN_CLOSED'\nexport const EVENT_POPIN_CLOSE_CLICK = 'WEB_COMPONENT_POPIN_CLOSE_CLICK'\nexport const EVENT_POPIN_KEY_DOWN = 'keydown'\nexport const EVENT_POPIN_FORM_TOGGLE_TITLE = 'WEB_COMPONENT_POPIN_FORM_TOGGLE_TITLE'\nexport const EVENT_CTA_CLICK = 'WEB_COMPONENT_CTA_CLICK'\nexport const EVENT_HERO_REORDER_OPEN = 'WEB_COMPONENT_HERO_REORDER_OPEN'\nexport const EVENT_HERO_REORDER_CLOSE = 'WEB_COMPONENT_HERO_REORDER_CLOSE'\nexport const EVENT_QUICKVIEW_OPEN = 'WEB_COMPONENT_QUICKVIEW_OPEN'\nexport const EVENT_QS_OPEN = 'WEB_COMPONENT_QS_OPEN'\nexport const EVENT_QS_OPENED = 'WEB_COMPONENT_QS_OPENED'\nexport const EVENT_QS_CLOSE = 'WEB_COMPONENT_QS_CLOSE'\nexport const EVENT_QS_CLOSED = 'WEB_COMPONENT_QS_CLOSED'\nexport const EVENT_QS_CLOSE_CLICK = 'WEB_COMPONENT_QS_CLOSE_CLICK'\nexport const EVENT_QS_KEY_DOWN = 'keydown'\nexport const EVENT_ADD_TO_CART = 'WEB_COMPONENT_ADD_TO_CART'\nexport const EVENT_CART_UPDATED = 'WEB_COMPONENT_CART_UPDATED'\nexport const EVENT_VIDEO_TOGGLE = 'WEB_COMPONENT_VIDEO_TOGGLE'\nexport const VIDEO_ON_HOVER = 'VIDEO_ON_HOVER'\nexport const VIDEO_ON_OUT = 'VIDEO_ON_OUT'\nexport const EVENT_DETAIL_OPEN = 'WEB_COMPONENT_DETAIL_OPEN'\nexport const EVENT_SLIDER_READY = 'WEB_COMPONENT_SLIDER_READY'\nexport const EVENT_SLIDE_CHANGE = 'WEB_COMPONENT_SLIDE_CHANGE'\nexport const EVENT_OVERLAY_OPEN = 'WEB_COMPONENT_OVERLAY_OPEN'\nexport const EVENT_OVERLAY_CLOSE = 'WEB_COMPONENT_OVERLAY_CLOSE'\nexport const EVENT_OVERLAY_CLICKED = 'WEB_COMPONENT_OVERLAY_CLICKED'\nexport const EVENT_OPEN_PRODUCT_AR_CLICKED = 'OPEN_PRODUCT_AR_CLICKED'\nexport const EVENT_SORT_BY_CHANGE = 'WEB_COMPONENT_SORT_BY_CHANGE'\n\nexport const EVENT_BUBBLE_SELECTED = 'EVENT_BUBBLE_SELECTED'\nexport const EVENT_RECO_TOOL_OPTION_CLICKED = 'EVENT_RECO_TOOL_OPTION_CLICKED'\nexport const WEB_COMPONENT_PROJECTS_LOADED = 'WEB_COMPONENT_PROJECTS_LOADED'\nexport const WEB_COMPONENT_ANCHOR_LOADED = 'WEB_COMPONENT_ANCHOR_LOADED'\n\nexport const EVENT_SWIPED_UP = 'swiped-up'\nexport const EVENT_SWIPED_DOWN = 'swiped-down'\nexport const EVENT_SWIPED_LEFT = 'swiped-left'\nexport const EVENT_SWIPED_RIGHT = 'swiped-right'\n\nexport const EVENT_HEADER_POSITION_CHANGED = 'EVENT_HEADER_POSITION_CHANGED'\n\nexport const keys = { ESC: 'Escape' }\n\nexport const ADD_TO_CART_MODIFIER_MINI = 'mini'\nexport const ADD_TO_CART_MODIFIER_DEFAULT = ADD_TO_CART_MODIFIER_MINI\n\nexport const COFFEE_ORIGINAL = 'original'\nexport const COFFEE_VERTUO = 'vertuo'\nexport const COFFEE_PRO = 'pro'\nexport const COFFEE_OL = 'OL'\nexport const COFFEE_VL = 'VL'\nexport const INTENSITY_MAX_OL = 14\nexport const INTENSITY_MAX_VL = 12\nexport const DEFAULT_BUBBLE_ICON = ''\n\nexport const NUMBER_PRODUCTS_SLIDER = 8\nexport const NUMBER_FEATURES_PDP = 8\n\nexport const ALIGNMENT = ['center', 'left', 'right']\nexport const POSITION = ['top', 'right', 'bottom', 'left']\nexport const TRANSLATION_ADD_TO_CART = 'Add to cart'\nexport const TRANSLATION_UPDATE_BASKET = 'Update basket'\n\nexport const TIME_INSTANT = 1\nexport const TIME_FAST = 300\nexport const TIME_MEDIUM = 600\nexport const TIME_SLOW = 1200\n\nexport const APP_APPLE_LINK = {\n    default: 'https://apps.apple.com/us/app/nespresso/id342879434',\n    us: 'https://apps.apple.com/us/app/nespresso-new/id1609639566',\n    uk: 'https://apps.apple.com/gb/app/nespresso-new/id1609639566'\n}\nexport const APP_ANDROID_LINK =\n    'https://play.google.com/store/apps/details?id=com.nespresso.activities'\nexport const APP_HUAWEI_LINK = 'https://appgallery.huawei.com/app/C102571517'\n\nexport const SRC_PAGE_PLP = 'plp'\nexport const SRC_PAGE_PDP = 'pdp'\n\nexport const PLP_TYPE_COFFEE = 'coffee'\nexport const PLP_TYPE_MACHINE = 'machine'\nexport const PLP_TYPE_ACCESSORY = 'accessory'\nexport const CALLEO_API_DOMAIN = 'https://www.contact.nespresso.com/'\n\n// SCSS RELATED\n// Todo : should be shared by JS and SCSS\nexport const BROWSER_CONTEXT = 16 // 1rem = 16px\nexport const COLOR_WHITE_1000 = '#FFFFFF' // Do not change for #FFF shortcut, it will break slider-natural gradients !\n\nexport const CONTRAST_DARK = 'dark'\nexport const CONTRAST_LIGHT = 'light'\n\nexport const B2B_CONTACT_FORM_POPIN_ID = 'b2b-contact-form-popin-id'\nexport const B2B_CONTACT_FORM_POPIN_SRC_SEARCH = 'coveo-search'\n\nexport const B2B_CONTACT_FORM_POPIN_SRC_SKU_MAIN_INFO = 'sku-main-info'\n\nexport const B2B_CONTACT_FORM_POPIN_SRC_SKU_MAIN_INFO_AUTO = 'sku-main-info-auto'\n\nexport const ASPECT_RATIO_16_9 = '16/9'\nexport const ASPECT_RATIO_1_1 = '1/1'\n\nexport const NESPRESSO_PRODUCTION_DOMAIN = 'https://www.nespresso.com'\nexport const NESPRESSO_ROLLOUT_DOMAIN = 'https://nc2-env-rollout.nespresso.com'\n\nexport const EVENT_QUIZ_ON_GO_BACK = 'WEB_COMPONENT_EVENT_QUIZ_ON_GO_BACK'\nexport const EVENT_QUIZ_SUBMIT = 'WEB_COMPONENT_EVENT_QUIZ_SUBMIT'\n","export default {\n    creative: 'before_content_composer'\n}\n","import { stringifyForAttribute } from '@kissui/helpers/src/utils'\nimport trackingData from './tracking'\nexport const renderCta = (props, cssClass) => {\n    const {\n        cta = {},\n        campaign = { id: '', name: '', creative: '', position: trackingData.creative }\n    } = props\n\n    if (!cta.label) {\n        return ''\n    }\n\n    cta.campaign_id = campaign.id || ''\n    cta.campaign_name = campaign.name || ''\n    cta.campaign_position = campaign.position || ''\n    cta.campaign_creative = campaign.creative || ''\n\n    const data = stringifyForAttribute(cta)\n\n    return `<div class=\"${cssClass}\"><nb-cta\n                data=\"${data}\">\n            ${cta.label}\n            </nb-cta></div>`\n}\n\nexport const renderLink = (props, cssClass, popin_id = '') => {\n    const {\n        link = {},\n        campaign = { id: '', name: '', creative: '', position: trackingData.creative }\n    } = props\n\n    if (!link.label) {\n        return ''\n    }\n\n    return `<div class=\"${cssClass}\"><nb-link\n        campaign_id=\"${campaign.id}\"\n        campaign_name=\"${name}\"\n        campaign_creative=\"${campaign.creative}\"\n        campaign_position=\"${campaign.position}\"\n        link=\"${link.link}\"\n        popin_id=\"${popin_id}\"\n        color=\"${link.color}\"\n        size=\"${link.size}\"\n        seo_label=\"${link.seo_label}\"\n        >${link.label}</nb-link></div>`\n}\n","import { BREAKPOINT_M, BREAKPOINT_TABLET } from '@kissui/components'\n\nconst viewport = () => {\n    const lt = (ref: number) => {\n        return window.innerWidth < ref\n    }\n\n    return {\n        get is() {\n            const { innerWidth: vw, devicePixelRatio } = window\n            return {\n                mobile: vw < BREAKPOINT_M,\n                mobile_tablet: vw < BREAKPOINT_TABLET,\n                tablet: vw >= BREAKPOINT_M && vw < BREAKPOINT_TABLET,\n                desktop: vw >= BREAKPOINT_TABLET && devicePixelRatio <= 1,\n                retina: vw >= BREAKPOINT_TABLET && devicePixelRatio > 1\n            }\n        },\n        lt\n    }\n}\n\nconst helper = viewport()\n\nexport default helper\n","import viewportHelper from '@kissui/helpers/src/viewport.helpers'\n\nexport const getImage = ({ background_retina, background_desktop, background_mobile }) => {\n    if (viewportHelper.is.mobile && background_mobile) {\n        return background_mobile\n    } else if (viewportHelper.is.retina && background_retina) {\n        return background_retina\n    }\n\n    return background_desktop\n}\n","export default class {\n    constructor(_props, _campaign) {\n        this.props = _props\n        this.campaign = _campaign\n        this.elementId = null\n    }\n    render() {\n        throw new Error('You must implement the render method')\n    }\n    bindEvents() {\n        return []\n    }\n}\n","export const getCurrency = () => window[window.config.padl.namespace].dataLayer.app.app.currency\n","import { COFFEE_VERTUO } from '@kissui/components/src/constants.mjs'\nimport { getCurrency } from './getCurrency'\nexport { getCurrency } from './getCurrency'\n\nexport const ECAPI_TYPE_CAPSULE = 'capsule'\nexport const ECAPI_TYPE_MACHINE = 'machine'\nexport const ECAPI_TYPE_ACCESSORY = 'accessory'\nexport const ECAPI_TYPE_GIFT_CARD = 'giftcard'\n\nconst TECHNOLOGY_CATEGORY_IDENTIFIER = '/machineTechno/'\nconst SLEEVE_OF_10 = 10\nconst SLEEVE_OF_7 = 7\n\nconst trimSku = sku => sku.replace(/[^a-z0-9- +./]/gi, '')\n\nexport const getLegacySKU = productId => productId.split('prod/').pop()\n\nexport const getPriceFormatter = async () => await window.napi.priceFormat()\n\nexport const getProduct = sku => window.napi.catalog().getProduct(trimSku(sku))\n\nexport function getTechnologyName(productData) {\n    const techno = productData.technologies[0]\n    return techno.substring(\n        techno.indexOf(TECHNOLOGY_CATEGORY_IDENTIFIER) + TECHNOLOGY_CATEGORY_IDENTIFIER.length\n    )\n}\n\nfunction isMultipleOf(quantity, multiple) {\n    return quantity % multiple === 0\n}\n\nexport function getSleeveNumber(product, getTechnologyNameFn = getTechnologyName) {\n    if (product.sales_multiple !== 1 && isMultipleOf(product.sales_multiple, SLEEVE_OF_10)) {\n        // Sleeve of original or vertuo\n        return product.sales_multiple / SLEEVE_OF_10\n    }\n\n    if (\n        product.sales_multiple !== 1 &&\n        getTechnologyNameFn(product) === COFFEE_VERTUO &&\n        isMultipleOf(product.sales_multiple, SLEEVE_OF_7)\n    ) {\n        // Sleeve of vertuo\n        return product.sales_multiple / SLEEVE_OF_7\n    }\n\n    if (product.sales_multiple === 1 && isMultipleOf(product.unitQuantity, SLEEVE_OF_10)) {\n        // Bundle of original or vertuo\n        return product.unitQuantity / SLEEVE_OF_10\n    }\n\n    if (\n        product.sales_multiple === 1 &&\n        getTechnologyNameFn(product) === COFFEE_VERTUO &&\n        isMultipleOf(product.unitQuantity, SLEEVE_OF_7)\n    ) {\n        // Bundle of vertuo\n        return product.unitQuantity / SLEEVE_OF_7\n    }\n\n    return NaN\n}\n\n/**\n * Guess if the product is part of a bundle.\n * This is determined by checking the 'sales_multiple' and 'unitQuantity' properties.\n */\nexport function isBundled(productData) {\n    // TODO: this function should not change the productData, but some components still need it\n    productData.sales_multiple = productData.sales_multiple || productData.salesMultiple\n\n    const isSalesMultipleGreaterThanOne = productData.sales_multiple > 1\n    const isUnitQuantityEqualToOne = productData.unitQuantity === 1\n    const isSalesMultipleEqualToOne = productData.sales_multiple === 1\n    const isUnitQuantityGreaterThanOne = productData.unitQuantity > 1\n\n    // The product is not bundled if sales_multiple > 1 and unitQuantity = 1\n    if (isSalesMultipleGreaterThanOne && isUnitQuantityEqualToOne) {\n        return false\n    }\n\n    // The product is bundled if sales_multiple = 1 and unitQuantity > 1\n    return isSalesMultipleEqualToOne && isUnitQuantityGreaterThanOne\n}\n\n/**\n * Replace an array of SKU with product data\n * Remove the element inside the list if sku fail. It prevents to get an empty item.\n * @param {Array.<String>} skus\n * @param getProductFn\n * @returns {Promise<Awaited<unknown>[]>}\n */\nexport function getProductAndClean(skus, getProductFn = getProduct, napi = window.napi) {\n    const promises = []\n\n    if (!napi) {\n        return Promise.reject()\n    }\n\n    if (!Array.isArray(skus)) {\n        skus = [skus]\n    }\n\n    // Load manually the product to delete SKU fail\n    for (const sku of skus) {\n        promises.push(\n            getProductFn(sku)\n                .then(data => skus.splice(skus.indexOf(sku), 1, data))\n                .catch(() => {\n                    skus.splice(skus.indexOf(sku), 1)\n                    console.error(`getProduct fail on sku ${sku}`)\n                })\n        )\n    }\n\n    return Promise.all(promises)\n}\n\nexport const getFormattedPrice = async price => {\n    const priceFormatter = await getPriceFormatter()\n    const currency = getCurrency()\n\n    return priceFormatter.html\n        ? priceFormatter.html(currency, price)\n        : priceFormatter.short(currency, price) || ''\n}\n\nexport const getProductCategories = async sku => {\n    const productDetails = await getProduct(sku)\n    const productCategories = productDetails ? productDetails.supercategories : []\n    const productCategoriesNew = await Promise.all(\n        productCategories.map(async categoryEncoded => {\n            const productCategoryData = await window.napi.catalog().getCategory(categoryEncoded)\n            return productCategoryData\n        })\n    )\n    return productCategoriesNew\n}\n","export type EventListener = {\n    element: HTMLElement\n    type: string\n    listener: (e: Event) => void\n    options?: boolean | AddEventListenerOptions\n}\n\nconst add = (eventListeners: EventListener[] = []) => {\n    eventListeners.forEach(eventListener => {\n        if (!eventListener || !eventListener.element) {\n            return\n        }\n        return eventListener.element.addEventListener(\n            eventListener.type,\n            eventListener.listener,\n            eventListener.options\n        )\n    })\n}\n\nconst remove = (eventListeners: EventListener[] = []) => {\n    eventListeners.forEach(eventListener => {\n        if (!eventListener || !eventListener.element) {\n            return\n        }\n        eventListener.element.removeEventListener(eventListener.type, eventListener.listener)\n    })\n}\n\nconst busNamespace = 'pageBuilder'\n\nexport const emitCustomEvent = (eventName: string, data: unknown) => {\n    const customEvent = new CustomEvent(`${busNamespace}.${eventName}`, {\n        detail: data,\n        bubbles: true,\n        cancelable: true,\n        composed: false\n    })\n\n    window.dispatchEvent(customEvent)\n}\n\nexport default { add, emitCustomEvent, remove }\n","import { getProduct } from '@kissui/helpers/src/catalog'\nimport { emitCustomEvent } from './events.helpers'\nimport { removeEmptyValues } from '@kissui/helpers/src/utils'\n\nconst raisedByPB = 'page builder'\nconst raisedByWC = 'Web component'\n\n/**\n * helper method for 'itemDisplay' GTM event\n * @param {*} event : 'itemDisplay' - Mandatory as is\n * @param {*} eventRaisedBy : 'Web component' - Mandatory as is\n * @param {*} eventAction : 'Click' - Action that led to the item display. For example, click\n * @param {*} itemTypes : ['products'] - Mandatory as is\n * @param {*} rootElement : ['nb-slider'] - Root DOM element for item detection. Closest common ancestor element of the inserted/displayed promotions and products. It will help the detection to reduce its performance consumption. Set to 0 (zero) in order to request detection through the entire document.\n */\nexport const itemDisplay = args => {\n    window.gtmDataObject = window.gtmDataObject || []\n    const eventData = {\n        event: 'itemDisplay',\n        eventRaisedBy: raisedByWC,\n        eventAction: 'Click',\n        itemTypes: ['products'],\n        ...args\n    }\n    window.gtmDataObject.push(eventData)\n    emitCustomEvent('itemDisplay', eventData)\n}\n\n/**\n *\n * helper method for 'customEvent' GTM event\n * @param {*} args (event, eventRaisedBy, eventCategory, eventAction, eventLabel, nonInteraction)\n */\n\nexport const customEvent = args => {\n    window.gtmDataObject = window.gtmDataObject || []\n    var eventData\n    if (args.event_GA4 === undefined || args.event_GA4 === false) {\n        eventData = {\n            event: 'customEvent',\n            eventRaisedBy: raisedByWC,\n            eventCategory: 'User Engagement',\n            eventAction: 'Click',\n            eventLabel: '',\n            nonInteraction: 0,\n            ...args\n        }\n    } else {\n        eventData = {\n            event_raised_by: raisedByPB,\n            ...args\n        }\n    }\n    window.gtmDataObject.push(eventData)\n    emitCustomEvent('customEvent', eventData)\n}\n\n/**\n * Helper method for tracking component interactions, compatible with GA4.\n *\n * @param {String} creative : component raising the event, e.g. 'before_coffees_list', 'before_machines_list', 'before_accessories_list'\n * @param {String} actionType : description of the interaction, e.g 'pdp quick view'\n * @param {String} internationalId : long SKU, e.g. 'erp.pt.b2c/prod/7243.30'\n * @param {String} internationalName : international name of the product, e.g. 'Vertuo Carafe Pour-Over Style Mild'\n * @param {String} productType : type of product, i.e. 'capsule', 'machine', 'accessory'\n * @param {String} range : product range, e.g. 'ispirazione italiana'\n * @param {String} technology : technology, i.e. 'original', 'vertuo'\n * @param {Number} price : price, e.g. .51\n * @param {String} eventAction : description of the action, e.g. 'PDP Quick View'\n *\n * Initally created for PDP Quick View tracking:\n * https://dsu-confluence.nestle.biz/display/DIANA/BEFORE+-+PDP+Quick+View\n * Will probably be rolled out across all components, update this comment accordingly.\n */\nexport const trackComponentInteraction = ({\n    creative = '',\n    actionType = '',\n    internationalId = '',\n    internationalName = '',\n    productType = '',\n    technology = '',\n    category = '',\n    rawPrice = '',\n    eventAction = ''\n}) => {\n    window.gtmDataObject = window.gtmDataObject || []\n    const eventData = {\n        event: 'page_builder_component_interaction',\n        event_raised_by: raisedByPB,\n        component_name: creative,\n        action_type: actionType,\n        item_id_event: internationalId,\n        item_name_event: internationalName,\n        item_category_event: productType,\n        item_technology_event: technology,\n        item_range_event: category,\n        item_price_event: rawPrice,\n        eventCategory: 'User Engagement',\n        eventAction: eventAction,\n        eventLabel: `${productType} - ${technology} - ${internationalName}`\n    }\n    window.gtmDataObject.push(eventData)\n    emitCustomEvent('page_builder_component_interaction', eventData)\n}\n\n/**\n *\n * Push 'view_promotion' event for GA 4\n * @param {*} args (event, event_raised_by, ecommerce: {promotion_id, promotion_name, creative_slot, creative_name})\n */\nexport const viewPromotion = args => {\n    const event = 'view_promotion'\n    const eventData = {\n        event,\n        event_raised_by: raisedByPB,\n        ecommerce: {}\n    }\n    if (Object.keys(args).length) {\n        const { id = '', creative = '', name = '', position = '' } = args\n        let ecommerceData = {\n            promotion_id: id,\n            promotion_name: name,\n            creative_slot: position,\n            creative_name: creative\n        }\n        ecommerceData = removeEmptyValues(ecommerceData)\n        eventData.ecommerce = ecommerceData\n    }\n    window.gtmDataObject ??= []\n    window.gtmDataObject.push(eventData)\n    emitCustomEvent(event, eventData)\n}\n\nexport const handlePromoClick = args => {\n    const { campaign, cta_name } = args\n\n    const cleanedData = removeEmptyValues(campaign)\n    selectPromotion({ cta_name, ...cleanedData })\n}\n\n/**\n *\n * Push 'select_promotion' event for GA 4\n * @param {*} args (event, event_raised_by, cta_name, ecommerce: {promotion_id, promotion_name, creative_slot, creative_name})\n */\nexport const selectPromotion = args => {\n    const event = 'select_promotion'\n    const eventData = {\n        event: 'select_promotion',\n        cta_name: args?.cta_name ?? '(not set)',\n        event_raised_by: raisedByPB,\n        ecommerce: {}\n    }\n    if (Object.keys(args).length) {\n        const { id = '', creative = '', name = '', position = '' } = args\n        let ecommerceData = {\n            promotion_id: id,\n            promotion_name: name,\n            creative_slot: position,\n            creative_name: creative\n        }\n        ecommerceData = removeEmptyValues(ecommerceData)\n        eventData.ecommerce = ecommerceData\n    }\n\n    window.gtmDataObject ??= []\n    window.gtmDataObject.push(eventData)\n    emitCustomEvent(event, eventData)\n}\n\nexport const interactionClick = (nameComponent, ctaName) => {\n    window.gtmDataObject = window.gtmDataObject || []\n    const eventData = {\n        event: 'page_builder_component_interaction',\n        event_raised_by: raisedByPB,\n        eventCategory: 'User Engagement',\n        eventAction: 'Click CTA',\n        eventLabel: `Page Builder - ${nameComponent} - ${ctaName}`,\n        component_name: nameComponent,\n        action_type: 'web component click',\n        cta_name: ctaName\n    }\n    window.gtmDataObject.push(eventData)\n    emitCustomEvent('page_builder_component_interaction', eventData)\n}\n\nexport const getProductInfo = async (sku, data) => {\n    let product = data\n    if (!product) {\n        product = await getProduct(sku)\n    }\n    return product\n}\n\nexport const getProductPayload = (data, actionField = {}) => {\n    const {\n        internationalName,\n        internationalId,\n        category,\n        unitPrice,\n        legacyId,\n        name,\n        technologies,\n        bundled,\n        inStock,\n        type\n    } = data\n\n    const technology = technologies.map(item => item.split('/').pop()).join('|')\n    const isDiscovery = category.toLowerCase().includes('discovery')\n\n    return [\n        // Array consists of one product details for PDP Product Detail View\n        {\n            ...actionField,\n            name: internationalName, // '[[International Product Name]]' NIE, Contract\n            id: internationalId, // '[[International Product ID]]'\n            price: unitPrice, // '[[Product Price]'\n            // dimension43: '[[true/false]]', // '[[true/false]]' // Signifies if this product is part of a standing order or not\n            dimension44: isDiscovery.toString(), // '[[true/false]]', // Signifies if this product is part of a discovery offer\n            dimension53: legacyId, // '[[Product Local market ID]]', // Local market id for product\n            dimension54: name, // '[[Product Local market Name]]', // Local market name for product\n            dimension55: category, // '[[Product Range]]', // Range of the product, eg: Barista Creations for Ice (Nessoft Category)\n            dimension56: technology, // '[[Product Technology]]', //Product technology according to Nespresso categorization (original, vertuo, pro)\n            dimension57: bundled ? 'bundle' : 'single', // '[[Product Type]]', //If the product is single or bundle\n            dimension192: inStock ? 'in stock' : 'out of stock', // '[in stock]', // \"in stock\" or \"out of stock\"\n            category: type, // '[[Product Category]]', //Product category according to Nespresso categorization (Nessoft type): capsule, accessory, machine\n            brand: 'Nespresso' // Static value set to Nespresso\n        }\n    ]\n}\n\nexport const trackDetailView = async (sku, data) => {\n    // https://dsu-confluence.nestle.biz/display/DIANA/HQ+PB+Tracking+-+Product+Detail+View\n    if (window.pbTrackDetailViewPDP || !sku || !window.napi) {\n        return\n    }\n\n    const productInfo = await getProductInfo(sku, data)\n    const productPayload = getProductPayload(productInfo)\n    const currency = productInfo.currency\n\n    window.gtmDataObject = window.gtmDataObject || []\n    const eventData = {\n        event: 'detailView',\n        currencyCode: currency,\n        eventRaisedBy: raisedByPB,\n        ecommerce: {\n            detail: {\n                actionField: {},\n                products: productPayload\n            }\n        }\n    }\n    window.gtmDataObject.push(eventData)\n    // Track only once per page\n    window.pbTrackDetailViewPDP = true\n    emitCustomEvent('detailView', eventData)\n}\n\nexport const trackAddToCartImpression = (product, isStickyBar) => {\n    // https://dsu-confluence.nestle.biz/pages/viewpage.action?spaceKey=DIANA&title=PDP+-+Sticky+Add+To+Cart+Custom+Event\n\n    window.gtmDataObject = window.gtmDataObject || []\n    const eventData = {\n        event: 'page_builder_component_interaction',\n        event_raised_by: raisedByPB,\n        component_name: 'before_sku_main_info',\n        action_type: isStickyBar\n            ? 'sticky add to cart impression'\n            : 'standard add to cart impression',\n        //product info\n        item_id_event: product.internationalId,\n        item_name_event: product.internationalName,\n        item_category_event: product.type,\n        item_price_event: product.price_per_capsule?.split(' ')[0],\n        item_market_id_event: product.legacyId,\n        item_market_name_event: product.name,\n        item_range_event: product.category_name,\n        item_technology_event: product.technology?.[0]?.split('/').slice(-1) ?? '',\n        item_type_event: product.bundled ? 'bundle' : 'single'\n    }\n    window.gtmDataObject.push(eventData)\n    emitCustomEvent('page_builder_component_interaction', eventData)\n}\n\nexport const productImpression = async (position, list, sku, data) => {\n    // https://dsu-confluence.nestle.biz/pages/viewpage.action?pageId=225612781\n    // don't track already tracked products\n    window.gtmDataObject = window.gtmDataObject || []\n    const hasDetailView = window.gtmDataObject.find(item => item.event === 'detailView')\n    const alreadyTracked = !!hasDetailView?.ecommerce?.detail?.products.find(p =>\n        sku.includes(p.id)\n    )\n    if (alreadyTracked) {\n        return\n    }\n\n    const productInfo = await getProductInfo(sku, data)\n    const productPayload = getProductPayload(productInfo, { list: list, position: position })\n    const currency = productInfo.currency\n    const eventData = {\n        event: 'impression',\n        eventAction: 'Product Impression',\n        currencyCode: currency,\n        eventRaisedBy: raisedByPB,\n        ecommerce: {\n            impressions: productPayload\n        }\n    }\n    window.gtmDataObject.push(eventData)\n    emitCustomEvent('impression', eventData)\n}\n\nexport const productClick = async (position, list, sku, data) => {\n    // https://dsu-confluence.nestle.biz/pages/viewpage.action?pageId=225612781\n\n    if (typeof list !== 'string') return\n\n    const productInfo = await getProductInfo(sku, data)\n    const productPayload = getProductPayload(productInfo, { position: position })\n    const currency = productInfo.currency\n\n    window.gtmDataObject = window.gtmDataObject || []\n    const eventData = {\n        event: 'productClick',\n        eventAction: 'Product Click',\n        currencyCode: currency,\n        eventRaisedBy: raisedByPB,\n        ecommerce: {\n            click: {\n                actionField: {\n                    list: list\n                },\n                products: productPayload\n            }\n        }\n    }\n    window.gtmDataObject.push(eventData)\n    emitCustomEvent('productClick', eventData)\n}\n\nexport function filterTrackingFromPlpFilters(filtersSelected) {\n    const grouped = groupSelectedFilters(filtersSelected)\n    const groupKeys = Object.keys(grouped)\n    const typesFiltersSelected = groupKeys.join('|').substring(0, 99)\n    const valuesFiltersSelected = groupKeys\n        .map(key => grouped[key].values.map(value => value.split('/').at(-1)).join(','))\n        .join('|')\n        .substring(0, 99)\n\n    return [typesFiltersSelected, valuesFiltersSelected]\n}\n\nexport const filterActionEvent = (\n    actionType,\n    filterType,\n    filterValues,\n    clickLocation,\n    dataType\n) => {\n    // https://dsu-confluence.nestle.biz/display/DIANA/PLP+-+Filter+Revamp\n    window.gtmDataObject = window.gtmDataObject || []\n    const eventData = getExplicitFilterEventData(\n        actionType,\n        filterType,\n        filterValues,\n        clickLocation\n    )\n\n    window.gtmDataObject.push(eventData)\n    if (window.NEXT_V1_PLP_EXPLICIT_FILTER_TRACKING && dataType) {\n        window.gtmDataObject.push({\n            ...window.NEXT_V1_PLP_EXPLICIT_FILTER_TRACKING,\n            experiment_action: `${actionType} - ${dataType}`,\n            cta_name: 'All filters'\n        })\n    }\n\n    emitCustomEvent('plp_filter', eventData)\n}\n\nconst getExplicitFilterEventData = (actionType, filterType, filterValues, clickLocation) => {\n    return {\n        event: 'plp_filter',\n        event_raised_by: raisedByPB,\n        action_type: actionType,\n        filter_type: filterType,\n        ...(filterValues ? { filter_values: filterValues } : {}),\n        ...(clickLocation ? { click_location: clickLocation } : {})\n    }\n}\n\nfunction groupSelectedFilters(filtersSelected = []) {\n    return filtersSelected.reduce((grouped, { key, value }) => {\n        if (!grouped[key]) grouped[key] = { key, values: [] }\n        grouped[key].values.push(value.replaceAll(',', '-'))\n        return grouped\n    }, {})\n}\n\nfunction arrTolastURLElementMapper(arr) {\n    if (typeof arr === 'undefined' || arr.length === 0) return undefined\n\n    return arr.map(item => item.split('/').pop()?.trim() || '')\n}\n\nfunction arrToJoinedString(arr, joiner = '|') {\n    if (typeof arr === 'undefined' || arr.length === 0) return undefined\n\n    return arr.map(item => item.trim()).join(joiner)\n}\n\nfunction findTechnogiesText(arr) {\n    if (typeof arr === 'undefined' || arr.length === 0) return undefined\n\n    if (arr.length === 1) return cleanText(arrTolastURLElementMapper(arr)?.[0])\n    else return 'multiple'\n}\n\nfunction cleanText(str) {\n    if (typeof str === 'undefined') return undefined\n\n    return str.toString().trim()\n}\n\nconst generateEcommerceObject = async (productIds, options) => {\n    const productRequests = productIds.map(SKU => getProduct(SKU))\n    const productData = await Promise.all(productRequests)\n\n    return {\n        ecommerce: {\n            currency: window[window.config.padl.namespace].dataLayer.app.app.currency,\n            value: productData.reduce((ac, product) => {\n                return ac + product.price\n            }, 0),\n            items: productData.map((product, index) => {\n                if (product.type === 'bundle' || product.type === 'giftcard') {\n                    return {\n                        item_id: cleanText(product.internationalId),\n                        item_name: cleanText(product.internationalName),\n                        item_brand: 'nespresso',\n                        item_category: cleanText(product.type),\n                        index: index + 1\n                    }\n                }\n\n                let output = {\n                    item_id: cleanText(product.internationalId),\n                    item_name: cleanText(product.internationalName),\n                    item_brand: 'nespresso',\n                    item_category: cleanText(product.type),\n                    item_category2: arrToJoinedString(\n                        arrTolastURLElementMapper(product.technologies)\n                    ),\n                    item_category3: cleanText(product.category),\n                    price: product.price,\n                    quantity: product.salesMultiple,\n                    affiliation: 'nespresso online store',\n                    coupon: undefined,\n                    discount: undefined,\n                    location_id: undefined,\n                    item_list_name: cleanText(options?.listName),\n                    item_list_id: cleanText(options?.listId),\n                    index: index + 1,\n                    item_market_id: cleanText(product.legacyId),\n                    item_market_name: cleanText(product.name),\n                    item_technology: findTechnogiesText(product.technologies),\n                    item_range: cleanText(product.category),\n                    item_discovery_offer: product.category.includes('discovery').toString(),\n                    item_added_by_user: undefined,\n                    item_ecotax_applicable: product?.displayEcoTax\n                        ? cleanText(product?.displayEcoTax.toString())\n                        : undefined,\n                    item_selection_list: cleanText(arrToJoinedString(product.productSelections)),\n                    item_in_stock: product?.inStock\n                        ? cleanText(product?.inStock.toString())\n                        : undefined,\n                    item_subscription_name: undefined,\n                    item_subscription_category: undefined,\n                    item_subscription_price: undefined,\n                    item_subscription_duration: undefined,\n                    item_subscription_fee: undefined\n                }\n\n                switch (product.type) {\n                    case 'capsule': {\n                        const capsuleProduct = product\n\n                        output.item_category4 = capsuleProduct.bundled ? 'bundle' : 'single'\n\n                        output.item_type = capsuleProduct.bundled ? 'bundle' : 'single'\n\n                        output.item_coffee_aromatic_profile = cleanText(\n                            arrToJoinedString(capsuleProduct.capsuleProductAromatics)?.toLowerCase()\n                        )\n\n                        output.item_coffee_intensity =\n                            cleanText(capsuleProduct.capsuleProperties.intensity) ?? undefined\n\n                        output.item_coffee_cup_size = cleanText(\n                            arrToJoinedString(capsuleProduct.capsuleCupSizes)\n                        )?.toLowerCase()\n\n                        break\n                    }\n                    case 'machine': {\n                        const machineProduct = product\n\n                        output.item_machine_shade = cleanText(machineProduct.colorShade?.name)\n\n                        break\n                    }\n                }\n\n                if (product.type === 'machine' || product.type === 'accessory') {\n                    output.item_avg_rating = product.ratingCode\n                    output.item_number_of_reviews = product.ratingCode\n                }\n\n                return output\n            })\n        }\n    }\n}\n\nexport const selectItems = async (productIds, options) => {\n    const ecommerceObject = await generateEcommerceObject(productIds, options)\n\n    const output = {\n        event: 'select_item',\n        event_raised_by: options?.eventRaisedBy ?? 'before_cross_sell_v3',\n        click_location: options?.clickLocation ?? 'page builder cross sell quick view',\n        item_list_id: options?.listId ?? 'before_cross_sell_v3',\n        subscription_product_included: 'false',\n        discovery_offer_included: 'false',\n        ...ecommerceObject\n    }\n\n    window.gtmDataObject.push({ ecommerce: null })\n    window.gtmDataObject.push(output)\n}\n\nexport const viewItemList = async (productIds, options) => {\n    const ecommerceObject = await generateEcommerceObject(productIds, options)\n\n    const output = {\n        event: 'view_item_list',\n        event_raised_by: options?.eventRaisedBy,\n        subscription_product_included: 'false',\n        discovery_offer_included: 'false',\n        ...ecommerceObject\n    }\n\n    if (options?.eventRaisedBy === undefined) delete output.event_raised_by\n\n    window.gtmDataObject.push({ ecommerce: null })\n    window.gtmDataObject.push(output)\n}\n\nexport const isGtmTrackingExists = trackingData => {\n    window.gtmDataObject = window.gtmDataObject || []\n\n    return window.gtmDataObject.some(\n        event =>\n            event.event === trackingData.event &&\n            event.ecommerce?.creative_slot === trackingData.campaign.position &&\n            event.ecommerce?.promotion_id === trackingData.campaign.id &&\n            event.ecommerce?.promotion_name === trackingData.campaign.name &&\n            event.ecommerce?.creative_name === trackingData.campaign.creative\n    )\n}\n","export const getDataLayer = () => {\n    return window[window?.padlNamespace]?.dataLayer\n}\n\nexport const getMarketCode = () => {\n    const dataLayer = getDataLayer()\n    if (!dataLayer) {\n        return 'ch'\n    }\n\n    return dataLayer.app.app.market.toLocaleLowerCase()\n}\n\nexport const getLangCode = () => {\n    const dataLayer = getDataLayer()\n    if (!dataLayer) {\n        return 'en'\n    }\n\n    return getDataLayer().page.page.pageInfo.language.toLocaleLowerCase()\n}\n\nexport const getSegmentCode = () => {\n    const dataLayer = getDataLayer()\n    if (!dataLayer) {\n        return 'B2C'\n    }\n\n    return getDataLayer().page.page.pageInfo.segmentBusiness\n}\n\nexport const isLoggedIn = () => {\n    const dataLayer = getDataLayer()\n    if (!dataLayer || !dataLayer.user) {\n        return false\n    }\n\n    return dataLayer.user.isLoggedIn\n}\n\nexport const interpolateMarketLang = (string, market, lang) => {\n    return string.replace('{market}', market).replace('{lang}', lang)\n}\n","import { getMarketCode } from './dataLayer'\n\nconst LABEL_CATEGORY_NAME = 'cat/capsule-range-label'\nconst LABEL_CATEGORY_NAME_MACHINE = 'cat/machine-range-label'\nexport const RANGE_CATEGORY_NAME = 'cat/capsule-range'\nconst FAIR_TRADE_CATEGORY_NAME = 'cat/capsule-range-fair-trade'\nconst VERTUO_NEXT_CATEGORY_NAME = 'cat/capsule-attribute-only-vertuo-next'\nconst ORGANIC_EU_CATEGORY_NAME = 'capsule-attribute-organic-eu'\nconst RAINFOREST_CATEGORY_NAME = 'capsule-attribute-rainforest'\nconst SUSTAINABILITY_CATEGORY_NAME = 'capsule-attribute-sustainability'\nconst ARABICA_CATEGORY_NAME = 'capsule-attribute-arabica'\nconst PRODUCT_HIGHLIGHT_CATEGORY_NAME = 'cat/capsule-attribute-highlight'\nconst TECHNOLOGY_CATEGORY_IDENTIFIER = '/machineTechno/'\n\nconst COMMON_URL = 'https://www.nespresso.com/shared_res/agility/commons/img/icons/'\n\nexport const FAIR_TRADE_IMG = COMMON_URL + 'fairTrade.svg'\nexport const ORGANIC_LOGO_IMG_EU = COMMON_URL + 'logo-organic-eu.svg'\nexport const ORGANIC_LOGO_IMG_US = COMMON_URL + 'logo-organic-us.svg'\nexport const ORGANIC_LOGO_IMG_CA = COMMON_URL + 'logo-organic-ca.svg'\nexport const ORGANIC_LOGO_IMG_BR = COMMON_URL + 'logo-organic-br.svg'\nexport const ORGANIC_LOGO_IMG_JP = COMMON_URL + 'logo-organic-jp.svg'\nexport const ORGANIC_LOGO_IMG_BE = COMMON_URL + 'logo-organic-be.png'\n\nexport const VERTUONEXT_LOGO_IMG = COMMON_URL + 'logo-only-vertuo-next.svg'\nexport const RAINFOREST_LOGO_IMG = COMMON_URL + 'logo-rainforest.svg'\nexport const SUSTAINABILITY_LOGO_IMG = COMMON_URL + 'logo-sustainability.svg'\nexport const Q_CERTIFICATION_ARABICA_LOGO_IMG = COMMON_URL + 'q_grade_certification_arabica.svg'\nexport const DESIGN_AWARD_2021_IMG = COMMON_URL + 'design_award_2021.svg'\n\nexport const LOGO_IMG_MAP = {\n    fair_trade: FAIR_TRADE_IMG,\n    is_organic: getOrganicLogo(),\n    only_vertuo_next: VERTUONEXT_LOGO_IMG,\n    is_q_certified_arabica: Q_CERTIFICATION_ARABICA_LOGO_IMG,\n    is_rainforest: RAINFOREST_LOGO_IMG,\n    is_sustainable: SUSTAINABILITY_LOGO_IMG,\n    is_design_award_2021: DESIGN_AWARD_2021_IMG\n}\n\nexport function getOrganicLogo() {\n    let organicLogoImg = ORGANIC_LOGO_IMG_EU\n\n    switch (getMarketCode()) {\n        case 'us':\n            organicLogoImg = ORGANIC_LOGO_IMG_US\n            break\n        case 'ca':\n            organicLogoImg = ORGANIC_LOGO_IMG_CA\n            break\n        case 'br':\n            organicLogoImg = ORGANIC_LOGO_IMG_BR\n            break\n        case 'jp':\n            organicLogoImg = ORGANIC_LOGO_IMG_JP\n            break\n        case 'be':\n            organicLogoImg = ORGANIC_LOGO_IMG_BE\n            break\n    }\n\n    return organicLogoImg\n}\n\n/**\n * retrieves the list of categories of type Vertuo Next\n * @param {category[]} categories\n */\nexport function getVertuoNext(categories) {\n    return categories.find(category => isVertuoNext(category))\n}\n\n/**\n * returns true when the category is product vertuo next\n * @param {category} category\n */\nfunction isVertuoNext(category) {\n    return getCategoryRegEx(VERTUO_NEXT_CATEGORY_NAME).test(category.id)\n}\n\n/**\n * retrieves the list of categories of type organic EU\n * @param {category[]} categories\n */\nexport function getOrganicEu(categories) {\n    return categories.find(category => isOrganicEu(category))\n}\n\n/**\n * returns true when the category is product organic EU\n * @param {category} category\n */\nfunction isOrganicEu(category) {\n    return getCategoryRegEx(ORGANIC_EU_CATEGORY_NAME).test(category.id)\n}\n\n/**\n * retrieves the list of categories of type rainforest\n * @param {category[]} categories\n */\nexport function getRainforest(categories) {\n    return categories.find(category => isRainforest(category))\n}\n\n/**\n * returns true when the category is rainforest\n * @param {category} category\n */\nfunction isRainforest(category) {\n    return getCategoryRegEx(RAINFOREST_CATEGORY_NAME).test(category.id)\n}\n\n/**\n * retrieves the list of categories of type sustainability\n * @param {category[]} categories\n */\nexport function getSustainability(categories) {\n    return categories.find(category => isSustainability(category))\n}\n\n/**\n * retrieves the list of categories of type arabica\n * @param {category[]} categories\n */\nexport function getArabica(categories) {\n    return categories.find(category => isArabica(category))\n}\n\n/**\n * returns true when the category is arabica\n * @param {category} category\n */\nfunction isArabica(category) {\n    return getCategoryRegEx(ARABICA_CATEGORY_NAME).test(category.id)\n}\n\n/**\n * returns true when the category is sustainability\n * @param {category} category\n */\nfunction isSustainability(category) {\n    return getCategoryRegEx(SUSTAINABILITY_CATEGORY_NAME).test(category.id)\n}\n\n/**\n * retrieves the list of categories of type label\n * @param {category[]} categories\n */\nexport function getLabels(categories) {\n    return categories.filter(category => isLabel(category))\n}\n\n/**\n * retrieves the list of categories of type label\n * @param {category[]} categories\n */\nexport function getProductHighlight(categories) {\n    return categories.find(category => isProductHighlight(category))\n}\n/**\n * retrieves the list of categories of type label\n * @param {category[]} categories\n */\nexport function getFairTrade(categories) {\n    return categories.find(category => isFairTrade(category))\n}\n\n/**\n * returns a regex to match the tail (global) of a given local category ID\n * @param {string} categoryIdTail : should contain the end of the category ID\n */\nexport function getCategoryRegEx(categoryIdTail) {\n    return new RegExp(categoryIdTail.replace(/\\//g, '\\\\/'))\n}\n\n/**\n * returns true when the category is child of the label category (is type label)\n * @param {category} category\n */\nfunction isLabel(category) {\n    return (\n        getCategoryRegEx(LABEL_CATEGORY_NAME).test(category.id) ||\n        getCategoryRegEx(LABEL_CATEGORY_NAME_MACHINE).test(category.id)\n    )\n}\n\n/**\n * returns true when the category is product highlight\n * @param {category} category\n */\nfunction isProductHighlight(category) {\n    return getCategoryRegEx(PRODUCT_HIGHLIGHT_CATEGORY_NAME).test(category.id)\n}\n/**\n * returns true when the category is fair trade\n * @param {category} category\n */\nfunction isFairTrade(category) {\n    return getCategoryRegEx(FAIR_TRADE_CATEGORY_NAME).test(category.id)\n}\n\n/**\n * returns true when the category is child of the range category (is type range)\n * @param {category} category\n */\nexport function isRange(category) {\n    return category.superCategories.some(superCategory =>\n        getCategoryRegEx(RANGE_CATEGORY_NAME).test(superCategory)\n    )\n}\n\nexport function getTechnologyName(productData, categories) {\n    if (!productData || !productData.technologies || !productData.technologies.length) {\n        return null\n    }\n\n    const techno = productData.technologies[0]\n    const categoryNameAsSubstring = techno.substring(\n        techno.indexOf(TECHNOLOGY_CATEGORY_IDENTIFIER) + TECHNOLOGY_CATEGORY_IDENTIFIER.length\n    )\n    const category = categories?.find(cat => cat.id === techno)\n\n    // Backward compatibility, return name as substring if the list of categories are not available\n    return category?.name || categoryNameAsSubstring\n}\n\nexport function isCategoryHidden(categoryId) {\n    let hideCategory = false\n    // To enable AB testing: exclude categories which are to be hidden\n    if (\n        window.PLP_HIDE_CATEGORIES?.length &&\n        window.PLP_HIDE_CATEGORIES.findIndex(c => categoryId.indexOf(c) >= 0) >= 0\n    ) {\n        hideCategory = true\n    }\n\n    // To enable AB testing: exclude categories except those which are to be shown\n    if (window.PLP_ONLY_SHOW_CATEGORIES?.length) {\n        // Default to hide\n        hideCategory = true\n        if (window.PLP_ONLY_SHOW_CATEGORIES.findIndex(c => categoryId.indexOf(c) >= 0) >= 0) {\n            hideCategory = false\n        }\n    }\n    return hideCategory\n}\n","import { INTENSITY_MAX_OL, INTENSITY_MAX_VL } from '@kissui/components'\n\nexport const getMaxIntensity = ({ technologies }) =>\n    technologies.indexOf('original') !== -1 ? INTENSITY_MAX_OL : INTENSITY_MAX_VL\n","import { getFinalPrice } from '@kissui/plp/services'\nimport { isBundled } from '@kissui/helpers/src/catalog'\nimport { getMaxIntensity } from '@kissui/components/src/sku-coffee/services'\n\nexport const getMergedProductCoffeeData = (\n    product,\n    pageBuilderProductProps,\n    pageBuilderProps,\n    priceFormatter,\n    currency\n) => {\n    const { bundle_details } = pageBuilderProductProps\n    const { options } = pageBuilderProps\n    const { show_sleeve_price } = options\n\n    const isBundledResult = isBundled(product)\n\n    const { showCapsulePrice, price_per_capsule, final_price } = getFinalPrice(\n        show_sleeve_price,\n        product,\n        isBundled\n    )\n\n    const option = {\n        bundled: isBundledResult,\n        intensity: product.capsuleProperties?.intensity || product.intensity || null,\n        max_intensity: getMaxIntensity(product),\n        price_per_capsule: price_per_capsule\n            ? priceFormatter.short(currency, price_per_capsule)\n            : null,\n        show_capsule_price: showCapsulePrice\n    }\n\n    if (show_sleeve_price) {\n        option.price = priceFormatter.short(currency, final_price)\n    }\n\n    if (bundle_details) {\n        option.bundle_details = bundle_details\n    }\n\n    return option\n}\n","import {\n    getVertuoNext,\n    getOrganicEu,\n    getRainforest,\n    getLabels,\n    getProductHighlight,\n    getFairTrade,\n    getSustainability,\n    isRange,\n    getCategoryRegEx,\n    RANGE_CATEGORY_NAME,\n    getArabica\n} from '@kissui/helpers/src/cremaDataHelper'\n\n/**\n * Modifies the structure to make it easier to use in components\n * Applies all the data customization mixing Page builder with HMC data\n * @param {object} plpData : original PLP data\n */\nexport async function getMergedPLPData(plpData) {\n    const { data } = plpData\n    if (!data) {\n        return []\n    }\n\n    const eCommerceData = data.configuration.eCommerceData\n\n    addLabels(eCommerceData)\n\n    addProductAttribute(\n        eCommerceData,\n        getFairTrade,\n        (prod, category) => (prod.fairTrade = category.name)\n    )\n    addProductAttribute(eCommerceData, getProductHighlight, prod => (prod.highlighted = true))\n    addProductAttribute(eCommerceData, getVertuoNext, prod => (prod.onlyVertuoNext = true))\n    addProductAttribute(eCommerceData, getOrganicEu, prod => (prod.organicEu = true))\n    addProductAttribute(eCommerceData, getRainforest, prod => (prod.rainforest = true))\n    addProductAttribute(eCommerceData, getSustainability, prod => (prod.sustainability = true))\n    addProductAttribute(eCommerceData, getArabica, prod => (prod.arabica = true))\n\n    addSubSegments(eCommerceData)\n\n    return eCommerceData.categories\n}\n\nfunction addSubSegments(eCommerceData) {\n    const { categories, productGroups, products } = eCommerceData\n    // should be forEach if nothing returned/assigned\n    categories.forEach(category => {\n        const hasSegment = category.subCategories.length > 0 && isRange(category)\n        if (hasSegment) {\n            category.segments = category.subCategories.map(categoryId => {\n                const segment = categories.find(subCategory => subCategory.id === categoryId)\n                if (segment && isSubsegment(categories, segment)) {\n                    segment.products = getProductsData(productGroups, segment.id, products)\n                    segment.isSegment = true\n                }\n                return segment\n            })\n        }\n\n        category.products = getProductsData(productGroups, category.id, products)\n    })\n}\n\nexport function getProductsData(productGroups, categoryId, products) {\n    let result = []\n    try {\n        const currentCategory = productGroups.find(category => category.categoryId === categoryId)\n\n        if (!currentCategory) {\n            return result\n        }\n\n        const { productIds } = currentCategory\n        return productIds.map(productId => {\n            const product = products.find(product => product.id === productId)\n            return product\n        })\n    } catch (e) {\n        //generally an anti pattern to only log the error, with no try catch the result would be the same\n        console.log(e)\n    }\n\n    return result\n}\n\n/**\n * adds labels property to products containing each label's category data (JSON parsed description property) assigned to it\n * labels are categories that have the label base category as parent\n * to apply a label on a given product, the label has to contain the product\n * this function has to clean the productGroups as well by removing the label ones\n * @param {category[]} categories\n * @param {productGroup[]} productGroups\n * @param {product[]} products\n */\nfunction addLabels(eCommerceData) {\n    const { categories, productGroups, products } = eCommerceData\n    const labels = getLabels(categories)\n    const labelGroups = getLabelGroups(productGroups, labels)\n    labelGroups.forEach(group => {\n        const label = labels.find(label => label.id === group.categoryId)\n        group.productIds.forEach(productId => {\n            const prod = products.find(product => product.id === productId)\n            prod.labels = prod.labels || []\n            prod.labels.push(label.description)\n        })\n    })\n    //removing label categories from productGroups\n    labelGroups.forEach(labelGroup => {\n        const indexToRemove = productGroups.findIndex(\n            productGroup => productGroup.categoryId === labelGroup.categoryId\n        )\n        productGroups.splice(indexToRemove, 1)\n    })\n}\n\n/**\n * adds a property to products containing the given category assigned to it\n * The category is recognized by ID\n * to apply a the category on a given product, the category's productGroup has to contain the product\n * this function has to clean the productGroups as well by removing the given's one to not let it display as a range in the PLP\n * @param {category[]} categories\n * @param {productGroup[]} productGroups\n * @param {product[]} products\n */\nfunction addProductAttribute(eCommerceData, categoryFetcher, assignHandler) {\n    const { categories, productGroups, products } = eCommerceData\n    const category = categoryFetcher(categories)\n    if (!category) {\n        return\n    }\n    const categoryGroup = getCategoryGroup(productGroups, category)\n    if (!categoryGroup) {\n        return\n    }\n    categoryGroup.productIds.forEach(productId => {\n        const prod = products.find(product => product.id === productId)\n        if (categoryFetcher === getArabica) {\n            console.log('addProductAttribute', prod)\n        }\n        assignHandler(prod, category)\n    })\n    const indexToRemove = productGroups.findIndex(\n        productGroup => productGroup.categoryId === categoryGroup.categoryId\n    )\n    productGroups.splice(indexToRemove, 1)\n}\n\n/**\n * retrieve all the productGroup that are labels\n * @param {productGroup[]} productGroups\n * @param {category[]} labels\n */\nfunction getLabelGroups(productGroups, labels) {\n    return productGroups.filter(group => labels.some(label => label.id === group.categoryId))\n}\n\n/**\n * retrieve the productGroup which correspond to a category\n * @param {productGroup[]} productGroups\n * @param {category} fairTrade\n */\nfunction getCategoryGroup(productGroups, category) {\n    return productGroups.find(group => category.id === group.categoryId)\n}\n\n/**\n * returns true when the category is child of the range category (is type range)\n * @param {category} category\n */\nexport function isSubsegment(categories, category) {\n    /*category.superCategories.some(superCategoryId => {\n        const superCategoryData = categories.find(categoryToFind => categoryToFind.id === superCategoryId)\n    })*/\n    const result = category.superCategories.some(superCategory =>\n        getCategoryRegEx(RANGE_CATEGORY_NAME).test(superCategory)\n    )\n    return result\n}\nexport function getFinalPrice(show_sleeve_price, product, isBundled) {\n    let showCapsulePrice = show_sleeve_price\n    let final_price\n    let price_per_capsule\n\n    const bundled = isBundled(product)\n\n    if (product.type === 'capsule' && !bundled) {\n        final_price = product.price * product.salesMultiple\n        // this isn't necessary in prod but the mock price formatter needs it\n        final_price = Math.round(final_price * 100) / 100\n        price_per_capsule = product.price\n    } else {\n        showCapsulePrice = false\n        final_price = product.price\n    }\n\n    return { showCapsulePrice, final_price, price_per_capsule }\n}\n","import {\n    ECAPI_TYPE_ACCESSORY,\n    ECAPI_TYPE_CAPSULE,\n    ECAPI_TYPE_GIFT_CARD,\n    ECAPI_TYPE_MACHINE\n} from '@kissui/helpers/src/catalog'\n\nexport const getSkuComponentByType = ({ type, is_machine_b2b }) => {\n    let result = 'nb-sku'\n\n    if (type === ECAPI_TYPE_CAPSULE) {\n        result = 'nb-sku-coffee'\n    } else if (type === ECAPI_TYPE_MACHINE && is_machine_b2b) {\n        result = 'nb-sku-machine-b2b'\n    } else if (type === ECAPI_TYPE_MACHINE) {\n        result = 'nb-sku-machine'\n    } else if (type === ECAPI_TYPE_ACCESSORY) {\n        result = 'nb-sku-accessory'\n    } else if (type === ECAPI_TYPE_GIFT_CARD) {\n        result = 'nb-sku-gift-card'\n    }\n\n    return result\n}\n\nexport const apiOverride = (productData, pageBuilderData) => {\n    if (!productData || !pageBuilderData) {\n        return {}\n    }\n\n    const { images, name, headline, description } = productData\n    const { api_override } = pageBuilderData\n\n    if (!api_override) {\n        return {}\n    }\n\n    return {\n        image: api_override.image || images?.icon || images?.url || images?.push || images?.main,\n        name: api_override.name || name,\n        headline: api_override.headline || headline,\n        description: api_override.description || description\n    }\n}\n","import VideoCard from './video-card/video-card.composer'\nimport ImageCard from './image-card/image-card.composer'\nimport ProductCard from './product-card/product-card.composer'\nimport ProductSku from './product-sku/product-sku.composer'\nimport TextCard from './text-card/text-card.composer'\n\nexport default {\n    video: VideoCard,\n    image: ImageCard,\n    product: ProductCard,\n    productSku: ProductSku,\n    text: TextCard\n}\n","/**\n *\n * Card Video Props\n *\n * - cardSize\n * - contrast\n * - animated\n * - title\n * - description\n * - cta {}\n * - link {}\n * - background_retina\n * - background_desktop\n * - background_mobile\n * - video {}\n *\n */\nimport { stripHTML, makeHash, stringifyForAttribute } from '@kissui/helpers/src/utils'\nimport { dispatchEvent } from '@kissui/helpers/src/assets/js/eventDispatch'\nimport { EVENT_POPIN_OPEN } from '@kissui/components'\nimport './video-card.composer.scss'\nimport { renderCta, renderLink } from '../../helpers/renderButtons'\nimport { getImage } from '../../helpers/getImage'\nimport Card from '../card.class'\nimport { handlePromoClick } from '@kissui/helpers/src/gtmEvents'\n\nconst POPIN_ID = 'nb-videos-popin'\n\nexport default class extends Card {\n    render() {\n        const {\n            video: { auto_play = false }\n        } = this.props\n\n        return `${!auto_play ? this.renderDefaultCardVideo() : this.renderAutoPlayCardVideo()}`\n    }\n\n    renderAutoPlayCardVideo() {\n        const { video } = this.props\n\n        video.video_service = 'local'\n\n        if (!video.video_id) {\n            throw new Error('You must add the video ID and video service defined')\n        }\n\n        return `\n            <div class=\"card-video card-video__is-autoplay\">\n                <nb-video data=\"${stringifyForAttribute(video)}\"></nb-video>\n                <button id=\"autoplay-toggle\" class=\"autoplay-button video_button icon-pause\" aria-pressed=\"false\" data-status=\"pause\">\n                    <span class=\"video_button__icon\">\n                        <nb-icon icon=\"24/symbol/play-solid\" class=\"playButton\"></nb-icon>\n                        <nb-icon icon=\"24/symbol/pause-solid\" class=\"pauseButton\"></nb-icon>\n                    </span>\n                    <span class=\"sr-only\">Pause</span>\n                </button>\n            </div>`\n    }\n\n    renderDefaultCardVideo() {\n        const { video, contrast, cardSize, animated } = this.props\n\n        if (!video.video_id || !video.video_service) {\n            throw new Error('You must add the video ID and video service defined')\n        }\n\n        const image = getImage(this.props)\n        const backgroundImage = image ? `background-image:url(${image})` : null\n        this.elementId = 'play_' + this.createPopinID()\n\n        return `\n            <div class=\"card-video\"\n                 style=\"${backgroundImage}\"\n                 contrast=\"${contrast}\"\n                 card-size=\"${cardSize}\"\n                 animated=\"${animated}\"\n                 >\n\n                ${this.renderPlayButton(this.elementId)}\n                ${this.renderCardDisplay()}\n\n            </div>${this.renderPlayer()}`\n    }\n\n    renderCardDisplay() {\n        return `\n            <div class=\"card-video__display\">\n                    <div class=\"gradient\"></div>\n                    ${this.renderTitle()}\n                    ${this.renderDescription()}\n                    ${renderCta(this.props, 'card-image__action')}\n                    ${renderLink(this.props, 'card-image__action')}\n                </div>\n        `\n    }\n    renderPlayButton(elementId) {\n        return `\n            <div class=\"card-video__play\" play_id=\"${elementId}\">\n                <button class=\"card-video__videoIcon\">\n                    <nb-icon icon=\"24/symbol/play-solid\"></nb-icon>\n                    <span class=\"sr-only\">Play</span>\n                </button>\n            </div>\n        `\n    }\n\n    renderPlayer() {\n        const {\n            video: {\n                video_id,\n                video_mobile = '',\n                display_ui_controls,\n                cc_policy_language,\n                video_service\n            } = {}\n        } = this.props\n\n        const POPIN_ID = this.createPopinID()\n        return `<nb-popin id=\"${POPIN_ID}\" variation=\"before\" bgcolor=\"white\">\n                    <nb-video\n                        container_id=\"player-${POPIN_ID}\"\n                        video_id=\"${video_id}\"\n                        video_mobile=\"${video_mobile}\"\n                        video_service=\"${video_service}\"\n                        popin_id=\"${POPIN_ID}\"\n                        display_controls=\"${display_ui_controls}\"\n                        ccPolicy_language=\"${cc_policy_language}\"\n                        allow_popin_autoplay=\"true\"\n                    ></nb-video>\n                  </nb-popin>`\n    }\n\n    onOpenPlayer(e) {\n        const { campaign } = this.props\n\n        e.preventDefault()\n        const POPIN_ID = this.createPopinID()\n        dispatchEvent({ eventName: EVENT_POPIN_OPEN, args: { id: POPIN_ID } })\n        handlePromoClick({\n            campaign: campaign,\n            cta_name: `VIDEO - ${this.props.video.video_id}`\n        })\n    }\n\n    createPopinID() {\n        const {\n            title,\n            video: { video_id }\n        } = this.props\n        const seed = title || video_id\n        this.stripedHeading = stripHTML(seed).substr(0, 15)\n        return `video-card-${makeHash(this.stripedHeading)}-${video_id}`\n    }\n\n    removePlayer() {\n        const playerElement = document.querySelector(`#${POPIN_ID}`)\n        if (playerElement) {\n            playerElement.remove()\n        }\n    }\n\n    boundOnButtonSelfVideoClick(e) {\n        const targetElement = e.target || e.srcElement\n        const video = document.querySelector('.card-video__is-autoplay video')\n        const srOnly = document.querySelector('.sr-only')\n\n        if (targetElement.dataset.status === 'pause') {\n            video.pause()\n            targetElement.dataset.status = 'play'\n            targetElement.classList.remove('icon-pause')\n            targetElement.classList.add('icon-play')\n            srOnly.textContent = 'Play'\n        } else {\n            video.play()\n            targetElement.dataset.status = 'pause'\n            targetElement.classList.remove('icon-play')\n            targetElement.classList.add('icon-pause')\n            srOnly.textContent = 'Pause'\n        }\n    }\n\n    bindEvents() {\n        const elementId = 'play_' + this.createPopinID()\n\n        this.renderSelfVideoButton = document.querySelector('#autoplay-toggle')\n        if (this.renderSelfVideoButton) {\n            this.renderSelfVideoButton.addEventListener('click', this.boundOnButtonSelfVideoClick)\n        }\n\n        return [\n            {\n                id: `[play_id=\"${elementId}\"]`,\n                eventType: 'click',\n                cb: this.onOpenPlayer.bind(this)\n            }\n        ]\n    }\n\n    renderTitle() {\n        const { title } = this.props\n        if (!title) {\n            return ''\n        }\n\n        return `<h3 class=\"h-lg-500\">${title}</h3>`\n    }\n\n    renderDescription() {\n        const { description } = this.props\n        if (!description) {\n            return ''\n        }\n\n        return `<p class=\"t-sm-400\">${description}</p>`\n    }\n}\n","/**\n *\n * Card Image Props\n *\n * - cardSize\n * - contrast\n * - animated\n * - title\n * - description\n * - cta {}\n * - link {}\n * - background_retina\n * - background_desktop\n * - background_mobile\n *\n */\n\nimport './image-card.composer.scss'\nimport Card from '../card.class'\n\nimport { renderCta, renderLink } from '../../helpers/renderButtons'\nimport { getImage } from '../../helpers/getImage'\n\nexport default class extends Card {\n    render() {\n        const { animated, contrast, cardSize, title = '', description = '' } = this.props\n\n        const image = getImage(this.props)\n        const backgroundImage = `background-image:url(${image})`\n\n        return `<div class=\"card-image\"\n            style=\"${backgroundImage}\"\n            animated=\"${animated}\"\n            contrast=\"${contrast}\"\n            card-size=\"${cardSize}\"\n            >\n                    <div class=\"card-image__wrapper\">\n                        <div class=\"card-image__display\">\n                            ${title && `<h3 class=\"card-image__title h-lg-500\">${title}</h3>`}\n                            ${description && `<p class=\"t-sm-400\">${description}</p>`}\n                            ${renderCta(this.props, 'card-image__action')}\n                            ${renderLink(this.props, 'card-image__action')}\n                        </div>\n                    </div>\n                    ${this.renderPopin()}\n                </div>`\n    }\n\n    renderPopin() {\n        const { cta, popin = {} } = this.props\n        const {\n            id = '',\n            image = '',\n            heading = '',\n            description = '',\n            image_alt = '',\n            close = ''\n        } = popin\n\n        if (!id || !cta.popin_id) {\n            return ''\n        }\n\n        return `<nb-popin\n                    id=\"${cta.popin_id}\"\n                    heading=\"${heading}\"\n                    variation=\"right\"\n                    bgcolor=\"highlight\"\n                    image=\"${image}\"\n                    image_alt=\"${image_alt}\"\n                    label_close=\"${close}\"\n                    size=\"SS\">\n                        ${description}\n                </nb-popin>`\n    }\n}\n","/**\n *\n * Card Product Props\n *\n * - cardSize\n * - contrast\n * - heading\n * - title\n * - cta {}\n * - background_color\n * - background_retina\n * - background_desktop\n * - background_mobile\n *\n */\n\nimport './product-card.composer.scss'\nimport Card from '../card.class'\n\nimport { renderCta } from '../../helpers/renderButtons'\nimport { getImage } from '../../helpers/getImage'\n\nexport default class extends Card {\n    render() {\n        const {\n            heading = '',\n            title = '',\n            productImage,\n            productImageAlt = '',\n            cardSize,\n            contrast\n        } = this.props\n\n        const cardSizeAtrb = cardSize ? `card-size='${cardSize}'` : ``\n        const image = getImage(this.props)\n        const backgroundImage = image ? `background-image:url(${image});` : ``\n        const backgroundColor = this.props['background_color']\n            ? `background-color:${this.props['background_color']};`\n            : ``\n\n        return `<div\n                    class=\"card-product\"\n                    style=\"${backgroundImage + backgroundColor}\"\n                    ${cardSizeAtrb}\n                    contrast=\"${contrast}\">\n                    <div class=\"card-product\">\n                        <div class=\"card-product__display\">\n                            <div class=\"card-product__item card-product__image\">\n                                <img class=\"card-product__item\"\n                                    src=\"${productImage}\"\n                                    alt=\"${productImageAlt}\"\n                                    height=\"150\"\n                                />\n                            </div>\n                            ${\n                                heading &&\n                                `<h3 class=\"t-xs-500-caps-sl card-product__item card-product__heading\">${heading}</h3>`\n                            }\n                            ${\n                                title &&\n                                `<h4 class=\"h-xl-700 card-product__item card-product__title\">${title}</h4>`\n                            }\n                            ${renderCta(this.props, 'card-product__item card-product__action')}\n                        </div>\n                    </div>\n                </div>`\n    }\n}\n","/**\n *\n * Card Product SKU Props\n *\n * - cardSize\n * - contrast\n * - heading\n * - title\n * - cta {}\n * - background_color\n * - background_retina\n * - background_desktop\n * - background_mobile\n *\n */\n\nimport './product-sku.composer.scss'\nimport Card from '../card.class'\n\nimport { makeId } from '@kissui/helpers/src/utils'\nimport { renderLink } from '../../helpers/renderButtons'\nimport { getImage } from '../../helpers/getImage'\nimport { getCurrency, getPriceFormatter, getProduct } from '@kissui/helpers/src/catalog'\nimport { getMergedProductData } from '@kissui/page-builder-sections/src/cross-sell-natural/dataTransform'\n\nexport default class extends Card {\n    async getSkuQuickViewData(sku, popinId, props) {\n        try {\n            const payload = await getProduct(sku)\n\n            if (!payload) {\n                return\n            }\n\n            const CARD_ID = `cardId_${popinId}`\n            const quickViewProps = await this.getSkuQuickViewProp(popinId, props, payload)\n\n            let quickViewElement = document.createElement('nb-sku-quick-view')\n            quickViewElement.setAttribute('data', JSON.stringify(quickViewProps))\n            quickViewElement.setAttribute('id', popinId)\n\n            const card = document.getElementById(CARD_ID)\n            card.appendChild(quickViewElement)\n        } catch (e) {\n            console.error(`getProduct fail on sku ${sku}`)\n        }\n    }\n\n    getCapsuleFeatures(capsuleProperties) {\n        return {\n            acidity: { value: capsuleProperties?.acidity },\n            bitterness: { value: capsuleProperties?.bitterness },\n            body: { value: capsuleProperties?.body },\n            capsuleProperties: { intensity: capsuleProperties?.intensity },\n            roast: { value: capsuleProperties?.roastLevel }\n        }\n    }\n\n    async getSkuQuickViewProp(popinId, product, skuData) {\n        const { sku_quick_view } = product\n\n        this.priceFormatter = await getPriceFormatter()\n        this.currency = getCurrency()\n\n        const productInfo = await getProduct(product.sku)\n        const mergedProductData = getMergedProductData(\n            productInfo,\n            product,\n            this.props,\n            this.priceFormatter,\n            this.currency\n        )\n\n        const props = {\n            popin: {\n                popin_id: popinId,\n                close: sku_quick_view.popin.close,\n                footer: true\n            },\n            product: {\n                ...product,\n                ...skuData,\n                ...this.getCapsuleFeatures(skuData.capsuleProperties)\n            },\n            intensity: {\n                intensity_label: 'Intensity',\n                a11y_intensity_max: 'max of {max_intensity}'\n            },\n            cup_sizes: {\n                ...sku_quick_view.cup_sizes,\n                items: product.cupSizesDetails\n            },\n            aromatic_profile: {\n                ...sku_quick_view.aromatic_profile,\n                items: mergedProductData.capsuleProductAromatics\n            },\n            link: {\n                ...sku_quick_view.link,\n                url: mergedProductData.pdpURLs.desktop\n            },\n            levels: {\n                ...sku_quick_view.levels\n            },\n            pricing: {\n                add_to_cart: {\n                    sku: mergedProductData.sku,\n                    longSku: mergedProductData.longSku,\n                    category_name: mergedProductData.categoryName,\n                    position: '',\n                    variation: 'small',\n                    price: mergedProductData.price,\n                    strikethrough_price: mergedProductData.strikethrough_price,\n                    hidePrice: mergedProductData.hidePrice,\n                    url: '',\n                    view_details_label: 'View details',\n                    rendererName: ''\n                },\n                showSleeve: {},\n                showCapsulePrice: {}\n            }\n        }\n\n        return props\n    }\n\n    render() {\n        const {\n            heading = '',\n            title = '',\n            productImage,\n            productImageAlt = '',\n            cardSize,\n            contrast,\n            sku\n        } = this.props\n\n        const popinId = `popin-product-sku-${makeId(5)}`\n\n        this.getSkuQuickViewData(sku, popinId, this.props)\n\n        const cardSizeAtrb = cardSize ? `card-size='${cardSize}'` : ``\n        const image = getImage(this.props)\n        const backgroundImage = image ? `background-image:url(${image});` : ``\n        const backgroundColor = this.props['background_color']\n            ? `background-color:${this.props['background_color']};`\n            : ``\n\n        return `<div\n                    class=\"card-product\"\n                    style=\"${backgroundImage + backgroundColor}\"\n                    ${cardSizeAtrb}\n                    contrast=\"${contrast}\"\n                    id=\"cardId_${popinId}\"\n                >\n                    <div class=\"card-product\">\n                        <div class=\"card-product__display\">\n                            <div class=\"card-product__item card-product__image\">\n                                <img class=\"card-product__item\"\n                                    src=\"${productImage}\"\n                                    alt=\"${productImageAlt}\"\n                                    height=\"150\"\n                                />\n                            </div>\n                            ${\n                                heading &&\n                                `<h3 class=\"t-xs-500-caps-sl card-product__item card-product__heading\">${heading}</h3>`\n                            }\n                            ${\n                                title &&\n                                `<h4 class=\"h-xl-700 card-product__item card-product__title\">${title}</h4>`\n                            }\n                            ${renderLink(\n                                this.props,\n                                'card-product__item card-product__action link-button--tertiary',\n                                popinId\n                            )}\n                        </div>\n                    </div>\n                </div>`\n    }\n}\n","import { sanitizeString } from '@kissui/helpers/src/utils'\nimport { getMergedProductCoffeeData } from './product.coffee.dto'\nimport { getMergedProductMachineData } from './product.machine.dto'\nimport { VARIATION_PLP } from '@kissui/components/src/sku/constants'\nimport { getMergedProductGiftCardData } from './product.giftCard.dto'\nimport { getMergedProductAccessoryData } from './product.accessory.dto'\nimport { apiOverride } from '@kissui/components/src/sku/services'\nimport {\n    ECAPI_TYPE_ACCESSORY,\n    ECAPI_TYPE_CAPSULE,\n    ECAPI_TYPE_GIFT_CARD,\n    ECAPI_TYPE_MACHINE\n} from '@kissui/helpers/src/catalog'\n\nexport const getMergedProductData = (\n    product,\n    pageBuilderProductProps,\n    pageBuilderProps,\n    priceFormatter,\n    currency\n) => {\n    const { options } = pageBuilderProps\n    const {\n        variant = {},\n        labels = [],\n        strikethrough_price,\n        additional_message,\n        additional_message_icon,\n        additional_message_link,\n        contact_cta\n    } = pageBuilderProductProps || {}\n\n    // lists header props not coming from this.props\n    let data = {\n        sku: product.internationalId,\n        technologies: product.technologies,\n        longSku: product.id,\n        name: product.name,\n        headline: sanitizeString(product.headline),\n        sales_multiple: product.salesMultiple,\n        unit_quantity: product.unitQuantity,\n        type: product.type,\n        category_name: product.rangeData?.name || '',\n        label_range: product.rangeData?.name || '',\n        price: product.price ? priceFormatter.short(currency, product.price) : null,\n        rawPrice: product.price,\n        strikethrough_price: strikethrough_price || '',\n        variation: VARIATION_PLP,\n        image_alt_text: product.name,\n        image: product.images?.icon || product.images?.push || product.images?.main,\n        additional_message: additional_message || '',\n        additional_message_icon: additional_message_icon || '',\n        additional_message_link: additional_message_link || {},\n        contact_cta: contact_cta || {},\n        ...apiOverride(product, pageBuilderProductProps)\n    }\n\n    if (labels && labels.length) {\n        data.labels = labels\n    }\n\n    if (product.highlighted) {\n        data.highlighted = product.highlighted\n    }\n\n    let dataTransformObjectProductType = {}\n    if (product.type === ECAPI_TYPE_CAPSULE) {\n        dataTransformObjectProductType = getMergedProductCoffeeData(\n            product,\n            pageBuilderProductProps,\n            pageBuilderProps,\n            priceFormatter,\n            currency\n        )\n    } else if (product.type === ECAPI_TYPE_MACHINE) {\n        dataTransformObjectProductType = getMergedProductMachineData(\n            product,\n            pageBuilderProductProps,\n            pageBuilderProps\n        )\n    } else if (product.type === ECAPI_TYPE_ACCESSORY) {\n        dataTransformObjectProductType = getMergedProductAccessoryData(\n            product,\n            pageBuilderProductProps,\n            pageBuilderProps\n        )\n    } else if (product.type === ECAPI_TYPE_GIFT_CARD) {\n        dataTransformObjectProductType = getMergedProductGiftCardData(\n            product,\n            pageBuilderProductProps,\n            pageBuilderProps\n        )\n    }\n\n    return {\n        ...product,\n        ...options,\n        ...variant,\n        ...data,\n        ...dataTransformObjectProductType\n    }\n}\n","export const VARIATION_PLP = 'plp'\nexport const VARIATION_PDP = 'pdp'\nexport const VARIATION_CROSS_SELL = 'cross-sell'\nexport const VARIATION_SMALL = 'small'\n","export const getMergedProductMachineData = (product, pageBuilderProductProps, pageBuilderProps) => {\n    const { strikethrough_price, variant = {} } = pageBuilderProductProps\n    const { ratingsAndReviews } = product\n\n    // lists header props not coming from this.props\n    const options = {\n        ratings: ratingsAndReviews\n    }\n\n    if (variant?.colors) {\n        options.colors = variant.colors\n        options.activeSku = product.internationalId\n        options.max_colors = 99\n    }\n\n    options.strikethrough_price = strikethrough_price || ''\n    options.show_ratings = (pageBuilderProps && pageBuilderProps.options.show_ratings) || false\n    options.minimum_rating = (pageBuilderProps && pageBuilderProps.options.minimum_rating) || 0\n\n    return options\n}\n","export const getMergedProductAccessoryData = () => ({})\n","export const getMergedProductGiftCardData = (_, pageBuilderProductProps) => {\n    const { variant = {} } = pageBuilderProductProps\n\n    return {\n        image: variant && variant.default_image\n    }\n}\n","/**\n *\n * Card Text Props\n *\n * - cardSize\n * - contrast\n * - icon {}\n * - heading\n * - title\n * - description\n * - link\n * - cta\n * - background_color\n * - background_retina\n * - background_desktop\n * - background_mobile\n *\n */\n\nimport './text-card.composer.scss'\nimport Card from '../card.class'\n\nimport { renderCta, renderLink } from '../../helpers/renderButtons'\nimport { getImage } from '../../helpers/getImage'\n\nexport default class extends Card {\n    render() {\n        const {\n            heading = '',\n            title = '',\n            description = '',\n            icon = '',\n            background_color,\n            cardSize,\n            contrast\n        } = this.props\n\n        const backgroundColorStyle = background_color\n            ? `background-color: ${background_color};`\n            : ''\n        const image = getImage(this.props)\n        const backgroundImage = image ? `background-image:url(${image});` : ''\n\n        return `<div class=\"card-text\" contrast=\"${contrast}\" style=\"${backgroundColorStyle}${backgroundImage}\" card-size=\"${cardSize}\">\n                    <div class=\"card-text\">\n                        <div class=\"card-text__display\">\n                            ${\n                                icon &&\n                                `<div class=\"card-text__item card-text__icon\">\n                            <nb-icon icon=\"${icon}\"></nb-icon>\n                        </div>`\n                            }\n                            ${\n                                heading &&\n                                `<h4 class=\"t-xs-700-caps-sl card-text__item card-text__heading\">${heading}</h4>`\n                            }\n                            ${\n                                title &&\n                                `<h3 class=\"h-xl-300 card-text__item card-text__title\">${title}</h3>`\n                            }\n                            ${\n                                description &&\n                                `<p class=\"t-sm-400 card-text__item card-text__body\">${description}</p>`\n                            }\n                            ${renderCta(this.props, 'card-text__item card-text__action')}\n                            ${renderLink(this.props, 'card-text__item card-text__action')}\n                        </div>\n                    </div>\n                ${this.renderPopin()}\n                </div>`\n    }\n\n    renderPopin() {\n        const { cta, popin = {} } = this.props\n        const {\n            id = '',\n            image = '',\n            heading = '',\n            description = '',\n            image_alt = '',\n            close = ''\n        } = popin\n\n        if (!id || !cta.popin_id) {\n            return ''\n        }\n\n        return `<nb-popin\n                    id=\"${cta.popin_id}\"\n                    heading=\"${heading}\"\n                    variation=\"right\"\n                    bgcolor=\"highlight\"\n                    image=\"${image}\"\n                    image_alt=\"${image_alt}\"\n                    label_close=\"${close}\"\n                    size=\"SS\">\n                        ${description}\n                </nb-popin>`\n    }\n}\n","export default [\n    'one',\n    'three-equal',\n    'two-equal',\n    'two-x2-right-bigger',\n    'two-x2-left-bigger',\n    'right-big-square',\n    'left-big-square'\n]\n","/*!\n * swiped-events.js - v@version@\n * Pure JavaScript swipe events\n * https://github.com/john-doherty/swiped-events\n * @inspiration https://stackoverflow.com/questions/16348031/disable-scrolling-when-touch-moving-certain-element\n * @author John Doherty <www.johndoherty.info>\n * @license MIT\n */\n\n// scrollElement has been added as an optional parameter in order to avoid scrolling to fire a swipe\nconst swipeEvents = (window: Window & typeof globalThis, document: Document, stopEl?: HTMLElement) => {\n    if (window.nwcSwipeEvents) {\n        return\n    }\n    window.nwcSwipeEvents = true\n\n    // patch CustomEvent to allow constructor creation (IE/Chrome)\n    // if (typeof window.CustomEvent !== 'function') {\n    //     window.CustomEvent = function(event, params) {\n    //         params = params || {bubbles: false, cancelable: false, detail: undefined}\n    //\n    //         let evt = document.createEvent('CustomEvent')\n    //         evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail)\n    //         return evt\n    //     }\n    //\n    //     window.CustomEvent.prototype = window.Event.prototype\n    // }\n\n    document.addEventListener('touchstart', handleTouchStart, false)\n    document.addEventListener('touchmove', handleTouchMove, false)\n    document.addEventListener('touchend', handleTouchEnd, false)\n\n    let xDown: null | number = null\n    let yDown: null | number = null\n    let xDiff: null | number = null\n    let yDiff: null | number = null\n    let timeDown: null | number = null\n    let startEl: HTMLElement | null = null\n\n    // Variables added for checkScrollConditions\n    let scrollTopArray: number[] = []\n    let scrollLeftArray: number[] = []\n\n    /**\n     * Avoid swipe up or down events to fire by checking the scrollTop position of the optional param scrollEl (scrollable zone)\n     * @param {string} direction - 'up' ,'down', 'left', 'right'\n     * @returns {boolean}\n     */\n    function checkScrollCondition(direction: \"up\" |\"down\" | \"left\" | \"right\", e: TouchEvent) {\n        if (stopEl === undefined) {\n            return true\n        }\n\n        let el = e.target as HTMLElement\n        let result = true\n        let i = 0\n        while (el !== stopEl && result) {\n            if (isScrollable(el)) {\n                switch (direction) {\n                    case 'up':\n                        result = scrollTopArray[i] === el.scrollHeight - el.clientHeight\n                        break\n                    case 'down':\n                        result = scrollTopArray[i] === 0\n                        break\n                    case 'left':\n                        result = scrollLeftArray[i] === el.scrollWidth - el.clientWidth\n                        break\n                    case 'right':\n                        result = scrollLeftArray[i] === 0\n                        break\n                    default:\n                        result = true\n                }\n            }\n            el = el.parentNode as HTMLElement\n            i++\n        }\n        return result\n    }\n\n    function memorizeStartElScrollPositions(el: HTMLElement) {\n        if (stopEl === undefined || !stopEl.contains(el)) {\n            return\n        }\n        scrollTopArray = []\n        scrollLeftArray = []\n        while (el !== stopEl) {\n            scrollTopArray.push(el.scrollTop)\n            scrollLeftArray.push(el.scrollLeft)\n            el = el.parentNode as HTMLElement\n        }\n    }\n\n    function isScrollable(el: HTMLElement) {\n        return el.scrollHeight > el.clientHeight || el.scrollWidth > el.clientWidth\n    }\n\n    /**\n     * Fires swiped event if swipe detected on touchend\n     * @param {object} e - browser event object\n     * @returns {void}\n     */\n    function handleTouchEnd(e: TouchEvent) {\n        // if the user released on a different target, cancel!\n        if (startEl !== e.target) {\n            return\n        }\n\n        // Calculate the data-swipe-threshold to be a percentage of the viewport\n        const defaultVertical = window.innerHeight * 0.25 // 25% of the viewport\n        const defaultHorizontal = window.innerWidth * 0.5 // 50% of the viewport\n\n        let swipeThresholdVertical =\n            getNearestAttribute(startEl!, 'data-swipe-threshold', defaultVertical)\n\n        let swipeThresholdHorizontal =\n            getNearestAttribute(startEl!, 'data-swipe-threshold', defaultHorizontal)\n\n        let swipeTimeout = getNearestAttribute(startEl!, 'data-swipe-timeout', 500) // default 500ms\n        let timeDiff = Date.now() - timeDown!\n        let eventType = ''\n        let changedTouches = e.changedTouches || e.touches || []\n\n        if (Math.abs(xDiff!) > Math.abs(yDiff!)) {\n            // most significant\n            if (Math.abs(xDiff!) > swipeThresholdHorizontal && timeDiff < swipeTimeout) {\n                if (xDiff! > 0) {\n                    if (checkScrollCondition('left', e)) {\n                        eventType = 'swiped-left'\n                    }\n                } else {\n                    if (checkScrollCondition('right', e)) {\n                        eventType = 'swiped-right'\n                    }\n                }\n            }\n        } else if (Math.abs(yDiff!) > swipeThresholdVertical && timeDiff < swipeTimeout) {\n            if (yDiff! > 0) {\n                if (checkScrollCondition('up', e)) {\n                    eventType = 'swiped-up'\n                }\n            } else {\n                if (checkScrollCondition('down', e)) {\n                    eventType = 'swiped-down'\n                }\n            }\n        }\n\n        if (eventType !== '') {\n            let eventData = {\n                dir: eventType.replace(/swiped-/, ''),\n                touchType: (changedTouches[0] as Touch & { touchType: string })?.touchType ?? 'direct', // This is a non standard feature used only by safari\n                xStart: xDown!,\n                xEnd: (changedTouches[0] || {}).clientX || -1,\n                yStart: yDown!,\n                yEnd: (changedTouches[0] || {}).clientY || -1\n            }\n\n            // fire `swiped` event event on the element that started the swipe\n            startEl!.dispatchEvent(\n                new CustomEvent('swiped', { bubbles: true, cancelable: true, detail: eventData })\n            )\n\n            // fire `swiped-dir` event on the element that started the swipe\n            startEl!.dispatchEvent(\n                new CustomEvent(eventType, { bubbles: true, cancelable: true, detail: eventData })\n            )\n        }\n\n        // reset values\n        xDown = null\n        yDown = null\n        timeDown = null\n    }\n\n    /**\n     * Records current location on touchstart event\n     * @param {object} e - browser event object\n     * @returns {void}\n     */\n    function handleTouchStart(e: TouchEvent) {\n        const target = e.target as HTMLElement\n        // if the element has data-swipe-ignore=\"true\" we stop listening for swipe events\n        if (target.getAttribute('data-swipe-ignore') === 'true') {\n            return\n        }\n\n        startEl = target\n        memorizeStartElScrollPositions(startEl)\n\n        timeDown = Date.now()\n        xDown = e.touches[0].clientX\n        yDown = e.touches[0].clientY\n        xDiff = 0\n        yDiff = 0\n    }\n\n    /**\n     * Records location diff in px on touchmove event\n     * @param {object} e - browser event object\n     * @returns {void}\n     */\n    function handleTouchMove(e: TouchEvent) {\n        if (!xDown || !yDown) {\n            return\n        }\n\n        let xUp = e.touches[0].clientX\n        let yUp = e.touches[0].clientY\n\n        xDiff = xDown - xUp\n        yDiff = yDown - yUp\n    }\n\n    /**\n     * Gets attribute off HTML element or nearest parent\n     * @param {object} el - HTML element to retrieve attribute from\n     * @param {string} attributeName - name of the attribute\n     * @param {any} defaultValue - default value to return if no match found\n     * @returns {any} attribute value or defaultValue\n     */\n    function getNearestAttribute(el: HTMLElement, attributeName: string | number, defaultValue: number) {\n        // walk up the dom tree looking for attributeName\n        while (el && el !== document.documentElement) {\n            let attributeValue = el.getAttribute(String(attributeName))\n\n            if (attributeValue) {\n                return parseInt(attributeValue, 10)\n            }\n\n            el = el.parentNode as HTMLElement\n        }\n\n        return defaultValue\n    }\n}\n\nexport default swipeEvents\n","export function recursiveSwitchAriaHidden(elem, componentOpenState) {\n    const parent = elem.parentNode\n    const body = document.getElementsByTagName('body')[0]\n\n    if (parent === body) {\n        return\n    }\n\n    const brothers = parent.children\n    for (const brother of brothers) {\n        if (brother !== elem) {\n            componentOpenState\n                ? brother.setAttribute('aria-hidden', componentOpenState)\n                : brother.removeAttribute('aria-hidden')\n        }\n    }\n    recursiveSwitchAriaHidden(parent, componentOpenState)\n}\n\nexport function focusin(e, el, loop) {\n    if (!el.contains(e.target)) {\n        if (el.lastFocused === el.firstFocusable) {\n            loop ? el.lastFocusable.focus() : el.firstFocusable.focus()\n        } else {\n            loop ? el.firstFocusable.focus() : el.lastFocusable.focus()\n        }\n    } else {\n        el.lastFocused = e.target\n    }\n}\n\nexport function setFirstAndLastFocusable(el) {\n    const focusable = el.querySelectorAll('button, [href], input, select, textarea, [tabindex=\"0\"]')\n    el.firstFocusable = focusable[0]\n    el.lastFocusable = focusable[focusable.length - 1]\n    el.lastFocused = el.firstFocusable\n}\n","import './overlay.scss'\nimport { dispatchEvent } from '@kissui/helpers/src/assets/js/eventDispatch'\nimport { EVENT_POPIN_CLOSE, TIME_INSTANT, TIME_SLOW } from '@kissui/components'\n\nconst open = popin_id => {\n    const overlay = document.createElement('DIV')\n    overlay.classList.add('nb-overlay')\n    overlay.addEventListener('click', () => {\n        dispatchEvent({ eventName: EVENT_POPIN_CLOSE, args: { id: popin_id } })\n    })\n    document.body.appendChild(overlay)\n    setTimeout(() => {\n        overlay.classList.add('fadein')\n    }, TIME_INSTANT)\n}\n\nconst close = () => {\n    if (!document.getElementsByClassName('nb-overlay').length) {\n        return\n    }\n    const overlay = document.getElementsByClassName('nb-overlay')[0]\n    overlay.classList.remove('fadein')\n    setTimeout(() => {\n        overlay.remove()\n    }, TIME_SLOW)\n}\n\nexport default { open, close }\n","import swipeEvents from '@kissui/helpers/src/swipeEvents'\nimport createProps, { parseBool } from '@kissui/helpers/src/props.helpers'\nimport {\n    recursiveSwitchAriaHidden,\n    setFirstAndLastFocusable,\n    focusin\n} from '@kissui/helpers/src/assets/js/scopedKeyboardNav'\nimport {\n    TIME_FAST,\n    EVENT_POPIN_OPENED,\n    EVENT_POPIN_CLOSED,\n    EVENT_VIDEO_TOGGLE,\n    EVENT_POPIN_OPEN,\n    EVENT_POPIN_CLOSE,\n    EVENT_POPIN_KEY_DOWN,\n    EVENT_SWIPED_DOWN\n} from '@kissui/components'\nimport Overlay from './components/overlay'\nimport viewportHelper from '@kissui/helpers/src/viewport.helpers'\nimport { dispatchEvent, readEvent } from '@kissui/helpers/src/assets/js/eventDispatch'\n\nconst STATE_OPEN = 'isOpen'\nconst SCROLL_LOCK = 'scroll-lock'\n\nclass Popin extends HTMLElement {\n    constructor() {\n        super()\n        this.props = {}\n        this.ariaModal = null\n        this.isVideo = null\n\n        this.boundOpen = this.open.bind(this)\n        this.boundClose = this.close.bind(this)\n        this.boundEscapeClose = this.escapeClose.bind(this)\n        this.boundFocus = this.focus.bind(this)\n        this.boundFocusin = this.focusin.bind(this)\n    }\n\n    connectedCallback() {\n        this.style.display = 'none'\n        this.props = createProps(this.attributes)\n\n        if (!this.id) {\n            this.id = this.props.id\n        }\n\n        if (!this.content && !this.slot) {\n            this.slot = this.innerHTML\n        }\n\n        this.ariaModal = false\n        this.isVideo = false\n        this.render()\n    }\n\n    attributeChangedCallback(name, oldValue, newValue) {\n        this.props = createProps(this.attributes)\n\n        if (name === 'content') {\n            this.props.content = newValue\n        }\n    }\n\n    static get observedAttributes() {\n        return ['content']\n    }\n\n    disconnectedCallback() {\n        if (!this.hasEvent) {\n            return\n        }\n        this.unbindEvent()\n    }\n\n    render() {\n        if (this.hasEvent) {\n            this.unbindEvent()\n        }\n        const {\n            heading = '',\n            subheading = '',\n            bgcolor = 'highlight',\n            size = 'M',\n            label_close = 'Close',\n            image = '',\n            image_alt = '',\n            variation = 'before',\n            content = '',\n            heading_class = viewportHelper.is.mobile ? 't-sm-700-sl' : 'h-lg-700'\n        } = this.props\n        const slot = content || this.slot\n\n        if (slot === '') {\n            this.bindEvent()\n            this.classList.remove(STATE_OPEN)\n            this.isOpen = false\n            return false\n        }\n        this.checkIsVideo(slot)\n        this.setAttribute('size', this.isVideo ? 'L' : size)\n\n        // FYI : The role is dialog, not alertdialog (only used for alerts / warnings ...)\n        this.setAttribute('role', 'dialog')\n        this.setAttribute('aria-hidden', 'true')\n        this.setAttribute('bgcolor', bgcolor)\n        this.setAttribute('variation', variation)\n\n        // Be careful to not remove the title div, even if empty, because it holds on purpose the top gradient for scroll effect\n        this.innerHTML = `\n            <nb-cta\n                variation=\"navigation\"\n                ${bgcolor === 'white' ? `contrast=\"highlight\"` : `contrast=\"light\"`}\n                icon_right=\"24/symbol/close\"\n                label=\"${label_close}\"></nb-cta>\n            <div class=\"wrapper\">\n                ${\n                    heading &&\n                    `<div class=\"title\" >\n                        ${heading && `<h2 class=\"${heading_class}\">${heading}</h2>`}\n                    </div>`\n                }\n                ${\n                    subheading &&\n                    `<div class=\"subtitle\">\n                            ${subheading && `<p class=\"t-sm-500\">${subheading}</p>`}\n                    </div>`\n                }\n\n                <div class=\"content t-sm-400\" tabindex=\"-1\">\n                    ${\n                        image &&\n                        `<div class=\"popin-header-img\"><img loading=\"lazy\" src=\"${image}\" alt=\"${image_alt}\" title=\"${image_alt}\" width=\"300\" height=\"225\" /></div>`\n                    }\n                    ${slot}\n                </div>\n                ${this.renderFooter()}\n            </div>\n            ${this.isVideo && viewportHelper.is.mobile ? '<div class=\"swipeOverlay\"></div>' : ''}\n        `\n\n        // Expected css to be downloaded\n        setTimeout(() => {\n            this.style.display = 'inherit'\n        }, 100)\n\n        // Set the first and last focusable elements\n        setFirstAndLastFocusable(this)\n\n        this.buttonElement = this.querySelector('button')\n        this.bindEvent()\n    }\n\n    renderFooter() {\n        const { footer } = this.props\n        return parseBool(footer) ? '<footer></footer>' : ''\n    }\n\n    checkIsVideo(slot) {\n        const tempEl = document.createElement('div')\n        tempEl.innerHTML = slot\n        if (tempEl.children.length === 1 && tempEl.children[0].tagName === 'NB-VIDEO') {\n            this.isVideo = true\n            this.setAttribute('video', 'true')\n        }\n    }\n\n    addLock() {\n        document.getElementsByTagName('html')[0].classList.add(SCROLL_LOCK)\n        Overlay.open(this.id)\n    }\n\n    removeLock() {\n        // In case we have popin inside a popin we shouldn't remove the scroll_lock\n        const parentPopin = this.parentNode.closest('nb-popin')\n        if (!parentPopin) {\n            document.getElementsByTagName('html')[0].classList.remove(SCROLL_LOCK)\n        }\n        Overlay.close()\n    }\n\n    switchAriaModal() {\n        this.ariaModal = !this.ariaModal\n        // This is the future way to scope the SR focus to a modal, but it's not supported yet by all SR\n        this.setAttribute('aria-modal', this.ariaModal)\n        // So we need to set aria-hidden=false to all ancestors of parent until body\n        recursiveSwitchAriaHidden(this, this.ariaModal)\n    }\n\n    async open(e) {\n        const event = readEvent(e)\n        if (event.id !== this.id) {\n            return\n        }\n        // Transitionend listener is fired multiple times (fore each css property)\n        // so we need to instantiate it only when we open or close and then we remove it on focusin\n        this.addEventListener('transitionend', this.boundFocus)\n        document.addEventListener('focusin', this.boundFocusin)\n        this.openingSource = document.activeElement\n\n        this.addLock()\n        this.switchAriaModal()\n        this.setAttribute('aria-hidden', 'false')\n        this.isOpen = !this.isOpen\n\n        // event variable already contains ID and other args sent along with dispatch event\n        dispatchEvent({\n            eventName: EVENT_POPIN_OPENED,\n            args: event\n        })\n\n        await new Promise(resolve => {\n            setTimeout(() => {\n                this.classList.add(STATE_OPEN)\n                resolve()\n            }, TIME_FAST)\n        })\n    }\n\n    close(event) {\n        event.cancelBubble = true\n        if (event.stopPropagation) {\n            event.stopPropagation()\n        }\n        // Transitionend listener is fired multiple times (fore each css property)\n        // so we need to instantiate it only when we open or close, and then we remove it on focusin\n        this.addEventListener('transitionend', this.boundFocus)\n        document.removeEventListener('focusin', this.boundFocusin)\n        this.removeLock()\n        if (this.isVideo) {\n            const openVideoPopin = this.closest('.has-open-video')\n            if (openVideoPopin) {\n                openVideoPopin.classList.remove('has-open-video')\n            }\n        }\n        this.switchAriaModal()\n        this.setAttribute('aria-hidden', 'true')\n        this.isOpen = !this.isOpen\n        this.classList.remove(STATE_OPEN)\n\n        dispatchEvent({\n            eventName: EVENT_POPIN_CLOSED,\n            args: { id: this.id }\n        })\n    }\n\n    focus() {\n        this.removeEventListener('transitionend', this.boundFocus)\n        if (this.isOpen) {\n            this.buttonElement.focus()\n        } else {\n            this.openingSource.focus()\n        }\n    }\n\n    focusin(e) {\n        focusin(e, this, true)\n    }\n\n    escapeClose(e) {\n        if (e.key === 'Escape' && this.isOpen) {\n            this.close(e)\n        }\n    }\n\n    swipeDown(e) {\n        if (this.isOpen) {\n            this.close(e)\n        }\n    }\n\n    swipeOverlayTogglePlayPause() {\n        dispatchEvent({\n            eventName: EVENT_VIDEO_TOGGLE,\n            args: { id: this.id }\n        })\n    }\n\n    bindEvent() {\n        this.hasEvent = true\n        this.buttonElement != null && this.buttonElement.addEventListener('click', this.boundClose)\n        window.addEventListener(EVENT_POPIN_OPEN, this.boundOpen)\n        window.addEventListener(EVENT_POPIN_CLOSE, this.boundClose)\n        document.addEventListener(EVENT_POPIN_KEY_DOWN, this.boundEscapeClose)\n\n        if (viewportHelper.is.mobile) {\n            swipeEvents(window, document, this)\n            this.boundSwipeDown = this.swipeDown.bind(this)\n            document.addEventListener(EVENT_SWIPED_DOWN, this.boundSwipeDown)\n            if (this.isVideo) {\n                this.swipeOverlay = this.querySelector('.swipeOverlay')\n                this.boundSwipeOverlayTogglePlayPause = this.swipeOverlayTogglePlayPause.bind(this)\n                this.swipeOverlay.addEventListener('click', this.boundSwipeOverlayTogglePlayPause)\n            }\n        }\n    }\n\n    unbindEvent() {\n        this.hasEvent = false\n        this.buttonElement != null &&\n            this.buttonElement.removeEventListener('click', this.boundClose)\n        window.removeEventListener(EVENT_POPIN_OPEN, this.boundOpen)\n        window.removeEventListener(EVENT_POPIN_CLOSE, this.boundClose)\n        document.removeEventListener(EVENT_POPIN_KEY_DOWN, this.boundEscapeClose)\n        if (this.boundSwipeDown) {\n            document.removeEventListener(EVENT_SWIPED_DOWN, this.boundSwipeDown)\n            this.boundSwipeDown = null\n        }\n        if (this.boundSwipeOverlayTogglePlayPause) {\n            this.swipeOverlay.removeEventListener('click', this.boundSwipeOverlayTogglePlayPause)\n            this.boundSwipeOverlayTogglePlayPause = null\n        }\n    }\n}\n\ncustomElements.get('nb-popin') || customElements.define('nb-popin', Popin)\n\nexport default Popin\n","/**\n *\n * Content Composer Props\n *\n * - copywriting\n * -    -   header {}\n * -    -   -   is_visible\n * -    -   -   heading\n * -    -   -   title\n * -    -   -   description\n * -    -   -   background_color\n * -    -   components [type_of_cards]\n * - layout\n * -    - contrast\n * -    - padding_top\n * -    - padding_bottom\n * -    - card_background_color\n * -    -   row_size\n * -    -   layout_type []\n * -    -   gap []\n * - campaign\n * -    -   id\n * -    -   name\n * -    -   creative: before_content_composer\n * -    -   position: []\n */\nimport createProps from '@kissui/helpers/src/props.helpers'\nimport cardTypeToClass from './subcomponents/index'\nimport COLUMNS_TYPES from './helpers/columnsSizes'\nimport viewportHelper from '@kissui/helpers/src/viewport.helpers'\n\nimport '@kissui/components/src/popin'\n\nclass ContentComposer extends HTMLElement {\n    connectedCallback() {\n        this.props = createProps(this.attributes)\n        this.controller = new AbortController()\n        this.eventsArray = []\n        this.render()\n    }\n\n    render() {\n        const {\n            copywriting: { header },\n            layout: { padding_top, padding_bottom, card_background_color },\n            campaign\n        } = this.props\n\n        const removeMarginTop = !header.is_visible ? '--padding-header: 0' : ''\n        const padding_top_no_header = !header.is_visible ? padding_top : ''\n\n        const styleCardBackgroundColor = card_background_color\n            ? `--background-card: ${card_background_color};`\n            : '--background-card: transparent;'\n\n        this.innerHTML = `\n                ${header.is_visible !== 'false' && this.renderHeader()}\n                <nb-container\n                    background_color=\"white_1000\"\n                    style=\"${styleCardBackgroundColor} ${removeMarginTop}\"\n                    contrast=\"light\"\n                    class=\"content_composer__subcomponents\"\n                    classname='${padding_top_no_header} ${padding_bottom}'\n                    campaign_id='${campaign.id}'\n                    campaign_name='${campaign.name}'\n                    campaign_position='${campaign.position}'\n                    campaign_creative='${campaign.creative}'\n                    >\n                    ${this.renderSubcomponents()}\n                </nb-container>\n        `\n        this.bindEvents()\n    }\n\n    renderHeader() {\n        const {\n            copywriting: {\n                header: {\n                    is_visible,\n                    background_color = '',\n                    heading = null,\n                    title = null,\n                    description = null\n                }\n            },\n            layout: { contrast = 'light', padding_top }\n        } = this.props\n\n        if (!is_visible) {\n            return ''\n        }\n\n        const styleBackgroundColor = background_color\n            ? `--background-header: ${background_color}`\n            : ''\n\n        return `<nb-container\n                    background_color=\"highlight_040_partial\"\n                    contrast=\"${contrast}\"\n                    classname=\"${padding_top} content-composer__heading\"\n                    style=\"${styleBackgroundColor};\"\n                >\n                    <div class=\"content-composer__heading__inner\">\n                        ${heading && `<h3 class=\"t-md-700-sl\">${heading}</h3>`}\n                        ${title && `<h2 class=\"h-3xl-700\">${title}</h2>`}\n                        ${description && `<p class=\"t-sm-400\">${description}</p>`}\n                    </div>\n                </nb-container>`\n    }\n\n    renderSubcomponents() {\n        const {\n            copywriting: { components },\n            layout: { layout_type, gap }\n        } = this.props\n\n        const types = COLUMNS_TYPES\n        const typeIndex = types.indexOf(layout_type)\n\n        if (typeIndex === -1) {\n            return ''\n        }\n\n        const gapSpace = gap || '4px'\n\n        return `\n                <div class=\"content-composer__showcase\" style=\"--main-gap-cards:${gapSpace}\" data-layout=\"${\n            types[typeIndex]\n        }\">\n                    ${components\n                        .map(component => this.renderSubComponent(component.variant))\n                        .join('')}\n                </div>\n        `\n    }\n\n    renderSubComponent(component) {\n        const { row_size } = this.props.layout\n\n        let cardType = ''\n        for (const [key] of Object.entries(cardTypeToClass)) {\n            if (component[`is_${key}`]) {\n                cardType = key\n                break\n            }\n        }\n\n        const CardClass = cardTypeToClass[cardType]\n        if (!CardClass) {\n            throw new Error(`Invalid card type: ${cardType}`)\n        }\n\n        // if it isn't mobile get the size from the row\n        if (!viewportHelper.is.mobile) {\n            component.details.cardSize = row_size\n        }\n        // it it's \"touch\", disable the card display effect\n        if (!viewportHelper.is.desktop && !viewportHelper.is.retina) {\n            component.details.animated = false\n        }\n\n        const card = new CardClass(component.details)\n        this.eventsArray = this.eventsArray.concat(card.bindEvents())\n        return card.render()\n    }\n\n    bindEvents() {\n        const signal = this.controller.signal\n        this.eventsArray.forEach(e => {\n            const element = document.querySelector(e.id)\n            if (element) {\n                element.addEventListener(e.eventType, e.cb, { signal })\n            }\n        })\n    }\n\n    disconnectedCallback() {\n        this.controller.abort()\n    }\n}\n\ncustomElements.get('nb-content-composer') ||\n    customElements.define('nb-content-composer', ContentComposer)\n\nexport default ContentComposer\n"],"names":["createProps","attributes","data","find","attribute","nodeName","getData","props","filter","reduce","all","attr","nodeValue","isNil","JSON","parse","error","console","log","obj","removeEmptyValues","findText","key","value","text","includes","stringifyForAttribute","escapeHtml","stringify","map","replace","m","DOMParser","sanitizeString","toString","dispatchEvent","eventName","args","element","window","Error","event","CustomEvent","detail","bubbles","Event","document","createEvent","initEvent","BREAKPOINT_TABLET","EVENT_POPIN_OPEN","EVENT_POPIN_CLOSE","EVENT_POPIN_KEY_DOWN","EVENT_SWIPED_DOWN","trackingData","creative","renderCta","cssClass","cta","campaign","id","name","position","label","campaign_id","campaign_name","campaign_position","campaign_creative","renderLink","popin_id","link","color","size","seo_label","helper","is","innerWidth","vw","devicePixelRatio","mobile","mobile_tablet","tablet","desktop","retina","lt","ref","getImage","background_retina","background_desktop","background_mobile","viewportHelper","Card","constructor","_props","_campaign","this","elementId","render","bindEvents","getProduct","sku","napi","catalog","trimSku","isBundled","productData","sales_multiple","salesMultiple","isSalesMultipleGreaterThanOne","isUnitQuantityEqualToOne","unitQuantity","isSalesMultipleEqualToOne","isUnitQuantityGreaterThanOne","selectPromotion","eventData","cta_name","event_raised_by","ecommerce","Object","keys","length","ecommerceData","promotion_id","promotion_name","creative_slot","creative_name","gtmDataObject","push","emitCustomEvent","customEvent","cancelable","composed","getMarketCode","dataLayer","padlNamespace","app","market","toLocaleLowerCase","COMMON_URL","ORGANIC_LOGO_IMG_EU","ORGANIC_LOGO_IMG_US","ORGANIC_LOGO_IMG_CA","ORGANIC_LOGO_IMG_BR","ORGANIC_LOGO_IMG_JP","ORGANIC_LOGO_IMG_BE","organicLogoImg","getOrganicLogo","getMaxIntensity","technologies","INTENSITY_MAX_OL","indexOf","getMergedProductCoffeeData","product","pageBuilderProductProps","pageBuilderProps","priceFormatter","currency","bundle_details","options","show_sleeve_price","isBundledResult","showCapsulePrice","price_per_capsule","final_price","bundled","type","price","Math","round","getFinalPrice","option","intensity","capsuleProperties","max_intensity","short","show_capsule_price","apiOverride","pageBuilderData","images","headline","description","api_override","image","icon","url","main","cardTypeToClass","video","auto_play","renderAutoPlayCardVideo","renderDefaultCardVideo","video_service","video_id","contrast","cardSize","animated","backgroundImage","createPopinID","renderPlayButton","renderCardDisplay","renderPlayer","renderTitle","renderDescription","video_mobile","display_ui_controls","cc_policy_language","POPIN_ID","onOpenPlayer","e","preventDefault","cleanedData","handlePromoClick","title","seed","stripedHeading","str","tmp","implementation","createHTMLDocument","body","innerHTML","textContent","RegExp","stripHTML","substr","hash","i","charCodeAt","makeHash","removePlayer","playerElement","querySelector","remove","boundOnButtonSelfVideoClick","targetElement","target","srcElement","srOnly","dataset","status","pause","classList","add","play","renderSelfVideoButton","addEventListener","eventType","cb","bind","renderPopin","popin","heading","image_alt","close","productImage","productImageAlt","cardSizeAtrb","background_color","productSku","getSkuQuickViewData","popinId","payload","CARD_ID","quickViewProps","getSkuQuickViewProp","quickViewElement","createElement","setAttribute","getElementById","appendChild","getCapsuleFeatures","acidity","bitterness","roast","roastLevel","skuData","sku_quick_view","async","priceFormat","getPriceFormatter","config","padl","namespace","mergedProductData","getMergedProductData","variant","labels","strikethrough_price","additional_message","additional_message_icon","additional_message_link","contact_cta","internationalId","longSku","unit_quantity","category_name","rangeData","label_range","rawPrice","variation","image_alt_text","highlighted","dataTransformObjectProductType","getMergedProductMachineData","ratingsAndReviews","ratings","colors","activeSku","max_colors","show_ratings","minimum_rating","getMergedProductGiftCardData","_","default_image","footer","intensity_label","a11y_intensity_max","cup_sizes","items","cupSizesDetails","aromatic_profile","capsuleProductAromatics","pdpURLs","levels","pricing","add_to_cart","categoryName","hidePrice","view_details_label","rendererName","showSleeve","result","characters","charAt","floor","random","makeId","backgroundColorStyle","COLUMNS_TYPES","swipeEvents","stopEl","nwcSwipeEvents","getAttribute","el","undefined","contains","scrollTopArray","scrollLeftArray","scrollTop","scrollLeft","parentNode","memorizeStartElScrollPositions","startEl","timeDown","Date","now","touches","clientX","clientY","xDiff","yDiff","xDown","yDown","xUp","yUp","defaultVertical","innerHeight","defaultHorizontal","swipeThresholdVertical","getNearestAttribute","swipeThresholdHorizontal","swipeTimeout","timeDiff","changedTouches","abs","checkScrollCondition","dir","touchType","xStart","xEnd","yStart","yEnd","direction","isScrollable","scrollHeight","clientHeight","scrollWidth","clientWidth","attributeName","defaultValue","documentElement","attributeValue","String","parseInt","recursiveSwitchAriaHidden","elem","componentOpenState","parent","getElementsByTagName","brothers","children","brother","removeAttribute","Overlay","overlay","setTimeout","getElementsByClassName","STATE_OPEN","SCROLL_LOCK","Popin","HTMLElement","ariaModal","isVideo","boundOpen","open","boundClose","boundEscapeClose","escapeClose","boundFocus","focus","boundFocusin","focusin","connectedCallback","style","display","content","slot","attributeChangedCallback","oldValue","newValue","observedAttributes","disconnectedCallback","hasEvent","unbindEvent","subheading","bgcolor","label_close","heading_class","bindEvent","isOpen","checkIsVideo","renderFooter","focusable","querySelectorAll","firstFocusable","lastFocusable","lastFocused","setFirstAndLastFocusable","buttonElement","parseBool","tempEl","tagName","addLock","removeLock","closest","switchAriaModal","readEvent","openingSource","activeElement","Promise","resolve","cancelBubble","stopPropagation","removeEventListener","openVideoPopin","loop","swipeDown","swipeOverlayTogglePlayPause","boundSwipeDown","swipeOverlay","boundSwipeOverlayTogglePlayPause","customElements","get","define","ContentComposer","controller","AbortController","eventsArray","copywriting","header","layout","padding_top","padding_bottom","card_background_color","removeMarginTop","is_visible","padding_top_no_header","styleCardBackgroundColor","renderHeader","renderSubcomponents","components","layout_type","gap","types","typeIndex","component","renderSubComponent","join","row_size","cardType","entries","CardClass","details","card","concat","signal","forEach","abort"],"mappings":"AAAA,MAEMA,EAAcC,IACVC,MAAAA,EAHMD,CAAAA,GAAcA,EAAWE,MAAKC,GAAoC,SAAvBA,EAAUC,WAGpDC,CAAQ,IAAIL,IACnBM,EAAQ,IAAIN,GACbO,QAAOJ,GAAoC,SAAvBA,EAAUC,WAC9BI,QAAO,CAACC,EAAKC,KACH,IAAKD,EAAK,CAACC,EAAKN,UAAWM,EAAKC,aACxC,CAAE,GAET,GAAIC,EAAMX,GACCK,OAAAA,EAGP,IACO,MAAA,IAAKA,KAAUO,KAAKC,MAAMb,EAAKU,WACzC,OAAQI,GACLC,QAAQC,IAAI,iBAAkBF,EAAOd,GAAMU,UAC/C,GAGEC,EAAQM,GAAoC,MAARA,EC+CnC,SAASC,EAAkBD,GAC9B,MAAME,EAAW,CACb,gEACA,kEACA,YACA,UACA,gBACA,aAGJ,IAAA,IAASC,KAAOH,EAAK,CACXI,MAAAA,EAAQJ,EAAIG,GAEdC,GAAU,MAAVA,GAAmD,KAAVA,GAKzC,GAAiB,iBAAVA,EACP,IAAA,MAAWC,KAAQH,EACXE,GAAAA,EAAME,SAASD,GAAO,QACfL,EAAIG,GACX,KACJ,cATGH,EAAIG,EAYnB,CAEOH,OAAAA,CACX,CAsPO,MAAMO,EAAwBA,CAACxB,EAAO,KAClCyB,EAAWb,KAAKc,UAAU1B,IAQxByB,EAAcH,IACvB,MAAMK,EAAM,CACR,IAAK,QACL,IAAK,OACL,IAAK,OACL,IAAK,SACL,IAAK,UAGT,OAAOL,EAAKM,QAAQ,YAAmBD,GAAAA,EAAIE,IAAE,EAQ/B,IAAIC,UAKTC,MAAAA,EAAkB/B,GACtBA,EAIEA,EAAKgC,WAAWJ,QAAQ,KAAM,UAAUA,QAAQ,KAAM,UAHlD,GCxXFK,EAAgBA,EAAGC,UAAAA,EAAWC,KAAAA,EAAMC,QAAAA,MAE7C,IAAKA,EACD,aAAWC,OAAW,KAGZ,MAAA,IAAIC,MACN,yGAHJF,EAAUC,MAIV,CAIJE,IAAAA,EACAJ,EACAI,EAAQ,IAAIC,YAAYN,EAAW,CAAEO,OAAQN,EAAMO,SAAS,IAEvC,mBAAVC,MACPJ,EAAQ,IAAII,MAAMT,IAElBK,EAAQK,SAASC,YAAY,SAC7BN,EAAMO,UAAUZ,GAAW,GAAM,IAGzCE,EAAQH,cAAcM,EAAK,ECpBlBQ,EAAoB,KAkBpBC,EAAmB,2BAEnBC,EAAoB,4BAGpBC,EAAuB,UAgCvBC,EAAoB,cC1DlBC,EAAA,CACXC,SAAU,2BCCDC,EAAYA,CAACjD,EAAOkD,KACvB,MACFC,IAAAA,EAAM,CAAE,EACRC,SAAAA,EAAW,CAAEC,GAAI,GAAIC,KAAM,GAAIN,SAAU,GAAIO,SAAUR,EAAaC,WACpEhD,EAEJ,IAAKmD,EAAIK,MACE,MAAA,GAGXL,EAAIM,YAAcL,EAASC,IAAM,GACjCF,EAAIO,cAAgBN,EAASE,MAAQ,GACrCH,EAAIQ,kBAAoBP,EAASG,UAAY,GAC7CJ,EAAIS,kBAAoBR,EAASJ,UAAY,GAI7C,MAAO,eAAeE,qCAFT/B,EAAsBgC,qBAIzBA,EAAIK,oCAAK,EAIVK,EAAaA,CAAC7D,EAAOkD,EAAUY,EAAW,MAC7C,MACFC,KAAAA,EAAO,CAAE,EACTX,SAAAA,EAAW,CAAEC,GAAI,GAAIC,KAAM,GAAIN,SAAU,GAAIO,SAAUR,EAAaC,WACpEhD,EAEC+D,OAAAA,EAAKP,MAIH,eAAeN,qCACHE,EAASC,+BACPC,qCACIF,EAASJ,yCACTI,EAASG,4BACtBQ,EAAKA,4BACDD,sBACHC,EAAKC,yBACND,EAAKE,6BACAF,EAAKG,wBACfH,EAAKP,wBAbD,EAAA,ECVTW,EAfK,CACH,MAAIC,GACM,MAAEC,WAAYC,EAAIC,iBAAAA,GAAqBvC,OACtC,MAAA,CACHwC,OAAQF,EHNI,IGOZG,cAAeH,EAAK5B,EACpBgC,OAAQJ,GHRI,KGQkBA,EAAK5B,EACnCiC,QAASL,GAAM5B,GAAqB6B,GAAoB,EACxDK,OAAQN,GAAM5B,GAAqB6B,EAAmB,EAE9D,EACAM,GAfQC,GACD9C,OAAOqC,WAAaS,GCFtBC,EAAWA,EAAGC,kBAAAA,EAAmBC,mBAAAA,EAAoBC,kBAAAA,KAC1DC,EAAef,GAAGI,QAAUU,EACrBA,EACAC,EAAef,GAAGQ,QAAUI,EAC5BA,EAGJC,ECTI,MAAAG,EACXC,WAAAA,CAAYC,EAAQC,GAChBC,KAAKxF,MAAQsF,EACbE,KAAKpC,SAAWmC,EAChBC,KAAKC,UAAY,IACrB,CACAC,MAAAA,GACU,MAAA,IAAIzD,MAAM,uCACpB,CACA0D,UAAAA,GACI,MAAO,EACX,ECXG,MCmBMC,EAAaC,GAAO7D,OAAO8D,KAAKC,UAAUH,WANvCC,CAAAA,GAAOA,EAAItE,QAAQ,mBAAoB,IAMWyE,CAAQH,IAiDnE,SAASI,EAAUC,GAEtBA,EAAYC,eAAiBD,EAAYC,gBAAkBD,EAAYE,cAEvE,MAAMC,EAAgCH,EAAYC,eAAiB,EAC7DG,EAAwD,IAA7BJ,EAAYK,aACvCC,EAA2D,IAA/BN,EAAYC,eACxCM,EAA+BP,EAAYK,aAAe,EAG5DF,QAAAA,IAAiCC,KAK9BE,GAA6BC,EACxC,CCvDA,MCoHaC,EAAkB5E,IACrBI,MACAyE,EAAY,CACdzE,MAAO,mBACP0E,SAAU9E,GAAM8E,UAAY,YAC5BC,gBAlJW,eAmJXC,UAAW,CAAC,GAEhB,GAAIC,OAAOC,KAAKlF,GAAMmF,OAAQ,CACpB,MAAE5D,GAAAA,EAAK,GAAIL,SAAAA,EAAW,GAAIM,KAAAA,EAAO,GAAIC,SAAAA,EAAW,IAAOzB,EAC7D,IAAIoF,EAAgB,CAChBC,aAAc9D,EACd+D,eAAgB9D,EAChB+D,cAAe9D,EACf+D,cAAetE,GAEnBkE,EAAgBrG,EAAkBqG,GAClCP,EAAUG,UAAYI,CAC1B,CAEAlF,OAAOuF,gBAAPvF,OAAOuF,cAAkB,IACzBvF,OAAOuF,cAAcC,KAAKb,GDvICc,EAAC5F,EAAmBlC,KAC/C,MAAM+H,EAAc,IAAIvF,YAAY,eAAmBN,IAAa,CAChEO,OAAQzC,EACR0C,SAAS,EACTsF,YAAY,EACZC,UAAU,IAGd5F,OAAOJ,cAAc8F,EAAW,ECgIhCD,CArBc,mBAqBSd,EAAS,ECvK7B,MAIMkB,EAAgBA,KACzB,MAAMC,EAJC9F,OAAOA,QAAQ+F,gBAAgBD,UAKtC,OAAKA,EAIEA,EAAUE,IAAIA,IAAIC,OAAOC,oBAHrB,IAAA,ECOTC,EAAa,kEAGNC,EAAsBD,EAAa,sBACnCE,EAAsBF,EAAa,sBACnCG,EAAsBH,EAAa,sBACnCI,EAAsBJ,EAAa,sBACnCK,EAAsBL,EAAa,sBACnCM,EAAsBN,EAAa,uBAkBzC,WACH,IAAIO,EAAiBN,EAErB,OAAQP,KACJ,IAAK,KACDa,EAAiBL,EACjB,MACJ,IAAK,KACDK,EAAiBJ,EACjB,MACJ,IAAK,KACDI,EAAiBH,EACjB,MACJ,IAAK,KACDG,EAAiBF,EACjB,MACJ,IAAK,KACDE,EAAiBD,EAK7B,CA9BgBE,GC9BT,MAAMC,EAAkBA,EAAGC,aAAAA,MACYC,IAA1CD,EAAaE,QAAQ,YZuEO,GACA,GavEnBC,EAA6BA,CACtCC,EACAC,EACAC,EACAC,EACAC,KAEM,MAAEC,eAAAA,GAAmBJ,GACnBK,QAAAA,GAAYJ,GACZK,kBAAAA,GAAsBD,EAExBE,EAAkBxD,EAAUgD,IAE1BS,iBAAAA,EAAkBC,kBAAAA,EAAmBC,YAAAA,GCoK1C,SAAuBJ,EAAmBP,EAAShD,GAClDyD,IACAE,EACAD,EAFAD,EAAmBF,EAIjBK,MAAAA,EAAU5D,EAAUgD,GAEtBA,MAAiB,YAAjBA,EAAQa,MAAuBD,GAM/BH,GAAmB,EACnBE,EAAcX,EAAQc,QANtBH,EAAcX,EAAQc,MAAQd,EAAQ7C,cAEtCwD,EAAcI,KAAKC,MAAoB,IAAdL,GAAqB,IAC9CD,EAAoBV,EAAQc,OAMzB,CAAEL,iBAAAA,EAAkBE,YAAAA,EAAaD,kBAAAA,EAC5C,CDtLiEO,CACzDV,EACAP,EACAhD,GAGEkE,EAAS,CACXN,QAASJ,EACTW,UAAWnB,EAAQoB,mBAAmBD,WAAanB,EAAQmB,WAAa,KACxEE,cAAe1B,EAAgBK,GAC/BU,kBAAmBA,EACbP,EAAemB,MAAMlB,EAAUM,GAC/B,KACNa,mBAAoBd,GAGpBF,OAAAA,IACAW,EAAOJ,MAAQX,EAAemB,MAAMlB,EAAUO,IAG9CN,IACAa,EAAOb,eAAiBA,GAGrBa,CAAAA,EEhBEM,EAAcA,CAACvE,EAAawE,KACjC,IAACxE,IAAgBwE,EACjB,MAAO,GAGL,MAAEC,OAAAA,EAAQrH,KAAAA,EAAMsH,SAAAA,EAAUC,YAAAA,GAAgB3E,GACxC4E,aAAAA,GAAiBJ,EAEzB,OAAKI,EAIE,CACHC,MAAOD,EAAaC,OAASJ,GAAQK,MAAQL,GAAQM,KAAON,GAAQnD,MAAQmD,GAAQO,KACpF5H,KAAMwH,EAAaxH,MAAQA,EAC3BsH,SAAUE,EAAaF,UAAYA,EACnCC,YAAaC,EAAaD,aAAeA,GAPlC,IC5Bf,MAAeM,EAAA,CACXC,MCqBW,cAAchG,EACzBM,MAAAA,GACU,MACF0F,OAASC,UAAAA,GAAY,IACrB7F,KAAKxF,MAET,MAAO,GAAIqL,EAA4C7F,KAAK8F,0BAArC9F,KAAK+F,0BAChC,CAEAD,uBAAAA,GACU,MAAEF,MAAAA,GAAU5F,KAAKxF,MAIvB,GAFAoL,EAAMI,cAAgB,SAEjBJ,EAAMK,SACD,MAAA,IAAIxJ,MAAM,uDAGb,MAAA,mGAEmBd,EAAsBiK,8gBASpD,CAEAG,sBAAAA,GACU,MAAEH,MAAAA,EAAOM,SAAAA,EAAUC,SAAAA,EAAUC,SAAAA,GAAapG,KAAKxF,MAErD,IAAKoL,EAAMK,WAAaL,EAAMI,cACpB,MAAA,IAAIvJ,MAAM,uDAGd8I,MAAAA,EAAQhG,EAASS,KAAKxF,OACtB6L,EAAkBd,EAAQ,wBAAwBA,KAAW,KACnE,OAAAvF,KAAKC,UAAY,QAAUD,KAAKsG,gBAEzB,kEAEWD,kCACGH,mCACCC,kCACDC,6CAGXpG,KAAKuG,iBAAiBvG,KAAKC,+BAC3BD,KAAKwG,4CAEHxG,KAAKyG,gBACrB,CAEAD,iBAAAA,GACW,MAAA,0HAGOxG,KAAK0G,sCACL1G,KAAK2G,4CACLlJ,EAAUuC,KAAKxF,MAAO,8CACtB6D,EAAW2B,KAAKxF,MAAO,yDAGzC,CACA+L,gBAAAA,CAAiBtG,GACN,MAAA,wDACsCA,kPAOjD,CAEAwG,YAAAA,GACU,MACFb,OACIK,SAAAA,EACAW,aAAAA,EAAe,GACfC,oBAAAA,EACAC,mBAAAA,EACAd,cAAAA,GACA,CAAC,GACLhG,KAAKxF,MAEHuM,EAAW/G,KAAKsG,gBACtB,MAAO,iBAAiBS,uHAEeA,yCACXd,6CACIW,8CACCZ,yCACLe,iDACQF,kDACCC,0HAIzC,CAEAE,YAAAA,CAAaC,GACH,MAAErJ,SAAAA,GAAaoC,KAAKxF,MAE1ByM,EAAEC,iBACIH,MAAAA,EAAW/G,KAAKsG,gBACtBlK,EAAc,CAAEC,UAAWc,EAAkBb,KAAM,CAAEuB,GAAIkJ,KRJjCzK,CAAAA,IACtB,MAAEsB,SAAAA,EAAUwD,SAAAA,GAAa9E,EAEzB6K,EAAc9L,EAAkBuC,GACtCsD,EAAgB,CAAEE,SAAAA,KAAa+F,GAAa,EQCxCC,CAAiB,CACbxJ,SAAUA,EACVwD,SAAU,WAAWpB,KAAKxF,MAAMoL,MAAMK,YAE9C,CAEAK,aAAAA,GACU,MACFe,MAAAA,EACAzB,OAASK,SAAAA,IACTjG,KAAKxF,MACH8M,EAAOD,GAASpB,EACtB,OAAAjG,KAAKuH,enBlGN,SAAmBC,GACtB,MAAMC,EAAM1K,SAAS2K,eAAeC,mBAAmB,IACvDF,OAAAA,EAAIG,KAAKC,UAAYL,GACbC,EAAIG,KAAKE,aAAe,IAAI/L,QAAQgM,OAAO,aAAc,KAAM,GAC3E,CmB8F8BC,CAAUV,GAAMW,OAAO,EAAG,IACzC,cnBpDR,SAAkBT,GACjBU,IACAC,EADAD,EAAO,EAGX,IAAKV,EACMU,OAAAA,EAEX,IAAKC,EAAI,EAAGA,EAAIX,EAAI/F,OAAQ0G,IAEhBD,GAAAA,GAAQ,GAAKA,EADfV,EAAIY,WAAWD,GAEbD,GAAA,EAEZ,MAAO,MAAQA,CACnB,CmBuC6BG,CAASrI,KAAKuH,mBAAmBtB,GAC1D,CAEAqC,YAAAA,GACI,MAAMC,EAAgBxL,SAASyL,cAAc,oBACzCD,GACAA,EAAcE,QAEtB,CAEAC,2BAAAA,CAA4BzB,GACxB,MAAM0B,EAAgB1B,EAAE2B,QAAU3B,EAAE4B,WAC9BjD,EAAQ7I,SAASyL,cAAc,kCAC/BM,EAAS/L,SAASyL,cAAc,YAED,UAAjCG,EAAcI,QAAQC,QACtBpD,EAAMqD,QACNN,EAAcI,QAAQC,OAAS,OAC/BL,EAAcO,UAAUT,OAAO,cAC/BE,EAAcO,UAAUC,IAAI,aAC5BL,EAAOhB,YAAc,SAErBlC,EAAMwD,OACNT,EAAcI,QAAQC,OAAS,QAC/BL,EAAcO,UAAUT,OAAO,aAC/BE,EAAcO,UAAUC,IAAI,cAC5BL,EAAOhB,YAAc,QAE7B,CAEA3H,UAAAA,GACUF,MAAAA,EAAY,QAAUD,KAAKsG,gBAEjC,OAAAtG,KAAKqJ,sBAAwBtM,SAASyL,cAAc,oBAChDxI,KAAKqJ,uBACLrJ,KAAKqJ,sBAAsBC,iBAAiB,QAAStJ,KAAK0I,6BAGvD,CACH,CACI7K,GAAI,aAAaoC,MACjBsJ,UAAW,QACXC,GAAIxJ,KAAKgH,aAAayC,KAAKzJ,OAGvC,CAEA0G,WAAAA,GACU,MAAEW,MAAAA,GAAUrH,KAAKxF,MAClB6M,OAAAA,EAIE,wBAAwBA,SAHpB,EAIf,CAEAV,iBAAAA,GACU,MAAEtB,YAAAA,GAAgBrF,KAAKxF,MACxB6K,OAAAA,EAIE,uBAAuBA,QAHnB,EAIf,GD9MAE,MEeW,cAAc3F,EACzBM,MAAAA,GACU,MAAEkG,SAAAA,EAAUF,SAAAA,EAAUC,SAAAA,EAAUkB,MAAAA,EAAQ,GAAIhC,YAAAA,EAAc,IAAOrF,KAAKxF,MAKrE,MAAA,oEAHO+E,EAASS,KAAKxF,mCAKZ4L,6BACAF,8BACCC,oKAIKkB,GAAS,0CAA0CA,yCACnDhC,GAAe,uBAAuBA,wCACtC5H,EAAUuC,KAAKxF,MAAO,sDACtB6D,EAAW2B,KAAKxF,MAAO,0GAG/BwF,KAAK0J,uCAEvB,CAEAA,WAAAA,GACU,MAAE/L,IAAAA,EAAKgM,MAAAA,EAAQ,CAAC,GAAM3J,KAAKxF,OAE7BqD,GAAAA,EAAK,GACL0H,MAAAA,EAAQ,GACRqE,QAAAA,EAAU,GACVvE,YAAAA,EAAc,GACdwE,UAAAA,EAAY,GACZC,MAAAA,EAAQ,IACRH,EAEJ,OAAK9L,GAAOF,EAAIW,SAIT,sCACWX,EAAIW,2CACCsL,kHAGFrE,sCACIsE,wCACEC,+DAETzE,iCAZP,EAcf,GFjEA5B,QGaW,cAAc7D,EACzBM,MAAAA,GACU,MACF0J,QAAAA,EAAU,GACVvC,MAAAA,EAAQ,GACR0C,aAAAA,EACAC,gBAAAA,EAAkB,GAClB7D,SAAAA,EACAD,SAAAA,GACAlG,KAAKxF,MAEHyP,EAAe9D,EAAW,cAAcA,KAAc,GACtDZ,EAAQhG,EAASS,KAAKxF,OAMrB,MAAA,+EALiB+K,EAAQ,wBAAwBA,MAAY,KAC5CvF,KAAKxF,MAAM0P,iBAC7B,oBAAoBlK,KAAKxF,MAAM0P,oBAC/B,6BAKQD,oCACU/D,iTAKW6D,gDACAC,6JAKXJ,GACA,yEAAyEA,yCAGzEvC,GACA,+DAA+DA,yCAEjE5J,EAAUuC,KAAKxF,MAAO,gIAIhD,GHxDA2P,WIeW,cAAcvK,EACzB,yBAAMwK,CAAoB/J,EAAKgK,EAAS7P,GAChC,IACM8P,MAAAA,QAAgBlK,EAAWC,GAEjC,IAAKiK,EACD,OAGEC,MAAAA,EAAU,UAAUF,IACpBG,QAAuBxK,KAAKyK,oBAAoBJ,EAAS7P,EAAO8P,GAElEI,IAAAA,EAAmB3N,SAAS4N,cAAc,qBAC9CD,EAAiBE,aAAa,OAAQ7P,KAAKc,UAAU2O,IACrDE,EAAiBE,aAAa,KAAMP,GAEvBtN,SAAS8N,eAAeN,GAChCO,YAAYJ,EACpB,CAAW,MACAzP,QAAAA,MAAM,0BAA0BoF,IAC5C,CACJ,CAEA0K,kBAAAA,CAAmBlG,GACR,MAAA,CACHmG,QAAS,CAAExP,MAAOqJ,GAAmBmG,SACrCC,WAAY,CAAEzP,MAAOqJ,GAAmBoG,YACxCrD,KAAM,CAAEpM,MAAOqJ,GAAmB+C,MAClC/C,kBAAmB,CAAED,UAAWC,GAAmBD,WACnDsG,MAAO,CAAE1P,MAAOqJ,GAAmBsG,YAE3C,CAEA,yBAAMV,CAAoBJ,EAAS5G,EAAS2H,GAClC,MAAEC,eAAAA,GAAmB5H,EAE3BzD,KAAK4D,oBb5CoB0H,gBAAkB9O,OAAO8D,KAAKiL,ca4C3BC,GAC5BxL,KAAK6D,Sd9DoBrH,OAAOA,OAAOiP,OAAOC,KAAKC,WAAWrJ,UAAUE,IAAIA,IAAIqB,ScgEhF,MACM+H,ECnDsBC,EAChCpI,EACAC,EACAC,EACAC,EACAC,KAEM,MAAEE,QAAAA,GAAYJ,GAEhBmI,QAAAA,EAAU,CAAE,EACZC,OAAAA,EAAS,GACTC,oBAAAA,EACAC,mBAAAA,EACAC,wBAAAA,EACAC,wBAAAA,EACAC,YAAAA,GACA1I,GAA2B,CAAA,EAG/B,IAAIvJ,EAAO,CACPkG,IAAKoD,EAAQ4I,gBACbhJ,aAAcI,EAAQJ,aACtBiJ,QAAS7I,EAAQ5F,GACjBC,KAAM2F,EAAQ3F,KACdsH,SAAUlJ,EAAeuH,EAAQ2B,UACjCzE,eAAgB8C,EAAQ7C,cACxB2L,cAAe9I,EAAQ1C,aACvBuD,KAAMb,EAAQa,KACdkI,cAAe/I,EAAQgJ,WAAW3O,MAAQ,GAC1C4O,YAAajJ,EAAQgJ,WAAW3O,MAAQ,GACxCyG,MAAOd,EAAQc,MAAQX,EAAemB,MAAMlB,EAAUJ,EAAQc,OAAS,KACvEoI,SAAUlJ,EAAQc,MAClByH,oBAAqBA,GAAuB,GAC5CY,UC/CqB,MDgDrBC,eAAgBpJ,EAAQ3F,KACxByH,MAAO9B,EAAQ0B,QAAQK,MAAQ/B,EAAQ0B,QAAQnD,MAAQyB,EAAQ0B,QAAQO,KACvEuG,mBAAoBA,GAAsB,GAC1CC,wBAAyBA,GAA2B,GACpDC,wBAAyBA,GAA2B,CAAE,EACtDC,YAAaA,GAAe,CAAE,KAC3BnH,EAAYxB,EAASC,IAGxBqI,GAAUA,EAAOtK,SACjBtH,EAAK4R,OAASA,GAGdtI,EAAQqJ,cACR3S,EAAK2S,YAAcrJ,EAAQqJ,aAG/B,IAAIC,EAAiC,CAAA,EACrC,Md9D8B,Yc8D1BtJ,EAAQa,KACRyI,EAAiCvJ,EAC7BC,EACAC,EACAC,EACAC,EACAC,GdnEsB,YcqEnBJ,EAAQa,KACfyI,EE3EmCC,EAACvJ,EAASC,EAAyBC,KACpE,MAAEqI,oBAAAA,EAAqBF,QAAAA,EAAU,CAAC,GAAMpI,GACtCuJ,kBAAAA,GAAsBxJ,EAGxBM,EAAU,CACZmJ,QAASD,GAGb,OAAInB,GAASqB,SACTpJ,EAAQoJ,OAASrB,EAAQqB,OACzBpJ,EAAQqJ,UAAY3J,EAAQ4I,gBAC5BtI,EAAQsJ,WAAa,IAGzBtJ,EAAQiI,oBAAsBA,GAAuB,GACrDjI,EAAQuJ,aAAgB3J,GAAoBA,EAAiBI,QAAQuJ,eAAiB,EACtFvJ,EAAQwJ,eAAkB5J,GAAoBA,EAAiBI,QAAQwJ,gBAAmB,EAEnFxJ,CAAAA,EFwD8BiJ,CAC7BvJ,EACAC,EACAC,GdxEwB,cc0ErBF,EAAQa,KACfyI,EGjF4C,GjBOhB,ac+ErBtJ,EAAQa,OACfyI,EIvFoCS,EAACC,EAAG/J,KACtC,MAAEoI,QAAAA,EAAU,CAAC,GAAMpI,EAElB,MAAA,CACH6B,MAAOuG,GAAWA,EAAQ4B,gBJmFOF,CAC7B/J,EACAC,IAKD,IACAD,KACAM,KACA+H,KACA3R,KACA4S,IDlCuBlB,OADAzL,EAAWqD,EAAQpD,KAGzCoD,EACAzD,KAAKxF,MACLwF,KAAK4D,eACL5D,KAAK6D,UAGK,MAAA,CACV8F,MAAO,CACHrL,SAAU+L,EACVP,MAAOuB,EAAe1B,MAAMG,MAC5B6D,QAAQ,GAEZlK,QAAS,IACFA,KACA2H,KACApL,KAAK+K,mBAAmBK,EAAQvG,oBAEvCD,UAAW,CACPgJ,gBAAiB,YACjBC,mBAAoB,0BAExBC,UAAW,IACJzC,EAAeyC,UAClBC,MAAOtK,EAAQuK,iBAEnBC,iBAAkB,IACX5C,EAAe4C,iBAClBF,MAAOnC,EAAkBsC,yBAE7B3P,KAAM,IACC8M,EAAe9M,KAClBkH,IAAKmG,EAAkBuC,QAAQhP,SAEnCiP,OAAQ,IACD/C,EAAe+C,QAEtBC,QAAS,CACLC,YAAa,CACTjO,IAAKuL,EAAkBvL,IACvBiM,QAASV,EAAkBU,QAC3BE,cAAeZ,EAAkB2C,aACjCxQ,SAAU,GACV6O,UAAW,QACXrI,MAAOqH,EAAkBrH,MACzByH,oBAAqBJ,EAAkBI,oBACvCwC,UAAW5C,EAAkB4C,UAC7B/I,IAAK,GACLgJ,mBAAoB,eACpBC,aAAc,IAElBC,WAAY,CAAE,EACdzK,iBAAkB,CAAC,GAK/B,CAEAhE,MAAAA,GACU,MACF0J,QAAAA,EAAU,GACVvC,MAAAA,EAAQ,GACR0C,aAAAA,EACAC,gBAAAA,EAAkB,GAClB7D,SAAAA,EACAD,SAAAA,EACA7F,IAAAA,GACAL,KAAKxF,MAEH6P,EAAU,qBtB9EjB,SAAgB5I,GACfmN,IAAAA,IAAAA,EAAS,GACTC,EAAa,iEAER1G,EAAI,EAAGA,EAAI1G,EAAQ0G,IACd0G,GAAAA,EAAWC,OAAOtK,KAAKuK,MAFdF,GAEoBrK,KAAKwK,WAEzCJ,OAAAA,CACX,CsBsE6CK,CAAO,KAE5CjP,KAAKoK,oBAAoB/J,EAAKgK,EAASrK,KAAKxF,OAEtCyP,MAAAA,EAAe9D,EAAW,cAAcA,KAAc,GACtDZ,EAAQhG,EAASS,KAAKxF,OAMrB,MAAA,+EALiB+K,EAAQ,wBAAwBA,MAAY,KAC5CvF,KAAKxF,MAAM0P,iBAC7B,oBAAoBlK,KAAKxF,MAAM0P,oBAC/B,6BAKQD,oCACU/D,sCACCmE,mUAMUN,gDACAC,6JAKXJ,GACA,yEAAyEA,yCAGzEvC,GACA,+DAA+DA,yCAEjEhJ,EACE2B,KAAKxF,MACL,gEACA6P,wFAK5B,GJxKA5O,KUcW,cAAcmE,EACzBM,MAAAA,GACU,MACF0J,QAAAA,EAAU,GACVvC,MAAAA,EAAQ,GACRhC,YAAAA,EAAc,GACdG,KAAAA,EAAO,GACP0E,iBAAAA,EACA/D,SAAAA,EACAD,SAAAA,GACAlG,KAAKxF,MAEH0U,EAAuBhF,EACvB,qBAAqBA,KACrB,GACA3E,EAAQhG,EAASS,KAAKxF,OAG5B,MAAO,oCAAoC0L,aAAoBgJ,IAFvC3J,EAAQ,wBAAwBA,MAAY,kBAEiDY,2IAI7FX,GACA,6FACaA,gFAIboE,GACA,mEAAmEA,yCAGnEvC,GACA,yDAAyDA,yCAGzDhC,GACA,uDAAuDA,wCAEzD5H,EAAUuC,KAAKxF,MAAO,qEACtB6D,EAAW2B,KAAKxF,MAAO,qHAGnCwF,KAAK0J,uCAEnB,CAEAA,WAAAA,GACU,MAAE/L,IAAAA,EAAKgM,MAAAA,EAAQ,CAAC,GAAM3J,KAAKxF,OAE7BqD,GAAAA,EAAK,GACL0H,MAAAA,EAAQ,GACRqE,QAAAA,EAAU,GACVvE,YAAAA,EAAc,GACdwE,UAAAA,EAAY,GACZC,MAAAA,EAAQ,IACRH,EAEJ,OAAK9L,GAAOF,EAAIW,SAIT,sCACWX,EAAIW,2CACCsL,kHAGFrE,sCACIsE,wCACEC,+DAETzE,iCAZP,EAcf,IClGJ8J,EAAe,CACX,MACA,cACA,YACA,sBACA,qBACA,mBACA,mBCGEC,EAAcA,CAAC5S,EAAoCO,EAAoBsS,KACzE,GAAI7S,EAAO8S,eACP,OAEJ9S,EAAO8S,gBAAiB,EAefhG,EAAAA,iBAAiB,cAyJ1B,SAA0BrC,GACtB,MAAM2B,EAAS3B,EAAE2B,OAEgC,SAA7CA,EAAO2G,aAAa,uBAId3G,EAAAA,EA3Gd,SAAwC4G,GACpC,QAAeC,IAAXJ,GAAyBA,EAAOK,SAASF,GAK7C,IAFAG,EAAiB,GACjBC,EAAkB,GACXJ,IAAOH,GACKrN,EAAAA,KAAKwN,EAAGK,WACP7N,EAAAA,KAAKwN,EAAGM,YACxBN,EAAKA,EAAGO,UAEhB,CAiGIC,CAA+BC,GAE/BC,EAAWC,KAAKC,MACRnJ,EAAAA,EAAEoJ,QAAQ,GAAGC,QACbrJ,EAAAA,EAAEoJ,QAAQ,GAAGE,QACbC,EAAA,EACAC,EAAA,EACZ,IAxK0D,GACjDnH,EAAAA,iBAAiB,aA8K1B,SAAyBrC,GACjB,IAACyJ,IAAUC,EACX,OAGAC,IAAAA,EAAM3J,EAAEoJ,QAAQ,GAAGC,QACnBO,EAAM5J,EAAEoJ,QAAQ,GAAGE,QAEvBC,EAAQE,EAAQE,EAChBH,EAAQE,EAAQE,CACpB,IAxLwD,GAC/CvH,EAAAA,iBAAiB,YAyE1B,SAAwBrC,GAEhBgJ,GAAAA,IAAYhJ,EAAE2B,OACd,OAIEkI,MAAAA,EAAuC,IAArBtU,EAAOuU,YACzBC,EAAwC,GAApBxU,EAAOqC,WAEjC,IAAIoS,EACAC,EAAoBjB,EAAU,uBAAwBa,GAEtDK,EACAD,EAAoBjB,EAAU,uBAAwBe,GAEtDI,EAAeF,EAAoBjB,EAAU,qBAAsB,KACnEoB,EAAWlB,KAAKC,MAAQF,EACxB3G,EAAY,GACZ+H,EAAiBrK,EAAEqK,gBAAkBrK,EAAEoJ,SAAW,GAElD7L,GAAAA,KAAK+M,IAAIf,GAAUhM,KAAK+M,IAAId,GAExBjM,KAAK+M,IAAIf,GAAUW,GAA4BE,EAAWD,IACtDZ,EAAS,EACLgB,EAAqB,OAAQvK,KACjBsC,EAAA,eAGZiI,EAAqB,QAASvK,KAClBsC,EAAA,iBAIjB/E,KAAK+M,IAAId,GAAUQ,GAA0BI,EAAWD,IAC3DX,EAAS,EACLe,EAAqB,KAAMvK,KACfsC,EAAA,aAGZiI,EAAqB,OAAQvK,KACjBsC,EAAA,gBAKN,KAAdA,EAAkB,CAClB,IAAIpI,EAAY,CACZsQ,IAAKlI,EAAUxN,QAAQ,UAAW,IAClC2V,UAAYJ,EAAe,IAAsCI,WAAa,SAC9EC,OAAQjB,EACRkB,MAAON,EAAe,IAAM,IAAIhB,UAAW,EAC3CuB,OAAQlB,EACRmB,MAAOR,EAAe,IAAM,IAAIf,UAAW,GAItCnU,EAAAA,cACL,IAAIO,YAAY,SAAU,CAAEE,SAAS,EAAMsF,YAAY,EAAMvF,OAAQuE,KAIhE/E,EAAAA,cACL,IAAIO,YAAY4M,EAAW,CAAE1M,SAAS,EAAMsF,YAAY,EAAMvF,OAAQuE,IAE9E,CAGQuP,EAAA,KACAC,EAAA,KACGT,EAAA,IACf,IAhJsD,GAEtD,IAAIQ,EAAuB,KACvBC,EAAuB,KACvBH,EAAuB,KACvBC,EAAuB,KACvBP,EAA0B,KAC1BD,EAA8B,KAG9BN,EAA2B,GAC3BC,EAA4B,GAOvB4B,SAAAA,EAAqBO,EAA4C9K,GACtE,QAAewI,IAAXJ,EACO,OAAA,EAGX,IAAIG,EAAKvI,EAAE2B,OACPgG,GAAS,EACTzG,EAAI,EACDqH,KAAAA,IAAOH,GAAUT,GAAQ,CACxBoD,GAAAA,EAAaxC,GACb,OAAQuC,GACJ,IAAK,KACDnD,EAASe,EAAexH,KAAOqH,EAAGyC,aAAezC,EAAG0C,aACpD,MACJ,IAAK,OACQvC,EAAsB,IAAtBA,EAAexH,GACxB,MACJ,IAAK,OACDyG,EAASgB,EAAgBzH,KAAOqH,EAAG2C,YAAc3C,EAAG4C,YACpD,MACJ,IAAK,QACQxC,EAAuB,IAAvBA,EAAgBzH,GACzB,MACJ,QACayG,GAAA,EAGrBY,EAAKA,EAAGO,WACR5H,GACJ,CACOyG,OAAAA,CACX,CAeA,SAASoD,EAAaxC,GAClB,OAAOA,EAAGyC,aAAezC,EAAG0C,cAAgB1C,EAAG2C,YAAc3C,EAAG4C,WACpE,CA8HSlB,SAAAA,EAAoB1B,EAAiB6C,EAAgCC,GAEnE9C,KAAAA,GAAMA,IAAOzS,EAASwV,iBAAiB,CAC1C,IAAIC,EAAiBhD,EAAGD,aAAakD,OAAOJ,IAExCG,GAAAA,EACOE,OAAAA,SAASF,EAAgB,IAGpChD,EAAKA,EAAGO,UACZ,CAEOuC,OAAAA,CACX;;;;;;;;GC5OG,SAASK,EAA0BC,EAAMC,GACtCC,MAAAA,EAASF,EAAK7C,WAGpB,GAAI+C,IAFS/V,SAASgW,qBAAqB,QAAQ,GAG/C,OAGJ,MAAMC,EAAWF,EAAOG,SACxB,IAAA,MAAWC,KAAWF,EACdE,IAAYN,IACZC,EACMK,EAAQtI,aAAa,cAAeiI,GACpCK,EAAQC,gBAAgB,gBAGtCR,EAA0BG,EAAQD,EACtC,CCbA,MAuBeO,EAvBF9U,IACH+U,MAAAA,EAAUtW,SAAS4N,cAAc,OACvC0I,EAAQnK,UAAUC,IAAI,cACtBkK,EAAQ/J,iBAAiB,SAAS,KAC9BlN,EAAc,CAAEC,UAAWe,EAAmBd,KAAM,CAAEuB,GAAIS,IAAY,IAE1EvB,SAAS6K,KAAKkD,YAAYuI,GAC1BC,YAAW,KACPD,EAAQnK,UAAUC,IAAI,SAAQ,G9B0EV,E8BzET,EAcJiK,EAXDtJ,KACV,IAAK/M,SAASwW,uBAAuB,cAAc9R,OAC/C,OAEJ,MAAM4R,EAAUtW,SAASwW,uBAAuB,cAAc,GAC9DF,EAAQnK,UAAUT,OAAO,UACzB6K,YAAW,KACPD,EAAQ5K,QAAM,G9BkEG,K8BjET,ECHV+K,EAAa,SACbC,EAAc,cAEpB,MAAMC,UAAcC,YAChB9T,WAAAA,WAEIG,KAAKxF,MAAQ,GACbwF,KAAK4T,UAAY,KACjB5T,KAAK6T,QAAU,KAEf7T,KAAK8T,UAAY9T,KAAK+T,KAAKtK,KAAKzJ,MAChCA,KAAKgU,WAAahU,KAAK8J,MAAML,KAAKzJ,MAClCA,KAAKiU,iBAAmBjU,KAAKkU,YAAYzK,KAAKzJ,MAC9CA,KAAKmU,WAAanU,KAAKoU,MAAM3K,KAAKzJ,MAClCA,KAAKqU,aAAerU,KAAKsU,QAAQ7K,KAAKzJ,KAC1C,CAEAuU,iBAAAA,GACIvU,KAAKwU,MAAMC,QAAU,OACrBzU,KAAKxF,MAAQP,EAAY+F,KAAK9F,YAEzB8F,KAAKnC,KACNmC,KAAKnC,GAAKmC,KAAKxF,MAAMqD,KAGpBmC,KAAK0U,UAAY1U,KAAK2U,OACvB3U,KAAK2U,KAAO3U,KAAK6H,WAGrB7H,KAAK4T,WAAY,EACjB5T,KAAK6T,SAAU,EACf7T,KAAKE,QACT,CAEA0U,wBAAAA,CAAyB9W,EAAM+W,EAAUC,GAChCta,KAAAA,MAAQP,EAAY+F,KAAK9F,YAEjB,YAAT4D,IACAkC,KAAKxF,MAAMka,QAAUI,EAE7B,CAEA,6BAAWC,GACP,MAAO,CAAC,UACZ,CAEAC,oBAAAA,GACShV,KAAKiV,UAGVjV,KAAKkV,aACT,CAEAhV,MAAAA,GACQF,KAAKiV,UACLjV,KAAKkV,cAEH,MACFtL,QAAAA,EAAU,GACVuL,WAAAA,EAAa,GACbC,QAAAA,EAAU,YACV3W,KAAAA,EAAO,IACP4W,YAAAA,EAAc,QACd9P,MAAAA,EAAQ,GACRsE,UAAAA,EAAY,GACZ+C,UAAAA,EAAY,SACZ8H,QAAAA,EAAU,GACVY,cAAAA,GAAgB3V,EAAef,GAAGI,OAAS,cAAgB,aAC3DgB,KAAKxF,MACHma,EAAOD,GAAW1U,KAAK2U,KAE7B,GAAa,KAATA,EACKY,OAAAA,KAAAA,YACLvV,KAAKkJ,UAAUT,OAAO+K,GACtBxT,KAAKwV,QAAS,GACP,EAEXxV,KAAKyV,aAAad,GAClB3U,KAAK4K,aAAa,OAAQ5K,KAAK6T,QAAU,IAAMpV,GAG/CuB,KAAK4K,aAAa,OAAQ,UAC1B5K,KAAK4K,aAAa,cAAe,QACjC5K,KAAK4K,aAAa,UAAWwK,GAC7BpV,KAAK4K,aAAa,YAAagC,GAG/B5M,KAAK6H,UAAY,kFAGK,UAAZuN,EAAsB,uBAAyB,4FAExCC,oEAGLzL,GACA,iDACMA,GAAW,cAAc0L,MAAkB1L,2DAIjDuL,GACA,uDACUA,GAAc,uBAAuBA,8HAM3C5P,GACA,0DAA0DA,WAAesE,aAAqBA,+DAEhG8K,8CAEJ3U,KAAK0V,mDAET1V,KAAK6T,SAAWlU,EAAef,GAAGI,OAAS,mCAAqC,eAItFsU,YAAW,KACPtT,KAAKwU,MAAMC,QAAU,SAAA,GACtB,KFhHJ,SAAkCjF,GAC/BmG,MAAAA,EAAYnG,EAAGoG,iBAAiB,2DACtCpG,EAAGqG,eAAiBF,EAAU,GAC9BnG,EAAGsG,cAAgBH,EAAUA,EAAUlU,OAAS,GAChD+N,EAAGuG,YAAcvG,EAAGqG,cACxB,CE8GQG,CAAyBhW,MAEzBA,KAAKiW,cAAgBjW,KAAKwI,cAAc,UACxCxI,KAAKuV,WACT,CAEAG,YAAAA,GACU,MAAE/H,OAAAA,GAAW3N,KAAKxF,MACjB0b,OlCnIU1a,EkCmIAmS,IlCnI8B,UAAVnS,EkCmIV,oBAAsB,GlCnIhCA,IAAAA,CkCoIrB,CAEAia,YAAAA,CAAad,GACHwB,MAAAA,EAASpZ,SAAS4N,cAAc,OACtCwL,EAAOtO,UAAY8M,EACY,IAA3BwB,EAAOlD,SAASxR,QAA+C,aAA/B0U,EAAOlD,SAAS,GAAGmD,UACnDpW,KAAK6T,SAAU,EACf7T,KAAK4K,aAAa,QAAS,QAEnC,CAEAyL,OAAAA,GACItZ,SAASgW,qBAAqB,QAAQ,GAAG7J,UAAUC,IAAIsK,GACvDL,EAAapT,KAAKnC,GACtB,CAEAyY,UAAAA,GAEwBtW,KAAK+P,WAAWwG,QAAQ,aAExCxZ,SAASgW,qBAAqB,QAAQ,GAAG7J,UAAUT,OAAOgL,GAE9DL,GACJ,CAEAoD,eAAAA,GACIxW,KAAK4T,WAAa5T,KAAK4T,UAEvB5T,KAAK4K,aAAa,aAAc5K,KAAK4T,WAErCjB,EAA0B3S,KAAMA,KAAK4T,UACzC,CAEA,UAAMG,CAAK9M,GACDvK,MAAAA,EhCnKWuK,CAAAA,IACrB,GAAKA,EAAErK,OAGP,OAAOqK,EAAErK,MAAAA,EgC+JS6Z,CAAUxP,GACpBvK,EAAMmB,KAAOmC,KAAKnC,KAKtBmC,KAAKsJ,iBAAiB,gBAAiBtJ,KAAKmU,YAC5CpX,SAASuM,iBAAiB,UAAWtJ,KAAKqU,cAC1CrU,KAAK0W,cAAgB3Z,SAAS4Z,cAE9B3W,KAAKqW,UACLrW,KAAKwW,kBACLxW,KAAK4K,aAAa,cAAe,SACjC5K,KAAKwV,QAAUxV,KAAKwV,OAGpBpZ,EAAc,CACVC,U/BxLsB,6B+ByLtBC,KAAMI,UAGJ,IAAIka,SAAQC,IACdvD,YAAW,KACPtT,KAAKkJ,UAAUC,IAAIqK,GACnBqD,M/B9HS,I+B+HD,IAEpB,CAEA/M,KAAAA,CAAMpN,GACFA,GAAAA,EAAMoa,cAAe,EACjBpa,EAAMqa,iBACNra,EAAMqa,kBAIV/W,KAAKsJ,iBAAiB,gBAAiBtJ,KAAKmU,YAC5CpX,SAASia,oBAAoB,UAAWhX,KAAKqU,cAC7CrU,KAAKsW,aACDtW,KAAK6T,QAAS,CACRoD,MAAAA,EAAiBjX,KAAKuW,QAAQ,mBAChCU,GACAA,EAAe/N,UAAUT,OAAO,iBAExC,CACAzI,KAAKwW,kBACLxW,KAAK4K,aAAa,cAAe,QACjC5K,KAAKwV,QAAUxV,KAAKwV,OACpBxV,KAAKkJ,UAAUT,OAAO+K,GAEtBpX,EAAc,CACVC,U/BxNsB,6B+ByNtBC,KAAM,CAAEuB,GAAImC,KAAKnC,KAEzB,CAEAuW,KAAAA,GACIpU,KAAKgX,oBAAoB,gBAAiBhX,KAAKmU,YAC3CnU,KAAKwV,OACLxV,KAAKiW,cAAc7B,QAEnBpU,KAAK0W,cAActC,OAE3B,CAEAE,OAAAA,CAAQrN,IF3OL,SAAiBA,EAAGuI,EAAI0H,GACtB1H,EAAGE,SAASzI,EAAE2B,QAOf4G,EAAGuG,YAAc9O,EAAE2B,OANf4G,EAAGuG,cAAgBvG,EAAGqG,eACtBqB,EAAO1H,EAAGsG,cAAc1B,QAAU5E,EAAGqG,eAAezB,QAEpD8C,EAAO1H,EAAGqG,eAAezB,QAAU5E,EAAGsG,cAAc1B,OAKhE,CEkOQE,CAAQrN,EAAGjH,MAAM,EACrB,CAEAkU,WAAAA,CAAYjN,GACM,WAAVA,EAAE1L,KAAoByE,KAAKwV,QAC3BxV,KAAK8J,MAAM7C,EAEnB,CAEAkQ,SAAAA,CAAUlQ,GACFjH,KAAKwV,QACLxV,KAAK8J,MAAM7C,EAEnB,CAEAmQ,2BAAAA,GACIhb,EAAc,CACVC,U/BxOsB,6B+ByOtBC,KAAM,CAAEuB,GAAImC,KAAKnC,KAEzB,CAEA0X,SAAAA,GACIvV,KAAKiV,UAAW,EACM,MAAtBjV,KAAKiW,eAAyBjW,KAAKiW,cAAc3M,iBAAiB,QAAStJ,KAAKgU,YAChFxX,OAAO8M,iBAAiBnM,EAAkB6C,KAAK8T,WAC/CtX,OAAO8M,iBAAiBlM,EAAmB4C,KAAKgU,YAChDjX,SAASuM,iBAAiBjM,EAAsB2C,KAAKiU,kBAEjDtU,EAAef,GAAGI,SAClBoQ,EAAY5S,OAAQO,SAAUiD,MAC9BA,KAAKqX,eAAiBrX,KAAKmX,UAAU1N,KAAKzJ,MAC1CjD,SAASuM,iBAAiBhM,EAAmB0C,KAAKqX,gBAC9CrX,KAAK6T,UACL7T,KAAKsX,aAAetX,KAAKwI,cAAc,iBACvCxI,KAAKuX,iCAAmCvX,KAAKoX,4BAA4B3N,KAAKzJ,MAC9EA,KAAKsX,aAAahO,iBAAiB,QAAStJ,KAAKuX,mCAG7D,CAEArC,WAAAA,GACSD,KAAAA,UAAW,EACM,MAAtBjV,KAAKiW,eACDjW,KAAKiW,cAAce,oBAAoB,QAAShX,KAAKgU,YACzDxX,OAAOwa,oBAAoB7Z,EAAkB6C,KAAK8T,WAClDtX,OAAOwa,oBAAoB5Z,EAAmB4C,KAAKgU,YACnDjX,SAASia,oBAAoB3Z,EAAsB2C,KAAKiU,kBACpDjU,KAAKqX,iBACLta,SAASia,oBAAoB1Z,EAAmB0C,KAAKqX,gBACrDrX,KAAKqX,eAAiB,MAEtBrX,KAAKuX,mCACLvX,KAAKsX,aAAaN,oBAAoB,QAAShX,KAAKuX,kCACpDvX,KAAKuX,iCAAmC,KAEhD,EAGJC,eAAeC,IAAI,aAAeD,eAAeE,OAAO,WAAYhE,GCzRpE,MAAMiE,UAAwBhE,YAC1BY,iBAAAA,GACIvU,KAAKxF,MAAQP,EAAY+F,KAAK9F,YAC9B8F,KAAK4X,WAAa,IAAIC,gBACtB7X,KAAK8X,YAAc,GACnB9X,KAAKE,QACT,CAEAA,MAAAA,GACU,MACF6X,aAAeC,OAAAA,GACfC,QAAUC,YAAAA,EAAaC,eAAAA,EAAgBC,sBAAAA,GACvCxa,SAAAA,GACAoC,KAAKxF,MAEH6d,EAAmBL,EAAOM,WAAqC,GAAxB,sBACvCC,EAAyBP,EAAOM,WAA2B,GAAdJ,EAE7CM,EAA2BJ,EAC3B,sBAAsBA,KACtB,kCAENpY,KAAK6H,UAAY,qBACe,UAAtBmQ,EAAOM,YAA0BtY,KAAKyY,gIAG3BD,KAA4BH,yIAGxBE,KAAyBJ,wCACvBva,EAASC,2CACPD,EAASE,iDACLF,EAASG,qDACTH,EAASJ,yDAE5BwC,KAAK0Y,mEAGnB1Y,KAAKG,YACT,CAEAsY,YAAAA,GACU,MACFV,aACIC,QACIM,WAAAA,EACApO,iBAAAA,EAAmB,GACnBN,QAAAA,EAAU,KACVvC,MAAAA,EAAQ,KACRhC,YAAAA,EAAc,OAGtB4S,QAAU/R,SAAAA,EAAW,QAASgS,YAAAA,IAC9BlY,KAAKxF,MAET,IAAK8d,EACM,MAAA,GAOJ,MAAA,8GAEiBpS,sCACCgS,4DAPIhO,EACvB,wBAAwBA,IACxB,wHASYN,GAAW,2BAA2BA,qCACtCvC,GAAS,yBAAyBA,qCAClChC,GAAe,uBAAuBA,sEAG5D,CAEAqT,mBAAAA,GACU,MACFX,aAAeY,WAAAA,GACfV,QAAUW,YAAAA,EAAaC,IAAAA,IACvB7Y,KAAKxF,MAEHse,EAAQ3J,EACR4J,EAAYD,EAAMvV,QAAQqV,GAE5BG,WAAAA,EACO,GAKJ,qFAFUF,GAAO,uBAIpBC,EAAMC,6BAEIJ,EACG7c,KAAIkd,GAAahZ,KAAKiZ,mBAAmBD,EAAUlN,WACnDoN,KAAK,uCAG1B,CAEAD,kBAAAA,CAAmBD,GACT,MAAEG,SAAAA,GAAanZ,KAAKxF,MAAMyd,OAEhC,IAAImB,EAAW,GACf,IAAA,MAAY7d,KAAQgG,OAAO8X,QAAQ1T,GAC/B,GAAIqT,EAAU,MAAMzd,KAAQ,CACxB6d,EAAW7d,EACX,KACJ,CAGE+d,MAAAA,EAAY3T,EAAgByT,GAClC,IAAKE,EACD,MAAM,IAAI7c,MAAM,sBAAsB2c,KAIrCzZ,EAAef,GAAGI,SACnBga,EAAUO,QAAQpT,SAAWgT,IAG5BxZ,EAAef,GAAGO,UAAYQ,EAAef,GAAGQ,SACjD4Z,EAAUO,QAAQnT,UAAW,GAGjC,MAAMoT,EAAO,IAAIF,EAAUN,EAAUO,SAChCzB,OAAAA,KAAAA,YAAc9X,KAAK8X,YAAY2B,OAAOD,EAAKrZ,cACzCqZ,EAAKtZ,QAChB,CAEAC,UAAAA,GACUuZ,MAAAA,EAAS1Z,KAAK4X,WAAW8B,OAC1B5B,KAAAA,YAAY6B,SAAQ1S,IACrB,MAAM1K,EAAUQ,SAASyL,cAAcvB,EAAEpJ,IACrCtB,GACAA,EAAQ+M,iBAAiBrC,EAAEsC,UAAWtC,EAAEuC,GAAI,CAAEkQ,OAAAA,GAAQ,GAGlE,CAEA1E,oBAAAA,GACIhV,KAAK4X,WAAWgC,OACpB,EAGJpC,eAAeC,IAAI,wBACfD,eAAeE,OAAO,sBAAuBC"}