{"version":3,"file":"index.es.min.js","sources":["../../../packages/helpers/src/utils.ts","../../../packages/helpers/src/props.helpers.js","../../../packages/helpers/src/assets/js/eventDispatch.js","../../../packages/components/src/constants.mjs","../../../packages/helpers/src/viewport.helpers.ts","../../../packages/helpers/src/gtmEvents.js","../../../packages/helpers/src/events.helpers.ts","../../../packages/page-builder-sections/src/hero-banner/components/countdown/countdown.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/components/src/video/constants.mjs","../../../packages/helpers/src/getScript.js","../../../packages/helpers/src/deferred.js","../../../packages/helpers/src/dataLayer.js","../../../packages/helpers/src/playerYoutube.js","../../../packages/helpers/src/htmlElement.js","../../../packages/helpers/src/playerYouku.js","../../../packages/components/src/video/components/youtube-overlay.js","../../../packages/components/src/video/video.js","../../../packages/page-builder-sections/src/hero-banner/hero-banner.js"],"sourcesContent":["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 '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\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, '"').replace(/'/g, ''')\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","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 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 kr: 'https://apps.apple.com/kr/app/%EB%84%A4%EC%8A%A4%ED%94%84%EB%A0%88%EC%86%8C-%EB%B6%80%ED%8B%B0%ED%81%AC/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","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 { 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 ...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 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 createProps from '@kissui/helpers/src/props.helpers'\n\nclass Counter extends HTMLElement {\n constructor() {\n super()\n this.props = {}\n this.intervalM = null\n }\n\n connectedCallback() {\n this.props = createProps(this.attributes)\n this.render()\n }\n\n render() {\n const { date, time = '00:00:00', locale = {} } = this.props\n if (!date) {\n return\n }\n const cleanLocale = typeof locale === 'string' ? JSON.parse(locale) : locale\n const dateTime = `${date} ${time}`\n const countDownDate = new Date(dateTime).getTime()\n\n if (this.checkDifference(countDownDate) <= 0) {\n this.setEndAttribute()\n return\n }\n\n this.reRenderTime(countDownDate, cleanLocale)\n this.intervalM = setInterval(() => this.reRenderTime(countDownDate, cleanLocale), 1000)\n }\n\n renderTime(val, text) {\n return `${val}${text}`\n }\n\n reRenderTime(countDownDate, locale) {\n const normalizeTime = operation => {\n const floor = Math.floor(operation)\n return ('0' + floor).slice(-2)\n }\n\n const difference = this.checkDifference(countDownDate)\n const days = normalizeTime(difference / (1000 * 60 * 60 * 24))\n const hours = normalizeTime((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))\n const minutes = normalizeTime((difference % (1000 * 60 * 60)) / (1000 * 60))\n const seconds = normalizeTime((difference % (1000 * 60)) / 1000)\n\n this.innerHTML = `<strong>${this.renderTime(days, locale.days)} ${this.renderTime(\n hours,\n locale.hours\n )} ${this.renderTime(minutes, locale.minutes)} ${this.renderTime(\n seconds,\n locale.seconds\n )}</strong>`\n\n if (difference <= 0) {\n if (this.intervalM) {\n clearInterval(this.intervalM)\n }\n this.innerHTML = ''\n this.setEndAttribute()\n }\n }\n\n setEndAttribute() {\n this.setAttribute('countdown-end', 'true')\n }\n\n checkDifference(countDownDate) {\n const dateNow = new Date().getTime()\n return countDownDate - dateNow\n }\n\n disconnectedCallback() {\n if (this.intervalM) {\n clearInterval(this.intervalM)\n }\n }\n}\n\ncustomElements.get('nb-countdown') || customElements.define('nb-countdown', Counter)\n\nexport default Counter\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 heading_id = 'popin-heading'\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 ${\n heading &&\n `<h2 id=\"${heading_id}\" class=\"${heading_class}\">${heading}</h2>`\n }\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","export const VIDEO_SERVICE_YOUTUBE = 'youtube'\nexport const VIDEO_SERVICE_YOUKU = 'youku'\nexport const VIDEO_SERVICE_LOCAL = 'local'\n","export default function getScript(source, asyncLoad = true, defer = false) {\n return new Promise((resolve, reject) => {\n if (document.querySelector(`script[src=\"${source}\"]`)) {\n return resolve() // Script already loaded\n }\n\n const script = document.createElement('script')\n const prior = document.getElementsByTagName('script')[0]\n script.async = asyncLoad\n script.defer = defer\n script.addEventListener('load', () => resolve())\n script.addEventListener('error', () => reject(new Error('Loading script')))\n script.src = source\n prior.parentNode.insertBefore(script, prior)\n })\n}\n","export default class Deferred {\n constructor() {\n this.promise = new Promise((resolve, reject) => {\n this.reject = reject\n this.resolve = resolve\n })\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 getScript from './getScript'\nimport Deferred from './deferred'\nimport { getMarketCode } from './dataLayer'\n\nfunction initYouTubeIframeAPI() {\n const deferred = new Deferred()\n\n if (window.YT?.Player || getMarketCode() === 'cn') {\n deferred.resolve()\n }\n\n // YouTube API will call this function automatically when player API is ready\n // https://developers.google.com/youtube/iframe_api_reference\n window.onYouTubeIframeAPIReady = function () {\n deferred.resolve()\n }\n\n getScript('https://www.youtube.com/iframe_api', false).then(() => {\n window.YT?.ready(() => deferred.resolve())\n })\n\n return deferred.promise\n}\n\nclass PlayerYoutube {\n constructor() {\n this.iframeApi = initYouTubeIframeAPI()\n }\n\n attach(iframeContainer, videoId, isBackgroundVideoPlaying, isAutoPlay = 1, moreParams = {}) {\n let params = {}\n\n if (isBackgroundVideoPlaying) {\n params = { playlist: videoId, controls: 0, loop: 1 }\n }\n\n return new Promise(resolve => {\n this.iframeApi.then(() => {\n const player = new window.YT.Player(iframeContainer, {\n videoId,\n host: 'https://www.youtube-nocookie.com',\n playerVars: {\n // disablekb: 1,\n // showinfo: 0,\n // modestbranding: 1,\n enablejsapi: 1,\n rel: 0,\n fs: 0,\n autoplay: isAutoPlay,\n ...params,\n ...moreParams\n },\n events: {\n onReady: () => {\n if (isBackgroundVideoPlaying) {\n player.mute()\n }\n resolve(player)\n },\n onStateChange: () => ({}),\n onError: () => ({})\n }\n })\n })\n })\n }\n}\n\nexport default PlayerYoutube\n","/**\n * Return real width for a DOM Node\n * @param {HTMLElement} el\n * @returns {number}\n */\nexport const outerWidth = el => {\n const style = getComputedStyle(el)\n const width = style.getPropertyValue('width') || 0\n const marginLeft = style.getPropertyValue('margin-left') || 0\n const marginRight = style.getPropertyValue('margin-right') || 0\n\n return parseInt(width) + parseInt(marginLeft) + parseInt(marginRight)\n}\n\n/**\n * Return real height for a DOM Node\n * @param {DOM Node} el\n * @returns {number}\n */\nexport const outerHeight = el => {\n const style = getComputedStyle(el)\n const height = style.getPropertyValue('height') || 0\n const marginTop = style.getPropertyValue('margin-top') || 0\n const marginBottom = style.getPropertyValue('margin-bottom') || 0\n\n return parseInt(height) + parseInt(marginTop) + parseInt(marginBottom)\n}\n\nexport const appendSchema = content => {\n const el = window.document.createElement('script')\n el.setAttribute('type', 'application/ld+json')\n el.innerHTML = JSON.stringify(content)\n window.document.head.appendChild(el)\n}\n","import getScript from './getScript'\nimport { outerWidth, outerHeight } from './htmlElement'\n\nclass PlayerYouku {\n constructor() {\n this.iframeApi = new Promise(resolve => {\n getScript('https://player.youku.com/jsapi').then(() => resolve())\n })\n }\n\n attach(iframeContainerId, videoId, isBackgroundVideoPlaying, isAutoPlay = 1, moreParams = {}) {\n let params = {}\n if (isBackgroundVideoPlaying) {\n const container = document.getElementById(iframeContainerId)\n\n params = {\n playlist: videoId,\n controls: 0,\n loop: 1,\n autoplay: 1,\n width: outerWidth(container),\n height: outerHeight(container)\n }\n }\n return new Promise(resolve => {\n this.iframeApi.then(() => {\n const player = new window.YKU.Player(iframeContainerId, {\n styleid: '0',\n client_id: 'a3660779c8b57c32',\n vid: videoId,\n newPlayer: true,\n autoplay: isAutoPlay,\n show_related: false,\n width: 640,\n height: 360,\n ...params,\n ...moreParams,\n events: {\n onPlayerReady: () => resolve(player),\n onPlayStart: () => ({}),\n onPlay: () => ({}),\n onPlayEnd: () => ({}),\n onPause: () => ({}),\n onWaiting: () => ({}),\n onFullScreen: () => ({}),\n onPlayError: () => ({})\n }\n })\n })\n })\n }\n}\n\nexport default PlayerYouku\n","import createProps from '@kissui/helpers/src/props.helpers'\n\nclass YoutubeOverlay extends HTMLElement {\n connectedCallback() {\n const { video_id = '' } = createProps(this.attributes)\n\n if (video_id) {\n this.render(video_id)\n }\n }\n\n render(videoId) {\n this.setAttribute('role', 'button')\n this.style.backgroundImage = `url(https://img.youtube.com/vi/${videoId}/sddefault.jpg)`\n this.innerHTML = `\n <div>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"90\"\n height=\"60\"\n viewBox=\"0 0 90 60\"\n >\n <rect width=\"90\" height=\"60\" rx=\"12\" fill=\"#FF0000\" />\n <polygon points=\"36,15 36,45 60,30\" fill=\"#FFFFFF\" />\n </svg>\n </div>\n `\n }\n}\n\ncustomElements.get('nb-youtube-overlay') ||\n customElements.define('nb-youtube-overlay', YoutubeOverlay)\n\nexport default YoutubeOverlay\n","import { VIDEO_SERVICE_YOUKU, VIDEO_SERVICE_YOUTUBE, VIDEO_SERVICE_LOCAL } from './constants.mjs'\nimport PlayerYoutube from '@kissui/helpers/src/playerYoutube'\nimport PlayerYouku from '@kissui/helpers/src/playerYouku'\nimport './components/youtube-overlay'\n\nimport { readEvent } from '@kissui/helpers/src/assets/js/eventDispatch'\nimport {\n EVENT_VIDEO,\n EVENT_POPIN_CLOSED,\n EVENT_POPIN_OPENED,\n EVENT_VIDEO_TOGGLE,\n VIDEO_ON_HOVER,\n VIDEO_ON_OUT\n} from '@kissui/components'\nimport viewportHelper from '@kissui/helpers/src/viewport.helpers'\nimport createProps from '@kissui/helpers/src/props.helpers'\nimport { setAttributes } from '@kissui/helpers/src/utils'\n\nclass Video extends HTMLElement {\n #percentThresholds = [25, 50, 75, 90]\n #lastTrackedThreshold = 0\n #progressInterval\n #eventCategory = 'User Engagement'\n\n constructor() {\n super()\n\n this.videoId = null\n this.videoMobile = null\n this.currentVideo = null\n this.videoService = ''\n this.containerId = ''\n this.ccPolicyLanguage = null\n this.ccPolicyCountry = null\n this.ccLoadPolicy = null\n this.displayControls = 0 // not display by default\n this.disabledKeyboard = 1 // disabled by default\n this.isBackground = false\n this.autoPlay = 0\n this.loop = 0\n this.mute = 'false'\n this.playOnHover = 'false'\n this.allowPopinAutoplay = false\n\n this.isPlaying = false\n\n this.play = null\n this.pause = null\n this.stop = null\n this.moveTo = null\n\n this.loadInterupted = null\n this.controlsReady = null\n this.overlayElement = null\n\n this._externalControl = this._externalControl.bind(this)\n }\n\n connectedCallback() {\n const { video_id, video_mobile, container_id, video_service, auto_play } = createProps(\n this.attributes\n )\n this.videoId = video_id || this.videoId\n this.videoMobile = video_mobile || this.videoMobile\n this.containerId = container_id || this.containerId\n this.videoService = video_service || this.videoService\n this.currentVideo =\n viewportHelper.is.mobile && this.videoMobile !== '' && this.videoMobile !== null\n ? this.videoMobile\n : this.videoId\n\n this.getAttributes(auto_play)\n this.init()\n }\n\n getAttributes(auto_play) {\n this.popinId = this.getAttribute('popin_id') || this.popinId\n this.ccPolicyLanguage = this.getAttribute('ccPolicy_language') || this.ccPolicyLanguage\n this.ccPolicyCountry = this.getAttribute('ccPolicy_country') || this.ccPolicyCountry\n this.ccLoadPolicy = this.getAttribute('cc_load_policy') || this.ccLoadPolicy\n this.displayControls =\n parseInt(this.getAttribute('display_controls')) || this.displayControls\n this.isBackground = this.getAttribute('is_background') === 'true' || this.isBackground\n this.autoPlay = this.getAttribute('auto_play') === 'true' || auto_play ? 1 : this.autoPlay\n this.loop = this.getAttribute('loop') === 'true' ? 1 : this.loop\n this.mute = this.getAttribute('mute') || this.mute\n this.playOnHover = this.getAttribute('play_on_hover') || this.playOnHover\n this.allowPopinAutoplay =\n this.getAttribute('allow_popin_autoplay') === 'true' || this.allowPopinAutoplay\n }\n\n init() {\n this.unbindEvent()\n\n if (this.popinId !== '') {\n this.setPopinEvents()\n }\n\n if (this.playOnHover === 'true') {\n this.setHoverEvents()\n }\n\n if (this.currentVideo) {\n this.render()\n\n if (this.videoService === VIDEO_SERVICE_LOCAL) {\n this.initLocal()\n } else {\n this.initServiceVideo()\n }\n\n this.boundExternalControl = this._externalControl.bind(this)\n window.addEventListener(EVENT_VIDEO + this.containerId, this.boundExternalControl)\n }\n }\n\n initServiceVideo() {\n if (!this.controlsReady) {\n if (this.videoService === VIDEO_SERVICE_YOUKU) {\n this.initYouku()\n } else {\n this.initYoutubeOverlay()\n }\n }\n }\n\n setPopinEvents() {\n this.boundOnPopinClosed = this.onPopinClosed.bind(this)\n window.addEventListener(EVENT_POPIN_CLOSED, this.boundOnPopinClosed)\n this.boundOnPopinOpened = this.onPopinOpened.bind(this)\n window.addEventListener(EVENT_POPIN_OPENED, this.boundOnPopinOpened)\n this.boundOnTogglePlayback = this.onTogglePlayback.bind(this)\n window.addEventListener(EVENT_VIDEO_TOGGLE, this.boundOnTogglePlayback)\n }\n\n setHoverEvents() {\n this.boundOnHover = this.onHover.bind(this)\n window.addEventListener(VIDEO_ON_HOVER, this.boundOnHover)\n this.boundOnOut = this.onOut.bind(this)\n window.addEventListener(VIDEO_ON_OUT, this.boundOnOut)\n }\n\n popinValid(id) {\n return this.popinId !== undefined && this.popinId !== '' && id === this.popinId\n }\n\n async onPopinOpened(e) {\n if (!this.allowPopinAutoplay || !this.popinValid(e.detail.id)) {\n return\n }\n\n // YouTube: hide lazy-overlay and init video on popin open\n // YouTube: prevent recreating player when popin closed & reopened\n if (this.videoService === VIDEO_SERVICE_YOUTUBE && !this.controlsReady) {\n this.initYoutube()\n return\n }\n\n await this.controlsReady\n this.play()\n }\n\n async onPopinClosed(e) {\n if (this.popinValid(e.detail.id)) {\n await this.controlsReady\n\n this.videoService === VIDEO_SERVICE_YOUTUBE ? this.stop() : this.pause()\n }\n }\n async onHover(e) {\n if (e.detail.id === this.containerId) {\n await this.controlsReady\n this.mute()\n this.play()\n this.loop = 1\n }\n }\n async onOut(e) {\n if (e.detail.id === this.containerId) {\n await this.controlsReady\n this.stop()\n }\n }\n\n async onTogglePlayback(e) {\n if (this.popinValid(e.detail.id)) {\n await this.controlsReady\n if (this.isPlaying) {\n this.pause()\n } else {\n this.play()\n }\n }\n }\n\n initYouku() {\n // Todo : Youku is not playing on mobile\n // Todo : to CSS display is not good\n const self = this\n const _YkPlayer = new PlayerYouku()\n\n this.controlsReady = new Promise((resolve, reject) => {\n this.loadInterupted = reject\n _YkPlayer\n .attach(this.containerId, this.currentVideo, this.isBackground, this.autoPlay)\n .then(player => {\n self.play = () => {\n player.playVideo()\n }\n self.pause = () => player.pauseVideo()\n self.stop = () => {\n player.pauseVideo()\n }\n\n window.addEventListener(\n 'message',\n function (e) {\n const { msg, stateParam } = e.data\n\n if (msg == 'state') {\n if (stateParam === 'play') {\n self.isPlaying = true\n } else if (stateParam === 'pause' || stateParam === 'stop') {\n self.isPlaying = false\n }\n }\n },\n false\n )\n })\n .finally(() => resolve())\n })\n }\n\n initYoutubeOverlay() {\n if (this.autoPlay) {\n this.initYoutube()\n return\n }\n\n this.overlayElement = document.createElement('nb-youtube-overlay')\n setAttributes(this.overlayElement, { video_id: this.currentVideo })\n this.appendChild(this.overlayElement)\n this.overlayElement.addEventListener('click', () => this.initYoutube())\n }\n\n initYoutube() {\n const _YtPlayer = new PlayerYoutube()\n\n const additionalParams = {\n color: '#8F7247',\n controls: this.displayControls,\n disablekb: this.disabledKeyboard,\n fs: 1\n }\n\n if (this.loop) {\n additionalParams.loop = this.loop\n additionalParams.controls = 0\n additionalParams.playlist = this.currentVideo\n }\n\n if (this.ccPolicyLanguage !== null) {\n Object.assign(additionalParams, {\n cc_load_policy: this.ccLoadPolicy || 1,\n cc_lang_pref: this.ccPolicyLanguage\n })\n }\n\n this.controlsReady = new Promise((resolve, reject) => {\n this.loadInterupted = reject\n _YtPlayer\n .attach(\n this.containerId,\n this.currentVideo,\n this.isBackground,\n this.autoPlay,\n additionalParams\n )\n .then(player => {\n this.play = () => player.playVideo()\n this.pause = () => player.pauseVideo()\n this.mute = () => player.mute()\n this.unMute = () => player.unMute()\n this.stop = () => player.stopVideo()\n this.moveTo = (time = 0) => player.seekTo(time, true)\n\n player.addEventListener('onStateChange', event =>\n this.onYoutubePlayerStateChange(player, event)\n )\n\n this.play()\n\n if (this.overlayElement) {\n this.overlayElement.removeEventListener('click', () => this.initYoutube())\n this.overlayElement.remove()\n }\n })\n .finally(() => resolve())\n })\n }\n\n onYoutubePlayerStateChange(player, event) {\n if (!player || !event || !window.YT) {\n return\n }\n\n const { PlayerState } = window.YT\n const { videoTitle } = player\n // -1 – unstarted\n // 0 – ended\n // 1 – playing\n // 2 – paused\n // 3 – buffering\n // 5 – video cued\n const state = event.data\n window.gtmDataObject = window.gtmDataObject || []\n\n if (state === PlayerState.PLAYING) {\n this.isPlaying = true\n\n window.gtmDataObject.push({\n event: 'video_playing',\n eventCategory: this.#eventCategory,\n eventAction: 'YouTube Video - Play',\n eventLabel: videoTitle,\n videoTitle\n })\n\n // Track video progress every second\n this.#progressInterval = setInterval(() => {\n this.trackVideoProgress(player, event)\n }, 1000)\n } else if (state === PlayerState.PAUSED) {\n this.isPlaying = false\n\n window.gtmDataObject.push({\n event: 'video_paused',\n eventCategory: this.#eventCategory,\n eventAction: 'YouTube Video - Pause',\n eventLabel: videoTitle,\n videoTitle\n })\n } else if (state === PlayerState.ENDED) {\n window.gtmDataObject.push({\n event: 'video_ended',\n eventCategory: this.#eventCategory,\n eventAction: 'YouTube Video - Complete',\n eventLabel: `Video - Complete - ${videoTitle}`,\n videoTitle\n })\n clearInterval(this.#progressInterval)\n }\n }\n\n trackVideoProgress(player, event) {\n const { PlayerState } = window.YT\n const { videoTitle, playerInfo } = player\n const state = event.data\n\n if (playerInfo?.duration && playerInfo?.currentTime) {\n const percentWatched = (playerInfo.currentTime / playerInfo.duration) * 100\n\n for (let threshold of this.#percentThresholds) {\n if (\n state === PlayerState.PLAYING &&\n percentWatched >= threshold &&\n this.#lastTrackedThreshold < threshold\n ) {\n window.gtmDataObject.push({\n event: 'video_progress',\n eventCategory: this.#eventCategory,\n eventAction: 'YouTube Video - Progress',\n eventLabel: `Video - Watched ${threshold}% - ${videoTitle}`,\n percentWatched: threshold,\n videoTitle\n })\n this.#lastTrackedThreshold = threshold\n }\n }\n }\n }\n\n initLocal() {\n const video = document.getElementById(this.containerId)\n this.play = () => video.play()\n this.pause = () => video.pause()\n }\n\n renderVideo() {\n if (this.videoService === VIDEO_SERVICE_LOCAL) {\n const autoPlay = this.autoPlay === 1 ? 'true' : 'false'\n const loop = this.loop === 1 ? 'true' : 'false'\n\n return `\n <video autoplay=\"${autoPlay}\" muted=\"${this.mute}\" loop=\"${loop}\" id=\"${\n this.containerId\n }\" ${this.displayControls === 1 ? `controls=\"true\"` : ''}>\n <source src=\"${this.currentVideo}\" type=\"video/mp4\">\n </video>\n `\n }\n\n return `<div id=\"${this.containerId}\"></div>`\n }\n\n render() {\n this.innerHTML = `${this.renderVideo()}`\n }\n\n _externalControl(e) {\n const event = readEvent(e)\n const { action, time = null } = event\n\n switch (action) {\n case 'play':\n this.play()\n break\n case 'pause':\n this.pause()\n break\n case 'mute':\n this.mute()\n break\n case 'unmute':\n this.unMute()\n break\n case 'stop':\n this.stop()\n break\n case 'moveTo':\n this.moveTo(time)\n break\n default:\n }\n }\n\n unbindEvent() {\n if (this.popinId !== '') {\n window.removeEventListener(EVENT_POPIN_CLOSED, this.boundOnPopinClosed)\n window.removeEventListener(EVENT_POPIN_OPENED, this.boundOnPopinOpened)\n window.removeEventListener(EVENT_VIDEO_TOGGLE, this.boundOnTogglePlayback)\n }\n\n if (this.playOnHover === 'true') {\n window.removeEventListener(VIDEO_ON_HOVER, this.boundOnHover)\n window.removeEventListener(VIDEO_ON_OUT, this.boundOnOut)\n }\n\n if (this.currentVideo !== '') {\n window.removeEventListener(EVENT_VIDEO + this.containerId, this.boundExternalControl)\n }\n\n if (this.loadInterupted) {\n this.loadInterupted()\n this.loadInterupted = null\n }\n\n if (this.overlayElement) {\n this.overlayElement.removeEventListener('click', () => this.initYoutube())\n }\n }\n\n disconnectedCallback() {\n this.unbindEvent()\n }\n}\n\ncustomElements.get('nb-video') || customElements.define('nb-video', Video)\n\nexport default Video\n","import { makeId, setAttributes, stringifyForAttribute } from '@kissui/helpers/src/utils'\nimport createProps from '@kissui/helpers/src/props.helpers'\nimport { dispatchEvent } from '@kissui/helpers/src/assets/js/eventDispatch'\nimport viewportHelper from '@kissui/helpers/src/viewport.helpers'\nimport { EVENT_POPIN_OPEN, EVENT_CTA_CLICK, CONTRAST_DARK } from '@kissui/components'\nimport { handlePromoClick } from '@kissui/helpers/src/gtmEvents'\n\nimport './components/countdown'\nimport '@kissui/components/src/popin'\nimport '@kissui/components/src/video'\n\nclass HeroBanner extends HTMLElement {\n constructor() {\n super()\n this.isMobile = false\n this.popinId = `video_${makeId(10)}`\n this.hasVideo = false\n this.hasSelfHostedVideo = false\n this.headingCountdown = false\n this.descCountdown = false\n this.countdownEnded = false\n this.boundOnLinkClick = this.onLinkClick.bind(this)\n this.boundOnOpenPlayer = this.onOpenPlayer.bind(this)\n this.boundhandlePromoClick = this.handleClick.bind(this)\n this.boundOnButtonCtaClick = this.onButtonCtaClick.bind(this)\n this.boundOnButtonSelfVideoClick = this.boundOnButtonSelfVideoClick.bind(this)\n\n this.renderSelfVideoButton = null\n this.videoButton = null\n this.link = null\n this.videoHTMLEle = null\n this.buttonCta = null\n this.videoPopinElement = null\n }\n\n connectedCallback() {\n this.props = createProps(this.attributes)\n this.hasSelfHostedVideo = !!this.props.layout?.background_video?.desktop\n this.classes = this.createClasses()\n this.render()\n this.countdownRerender()\n }\n\n createClasses() {\n const { padding_top, padding_bottom } = this.props.layout\n const base = 'nb-hero-banner'\n\n const fullHeight =\n this.props.layout.background_video?.fullHeight === 'true' ||\n this.props.layout.background_video?.fullHeight === true\n ? 'fullHeight'\n : ''\n\n return {\n base,\n videoCta: base + '__video',\n videoCtaIcon: base + '__videoIcon',\n hasSelfHostedVideo: this.hasSelfHostedVideo\n ? base + '__selfHostedVideo' + ' ' + fullHeight\n : '',\n container: [base, padding_top, padding_bottom].join(' ')\n }\n }\n\n getContrast() {\n let { contrast, contrast_mobile, contrastMobile = null } = this.props.layout\n\n // Retro compatibility\n if (contrastMobile) {\n contrast_mobile = contrastMobile\n }\n\n if (viewportHelper.is.mobile && contrast_mobile !== '') {\n // manages responsive contrast at the custom element level\n this.setAttribute('contrast', contrast_mobile)\n }\n\n return viewportHelper.is.mobile && contrast_mobile !== '' ? contrast_mobile : contrast\n }\n\n getTextAlignment() {\n let { textAlign = null } = this.props.layout\n\n if ((viewportHelper.is.desktop || viewportHelper.is.retina) && textAlign !== '') {\n return textAlign\n }\n }\n\n getColor() {\n let result = 'black'\n\n if (this.getContrast() === CONTRAST_DARK) {\n result = 'white'\n }\n\n return result\n }\n\n render() {\n const { layout, campaign, copywriting } = this.props\n const {\n background_color,\n background = {\n retina: '',\n desktop: '',\n mobile: ''\n }\n } = layout\n const { video = {}, text_countdown = {} } = copywriting\n this.descCountdown = !!text_countdown?.date\n this.hasVideo = !!(video.video_id && video.video_service)\n\n let renderSelfVideoMobile = ''\n let renderSelfVideoDesktop = ''\n const backgroundRetina = background.retina || ''\n const backgroundDesktop = background.desktop || ''\n const backgroundMobile = background.mobile || ''\n\n if (this.hasSelfHostedVideo) {\n if (viewportHelper.is.mobile) {\n renderSelfVideoMobile = this.renderSelfVideoBackground()\n } else {\n renderSelfVideoDesktop = this.renderSelfVideoBackground()\n }\n }\n\n this.innerHTML = `\n <nb-container\n background_color=\"${background_color}\"\n background_retina=\"${backgroundRetina}\"\n background_desktop=\"${backgroundDesktop}\"\n background_mobile=\"${backgroundMobile}\"\n campaign_id=\"${campaign.id}\"\n campaign_name=\"${campaign.name}\"\n campaign_position=\"${campaign.position}\"\n campaign_creative=\"${campaign.creative}\"\n contrast=\"${this.getContrast()}\"\n classname=\"${this.classes.container} ${this.classes.hasSelfHostedVideo}\"\n lazy_load=\"false\"\n\n >\n <div class=\"${\n this.classes.base\n }__centerContainer\" text-align=\"${this.getTextAlignment()}\">\n <div class=\"${this.classes.base}__content\">\n <div class=\"${this.classes.base}__content__top\">\n ${this.renderTitle()}\n ${this.renderImage()}\n ${this.renderDescription()}\n </div>\n ${renderSelfVideoMobile}\n <div class=\"${this.classes.base}__content__bottom\">\n <div class=\"${this.classes.base}__ctasWrapper\">\n ${this.renderCta()}\n ${this.renderCtaSecondary()}\n </div>\n ${this.renderVideoCta()}\n ${this.renderLink()}\n ${this.renderVideoBackground()}\n </div>\n </div>\n </div>\n ${renderSelfVideoDesktop}\n </nb-container>\n `\n\n this.bindEvents()\n }\n\n renderPlayer() {\n if (!this.hasVideo) {\n return ''\n }\n\n const {\n video_id,\n video_mobile = '',\n display_ui_controls,\n cc_policy_language,\n video_service\n } = this.props.copywriting.video\n\n this.videoPopinElement = document.createElement('nb-popin')\n\n setAttributes(this.videoPopinElement, {\n id: this.popinId,\n popin_id: this.popinId,\n variation: 'before',\n bgcolor: 'white'\n })\n\n this.videoElement = document.createElement('nb-video')\n setAttributes(this.videoElement, {\n container_id: 'player-' + this.popinId,\n video_id: video_id,\n video_mobile: video_mobile,\n video_service: video_service,\n popin_id: this.popinId,\n display_controls: display_ui_controls,\n ccPolicy_language: cc_policy_language,\n allow_popin_autoplay: 'true'\n })\n this.videoPopinElement.appendChild(this.videoElement)\n this.appendChild(this.videoPopinElement)\n }\n renderSelfVideoBackground() {\n if (!this.hasSelfHostedVideo || !this.props.layout.background_video) {\n return ''\n }\n\n const { labelPause, labelPlay, mobilePoster, desktopPoster, mobile, desktop } =\n this.props.layout.background_video\n\n const video_url = viewportHelper.is.mobile ? mobile : desktop\n const video_poster_url = viewportHelper.is.mobile ? mobilePoster : desktopPoster\n const styleInline = viewportHelper.is.mobile ? 'position: relative' : ''\n\n return `\n <div class=\"video__container\" style=\"${styleInline}\">\n <div class=\"video__controls__container\">\n <video id=\"video_selfHosted\" class=\"${this.classes.base}__visual\" preload=\"metadata\" poster=\"${video_poster_url}\" playsinline autoplay muted loop>\n <source src=\"${video_url}\" type=\"video/mp4\">\n </video>\n <button id=\"video__play__centerButton\" class=\"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\" alt=\"${labelPlay}\"></nb-icon>\n <nb-icon icon=\"24/symbol/pause-solid\" class=\"pauseButton\" alt=\"${labelPause}\"></nb-icon>\n <p class=\"sr-only video_button\">${labelPause}</p>\n </span>\n </button>\n </div>\n </div>`\n }\n\n renderVideoBackground() {\n const { video } = this.props.copywriting\n\n if (!this.hasVideo || viewportHelper.is.mobile || !video.auto_play) {\n return ''\n }\n\n this.props.copywriting.video.mute = true\n this.createVideoElement()\n\n return this.videoElement.outerHTML\n }\n\n createVideoElement() {\n this.videoElement = document.createElement('nb-video')\n setAttributes(this.videoElement, {\n ...this.props.copywriting.video,\n container_id: `player-${this.popinId}`,\n popin_id: this.popinId,\n allow_popin_autoplay: 'true'\n })\n }\n\n countdownRerender() {\n if (!this.headingCountdown && !this.descCountdown) {\n return ''\n }\n\n const eleCountdown = this.querySelector('nb-countdown')\n if (!eleCountdown) {\n return ''\n }\n\n this.countdownEnded = eleCountdown.getAttribute('countdown-end') === 'true'\n if (this.countdownEnded) {\n this.render()\n }\n }\n\n renderTitle() {\n const {\n overline,\n heading,\n heading_countdown = {},\n image_logo,\n image_logo_max_width,\n image_logo_alt\n } = this.props.copywriting\n this.headingCountdown = !!heading_countdown?.date\n\n this.overLineRender = ''\n if (overline) {\n this.overLineRender = `<h1 class=\"t-md-700-sl ${this.classes.base}__overline\">${overline}</h1>`\n }\n\n this.imageLogoRender = ''\n if (image_logo) {\n let imageMaxWidth = ''\n if (image_logo_max_width) {\n imageMaxWidth = `style=\"max-width:${image_logo_max_width}\"`\n }\n\n this.imageLogoRender = `<div class=${this.classes.base}__imageLogo>\n <img class=${this.classes.base}__imageLogoAsset\n src=${image_logo}\n alt=${image_logo_alt}\n fetchpriority=\"high\"\n ${imageMaxWidth} />\n </div>`\n }\n\n this.headingRender = ''\n\n if (heading) {\n const headingCountdown = this.countdownEnded\n ? heading_countdown.heading\n : heading + this.renderCountdown(heading_countdown)\n\n this.headingRender = `<h2 class='${\n this.hasSelfHostedVideo ? 'h-2xl-700' : 'h-3xl-700'\n } ${this.classes.base}__title'>${\n this.headingCountdown ? headingCountdown : heading\n }</h2>`\n }\n\n return `\n ${this.overLineRender}\n ${this.imageLogoRender}\n ${this.headingRender}\n `\n }\n\n renderImage() {\n if (!this.props.copywriting.image || !viewportHelper.is.mobile) {\n return ''\n }\n\n const { copywriting } = this.props\n const { image, image_alt } = copywriting\n\n const className = `${this.classes.base}__imageCenteredMobile`\n const classNameImg = `${this.classes.base}__image`\n\n return `<div class=\"${className}\">\n <img class=\"${classNameImg}\" src=${image} alt=\"${image_alt}\" fetchpriority=\"high\" />\n ${this.hasVideo ? this.renderVideoCtaIcon() : ''}\n </div>`\n }\n\n renderDescription() {\n const { copywriting } = this.props\n const { text = '', text_countdown = {} } = copywriting\n\n if (!text) {\n return ''\n }\n\n const headingCountdown = this.countdownEnded\n ? text_countdown.text\n : `${text} ${this.renderCountdown(text_countdown)}`\n\n return `<div class='t-md-400-sl ${this.classes.base}__text'>${\n this.descCountdown ? headingCountdown : text\n }</div>`\n }\n\n renderCountdown(countdown) {\n const { date, time, locale } = countdown\n\n return `<nb-countdown date=\"${date}\" time=\"${time}\" locale=${JSON.stringify(\n locale\n )}></nb-countdown>`\n }\n\n renderVideoCta() {\n const { cta = {} } = this.props.copywriting\n const { label = '' } = cta\n\n if (!this.hasVideo || label === '') {\n return ''\n }\n\n const ctaVideoClass = this.classes.videoCta\n const data = stringifyForAttribute(cta)\n\n return `<nb-cta\n icon_right=\"24/symbol/play-solid\"\n class=\"${this.classes.base}__cta ${ctaVideoClass}\"\n data=\"${data}\"\n >${label}</nb-cta>`\n }\n\n renderVideoCtaIcon() {\n const { cta = {} } = this.props.copywriting\n const { label = '' } = cta\n\n if (!this.hasVideo || label === '') {\n return ''\n }\n\n const ctaVideoClass = this.classes.videoCtaIcon\n const data = stringifyForAttribute(cta)\n\n return `<nb-cta\n icon_right=\"24/symbol/play-solid\"\n class=\"${this.classes.base}__videoIcon ${ctaVideoClass}\"\n data=\"${data}\"\n tracking_label=\"Page Builder - Hero Banner - Click CTA - Play video\"\n ></nb-cta>`\n }\n\n renderCta() {\n const { campaign, copywriting } = this.props\n const { cta = {}, heading_countdown = {}, text_countdown = {} } = copywriting\n const { label = '' } = cta\n\n if (this.hasVideo || label === '') {\n return ''\n }\n\n if (this.countdownEnded) {\n if (this.descCountdown) {\n cta.link = text_countdown.cta_link\n } else if (this.headingCountdown) {\n cta.link = heading_countdown.cta_link\n }\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 `<nb-cta class=\"${this.classes.base}__cta\" data=\"${data}\">${label}</nb-cta>`\n }\n\n renderCtaSecondary() {\n const { campaign, copywriting } = this.props\n const { cta_secondary = {} } = copywriting\n const { label = '' } = cta_secondary\n\n if (label === '') {\n return ''\n }\n\n cta_secondary.campaign_id = campaign.id || ''\n cta_secondary.campaign_name = campaign.name || ''\n cta_secondary.campaign_position = campaign.position || ''\n cta_secondary.campaign_creative = campaign.creative || ''\n\n const data = stringifyForAttribute(cta_secondary)\n\n return `<nb-cta class=\"${this.classes.base}__ctaSecondary\" data=\"${data}\">${label}</nb-cta>`\n }\n\n renderLink() {\n const { campaign = {}, copywriting: { popin = {} } = {} } = this.props\n const { id = '', text = '' } = popin\n\n if (!text) {\n return ''\n }\n\n return `\n <nb-link\n campaign_id=\"${campaign.id || ''}\"\n campaign_name=\"${campaign.name || ''}\"\n campaign_position=\"${campaign.position || ''}\"\n campaign_creative=\"${campaign.creative || ''}\"\n size=\"xsmall\"\n color=\"${this.getColor()}\"\n popin_id=\"${id}\"\n class=\"${this.classes.base}__link\"\n >${text}</nb-link>\n `\n }\n\n onOpenPlayer() {\n if (!this.videoPopinElement) {\n this.renderPlayer()\n }\n dispatchEvent({ eventName: EVENT_POPIN_OPEN, args: { id: this.popinId } })\n }\n\n renderPopin() {\n const { copywriting: { popin = {} } = {} } = this.props\n const {\n id = '',\n image = '',\n heading = '',\n description = '',\n image_alt = '',\n close = ''\n } = popin\n\n if (!id) {\n return ''\n }\n\n return `<nb-popin\n id=\"${id}\"\n heading=\"${heading}\"\n variation=\"next\"\n bgcolor=\"highlight\"\n image=\"${image}\"\n image_alt=\"${image_alt}\"\n label_close=\"${close}\">\n ${description}\n </nb-popin>`\n }\n\n onLinkClick() {\n const { copywriting: { popin: { id } } = {} } = this.props\n\n // Just the first time, we need to build the DOM and trigger the event, after it's all standard\n const fragment = document.createElement('div')\n fragment.innerHTML = this.renderPopin()\n\n const container = this.querySelector('nb-container')\n if (container) {\n container.appendChild(fragment)\n }\n\n dispatchEvent({ eventName: EVENT_POPIN_OPEN, args: { id } })\n\n if (this.link) {\n this.link.removeEventListener('click', this.boundOnLinkClick)\n }\n }\n\n disconnectedCallback() {\n this.unbindEvents()\n }\n\n bindEvents() {\n this.videoButton = this.querySelector(`.${this.classes.videoCta}`)\n if (this.videoButton) {\n this.videoButton.addEventListener('click', this.boundOnOpenPlayer)\n }\n\n this.videoCtaButton = this.querySelector(`.${this.classes.videoCtaIcon}`)\n if (this.videoCtaButton) {\n this.videoCtaButton.addEventListener('click', this.boundOnOpenPlayer)\n }\n\n this.link = this.querySelector(`nb-link`)\n if (this.link) {\n this.link.addEventListener('click', this.boundOnLinkClick)\n }\n\n this.videoHTMLEle = this.querySelector(`.${this.classes.videoCta}`)\n if (this.videoHTMLEle) {\n this.videoHTMLEle.addEventListener('click', this.boundhandlePromoClick)\n }\n\n this.buttonCta = this.querySelector('.nb-hero-banner__cta')\n if (this.buttonCta) {\n this.buttonCta.addEventListener('click', this.boundOnButtonCtaClick)\n }\n\n this.renderSelfVideoButton = this.querySelector('#video__play__centerButton')\n if (this.renderSelfVideoButton) {\n this.renderSelfVideoButton.addEventListener('click', this.boundOnButtonSelfVideoClick)\n }\n }\n\n boundOnButtonSelfVideoClick(e) {\n const targetElement = e.target || e.srcElement\n const video = document.getElementById('video_selfHosted')\n const videoControlText = document.querySelector('.sr-only.video_button')\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 videoControlText.innerText = 'Play'\n } else {\n video.play()\n targetElement.dataset.status = 'pause'\n targetElement.classList.remove('icon-play')\n targetElement.classList.add('icon-pause')\n videoControlText.innerText = 'Pause'\n }\n }\n\n onButtonCtaClick() {\n const cta = this.props.copywriting.cta\n if (cta.disabled) return\n dispatchEvent({ eventName: EVENT_CTA_CLICK })\n }\n\n unbindEvents() {\n if (this.videoButton) {\n this.videoButton.removeEventListener('click', this.boundOnOpenPlayer)\n }\n\n if (this.link) {\n this.link.removeEventListener('click', this.boundOnLinkClick)\n }\n\n if (this.videoHTMLEle) {\n this.videoHTMLEle.removeEventListener('click', this.boundhandlePromoClick)\n }\n\n if (this.buttonCta) {\n this.buttonCta.removeEventListener('click', this.boundOnButtonCtaClick)\n }\n\n if (this.renderSelfVideoButton) {\n this.renderSelfVideoButton.removeEventListener(\n 'click',\n this.boundOnButtonSelfVideoClick\n )\n }\n }\n\n handleClick() {\n const { campaign } = this.props\n if (!campaign.id) {\n return ''\n }\n\n let ctaOrPopin = this.props.copywriting.popin ? 'POPIN' : 'CTA'\n\n handlePromoClick({\n campaign,\n cta_name: `${ctaOrPopin} - ${this.props.copywriting.cta.label}`\n })\n }\n}\n\ncustomElements.get('nb-hero-banner') || customElements.define('nb-hero-banner', HeroBanner)\n\nexport default HeroBanner\n"],"names":["removeEmptyValues","obj","findText","key","value","text","includes","stringifyForAttribute","data","escapeHtml","JSON","stringify","map","replace","m","DOMParser","setAttributes","element","attrs","setAttribute","createProps","attributes","find","attribute","nodeName","getData","props","filter","reduce","all","attr","nodeValue","isNil","parse","error","console","log","dispatchEvent","eventName","args","window","Error","event","CustomEvent","detail","bubbles","Event","document","createEvent","initEvent","readEvent","e","BREAKPOINT_TABLET","EVENT_VIDEO","EVENT_POPIN_OPEN","EVENT_POPIN_OPENED","EVENT_POPIN_CLOSE","EVENT_POPIN_CLOSED","EVENT_POPIN_KEY_DOWN","EVENT_VIDEO_TOGGLE","VIDEO_ON_HOVER","VIDEO_ON_OUT","EVENT_SWIPED_DOWN","helper","is","innerWidth","vw","devicePixelRatio","mobile","mobile_tablet","tablet","desktop","retina","lt","ref","selectPromotion","eventData","cta_name","event_raised_by","ecommerce","Object","keys","length","id","creative","name","position","ecommerceData","promotion_id","promotion_name","creative_slot","creative_name","gtmDataObject","push","emitCustomEvent","customEvent","cancelable","composed","Counter","HTMLElement","constructor","super","this","intervalM","connectedCallback","render","date","time","locale","cleanLocale","countDownDate","Date","getTime","checkDifference","setEndAttribute","reRenderTime","setInterval","renderTime","val","normalizeTime","operation","Math","floor","slice","difference","days","hours","minutes","seconds","innerHTML","clearInterval","disconnectedCallback","customElements","get","define","swipeEvents","stopEl","nwcSwipeEvents","addEventListener","target","getAttribute","el","undefined","contains","scrollTopArray","scrollLeftArray","scrollTop","scrollLeft","parentNode","memorizeStartElScrollPositions","startEl","timeDown","now","touches","clientX","clientY","xDiff","yDiff","xDown","yDown","xUp","yUp","defaultVertical","innerHeight","defaultHorizontal","swipeThresholdVertical","getNearestAttribute","swipeThresholdHorizontal","swipeTimeout","timeDiff","eventType","changedTouches","abs","checkScrollCondition","dir","touchType","xStart","xEnd","yStart","yEnd","direction","result","i","isScrollable","scrollHeight","clientHeight","scrollWidth","clientWidth","attributeName","defaultValue","documentElement","attributeValue","String","parseInt","recursiveSwitchAriaHidden","elem","componentOpenState","parent","getElementsByTagName","brothers","children","brother","removeAttribute","Overlay","popin_id","overlay","createElement","classList","add","body","appendChild","setTimeout","close","getElementsByClassName","remove","STATE_OPEN","SCROLL_LOCK","Popin","ariaModal","isVideo","boundOpen","open","bind","boundClose","boundEscapeClose","escapeClose","boundFocus","focus","boundFocusin","focusin","style","display","content","slot","attributeChangedCallback","oldValue","newValue","observedAttributes","hasEvent","unbindEvent","heading","subheading","bgcolor","size","label_close","image","image_alt","variation","heading_class","viewportHelper","heading_id","bindEvent","isOpen","checkIsVideo","renderFooter","focusable","querySelectorAll","firstFocusable","lastFocusable","lastFocused","setFirstAndLastFocusable","buttonElement","querySelector","footer","parseBool","tempEl","tagName","addLock","removeLock","closest","switchAriaModal","openingSource","activeElement","Promise","resolve","cancelBubble","stopPropagation","removeEventListener","openVideoPopin","loop","swipeDown","swipeOverlayTogglePlayPause","boundSwipeDown","swipeOverlay","boundSwipeOverlayTogglePlayPause","VIDEO_SERVICE_YOUTUBE","VIDEO_SERVICE_LOCAL","getScript","source","asyncLoad","defer","reject","script","prior","async","src","insertBefore","Deferred","promise","getMarketCode","dataLayer","padlNamespace","app","market","toLocaleLowerCase","PlayerYoutube","iframeApi","deferred","YT","Player","onYouTubeIframeAPIReady","then","ready","initYouTubeIframeAPI","attach","iframeContainer","videoId","isBackgroundVideoPlaying","isAutoPlay","moreParams","params","playlist","controls","player","host","playerVars","enablejsapi","rel","fs","autoplay","events","onReady","mute","onStateChange","onError","outerWidth","getComputedStyle","width","getPropertyValue","marginLeft","marginRight","outerHeight","height","marginTop","marginBottom","PlayerYouku","iframeContainerId","container","getElementById","YKU","styleid","client_id","vid","newPlayer","show_related","onPlayerReady","onPlayStart","onPlay","onPlayEnd","onPause","onWaiting","onFullScreen","onPlayError","YoutubeOverlay","video_id","backgroundImage","Video","__privateAdd","_percentThresholds","_lastTrackedThreshold","_progressInterval","_eventCategory","videoMobile","currentVideo","videoService","containerId","ccPolicyLanguage","ccPolicyCountry","ccLoadPolicy","displayControls","disabledKeyboard","isBackground","autoPlay","playOnHover","allowPopinAutoplay","isPlaying","play","pause","stop","moveTo","loadInterupted","controlsReady","overlayElement","_externalControl","video_mobile","container_id","video_service","auto_play","getAttributes","init","popinId","setPopinEvents","setHoverEvents","initLocal","initServiceVideo","boundExternalControl","initYouku","initYoutubeOverlay","boundOnPopinClosed","onPopinClosed","boundOnPopinOpened","onPopinOpened","boundOnTogglePlayback","onTogglePlayback","boundOnHover","onHover","boundOnOut","onOut","popinValid","initYoutube","self","_YkPlayer","playVideo","pauseVideo","msg","stateParam","finally","_YtPlayer","additionalParams","color","disablekb","assign","cc_load_policy","cc_lang_pref","unMute","stopVideo","seekTo","onYoutubePlayerStateChange","PlayerState","videoTitle","state","PLAYING","eventCategory","__privateGet","eventAction","eventLabel","__privateSet","trackVideoProgress","PAUSED","ENDED","playerInfo","duration","currentTime","percentWatched","threshold","video","renderVideo","action","WeakMap","HeroBanner","isMobile","characters","charAt","random","makeId","hasVideo","hasSelfHostedVideo","headingCountdown","descCountdown","countdownEnded","boundOnLinkClick","onLinkClick","boundOnOpenPlayer","onOpenPlayer","boundhandlePromoClick","handleClick","boundOnButtonCtaClick","onButtonCtaClick","boundOnButtonSelfVideoClick","renderSelfVideoButton","videoButton","link","videoHTMLEle","buttonCta","videoPopinElement","layout","background_video","classes","createClasses","countdownRerender","padding_top","padding_bottom","base","fullHeight","videoCta","videoCtaIcon","join","getContrast","contrast","contrast_mobile","contrastMobile","getTextAlignment","textAlign","getColor","campaign","copywriting","background_color","background","text_countdown","renderSelfVideoMobile","renderSelfVideoDesktop","backgroundRetina","backgroundDesktop","backgroundMobile","renderSelfVideoBackground","renderTitle","renderImage","renderDescription","renderCta","renderCtaSecondary","renderVideoCta","renderLink","renderVideoBackground","bindEvents","renderPlayer","display_ui_controls","cc_policy_language","videoElement","display_controls","ccPolicy_language","allow_popin_autoplay","labelPause","labelPlay","mobilePoster","desktopPoster","video_url","video_poster_url","createVideoElement","outerHTML","eleCountdown","overline","heading_countdown","image_logo","image_logo_max_width","image_logo_alt","overLineRender","imageLogoRender","imageMaxWidth","headingRender","renderCountdown","renderVideoCtaIcon","countdown","cta","label","ctaVideoClass","cta_link","campaign_id","campaign_name","campaign_position","campaign_creative","cta_secondary","popin","renderPopin","description","fragment","unbindEvents","videoCtaButton","targetElement","srcElement","videoControlText","dataset","status","innerText","disabled","cleanedData","handlePromoClick"],"mappings":"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"}