{"version":3,"file":"index.es.min.js","sources":["../../../packages/helpers/src/props.helpers.js","../../../packages/components/src/card-labels/cardLabels.js","../../../packages/helpers/src/dataLayer.js","../../../packages/helpers/src/cremaDataHelper.js","../../../packages/components/src/card-logos/cardLogos.js","../../../packages/components/src/energy-label/energyLabel.js","../../../packages/components/src/intensity/intensity.js","../../../packages/helpers/src/utils.ts","../../../packages/components/src/constants.mjs","../../../packages/helpers/src/viewport.helpers.ts","../../../packages/helpers/src/assets/js/eventDispatch.js","../../../packages/components/src/plp-product-card/fragments/bundle.js","../../../packages/helpers/src/colors.helpers.js","../../../packages/components/src/plp-product-card/fragments/features.js","../../../packages/components/src/plp-product-card/fragments/lazyLoad.js","../../../packages/components/src/plp-product-card/fragments/price.js","../../../packages/helpers/src/getCurrency.js","../../../packages/helpers/src/catalog.js","../../../packages/components/src/plp-product-card/fragments/renderStrikethroughPrice.js","../../../packages/components/src/plp-product-card/fragments/sleeve.js","../../../packages/components/src/plp-product-card/fragments/priceWrapper.js","../../../packages/components/src/plp-product-card/fragments/priceCapsule.js","../../../packages/components/src/plp-product-card/fragments/priceA11y.js","../../../packages/components/src/plp-product-card/fragments/outOfStock.js","../../../packages/components/src/plp-product-card/fragments/addToCart.js","../../../packages/components/src/plp-product-card/fragments/ratings.js","../../../packages/components/src/slider/js/constants.js","../../../packages/components/src/slider/js/CarouselTouchPlugin.js","../../../packages/components/src/slider/js/CarouselCreamUiHack.js","../../../packages/components/src/slider/js/Carousel.js","../../../packages/helpers/src/events.helpers.ts","../../../packages/helpers/src/gtmEvents.js","../../../packages/components/src/slider/slider.js","../../../packages/components/src/plp-product-card/components/plp-product-card-image-slider.js","../../../packages/components/src/plp-product-card/fragments/header.js","../../../packages/components/src/sku/constants.mjs","../../../packages/components/src/plp-product-card/fragments/image.js","../../../packages/components/src/plp-product-card/fragments/slider.js","../../../packages/components/src/plp-product-card/fragments/subscription.js","../../../packages/components/src/colors/components/color/constants.mjs","../../../packages/components/src/sku/services/index.js","../../../packages/components/src/plp-product-card/plp-product-card.js","../../../packages/components/src/plp-product-card/fragments/labelTechnology.js","../../../packages/components/src/plp-product-card/fragments/labels.js","../../../packages/helpers/src/logos.helpers.js","../../../packages/helpers/src/energy-label.helpers.js","../../../packages/components/src/plp-product-card/fragments/labelRange.js","../../../packages/components/src/plp-product-card/fragments/heading.js","../../../packages/components/src/plp-product-card/fragments/headline.js","../../../packages/helpers/src/intensity.helpers.js","../../../packages/components/src/plp-product-card/fragments/additionalMessage.js","../../../packages/components/src/plp-product-card/fragments/setCardTheme.js","../../../packages/page-builder-sections/src/product-grid/components/plp-category/plp-category.js","../../../packages/helpers/src/assets/js/viewportTracking.js","../../../packages/helpers/src/assets/js/zoneTracking.js","../../../packages/components/src/sku-coffee/services/index.js","../../../packages/page-builder-sections/src/product-grid/dataTransform/product.coffee.dto.js","../../../services/plp/services.js","../../../packages/page-builder-sections/src/product-grid/dataTransform/product.machine.dto.js","../../../packages/page-builder-sections/src/product-grid/dataTransform/product.dto.js","../../../packages/page-builder-sections/src/product-grid/dataTransform/product.accessory.dto.js","../../../packages/page-builder-sections/src/product-grid/dataTransform/product.giftCard.dto.js","../../../services/pdp-data/src/prod/index.js","../../../packages/page-builder-sections/src/product-grid/product-grid.js"],"sourcesContent":["const getData = attributes => attributes.find(attribute => attribute.nodeName === 'data')\n\nconst createProps = attributes => {\n const data = getData([...attributes])\n const props = [...attributes]\n .filter(attribute => attribute.nodeName !== 'data')\n .reduce((all, attr) => {\n return { ...all, [attr.nodeName]: attr.nodeValue }\n }, {})\n\n if (isNil(data)) {\n return props\n }\n\n try {\n return { ...props, ...JSON.parse(data.nodeValue) }\n } catch (error) {\n console.log('ERROR: No data', error, data?.nodeValue)\n }\n}\n\nconst isNil = obj => obj === undefined || obj === null\n\nexport const parseBool = value => (!value || value === 'false' ? false : true)\n\nexport default createProps\n","import createProps from '@kissui/helpers/src/props.helpers'\n\nclass CardLabels extends HTMLElement {\n constructor() {\n super()\n this.props = {}\n this.labels = []\n }\n\n connectedCallback() {\n this.props = createProps(this.attributes)\n this.render()\n }\n\n render() {\n const { labels = [], direction = 'column' } = this.props\n this.classList.add(`${direction === 'row' ? 'direction-row' : 'direction-' + direction}`)\n\n if (labels.length === 0) {\n return ''\n }\n this.labels = labels\n\n this.innerHTML = `${this.renderLabels()}`\n }\n\n renderLabels() {\n return this.labels\n .map(label => {\n const { name = '', bgColor = '', color = '' } = label\n return `<mark class=\"t-3xs-500-caps-sl\"\n ${\n bgColor &&\n color &&\n `style=\"background: ${bgColor}; color: ${color}\"`\n }>\n <span>${name}</span>\n </mark>`\n })\n .join('')\n }\n}\n\ncustomElements.get('nb-card-labels') || customElements.define('nb-card-labels', CardLabels)\n\nexport default CardLabels\n","export const getDataLayer = () => {\n return window[window?.padlNamespace]?.dataLayer\n}\n\nexport const getMarketCode = () => {\n const dataLayer = getDataLayer()\n if (!dataLayer) {\n return 'ch'\n }\n\n return dataLayer.app.app.market.toLocaleLowerCase()\n}\n\nexport const getLangCode = () => {\n const dataLayer = getDataLayer()\n if (!dataLayer) {\n return 'en'\n }\n\n return getDataLayer().page.page.pageInfo.language.toLocaleLowerCase()\n}\n\nexport const getSegmentCode = () => {\n const dataLayer = getDataLayer()\n if (!dataLayer) {\n return 'B2C'\n }\n\n return getDataLayer().page.page.pageInfo.segmentBusiness\n}\n\nexport const isLoggedIn = () => {\n const dataLayer = getDataLayer()\n if (!dataLayer || !dataLayer.user) {\n return false\n }\n\n return dataLayer.user.isLoggedIn\n}\n\nexport const interpolateMarketLang = (string, market, lang) => {\n return string.replace('{market}', market).replace('{lang}', lang)\n}\n","import { getMarketCode } from './dataLayer'\n\nconst LABEL_CATEGORY_NAME = 'cat/capsule-range-label'\nconst LABEL_CATEGORY_NAME_MACHINE = 'cat/machine-range-label'\nexport const RANGE_CATEGORY_NAME = 'cat/capsule-range'\nconst FAIR_TRADE_CATEGORY_NAME = 'cat/capsule-range-fair-trade'\nconst VERTUO_NEXT_CATEGORY_NAME = 'cat/capsule-attribute-only-vertuo-next'\nconst ORGANIC_EU_CATEGORY_NAME = 'capsule-attribute-organic-eu'\nconst RAINFOREST_CATEGORY_NAME = 'capsule-attribute-rainforest'\nconst SUSTAINABILITY_CATEGORY_NAME = 'capsule-attribute-sustainability'\nconst ARABICA_CATEGORY_NAME = 'capsule-attribute-arabica'\nconst PRODUCT_HIGHLIGHT_CATEGORY_NAME = 'cat/capsule-attribute-highlight'\nconst TECHNOLOGY_CATEGORY_IDENTIFIER = '/machineTechno/'\n\nconst COMMON_URL = 'https://www.nespresso.com/shared_res/agility/commons/img/icons/'\n\nexport const FAIR_TRADE_IMG = COMMON_URL + 'fairTrade.svg'\nexport const ORGANIC_LOGO_IMG_EU = COMMON_URL + 'logo-organic-eu.svg'\nexport const ORGANIC_LOGO_IMG_US = COMMON_URL + 'logo-organic-us.svg'\nexport const ORGANIC_LOGO_IMG_CA = COMMON_URL + 'logo-organic-ca.svg'\nexport const ORGANIC_LOGO_IMG_BR = COMMON_URL + 'logo-organic-br.svg'\nexport const ORGANIC_LOGO_IMG_JP = COMMON_URL + 'logo-organic-jp.svg'\nexport const ORGANIC_LOGO_IMG_BE = COMMON_URL + 'logo-organic-be.png'\n\nexport const VERTUONEXT_LOGO_IMG = COMMON_URL + 'logo-only-vertuo-next.svg'\nexport const RAINFOREST_LOGO_IMG = COMMON_URL + 'logo-rainforest.svg'\nexport const SUSTAINABILITY_LOGO_IMG = COMMON_URL + 'logo-sustainability.svg'\nexport const Q_CERTIFICATION_ARABICA_LOGO_IMG = COMMON_URL + 'q_grade_certification_arabica.svg'\nexport const DESIGN_AWARD_2021_IMG = COMMON_URL + 'design_award_2021.svg'\n\nexport const LOGO_IMG_MAP = {\n fair_trade: FAIR_TRADE_IMG,\n is_organic: getOrganicLogo(),\n only_vertuo_next: VERTUONEXT_LOGO_IMG,\n is_q_certified_arabica: Q_CERTIFICATION_ARABICA_LOGO_IMG,\n is_rainforest: RAINFOREST_LOGO_IMG,\n is_sustainable: SUSTAINABILITY_LOGO_IMG,\n is_design_award_2021: DESIGN_AWARD_2021_IMG\n}\n\nexport function getOrganicLogo() {\n let organicLogoImg = ORGANIC_LOGO_IMG_EU\n\n switch (getMarketCode()) {\n case 'us':\n organicLogoImg = ORGANIC_LOGO_IMG_US\n break\n case 'ca':\n organicLogoImg = ORGANIC_LOGO_IMG_CA\n break\n case 'br':\n organicLogoImg = ORGANIC_LOGO_IMG_BR\n break\n case 'jp':\n organicLogoImg = ORGANIC_LOGO_IMG_JP\n break\n case 'be':\n organicLogoImg = ORGANIC_LOGO_IMG_BE\n break\n }\n\n return organicLogoImg\n}\n\n/**\n * retrieves the list of categories of type Vertuo Next\n * @param {category[]} categories\n */\nexport function getVertuoNext(categories) {\n return categories.find(category => isVertuoNext(category))\n}\n\n/**\n * returns true when the category is product vertuo next\n * @param {category} category\n */\nfunction isVertuoNext(category) {\n return getCategoryRegEx(VERTUO_NEXT_CATEGORY_NAME).test(category.id)\n}\n\n/**\n * retrieves the list of categories of type organic EU\n * @param {category[]} categories\n */\nexport function getOrganicEu(categories) {\n return categories.find(category => isOrganicEu(category))\n}\n\n/**\n * returns true when the category is product organic EU\n * @param {category} category\n */\nfunction isOrganicEu(category) {\n return getCategoryRegEx(ORGANIC_EU_CATEGORY_NAME).test(category.id)\n}\n\n/**\n * retrieves the list of categories of type rainforest\n * @param {category[]} categories\n */\nexport function getRainforest(categories) {\n return categories.find(category => isRainforest(category))\n}\n\n/**\n * returns true when the category is rainforest\n * @param {category} category\n */\nfunction isRainforest(category) {\n return getCategoryRegEx(RAINFOREST_CATEGORY_NAME).test(category.id)\n}\n\n/**\n * retrieves the list of categories of type sustainability\n * @param {category[]} categories\n */\nexport function getSustainability(categories) {\n return categories.find(category => isSustainability(category))\n}\n\n/**\n * retrieves the list of categories of type arabica\n * @param {category[]} categories\n */\nexport function getArabica(categories) {\n return categories.find(category => isArabica(category))\n}\n\n/**\n * returns true when the category is arabica\n * @param {category} category\n */\nfunction isArabica(category) {\n return getCategoryRegEx(ARABICA_CATEGORY_NAME).test(category.id)\n}\n\n/**\n * returns true when the category is sustainability\n * @param {category} category\n */\nfunction isSustainability(category) {\n return getCategoryRegEx(SUSTAINABILITY_CATEGORY_NAME).test(category.id)\n}\n\n/**\n * retrieves the list of categories of type label\n * @param {category[]} categories\n */\nexport function getLabels(categories) {\n return categories.filter(category => isLabel(category))\n}\n\n/**\n * retrieves the list of categories of type label\n * @param {category[]} categories\n */\nexport function getProductHighlight(categories) {\n return categories.find(category => isProductHighlight(category))\n}\n/**\n * retrieves the list of categories of type label\n * @param {category[]} categories\n */\nexport function getFairTrade(categories) {\n return categories.find(category => isFairTrade(category))\n}\n\n/**\n * returns a regex to match the tail (global) of a given local category ID\n * @param {string} categoryIdTail : should contain the end of the category ID\n */\nexport function getCategoryRegEx(categoryIdTail) {\n return new RegExp(categoryIdTail.replace(/\\//g, '\\\\/'))\n}\n\n/**\n * returns true when the category is child of the label category (is type label)\n * @param {category} category\n */\nfunction isLabel(category) {\n return (\n getCategoryRegEx(LABEL_CATEGORY_NAME).test(category.id) ||\n getCategoryRegEx(LABEL_CATEGORY_NAME_MACHINE).test(category.id)\n )\n}\n\n/**\n * returns true when the category is product highlight\n * @param {category} category\n */\nfunction isProductHighlight(category) {\n return getCategoryRegEx(PRODUCT_HIGHLIGHT_CATEGORY_NAME).test(category.id)\n}\n/**\n * returns true when the category is fair trade\n * @param {category} category\n */\nfunction isFairTrade(category) {\n return getCategoryRegEx(FAIR_TRADE_CATEGORY_NAME).test(category.id)\n}\n\n/**\n * returns true when the category is child of the range category (is type range)\n * @param {category} category\n */\nexport function isRange(category) {\n return category.superCategories.some(superCategory =>\n getCategoryRegEx(RANGE_CATEGORY_NAME).test(superCategory)\n )\n}\n\nexport function getTechnologyName(productData, categories) {\n if (!productData || !productData.technologies || !productData.technologies.length) {\n return null\n }\n\n const techno = productData.technologies[0]\n const categoryNameAsSubstring = techno.substring(\n techno.indexOf(TECHNOLOGY_CATEGORY_IDENTIFIER) + TECHNOLOGY_CATEGORY_IDENTIFIER.length\n )\n const category = categories?.find(cat => cat.id === techno)\n\n // Backward compatibility, return name as substring if the list of categories are not available\n return category?.name || categoryNameAsSubstring\n}\n\nexport function isCategoryHidden(categoryId) {\n let hideCategory = false\n // To enable AB testing: exclude categories which are to be hidden\n if (\n window.PLP_HIDE_CATEGORIES?.length &&\n window.PLP_HIDE_CATEGORIES.findIndex(c => categoryId.indexOf(c) >= 0) >= 0\n ) {\n hideCategory = true\n }\n\n // To enable AB testing: exclude categories except those which are to be shown\n if (window.PLP_ONLY_SHOW_CATEGORIES?.length) {\n // Default to hide\n hideCategory = true\n if (window.PLP_ONLY_SHOW_CATEGORIES.findIndex(c => categoryId.indexOf(c) >= 0) >= 0) {\n hideCategory = false\n }\n }\n return hideCategory\n}\n","import { LOGO_IMG_MAP } from '@kissui/helpers/src/cremaDataHelper'\nimport createProps from '@kissui/helpers/src/props.helpers'\n\nclass CardLogos extends HTMLElement {\n constructor() {\n super()\n this.props = {}\n }\n\n connectedCallback() {\n this.props = createProps(this.attributes)\n this.render()\n }\n\n render() {\n // individual props for each logo is there for retro compatibility\n // logos is the prop that we should use going forward to add any logo\n let { direction = 'row', logos } = this.props\n let fair_trade\n let alt_fair_trade\n let is_organic\n let alt_organic\n let only_vertuo_next\n let alt_vertuo_next\n let is_rainforest\n let alt_rainforest\n let is_sustainable\n let alt_sustainable\n let is_q_certified_arabica\n let alt_q_certification_arabica\n\n this.classList.add(\n `${direction === 'column' ? 'direction-column' : 'direction-' + direction}`\n )\n\n let logos_list = []\n if (logos == null) {\n fair_trade = this.props?.fair_trade\n alt_fair_trade = this.props?.alt_fair_trade\n is_organic = this.props?.is_organic\n alt_organic = this.props?.alt_organic\n only_vertuo_next = this.props?.only_vertuo_next\n alt_vertuo_next = this.props?.alt_vertuo_next\n is_rainforest = this.props?.is_rainforest\n alt_rainforest = this.props?.alt_rainforest\n is_sustainable = this.props?.is_sustainable\n alt_sustainable = this.props?.alt_sustainable\n is_q_certified_arabica = this.props?.is_q_certified_arabica\n alt_q_certification_arabica = this.props?.alt_q_certification_arabica\n } else if (logos.length === undefined) {\n // Logos exists but is not an array, this is the old format\n fair_trade = logos?.fair_trade\n alt_fair_trade = logos?.alt_fair_trade\n is_organic = logos?.is_organic\n alt_organic = logos?.alt_organic\n only_vertuo_next = logos?.only_vertuo_next\n alt_vertuo_next = logos?.alt_vertuo_next\n is_rainforest = logos?.is_rainforest\n alt_rainforest = logos?.alt_rainforest\n is_sustainable = logos?.is_sustainable\n alt_sustainable = logos?.alt_sustainable\n is_q_certified_arabica = logos?.is_q_certified_arabica\n alt_q_certification_arabica = logos?.alt_q_certification_arabica\n } else if (logos.length) {\n logos_list = [...logos]\n }\n\n // here we fill logos with logos taken from individual props\n ;[\n [fair_trade, 'fair_trade', alt_fair_trade, logos_list],\n [is_organic, 'is_organic', alt_organic, logos_list],\n [only_vertuo_next, 'only_vertuo_next', alt_vertuo_next, logos_list],\n [is_rainforest, 'is_rainforest', alt_rainforest, logos_list],\n [is_sustainable, 'is_sustainable', alt_sustainable, logos_list],\n [\n is_q_certified_arabica,\n 'is_q_certified_arabica',\n alt_q_certification_arabica,\n logos_list\n ]\n ].forEach(param => this.appendLogo.apply(this, param))\n\n this.innerHTML = logos_list\n .map(logo => `<img src=\"${LOGO_IMG_MAP[logo.name]}\" alt=\"${logo.alt}\" loading=\"lazy\">`)\n .join('')\n }\n\n appendLogo(param, name, alt, list) {\n if (!!param && !this.hasLogo(list, name)) {\n list.push({ name, alt })\n }\n }\n\n hasLogo(logosList, logoName) {\n return logosList.some(logo => logo.name === logoName)\n }\n}\n\ncustomElements.get('nb-card-logos') || customElements.define('nb-card-logos', CardLogos)\n\nexport default CardLogos\n","import createProps from '@kissui/helpers/src/props.helpers'\n\nclass EnergyLabel extends HTMLElement {\n constructor() {\n super()\n this.props = {}\n this.level = ''\n this.levelPlus = ''\n }\n\n connectedCallback() {\n this.props = createProps(this.attributes)\n this.render()\n }\n\n render() {\n const { a11y_label, level } = this.props\n\n if (a11y_label === '' || level === '') {\n return ''\n }\n\n this.classList.add(`level_${level}`)\n\n switch (level) {\n case 'g':\n this.level = 'G'\n break\n case 'f':\n this.level = 'F'\n break\n case 'e':\n this.level = 'E'\n break\n case 'd':\n this.level = 'D'\n break\n case 'c':\n this.level = 'C'\n break\n case 'b':\n this.level = 'B'\n break\n case 'a4':\n this.level = 'A'\n break\n case 'a3':\n this.level = 'A'\n this.levelPlus = '+'\n break\n case 'a2':\n this.level = 'A'\n this.levelPlus = '++'\n break\n default:\n this.level = 'A'\n this.levelPlus = '+++'\n break\n }\n\n this.innerHTML = `\n <mark>\n ${this.level}\n ${this.levelPlus !== '' ? `<sup>${this.levelPlus}</sup>` : ''}\n <span class=\"sr-only\">${a11y_label} ${this.level}${this.levelPlus}</span>\n </mark>\n `\n }\n}\n\ncustomElements.get('nb-energy-label') || customElements.define('nb-energy-label', EnergyLabel)\n\nexport default EnergyLabel\n","import createProps from '@kissui/helpers/src/props.helpers'\n\nclass Intensity extends HTMLElement {\n constructor() {\n super()\n this.props = {}\n }\n\n connectedCallback() {\n this.props = createProps(this.attributes)\n this.render()\n }\n\n render() {\n const { intensity_label = 'Intensity', a11y_intensity_max, max_intensity } = this.props\n const intensity = parseInt(this.props.intensity)\n\n if (!intensity || isNaN(intensity)) {\n return ''\n }\n\n const a11yIntensityMax = a11y_intensity_max?.replace('{max_intensity}', max_intensity)\n\n this.innerHTML = `\n <p>\n <span class=\"sr-only\">${intensity_label} ${intensity} ${a11yIntensityMax}</span>\n <div class=\"t-xs-500-sl\" aria-hidden=\"true\">${intensity_label}</div>\n ${this.renderIntensityMin(intensity)}\n <div class=\"t-xs-700-sl\" aria-hidden=\"true\">${intensity}</div>\n ${this.renderIntensityMax(intensity)}\n </p>\n `\n }\n\n renderIntensityMin(intensity) {\n const min_intensity = 0\n\n return new Array(Math.max(intensity, 0) - min_intensity)\n .fill('<span class=\"bar filled\"></span>')\n .join('')\n }\n\n renderIntensityMax(intensity) {\n let { max_intensity } = this.props\n if (!max_intensity || max_intensity === 'undefined') {\n max_intensity = 14\n }\n\n return new Array(parseInt(max_intensity) - Math.min(intensity, parseInt(max_intensity)))\n .fill('<span class=\"bar\"></span>')\n .join('')\n }\n}\n\ncustomElements.get('nb-intensity') || customElements.define('nb-intensity', Intensity)\n\nexport default Intensity\n","export { waitForSelector } from './waitForSelector'\n\nexport const constants = {\n LEFT: 37,\n UP: 38,\n RIGHT: 39,\n DOWN: 40,\n ESC: 27,\n SPACE: 32,\n ENTER: 13,\n TAB: 9\n}\n\nexport function capitalize(s = '') {\n return s[0].toUpperCase() + s.slice(1)\n}\n\nexport const convertToCamelCase = (str: string): string => {\n const arr = str.match(/[a-z]+|\\d+/gi)\n if (!arr) { return str }\n return arr.map((m, i) => {\n let low = m.toLowerCase()\n if (i !== 0) {\n low = low.split('').map((s, k) => (k === 0 ? s.toUpperCase() : s)).join(\"\")\n }\n return low\n }).join(\"\")\n}\n\nexport function slug(s = '') {\n return s\n .toLowerCase()\n .trim()\n .replace(/\\s+/g, '-') // Replace spaces with -\n .replace(/[^\\w-]+/g, '') // Remove all non-word chars\n .replace(/--+/g, '-') // Replace multiple - with single -\n}\n\nexport function pxToEm(target: number, stripedInnerFontSize = 1) {\n return target / 14 / stripedInnerFontSize + 'em'\n}\n\nexport function percent(target: number) {\n return target + '%'\n}\n\nexport function parseHTML(str: string) {\n const tmp = document.implementation.createHTMLDocument('')\n tmp.body.innerHTML = str\n return tmp.body.childNodes\n}\n\nexport function stripHTML(str: string) {\n const tmp = document.implementation.createHTMLDocument('')\n tmp.body.innerHTML = str\n return (tmp.body.textContent ?? \"\").replace(RegExp('[\\\\s|\\'|\"]', 'g'), '')\n}\n\nexport function makeId(length: number) {\n var result = ''\n var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\n var charactersLength = characters.length\n for (var i = 0; i < length; i++) {\n result += characters.charAt(Math.floor(Math.random() * charactersLength))\n }\n return result\n}\n\nexport function removeEmptyValues(obj: { [key: string]: any }): { [key: string]: any } {\n const findText = [\n 'Default campaign ID (tracking missing in Page Builder export)',\n 'Default campaign name (tracking missing in Page Builder export)',\n 'promoname', \n 'promoid', \n 'promocreative', \n 'undefined'\n ];\n \n for (let key in obj) {\n const value = obj[key];\n \n if (value === null || value === undefined || value === '') {\n delete obj[key];\n continue;\n }\n \n if (typeof value === 'string') {\n for (const text of findText) {\n if (value.includes(text)) {\n delete obj[key];\n break;\n }\n }\n }\n }\n \n return obj;\n}\n\nexport function makeHash(str: string) {\n var hash = 0,\n i,\n chr\n if (!str) {\n return hash\n }\n for (i = 0; i < str.length; i++) {\n chr = str.charCodeAt(i)\n hash = (hash << 5) - hash + chr\n hash |= 0 // Convert to 32bit integer\n }\n return 'id-' + hash\n}\n\nexport function getHashLink(link: string) {\n let linkHash = link\n let linkNoHash = link\n if (link.indexOf('#') !== -1) {\n linkNoHash = link.replace('#', '')\n } else {\n linkHash = '#' + link\n }\n\n return { linkNoHash, linkHash }\n}\n\nexport function lazyLoad(node: Element, attribute: string, value: any, url: string) {\n const CLASSNAME_OUT_OF_SCREEN = 'lazy-load'\n const CLASSNAME_IN_SCREEN = 'lazy-loaded'\n const CLASSNAME_ON_ERROR = 'lazy-loaded-error'\n\n const isOldIOS = () => {\n var agent = window.navigator.userAgent,\n start = agent.indexOf('OS ')\n if ((agent.indexOf('iPhone') > -1 || agent.indexOf('iPad') > -1) && start > -1) {\n return window.Number(agent.substr(start + 3, 3).replace('_', '.')) < 14\n }\n return false\n }\n\n const inViewPort = (attribute: string, value: any) => {\n node.setAttribute(attribute, value)\n\n const cb = () => node.classList.add(CLASSNAME_IN_SCREEN)\n\n if (url) {\n const img = new Image()\n img.src = url\n img.onload = cb\n img.onerror = () => {\n cb()\n node.classList.add(CLASSNAME_ON_ERROR)\n throw new Error(`Image ${url} cannot be loaded`)\n }\n\n return\n }\n\n cb()\n }\n\n if (/Trident\\/|MSIE/.test(window.navigator.userAgent) || isOldIOS()) {\n inViewPort(attribute, value)\n } else {\n if ('IntersectionObserver' in window) {\n node.classList.add(CLASSNAME_OUT_OF_SCREEN)\n let lazyBackgroundObserver = new IntersectionObserver(function (entries) {\n entries.forEach(function (entry) {\n if (entry.isIntersecting) {\n inViewPort(attribute, value)\n lazyBackgroundObserver.unobserve(entry.target)\n }\n })\n })\n lazyBackgroundObserver.observe(node)\n } else {\n inViewPort(attribute, value)\n }\n }\n}\n\nexport function lazyLoadCallback(node: Element, cb: () => void) {\n const isOldIOS = () => {\n var agent = window.navigator.userAgent,\n start = agent.indexOf('OS ')\n if ((agent.indexOf('iPhone') > -1 || agent.indexOf('iPad') > -1) && start > -1) {\n return window.Number(agent.substr(start + 3, 3).replace('_', '.')) < 14\n }\n return false\n }\n\n if (/Trident\\/|MSIE/.test(window.navigator.userAgent) || isOldIOS()) {\n cb()\n } else {\n if ('IntersectionObserver' in window) {\n let lazyBackgroundObserver = new IntersectionObserver(\n function (entries) {\n entries.forEach(function (entry) {\n if (entry.isIntersecting) {\n cb()\n lazyBackgroundObserver.unobserve(entry.target)\n }\n })\n },\n { rootMargin: '150% 0px' }\n )\n lazyBackgroundObserver.observe(node)\n }\n }\n}\n\n// Debounce\nexport function debounce<T>(func: (v: T) => void, time = 100) {\n let timer: number\n return function (event: T) {\n if (timer) {\n window.clearTimeout(timer)\n }\n timer = window.setTimeout(func, time, event)\n }\n}\n\n// isIE - to check for internet explorer\nexport function isIE() {\n let ua = window.navigator.userAgent,\n isIE = /MSIE|Trident/.test(ua)\n\n return isIE\n}\n\n// Load external script\nexport const loadExternalScript = ({\n src,\n callback = null,\n async = false,\n defer = false,\n module = false,\n id = ''\n}: {\n src: string;\n callback: null | GlobalEventHandlers[\"onload\"]\n module: boolean,\n defer: boolean,\n async: boolean,\n id: string\n}) => {\n const script = document.createElement('script')\n script.type = module ? 'module' : 'text/javascript'\n script.src = src\n id ? (script.id = id) : false // add id attribute only if passed\n if (typeof callback === 'function') {\n script.onload = callback\n }\n script.async = async\n script.defer = defer\n document.body.appendChild(script)\n}\n\n// Load external css\nexport const loadExternalCss = ({ src }: { src: string }) => {\n const script = document.createElement('link')\n script.rel = 'stylesheet'\n script.href = src\n document.body.appendChild(script)\n}\n// Lazy load vendor script\nexport const lazyLoadVendorScript = (handler, el) => {\n const observer = new IntersectionObserver(handler)\n observer.observe(el)\n}\n\n/**\n * Replaces variable inside a given string\n * Each variable have to be enclosed between stChr and enChr\n * The values have to be contained in the vars object, they key must match\n * example :\n * txt : 'See {resultsLength} Results'\n * vars : {resultsLength:'30'}\n * stChr : '{'\n * enChr : '}'\n *\n * will return : 'See 30 Results'\n *\n * @param {string} txt\n * @param {object} vars\n * @param {string} stChr\n * @param {string} enChr\n */\nexport function interpolate(txt: string, vars: Record<string, null | undefined | string>, stChr: string, enChr: string) {\n let curIdx = 0\n\n while (txt) {\n const stIdx = txt.indexOf(stChr, curIdx)\n if (stIdx === -1) {\n break\n }\n const enIdx = txt.indexOf(enChr, stIdx + 1)\n if (enIdx === -1) {\n break\n }\n const hashId = txt.substring(stIdx + stChr.length, enIdx)\n if (vars[hashId] != null) {\n txt = txt.substr(0, stIdx) + vars[hashId] + txt.substr(enIdx + enChr.length)\n curIdx = stIdx\n } else {\n curIdx = enIdx\n }\n }\n return txt\n}\n\n/**\n * Find in container element, add height to equal size of element\n * @param container css path where my element is contain e.g. `.c-container`\n * @param el css path of elements to equalized\n */\nexport const equalHeight = (containerSelector: string, el: string, elementScope: HTMLElement) => {\n const container = elementScope.querySelector<HTMLElement>(containerSelector)\n if (!container) {\n return\n }\n\n const items = container.querySelectorAll<HTMLElement>(el)\n let max = -1\n\n for (let i = 0; i < [...items].length; i++) {\n const item = [...items][i]\n let h = item.offsetHeight\n max = h > max ? h : max\n }\n\n if (max <= 0) {\n return\n }\n\n for (let i = 0; i < [...items].length; i++) {\n const item = [...items][i]\n item.style.height = `${max}px`\n }\n}\n\nexport const stringifyCurlyQuote = (data: {}) => JSON.stringify(data).replace(\"'\", '’')\n\nexport const stringifyForAttribute = (data = {}) => {\n return escapeHtml(JSON.stringify(data))\n}\n\n/**\n * This function is included instead of sanitizeString because for\n * inserting HTML into innerHTML we need to make sure all HTML\n * entities are escaped.\n */\nexport const escapeHtml = (text: string) => {\n const map = {\n '&': '&',\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","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","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","import { EVENT_POPIN_OPEN } from '@kissui/components'\nimport { setAttributes } from '@kissui/helpers/src/utils'\nimport { dispatchEvent } from '@kissui/helpers/src/assets/js/eventDispatch'\n\nconst bundlePopinID = 'bundle-popin-id'\nlet bundlePopinContent = ''\nlet label_close\n\nexport const renderBundlePopinLink = (\n { type, bundle_details, bundled, sku, position, range },\n component\n) => {\n if (\n type === 'capsule' &&\n bundle_details &&\n bundle_details.popin_link_text &&\n bundled === true\n ) {\n bundlePopinContent = `<nb-bundle-details\n main_sku='${sku}'\n description='${bundle_details.description}'\n other_skus='${bundle_details.other_skus}'\n other_skus_quantity= '${bundle_details.other_skus_quantity}'\n range='${range}'\n position='${position}'>\n </nb-bundle-details>`\n\n component.variation = 'white'\n\n label_close = bundle_details.popin_label_close\n return `<nb-link class=\"cn_card__cta__bundle\" size=\"large\" color=\"gold\" label=\"${bundle_details.popin_link_text}\"></nb-link>`\n }\n return ''\n}\n\nexport const openBundlePopin = component => {\n renderPopinBundleDetail(component)\n component.bundlePopIn = document.getElementById(bundlePopinID)\n component.appendChild(component.bundlePopIn)\n\n setAttributes(component.bundlePopIn, {\n variation: 'before',\n bgcolor: 'white',\n size: 'L',\n padding: 'false',\n label_close: label_close,\n content: bundlePopinContent\n })\n\n component.bundlePopIn.classList.add('nb-popin--bundle')\n\n dispatchEvent({\n eventName: EVENT_POPIN_OPEN,\n args: { id: bundlePopinID }\n })\n}\n\nconst renderPopinBundleDetail = component => {\n if (document.getElementById(bundlePopinID) != null) return\n let popin = document.createElement('nb-popin')\n popin = component.appendChild(popin)\n popin.setAttribute('id', bundlePopinID)\n popin.setAttribute('content', '')\n}\n","import viewportHelper from '@kissui/helpers/src/viewport.helpers'\nimport { stringifyForAttribute } from '@kissui/helpers/src/utils'\n\nconst DISPLAY_COLOR_MAX = 4\n\nexport const renderColors = props => {\n if (!props) {\n return ''\n }\n\n const {\n colors,\n sku,\n max_colors = DISPLAY_COLOR_MAX,\n a11y_extra_color = '',\n url,\n activeSku,\n name\n } = props\n\n if (!colors) {\n return ''\n }\n\n const colorData = stringifyForAttribute({\n colors,\n max_colors,\n activeSku: activeSku || sku,\n extra_url: url,\n extra_title: name + ', ' + a11y_extra_color\n })\n\n const size = viewportHelper.is.mobile ? 'small' : 'large'\n\n return `<nb-colors data=\"${colorData}\" size=\"${size}\"></nb-colors>`\n}\n","import { stringifyForAttribute } from '@kissui/helpers/src/utils'\n\nexport function renderFeatures({ features = [] }) {\n if (features.length === 0) {\n return ''\n }\n\n return `<div class=\"cn_card__features\">${features.map(renderFeature).join('')}</div>`\n}\n\nfunction renderFeature({ icon, text, heading = '', description = '' }) {\n const desc = text || (heading ? `${heading} ${description}` : '')\n if (!desc) {\n return ''\n }\n const data = stringifyForAttribute({ icon, label: desc, classname: 't-xs-500' })\n return `<nb-icon-text data=\"${data}\"></nb-icon-text>`\n}\n","import { lazyLoad } from '@kissui/helpers/src/utils'\n\nexport const initLazyLoad = (props, component) => {\n const { image = '' } = props\n let width = '150'\n const el = component.querySelector('img.cn_card__image__single')\n if (!el) {\n return\n }\n const getWidth = el.getAttribute('data-imwidth')\n if (getWidth) {\n width = getWidth\n }\n const imPolicy = `?impolicy=product&imwidth=${width}`\n\n lazyLoad(el, 'src', `${image + imPolicy}`, image + imPolicy)\n}\n","export const renderPrice = ({ price, giftcard_price, type, hidePrice, subscription = {} }) => {\n if (!price || (type === 'giftcard' && !giftcard_price) || hidePrice) {\n return ''\n }\n const { from = '', custom_price = '' } = subscription\n return `\n ${from ? `<p class=\"t-sm-400\">${from}</p>` : ''}\n <h4 class=\"cn_card__priceWrapper--current t-md-700-sl\"><span>${\n custom_price || price\n }</span></h4>`\n}\n","export const getCurrency = () => window[window.config.padl.namespace].dataLayer.app.app.currency\n","import { COFFEE_VERTUO } from '@kissui/components/src/constants.mjs'\nimport { getCurrency } from './getCurrency'\nexport { getCurrency } from './getCurrency'\n\nexport const ECAPI_TYPE_CAPSULE = 'capsule'\nexport const ECAPI_TYPE_MACHINE = 'machine'\nexport const ECAPI_TYPE_ACCESSORY = 'accessory'\nexport const ECAPI_TYPE_GIFT_CARD = 'giftcard'\n\nconst TECHNOLOGY_CATEGORY_IDENTIFIER = '/machineTechno/'\nconst SLEEVE_OF_10 = 10\nconst SLEEVE_OF_7 = 7\n\nconst trimSku = sku => sku.replace(/[^a-z0-9- +./]/gi, '')\n\nexport const getLegacySKU = productId => productId.split('prod/').pop()\n\nexport const getPriceFormatter = async () => await window.napi.priceFormat()\n\nexport const getProduct = sku => window.napi.catalog().getProduct(trimSku(sku))\n\nexport function getTechnologyName(productData) {\n const techno = productData.technologies[0]\n return techno.substring(\n techno.indexOf(TECHNOLOGY_CATEGORY_IDENTIFIER) + TECHNOLOGY_CATEGORY_IDENTIFIER.length\n )\n}\n\nfunction isMultipleOf(quantity, multiple) {\n return quantity % multiple === 0\n}\n\nexport function getSleeveNumber(product, getTechnologyNameFn = getTechnologyName) {\n if (product.sales_multiple !== 1 && isMultipleOf(product.sales_multiple, SLEEVE_OF_10)) {\n // Sleeve of original or vertuo\n return product.sales_multiple / SLEEVE_OF_10\n }\n\n if (\n product.sales_multiple !== 1 &&\n getTechnologyNameFn(product) === COFFEE_VERTUO &&\n isMultipleOf(product.sales_multiple, SLEEVE_OF_7)\n ) {\n // Sleeve of vertuo\n return product.sales_multiple / SLEEVE_OF_7\n }\n\n if (product.sales_multiple === 1 && isMultipleOf(product.unitQuantity, SLEEVE_OF_10)) {\n // Bundle of original or vertuo\n return product.unitQuantity / SLEEVE_OF_10\n }\n\n if (\n product.sales_multiple === 1 &&\n getTechnologyNameFn(product) === COFFEE_VERTUO &&\n isMultipleOf(product.unitQuantity, SLEEVE_OF_7)\n ) {\n // Bundle of vertuo\n return product.unitQuantity / SLEEVE_OF_7\n }\n\n return NaN\n}\n\n/**\n * Guess if the product is part of a bundle.\n * This is determined by checking the 'sales_multiple' and 'unitQuantity' properties.\n */\nexport function isBundled(productData) {\n // TODO: this function should not change the productData, but some components still need it\n productData.sales_multiple = productData.sales_multiple || productData.salesMultiple\n\n const isSalesMultipleGreaterThanOne = productData.sales_multiple > 1\n const isUnitQuantityEqualToOne = productData.unitQuantity === 1\n const isSalesMultipleEqualToOne = productData.sales_multiple === 1\n const isUnitQuantityGreaterThanOne = productData.unitQuantity > 1\n\n // The product is not bundled if sales_multiple > 1 and unitQuantity = 1\n if (isSalesMultipleGreaterThanOne && isUnitQuantityEqualToOne) {\n return false\n }\n\n // The product is bundled if sales_multiple = 1 and unitQuantity > 1\n return isSalesMultipleEqualToOne && isUnitQuantityGreaterThanOne\n}\n\n/**\n * Replace an array of SKU with product data\n * Remove the element inside the list if sku fail. It prevents to get an empty item.\n * @param {Array.<String>} skus\n * @param getProductFn\n * @returns {Promise<Awaited<unknown>[]>}\n */\nexport function getProductAndClean(skus, getProductFn = getProduct, napi = window.napi) {\n const promises = []\n\n if (!napi) {\n return Promise.reject()\n }\n\n if (!Array.isArray(skus)) {\n skus = [skus]\n }\n\n // Load manually the product to delete SKU fail\n for (const sku of skus) {\n promises.push(\n getProductFn(sku)\n .then(data => skus.splice(skus.indexOf(sku), 1, data))\n .catch(() => {\n skus.splice(skus.indexOf(sku), 1)\n console.error(`getProduct fail on sku ${sku}`)\n })\n )\n }\n\n return Promise.all(promises)\n}\n\nexport const getFormattedPrice = async price => {\n const priceFormatter = await getPriceFormatter()\n const currency = getCurrency()\n\n return priceFormatter.html\n ? priceFormatter.html(currency, price)\n : priceFormatter.short(currency, price) || ''\n}\n\nexport const getProductCategories = async sku => {\n const productDetails = await getProduct(sku)\n const productCategories = productDetails ? productDetails.supercategories : []\n const productCategoriesNew = await Promise.all(\n productCategories.map(async categoryEncoded => {\n const productCategoryData = await window.napi.catalog().getCategory(categoryEncoded)\n return productCategoryData\n })\n )\n return productCategoriesNew\n}\n","import { getFormattedPrice } from '@kissui/helpers/src/catalog'\n\nexport const renderStrikethroughPrice = async strikethroughPrice => {\n if (!strikethroughPrice) return ''\n let finalStrikethroughPrice = await getFormattedPrice(strikethroughPrice)\n\n return `${`<p class=\"cn_card__strikethroughPrice t-sm-400\">${finalStrikethroughPrice}</p>`}`\n}\n","import { interpolate } from '@kissui/helpers/src/utils'\n\nexport const renderShowSleeve = props => {\n const {\n sales_multiple,\n label_sleeve,\n label_sleeves,\n show_sleeve = false,\n sleeve_syntax = '{numberOfSleeves} {sleeveLabel} ({quantity} {label_capsules})',\n number_of_sleeves,\n label_capsules,\n type,\n bundled,\n unit_quantity,\n unitQuantity\n } = props\n\n const numberOfSleeves = number_of_sleeves\n const sleeveLabel = numberOfSleeves > 1 && label_sleeves ? label_sleeves : label_sleeve\n const quantity = bundled === false ? sales_multiple : unit_quantity || unitQuantity || 0\n const html = content => {\n content = interpolate(\n content,\n {\n numberOfSleeves,\n sleeveLabel,\n quantity,\n label_capsules,\n label_sleeve\n },\n '{',\n '}'\n )\n return `<p class=\"cn_card__priceWrapper--items t-xs-500-sl showSleeve\">${content}</p>`\n }\n let labelContent\n\n if (show_sleeve && type === 'capsule') {\n if (numberOfSleeves && label_sleeve && label_capsules) {\n labelContent = sleeve_syntax\n } else {\n return ''\n }\n return html(labelContent)\n }\n return ''\n}\n","import { renderAddToCart } from './addToCart'\nimport { renderOutOfStock } from './outOfStock'\nimport { renderPrice } from './price'\nimport { renderA11yPrice } from './priceA11y'\nimport { renderCapsulePrice } from './priceCapsule'\nimport { renderStrikethroughPrice } from './renderStrikethroughPrice'\nimport { renderShowSleeve } from './sleeve'\n\nexport async function renderPriceWrapper(props) {\n const { in_stock, strikethrough_price, hide_add_to_cart = false } = props\n\n const showOutOfStock = in_stock != null && !in_stock\n\n if (hide_add_to_cart === true) {\n return ''\n }\n\n return `\n <div class=\"cn_card__priceWrapper\">\n <div class=\"cn_card__priceInnerWrapper\">\n ${strikethrough_price ? await renderStrikethroughPrice(strikethrough_price) : ''}\n ${renderPrice(props)}\n ${!showOutOfStock ? renderShowSleeve(props) : ''}\n ${!showOutOfStock ? renderCapsulePrice(props) : ''}\n ${renderA11yPrice(props)}\n ${showOutOfStock ? renderOutOfStock(props) : ''}\n </div>\n ${renderAddToCart(props)}\n </div>`\n}\n","import { interpolate } from '@kissui/helpers/src/utils'\n\nexport const renderCapsulePrice = props => {\n const {\n show_capsule_price = false,\n price_per_capsule,\n capsule_price_label,\n capsule_price_syntax = '{capsule_price_label}: {price_per_capsule}'\n } = props\n\n if (!show_capsule_price) {\n return ''\n }\n\n const html = content => {\n content = interpolate(\n content,\n {\n capsule_price_label,\n price_per_capsule\n },\n '{',\n '}'\n )\n return `<p class=\"cn_card__priceWrapper--items t-xs-500-sl capsulePrice\">${content}</p>`\n }\n\n return html(capsule_price_syntax)\n}\n","export const renderA11yPrice = ({\n type,\n price,\n price_per_capsule,\n a11y_price = 'euros per sleeve',\n a11y_capsule_price = 'Capsule price',\n sleeve_variation_pdp = 'false'\n}) => {\n return `<span class=\"sr-only\">\n ${\n sleeve_variation_pdp === 'true'\n ? type === 'capsule'\n ? `${a11y_capsule_price}: ${price_per_capsule}`\n : ''\n : `${price} ${a11y_price}`\n }\n </span>`\n}\n","export const renderOutOfStock = props => {\n const { label_outofstock } = props.shop_similar\n\n if (label_outofstock === '') {\n return ''\n }\n return `<p class=\"cn_card__priceWrapper--items t-xs-500-sl\">${label_outofstock}</p>`\n}\n","import { stringifyForAttribute } from '@kissui/helpers/src/utils'\nimport viewportHelper from '@kissui/helpers/src/viewport.helpers'\n\nexport const renderAddToCart = props => {\n const {\n category_name = '',\n type,\n sku,\n longSku = '',\n position,\n giftcard_price,\n variation = 'plp',\n quantity_selector,\n hidePrice,\n url,\n view_details_label = 'View details'\n } = props\n\n let buttonSize = 'large'\n if (variation === 'plp') {\n buttonSize = viewportHelper.is.mobile ? 'small' : 'large'\n }\n\n if (type === 'giftcard' && giftcard_price) {\n const giftCardData = {\n price: giftcard_price,\n sku: sku,\n add_to_cart: buttonSize,\n quantity_selector: quantity_selector\n }\n return `<nb-add-gift-card data=\"${stringifyForAttribute(giftCardData)}\"></nb-add-gift-card>`\n }\n\n if (hidePrice) {\n return `<nb-cta link=\"${url}\" variation=\"primary\">${view_details_label}</nb-cta>`\n }\n\n return `\n <nb-add-to-cart\n sku=\"${sku}\"\n longSku=\"${longSku}\"\n buttonSize=\"${buttonSize}\"\n showPrice\n range='${category_name}'\n position='${position}'\n ></nb-add-to-cart>\n `\n}\n","export const renderRatings = ({ sku, minimum_rating = 0 }, refElement) => {\n if (!window.napi.ratings) {\n return ''\n }\n window.napi\n .ratings()\n .summary(sku)\n .then(ratingsResult => {\n if (\n ratingsResult &&\n ratingsResult.ratingAverage > 0 &&\n ratingsResult.ratingAverage > minimum_rating\n ) {\n return ratingsResult\n }\n return ''\n })\n .then(ratings => {\n if (!ratings) {\n return ''\n }\n const ratingData = {\n stars: ratings ? parseFloat(ratings.ratingAverage.toFixed(2)) : 0\n }\n return ratingData\n })\n .then(ratingData => {\n if (ratingData) {\n const elem = document.createElement('nb-rating')\n elem.setAttribute('stars', ratingData ? ratingData.stars : 0)\n refElement.querySelector('nb-loader').replaceWith(elem)\n } else {\n refElement.querySelector('nb-loader').remove()\n }\n })\n}\n","export const root = 'carousel'\nexport const wrapper = 'wrapper'\nexport const container = 'container'\nexport const item = 'item'\nexport const next = 'next'\nexport const prev = 'prev'\nexport const hidden = 'hidden'\nexport const bulletActive = 'active'\nexport const dragRatio = 0.1\n","import { dragRatio } from './constants'\n\n/**\n * Allow touch gesture on the carousel\n */\nclass CarouselTouchPlugin {\n constructor(carousel) {\n this._carousel = carousel\n\n // Disable dragging image effect\n this._carousel._container.addEventListener('dragstart', e => e.preventDefault())\n this._carousel._container.addEventListener('touchstart', e => this.startDrag(e), {\n passive: true\n })\n this._carousel._container.addEventListener('mousedown', e => this.startDrag(e))\n this._carousel._container.addEventListener('touchstart', e => this.startDrag(e), {\n passive: true\n })\n\n window.addEventListener('mousemove', e => this.drag(e), { passive: false })\n window.addEventListener('touchmove', e => this.drag(e), { passive: false })\n\n window.addEventListener('mouseup', () => this.endDrag())\n window.addEventListener('touchend', () => this.endDrag())\n window.addEventListener('touchcancel', () => this.endDrag())\n\n this.translateFactor = 150\n }\n\n /**\n * Start moving slide when touch\n * @param {MouseEvent|TouchEvent} e\n */\n startDrag(e) {\n // Touch and more than one finger, probably a zoom, not a swipe.\n if (e.touches && e.touches.length > 1) {\n return\n }\n\n if (e.touches) {\n e = e.touches[0]\n }\n\n this._origin = { x: e.screenX, y: e.screenY }\n this._width = this._carousel.containerWidth\n }\n\n /**\n * Start moving slide when touch\n * @param {MouseEvent|TouchEvent} e\n */\n drag(e) {\n if (!this._origin) {\n return\n }\n\n const point = e.touches ? e.touches[0] : e\n const translate = {\n x: point.screenX - this._origin.x,\n y: point.screenY - this._origin.y\n }\n\n this._lastTranslate = translate\n\n const offsetCurrent = this._carousel._currentIndex * this._carousel._widthSlide\n const offsetNew = (this.translateFactor * translate.x) / this._width\n const translateDelta = offsetCurrent - offsetNew\n this._carousel.translate(translateDelta)\n }\n\n /**\n * Prevent to drag the page when swiping\n * @param {MouseEvent|TouchEvent} e\n * @param {Object} translate\n * @param {Number} translate.x\n * @param {Number} translate.y\n */\n preventMobileYTranslate(e, translate) {\n if (!e.touches) {\n return\n }\n\n if (e.touches && Math.abs(translate.x) > Math.abs(translate.y)) {\n e.preventDefault()\n e.stopPropagation()\n } else if (e.touches && Math.abs(translate.y) > Math.abs(translate.x)) {\n e.preventDefault()\n e.stopPropagation()\n }\n }\n\n /**\n * @param {MouseEvent|TouchEvent} e\n */\n endDrag() {\n if (!this._origin || !this._lastTranslate) {\n this._origin = null\n this._lastTranslate = null\n return\n }\n\n // If drag delta is above dragRatio, we will move right or left\n const dragDelta = this._lastTranslate.x / this._carousel.carouselWidth\n\n if (Math.abs(dragDelta) > dragRatio) {\n const slideDirection = this._lastTranslate.x < 0 ? 'next' : 'prev'\n this._carousel[slideDirection]()\n }\n // Return to current element\n else {\n this._carousel.goToItem(this._carousel._currentIndex)\n }\n\n this._origin = null\n this._lastTranslate = null\n }\n}\n\nexport default CarouselTouchPlugin\n","/**\n * Allow touch gesture on the carousel\n */\nclass CarouselCreamUiHack {\n constructor(carousel) {\n this._carousel = carousel\n\n new MutationObserver(mutations => {\n mutations.forEach(function (mutation) {\n if (!mutation || !mutation.oldValue || !mutation.classList) {\n return\n }\n\n const oldState = mutation.classList.contains('has-overlay-absolute')\n const newState = document.body.classList.contains('has-overlay')\n const closeAddToCart = oldState && !newState\n\n if (!closeAddToCart) {\n return\n }\n\n this._carousel.goToItem(this._carousel._currentIndex)\n })\n }).observe(document.body, {\n attributes: true,\n attributeFilter: ['class'],\n attributeOldValue: true\n })\n }\n}\n\nexport default CarouselCreamUiHack\n","import { root, wrapper, container, item, next, prev, hidden, bulletActive } from './constants'\nimport CarouselTouchPlugin from './CarouselTouchPlugin'\nimport CarouselCreamUiHack from './CarouselCreamUiHack'\n\nclass Carousel {\n /**\n * This callback type is called `requestCallback` and is displayed as a global symbol.\n *\n * @callback moveCallback\n * @param {Number} index\n */\n\n /**\n * @param {HTMLElement} element\n * @param {Object} options\n * @param {Number} [options.slidesToScroll=1] options.slidesToScroll of element do slide\n * @param {Number} [options.slidesVisible=1] options.slidesVisible of element to display\n * @param {Number} [options.spaceBetween=0] options.spaceBetween space between slides\n * @param {Boolean} [options.navigationButton=true] options.navigationButton show navigation button\n * @param {Boolean} [options.loop=true] options.loop loop at the end of the carousel\n * @param {Boolean} [options.pagination=true] options.pagination display pagination\n * @param {String} [options.pagination_variation'] 'stepper' --> enables an stepper on the slider (e.g. current-slide/total-number-of-slides)\n * @param {Boolean} [options.nav_centered=false] options.nav_centered display centered navigation next and prev buttons below the slider\n */\n constructor(element, options = {}) {\n this._element = element\n this._slides = [].slice.call(element.children)\n const _index = options.index || 0\n\n this._options = Object.assign(\n {},\n {\n slidesToScroll: 1,\n slidesVisible: 1,\n spaceBetween: 0,\n navigationButton: true,\n loop: true,\n navigationAsSlider: false,\n pagination: true,\n hookGetRightBoundary: null,\n hookSlideChange: null,\n hookMove: null,\n hookNext: null,\n hookPrevious: null,\n pagination_variation: null,\n nav_centered: false\n },\n options\n )\n\n this.moveCallbacks = []\n this._ratio = this._slides.length / this._options.slidesVisible\n\n this.buildIHM()\n new CarouselCreamUiHack(this)\n if (!this.hasPagination()) {\n return\n }\n new CarouselTouchPlugin(this)\n this.goToItem(_index)\n }\n\n /**\n * @returns {HTMLElement}\n */\n get element() {\n return this._element\n }\n\n /**\n * @returns {number & Number}\n */\n get navigationAsSlider() {\n return this._options.navigationAsSlider\n }\n\n /**\n * @returns {number & Number}\n */\n get slidesToScroll() {\n return this._options.slidesToScroll\n }\n\n /**\n * @returns {number}\n */\n get slidesVisible() {\n return this._options.slidesVisible\n }\n\n /**\n * @returns {number}\n */\n get slidesTotal() {\n return this._slides.length\n }\n\n /**\n * @returns {boolean & Boolean}\n */\n get navigationButton() {\n return this._options.navigationButton\n }\n\n /**\n * @returns {string}\n */\n get navigationVariation() {\n return this._options.navigation_variation\n }\n\n /**\n * @returns {string}\n */\n get navigationSize() {\n return this._options.navigation_size\n }\n\n /**\n * @returns {boolean & Boolean}\n */\n get loop() {\n return this._options.loop\n }\n\n /**\n * @returns {Boolean}\n */\n get pagination() {\n return this._options.pagination\n }\n\n /**\n * @returns {number}\n */\n get containerWidth() {\n return this._container.offsetWidth\n }\n\n /**\n * @returns {number}\n */\n get carouselWidth() {\n return this._root.offsetWidth\n }\n\n /**\n * @returns {number}\n */\n get wrapperWidth() {\n return this._wrapper.offsetWidth\n }\n\n /**\n * @returns {Boolean}\n */\n get paginationVariation() {\n return this._options.pagination_variation\n }\n\n /**\n * @returns {Boolean}\n */\n get nav_centered() {\n return this._options.nav_centered\n }\n\n /**\n * Get slide width from container wrapper width and slides count\n *\n * @param {Number} wrapperWidth\n * @returns {Number} slide width\n */\n getSlideWidth(wrapperWidth) {\n const { slidesVisible, spaceBetween } = this._options\n return (wrapperWidth + parseInt(spaceBetween)) / slidesVisible\n }\n\n /**\n * Refactor carousel to add the elements needs\n */\n buildIHM() {\n this._root = this.createElement('div', root)\n this._container = this.createElement('div', container)\n this._wrapper = this.createElement('div', wrapper)\n this._children = this._slides.map(child => {\n const element = this.createElement('div', item)\n element.appendChild(child)\n this._container.appendChild(element)\n return element\n })\n this._wrapper.appendChild(this._container)\n this._root.appendChild(this._wrapper)\n this._element.appendChild(this._root)\n\n this.setWrapperStyle()\n\n if (!this.hasPagination()) {\n return\n }\n\n if (this.navigationButton) {\n this.createNavigation()\n }\n\n if (this.pagination) {\n this.createPagination()\n }\n }\n\n /**\n * Set elements sizes\n */\n setWrapperStyle() {\n const wrapperWidth = this.wrapperWidth\n const widthSlide = this.getSlideWidth(wrapperWidth)\n const widthContainer = widthSlide * this._children.length\n\n this.setContainerWidth(widthContainer)\n this.setWrapperWidth(wrapperWidth)\n\n for (const slide of this._children) {\n this.setSlideWidth(slide, widthSlide)\n }\n\n this._widthContainer = widthContainer\n this._widthSlide = widthSlide\n this._widthWrapper = wrapperWidth\n }\n\n /**\n * Fix width for each slide\n * @param {object} slide\n * @param {number} widthSlide\n */\n setSlideWidth(slide, widthSlide) {\n slide.style.width = `${widthSlide - this._options.spaceBetween}px`\n if (this._options.spaceBetween) {\n slide.style.marginRight = `${this._options.spaceBetween}px`\n }\n }\n\n /**\n * Fix width for container\n * @param {Number} width\n */\n setContainerWidth(width) {\n this._container.style.width = `${width}px`\n }\n\n /**\n * Fix width for wrapper\n * @param {Number} width\n */\n setWrapperWidth(width) {\n this._wrapper.style.width = `${width}px`\n }\n\n /**\n * Prevent transition\n */\n disableTransition() {\n this._container.style.transition = 'none'\n }\n\n /**\n * Enable transition\n */\n enableTransition() {\n this._container.style.transition = ''\n }\n\n translate(delta) {\n this._container.style.left = `${-delta}px`\n }\n\n /**\n * Create element\n * @param {String} tag name\n * @param {String} className\n * @returns {HTMLElement}\n */\n createElement(tag, className) {\n let div = document.createElement(tag)\n div.setAttribute('class', className)\n return div\n }\n\n /**\n * Create two button prev/next\n */\n createNavigation() {\n const sliderWidth = this.getSlideWidth(this.wrapperWidth)\n const prevButton = this.createNavigationButton(\n 'prev',\n '24/symbol/chevron-left',\n 'a11y_slider_previous_button',\n sliderWidth\n )\n const nextButton = this.createNavigationButton(\n 'next',\n '24/symbol/chevron-right',\n 'a11y_slider_next_button',\n sliderWidth\n )\n\n this.addNavigationListeners(prevButton, nextButton)\n\n // Note : now navigation is always outside to avoid been cut by overflow\n let mainContainer = this._root.parentElement\n\n mainContainer.appendChild(prevButton)\n mainContainer.appendChild(nextButton)\n\n this.onMove(carousel => {\n const max = carousel._currentIndex + this.slidesVisible\n\n if (!this.loop) {\n if (carousel._currentIndex <= 0) {\n prevButton.classList.add(hidden)\n } else {\n prevButton.classList.remove(hidden)\n }\n\n if (this._slides.length === max) {\n nextButton.classList.add(hidden)\n } else {\n nextButton.classList.remove(hidden)\n }\n\n if (this._options.hookMove) {\n this._options.hookMove(nextButton)\n }\n }\n })\n }\n\n createNavigationButton(type, icon, label, sliderWidth) {\n const button = this.createElement('nb-cta', type === 'prev' ? prev : next)\n button.setAttribute('variation', 'navigation')\n button.setAttribute('contrast', this.navigationVariation)\n button.setAttribute('size', this.navigationSize)\n button.setAttribute('icon_right', icon)\n button.setAttribute('label', label)\n\n if (this.navigationAsSlider) {\n button.style.width = sliderWidth + 'px'\n }\n\n return button\n }\n\n addNavigationListeners(prevButton, nextButton) {\n nextButton.addEventListener('click', () => this.next())\n prevButton.addEventListener('click', () => this.prev())\n\n nextButton.addEventListener('keydown', e => {\n if (e.key === 'Enter' || e.key === 'Space') this.next()\n })\n prevButton.addEventListener('keydown', e => {\n if (e.key === 'Enter' || e.key === 'Space') this.prev()\n })\n }\n\n getSlideNotVisible() {\n return this._children.length - (this.slidesVisible - 1)\n }\n\n hasPagination() {\n return this.getSlideNotVisible() > 1\n }\n\n /**\n * Create pagination Bullets\n */\n createPaginationBullets() {\n const paginationBullets = document.createElement('nav')\n\n const buttons = []\n for (let i = 0; i < this.getSlideNotVisible(); i = i + this.slidesToScroll) {\n let span = document.createElement('span')\n span.innerText = (i + 1).toString()\n\n let button = document.createElement('button')\n button.addEventListener('click', () => this.goToItem(i))\n button.appendChild(span)\n\n paginationBullets.appendChild(button)\n buttons.push(button)\n }\n\n const selectButton = index => {\n let activeButton = buttons[index / this.slidesToScroll]\n\n if (!activeButton) {\n return\n }\n\n buttons.forEach(button => button.classList.remove(bulletActive))\n activeButton.classList.add(bulletActive)\n }\n\n selectButton(this._currentIndex)\n this.onMove(() => selectButton(this._currentIndex))\n\n this._root.parentElement.parentElement.appendChild(paginationBullets)\n }\n\n /**\n * Create pagination pagination_variation\n */\n createPaginationStepper() {\n const paginationStepper = document.createElement('nav')\n paginationStepper.classList.add('t-sm-500')\n\n let spanTotal = document.createElement('div')\n spanTotal.innerText = this.slidesTotal - this.slidesVisible + 1\n spanTotal.classList.add('totalPages')\n\n let slash = document.createElement('div')\n slash.innerText = ' / '\n\n let spanCurrent = document.createElement('div')\n spanCurrent.classList.add('currentPage')\n\n paginationStepper.appendChild(spanCurrent)\n paginationStepper.appendChild(slash)\n paginationStepper.appendChild(spanTotal)\n\n this.onMove(() => (spanCurrent.innerText = this._currentIndex + 1))\n // simplified aria strategy, no extra props needed, keep it simple :)\n this.onMove(() =>\n paginationStepper.setAttribute(\n 'aria-label',\n spanCurrent.innerText + slash.innerHTML + spanTotal.innerHTML\n )\n )\n\n this._root.parentElement.parentElement.appendChild(paginationStepper)\n }\n\n /**\n * Create pagination\n */\n createPagination() {\n /**\n * 1. Less than 5 slides create always bullets\n */\n if (this.slidesTotal <= 5) {\n this.createPaginationBullets()\n } else {\n /**\n * 2. More than 5 slides:\n */\n /**\n * 2.1 If pagination_variation prop set to true create pagination_variation\n */\n if (this.paginationVariation === 'stepper') {\n this.createPaginationStepper()\n console.info('paginationVariation >> enabled')\n } else {\n /**\n * 2.2 If pagination_variation prop set to false create bullets\n */\n this.createPaginationBullets()\n console.info('bullets enabled')\n }\n }\n }\n\n next() {\n let next = this._currentIndex + this.slidesToScroll\n\n if (this._options.hookNext) {\n next = this._options.hookNext(next)\n }\n\n this.goToItem(next)\n }\n\n prev() {\n let prev = this._currentIndex - this.slidesToScroll\n\n if (this._options.hookPrevious) {\n prev = this._options.hookPrevious(prev)\n }\n\n this.goToItem(prev)\n }\n\n /**\n * Move carousel to targeted slide\n * @param {Number} index\n */\n goToItem(index) {\n this.hackUi()\n\n const incomingIndex = this.getOverflowingIndex(index)\n\n let translateX = incomingIndex * this._widthSlide\n\n if (this._options.hookSlideChange) {\n translateX = this._options.hookSlideChange(incomingIndex, translateX)\n }\n\n this.translate(translateX)\n this._currentIndex = incomingIndex\n this.indexHasChange()\n }\n\n /**\n * TODO : what was this for ?\n * Hack Cream ui fix\n * @returns {void}\n */\n hackUi() {\n const $html = document.querySelector('html')\n if (\n $html.classList.contains('has-overlay-absolute') ||\n $html.classList.contains('has-overlay')\n ) {\n return\n }\n }\n\n /**\n * Check if incoming slide is contained in the boundaries\n * In loop mode, returns either first or last index\n *\n * @returns {number}\n */\n getOverflowingIndex(index) {\n const reachedLeftBoundary = this.getLeftBoundary(index)\n const reachedRightBoundary = this.getRightBoundary(index)\n\n const lastIndex = this._children.length - this._options.slidesVisible\n\n if (reachedLeftBoundary) {\n return this.loop ? lastIndex : 0\n }\n if (reachedRightBoundary) {\n return this.loop ? 0 : lastIndex\n }\n\n return index\n }\n\n /**\n * Detect when it's going out of left side\n * @param index\n * @returns {boolean}\n */\n getLeftBoundary(index) {\n return index < 0\n }\n\n /**\n * Detect when it's going out of right side\n * @param {Number} index\n * @returns {boolean|boolean}\n */\n getRightBoundary(index) {\n // Bigger or if element is not existing\n const overflowingIndex = index >= this._children.length\n\n const incomingSlideIndex = this.currentIndex + this.slidesVisible\n const existingSlide = this._children[incomingSlideIndex] !== undefined\n const goingToNextSlide = index > this.currentIndex\n\n let boundaryReached = overflowingIndex || (goingToNextSlide && !existingSlide)\n\n if (this._options.hookGetRightBoundary) {\n boundaryReached = this._options.hookGetRightBoundary(boundaryReached, index)\n }\n\n return boundaryReached\n }\n\n /**\n * Get max availbale width from rendered slides\n * @param {Array} slides\n * @returns {Number} max width\n */\n _getMaxSlideWidth(slides) {\n return slides.reduce((width, slide) => Math.max(width, slide.offsetWidth), 0)\n }\n\n /**\n * Add cb after the slide change\n * @param {moveCallback} cb\n */\n onSlideChange(cb) {\n this.onMove(cb)\n }\n\n /**\n * Add cb after the slide change\n * @param {moveCallback} cb\n */\n onMove(cb) {\n this.moveCallbacks.push(cb)\n }\n\n /**\n * Trigger the callback\n */\n indexHasChange() {\n this.moveCallbacks.forEach(cb => cb(this))\n this.activateItems()\n }\n\n activateItems() {\n const max = this._currentIndex + this.slidesVisible\n let t = 0\n this._slides.map((item, index) => {\n item.classList.remove('active')\n item.parentElement.classList.remove('activeParent')\n item.parentElement.classList.remove('currentCenteredSlide')\n\n const video = item.querySelector('video')\n if (video) {\n video.pause()\n }\n\n if (index >= this._currentIndex && index < max) {\n item.classList.add('active')\n item.parentElement.classList.add('activeParent')\n\n if (t === 1) {\n item.parentElement.classList.add('currentCenteredSlide')\n if (video) {\n video.play()\n }\n }\n\n t++\n }\n })\n }\n\n setClass(className) {\n this._element.classList.add(className)\n }\n\n unsetClass(className) {\n this._element.classList.remove(className)\n }\n\n get currentIndex() {\n return this._currentIndex\n }\n}\n\nexport default Carousel\n","export type EventListener = {\n element: HTMLElement\n type: string\n listener: (e: Event) => void\n options?: boolean | AddEventListenerOptions\n}\n\nconst add = (eventListeners: EventListener[] = []) => {\n eventListeners.forEach(eventListener => {\n if (!eventListener || !eventListener.element) {\n return\n }\n return eventListener.element.addEventListener(\n eventListener.type,\n eventListener.listener,\n eventListener.options\n )\n })\n}\n\nconst remove = (eventListeners: EventListener[] = []) => {\n eventListeners.forEach(eventListener => {\n if (!eventListener || !eventListener.element) {\n return\n }\n eventListener.element.removeEventListener(eventListener.type, eventListener.listener)\n })\n}\n\nconst busNamespace = 'pageBuilder'\n\nexport const emitCustomEvent = (eventName: string, data: unknown) => {\n const customEvent = new CustomEvent(`${busNamespace}.${eventName}`, {\n detail: data,\n bubbles: true,\n cancelable: true,\n composed: false\n })\n\n window.dispatchEvent(customEvent)\n}\n\nexport default { add, emitCustomEvent, remove }\n","import { getProduct } from '@kissui/helpers/src/catalog'\nimport { emitCustomEvent } from './events.helpers'\nimport { removeEmptyValues } from '@kissui/helpers/src/utils'\n\nconst raisedByPB = 'page builder'\nconst raisedByWC = 'Web component'\n\n/**\n * helper method for 'itemDisplay' GTM event\n * @param {*} event : 'itemDisplay' - Mandatory as is\n * @param {*} eventRaisedBy : 'Web component' - Mandatory as is\n * @param {*} eventAction : 'Click' - Action that led to the item display. For example, click\n * @param {*} itemTypes : ['products'] - Mandatory as is\n * @param {*} rootElement : ['nb-slider'] - Root DOM element for item detection. Closest common ancestor element of the inserted/displayed promotions and products. It will help the detection to reduce its performance consumption. Set to 0 (zero) in order to request detection through the entire document.\n */\nexport const itemDisplay = args => {\n window.gtmDataObject = window.gtmDataObject || []\n const eventData = {\n event: 'itemDisplay',\n eventRaisedBy: raisedByWC,\n eventAction: 'Click',\n itemTypes: ['products'],\n ...args\n }\n window.gtmDataObject.push(eventData)\n emitCustomEvent('itemDisplay', eventData)\n}\n\n/**\n *\n * helper method for 'customEvent' GTM event\n * @param {*} args (event, eventRaisedBy, eventCategory, eventAction, eventLabel, nonInteraction)\n */\n\nexport const customEvent = args => {\n window.gtmDataObject = window.gtmDataObject || []\n var eventData\n if (args.event_GA4 === undefined || args.event_GA4 === false) {\n eventData = {\n event: 'customEvent',\n eventRaisedBy: raisedByWC,\n ...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","import CarouselLib from './js/Carousel'\nimport createProps from '@kissui/helpers/src/props.helpers'\nimport { makeId } from '@kissui/helpers/src/utils'\nimport { itemDisplay } from '@kissui/helpers/src/gtmEvents'\nimport { dispatchEvent } from '@kissui/helpers/src/assets/js/eventDispatch'\nimport { EVENT_SLIDE_CHANGE } from '@kissui/components'\n\nclass Slider extends HTMLElement {\n constructor() {\n super()\n this._slider = null\n this.randomId = null\n }\n\n static get observedAttributes() {\n return [\n 'navigation_as_slider',\n 'slides_to_scroll',\n 'slides_visible',\n 'pagination',\n 'pagination_variation',\n 'nav_centered'\n ]\n }\n\n connectedCallback() {\n this.slot = this.innerHTML\n this.props = createProps(this.attributes)\n this.randomId = this.props.testId ? this.props.testId : `slider_${makeId(5)}`\n this.render()\n }\n\n createProps() {\n return [...this.attributes].reduce(\n (all, attribute) => ({ ...all, [attribute.nodeName]: attribute.nodeValue }),\n {}\n )\n }\n\n render() {\n this.innerHTML = `<div class=\"slider ${this.randomId}\">${this.slot}</div>`\n this.loadSlider()\n }\n\n loadSlider() {\n const {\n navigation_as_slider = 'false',\n indexSlider = 0,\n slides_loop = 'true',\n slides_visible = 4,\n slides_to_scroll = 1,\n navigation = 'true',\n pagination = 'true',\n space_between = 0,\n navigation_variation = 'dark',\n navigation_size = '48',\n pagination_variation = 'stepper',\n nav_centered = 'false'\n } = this.props\n\n const el = this.querySelector(`.${this.randomId}`)\n const options = {\n index: parseInt(indexSlider),\n slidesToScroll: parseInt(slides_to_scroll),\n slidesVisible: parseInt(slides_visible),\n spaceBetween: space_between,\n loop: slides_loop === 'true',\n navigationAsSlider: navigation_as_slider === 'true',\n navigationButton: navigation === 'true',\n pagination: pagination === 'true',\n navigation_variation,\n navigation_size,\n pagination_variation,\n nav_centered\n }\n this._slider = new CarouselLib(el, options)\n this._slider.setClass('first')\n this._slider.onSlideChange(this.handleClick.bind(this))\n }\n\n handleClick() {\n dispatchEvent({\n eventName: EVENT_SLIDE_CHANGE,\n args: { slideIndex: this._slider.currentIndex }\n })\n\n this.toggleClasses()\n // GTM 'itemDisplay' event\n itemDisplay({ rootElement: ['nb-slider'] })\n }\n\n toggleClasses() {\n const isFirst = this._slider.currentIndex === 0\n const isLast =\n this._slider.slidesTotal === this._slider.currentIndex + this._slider.slidesVisible\n\n this._slider.unsetClass('last')\n this._slider.unsetClass('first')\n\n if (isFirst) {\n this._slider.setClass('first')\n } else if (isLast) {\n this._slider.setClass('last')\n }\n }\n}\n// Registers custom element\ncustomElements.get('nb-slider') || customElements.define('nb-slider', Slider)\n\nexport default Slider\n","import './plp-product-card-image-slider.scss'\nimport createProps from '@kissui/helpers/src/props.helpers'\nimport { lazyLoad, setAttributes } from '@kissui/helpers/src/utils'\nimport '../../slider'\n\nclass PlpProductCardImageSlider extends HTMLElement {\n constructor() {\n super()\n this.props = {}\n }\n\n connectedCallback() {\n this.props = createProps(this.attributes)\n this.render()\n }\n\n render() {\n const { slides, image_alt_text } = this.props\n\n let nbSlider = document.createElement('nb-slider')\n setAttributes(nbSlider, {\n slides_to_scroll: '1',\n slides_visible: '1',\n navigation: 'true',\n navigation_variation: 'highlight',\n navigation_size: '32',\n pagination: 'true'\n })\n\n let nbLoader = document.createElement('nb-loader')\n setAttributes(nbLoader, { icon: 'loading' })\n this.appendChild(nbLoader)\n\n const imWidth = '600'\n slides.forEach(slide => {\n const url = `${slide.url}?impolicy=product&imwidth=${imWidth}`\n let image = document.createElement('img')\n image.setAttribute('alt', image_alt_text)\n image.setAttribute('title', image_alt_text)\n image.setAttribute('data-src', url)\n nbSlider.appendChild(image)\n })\n\n this.appendChild(nbSlider)\n slides.forEach(slide => {\n const url = `${slide.url}?impolicy=product&imwidth=${imWidth}`\n let image = nbSlider.querySelector(`img[data-src=\"${url}\"]`)\n\n lazyLoad(image, 'src', url, url)\n })\n }\n}\n\ncustomElements.get('nb-product-card-image-slider') ||\n customElements.define('nb-product-card-image-slider', PlpProductCardImageSlider)\n\nexport default PlpProductCardImageSlider\n","import renderImage from './image'\nimport renderImageOrSlider from './slider'\nimport { VARIATION_PDP } from '@kissui/components/src/sku/constants'\n\nexport function renderHeader(\n { type, show_slider, slides, image, image_alt_text, plp_type },\n viewportHelper,\n imwidth\n) {\n if (image === undefined || image === '' || plp_type === VARIATION_PDP) {\n return ''\n }\n\n const hasSliderActivated =\n !viewportHelper.is.mobile && show_slider && slides && slides.length > 1\n\n const isMachineWithSlider = (type === 'machine' || plp_type === 'machine') && hasSliderActivated\n\n if (isMachineWithSlider) {\n return renderImageOrSlider(slides, image_alt_text)\n }\n\n return renderImage(image, image_alt_text, null, imwidth)\n}\n","export const VARIATION_PLP = 'plp'\nexport const VARIATION_PDP = 'pdp'\nexport const VARIATION_CROSS_SELL = 'cross-sell'\nexport const VARIATION_SMALL = 'small'\n","export default function renderImage(imgUrl, image_alt_text, url, imwidth = 150) {\n if (!imgUrl) {\n return ''\n }\n\n return `<div class=\"cn_card__image\">\n ${url ? `<a href=\"${url}\" target=\"_self\" aria-hidden=\"true\" tabindex=\"-1\">` : ''}\n <img class=\"cn_card__image__single\" src=${imgUrl} alt=\"${image_alt_text}\" data-imwidth=\"${imwidth}\" />\n ${url ? '</a>' : ''}\n </div>`\n}\n","import { stringifyForAttribute } from '@kissui/helpers/src/utils'\n\nexport default function renderImageOrSlider(slides, image_alt_text) {\n if (!slides || slides.length <= 0) {\n return ''\n }\n\n return `<div class=\"cn_card__image\">\n <nb-product-card-image-slider\n data='${stringifyForAttribute({ slides })}'\n image_alt_text=${image_alt_text}>\n </nb-product-card-image-slider>\n </div>`\n}\n","import { stringifyForAttribute, escapeHtml } from '@kissui/helpers/src/utils'\nimport { renderPrice } from './price'\nexport function renderSubscription(props) {\n const { subscription } = props\n\n if (subscription === undefined) {\n return ''\n }\n return `\n <div class=\"cn_card__subscriptionWrapper\">\n ${renderPrice(props)}\n ${subscriptionText(props)}\n ${buttonStyle(props)}\n </div>\n\n `\n}\n\nexport const subscriptionText = props => {\n const { subscription } = props\n const priceClass = 't-xs-500-sl'\n return `<p class=${priceClass}>${subscription.text}</p>`\n}\n\nexport const buttonStyle = props => {\n const {\n popin_id,\n view_details_label = 'View details',\n category_name = '',\n sku,\n longSku = '',\n position,\n button_style,\n button_text,\n tracking_position = '',\n tracking_list = '',\n button_url = '',\n campaign,\n tabbed_component\n } = props\n let buttonSize = 'large'\n const {\n id = '',\n name = '',\n position: campaign_position = '',\n creative = ''\n } = JSON.parse(campaign)\n\n if (button_style === 'link-page') {\n return `\n ${createButton({\n link_url: `${button_url}`,\n classList: 'cn_card__linkToPage',\n variation: 'primary',\n longSku,\n button_text,\n id,\n name,\n tracking_position,\n tracking_list,\n campaign_position,\n creative,\n tabbed_component,\n view_details_label\n })}\n `\n } else if (button_style === 'add-to-cart') {\n return `\n <nb-add-to-cart\n sku=\"${sku}\"\n longSku=\"${longSku}\"\n buttonSize=\"${buttonSize}\"\n showPrice\n range='${category_name}'\n position='${position}'\n ></nb-add-to-cart>\n `\n } else if (button_style === 'b2b-contact-form') {\n return `\n ${createButton({\n classList: 'cn_card__openContactForm',\n variation: 'tertiary',\n longSku,\n id,\n name,\n campaign_position,\n creative,\n tabbed_component,\n button_text,\n view_details_label\n })}\n `\n }\n\n const contentHtml = `<nb-machine-details data=\"${stringifyForAttribute(props)}\" />`\n\n const skuData = {\n internationalId: props.sku,\n internationalName: props.name,\n type: props.type,\n technology: props.technology,\n category: props.category,\n rawPrice: props.rawPrice\n }\n\n return `\n ${createButton({\n classList: 'cn_card__viewDetails',\n popin_id,\n longSku,\n tracking_list,\n tracking_position,\n variation: 'primary',\n id,\n name,\n campaign_position,\n creative,\n tabbed_component,\n button_text,\n view_details_label,\n skuData\n })}\n\n <nb-popin\n id=\"${popin_id}\"\n variation=\"before\"\n bgcolor=\"highlight\"\n size=\"L\"\n padding=\"false\"\n label_close=\"Close\"\n content=\"${escapeHtml(contentHtml)}\">\n </nb-popin>\n `\n}\n\nfunction createButton(options) {\n const {\n link_url,\n classList,\n popin_id,\n longSku,\n tracking_list,\n tracking_position,\n variation,\n id,\n name,\n campaign_position,\n creative,\n tabbed_component,\n button_text,\n view_details_label,\n skuData\n } = options\n\n return `\n <nb-cta\n ${link_url ? `link=\"${link_url}\"` : ''}\n class=\"${classList}\"\n ${popin_id ? `popin_id=\"${popin_id}\"` : ''}\n ${longSku ? `long_sku=\"${longSku}\"` : ''}\n ${tracking_list ? `tracking_list=\"${tracking_list}\"` : ''}\n ${tracking_position ? `tracking_position=\"${tracking_position}\"` : ''}\n variation=\"${variation}\"\n ${id ? `campaign_id=\"${id}\"` : ''}\n ${name ? `campaign_name=\"${name}\"` : ''}\n ${campaign_position ? `campaign_position=\"${campaign_position}\"` : ''}\n ${creative ? `campaign_creative=\"${creative}\"` : ''}\n ${tabbed_component ? `tabbed_component=\"${tabbed_component}\"` : ''}\n ${skuData ? `sku_data='${JSON.stringify(skuData)}'` : ''}\n >\n ${button_text || view_details_label}\n </nb-cta>\n `\n}\n","export const EVENT_COLOR_CLICKED = 'EVENT_COLOR_CLICKED'\n","import {\n ECAPI_TYPE_ACCESSORY,\n ECAPI_TYPE_CAPSULE,\n ECAPI_TYPE_GIFT_CARD,\n ECAPI_TYPE_MACHINE\n} from '@kissui/helpers/src/catalog'\n\nexport const getSkuComponentByType = ({ type, is_machine_b2b }) => {\n let result = 'nb-sku'\n\n if (type === ECAPI_TYPE_CAPSULE) {\n result = 'nb-sku-coffee'\n } else if (type === ECAPI_TYPE_MACHINE && is_machine_b2b) {\n result = 'nb-sku-machine-b2b'\n } else if (type === ECAPI_TYPE_MACHINE) {\n result = 'nb-sku-machine'\n } else if (type === ECAPI_TYPE_ACCESSORY) {\n result = 'nb-sku-accessory'\n } else if (type === ECAPI_TYPE_GIFT_CARD) {\n result = 'nb-sku-gift-card'\n }\n\n return result\n}\n\nexport const apiOverride = (productData, pageBuilderData) => {\n if (!productData || !pageBuilderData) {\n return {}\n }\n\n const { images, name, headline, description } = productData\n const { api_override } = pageBuilderData\n\n if (!api_override) {\n return {}\n }\n\n return {\n image: api_override.image || images?.icon || images?.url || images?.push || images?.main,\n name: api_override.name || name,\n headline: api_override.headline || headline,\n description: api_override.description || description\n }\n}\n","import '@kissui/components/src/card-labels'\nimport '@kissui/components/src/card-logos'\nimport '@kissui/components/src/energy-label'\nimport '@kissui/components/src/intensity'\n\nimport { setAttributes } from '@kissui/helpers/src/utils'\nimport createProps from '@kissui/helpers/src/props.helpers'\nimport viewportHelper from '@kissui/helpers/src/viewport.helpers'\nimport { renderLogos } from '@kissui/helpers/src/logos.helpers'\n\nimport renderAdditionalMessage from './fragments/additionalMessage'\nimport { openBundlePopin, renderBundlePopinLink } from './fragments/bundle'\n\nimport { renderEnergyLabel } from '@kissui/helpers/src/energy-label.helpers'\nimport { renderColors } from '@kissui/helpers/src/colors.helpers'\nimport { renderFeatures } from './fragments/features'\nimport { renderHeading } from './fragments/heading'\nimport renderHeadline from './fragments/headline'\n\nimport { renderIntensity } from '@kissui/helpers/src/intensity.helpers'\nimport renderLabelRange from './fragments/labelRange'\nimport { renderLabels } from './fragments/labels'\nimport renderLabelTechnology from './fragments/labelTechnology'\nimport { initLazyLoad } from './fragments/lazyLoad'\nimport { renderPriceWrapper } from './fragments/priceWrapper'\nimport { renderRatings } from './fragments/ratings'\nimport { setCardTheme } from './fragments/setCardTheme'\n\nimport './components/plp-product-card-image-slider'\nimport { renderHeader } from './fragments/header'\nimport { renderSubscription } from './fragments/subscription'\n\nimport { EVENT_COLOR_CLICKED } from '@kissui/components/src/colors/components/color/constants.mjs'\nimport { readEvent, dispatchEvent } from '@kissui/helpers/src/assets/js/eventDispatch'\nimport { getProduct, getPriceFormatter, getCurrency } from '@kissui/helpers/src/catalog'\n\nimport { handlePromoClick, productClick } from '@kissui/helpers/src/gtmEvents'\nimport {\n B2B_CONTACT_FORM_POPIN_ID,\n EVENT_POPIN_OPEN,\n B2B_CONTACT_FORM_POPIN_SRC_SKU_MAIN_INFO\n} from '@kissui/components'\n\nimport { apiOverride } from '@kissui/components/src/sku/services'\n\nclass PlpProductCard extends HTMLElement {\n async connectedCallback() {\n this.props = createProps(this.attributes)\n this.boundOnPDPLinkClick = this.onPDPLinkClick.bind(this)\n this.boundOnColorClick = this.onColorClick.bind(this)\n this.boundOpenPopin = this.onOpenPopin.bind(this)\n await this.render()\n initLazyLoad(this.props, this)\n }\n\n async render() {\n const {\n additional_message_icon,\n additional_message,\n category_name = '',\n giftcard_price,\n hide_header,\n image,\n intensity,\n label_technology,\n label_range,\n labels = [],\n plp_type,\n position,\n rating_enabled = false,\n show_ratings = false,\n sku,\n src_page,\n type,\n orientation,\n imwidth\n } = this.props\n\n if (type === 'giftcard' && !giftcard_price) {\n return null\n }\n if (hide_header || !image) {\n this.classList.add('hide-header')\n }\n\n if (labels.length) {\n this.classList.add('has-labels')\n }\n\n if (orientation === 'landscape') {\n this.classList.add('cn_card--landscape')\n }\n\n this.innerHTML = `\n ${renderHeader(this.props, viewportHelper, imwidth)}\n ${renderLabels(this.props)}\n ${renderLogos(this.props, this)}\n ${renderEnergyLabel(this.props)}\n <div class=\"cn_card__content\">\n ${renderLabelTechnology(label_technology)}\n ${renderLabelRange(label_range)}\n\n ${renderHeading(this.props, viewportHelper)}\n ${\n show_ratings && rating_enabled\n ? `<div class=\"cn_card__rating\"><nb-loader></nb-loader></div>`\n : ''\n }\n\n ${renderHeadline(this.props)}\n\n ${type === 'machine' ? renderColors(this.props, viewportHelper) : ''}\n ${type === 'machine' ? renderFeatures(this.props) : ''}\n\n ${type === 'capsule' ? renderBundlePopinLink(this.props, this) : ''}\n ${type === 'capsule' ? renderIntensity(intensity, this.props) : ''}\n\n ${await renderPriceWrapper(this.props)}\n\n ${type === 'machine' ? renderSubscription(this.props) : ''}\n\n ${renderAdditionalMessage(additional_message_icon, additional_message)}\n </div>\n `\n\n setAttributes(this, {\n 'data-product-item-id': sku,\n 'data-product-section': category_name,\n 'data-product-position': position,\n 'data-src-page': src_page,\n 'data-plp-type': plp_type\n })\n setCardTheme(this.props, this)\n this.bundlePopinLink = this.querySelector('.cn_card__cta__bundle button')\n\n this.classList.add('cn_card')\n this.bindEvent()\n\n if (show_ratings && rating_enabled) {\n renderRatings(this.props, this.querySelector('.cn_card__rating'))\n }\n }\n\n async onPDPLinkClick() {\n const productIndex = this.getAttribute('tracking_position') || 0\n await productClick(productIndex, this, this.props.longSku)\n }\n\n onColorClick(e) {\n const event = readEvent(e)\n if (!event.sku) {\n return\n }\n\n this.props.sku = event.sku\n\n this.template = '<nb-loader></nb-loader>'\n\n const newLabels = this.props.colors?.find(c => c.sku === this.props.sku)?.labels\n\n Promise.all([getPriceFormatter(), getProduct(this.props.sku)])\n .then(([formatter, payload]) => {\n if (!payload || !formatter) {\n return\n }\n\n const { name, legacyId, id, images, responsiveImages, price, pdpURLs } = payload\n\n this.props = {\n ...this.props,\n name,\n sku: legacyId || '',\n longSku: id || '',\n image: responsiveImages?.standard || images?.icon || '',\n image_alt_text: name || '',\n price: formatter.short(getCurrency(), price),\n activeSku: legacyId || '',\n url: pdpURLs?.desktop || '',\n labels: newLabels,\n ...apiOverride(payload, this.props)\n }\n\n this.render()\n })\n .catch(() => {\n console.error(`getProduct fail on sku ${this.props.sku}`)\n })\n }\n\n onOpenPopin() {\n const { button_text, campaign, name } = this.props\n handlePromoClick({ campaign, cta_name: `CTA - ${button_text}` })\n\n const skuArgs = {\n id: B2B_CONTACT_FORM_POPIN_ID,\n srcComponent: B2B_CONTACT_FORM_POPIN_SRC_SKU_MAIN_INFO,\n productName: name\n }\n\n dispatchEvent({ eventName: EVENT_POPIN_OPEN, args: skuArgs })\n }\n\n bindEvent() {\n this.linkElements = []\n this.unbindEvent()\n this.linkElements = this.querySelectorAll(`a[href]`)\n this.addEventListener(EVENT_COLOR_CLICKED, this.boundOnColorClick)\n if (this.linkElements.length) {\n Array.from(this.linkElements).forEach(linkElement => {\n linkElement.addEventListener('click', this.boundOnPDPLinkClick)\n })\n }\n if (this.bundlePopinLink) {\n this.boundBundlePopinLinkClick = openBundlePopin.bind(null, this)\n this.bundlePopinLink.addEventListener('click', this.boundBundlePopinLinkClick)\n }\n\n this.contactBtn = this.querySelector(`nb-cta.cn_card__openContactForm`)\n if (this.contactBtn) {\n this.contactBtn.addEventListener('click', this.boundOpenPopin)\n }\n }\n\n unbindEvent() {\n this.removeEventListener(EVENT_COLOR_CLICKED, this.boundOnColorClick)\n if (this.linkElements?.length) {\n Array.from(this.linkElements).forEach(linkElement => {\n linkElement.removeEventListener('click', this.boundOnPDPLinkClick)\n })\n this.linkElements = []\n }\n if (this.bundlePopinLink) {\n this.bundlePopinLink.removeEventListener('click', this.boundBundlePopinLinkClick)\n }\n if (this.contactBtn) {\n this.contactBtn.removeEventListener('click', this.boundOpenPopin)\n }\n }\n\n disconnectedCallback() {\n this.unbindEvent()\n }\n}\n\ncustomElements.get('nb-plp-product-card') ||\n customElements.define('nb-plp-product-card', PlpProductCard)\n\nexport default PlpProductCard\n","export default function renderLabelTechnology(label_technology) {\n return `${\n label_technology ? `<p class=\"cn_card__technology t-xs-700\">${label_technology}</p>` : ''\n }`\n}\n","import { stringifyForAttribute } from '@kissui/helpers/src/utils'\nimport viewportHelper from '@kissui/helpers/src/viewport.helpers'\n\nexport const renderLabels = ({ labels = [] }) => {\n if (labels.length === 0) {\n return ''\n }\n\n const data = stringifyForAttribute({ labels })\n\n return `<nb-card-labels data='${data}' direction=\"${\n viewportHelper.is.mobile ? 'row' : 'column'\n }\"></nb-card-labels>`\n}\n","import { stringifyForAttribute } from '@kissui/helpers/src/utils'\n\nexport const renderLogos = (props, component) => {\n const {\n fair_trade,\n alt_fair_trade,\n is_organic,\n alt_organic,\n only_vertuo_next,\n alt_vertuo_next,\n is_rainforest,\n alt_rainforest,\n is_sustainable,\n alt_sustainable,\n is_q_certified_arabica,\n alt_q_certification_arabica,\n logos\n } = props\n\n if (\n !fair_trade &&\n !is_organic &&\n !only_vertuo_next &&\n !is_rainforest &&\n !is_sustainable &&\n !is_q_certified_arabica &&\n (logos == null || logos.length < 1)\n ) {\n return ''\n }\n\n component.classList.add('has-logos')\n\n const data = {\n fair_trade,\n alt_fair_trade,\n is_organic,\n alt_organic,\n only_vertuo_next,\n alt_vertuo_next,\n is_rainforest,\n alt_rainforest,\n is_sustainable,\n alt_sustainable,\n is_q_certified_arabica,\n alt_q_certification_arabica,\n logos\n }\n return `<nb-card-logos data='${stringifyForAttribute(data)}'></nb-card-logos>`\n}\n","import { stringifyForAttribute } from '@kissui/helpers/src/utils'\n\nexport const renderEnergyLabel = props => {\n const { a11y_energy_label, energy_level } = props\n\n if (!energy_level) {\n return ''\n }\n\n const data = {\n a11y_label: a11y_energy_label,\n level: energy_level\n }\n\n return `<nb-energy-label data='${stringifyForAttribute(data)}'></nb-energy-label>`\n}\n","export default function renderLabelRange(label_range) {\n return `${label_range ? `<p class=\"cn_card__range t-xs-500\">${label_range}</p>` : ''}`\n}\n","import { SRC_PAGE_PDP } from '@kissui/components'\n\nexport const renderHeading = (\n { url, a11y_product_card = '', name = '', label_decaffeinato, src_page = '' },\n viewportHelper\n) => {\n const decaffeinatoRegExp = new RegExp(label_decaffeinato, 'ig')\n const hasDecaffeinato =\n label_decaffeinato && label_decaffeinato !== '' && decaffeinatoRegExp.test(name)\n\n a11y_product_card = a11y_product_card.replace('{productName}', name)\n\n if (hasDecaffeinato) {\n name = name.replace(decaffeinatoRegExp, '').trim()\n } else {\n label_decaffeinato = ''\n }\n\n const headingLevel = src_page === SRC_PAGE_PDP ? 'h1' : 'h3'\n\n return `${\n url\n ? `<${headingLevel} class='cn_card__title h-lg-700'><a href=\"${url}\" target=\"_self\" title=\"${a11y_product_card}\" aria-label=\"${a11y_product_card}\">`\n : `<${headingLevel} class='cn_card__title h-lg-700'>`\n }\n${name}\n${\n label_decaffeinato\n ? `<span class='${\n viewportHelper.is.mobile ? 't-xs-700-sl' : 't-md-700-sl'\n }'>${label_decaffeinato}</span>`\n : ''\n}\n${url ? `</a></${headingLevel}>` : `</${headingLevel}>`}`\n}\n","import viewportHelper from '@kissui/helpers/src/viewport.helpers'\n\nexport default function renderHeadline({ headline = '', is_headline_hidden = false }) {\n return `${\n headline === '' || (is_headline_hidden && viewportHelper.is.mobile)\n ? ''\n : `<p class=\"cn_card__text t-sm-400\">${headline}</p>`\n }`\n}\n","export const renderIntensity = (intensity, options) => {\n if (intensity === 0 || isNaN(parseInt(intensity))) {\n return ''\n }\n\n const { intensity_label = '', max_intensity, a11y_intensity_max = '' } = options\n\n return `<nb-intensity\n intensity=\"${intensity}\"\n ${max_intensity ? `max_intensity=\"${max_intensity}\"` : ''}\n a11y_intensity_max=\"${a11y_intensity_max}\"\n intensity_label=\"${intensity_label}\">\n </nb-intensity>`\n}\n","export default function renderAdditionalMessage(additional_message_icon, additional_message) {\n if (!additional_message) {\n return ''\n }\n return `<p class=\"cn_card__additionalMessage t-sm-500-sl\">\n <nb-icon\n icon=\"${additional_message_icon}\"\n class=\"additionalMsgIcon\"\n ></nb-icon> ${additional_message}</p>`\n}\n","import viewportHelper from '@kissui/helpers/src/viewport.helpers'\nimport { SRC_PAGE_PLP, PLP_TYPE_COFFEE } from '@kissui/components'\n\nexport const setCardTheme = (props, component) => {\n const { src_page, plp_type } = props\n if (src_page === SRC_PAGE_PLP) {\n if (plp_type === PLP_TYPE_COFFEE) {\n // PLP COFFEE\n viewportHelper.is.mobile\n ? component.setAttribute('theme', 'landscape')\n : component.setAttribute('theme', 'portrait')\n } else {\n // PLP MACHINE OR ACCESSORY\n component.setAttribute('theme', 'portrait')\n }\n } else {\n // PDP\n component.setAttribute('theme', 'pdp')\n }\n}\n","import createProps from '@kissui/helpers/src/props.helpers'\n\nclass PlpCategory extends HTMLElement {\n constructor() {\n super()\n this.slot = this.innerHTML\n }\n\n connectedCallback() {\n this.props = createProps(this.attributes)\n this.render()\n }\n\n render() {\n // todo: We need to understand why the plp category is rendered 3 times\n const {\n segments = 'false',\n background_retina = 'https://www.nespresso.com/shared_res/agility/next-components/assets/backgrounds/barista_creation_range_L.jpg',\n background_desktop = 'https://www.nespresso.com/shared_res/agility/next-components/assets/backgrounds/barista_creation_range_L.jpg',\n background_mobile = 'https://www.nespresso.com/shared_res/agility/next-components/assets/backgrounds/barista_creation_range_L.jpg',\n background_tablet = '',\n contrast = 'dark',\n name = '',\n description = '',\n cta_text = '',\n cta_link = ''\n } = this.props\n\n this.innerHTML = `\n <article class='cb-plp-category ${segments === 'true' ? 'wSegments' : 'woSegments'}'>\n <nb-container\n classname=\"cb-plp-category--header\"\n contrast='${contrast}'\n background_retina='${background_retina}'\n background_desktop='${background_desktop}'\n background_mobile='${background_mobile}'\n background_tablet='${background_tablet}'\n >\n <header>\n ${name ? this.renderHeading(name) : ''}\n <div class=\"cb-plp-category--description\">\n ${description && this.renderDescription(description)}\n ${cta_link && cta_text && this.renderCTA(cta_link, cta_text)}\n </divc>\n </header>\n </nb-container>\n <nb-container classname=\"cb-plp-category--coffees\" contrast='light'>\n ${segments === 'true' ? this.renderWithSegment() : this.renderWithoutSegment()}\n </nb-container>\n </article>\n `\n\n this.setDesktopSegmentMarginTop()\n }\n\n setDesktopSegmentMarginTop() {\n let headerHeight = 0\n let headingHeight = 0\n\n const header = this.querySelector('header')\n if (!header) {\n return\n }\n\n const headerComputedStyle = getComputedStyle(header)\n headerHeight = header.clientHeight - parseFloat(headerComputedStyle.paddingBottom)\n\n const heading = header.querySelector('h1')\n if (!heading) {\n return\n }\n\n const headingComputedStyle = getComputedStyle(heading)\n headingHeight = heading.clientHeight + parseFloat(headingComputedStyle.marginBottom)\n\n const target = header.closest('.cb-plp-category')\n const totalHeight = headerHeight - headingHeight\n\n target.style.setProperty('--woSegments-coffees-margin-top', '-' + totalHeight + 'px')\n }\n\n renderWithSegment() {\n return `${this.slot}`\n }\n\n renderWithoutSegment() {\n return `<div class=\"cb-plp-category--segment\">\n <div class='cb-plp-category--side'></div>\n <div class='cb-plp-category--center'>${this.slot}</div>\n </div>`\n }\n\n renderHeading(name) {\n return `<h2 class=\"h-2xl-700 cb-plp-category--title\">${name}</h2>`\n }\n\n renderDescription(description) {\n return `<p class=\"t-sm-400\">${description}</p>`\n }\n\n renderCTA(cta_link, cta_text) {\n const { contrast } = this.props\n return `<nb-link\n class=\"top-range-link\"\n color='${contrast === 'dark' ? 'white' : 'black'}'\n size='large'\n link='${cta_link}'\n seo_label=\"${cta_text}\"\n campaign_id=\"${this.props.campaign_id || ''}\"\n campaign_name=\"${this.props.campaign_name || ''}\"\n campaign_position=\"${this.props.campaign_position || ''}\"\n campaign_creative=\"${this.props.campaign_creative || ''}\"\n >${cta_text}</nb-link>`\n }\n}\n\ncustomElements.get('nb-plp-category') || customElements.define('nb-plp-category', PlpCategory)\n\nexport default PlpCategory\n","import { viewPromotion } from '@kissui/helpers/src/gtmEvents'\n\nexport default class {\n constructor(node, data) {\n this.observer = new IntersectionObserver(\n IntersectionObserverEntry => this.onChange(IntersectionObserverEntry),\n { threshold: [0], rootMargin: '0% 0%' }\n )\n\n this.el = node\n this.data = data\n\n if (!(this.el instanceof Element)) {\n return\n }\n\n this.observer.observe(this.el)\n }\n\n /**\n * Check if element are in the viewport\n * @param {Array} observables\n * @param {HTMLElement} observables.target\n * @param {Boolean} observables.isIntersecting\n */\n onChange(observables) {\n observables.forEach(observable => {\n if (!observable.isIntersecting) {\n return\n }\n\n this.track(observable)\n this.observer.unobserve(observable.target)\n })\n }\n\n track() {\n // This line is needed to make the code compatible with Safari <=13\n if ('requestIdleCallback' in window) {\n window.requestIdleCallback(() => this.runTrack())\n } else {\n window.setTimeout(() => this.runTrack(), 1)\n }\n }\n\n runTrack() {\n if (!this.data['id'] || this.data['id'] === null || this.data['id'] === '') {\n return\n }\n viewPromotion({ ...this.data })\n }\n}\n","import Viewport from './viewportTracking'\nimport { viewPromotion } from '@kissui/helpers/src/gtmEvents'\nimport { isObjectEmpty, removeEmptyValues } from '@kissui/helpers/src/utils'\n\nexport default function (node, campaign) {\n const tracking = new ZoneTracking(node, campaign)\n\n return {\n destroy: () => {\n if (!tracking.getIom().hasIntersectionObserver()) {\n tracking.destroy()\n }\n }\n }\n}\n\nclass ZoneTracking extends Viewport {\n constructor(node, data) {\n super(node)\n this.data = data\n }\n\n runTrack() {\n const cleanedData = removeEmptyValues(this.data)\n if (cleanedData && !isObjectEmpty(cleanedData)) {\n viewPromotion({ ...cleanedData })\n }\n }\n}\n","import { INTENSITY_MAX_OL, INTENSITY_MAX_VL } from '@kissui/components'\n\nexport const getMaxIntensity = ({ technologies }) =>\n technologies.indexOf('original') !== -1 ? INTENSITY_MAX_OL : INTENSITY_MAX_VL\n","import { getFinalPrice } from '@kissui/plp/services'\nimport { isBundled } from '@kissui/helpers/src/catalog'\nimport { getMaxIntensity } from '@kissui/components/src/sku-coffee/services'\n\nexport const getMergedProductCoffeeData = (\n product,\n pageBuilderProductProps,\n pageBuilderProps,\n priceFormatter,\n currency\n) => {\n const { bundle_details } = pageBuilderProductProps\n const { options } = pageBuilderProps\n const { show_sleeve_price } = options\n\n const isBundledResult = isBundled(product)\n\n const { showCapsulePrice, price_per_capsule, final_price } = getFinalPrice(\n show_sleeve_price,\n product,\n isBundled\n )\n\n const option = {\n bundled: isBundledResult,\n intensity: product.capsuleProperties?.intensity || product.intensity || null,\n max_intensity: getMaxIntensity(product),\n price_per_capsule: price_per_capsule\n ? priceFormatter.short(currency, price_per_capsule)\n : null,\n show_capsule_price: showCapsulePrice\n }\n\n if (show_sleeve_price) {\n option.price = priceFormatter.short(currency, final_price)\n }\n\n if (bundle_details) {\n option.bundle_details = bundle_details\n }\n\n return option\n}\n","import {\n getVertuoNext,\n getOrganicEu,\n getRainforest,\n getLabels,\n getProductHighlight,\n getFairTrade,\n getSustainability,\n isRange,\n getCategoryRegEx,\n RANGE_CATEGORY_NAME,\n getArabica\n} from '@kissui/helpers/src/cremaDataHelper'\n\n/**\n * Modifies the structure to make it easier to use in components\n * Applies all the data customization mixing Page builder with HMC data\n * @param {object} plpData : original PLP data\n */\nexport async function getMergedPLPData(plpData) {\n const { data } = plpData\n if (!data) {\n return []\n }\n\n const eCommerceData = data.configuration.eCommerceData\n\n addLabels(eCommerceData)\n\n addProductAttribute(\n eCommerceData,\n getFairTrade,\n (prod, category) => (prod.fairTrade = category.name)\n )\n addProductAttribute(eCommerceData, getProductHighlight, prod => (prod.highlighted = true))\n addProductAttribute(eCommerceData, getVertuoNext, prod => (prod.onlyVertuoNext = true))\n addProductAttribute(eCommerceData, getOrganicEu, prod => (prod.organicEu = true))\n addProductAttribute(eCommerceData, getRainforest, prod => (prod.rainforest = true))\n addProductAttribute(eCommerceData, getSustainability, prod => (prod.sustainability = true))\n addProductAttribute(eCommerceData, getArabica, prod => (prod.arabica = true))\n\n addSubSegments(eCommerceData)\n\n return eCommerceData.categories\n}\n\nfunction addSubSegments(eCommerceData) {\n const { categories, productGroups, products } = eCommerceData\n // should be forEach if nothing returned/assigned\n categories.forEach(category => {\n const hasSegment = category.subCategories.length > 0 && isRange(category)\n if (hasSegment) {\n category.segments = category.subCategories.map(categoryId => {\n const segment = categories.find(subCategory => subCategory.id === categoryId)\n if (segment && isSubsegment(categories, segment)) {\n segment.products = getProductsData(productGroups, segment.id, products)\n segment.isSegment = true\n }\n return segment\n })\n }\n\n category.products = getProductsData(productGroups, category.id, products)\n })\n}\n\nexport function getProductsData(productGroups, categoryId, products) {\n let result = []\n try {\n const currentCategory = productGroups.find(category => category.categoryId === categoryId)\n\n if (!currentCategory) {\n return result\n }\n\n const { productIds } = currentCategory\n return productIds.map(productId => {\n const product = products.find(product => product.id === productId)\n return product\n })\n } catch (e) {\n //generally an anti pattern to only log the error, with no try catch the result would be the same\n console.log(e)\n }\n\n return result\n}\n\n/**\n * adds labels property to products containing each label's category data (JSON parsed description property) assigned to it\n * labels are categories that have the label base category as parent\n * to apply a label on a given product, the label has to contain the product\n * this function has to clean the productGroups as well by removing the label ones\n * @param {category[]} categories\n * @param {productGroup[]} productGroups\n * @param {product[]} products\n */\nfunction addLabels(eCommerceData) {\n const { categories, productGroups, products } = eCommerceData\n const labels = getLabels(categories)\n const labelGroups = getLabelGroups(productGroups, labels)\n labelGroups.forEach(group => {\n const label = labels.find(label => label.id === group.categoryId)\n group.productIds.forEach(productId => {\n const prod = products.find(product => product.id === productId)\n prod.labels = prod.labels || []\n prod.labels.push(label.description)\n })\n })\n //removing label categories from productGroups\n labelGroups.forEach(labelGroup => {\n const indexToRemove = productGroups.findIndex(\n productGroup => productGroup.categoryId === labelGroup.categoryId\n )\n productGroups.splice(indexToRemove, 1)\n })\n}\n\n/**\n * adds a property to products containing the given category assigned to it\n * The category is recognized by ID\n * to apply a the category on a given product, the category's productGroup has to contain the product\n * this function has to clean the productGroups as well by removing the given's one to not let it display as a range in the PLP\n * @param {category[]} categories\n * @param {productGroup[]} productGroups\n * @param {product[]} products\n */\nfunction addProductAttribute(eCommerceData, categoryFetcher, assignHandler) {\n const { categories, productGroups, products } = eCommerceData\n const category = categoryFetcher(categories)\n if (!category) {\n return\n }\n const categoryGroup = getCategoryGroup(productGroups, category)\n if (!categoryGroup) {\n return\n }\n categoryGroup.productIds.forEach(productId => {\n const prod = products.find(product => product.id === productId)\n if (categoryFetcher === getArabica) {\n console.log('addProductAttribute', prod)\n }\n assignHandler(prod, category)\n })\n const indexToRemove = productGroups.findIndex(\n productGroup => productGroup.categoryId === categoryGroup.categoryId\n )\n productGroups.splice(indexToRemove, 1)\n}\n\n/**\n * retrieve all the productGroup that are labels\n * @param {productGroup[]} productGroups\n * @param {category[]} labels\n */\nfunction getLabelGroups(productGroups, labels) {\n return productGroups.filter(group => labels.some(label => label.id === group.categoryId))\n}\n\n/**\n * retrieve the productGroup which correspond to a category\n * @param {productGroup[]} productGroups\n * @param {category} fairTrade\n */\nfunction getCategoryGroup(productGroups, category) {\n return productGroups.find(group => category.id === group.categoryId)\n}\n\n/**\n * returns true when the category is child of the range category (is type range)\n * @param {category} category\n */\nexport function isSubsegment(categories, category) {\n /*category.superCategories.some(superCategoryId => {\n const superCategoryData = categories.find(categoryToFind => categoryToFind.id === superCategoryId)\n })*/\n const result = category.superCategories.some(superCategory =>\n getCategoryRegEx(RANGE_CATEGORY_NAME).test(superCategory)\n )\n return result\n}\nexport function getFinalPrice(show_sleeve_price, product, isBundled) {\n let showCapsulePrice = show_sleeve_price\n let final_price\n let price_per_capsule\n\n const bundled = isBundled(product)\n\n if (product.type === 'capsule' && !bundled) {\n final_price = product.price * product.salesMultiple\n // this isn't necessary in prod but the mock price formatter needs it\n final_price = Math.round(final_price * 100) / 100\n price_per_capsule = product.price\n } else {\n showCapsulePrice = false\n final_price = product.price\n }\n\n return { showCapsulePrice, final_price, price_per_capsule }\n}\n","const VOLTAGE_110 = '110'\nconst VOLTAGE_220 = '220'\n\nexport const getMergedProductMachineData = (product, pageBuilderProductProps, pageBuilderProps) => {\n const { strikethrough_price, variant } = pageBuilderProductProps\n const { show_voltage, voltage_label, a11y_voltage_label, voltage_list } = variant\n const { colorVariants, ratingsAndReviews } = product\n\n // lists header props not coming from this.props\n let options = {\n ratings: ratingsAndReviews\n }\n\n if (show_voltage) {\n const currentVoltage = getCurrentVoltage(product)\n const voltageData = getVoltageSwitcher(colorVariants, voltage_list, product)\n\n const colors = colorVariants\n .filter(productColor => productColor.name.indexOf(currentVoltage) > -1)\n .map(productColor => getColorModel(productColor))\n\n options = {\n ...options,\n colors,\n show_voltage,\n voltage_label,\n a11y_voltage_label,\n voltage_list: voltageData\n }\n }\n\n if (options.colors) {\n options.activeSku = product.internationalId\n options.colors = !options.colors\n ? colorVariants.map(productColor => getColorModel(productColor))\n : options.colors\n options.max_colors = 99\n }\n\n options.strikethrough_price = strikethrough_price || ''\n options.show_ratings = (pageBuilderProps && pageBuilderProps.options.show_ratings) || false\n options.minimum_rating = (pageBuilderProps && pageBuilderProps.options.minimum_rating) || 0\n\n return options\n}\n\nconst getCurrentVoltage = product =>\n product.name.indexOf(VOLTAGE_110) > -1 ? VOLTAGE_110 : VOLTAGE_220\n\nconst getColorModel = product => {\n return {\n category:\n product.colorCategories && product.colorCategories[0]\n ? product.colorCategories[0]\n : null,\n name: product.colorShade ? product.colorShade.name : null,\n code: product.colorShade ? product.colorShade.cssColorCode : null,\n sku: product.internationalId,\n link: product.url\n }\n}\n\n/**\n * Return an array with the url of the opposite voltage for the machine\n * https://dsu-confluence.nestle.biz/x/fKgaCQ\n * @param colorVariants - HMC Crema UI PDP Data\n * @param voltage_list - Page Builder\n * @param product - HMC Crema UI PDP Data Current product display\n * @returns {Array} voltages\n * @returns {String} voltages[].label - Label of voltage\n * @returns {String} voltages[].link - Empty if current voltage, or fill with the machine url of the opposite voltage\n */\nconst getVoltageSwitcher = (colorVariants, voltage_list, product) => {\n // From current voltage, get the same color for the opposite voltage\n const currentVoltage = getCurrentVoltage(product)\n const oppositeVoltages = voltage_list.filter(voltage => voltage.label !== currentVoltage)\n\n if (!oppositeVoltages || !oppositeVoltages.length) {\n return voltage_list\n }\n\n const oppositeVoltage = oppositeVoltages.pop().label\n\n // Find in machines same name with new voltage\n const oppositeVoltageMachineName = product.name.replace(currentVoltage, oppositeVoltage)\n const oppositeVariation = colorVariants.find(\n machine =>\n machine.name === oppositeVoltageMachineName &&\n product.colorShade.cssColorCode === machine.colorShade.cssColorCode\n )\n\n if (!oppositeVariation) {\n return voltage_list\n }\n\n const { url = '' } = oppositeVariation\n\n // Build final array, current voltage without link and opposite voltage with link\n return voltage_list.map(voltage => {\n if (voltage.label !== currentVoltage) {\n voltage.url = url\n voltage.selected = false\n } else {\n voltage.selected = true\n }\n\n return voltage\n })\n}\n","import { sanitizeString } from '@kissui/helpers/src/utils'\nimport { getMergedProductCoffeeData } from './product.coffee.dto'\nimport { getMergedProductMachineData } from './product.machine.dto'\nimport { VARIATION_PLP } from '@kissui/components/src/sku/constants'\nimport { getMergedProductGiftCardData } from './product.giftCard.dto'\nimport { getMergedProductAccessoryData } from './product.accessory.dto'\nimport { apiOverride } from '@kissui/components/src/sku/services'\nimport {\n ECAPI_TYPE_ACCESSORY,\n ECAPI_TYPE_CAPSULE,\n ECAPI_TYPE_GIFT_CARD,\n ECAPI_TYPE_MACHINE\n} from '@kissui/helpers/src/catalog'\n\nexport const getMergedProductData = (\n product,\n pageBuilderProductProps,\n pageBuilderProps,\n priceFormatter,\n currency\n) => {\n const { options } = pageBuilderProps\n const {\n variant,\n labels,\n strikethrough_price,\n additional_message,\n additional_message_icon,\n additional_message_link\n } = pageBuilderProductProps\n\n // lists header props not coming from this.props\n let data = {\n sku: product.internationalId,\n technologies: product.technologies,\n longSku: product.id,\n name: product.name,\n headline: sanitizeString(product.headline),\n sales_multiple: product.salesMultiple,\n unit_quantity: product.unitQuantity,\n type: product.type,\n category_name: product.rangeData?.name || '',\n label_range: product.rangeData?.name || '',\n price: product.price ? priceFormatter.short(currency, product.price) : null,\n strikethrough_price: strikethrough_price || '',\n variation: VARIATION_PLP,\n image_alt_text: product.name,\n image: product.images?.icon,\n url: product.pdpURLs?.desktop || '',\n additional_message: additional_message || '',\n additional_message_icon: additional_message_icon || '',\n additional_message_link: additional_message_link || {},\n ...apiOverride(product, pageBuilderProductProps)\n }\n\n if (labels && labels.length) {\n data.labels = labels\n }\n\n if (product.highlighted) {\n data.highlighted = product.highlighted\n }\n\n let dataTransformObjectProductType = {}\n if (product.type === ECAPI_TYPE_CAPSULE) {\n dataTransformObjectProductType = getMergedProductCoffeeData(\n product,\n pageBuilderProductProps,\n pageBuilderProps,\n priceFormatter,\n currency\n )\n } else if (product.type === ECAPI_TYPE_MACHINE) {\n dataTransformObjectProductType = getMergedProductMachineData(\n product,\n pageBuilderProductProps,\n pageBuilderProps\n )\n } else if (product.type === ECAPI_TYPE_ACCESSORY) {\n dataTransformObjectProductType = getMergedProductAccessoryData(\n product,\n pageBuilderProductProps,\n pageBuilderProps\n )\n } else if (product.type === ECAPI_TYPE_GIFT_CARD) {\n dataTransformObjectProductType = getMergedProductGiftCardData(\n product,\n pageBuilderProductProps,\n pageBuilderProps\n )\n }\n\n return {\n ...product,\n ...options,\n ...variant,\n ...data,\n ...dataTransformObjectProductType\n }\n}\n","export const getMergedProductAccessoryData = () => ({})\n","export const getMergedProductGiftCardData = (_, pageBuilderProductProps) => {\n const { variant } = pageBuilderProductProps\n\n return {\n image: variant && variant.default_image\n }\n}\n","import { getDataLayer } from '@kissui/helpers/src/dataLayer'\n\nexport async function setPDPDataProvider() {\n window.getPDPData = window.getPDPData || getPDPData\n}\n\nexport async function getPDPData() {\n return await window.pdpData\n}\n\nexport async function market() {\n return napi.market().read() // eslint-disable-line\n}\n\nexport function getCurrency() {\n return getDataLayer().currency\n}\n\nexport async function getPriceFormatter() {\n return napi.priceFormat() // eslint-disable-line\n}\n","import '@kissui/components/src/plp-product-card'\nimport './components/plp-category'\nimport createProps from '@kissui/helpers/src/props.helpers'\nimport zoneTracking from '@kissui/helpers/src/assets/js/zoneTracking'\nimport { getSkuComponentByType } from '@kissui/components/src/sku/services'\nimport { getMergedProductData } from './dataTransform'\nimport { getPriceFormatter, market } from '@kissui/pdp-data'\nimport { getProduct } from '@kissui/helpers/src/catalog'\n\nclass ProductGrid extends HTMLElement {\n // Fires when an instance of the element is created or updated\n constructor() {\n super()\n this.props = {}\n this.currency = null\n this.priceFormatter = null\n }\n\n // Fires when an instance was inserted into the document\n connectedCallback() {\n this.props = createProps(this.attributes)\n\n this.render()\n this.loadProducts().then()\n }\n\n async loadProducts() {\n const payloads = await Promise.all([market(), getPriceFormatter()])\n\n const [{ currency }, priceFormatter] = payloads\n this.currency = currency\n this.priceFormatter = priceFormatter\n await this.renderProducts()\n this.initTracking()\n }\n\n render() {\n const { layout = {} } = this.props\n\n this.innerHTML = `<div class=\"nb-product-grid ${layout.padding_top} ${\n layout.padding_bottom\n }\">${this.renderCategoryContainer()}</div>\n `\n this.productContainer = this.querySelector('.nb-pcg-grid')\n }\n\n renderCategoryContainer() {\n const { copywriting = {}, layout = { contrast: 'dark' }, campaign = {} } = this.props\n\n const { contrast, background = {} } = layout\n\n const { heading = '', description = '', link } = copywriting\n\n const linkName = (link && link.label) || '',\n linkUrl = (link && link.link) || '',\n linkSeoLabel = (link && link.seo_label) || linkName || ''\n\n return `<nb-plp-category\n name=\"${heading}\"\n description=\"${description}\"\n background_retina=\"${background.retina}\"\n background_desktop=\"${background.desktop}\"\n background_tablet=\"${background.tablet}\"\n background_mobile=\"${background.mobile}\"\n campaign_id=\"${campaign.id || ''}\"\n campaign_name=\"${campaign.name || ''}\"\n campaign_position=\"${campaign.position || ''}\"\n campaign_creative=\"${campaign.creative || ''}\"\n cta_text=\"${linkName}\"\n cta_link=\"${linkUrl}\"\n contrast=\"${contrast}\">\n <div class='nb-pcg-grid'></div>\n ${\n linkName && linkUrl\n ? `<nb-link link='${linkUrl}' size='large' color='gold' class='bottom-range-link' seo_label=\"${linkSeoLabel}\">${linkName}</nb-link>`\n : ''\n }\n </nb-plp-category>`\n }\n\n renderProducts() {\n const { copywriting = {} } = this.props\n const { heading = '' } = copywriting\n\n this.props.products.forEach(async (pageBuilderProduct, index) => {\n const product = await getProduct(pageBuilderProduct.sku).catch(() => {\n this.props.products.splice(this.props.products.indexOf(pageBuilderProduct.sku), 1)\n console.error(`getProduct fail on sku ${pageBuilderProduct.sku}`)\n })\n\n if (!product) {\n return\n }\n\n const mergedProductData = getMergedProductData(\n product,\n pageBuilderProduct,\n this.props,\n this.priceFormatter,\n this.currency\n )\n\n this.renderProductElement(mergedProductData, index, heading)\n })\n }\n\n renderProductElement(product, index, heading) {\n const tag = getSkuComponentByType(product) // sku-coffee\n const elementProduct = document.createElement(tag)\n\n elementProduct.setAttribute('data', JSON.stringify(product))\n elementProduct.setAttribute('tracking_list', heading)\n elementProduct.setAttribute('tracking_position', index + 1)\n const children = this.productContainer.children\n\n if (index > children.length - 1) {\n this.productContainer.appendChild(elementProduct)\n } else {\n this.productContainer.insertBefore(elementProduct, children[index])\n }\n }\n\n initTracking() {\n const { campaign = {} } = this.props\n\n zoneTracking(this, {\n id: campaign.id,\n name: campaign.name,\n position: campaign.position,\n creative: campaign.creative\n })\n }\n}\n\n// Registers custom element\ncustomElements.get('nb-product-grid') || customElements.define('nb-product-grid', ProductGrid)\n\nexport default ProductGrid\n"],"names":["createProps","attributes","data","find","attribute","nodeName","getData","props","filter","reduce","all","attr","nodeValue","isNil","JSON","parse","error","console","log","obj","CardLabels","HTMLElement","constructor","super","this","labels","connectedCallback","render","direction","classList","add","length","innerHTML","renderLabels","map","label","name","bgColor","color","join","customElements","get","define","getMarketCode","dataLayer","window","padlNamespace","app","market","toLocaleLowerCase","COMMON_URL","ORGANIC_LOGO_IMG_EU","ORGANIC_LOGO_IMG_US","ORGANIC_LOGO_IMG_CA","ORGANIC_LOGO_IMG_BR","ORGANIC_LOGO_IMG_JP","ORGANIC_LOGO_IMG_BE","VERTUONEXT_LOGO_IMG","RAINFOREST_LOGO_IMG","SUSTAINABILITY_LOGO_IMG","Q_CERTIFICATION_ARABICA_LOGO_IMG","DESIGN_AWARD_2021_IMG","LOGO_IMG_MAP","fair_trade","is_organic","organicLogoImg","getOrganicLogo","only_vertuo_next","is_q_certified_arabica","is_rainforest","is_sustainable","is_design_award_2021","CardLogos","alt_fair_trade","alt_organic","alt_vertuo_next","alt_rainforest","alt_sustainable","alt_q_certification_arabica","logos","logos_list","undefined","forEach","param","appendLogo","apply","logo","alt","list","hasLogo","push","logosList","logoName","some","EnergyLabel","level","levelPlus","a11y_label","Intensity","intensity_label","a11y_intensity_max","max_intensity","intensity","parseInt","isNaN","a11yIntensityMax","replace","renderIntensityMin","renderIntensityMax","Array","Math","max","min_intensity","fill","min","removeEmptyValues","findText","key","value","text","includes","lazyLoad","node","url","inViewPort","setAttribute","cb","img","Image","src","onload","onerror","Error","test","navigator","userAgent","agent","start","indexOf","Number","substr","lazyBackgroundObserver","IntersectionObserver","entries","entry","isIntersecting","unobserve","target","observe","isOldIOS","interpolate","txt","vars","stChr","enChr","curIdx","stIdx","enIdx","hashId","substring","stringifyForAttribute","escapeHtml","stringify","m","DOMParser","sanitizeString","toString","setAttributes","element","attrs","BREAKPOINT_TABLET","EVENT_POPIN_OPEN","helper","is","innerWidth","vw","devicePixelRatio","mobile","mobile_tablet","tablet","desktop","retina","lt","ref","dispatchEvent","eventName","args","event","CustomEvent","detail","bubbles","Event","document","createEvent","initEvent","bundlePopinID","label_close","bundlePopinContent","openBundlePopin","component","renderPopinBundleDetail","bundlePopIn","getElementById","appendChild","variation","bgcolor","size","padding","content","id","popin","createElement","DISPLAY_COLOR_MAX","renderFeature","icon","heading","description","desc","classname","renderPrice","price","giftcard_price","type","hidePrice","subscription","from","custom_price","getCurrency","config","padl","namespace","currency","ECAPI_TYPE_CAPSULE","ECAPI_TYPE_MACHINE","ECAPI_TYPE_ACCESSORY","ECAPI_TYPE_GIFT_CARD","getPriceFormatter","async","napi","priceFormat","getProduct","sku","catalog","trimSku","isBundled","productData","sales_multiple","salesMultiple","isSalesMultipleGreaterThanOne","isUnitQuantityEqualToOne","unitQuantity","isSalesMultipleEqualToOne","isUnitQuantityGreaterThanOne","renderStrikethroughPrice","strikethroughPrice","priceFormatter","html","short","getFormattedPrice","renderShowSleeve","label_sleeve","label_sleeves","show_sleeve","sleeve_syntax","number_of_sleeves","label_capsules","bundled","unit_quantity","numberOfSleeves","sleeveLabel","quantity","labelContent","renderPriceWrapper","in_stock","strikethrough_price","hide_add_to_cart","showOutOfStock","show_capsule_price","price_per_capsule","capsule_price_label","capsule_price_syntax","renderCapsulePrice","renderA11yPrice","a11y_price","a11y_capsule_price","sleeve_variation_pdp","label_outofstock","shop_similar","renderOutOfStock","category_name","longSku","position","quantity_selector","view_details_label","buttonSize","viewportHelper","add_to_cart","renderAddToCart","hidden","bulletActive","CarouselTouchPlugin","carousel","_carousel","_container","addEventListener","e","preventDefault","startDrag","passive","drag","endDrag","translateFactor","touches","_origin","x","screenX","y","screenY","_width","containerWidth","point","translate","_lastTranslate","translateDelta","_currentIndex","_widthSlide","preventMobileYTranslate","abs","stopPropagation","dragDelta","carouselWidth","slideDirection","goToItem","CarouselCreamUiHack","MutationObserver","mutations","mutation","oldValue","oldState","contains","newState","body","attributeFilter","attributeOldValue","Carousel","options","_element","_slides","slice","call","children","_index","index","_options","Object","assign","slidesToScroll","slidesVisible","spaceBetween","navigationButton","loop","navigationAsSlider","pagination","hookGetRightBoundary","hookSlideChange","hookMove","hookNext","hookPrevious","pagination_variation","nav_centered","moveCallbacks","_ratio","buildIHM","hasPagination","slidesTotal","navigationVariation","navigation_variation","navigationSize","navigation_size","offsetWidth","_root","wrapperWidth","_wrapper","paginationVariation","getSlideWidth","_children","child","setWrapperStyle","createNavigation","createPagination","widthSlide","widthContainer","setContainerWidth","setWrapperWidth","slide","setSlideWidth","_widthContainer","_widthWrapper","style","width","marginRight","disableTransition","transition","enableTransition","delta","left","tag","className","div","sliderWidth","prevButton","createNavigationButton","nextButton","addNavigationListeners","mainContainer","parentElement","onMove","remove","button","next","prev","getSlideNotVisible","createPaginationBullets","paginationBullets","buttons","i","span","innerText","selectButton","activeButton","createPaginationStepper","paginationStepper","spanTotal","slash","spanCurrent","info","hackUi","incomingIndex","getOverflowingIndex","translateX","indexHasChange","$html","querySelector","reachedLeftBoundary","getLeftBoundary","reachedRightBoundary","getRightBoundary","lastIndex","overflowingIndex","incomingSlideIndex","currentIndex","existingSlide","goingToNextSlide","boundaryReached","_getMaxSlideWidth","slides","onSlideChange","activateItems","t","item","video","pause","play","setClass","unsetClass","emitCustomEvent","customEvent","cancelable","composed","raisedByPB","viewPromotion","eventData","event_raised_by","ecommerce","keys","creative","ecommerceData","promotion_id","promotion_name","creative_slot","creative_name","gtmDataObject","selectPromotion","cta_name","productClick","productInfo","product","getProductInfo","productPayload","getProductPayload","actionField","internationalName","internationalId","category","unitPrice","legacyId","technologies","inStock","technology","split","pop","dimension44","toLowerCase","dimension53","dimension54","dimension55","dimension56","dimension57","dimension192","brand","eventAction","currencyCode","eventRaisedBy","click","products","Slider","_slider","randomId","observedAttributes","slot","testId","result","characters","charAt","floor","random","makeId","loadSlider","navigation_as_slider","indexSlider","slides_loop","slides_visible","slides_to_scroll","navigation","space_between","el","CarouselLib","handleClick","bind","slideIndex","toggleClasses","itemTypes","itemDisplay","rootElement","isFirst","isLast","PlpProductCardImageSlider","image_alt_text","nbSlider","nbLoader","image","renderHeader","show_slider","plp_type","imwidth","hasSliderActivated","imgUrl","renderImage","renderImageOrSlider","subscriptionText","buttonStyle","popin_id","button_style","button_text","tracking_position","tracking_list","button_url","campaign","tabbed_component","campaign_position","createButton","link_url","contentHtml","skuData","rawPrice","EVENT_COLOR_CLICKED","apiOverride","pageBuilderData","images","headline","api_override","main","PlpProductCard","boundOnPDPLinkClick","onPDPLinkClick","boundOnColorClick","onColorClick","boundOpenPopin","onOpenPopin","initLazyLoad","getWidth","getAttribute","imPolicy","additional_message_icon","additional_message","hide_header","label_technology","label_range","rating_enabled","show_ratings","src_page","orientation","renderLogos","a11y_energy_label","energy_level","renderEnergyLabel","renderLabelRange","renderHeading","a11y_product_card","label_decaffeinato","decaffeinatoRegExp","RegExp","hasDecaffeinato","trim","headingLevel","is_headline_hidden","renderHeadline","colors","max_colors","a11y_extra_color","activeSku","extra_url","extra_title","renderColors","features","renderFeatures","renderBundlePopinLink","bundle_details","range","popin_link_text","other_skus","other_skus_quantity","popin_label_close","renderIntensity","renderSubscription","renderAdditionalMessage","setCardTheme","bundlePopinLink","bindEvent","renderRatings","minimum_rating","refElement","ratings","summary","then","ratingsResult","ratingAverage","stars","parseFloat","toFixed","ratingData","elem","replaceWith","productIndex","readEvent","template","newLabels","c","Promise","formatter","payload","responsiveImages","pdpURLs","standard","catch","cleanedData","handlePromoClick","srcComponent","productName","linkElements","unbindEvent","querySelectorAll","linkElement","boundBundlePopinLinkClick","contactBtn","removeEventListener","disconnectedCallback","PlpCategory","segments","background_retina","background_desktop","background_mobile","background_tablet","contrast","cta_text","cta_link","renderDescription","renderCTA","renderWithSegment","renderWithoutSegment","setDesktopSegmentMarginTop","headerHeight","headingHeight","header","headerComputedStyle","getComputedStyle","clientHeight","paddingBottom","headingComputedStyle","marginBottom","totalHeight","closest","setProperty","campaign_id","campaign_name","campaign_creative","Viewport","observer","IntersectionObserverEntry","onChange","threshold","rootMargin","Element","observables","observable","track","requestIdleCallback","runTrack","setTimeout","ZoneTracking","isObjectEmpty","getMaxIntensity","INTENSITY_MAX_OL","getMergedProductCoffeeData","pageBuilderProductProps","pageBuilderProps","show_sleeve_price","isBundledResult","showCapsulePrice","final_price","round","getFinalPrice","option","capsuleProperties","getCurrentVoltage","VOLTAGE_110","getColorModel","colorCategories","colorShade","code","cssColorCode","link","getVoltageSwitcher","colorVariants","voltage_list","currentVoltage","oppositeVoltages","voltage","oppositeVoltage","oppositeVoltageMachineName","oppositeVariation","machine","selected","getMergedProductData","variant","additional_message_link","rangeData","highlighted","dataTransformObjectProductType","getMergedProductMachineData","show_voltage","voltage_label","a11y_voltage_label","ratingsAndReviews","voltageData","productColor","getMergedProductGiftCardData","_","default_image","read","ProductGrid","loadProducts","payloads","renderProducts","initTracking","layout","padding_top","padding_bottom","renderCategoryContainer","productContainer","copywriting","background","linkName","linkUrl","linkSeoLabel","seo_label","pageBuilderProduct","splice","mergedProductData","renderProductElement","getSkuComponentByType","is_machine_b2b","elementProduct","insertBefore","tracking","zoneTracking"],"mappings":"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"}