{"version":3,"file":"default/js/productDetail.js","mappings":"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","sources":["webpack://vodafoneziggo/webpack/runtime/chunk loaded","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/Animation.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/ConfirmationModal.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/VZSpinner.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/form/form.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/modal.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/VZAlert.js","webpack://vodafoneziggo/./node_modules/clsx/dist/clsx.m.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/modals/modalHelper.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/modals/VZModal.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/idType.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/form/masks/caps.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/form/masks/postcode.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/form/masks/iban.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/form/masks/date.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/form/mask.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/preventCharacters.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/readonly.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/index.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/documentNumber.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/mask.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/password.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/regex.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/valid.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/form/VZInputField.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/postcode_check/postcodeCheckHelpers.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/postcode_check/AddressCheck.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/util/cookies.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/postcode_check/VZPostcodeCheck.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/prompt.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/journey/journeyHelper.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/journey/VZJourney.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/journey/VZJourneyModal.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/add/VZAddBase.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/util/domUtils.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/add/VZAddDevice.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/util/transitions.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/add/VZAddGroup.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/add/VZAddLocation.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/add/VZAddOneNet.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/VZHardware.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/VZSorting.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/VZRangeSlider.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/VZPriceBalanceSlider.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/VZDeleteGroup.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/VZFilter.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/VZGroupSummary.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/Alert.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/VZQuantitySelector.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/VZVariationAttribute.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/VZPorting.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/VZProductCard.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/product/components/sidebar.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/util/constants.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/util/urlUtils.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/util/util.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/util/validation.js","webpack://vodafoneziggo/webpack/bootstrap","webpack://vodafoneziggo/webpack/runtime/amd options","webpack://vodafoneziggo/webpack/runtime/compat get default export","webpack://vodafoneziggo/webpack/runtime/define property getters","webpack://vodafoneziggo/webpack/runtime/global","webpack://vodafoneziggo/webpack/runtime/hasOwnProperty shorthand","webpack://vodafoneziggo/webpack/runtime/runtimeId","webpack://vodafoneziggo/webpack/runtime/jsonp chunk loading","webpack://vodafoneziggo/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","export default class Animation {\n /**\n * Shakes the element and removes the class at the end of the animation.\n *\n * @function shake\n * @param {Element} element - The element.\n * @returns {void}\n */\n static shakeSubtle(element) {\n element.classList.add('shake-subtle');\n element.addEventListener(\n 'animationend',\n () => {\n element.classList.remove('shake-subtle');\n },\n { once: true }\n );\n }\n}\n","export default class VZConfirmationModal {\n constructor() {\n if (window.bs && window.bs.Modal) {\n this.confirmationModal = new window.bs.Modal(document.getElementById('confirmation-modal'));\n }\n\n this.toggleConfirmationModal = this.toggleConfirmationModal.bind(this);\n }\n\n toggleConfirmationModal() {\n if (!this.confirmationModal) {\n return Promise.reject(new Error('Confirmation modal is not initialized.'));\n }\n\n this.confirmationModal.show();\n\n return new Promise((resolve) => {\n const handleCancel = () => {\n cleanup(); // eslint-disable-line no-use-before-define\n resolve(false);\n };\n\n const handleConfirm = () => {\n cleanup(); // eslint-disable-line no-use-before-define\n resolve(true);\n };\n\n const cleanup = () => {\n this.confirmationModal._element.querySelector('.js-confirmation-modal-cancel').removeEventListener('click', handleCancel); // eslint-disable-line no-underscore-dangle\n this.confirmationModal._element.querySelector('.js-confirmation-modal-confirm').removeEventListener('click', handleConfirm); // eslint-disable-line no-underscore-dangle\n };\n\n this.confirmationModal._element.querySelector('.js-confirmation-modal-cancel').addEventListener('click', handleCancel); // eslint-disable-line no-underscore-dangle\n this.confirmationModal._element.querySelector('.js-confirmation-modal-confirm').addEventListener('click', handleConfirm); // eslint-disable-line no-underscore-dangle\n });\n }\n}\n","'use strict';\n\nimport Lottie from 'lottie-web/build/player/lottie_light.min';\nconst redSpinnerData = require('./spinners/spinner_animation_min.json');\n\n/**\n * @class VZSpinner\n * @param {HTMLElement} [parent] - Parent element for the spinner to be added in.\n * @description\n * Creates a VZ-Spinner component\n *\n * @example\n * \n *
\n *
\n *
\n *
\n */\nclass VZSpinner extends HTMLElement {\n constructor(parentEl) {\n super();\n\n this.showing = false;\n this.stop = this.stop.bind(this);\n this.veil = null;\n\n const parentElement = parentEl || document.body;\n const location = parentElement.tagName === 'IMG' ? parentElement.parentElement : parentElement;\n location.appendChild(this);\n\n this.lottie = Lottie.loadAnimation({\n container: this.veil.querySelector('.spinner'),\n renderer: 'svg',\n loop: true,\n autoplay: false,\n animationData: redSpinnerData\n });\n }\n\n /**\n * @public\n * @param {string} [msg] - A message to be shown below the spinner.\n * @returns {Promise} promise\n */\n start(msg) {\n return new Promise((resolve) => {\n if (this.showing) resolve();\n const parentPosition = window.getComputedStyle(this.parentElement).getPropertyValue('position');\n\n if (parentPosition === 'static') {\n if (this.parentElement.tagName !== 'BODY') {\n this.parentElement.style.position = 'relative';\n }\n this.parentElement.classList.add('veiled');\n }\n\n if (msg) {\n this.veil.insertAdjacentHTML('beforeend', `
${msg}
`);\n }\n\n this.showing = true;\n setTimeout(() => {\n if (this.showing) {\n this.lottie?.play();\n this.veil.classList.add('show');\n }\n resolve();\n }, 500);\n });\n }\n\n /**\n * @public\n * @returns {Promise} promise\n */\n stop() {\n return new Promise((resolve) => {\n if (!this.showing) resolve();\n if (this.parentElement.classList.contains('veiled')) {\n this.parentElement.style.position = '';\n this.parentElement.classList.remove('veiled');\n }\n\n const content = this.veil.querySelector('.content');\n if (content) content.remove();\n this.veil.classList.remove('show');\n this.showing = false;\n this.lottie?.stop();\n resolve();\n });\n }\n\n connectedCallback() {\n this.innerHTML = `\n
\n
\n
\n
\n `;\n\n this.veil = this.querySelector('.veil');\n this.veil.addEventListener('click', (evt) => evt.stopPropagation());\n }\n}\n\nwindow.VZSpinner = window.customElements.get('vz-spinner') || VZSpinner;\nexport default window.VZSpinner;\n\nif (!window.customElements.get('vz-spinner')) {\n window.customElements.define('vz-spinner', VZSpinner);\n}\n","'use strict';\n\n/**\n * @public prepareFormValues\n * @param {HTMLElement} app - The app component\n *\n * @description\n * Sets the value of an input field as a property. By doing this, a previous\n * selection can be preselected when navigating back in the product configurator.\n */\nexport function prepareFormValues(app) {\n const valueTypes = ['text', 'hidden', 'range', 'email', 'number', 'tel', 'password'];\n [...app.querySelectorAll('input')].forEach((field) => {\n if (valueTypes.indexOf(field.type) !== -1) {\n field.setAttribute('value', field.value);\n } else if (field.type === 'radio' || field.type === 'checkbox') {\n if (field.checked) {\n field.setAttribute('checked', true);\n } else {\n field.removeAttribute('checked');\n }\n }\n });\n}\n\n/**\n * @public getFieldValidationMessage\n * @param {HTMLInputElement | HTMLSelectElement} field - Invalid field element\n * @returns {string | false} - Error message for invalid field\n */\nexport function getFieldValidationMessage(field) {\n // Valid\n if (field.validity.valid) return false;\n\n // Required\n if (field.required && field.value.length === 0) return field.getAttribute('data-missing-error');\n\n // Checked\n if (!field.checked && (field.matches('[type=\"checkbox\"]') || field.matches('[type=\"radio\"]'))) return field.getAttribute('data-missing-error');\n\n // Regex\n if (field.pattern && !new RegExp(field.pattern).test(field.value)) return field.getAttribute('data-pattern-error');\n\n // Dates\n if (field.dataset.mask === 'date' && field.dataset.invalid === 'true') return field.getAttribute('data-invalid-error');\n if (field.dataset.mask === 'date' && field.dataset.invalidMin === 'true') return field.getAttribute('data-mindate-error');\n if (field.dataset.mask === 'date' && field.dataset.invalidMax === 'true') return field.getAttribute('data-maxdate-error');\n if (field.dataset.mask === 'addition' && field.dataset.multipleAdditions === 'true') return field.getAttribute('data-missing-error');\n\n // No valid error messages\n return false;\n}\n","import { CONST } from 'Util/util';\nimport { validateForm, validateField } from 'app_vodafone_ziggo/util/validation';\nimport Modal from 'bootstrap/js/src/modal';\nimport VZSpinner from 'Components/VZSpinner';\nimport { appendCsrfToUrl } from 'app_vodafone_ziggo/util/urlUtils';\n\nwindow.bs = window.bs || {};\nwindow.bs.Modal = Modal;\n\nconst spinner = document.querySelector('vz-spinner') || new VZSpinner();\n\nconst selectors = {\n errorModal: 'error-modal',\n activeModal: '.modal.show',\n modalStepContainer: '.js-modal-step-container',\n modalStep: '.js-modal-step',\n modalStepInputs: '.form-control, .custom-control'\n};\n\n/**\n * @function showErrorModal\n * @param {string|null} title - The title of the modal\n * @param {string|null} body - The error message within the modal\n * @param {string|null} cta - The cta text within the modal\n */\nfunction showErrorModal(title, body, cta) {\n const errorModalHtml = `\n
\n
\n
\n
\n

${title}

\n \n
\n\n
\n
\n
${body}
\n
\n
\n\n \n
\n \n
\n
\n
\n
`;\n\n const existingModal = document.getElementById(selectors.errorModal);\n\n if (existingModal) {\n window.bs.Modal.getInstance(existingModal).show();\n } else {\n document.body.insertAdjacentHTML('beforeend', errorModalHtml);\n const modal = new window.bs.Modal(document.getElementById(selectors.errorModal));\n modal.show();\n window.addEventListener(CONST.events.popstate, () => {\n modal.hide();\n });\n }\n}\n\n/**\n * @public resetModalState\n * @param {HTMLElement} modal - A DOM modal element\n *\n * In case of a modal that has multiple steps\n * Loop over the steps to remove the active class\n * and add the active class to the first step\n */\nfunction resetModalState(modal) {\n [...modal.querySelectorAll(selectors.modalStep)].forEach((step, index) => {\n if (index === 0) {\n step.classList.add(CONST.classes.active);\n } else {\n step.classList.remove(CONST.classes.active);\n }\n });\n}\n\n/**\n * @public createModalByUrl\n * @param {string} targetId - The id of the target modal\n * @param {string} targetEndpoint - The url to call which should return the modal html\n * @returns {Promise} - Promise\n *\n * @description\n * Will create/show a modal based on a URL to a pipeline.\n * That pipeline should return a template with the modal HTML for more creative freedom\n */\nfunction createModalByUrl(targetId, targetEndpoint) {\n const modalId = `modal-${targetId}`;\n const existingModal = document.getElementById(modalId);\n\n if (existingModal) {\n return new Promise((resolve) => {\n resetModalState(existingModal);\n window.bs.Modal.getInstance(existingModal).show();\n resolve(existingModal);\n });\n }\n\n spinner.start();\n return fetch(targetEndpoint)\n .then((res) => {\n if (res.status === 500) throw new Error('Fetch failed');\n return res.text();\n })\n .then((response) => {\n document.body.insertAdjacentHTML('beforeend', response);\n\n const modalElement = document.getElementById(modalId);\n const modal = new window.bs.Modal(modalElement);\n\n new ModalClass(modal); // eslint-disable-line\n modal.show();\n document.dispatchEvent(new CustomEvent('custom_modal:shown'));\n return modalElement;\n })\n .catch((response) => {\n console.error('error', response);\n return response;\n })\n .finally(spinner.stop);\n}\n\n/**\n * @class ModalClass\n */\nclass ModalClass {\n constructor(modalInstance) {\n this.modal = modalInstance._element; // eslint-disable-line no-underscore-dangle\n this.modalActiveStep = this.modal.querySelector(`${selectors.modalStep}.${CONST.classes.active}`);\n this.modalFields = [...this.modal.querySelectorAll(selectors.modalStepInputs)];\n\n this.validateModalField = this.validateModalField.bind(this);\n this.submitStepForm = this.submitStepForm.bind(this);\n this.appendModalStep = this.appendModalStep.bind(this);\n\n this.modalFields.forEach((field) => {\n field.addEventListener(CONST.events.blur, (event) => {\n this.lastFocussedField = event.target;\n });\n\n field.addEventListener(CONST.events.keyUp, this.validateModalField);\n field.addEventListener(CONST.events.change, this.validateModalField);\n });\n\n this.modalActiveStep.addEventListener(CONST.events.submit, this.submitStepForm);\n\n const customEvent = new CustomEvent('modalLoaded', {\n detail: {\n modal: this.modal\n }\n });\n document.dispatchEvent(customEvent);\n }\n\n /**\n * @method validateModalField\n * @param {event} event - The submit event\n */\n validateModalField(event) {\n // If we're using tab, make sure to validate the previous field instead of the new field\n if (this.lastFocussedField && event.key && event.key.toLowerCase() === 'tab') {\n validateField(this.lastFocussedField);\n this.lastFocussedField = event.target;\n } else {\n const currField = event.target;\n this.lastFocussedField = currField;\n validateField(currField);\n }\n }\n\n /**\n * @method submitStepForm\n * @param {event} event - The submit event\n */\n submitStepForm(event) {\n event.preventDefault();\n const form = event.target;\n\n const validForm = validateForm(form);\n if (!validForm) {\n return;\n }\n\n const endpoint = form.getAttribute('action');\n const formData = new FormData(form);\n const csrfName = form && form.getAttribute(CONST.attributes.csrfName);\n const csrfToken = form && form.getAttribute(CONST.attributes.csrfToken);\n formData.append(csrfName, csrfToken);\n\n /* eslint-disable no-underscore-dangle */\n if (window._dd && window._dd.user && window._dd.user.ids && window._dd.user.ids.ga_id) {\n formData.append('gaId', window._dd.user.ids.ga_id);\n }\n /* eslint-enable no-underscore-dangle */\n\n spinner.start();\n\n fetch(endpoint, {\n method: 'POST',\n body: formData\n })\n .then((res) => res.text())\n .then(this.appendModalStep)\n .catch((error) => {\n console.error('submitStepForm error', error);\n })\n .finally(spinner.stop);\n }\n\n /**\n * @method scrollToTop\n */\n static scrollToTop() {\n const activeModal = document.querySelector(selectors.activeModal);\n const supportsNativeSmoothScroll = 'scrollBehavior' in document.documentElement.style;\n if (supportsNativeSmoothScroll) {\n activeModal.scrollTo({\n top: 0,\n left: 0,\n behavior: 'smooth'\n });\n } else {\n activeModal.scrollTop = 0;\n }\n }\n\n /**\n * @method appendModalStep\n * @param {string} response - The response containing the next step\n */\n appendModalStep(response) {\n const modalStepContainer = document.querySelector(`${selectors.activeModal} ${selectors.modalStepContainer}`);\n const currentStep = modalStepContainer.querySelector(`${selectors.modalStep}.${CONST.classes.active}`);\n\n currentStep.classList.remove(CONST.classes.active);\n modalStepContainer.insertAdjacentHTML('beforeend', response);\n\n const newStep = modalStepContainer.querySelector(`${selectors.modalStep}:last-child`);\n newStep.classList.add(CONST.classes.active);\n\n this.constructor.scrollToTop();\n\n const customEvent = new CustomEvent('modalStep', {\n detail: {\n currentStep: currentStep,\n newStep: newStep\n }\n });\n document.dispatchEvent(customEvent);\n }\n}\n\n/**\n * @function refreshToken\n * @description Calls an endpoint to execute authorization when the Business Scan contact me modals are opened - BO-1488.\n */\nfunction refreshToken() {\n const container = document.querySelector('[data-refresh-token-url]');\n const { refreshTokenUrl } = container.dataset;\n if (!refreshTokenUrl) return;\n\n const endpoint = appendCsrfToUrl(refreshTokenUrl);\n\n fetch(endpoint);\n}\n\nexport { showErrorModal, createModalByUrl, refreshToken };\n","'use strict';\n\nimport Alert from 'bootstrap/js/src/alert';\n\n/**\n * @example\n * \n */\nclass VZAlert extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.removeAlert = this.removeAlert.bind(this);\n this.showAlert = this.showAlert.bind(this);\n\n this.hasCookie().then(this.showAlert).catch(this.removeAlert);\n\n this.addEventListener('close.bs.alert', this.onClose.bind(this));\n }\n\n disconnectedCallback() {\n this.addEventListener('close.bs.alert', this.onClose);\n }\n\n hasCookie() {\n const name = `${this.getAttribute('name')}=`;\n return new Promise((resolve, reject) => {\n const cookies = document.cookie.split(';');\n return !cookies.find((cookie) => cookie.indexOf(name) !== -1) ? resolve() : reject(); // eslint-disable-line no-promise-executor-return\n });\n }\n\n onClose() {\n const expirationDate = new Date();\n expirationDate.setTime(expirationDate.getTime() + 365 * 24 * 60 * 60 * 1000);\n\n const cookieString = `${this.getAttribute('name')}=true; expires=${expirationDate.toGMTString()}; path=/; secure; sameSite=None`;\n document.cookie = cookieString;\n }\n\n removeAlert() {\n return this.remove();\n }\n\n showAlert() {\n const instance = new Alert(this); // eslint-disable-line\n this.classList.remove('d-none');\n this.classList.add('d-flex');\n }\n}\n\nexport default window.customElements.get('vz-alert') || VZAlert;\nif (!window.customElements.get('vz-alert')) {\n window.customElements.define('vz-alert', VZAlert);\n}\n","function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e))for(t=0;t\n
\n
\n ${iconName?.length ? `` : ''}\n
\n
\n ${titleText}\n
\n
\n ${closeBtn && closeBtnUrl ? `` : ''}\n ${closeBtn && !closeBtnUrl ? '' : ''}\n
\n\n
\n ${bodyTitle?.length ? `

${bodyTitle}

` : ''}\n ${bodyText?.length ? `

${bodyText}

` : ''}\n
\n\n \n
\n \n `;\n }\n\n /**\n * @function renderAbandonConfigurationModal\n * @description Will add an onclick listener to all 'Wijzigen' cta's inside the minicart. When clicked on, the abandonConfiguration modal will show up.\n */\n // eslint-disable-next-line\n renderAbandonConfigurationModal() {\n const editButtons = [...document.querySelectorAll('.js-edit-button')];\n editButtons.forEach((editButton) => {\n editButton.addEventListener('click', () => {\n const { abandonConfigurationModalId } = editButton.dataset;\n\n const abandonConfigurationModal = document.getElementById(abandonConfigurationModalId);\n abandonConfigurationModal?.render();\n });\n });\n }\n}\n","'use-strict';\n\nimport ModalHelper from './modalHelper';\n\n/**\n * @class VZModal\n * @description Creates a modal based on defaultModalHTML or the HTML within the custom element.\n * @example\n * \n
Optional custom HTML if not using defaultModalHTML
\n \n * @usage\n * const modal = document.getElementById('specific-modal-name');\n * modal.render(); // An optional object can be passed to render() to overwrite the defaults.\n */\nexport default class VZModal extends HTMLElement {\n constructor() {\n super();\n this.setAttribute('tabindex', '-1');\n this.setAttribute('aria-hidden', 'true');\n this.hasCustomHtml = this.dataset.customModal === 'true';\n this.modalHelper = new ModalHelper();\n }\n\n /**\n * @function createTemplate\n * @description Injects the default modal HTML into the modal container.\n * @param {string} templateHtml - String representing default modal HTML.\n */\n createTemplate(templateHtml) {\n const template = document.createElement('template');\n template.innerHTML = templateHtml;\n this.appendChild(template.content.cloneNode(true));\n }\n\n connectedCallback() {\n document.addEventListener('minicart:open', this.modalHelper.renderAbandonConfigurationModal);\n }\n\n disconnectedCallback() {\n document.removeEventListener('minicart:open', this.modalHelper.renderAbandonConfigurationModal);\n }\n\n /**\n * @function render\n * @description Renders the contents of the addToBasketModal and injects text based on data attributes.\n * @param {Object} options - An optional parameter with configuration options for the modal. To be used to overwrite the default options.\n */\n render(options = {}) {\n // If the default modal does not fit the requirement, custom HTML can be added within the custom element.\n if (this.hasCustomHtml) {\n this.showModal();\n return;\n }\n\n this.configurationOptions = { ...this.dataset, ...ModalHelper.defaultOptions, ...options };\n const defaultModalHTML = ModalHelper.getDefaultModalHtml(this.configurationOptions);\n\n // Remove existing modal so the template can be recreated with new content.\n this.querySelector('.js-modal-dialog')?.remove();\n\n this.createTemplate(defaultModalHTML); // Inject the template, add it to the DOM.\n\n this.showModal(); // Display the modal.\n }\n\n /**\n * @function showModal\n * @description Checks if modal already exists and either creates a new one to show, or shows the existing one.\n */\n showModal() {\n const { backdrop, keyboard } = { ...this.configurationOptions, ...this.dataset }; // If passed in the dataset, the default values for keyboard and backdrop will be overwritten.\n const keyboardSetting = typeof keyboard === 'string' ? keyboard === 'true' : keyboard;\n\n const newModal = new window.bs.Modal(this, { backdrop, keyboard: keyboardSetting }); // Options come from data attributes.\n if (newModal) newModal.show();\n }\n\n /**\n * @function hideModal\n * @description Hides the modal\n */\n hideModal() {\n window.bs.Modal.getInstance(this)?.hide();\n }\n}\n\nif (!window.customElements.get('vz-modal')) {\n window.customElements.define('vz-modal', VZModal);\n}\n","'use strict';\n\n// Can't import cartridges/app_vodafone_ziggo/cartridge/scripts/forms/validator.js\nconst ID_TYPES_CODES = {\n idCard: '1',\n passport: '2',\n driversLicense: '3',\n permit1: '4',\n permit2: '5',\n permit3: '6',\n permit4: '7',\n permit5: '8',\n permitEU: '9',\n other: '10'\n};\n\nconst ID_VALIDATION_RULES = {};\nID_VALIDATION_RULES[ID_TYPES_CODES.passport] = /^[A-NP-Z]{2}[\\dA-NP-Z]{6}\\d{1}$/gi;\nID_VALIDATION_RULES[ID_TYPES_CODES.idCard] = ID_VALIDATION_RULES[ID_TYPES_CODES.passport];\nID_VALIDATION_RULES[ID_TYPES_CODES.driversLicense] = /^\\d{10}$/gi;\nID_VALIDATION_RULES[ID_TYPES_CODES.permit1] = /^(?!(X00|V))[\\dA-Z]{8,9}$/gi;\nID_VALIDATION_RULES[ID_TYPES_CODES.permit2] = ID_VALIDATION_RULES[ID_TYPES_CODES.permit1];\nID_VALIDATION_RULES[ID_TYPES_CODES.permit2] = ID_VALIDATION_RULES[ID_TYPES_CODES.permit1];\nID_VALIDATION_RULES[ID_TYPES_CODES.permit3] = ID_VALIDATION_RULES[ID_TYPES_CODES.permit1];\nID_VALIDATION_RULES[ID_TYPES_CODES.permit4] = ID_VALIDATION_RULES[ID_TYPES_CODES.permit1];\nID_VALIDATION_RULES[ID_TYPES_CODES.permit5] = ID_VALIDATION_RULES[ID_TYPES_CODES.permit1];\nID_VALIDATION_RULES[ID_TYPES_CODES.permitEU] = ID_VALIDATION_RULES[ID_TYPES_CODES.permit1];\n\n// this regexp is always invalid\nID_VALIDATION_RULES[ID_TYPES_CODES.other] = /(?=a)b/;\n\n/**\n * @constant {string} ID_TYPE - Selector for identification type\n */\nconst ID_TYPE = 'dwfrm_checkoutDetails_identification_idtype';\n\n/**\n * @private setValidationPattern\n * @param {Event} evt - Change or load event\n */\nfunction setValidationPattern(evt) {\n const element = evt.target.id === ID_TYPE ? evt.target : document.getElementById(ID_TYPE);\n if (element.value) {\n element.closest('form').dispatchEvent(\n new CustomEvent('identificationTypeChanged', {\n detail: {\n type: element.value,\n regex: ID_VALIDATION_RULES[element.value]\n }\n })\n );\n }\n}\n\n/**\n * @public idType\n * @param {HTMLSelectElement} element - Identification type selector\n */\nexport default function idType(element) {\n if (element.id !== ID_TYPE) return;\n\n element.addEventListener('change', setValidationPattern);\n window.addEventListener('load', setValidationPattern);\n}\n","'use strict';\n\n/**\n * @constant {string} CAPS_MASK_ATTRIBUTE - Attribute value for caps mask\n */\nexport const CAPS_MASK_ATTRIBUTE = 'caps';\n\n/**\n * @class CapsMask\n * @param {HTMLInputElement} element - An input field\n */\nexport class CapsMask {\n constructor(element) {\n element.addEventListener('input', this.onInput.bind(element));\n element.addEventListener('change', this.onInput.bind(element));\n }\n\n onInput() {\n const position = this.selectionStart;\n this.value = this.value.toUpperCase();\n this.setSelectionRange(position, position);\n }\n}\n","'use strict';\n\nimport { CapsMask } from './caps';\n\n/**\n * @constant {string} POSTCODE_MASK_ATTRIBUTE - Attribute value for postcode mask\n */\nconst POSTCODE_MASK_ATTRIBUTE = 'postcode';\n\n/**\n * @constant {integer} BACKSPACE_KEYCODE\n */\nconst BACKSPACE_KEYCODE = 8;\n\n/**\n * @constant {integer} DELETE_KEYCODE\n */\nconst DELETE_KEYCODE = 46;\n\n/**\n * @constant {Array} UNDO_KEYS\n */\nconst UNDO_KEYS = [BACKSPACE_KEYCODE, DELETE_KEYCODE, 'backspace', 'delete'];\n\n/**\n * @class PostCodeMask\n * @param {HTMLInputElement} element - The input field to put the postcode mask on.\n */\nclass PostCodeMask extends CapsMask {\n constructor(element) {\n super(element);\n this.element = element;\n this.onKeyUp = this.onKeyUp.bind(this);\n\n element.addEventListener('keyup', this.onKeyUp);\n }\n\n /**\n * @private onKeyUp\n * @param {KeyboardEvent} evt - On key up event\n */\n onKeyUp(evt) {\n const key = evt.key && typeof evt.key !== 'number' ? evt.key.toLocaleLowerCase() : evt.key || null;\n if (key && UNDO_KEYS.some((k) => k === key)) {\n if (this.element.value.length === 5) {\n this.element.value = this.element.value.substring(0, 4);\n }\n return;\n }\n\n // Mask the input value for postcodes using a regular expression.\n this.element.value = this.element.value.replace(/(^\\d{4})(\\w{0,2}$)/, '$1 $2');\n }\n}\n\nexport { PostCodeMask, POSTCODE_MASK_ATTRIBUTE };\n","'use strict';\n\nimport { CapsMask } from './caps';\n\n/**\n * @constant {string} POSTCODE_MASK_ATTRIBUTE - Attribute value for postcode mask\n */\nconst IBAN_MASK_ATTRIBUTE = 'iban';\n\n/**\n * @constant {integer} BACKSPACE_KEYCODE\n */\nconst BACKSPACE_KEYCODE = 8;\n\n/**\n * @constant {integer} DELETE_KEYCODE\n */\nconst DELETE_KEYCODE = 46;\n\n/**\n * @constant {Array} UNDO_KEYS\n */\nconst UNDO_KEYS = [BACKSPACE_KEYCODE, DELETE_KEYCODE, 'backspace', 'delete'];\n\nclass IBANMask extends CapsMask {\n constructor(element) {\n super(element);\n this.element = element;\n this.onKeyUp = this.onKeyUp.bind(this);\n\n element.addEventListener('keyup', this.onKeyUp);\n }\n\n /**\n * @private onKeyUp\n * @param {KeyboardEvent} evt - On key up event\n */\n onKeyUp(evt) {\n const key = evt.key && typeof evt.key !== 'number' ? evt.key.toLocaleLowerCase() : evt.key || null;\n if (key && UNDO_KEYS.some((k) => k === key)) {\n if (this.element.value.length % 4 === 1) {\n this.element.value = this.element.value.substring(0, this.element.value.length);\n }\n return;\n }\n\n // Mask the input value for iban using a regular expression.\n this.element.value = this.element.value\n .replace(/\\s/g, '')\n .replace(/^([a-zA-Z]{2}\\d{2})(\\w{0,4})(\\d{0,4})(\\d{0,4})(\\d{0,2})/, '$1 $2 $3 $4 $5')\n .replace(/\\s\\s+/g, ' ');\n }\n}\n\nexport { IBANMask, IBAN_MASK_ATTRIBUTE };\n","'use strict';\n\n/**\n * @constant {string} DATE_MASK_ATTRIBUTE - Attribute value for date mask\n */\nconst DATE_MASK_ATTRIBUTE = 'date';\n\nclass DateMask {\n constructor(element) {\n this.field = element;\n this.cursorIndex = 0;\n this.maskText = element.getAttribute('data-mask-text');\n this.pressedCharacters = [];\n\n this.onInput = this.onInput.bind(this);\n this.onPaste = this.onPaste.bind(this);\n this.replaceRemovedDigitWithLetter = this.replaceRemovedDigitWithLetter.bind(this);\n this.onArrowRight = this.onArrowRight.bind(this);\n this.onArrowLeft = this.onArrowLeft.bind(this);\n this.onCharacterRemoval = this.onCharacterRemoval.bind(this);\n this.checkIfDashIsSelected = this.checkIfDashIsSelected.bind(this);\n this.replaceAsYouType = this.replaceAsYouType.bind(this);\n\n element.addEventListener('keydown', this.onKeyDown.bind(this));\n element.addEventListener('keyup', this.onInput);\n element.addEventListener('paste', this.onPaste);\n }\n\n /**\n * @private runRegexOnValue\n * @param {string} value - The value\n * @returns {array} - The final manipulated value as an array with each character\n *\n * @description\n * Mask the input value for date using regular expressions and enforcing dashes at specific locations\n */\n static runRegexOnValue(value) {\n return value\n .toUpperCase() // In case lowercase d/m/j letters are entered\n .replace(/^(\\d{1}-)-/, '0$1-') // If we already have the mask and one digit plus a dash has been entered, prepend a 0\n .replace(/-(\\d{1}-)-/, '-0$1-') // For the 2nd group, do the same and prepend a 0\n\n .replace(/-+-/g, '-') // Convert multiple dashes to a single dash\n .replace(/[^\\dDMJ-]/g, '') // Remove any character that is not [numeric, letters D/M/J, a dash]\n .replace(/^-(\\d{1})/, '$1') // If the string starts with a dash, remove the dash\n .replace(/-/g, '') // After all manipulations and cleaning up, remove all dashes (which could also have been added in the 3rd group) and..\n .split(''); // split up our current string so we can enforce dashes on specific locations only\n }\n\n /**\n * @private totalLengthUntilLastDigit\n * @param {string} newVal - The value\n * @returns {number} - The total length\n *\n * @description\n * Calculate what the total length of newVal would be once the dashes are added through `splice`, only until the last entered digit\n * We need this to do calculations for cursorOffset\n */\n static totalLengthUntilLastDigit(newVal) {\n const untilLastDigit = newVal.join('').replace(/[\\D]*$/, '');\n let totalLength = untilLastDigit.length;\n if (totalLength > 4) {\n totalLength += 1;\n }\n if (totalLength > 2) {\n totalLength += 1;\n }\n\n return totalLength;\n }\n\n /**\n * @private replaceRemovedDigitWithLetter\n * @param {string} newVal - The value\n * @returns {array} - The updated newVal\n *\n * @description\n * Will replace the removed digit with a corresponding letter from the maskText\n */\n replaceRemovedDigitWithLetter(newVal) {\n // Calculate the offset which is necessary to determine where the replacing character should be placed\n // The offset is based on the cursorIndex and the amount of dashes that are present\n let cursorOffset = 0;\n const cursorIndex = this.cursorIndex;\n\n if (cursorIndex === 3 || cursorIndex === 4) {\n cursorOffset -= 1;\n } else if (cursorIndex > 4) {\n cursorOffset -= 2;\n }\n\n // Decide which character should take it's place and add it to the array\n const removedCharacter = this.maskText.substring(cursorIndex, cursorIndex + 1);\n\n if (removedCharacter !== '-') {\n newVal.splice(cursorIndex + cursorOffset, 0, removedCharacter);\n }\n\n return newVal;\n }\n\n /**\n * @private addDashes\n * @param {string} newVal - The value\n * @returns {array} - The updated newVal\n *\n * @description\n * Will add dashes at specific spots\n */\n static addDashes(newVal) {\n // If we have 4 or more digits, add a dash\n if (newVal.length >= 4) {\n newVal.splice(4, 0, '-');\n }\n\n // If we have 2 or more digits, add a dash\n if (newVal.length >= 2) {\n newVal.splice(2, 0, '-');\n }\n\n return newVal;\n }\n\n /**\n * @private onArrowRight\n * @param {string} newVal - The value\n *\n * @description\n * Will move the cursor to the right based on some checks\n */\n onArrowRight(newVal) {\n if (this.checkIfDashIsSelected(newVal)) this.cursorIndex += 1;\n this.field.setSelectionRange(this.cursorIndex, this.cursorIndex);\n }\n\n /**\n * @private onArrowLeft\n * @param {string} newVal - The value\n *\n * @description\n * Will move the cursor to the left based on some checks\n */\n onArrowLeft(newVal) {\n if (this.checkIfDashIsSelected(newVal, 'left')) this.cursorIndex -= 1;\n this.field.setSelectionRange(this.cursorIndex, this.cursorIndex);\n }\n\n /**\n * @private onCharacterRemoval\n * @param {string} newVal - The value\n *\n * @description\n * Will move the cursor to the left based on some checks\n */\n onCharacterRemoval(newVal) {\n // If the character on the left is a dash, move an extra spot to the left\n if (this.checkIfDashIsSelected(newVal, 'left')) this.cursorIndex -= 1;\n\n // If we end up before the beginning, reset the index\n if (this.cursorIndex < 0) this.cursorIndex = 0;\n\n this.field.setSelectionRange(this.cursorIndex, this.cursorIndex);\n }\n\n /**\n * @private checkIfDashIsSelected\n * @param {string} value - The string to check\n * @param {string} direction - Either 'left' or 'right'\n * @param {number} offset - An optional offset\n * @returns {boolean} - True of false\n */\n checkIfDashIsSelected(value, direction, offset = 0) {\n const cursorIndex = this.cursorIndex + offset;\n\n if (direction === 'left') {\n return value.substring(cursorIndex - 1, cursorIndex) === '-';\n }\n\n return value.substring(cursorIndex, cursorIndex + 1) === '-';\n }\n\n /**\n * @private replaceAt\n * @param {string} value - The original value\n * @param {number} index - The position of the old character to replace\n * @param {string} replacement - The replacement character\n * @returns {string} - An updated value\n */\n static replaceAt(value, index, replacement) {\n return value.substring(0, index) + replacement + value.substring(index + 1);\n }\n\n /**\n * @private replaceAsYouType\n * @param {string} key - The pressed key as a string\n * @returns {string} - A possibly updated value\n * @description\n * Will replace the next character as you type. This is necessary since we have a max-length on the field.\n */\n replaceAsYouType(key) {\n let value = this.field.value;\n const isDigit = !window.isNaN(key);\n const allowedDash = key === '-' && this.checkIfDashIsSelected(value, 'right', 1);\n\n // If we're not at the end\n // and there's no selection at the moment\n // and the inputted character is either a digit or a dash\n if (this.cursorIndex < value.length && !this.hasSelection && (isDigit || allowedDash)) {\n // If we're before a dash, replace the character after the dash\n if (this.checkIfDashIsSelected(value)) {\n this.cursorIndex++;\n }\n\n value = this.constructor.replaceAt(value, this.cursorIndex, key);\n this.cursorIndex++;\n }\n\n return value;\n }\n\n /**\n * @private onKeyDown\n * @param {KeyboardEvent} evt - On key down event\n */\n onKeyDown(evt) {\n // If the user is holding the key down, and it's not the backspace/delete button, preventDefault\n if (evt.repeat && evt.key !== 'Backspace' && evt.key !== 'Delete') {\n evt.preventDefault();\n return;\n }\n\n this.hasSelection = evt.target.selectionEnd > evt.target.selectionStart;\n const isDigit = !window.isNaN(evt.key);\n\n if (isDigit || evt.key === '-') {\n evt.preventDefault();\n this.pressedCharacters.push(evt.key);\n this.onInput(evt);\n }\n }\n\n /**\n * @private onInput\n * @param {KeyboardEvent} evt - On key up event\n */\n onInput(evt) {\n if (\n evt.type === 'keyup' &&\n (evt.key === 'Escape' ||\n evt.key === 'Enter' ||\n evt.key === 'Tab' ||\n evt.key === 'Control' ||\n evt.key === 'Shift' ||\n evt.key === 'Alt' ||\n evt.key === 'Meta' ||\n evt.key === 'ArrowUp' ||\n evt.key === 'ArrowDown')\n ) {\n return;\n }\n\n const field = this.field;\n const val = field.value;\n let charRemoved = evt.type === 'keyup' && (evt.key === 'Backspace' || evt.key === 'Delete');\n this.cursorIndex = field.selectionStart;\n\n // Getting the pressed character from the array is to cater for the edge case where the user held down for example '1' and then pressed '2'.\n // This should force '1' to be shown first and then '2', instead of the other way around if we would just get evt.key.\n // This is a \"complex\" workaround for a simple problem which would much easier be fixed by using `onKeyDown` instead of `onKeyUp`, but it's\n // too late to refactor half of this file now...\n const firstPressedCharacter = this.pressedCharacters[0];\n\n // If the entire value/date has been selected\n if (evt.target.selectionStart === 0 && evt.target.selectionEnd === 10) {\n if (firstPressedCharacter) {\n // If a character has been entered, reset the value to the pressed character\n field.value = firstPressedCharacter;\n this.cursorIndex++;\n } else {\n // Stop executing the rest of this method so the user can \"select all\" and then hit backspace/delete\n return;\n }\n }\n\n // Init the mask if there is no value yet (seeing as we preventDefault in `onKeyDown`)\n // Also adjust the `empty` class accordingly\n if (val.length === 0 && firstPressedCharacter) {\n field.value = firstPressedCharacter;\n field.classList.remove('empty');\n } else if (val.length === 0) {\n field.classList.add('empty');\n }\n\n // Replace characters as you type\n let newVal = this.replaceAsYouType(firstPressedCharacter, val);\n field.value = newVal;\n\n this.pressedCharacters.shift();\n\n // Mask the input value for date using regular expressions and enforcing dashes at specific locations\n newVal = this.constructor.runRegexOnValue(newVal);\n\n // Calculate what the total length of newVal would be once the dashes are added through `splice`, only until the last entered digit\n // We need this to do calculations for cursorOffset\n const totalLength = this.constructor.totalLengthUntilLastDigit(newVal);\n\n // Will replace the removed digit with a corresponding letter from the maskText\n if (charRemoved) {\n newVal = this.replaceRemovedDigitWithLetter(newVal);\n }\n\n // If we removed any digit \"in the middle\",\n // Reset `charRemoved` to false, in order to keep the cursor in the current position\n if (charRemoved && this.cursorIndex < totalLength) {\n charRemoved = false;\n }\n\n // Add dashes at specific spots\n newVal = this.constructor.addDashes(newVal);\n\n // Set final value with a format of xx-xx-xxxx\n // If the value is incomplete, finish the rest with the mask\n if (totalLength > 0) {\n newVal = newVal.join('').substring(0, 10);\n newVal += this.maskText.substring(newVal.length, 10);\n this.field.value = newVal;\n } else {\n this.field.value = '';\n return;\n }\n\n // If arrow left was pressed\n if (evt.key === 'ArrowLeft') {\n this.onArrowLeft(newVal);\n return;\n }\n\n // If arrow right was pressed\n if (evt.key === 'ArrowRight') {\n this.onArrowRight(newVal);\n return;\n }\n\n // If a character was removed\n if (charRemoved) {\n this.onCharacterRemoval(newVal);\n return;\n }\n\n // When a character has been entered, increment the cursorIndex\n if (this.checkIfDashIsSelected(newVal)) {\n this.cursorIndex += 1;\n }\n\n // Set the new selection based on calculations done in above methods\n this.field.setSelectionRange(this.cursorIndex, this.cursorIndex);\n }\n\n /**\n * @private onPaste\n * @param {KeyboardEvent} evt - On key up event\n */\n onPaste(evt) {\n this.onInput(evt);\n\n setTimeout(() => {\n const val = this.field.value;\n this.field.setSelectionRange(val.length, val.length);\n }, 100); // small delay is necessary because the dashes are added after paste\n }\n}\n\nexport { DateMask, DATE_MASK_ATTRIBUTE };\n","'use strict';\n\nimport { POSTCODE_MASK_ATTRIBUTE, PostCodeMask } from './masks/postcode';\nimport { IBAN_MASK_ATTRIBUTE, IBANMask } from './masks/iban';\nimport { DATE_MASK_ATTRIBUTE, DateMask } from './masks/date';\nimport { CAPS_MASK_ATTRIBUTE, CapsMask } from './masks/caps';\n\n/**\n * @class Mask\n * @param {HTMLInputElement} element - The input field to put a mask on\n */\nclass Mask {\n constructor(element) {\n this.element = element;\n this.maskType = this.element.getAttribute('data-mask');\n\n // PostCode mask\n if (this.maskType === POSTCODE_MASK_ATTRIBUTE) {\n this.mask = new PostCodeMask(this.element);\n }\n if (this.maskType === IBAN_MASK_ATTRIBUTE) {\n this.mask = new IBANMask(this.element);\n }\n if (this.maskType === DATE_MASK_ATTRIBUTE) {\n this.mask = new DateMask(this.element);\n }\n if (this.maskType === CAPS_MASK_ATTRIBUTE) {\n this.mask = new CapsMask(this.element);\n }\n }\n}\n\nexport default Mask;\n","'use strict';\n\n/**\n * @private preventCharacters\n * @param {Event} event - Keydown or paste event\n */\nfunction preventCharacters(event) {\n const { target } = event;\n const bannedCharacters = target.getAttribute('data-prevent');\n\n if (event.key && bannedCharacters.includes(event.key)) {\n event.preventDefault();\n } else if (event.clipboardData) {\n event.preventDefault();\n\n const clipboardData = event.clipboardData.getData('text/plain');\n const dataWithoutBannedCharacters = clipboardData\n .split('')\n .filter((character) => !bannedCharacters.includes(character))\n .join('');\n const currValue = target.value;\n\n if (typeof target.selectionStart === 'number') {\n const start = target.selectionStart;\n const end = target.selectionEnd;\n const newVal = [];\n\n if (start === 0 && end === 0) {\n newVal.push(dataWithoutBannedCharacters);\n newVal.push(currValue);\n } else {\n newVal.push(currValue.substr(0, start));\n newVal.push(dataWithoutBannedCharacters);\n newVal.push(currValue.substr(end, currValue.length - 1));\n }\n\n target.value = newVal.join('');\n } else {\n // Some input types don't support `selectionStart`. In this edge case, just append it to the end\n target.value = currValue + dataWithoutBannedCharacters;\n }\n }\n}\n\n/**\n * @public preventCharactersOnInput\n * @param {HTMLInputElement} element - The input element\n */\nexport default function preventCharactersOnInput(element) {\n if (!element.getAttribute('data-prevent')) return;\n\n element.addEventListener('keydown', preventCharacters);\n element.addEventListener('paste', preventCharacters);\n}\n","'use strict';\n\nconst events = ['keydown', 'paste', 'focus', 'mousedown'];\n\n/**\n * Prevent entry in the field\n * @param {Event} evt - An event\n */\nfunction preventEntry(evt) {\n // ignore tab\n if (evt.keyCode !== 9) evt.preventDefault();\n}\n\n/**\n * Enable the read-only feature\n * @param {HTMLElement} element - The element to make read-only\n * @returns {bool} enabled\n */\nfunction enable(element) {\n events.forEach((event) => {\n element.addEventListener(event, preventEntry);\n });\n return true;\n}\n\n/**\n * Disable the read-only feature\n * @param {HTMLElement} element - The element to make read-only\n * @returns {bool} enabled\n */\nfunction disable(element) {\n events.forEach((event) => {\n element.removeEventListener(event, preventEntry);\n });\n return false;\n}\n\n/**\n * @public idType\n * @param {HTMLSelectElement} element - Identification type selector\n */\nexport default function idType(element) {\n if (!element.hasAttribute('read-only')) return;\n Object.defineProperty(element, 'read-only', {\n enumerable: false,\n configurable: false,\n set: (bool) => {\n if (bool) {\n this.value = enable(element);\n return;\n }\n this.value = disable(element);\n }\n });\n element['read-only'] = element.getAttribute('read-only');\n}\n","'use strict';\n\nimport documentNumber from './documentNumber';\nimport idType from './idType';\nimport mask from './mask';\nimport password from './password';\nimport preventCharacters from './preventCharacters';\nimport readonly from './readonly';\nimport regex from './regex';\nimport valid from './valid';\n\nexport default {\n documentNumber,\n idType,\n mask,\n password,\n preventCharacters,\n readonly,\n regex,\n valid\n};\n","'use strict';\n\n/**\n * @constant {string} DOCUMENT_NUMBER - Input field for document number\n */\nconst DOCUMENT_NUMBER = 'dwfrm_checkoutDetails_identification_documentNumber';\n\n/**\n * @public documentNumber\n * @param {HTMLInputElement} element - Document Number input field\n */\nexport default function documentNumber(element) {\n if (element.name !== DOCUMENT_NUMBER) return;\n\n element.closest('form').addEventListener('identificationTypeChanged', (evt) => {\n // First reset regex state due to /g entries\n // https://stackoverflow.com/questions/2630418/javascript-regex-returning-true-then-false-then-true-etc/2630538#2630538\n element.pattern = evt.detail.regex.toString().replace('/^', '^').replace('$/gi', '$');\n element.regex.lastIndex = 0;\n element.regex = new RegExp(element.pattern);\n if (element.value.length > 0) {\n element.dispatchEvent(new CustomEvent('input'));\n element.dispatchEvent(new CustomEvent('blur'));\n }\n });\n\n const originalErrorMsg = element.dataset.patternError;\n element.addEventListener('input', () => {\n // Reset to original error message\n element.dataset.patternError = originalErrorMsg;\n if (element.dataset.selectedId && element.dataset.selectedId.includes('verblijfsdocument')) {\n if (element.value.toLowerCase().startsWith('x00')) element.dataset.patternError = element.dataset.patternX00Error;\n if (element.value.toLowerCase().startsWith('v')) element.dataset.patternError = element.dataset.patternVError;\n }\n });\n}\n","'use strict';\n\nimport Mask from 'Components/form/mask';\n\n/**\n * @public regex\n * @param {HTMLInputElement} element - The element to put the mask on\n */\nexport default function mask(element) {\n Object.defineProperty(element, 'mask', {\n enumerable: false,\n configurable: false,\n value: new Mask(element)\n });\n}\n","'use strict';\n\n/**\n * @constant {string} PASSWORD_VIEW_TOGGLE - Selector for toggling the view state of a password field.\n */\nconst PASSWORD_VIEW_TOGGLE = '.js-password-toggle';\n\n/**\n * @public showPassword\n * @param {HTMLInputElement} element - The element used to set the password toggle.\n */\nexport default function showPassword(element) {\n const feedbackElement = element.parentElement.querySelector(PASSWORD_VIEW_TOGGLE);\n if (!feedbackElement) return;\n\n feedbackElement.addEventListener('click', () => {\n element.showPassword = element.type === 'password';\n });\n Object.defineProperty(element, 'showPassword', {\n enumerable: false,\n configurable: false,\n set: (value) => {\n if (value) {\n element.type = 'text';\n } else {\n element.type = 'password';\n }\n }\n });\n}\n","'use strict';\n\n/**\n * @public regex\n * @param {HTMLInputElement} element - The element used to set the regex.\n */\nexport default function regex(element) {\n Object.defineProperty(element, 'regex', {\n enumerable: false,\n configurable: true,\n writable: true,\n value: element.required ? new RegExp(element.pattern) : new RegExp() // Pattern or empty when not mandatory\n });\n}\n","'use strict';\n\n/**\n * @public validate\n * @param {HTMLInputElement} element - The element used to validate.\n */\nexport default function validate(element) {\n Object.defineProperty(element, 'valid', {\n enumerable: true,\n configurable: false,\n set: (value) => {\n if (value) {\n element.classList.add('valid');\n element.classList.remove('invalid');\n } else {\n element.classList.add('invalid');\n element.classList.remove('valid');\n }\n }\n });\n}\n","'use strict';\n\nimport decorators from 'Decorators/index';\nimport { validate } from 'app_vodafone_ziggo/util/validation';\n\n/**\n * @class InputField\n * @param {HTMLInputElement} element - The element to create an instance on\n */\nclass VZInputField extends HTMLInputElement {\n constructor() {\n super();\n this.validatePattern = this.validatePattern.bind(this);\n this.setFieldStatus = this.setFieldStatus.bind(this);\n this.onPaste = this.onPaste.bind(this);\n\n this.addEventListener('input', this.validatePattern);\n this.addEventListener('input', this.setFieldStatus);\n this.addEventListener('changeDate', this.setFieldStatus);\n this.addEventListener('changeDate', validate);\n this.addEventListener('paste', this.onPaste);\n this.validate = validate;\n\n decorators.readonly(this);\n decorators.regex(this);\n decorators.valid(this);\n decorators.documentNumber(this);\n\n if (this.hasAttribute('data-mask')) {\n decorators.mask(this);\n }\n\n if (this.hasAttribute('data-prevent')) {\n decorators.preventCharacters(this);\n }\n\n if (this.type === 'password') {\n decorators.password(this);\n }\n\n // Set initial state\n this.setFieldStatus();\n\n if (this.type === 'radio' || this.type === 'checkbox') {\n this.addEventListener('change', validate);\n } else {\n this.addEventListener('blur', validate);\n }\n\n this.closest('form').addEventListener('submit', this.disableExcludedFields);\n }\n\n onPaste(evt) {\n // Execute these methods at the end of the callstack, otherwise `field.value` will be the value before the paste.\n setTimeout(() => {\n this.setFieldStatus();\n validate(evt);\n }, 1);\n }\n\n disableExcludedFields() {\n if (this.hasAttribute('data-exclude')) {\n this.setAttribute('disabled', 'disabled');\n }\n }\n\n /**\n * @private setFieldStatus\n * @description\n * Sets an empty class when the element is empty for styling purposes.\n */\n setFieldStatus() {\n const hasValue = this.value.length > 0;\n const placeholderIsShown = this.constructor.placeholderActive(this);\n if (hasValue) {\n this.classList.remove('empty');\n } else if (placeholderIsShown) {\n // input[type=\"number\"] accepts dash and dots but returns no value for that.\n this.classList.add('empty');\n }\n }\n\n /**\n * @private validatePattern\n * @description\n * Checks whether the value is valid based on pattern\n */\n validatePattern() {\n this.valid = this.regex.test(this.value);\n }\n\n /**\n * @function placeholderActive\n *\n * @param {HTMLInputElement} element - Input element\n * @return {boolean} whether the placeholder is shown or not\n */\n static placeholderActive(element) {\n const selector = `${element.nodeName.toLowerCase()}[name=\"${element.name}\"]:placeholder-shown`;\n return !!document.querySelector(selector);\n }\n}\n\nexport default window.customElements.get('vz-input') || VZInputField;\nif (!window.customElements.get('vz-input')) {\n window.customElements.define('vz-input', VZInputField, { extends: 'input' });\n}\n","'use-strict';\n\nimport { showErrorModal } from 'Root/modal';\n\nexport default class PostcodeCheckHelpers {\n /**\n * @function stripLeadingZero\n * @param {Event} event - InputEvent\n * @description Strips the leading zero and disallows zero as a value.\n */\n static stripLeadingZero(event) {\n const { target: field, data } = event;\n\n if (data === '0') {\n const value = parseInt(field.value, 10);\n field.value = value > 0 ? value : '';\n }\n }\n\n /**\n * @function preventDashDotComma\n * @param {KeyboardEvent} event - keydown\n * @description Prevents a user from filling in a dash, dot or a comma.\n */\n static preventDashDotComma(event) {\n const { key } = event;\n if (['-', ',', '.'].includes(key)) {\n event.preventDefault();\n }\n }\n\n /**\n * @function respectMaxLength\n * @param {Event} event - Input event\n * @description input[type=\"number\"] doesn't respect max-length attribute.\n * This method slices of the last character when exceeding the max length.\n */\n static respectMaxLength(event) {\n const { target } = event;\n if (target.value.length > target.maxLength) {\n target.value = target.value.slice(0, target.maxLength);\n }\n }\n\n /**\n * @function removePAID\n * @description Will remove the PAID when the user has made a change to the address while in edit mode. This references the VZPostcodeCheck form.\n */\n static removePAID() {\n if (this.hiddenInputWithPaid) this.hiddenInputWithPaid.remove();\n }\n\n /**\n * @function hideForm\n * @description Hides the location search form. This references the VZPostcodeCheck form.\n */\n static hideForm() {\n this.classList.add('d-none');\n }\n\n /**\n * @function showForm\n * @description Shows the location search form. This references the VZPostcodeCheck form.\n */\n static showForm() {\n this.classList.remove('d-none');\n }\n\n /**\n * @function handleErrors\n * @description handles network errors with a generic modal. This references the VZPostcodeCheck form.\n * @param {Error} error - The error thrown by fn fetchAddressAndAvailability is the response is not OK.\n */\n static handleErrors(error) {\n if (error) console.warn(error);\n const { title, body, cta } = JSON.parse(this.dataset?.generalError);\n showErrorModal(title, body, cta);\n }\n\n /**\n * @async\n * @function fetchAddressAndAvailability\n * @description Fetches either the address check or the availability endpoint based on waht's passed in.\n * @param {string} endpoint - A string representing the endpoint to fetch.\n * @param {HTMLFormElement} form - The availability check (VZPostcodeCheck) form.\n * @returns {Object} A Json object returned from the endpoint.\n */\n static async fetchAddressAndAvailability(endpoint, form) {\n const formData = new FormData(form);\n formData.append(window.csrf.tokenName, window.csrf.token);\n\n // This is not available in response.isml, so sending it to the BE to make it available there.\n formData.append('configuratorType', form.configuratorType);\n\n const fetchOptions = { method: 'POST', body: formData };\n const response = await fetch(endpoint, fetchOptions);\n\n if (!response.ok) {\n throw new Error(`There was an error fetching the endpoint - ${endpoint} - status: ${response.status}`);\n }\n\n const responseJson = await response.json();\n return responseJson;\n }\n\n /**\n * @function removeExistingFeedbackMessage\n * @description Removes the existing feedback messages if they exist.\n * @param {HTMLFormElement} form - The availability check (VZPostcodeCheck) form.\n * @param {string} classNames - A comma separated string of class selectors.\n */\n static removeExistingFeedbackMessage(form, classNames) {\n const existingMessages = [...form.querySelectorAll(classNames)];\n if (existingMessages) existingMessages.forEach((message) => message.remove());\n }\n\n /**\n * @function showFeedbackMessage\n * @description Shows the message by creating an element with the message and injects it into the VZPostcodeCheck form.\n * This references the VZPostcodeCheck form.\n * @param {string} message - The message to show in the form.\n * @param {boolean} isError - Determines whether the message passed in is an error message or not.\n */\n static showFeedbackMessage(message, isError = true) {\n const templateString = `
\n

${message}

\n
`;\n const domParser = new DOMParser();\n const messageElement = domParser.parseFromString(templateString, 'text/html').querySelector('.js-availability-address-check-message');\n\n PostcodeCheckHelpers.removeExistingFeedbackMessage(this, '.js-availability-address-check-message');\n this.appendChild(messageElement);\n }\n\n /**\n * @function handleUnableToOrder\n * @description Updates availability check response heading with the address from the address check when a given location has no availability.\n * @returns {void} Early exit if the element is not found.\n */\n static handleUnableToOrder() {\n const responseHeadingElement = this.parentElement.querySelector('.js-availability-response-address');\n responseHeadingElement.setAttribute('unabletoorder', true);\n if (!responseHeadingElement) return;\n\n responseHeadingElement.textContent = this.addressCheckAddress;\n }\n\n /**\n * @function pushErrorsToDataLayer\n * @description When there is an error during the availability check, this will push an event notifying tag manager of the error.\n * @param {Object} addressParts - An object containing address details including the PAID.\n * @param {boolean} locationAlreadyInBasket - Whether the location is in the basket or not.\n */\n static pushErrorsToDataLayer(addressParts, locationAlreadyInBasket) {\n // Not a real error, so locationAlreadyInBasket errors won't be pushed.\n if (locationAlreadyInBasket) return;\n\n window.dataLayer = window.dataLayer || [];\n const { postalCode, houseNumber, extension, paid } = addressParts;\n\n // FYI - using addressCheckAddressParts from AddressCheck instead of address in the response of the availability check because that address is sometimes undefined.\n const erroneousAddressCombination = `${postalCode}-${houseNumber}${extension ? `-${extension}` : ''}`;\n const elementToPush = {\n event: 'availabilityCheckError', // eslint-disable-line quote-props\n payload: {\n // eslint-disable-line quote-props\n erroneousAddressCombination: erroneousAddressCombination.replace(/\\s/g, ''),\n paid: paid || 'No PAID available for this address combination.'\n }\n };\n\n window.dataLayer.push(elementToPush);\n }\n}\n","'use-strict';\n\nimport 'core-js/features/array/at';\n\nimport PCHelpers from './postcodeCheckHelpers';\nimport VZSpinner from 'Components/VZSpinner';\nimport { toggleButtonState } from 'Root/util/util';\n\nexport default class AddressCheck {\n constructor(availabilityForm, additionSelectElement) {\n this.availabilityForm = availabilityForm;\n this.additionSelectElement = additionSelectElement;\n this.addressCheckEndpoint = this.availabilityForm.dataset?.addressCheckUrl;\n this.spinner = document.querySelector('vz-spinner') || new VZSpinner();\n this.postalCode = null;\n this.houseNumber = null;\n this.addition = null;\n\n // Hook up a change event to the addition select field so we can grab the PAID to do the availability check using that\n this.additionSelectElement.addEventListener('blur', this.handleAdditionOnBlur.bind(this));\n [...this.availabilityForm.querySelectorAll('input')].forEach((input) => input.addEventListener('blur', this.handleAddressCheckOnBlur.bind(this)));\n this.executeAddressCheckOnLoad();\n }\n\n /**\n * @function sortAddressExtensions\n * @description Sorts the addresses based on the extension. Manipulates the existing array.\n * @param {Array} addressInfoArray - The array of address information returned from the addressCheck endpoint.\n */\n static sortAddressExtensions(addressInfoArray) {\n addressInfoArray.sort((a, b) => (a.extension.toLowerCase() < b.extension.toLowerCase() ? -1 : 0));\n\n // Get the index of the no extension array item.\n const indexOfNoExtension = addressInfoArray.indexOf(addressInfoArray.find((address) => !address.extensionRequired));\n if (indexOfNoExtension >= 0) {\n // Move the no extension item to the beginning of the array, and delete it in the original location, only if it exists.\n addressInfoArray.splice(0, 0, addressInfoArray.splice(indexOfNoExtension, 1)[0]);\n }\n }\n\n /**\n * @function removeAdditionOptions\n * @description Empties the additionSelectElement except for the default option. Makes the default selected.\n * @param {HTMLOptionsCollection} options - The additionSelectElement options.\n */\n removeAdditionOptions(options) {\n const optionsArray = [...options];\n const defaultOption = optionsArray.find((option) => option.hasAttribute('default'));\n\n optionsArray.filter((option) => !option.hasAttribute('default')).forEach((option) => option.remove()); // Remove options.\n this.additionSelectElement.selectedIndex = optionsArray.indexOf(defaultOption); // Set the default value as selected.\n this.additionSelectElement.classList.remove('valid'); // Reset the validity state.\n }\n\n /**\n * @function generateAdditionElementOptions\n * @description Generates the option elements to populate the additionSelectElement based on the address info passed in.\n * @param {Array} addressInfo - The array of address information returned from the addressCheck endpoint.\n * @param {boolean} hasMultipleExtensions - A boolean determining whether the address entered by the user has more extensions than 'No extension'\n */\n generateAdditionElementOptions(addressInfo, hasMultipleExtensions) {\n // skips if there is already additions selected\n if (this.addition) {\n return;\n }\n this.removeAdditionOptions(this.additionSelectElement.options); // Prevent duplicate options from being generated.\n AddressCheck.sortAddressExtensions(addressInfo); // Sort alphabetically based on extensions.\n\n // Generate option elements based on address info returned from fetch.\n this.additionSelectElement.innerHTML = addressInfo.reduce((result, address, index) => {\n const { paid, extension, extensionRequired, formattedAddress, addressParts } = address;\n const stringifiedAddressParts = JSON.stringify(addressParts).replace(/'/g, '''); // JSON.stringify does not escape single quotes so it needs to be done manually\n\n return `${result}\n \n `;\n }, this.additionSelectElement.innerHTML);\n }\n\n /**\n * @function handleAdditionOnBlur\n * @description Grabs the PAID to be used for the availability check. Sets the address to be used when the availability service returns\n * 'unableToOrder = true'. Validates the additionSelectElement and enables the CTA.\n * @param {Event} event - The blur event fired from the additionSelectElement.\n */\n handleAdditionOnBlur(event) {\n const { target: additionSelectElement } = event;\n const selectedExtensionOption = [...additionSelectElement.options].find((option) => option.selected);\n const { paid: addressCheckPAID, formattedAddress: addressCheckAddress, addressParts } = selectedExtensionOption.dataset;\n this.addition = selectedExtensionOption.value; // set addition to stop the regeneration of additions dropdown\n const paidHiddenInput = this.availabilityForm.hiddenInputWithPAID;\n paidHiddenInput.value = addressCheckPAID; // Set the PAID to the hidden input so the availability check is performed with the PAID\n\n // Update the address on change so its up to date for use in fn handleUnableToOrder. This is used to show the address in the availability check response.\n this.availabilityForm.addressCheckAddress = addressCheckAddress;\n\n // Provide the availability check element with the parts of the address so it can be used when pushing errors to the dataLayer. See fn pushAvailabilityCheckErrorsToDataLayer().\n // This is also used to show addresses in the sidebar for One Net where there is no availability.\n this.availabilityForm.addressCheckAddressParts = JSON.parse(decodeURI(addressParts));\n\n // If the user has selected a value, mark the field as valid and enable the CTA to perform the availability check.\n if (additionSelectElement.checkValidity()) {\n additionSelectElement.classList.add('valid');\n\n // Enable the CTA once a selection has been made.\n toggleButtonState(this.availabilityForm.submitButton, true);\n }\n\n additionSelectElement.setAttribute('value', event.target.value);\n }\n\n /**\n * @function handleAddressCheckOnBlur\n * @description Executes the address check on blur of the postcode and/or house number field, given that both have a valid value.\n * @param {Event} event - The blur event.\n */\n handleAddressCheckOnBlur() {\n const { postcodeInputElement, houseNumberInputElement } = this.availabilityForm;\n // checks if there was anything changed since previous time\n if (this.postalCode !== postcodeInputElement.value || this.houseNumber !== houseNumberInputElement.value) {\n this.addition = null; // resets additions after a change in postal or houseNumber\n this.postalCode = postcodeInputElement.value;\n this.houseNumber = houseNumberInputElement.value;\n const isMinimumRequirementMet = [postcodeInputElement, houseNumberInputElement].every((element) => element.value && element.checkValidity());\n if (isMinimumRequirementMet) {\n this.executeAddressCheck().catch((error) => PCHelpers.showFeedbackMessage.bind(this.availabilityForm)(error)); // Handle rejection from promise returned in fn executeAddressCheck.\n }\n }\n }\n\n /**\n * @function handleAddressNotFound\n * @description Handles the scenario where no address is found.\n */\n handleAddressNotFound() {\n this.removeAdditionOptions(this.additionSelectElement.options); // Reset the additionSelectElement when an address is not found.\n toggleButtonState(this.availabilityForm.submitButton, false);\n PCHelpers.removeExistingFeedbackMessage(this.availabilityForm, '.js-availability-address-check-message');\n }\n\n /**\n * @function handleMultipleAdditions\n * @description When the address check responds with multiple additions for a postcode and house number,\n * this will generate options and append them to the additionSelectElement.\n * @param {Object} addressCheckResponseData - The JSON response returned from the address check.\n */\n handleMultipleAdditions(addressCheckResponseData) {\n const { addressInfo, hasMultipleExtensions } = addressCheckResponseData;\n const { additionHelpText } = this.availabilityForm.dataset;\n\n if (!this.addition) {\n this.additionSelectElement.classList.remove('valid'); // Reset the validity state of the addition element\n }\n this.generateAdditionElementOptions(addressInfo, hasMultipleExtensions); // Populate the additions field.\n this.additionSelectElement.removeAttribute('read-only'); // In case the field was previously disabled, enable it again.\n PCHelpers.removeExistingFeedbackMessage(this.availabilityForm, '.js-availability-address-check-message');\n PCHelpers.showFeedbackMessage.bind(this.availabilityForm)(additionHelpText, false); // Show a help message when there are multiple extensions\n if (!this.addition) {\n toggleButtonState(this.availabilityForm.submitButton, false); // Disable the CTA until a selection has been made\n }\n }\n\n /**\n * @function handleSuccessfulAddressCheck\n * @description Handles the successful addressCheck scenario.\n * @param {Object} addressCheckResponseData - The JSON response returned from the address check.\n */\n handleSuccessfulAddressCheck(addressCheckResponseData) {\n const { formattedAddress = null, hasMultipleExtensions, addressInfo } = addressCheckResponseData;\n\n // Update the address on change so its up to date for use in fn handleUnableToOrder\n this.availabilityForm.addressCheckAddress = formattedAddress;\n this.generateAdditionElementOptions(addressInfo, hasMultipleExtensions); // Populate the additions field.\n\n // Disable the field when there are no extensions apart from 'No Extension'.\n if (!hasMultipleExtensions && !addressInfo.extensionRequired) {\n this.additionSelectElement.setAttribute('read-only', 'true');\n this.additionSelectElement.dispatchEvent(new Event('blur'));\n }\n\n PCHelpers.removeExistingFeedbackMessage(this.availabilityForm, '.js-availability-address-check-message, .error-msg');\n }\n\n /**\n * @function executeAddressCheck\n * @description Executes the address check.\n * @returns {Promise} A promise determining whether the address check was succesful or not. Rejected when address is not found,\n * resolved in other scenarios so the availability check can be performed.\n */\n executeAddressCheck() {\n this.spinner.start();\n\n /**\n * BO-1570 - To make sure that the availability check is only executed for found addresses, a promise needs to be returned and\n * rejected when the address is not found so that the availability check is not performed.\n */\n return new Promise((resolve, reject) => {\n PCHelpers.fetchAddressAndAvailability(this.addressCheckEndpoint, this.availabilityForm)\n .then((addressCheckResponseData) => {\n const multipleExtensionsFound = addressCheckResponseData?.multipleExtensionsFound;\n\n if (!addressCheckResponseData?.success && multipleExtensionsFound) {\n this.handleMultipleAdditions(addressCheckResponseData);\n resolve();\n } else if (!addressCheckResponseData?.success) {\n this.handleAddressNotFound();\n reject(addressCheckResponseData?.serverErrors[0]);\n } else {\n this.handleSuccessfulAddressCheck(addressCheckResponseData);\n resolve();\n }\n })\n .catch(PCHelpers.handleErrors.bind(this))\n .finally(this.spinner.stop);\n });\n }\n\n /**\n * @function executeAddressCheckOnLoad\n * @description Executes the address check on load if values are present. This is mainly so the extension list is populated already,\n * and that the CTA is enabled/disabled based on the status of the address check.\n */\n executeAddressCheckOnLoad() {\n const { postcodeInputElement, houseNumberInputElement } = this.availabilityForm;\n\n if (postcodeInputElement.checkValidity() && houseNumberInputElement.checkValidity()) {\n this.executeAddressCheck().catch((error) => PCHelpers.showFeedbackMessage.bind(this.availabilityForm)(error)); // Handle rejection from promise returned in fn executeAddressCheck.\n }\n }\n}\n","/**\n * @public setCookie\n * @param {string} cookieName - The cookie name\n * @param {string} cookieValue - The cookie value\n * @param {string} domain - The domain\n * @param {string} expirationDays - The expiration in days\n */\nfunction setCookie(cookieName, cookieValue, domain, expirationDays = 30) {\n const date = new Date();\n date.setTime(date.getTime() + expirationDays * 24 * 60 * 60 * 1000);\n const expires = `expires=${date.toUTCString()}`;\n const domainAndPath = `${domain ? `domain=${domain};` : ''}path=/; secure; sameSite=None`;\n const cookieString = `${cookieName}=${cookieValue};${expires};${domainAndPath}`;\n\n document.cookie = cookieString;\n}\n\n/**\n * @public getCookie\n * @param {string} cookieName - The cookie name\n * @return {string|null} The value of the cookie || null\n */\nfunction getCookie(cookieName) {\n const value = `; ${document.cookie}`;\n const parts = value.split(`; ${cookieName}=`);\n if (parts.length === 2) return parts.pop().split(';').shift();\n return null;\n}\n\nexport { setCookie, getCookie };\n","'use strict';\n\nimport 'core-js/features/array/at';\n\nimport 'Components/form/VZInputField';\nimport { appendParamToURL, getParamFromURL } from 'Util/urlUtils';\nimport { toggleButtonState, trackPdpEccomerceEvent } from 'Root/util/util';\nimport VZSpinner from 'Components/VZSpinner';\nimport PCHelpers from './postcodeCheckHelpers';\nimport AddressCheck from './AddressCheck';\nimport { setCookie, getCookie } from 'Util/cookies';\nimport { isIOS, scrollTo } from 'Util/util';\n\nconst spinner = document.querySelector('vz-spinner') || new VZSpinner();\n\n/**\n * @class PostCodeCheck\n * @description the availability check component used in the BIF configurator and for a Page Designer component.\n * It performs an address check and an availability check for the given address.\n */\nexport default class VZPostCodeCheck extends HTMLFormElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.form = document.getElementById('product-form');\n this.sidebar = document.querySelector('.js-configurator-summary');\n this.pdpSubmitButtons = [...document.querySelectorAll('.js-pdp-submit-button button')];\n this.editMode = document.querySelector('.js-edit-mode');\n this.hiddenInputWithPAID = this.querySelector('[name=\"paid\"]');\n this.postcodeInputElement = this.querySelector('.js-postcode-check-postcode');\n this.houseNumberInputElement = this.querySelector('.js-postcode-check-house-number');\n this.additionSelectElement = this.querySelector('.js-postcode-check-addition');\n this.submitButton = this.querySelector('button[type=\"submit\"]');\n this.isPageDesignerComponent = !!document.querySelector('.js-pd-postcode-check');\n this.parentSelector = this.isPageDesignerComponent ? document.querySelector('.js-pd-postcode-check') : this.form;\n this.configuratorType = this.dataset.configuratorType;\n this.isOneNet = this.dataset.configuratorType === 'one-net';\n this.isBusinessInternet = this.dataset.configuratorType === 'internet';\n this.isSharedOneNetConfiguration = window.location.href.includes('sharedonenet');\n\n this.removeLocation = this.removeLocation.bind(this);\n this.updateChatInfo = this.updateChatInfo.bind(this);\n\n // Initialise the address check.\n this.addressCheck = new AddressCheck(this, this.additionSelectElement);\n\n this.addEventListener('submit', this.handleAvailabilityFormSubmit.bind(this));\n this.toggleButtonState();\n\n if (this.editMode || window.location.href.includes('paid=')) {\n this.autoSubmitForm();\n }\n\n [...this.querySelectorAll('input')].forEach((field) => {\n if (field.type === 'number') {\n field.addEventListener('input', PCHelpers.respectMaxLength);\n field.addEventListener('input', PCHelpers.stripLeadingZero);\n field.addEventListener('keydown', PCHelpers.preventDashDotComma);\n }\n\n // The order of eventListeners is important, toggle the button state after the above events are done\n field.addEventListener('input focus', this.toggleButtonState.bind(this));\n\n if (this.editMode || window.location.href.includes('paid=')) {\n field.addEventListener('input', PCHelpers.removePAID.bind(this));\n }\n });\n\n // Add an event listener to select fields change event\n [...this.querySelectorAll('select')].forEach((select) => {\n select.addEventListener('change', this.toggleButtonState.bind(this));\n });\n\n // Add an event listener to enable product configuration after one net seat is selected.\n document.addEventListener('oneNet:seatSelection', this.enableProductConfiguration.bind(this));\n }\n\n /**\n * @function toggleButtonState\n * @description Validates the form and toggles the location submit button state.\n */\n toggleButtonState() {\n if (this.checkValidity() || (this.postcodeInputElement.checkValidity() && this.houseNumberInputElement.checkValidity())) {\n this.additionSelectElement.removeAttribute('read-only');\n toggleButtonState(this.submitButton, true);\n } else {\n this.additionSelectElement.setAttribute('read-only', 'true');\n toggleButtonState(this.submitButton, false);\n }\n }\n\n /**\n * @function enableProductConfiguration\n * @description Remove transparent layer from the form and add pointer events.\n * This does/should not execute for the PD postcode check component.\n * @param {Event} event - The oneNet:seatSelection event fired from VZQuantitySelector fn. onChange().\n */\n enableProductConfiguration(event = null) {\n const oneNetTierCard = [...document.querySelectorAll('.js-one-net-variation-card')].map((card) => card.closest('.pdp-card-section'));\n const isOneNetSeatSelectionEventFired = event && event.type === 'oneNet:seatSelection';\n this.isOneNetSeatSelected = isOneNetSeatSelectionEventFired && event?.detail?.isOneNetSeatSelected;\n this.areOneNetSeatsBelowThreshold = isOneNetSeatSelectionEventFired && event?.detail?.areOneNetSeatsBelowThreshold;\n this.shouldDisableOneNetConfiguration = !this.isOneNetSeatSelected || this.areOneNetSeatsBelowThreshold; // Minimum requirement to enable the whole configurator.\n\n // Enable the sidebar on availability check success or if one net and a seat has been selected.\n const elements = [\n this.form,\n ...this.pdpSubmitButtons,\n ...(this.isOneNet ? oneNetTierCard : []),\n ...(this.isBusinessInternet || this.isOneNetSeatSelected || this.editMode || this.isSharedOneNetConfiguration ? [this.sidebar] : [])\n ];\n const elementsToEnable = elements.filter(Boolean); // Filter out falsy values.\n const oneNetCriteria = this.isOneNet && this.success && !this.isPageDesignerComponent;\n const businessInternetCriteria = this.isBusinessInternet && this.success && !this.unableToOrder && !this.isPageDesignerComponent;\n\n if (businessInternetCriteria || oneNetCriteria) {\n elementsToEnable.forEach((element) => {\n if (element) {\n element.classList.remove('opacity-50', 'pe-none');\n element.removeAttribute('disabled');\n }\n });\n }\n\n // For one net, on availability check success, we only enable the tier card, rest must be disabled and enabled only after selecting a seat, see fn disableProductConfiguration. Do not disable for edit mode, since seats are already selected\n if (oneNetCriteria && this.shouldDisableOneNetConfiguration && !this.editMode && !this.isSharedOneNetConfiguration)\n this.disableProductConfiguration.bind(this)({ isEditLocation: false });\n }\n\n /**\n * @function disableProductConfiguration\n * @description Fade out the form and remove pointer events. This does/should not execute for the PD postcode check component.\n * @param {boolean} isEditLocation - Default is true for when this function is being called by an event listener.\n */\n disableProductConfiguration({ isEditLocation = true }) {\n if (this.isPageDesignerComponent) return;\n const nonTierOneNetCards = [...document.querySelectorAll('.js-pdp-card-section:not(.js-one-net-variation-card)')];\n\n // Remove all olds cards\n if (this.isOneNet) {\n nonTierOneNetCards.forEach((card) => card.parentElement?.removeChild(card));\n }\n\n // If we are in edit mode, then we disable the entire form regardless of configurator type, the configurator specific elements will be re-evaluated in fn enableProductConfiguration.\n const elements = [...this.pdpSubmitButtons, ...(this.isOneNet && !isEditLocation ? nonTierOneNetCards : [this.form, this.sidebar])];\n\n // If one-net, disable sidebar if seats are below threshold after selection.\n if (this.shouldDisableOneNetConfiguration) elements.push(this.sidebar);\n\n elements.forEach((element) => {\n if (element) {\n element.classList.add('opacity-50', 'pe-none');\n element.setAttribute('disabled', '');\n }\n });\n\n // Reset contract duration\n const defaultDuration = document.querySelector('.js-contract-duration-card input[name=\"contractDuration\"][value=\"36\"]:not(:checked)');\n defaultDuration?.dispatchEvent(new CustomEvent('change'));\n }\n\n /**\n * @function removeLocation\n * @description Removes the previous location result.\n */\n removeLocation() {\n [this.parentElement.querySelector('.js-postcode-response'), document.querySelector('.js-current-address')].forEach((element) =>\n element?.parentElement.removeChild(element)\n );\n }\n\n /**\n * @function showEditLocation\n * @description Shows a button which allows a customer to edit the configuration.\n */\n showEditLocation() {\n const editButton = this.parentElement.querySelector('.js-postcode-edit');\n if (editButton) {\n editButton.addEventListener('click', this.removeLocation);\n editButton.addEventListener('click', PCHelpers.showForm.bind(this));\n editButton.addEventListener('click', this.disableProductConfiguration.bind(this));\n }\n spinner.stop();\n }\n\n /**\n * @function setAddress\n * @description Sets the address in the sidebar.\n * @returns {void} Early exit if this is the PD component version of VZPostcodeCheck.\n */\n setAddress() {\n if (this.isPageDesignerComponent) return;\n\n const extension = this.address.extension || this.address.houseNumberExtension || '';\n const template = `
\n
${this.address.street} ${this.address.houseNumber} ${extension},
\n
${this.address.postalCode} ${this.address.city}
\n \n \n \n
`;\n document.querySelector('#configuration-details .js-configurator-summary-group-list').insertAdjacentHTML('afterbegin', template);\n\n this.updateChatInfo();\n }\n\n /**\n * @function updateChatInfo\n * @description Will update the hidden input field (if available) containing information for the chat agent\n */\n updateChatInfo() {\n const dataField = document.getElementById('activeConfiguratorGroup');\n if (!dataField) return;\n\n dataField.dispatchEvent(\n new CustomEvent('locationChange', {\n detail: this.address || this.addressCheckAddressParts\n })\n );\n }\n\n /**\n * @function updateResult\n * @param {JSON} availabilityCheckResponseData - Response object containing the HTML response string.\n * @description Removes the previous location and inserts the new one.\n */\n updateResult(availabilityCheckResponseData) {\n const {\n success: isResponseSuccessful,\n serverErrors,\n paid,\n speed,\n html: responseHtml,\n address,\n unableToOrder = null,\n locationAlreadyInBasket = null,\n locationHasExistingSubscription = null\n } = availabilityCheckResponseData;\n this.success = isResponseSuccessful;\n this.unableToOrder = unableToOrder;\n this.removeLocation();\n\n // All the error scenarios, on which we push an event to the data layer. NOTE: not sent when locationAlreadyInBasket.\n if ((address?.active || !isResponseSuccessful || unableToOrder) && this.addressCheckAddressParts && !this.isOneNet) {\n PCHelpers.pushErrorsToDataLayer(this.addressCheckAddressParts, locationAlreadyInBasket);\n }\n\n // BO-1743: If the location is outside the serviceable area, we show a modal for BI.\n if (this.isBusinessInternet && unableToOrder && !locationHasExistingSubscription) {\n const locationUnavailableModal = document.getElementById('location-unavailable-modal');\n locationUnavailableModal.render();\n }\n\n if ((!isResponseSuccessful || locationAlreadyInBasket) && serverErrors.length) {\n PCHelpers.showFeedbackMessage.bind(this)(serverErrors[0]);\n return;\n }\n\n this.PAID = paid;\n this.availableSpeed = speed;\n this.insertAdjacentHTML('afterEnd', responseHtml); // Inject the success or error html.\n\n // Dispatch the availability:update event so the page designer components reassign the event listeners.\n document.dispatchEvent(new CustomEvent('availability:update'));\n\n // Prevent default scrolling on IOS, so document is scrolled to top once results are populated.\n if (isIOS()) {\n const outputWrapper = document.querySelector('.js-postcode-response');\n scrollTo(outputWrapper.getBoundingClientRect());\n }\n\n if (unableToOrder && this.addressCheckAddress) {\n PCHelpers.handleUnableToOrder.bind(this)();\n }\n if (!unableToOrder) {\n const responseHeadingElement = this.parentElement.querySelector('.js-availability-response-address');\n responseHeadingElement.removeAttribute('unabletoorder');\n }\n\n if ((typeof address !== 'string' && address) || this.isOneNet) {\n // In scenarios where unableToOrder is true, the address is a string of undefined, in that case, we use addressCheckAddressParts.\n this.address = typeof address === 'string' && (address.includes('undefined') || address.length === 0) ? this.addressCheckAddressParts : address;\n this.setAddress.call(this);\n }\n\n // Store the saved address in a cookie so it can be restored when the form has been cleared - BO-1660.\n const addressData = {\n postcode: this.postcodeInputElement.value,\n houseNumber: this.houseNumberInputElement.value,\n paid: paid\n };\n\n if (this.additionSelectElement.selectedIndex) {\n addressData.addition = this.additionSelectElement.getAttribute('value');\n }\n\n // Availability form address cookie \"ADDRESS-{postcode}{housenumber}{addition}\"\n const availabilityFormAddressCookieName = `ADDRESS-${addressData.postcode.replace(' ', '')}${addressData.houseNumber}${addressData.addition || ''}`;\n const availabilityFormAddressCookie = `availabilityFormAddressData-${availabilityFormAddressCookieName}`;\n\n setCookie(availabilityFormAddressCookie, JSON.stringify(addressData), window.location.hostname, 0.5);\n\n document.dispatchEvent(new CustomEvent('postcodeChanged'));\n\n this.setBiState(responseHtml);\n PCHelpers.hideForm.bind(this)();\n }\n\n /**\n * @function executeAvailabilityCheck\n * @description Performs the availability check when the form is submitted and the address check is successful.\n * Updates the DOM with location data.\n */\n executeAvailabilityCheck() {\n spinner.start();\n\n PCHelpers.fetchAddressAndAvailability(this.action, this)\n .then(this.updateResult.bind(this))\n .then(this.enableProductConfiguration.bind(this))\n .then(this.updateURLs.bind(this))\n .then(this.disableUnavailableSpeeds.bind(this))\n .catch(PCHelpers.handleErrors.bind(this))\n .finally(this.showEditLocation.bind(this));\n }\n\n /**\n * @function handleAvailabilityFormSubmit\n * @param {FormEvent} event - Form submit event.\n * @description Handles the address check when the availability form is submitted. Then, if successful, it kicks of the availability check.\n */\n handleAvailabilityFormSubmit(event) {\n event.preventDefault();\n if (!this.checkValidity()) return;\n\n trackPdpEccomerceEvent(this.configuratorType, {\n name: 'Postcode check',\n number: 2\n });\n\n // BO-1570 - Address check has to be performed before availability check so that the availability check does not fire if the address is not found.\n this.addressCheck\n .executeAddressCheck()\n .then(this.executeAvailabilityCheck.bind(this))\n .catch((error) => PCHelpers.showFeedbackMessage.bind(this)(error)) // Handle rejection from promise returned in fn executeAddressCheck.\n .finally(spinner.stop);\n }\n\n /**\n * @function updateURLs\n * @description Updates all URLs to have the PAID. This does/should not execute for the PD postcode check component.\n */\n updateURLs() {\n if (!(this.success && this.PAID)) return;\n\n [...this.parentSelector.querySelectorAll('[data-url]')].forEach((element) => {\n const url = element.getAttribute('data-url');\n const newURL = appendParamToURL(url, 'paid', this.PAID);\n element.setAttribute('data-url', newURL);\n });\n }\n\n /**\n * @function disableUnavailableSpeeds\n * @description Disables speeds which are not available in a given region.\n */\n disableUnavailableSpeeds() {\n if (!(this.success && this.availableSpeed)) return;\n\n const speedNumber = parseInt(this.availableSpeed, 10);\n [...this.parentSelector.querySelectorAll('[name=\"tier\"]')].forEach((element) => {\n const elementValueNumber = parseInt(element.value, 10);\n if (elementValueNumber > speedNumber || (speedNumber === 1000 && elementValueNumber === 700)) {\n element.setAttribute('disabled', 'disabled');\n element.nextElementSibling.classList.add('opacity-50', 'pe-none');\n\n if (element.hasAttribute('checked')) {\n element.removeAttribute('checked');\n this.selectHighestPossibleTier();\n }\n } else {\n element.removeAttribute('disabled');\n element.nextElementSibling.classList.remove('opacity-50', 'pe-none');\n }\n });\n }\n\n /**\n * @function selectHighestPossibleTier\n * @description Sorts all the tiers on speed, filters out unavailable tiers and then makes the highest available tier active.\n * This does/should not execute for the PD postcode check component.\n */\n selectHighestPossibleTier() {\n if (this.isPageDesignerComponent) return;\n\n // Available tiers\n const tiers = [...this.form.querySelectorAll('[name=\"tier\"]:not(:disabled)')];\n\n // Highest tier first\n const sortedTiers = tiers.sort((a, b) => parseInt(b.value, 10) - parseInt(a.value, 10));\n\n // First available tier\n const highestPossibleSpeed = sortedTiers.find(\n (tier) => parseInt(tier.value, 10) === parseInt(this.availableSpeed, 10) || parseInt(tier.value, 10) <= parseInt(this.availableSpeed, 10)\n );\n\n // A change event needs to be triggered to initiate a new variation fetch\n const event = new Event('change', {\n bubbles: true,\n cancelable: true\n });\n highestPossibleSpeed.dispatchEvent(event);\n }\n\n /**\n * @function autoSubmitForm\n * @description Will auto submit the form on page load if the user is in edit mode and PAID is available.\n */\n autoSubmitForm() {\n this.PAID = this.hiddenInputWithPAID && this.hiddenInputWithPAID.value !== 'null' ? this.hiddenInputWithPAID.value : getParamFromURL(window.location.href, 'paid');\n\n // Availability form address cookie \"ADDRESS-{postcode}{housenumber}{addition}\"\n const availabilityFormAddressCookieName = this.PAID;\n const { postcode, houseNumber, addition, paid } = JSON.parse(getCookie(`availabilityFormAddressData-${availabilityFormAddressCookieName}`));\n\n // Restore the form field values so that this.checkValidity() passes, and the fields are filled if the user chooses to edit the address - BO-1660.\n if (postcode && houseNumber) {\n this.postcodeInputElement.value = postcode;\n this.houseNumberInputElement.value = houseNumber;\n\n if (addition) {\n this.additionSelectElement.value = addition;\n this.additionSelectElement.setAttribute('value', addition);\n }\n\n // Call setFieldStatus so the fields are formatted correctly.\n [this.postcodeInputElement, this.houseNumberInputElement].forEach((input) => input.setFieldStatus());\n }\n\n if (this.PAID && this.checkValidity()) {\n this.hiddenInputWithPAID.value = paid;\n const customEvent = new CustomEvent('submit');\n this.dispatchEvent(customEvent);\n }\n }\n\n setBiState(responseHtml) {\n const template = document.createElement('template');\n template.innerHTML = responseHtml;\n const isOrderable = template.content.querySelector('[data-bi-orderable]')?.getAttribute('data-bi-orderable');\n this.parentElement.closest('[data-configurator-type]')?.setAttribute('data-bi-orderable', isOrderable);\n }\n}\n\nif (!window.customElements.get('vz-postcode-check')) {\n window.customElements.define('vz-postcode-check', VZPostCodeCheck, { extends: 'form' });\n}\n","'use strict';\n\nimport { CONST, documentReady, addEvent } from 'app_vodafone_ziggo/util/util';\n\n/**\n * @constant {Object} selectors - Selectors used for the Prompt\n * @property {string} promptOpen - .js-btn-prompt-open\n * @property {string} promptCancel - .js-btn-prompt-cancel\n * @property {string} promptConfirm - .js-btn-prompt-confirm\n */\nconst selectors = {\n prompt: '.js-prompt',\n promptOpen: '.js-btn-prompt-open',\n promptCancel: '.js-btn-prompt-cancel',\n promptConfirm: '.js-btn-prompt-confirm',\n chatPromptOpen: '.dimelo_chat_show_when_offline',\n chatClosedPrompt: '#bscan-chat-closed'\n};\n\n/**\n * @private promptOpen\n * @param {event} event - The click event\n */\nfunction promptOpen(event) {\n const button = event.target;\n const target = button.getAttribute(CONST.attributes.target);\n const prompt = document.querySelector(target);\n\n if (prompt) {\n prompt.classList.add(CONST.classes.active);\n }\n}\n\n/**\n * @private promptClose\n * @param {event} event - The click event\n * @param {boolean} confirm - If the \"confirm\" button has been clicked\n */\nfunction promptClose(event, confirm) {\n if (!confirm) {\n event.preventDefault();\n }\n\n const button = event.target;\n const prompt = button.closest(selectors.prompt);\n\n if (prompt) {\n prompt.classList.remove(CONST.classes.active);\n button.blur(); // Remove the focus on the button, necessary for BScan keyboard navigation\n }\n}\n\ndocumentReady(() => {\n addEvent(document, CONST.events.click, selectors.promptOpen, promptOpen);\n addEvent(document, CONST.events.click, selectors.promptCancel, (event) => {\n promptClose(event, false);\n });\n addEvent(document, CONST.events.click, selectors.promptConfirm, (event) => {\n promptClose(event, true);\n });\n\n addEvent(document, CONST.events.click, selectors.chatPromptOpen, (event) => {\n const button = event.target;\n\n if (!button.getAttribute(CONST.attributes.target)) {\n button.setAttribute(CONST.attributes.target, selectors.chatClosedPrompt);\n }\n\n promptOpen(event);\n });\n});\n","'use strict';\n\nimport { setCookie, getCookie } from 'Util/cookies';\n\n/**\n * @function getJourney\n * @description Retrieves the current journey a customer is in.\n * @returns {Array} An Array of products to be configured in the current journey.\n */\nfunction getJourney() {\n return (\n getCookie('journey')\n ?.split('|')\n .filter((item) => item.length > 0) || []\n );\n}\n\n/**\n * @function notifyJourneyModal\n * @param {Array} journey - A stringified version of the journey Object\n * @description Notifies the journey modal on the new journey state\n */\nfunction notifyJourneyModal(journey) {\n const journeyModal = document.getElementById('journey-modal');\n if (journeyModal) {\n journeyModal.setAttribute('products', journey.join('|'));\n }\n}\n\n/**\n * @function updateJourney\n * @param {Array} journey - The updated journey\n * @param {Object} urls - The urls for adding journey products to basket\n * @description Updates the journey with newly added or removed products.\n */\nfunction updateJourney(journey, urls) {\n // cookie lifetime is similar to basket lifetime (4h)\n setCookie('journey', journey.join('|'), window.location.hostname, 0.1667);\n if (urls) {\n setCookie('journeyUpdateUrl-business-mobile', urls['business-mobile'], window.location.hostname, 0.1667);\n setCookie('journeyUpdateUrl-internet', urls.internet, window.location.hostname, 0.1667);\n }\n}\n\n/**\n * @function clearJourney\n * @description Clears the journey\n */\nfunction clearJourney() {\n setCookie('journey', null, window.location.hostname, 0);\n setCookie('journeyUpdateUrl-business-mobile', null, window.location.hostname, 0);\n setCookie('journeyUpdateUrl-internet', null, window.location.hostname, 0);\n}\n\nexport { clearJourney, getJourney, notifyJourneyModal, updateJourney };\n","'use strict';\n\nimport { getJourney, notifyJourneyModal, updateJourney } from './journeyHelper';\n\nexport default class VZJourney extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.addEventListener('change', this.onChange);\n this.addEventListener('deselect', this.setState);\n this.setState();\n this.showOrHideDependingOnBusinessInternetAccess();\n document.addEventListener('postcodeChanged', this.showOrHideDependingOnBusinessInternetAccess.bind(this));\n }\n\n disconnectedCallback() {\n this.removeEventListener('change', this.onChange);\n this.removeEventListener('deselect', this.setState);\n document.removeEventListener('postcodeChanged', this.showOrHideDependingOnBusinessInternetAccess.bind(this));\n }\n\n onChange() {\n const id = this.querySelector('input[name$=_journey]')?.id;\n if (id.includes('_dummy')) {\n this.constructor.removeStep(id);\n } else {\n this.constructor.addStep(id);\n }\n this.setState();\n this.triggerLinkedProduct();\n }\n\n setState() {\n const inputField = this.querySelector('input[name$=_journey]');\n const { id } = inputField;\n const journey = getJourney();\n if (journey.indexOf(id) !== -1 || (id.includes('_dummy') && journey.indexOf(id.split('_dummy')[0]) === -1)) {\n inputField.setAttribute('checked', 'checked');\n inputField.setAttribute('disabled', 'disabled');\n } else {\n inputField.removeAttribute('checked');\n inputField.removeAttribute('disabled');\n }\n }\n\n triggerLinkedProduct() {\n const id = this.querySelector('input[name$=_journey]')?.id;\n const linkedProductID = id.includes('_dummy') ? id.split('_dummy')[0] : `${id}_dummy`;\n const linkedProduct = document.querySelector(`vz-journey input[type=\"radio\"]#${linkedProductID}`);\n linkedProduct.closest('vz-journey').dispatchEvent(new CustomEvent('deselect'));\n }\n\n showOrHideDependingOnBusinessInternetAccess() {\n const isBIAvailable = !document.querySelector('.js-availability-response-address')?.hasAttribute('unabletoorder');\n const journeyCardElement = this.closest('.js-pdp-card-section');\n if (isBIAvailable) {\n journeyCardElement.classList.remove('d-none');\n } else {\n journeyCardElement.classList.add('d-none');\n }\n }\n\n static addStep(productID) {\n const journey = getJourney();\n\n journey.push(productID);\n const journeyArray = [...new Set(journey)]; // ensure unique values\n updateJourney(journeyArray);\n notifyJourneyModal(journeyArray);\n }\n\n static removeStep(productID) {\n const journey = getJourney();\n const index = journey.indexOf(productID.split('_dummy')[0]);\n if (index > -1) {\n journey.splice(index, 1);\n updateJourney(journey);\n notifyJourneyModal(journey);\n }\n }\n}\n\nif (!window.customElements.get('vz-journey')) {\n window.customElements.define('vz-journey', VZJourney);\n}\n","'use strict';\n\nimport VZModal from 'Components/modals/VZModal';\nimport { getJourney, updateJourney } from './journeyHelper';\n\nexport default class VZJourneyModal extends VZModal {\n constructor() {\n super();\n }\n\n static get observedAttributes() {\n return ['products', 'class'];\n }\n\n attributeChangedCallback(name, oldValue, newValue) {\n if (name === 'products') {\n const value = newValue.split('|');\n this.toggleProductVisibility(value);\n }\n\n if (name === 'class' && newValue.includes('show')) this.updateModal();\n }\n\n connectedCallback() {\n this.setInitialState();\n }\n\n setInitialState() {\n this.setAttribute('products', getJourney().join('|'));\n }\n\n updateModal() {\n const checkboxes = [...document.querySelectorAll('vz-journey input:checked')];\n const productIDS = checkboxes\n .map((item) => item.id)\n .concat(document.querySelector('[data-configurator-type]')?.dataset?.configuratorType)\n .concat(JSON.parse(this.getAttribute('products-in-cart')))\n .filter((item) => item && !item.includes('_dummy'));\n this.updateResources();\n\n if (checkboxes.length > 0 && !productIDS.every((id) => id === 'one-net')) {\n const updateUrls = {\n 'business-mobile': this.querySelector('li[data-id=business-mobile]')?.getAttribute('data-url'),\n internet: this.querySelector('li[data-id=internet]')?.getAttribute('data-url')\n };\n updateJourney(productIDS, updateUrls);\n this.setAttribute('products', productIDS.join('|'));\n }\n }\n\n getNextProduct() {\n const nextProduct = this.querySelector('[data-id]:not(.d-none):not(.order-0)');\n return nextProduct?.dataset || {};\n }\n\n updateResources() {\n const { addtocart, subtitle, title, url } = this.getNextProduct();\n if (!addtocart) {\n this.querySelector('.js-subtitle').classList.add('d-none');\n this.querySelector('.js-title').classList.add('d-none');\n this.querySelector('.js-next-product').classList.add('d-none');\n this.querySelector('.js-to-cart').classList.remove('d-none');\n } else {\n this.querySelector('.js-next-product').innerText = addtocart;\n this.querySelector('.js-subtitle').innerText = subtitle;\n this.querySelector('.js-subtitle').classList.remove('d-none');\n this.querySelector('.js-title').innerText = title;\n this.querySelector('.js-title').classList.remove('d-none');\n this.querySelector('.js-next-product').href = url;\n this.querySelector('.js-next-product').classList.remove('d-none');\n this.querySelector('.js-to-cart').classList.add('d-none');\n }\n }\n\n /**\n * @function populateModal\n * @param {Array} productsInJourney - Products in the journey\n */\n toggleProductVisibility(productsInJourney) {\n [...this.querySelectorAll('[data-id]')].forEach((product) => {\n if (productsInJourney.includes(product.getAttribute('data-id'))) {\n product.classList.remove('d-none');\n } else {\n product.classList.add('d-none');\n }\n });\n }\n}\n\nif (!window.customElements.get('vz-journey-modal')) {\n window.customElements.define('vz-journey-modal', VZJourneyModal);\n}\n","'use strict';\n\nimport VZSpinner from 'Components/VZSpinner';\nimport { showErrorModal } from 'Root/modal';\n\nexport default class VZAddBase extends HTMLElement {\n constructor() {\n super();\n this.form = document.querySelector('#product-form');\n this.editMode = document.querySelector('.js-edit-mode');\n this.spinner = document.querySelector('vz-spinner') || new VZSpinner();\n }\n\n /**\n * @function getAddons\n * @return {string} - Selected addons stringified\n * @description Returns the selected addons\n */\n static getAddons() {\n return document.getElementById('addons')?.value || '[]';\n }\n\n /**\n * @function getAllProducts\n * @return {Array} - An array of linked products or an empty Array.\n * @description Looks for all one net products: additional, required, optional.\n */\n static getAllProducts() {\n const additionalProducts = JSON.parse(document.getElementById('additionalProducts')?.value || '[]');\n const requiredBusinessRulesProducts = JSON.parse(document.getElementById('requiredBusinessRulesProducts')?.value || '[]');\n const optionalBusinessRulesAddons = JSON.parse(document.getElementById('optionalBusinessRulesAddons')?.value || '[]');\n const allProducts = [...additionalProducts, ...requiredBusinessRulesProducts, ...optionalBusinessRulesAddons]\n .filter((item) => item)\n .filter((product) => product.pid && product.quantity);\n\n return allProducts || [];\n }\n\n /**\n * @function getPAID\n * @return {HTMLInputElement} hidden input containing the PAID\n * @description Gets the PAID input field\n */\n static getPAID() {\n return document.getElementById('paid');\n }\n\n /**\n * @function handleNetworkError\n * @description This function is called when adding to the basket for business internet products returns a 500.\n */\n static handleNetworkError() {\n const { title, body, cta } = JSON.parse(document.querySelector('vz-product-card').dataset.generalError);\n showErrorModal(title, body, cta);\n }\n}\n","'use stict';\n\n/**\n * Smoothly scrolls to an element, considering header height and an offset.\n * @param {HTMLElement} element - The DOM element to scroll to.\n */\nexport function scrollToElement(element) {\n const headerOffset = document.querySelector('.js-page-header').offsetHeight + 32;\n const elementPosition = element.getBoundingClientRect().top;\n const offsetPosition = elementPosition + window.scrollY - headerOffset;\n\n window.scrollTo({\n top: offsetPosition,\n behavior: 'smooth'\n });\n}\n\n/**\n * Sets classes on an element based on its scroll position.\n * @param {HTMLElement} el - The scrollable DOM element.\n */\nexport function setScrollClasses(el) {\n const isScrollable = el.scrollHeight > el.clientHeight;\n\n if (!isScrollable) {\n el.classList.remove('is-bottom-overflowing', 'is-top-overflowing');\n return;\n }\n\n const isScrolledToBottom = el.scrollHeight <= el.clientHeight + el.scrollTop + 1;\n const isScrolledToTop = el.scrollTop === 0;\n\n el.classList.toggle('is-bottom-overflowing', !isScrolledToBottom);\n el.classList.toggle('is-top-overflowing', !isScrolledToTop);\n}\n","'use strict';\n\nimport VZAddBase from './VZAddBase';\nimport { scrollToElement } from '../../../util/domUtils';\nimport { handleTransition } from 'Util/transitions.js';\n\nexport default class VZAddDevice extends VZAddBase {\n constructor() {\n super();\n this.configuratorType = document.querySelector('[data-configurator-type]').dataset.configuratorType;\n this.addDeviceBtn = this.querySelector('.js-add-device');\n this.devicesContainer = document.querySelector('.js-hardware-device-cards');\n this.devicesCards = document.querySelectorAll('.js-hardware-device-card');\n this.bmQuantityCard = document.querySelector('.js-business-mobile-quantity-card');\n this.addSimsLinks = document.querySelectorAll('.js-add-sims-link');\n this.addDevicesLink = document.querySelector('.js-add-devices-link');\n }\n\n connectedCallback() {\n if (this.configuratorType === 'business-mobile') {\n this.onClick = this.onClick.bind(this);\n if (this.addDeviceBtn) {\n this.addDeviceBtn.addEventListener('click', this.onClick);\n }\n }\n this.toggleVisiblity();\n\n // Scroll to BM Quantity Card\n this.addSimsLinks?.forEach((link) => {\n link.addEventListener('click', (event) => {\n event.preventDefault();\n scrollToElement(this.bmQuantityCard);\n });\n });\n\n // Keep last card open after sorting & filtering\n document.querySelector('#product-configurator')?.addEventListener('pdp:sorting', () => {\n this.addNewDevice();\n });\n document.querySelector('#product-configurator')?.addEventListener('pdp:filter', () => {\n this.addNewDevice();\n });\n }\n\n disconnectedCallback() {\n this.removeEventListener('click', this.onClick);\n }\n\n toggleVisiblity() {\n if ([...this.devicesCards].some((card) => !card.classList.contains('is-configured') && card.classList.contains('d-none'))) {\n this.classList.remove('d-none');\n } else {\n this.classList.add('d-none');\n }\n }\n\n /**\n * @function onClick\n * @description Handles the onClick\n */\n onClick() {\n handleTransition(() => {\n this.addNewDevice();\n });\n }\n\n addNewDevice() {\n // Collapse previous card\n [...this.devicesCards].forEach((card) => {\n if (!card.classList.contains('is-collapsed')) {\n card.classList.add('is-collapsed');\n }\n });\n\n const lastDeviceCard = this.devicesCards[this.devicesCards.length - 1];\n if (lastDeviceCard && lastDeviceCard.classList.contains('d-none')) {\n lastDeviceCard.classList.remove('d-none');\n }\n\n // Update this.devicesCards to include the newly added device\n this.devicesCards = document.querySelectorAll('.js-hardware-device-card');\n this.toggleVisiblity();\n\n // Scroll to the lastDeviceCard\n if (lastDeviceCard) {\n scrollToElement(lastDeviceCard);\n }\n }\n}\n\nif (!window.customElements.get('vz-add-device')) {\n window.customElements.define('vz-add-device', VZAddDevice);\n}\n","/**\n * Handles the transition for a given action.\n * If `document.startViewTransition` is available, it uses that for the transition.\n * Otherwise, it directly calls the action.\n *\n * @param {Function} action - The action to be performed during the transition.\n */\nexport function handleTransition(action) {\n if (document.startViewTransition) {\n document.startViewTransition(action);\n } else {\n action();\n }\n}\n","'use strict';\n\nimport VZAddBase from './VZAddBase';\nimport { getJourney } from 'Root/journey/journeyHelper';\n\nexport default class VZAddGroup extends VZAddBase {\n constructor() {\n super();\n this.configuratorType = document.querySelector('[data-configurator-type]').dataset.configuratorType;\n this.addToCartUrl = this.dataset.addToCartUrl;\n this.removeFromCartUrl = this.dataset.removeFromCartUrl;\n this.csSolutionId = null;\n }\n\n connectedCallback() {\n this.setDurationProperties();\n this.addEventListener('click', this.onClick);\n document.querySelector('vz-group-summary').addEventListener('variationChange', this.setDurationProperties.bind(this));\n }\n\n disconnectedCallback() {\n this.removeEventListener('click', this.onClick);\n }\n\n /**\n * @private setDurationProperties\n * @description Will set and update properties related to contract duration\n */\n setDurationProperties() {\n this.selectedDuration = document.querySelector('#contractDuration input:checked')?.id;\n }\n\n /**\n * @function submitForm\n * @description Submits the product form when the add to basket modal submit button is clicked.\n * @param {Event} event - A click event on the add to basket modal submit button.\n */\n async submitForm(event) {\n event.preventDefault();\n this.spinner.start();\n const selectedOptionalBusinessRulesAddons = this.constructor.getAllProducts();\n const optionalBusinessRulesAddonsInCart = JSON.parse(this.dataset.nonCsItemsInCart);\n\n const toBeAdded = selectedOptionalBusinessRulesAddons.filter((addon) => !optionalBusinessRulesAddonsInCart.some(({ id }) => id === addon.pid));\n const toBeRemoved = optionalBusinessRulesAddonsInCart.filter((addon) => !selectedOptionalBusinessRulesAddons.some(({ pid }) => pid === addon.id));\n\n const isPartOfJourney = document.querySelector('[name=\"isPartOfJourney\"]')?.value;\n const inJourney = getJourney()?.length > 0 && (isPartOfJourney ? isPartOfJourney === 'true' : false);\n\n // If we are in editing mode, remove the old group first\n if (this.editMode) {\n await fetch(document.querySelector('#remove-group').action, {\n method: 'GET'\n });\n }\n\n if (inJourney) {\n const belongsToGuidedJourney = document.createElement('input');\n belongsToGuidedJourney.setAttribute('type', 'hidden');\n belongsToGuidedJourney.setAttribute('name', 'belongsToGuidedJourney');\n belongsToGuidedJourney.setAttribute('value', inJourney);\n this.form.appendChild(belongsToGuidedJourney);\n }\n\n toBeRemoved.forEach(async (product) => {\n await this.submitLinkedProducts(\n toBeRemoved,\n inJourney,\n `${this.removeFromCartUrl}&${new URLSearchParams({\n pid: product.id,\n uuid: product.uuid\n })}`,\n 'GET'\n );\n });\n\n if (toBeAdded.length > 0) {\n await this.submitLinkedProducts.bind(this)(toBeAdded, inJourney, this.addToCartUrl, 'POST');\n }\n\n await this.updateContractDurations();\n [...this.form.querySelectorAll('input[name^=\"hardware_\"')].forEach((field) => field.setAttribute('disabled', 'disabled'));\n\n this.businessRulesProductsString = document.querySelector('vz-product-card')?.getAttribute('businessrules-products');\n this.businessRulesProducts = this.businessRulesProductsString && JSON.parse(this.businessRulesProductsString);\n const contractsToAdd = [];\n const duplicatesToAdd = [];\n if (this.configuratorType === 'business-mobile' && this.businessRulesProducts) {\n // Submit BM Hardware contract product\n let optionalBusinessRulesAddons = JSON.parse(this.form.querySelector('#optionalBusinessRulesAddons')?.value || '[]');\n let contractPid;\n Object.keys(this.businessRulesProducts)\n .filter((key) => this.businessRulesProducts[key].isMobileHardware)\n .forEach((key) => {\n const isMobileHardwareContract = Number.parseInt(this.businessRulesProducts[key].recurringPrice, 10) > 0;\n optionalBusinessRulesAddons = optionalBusinessRulesAddons.map((product) => {\n if (key.includes(product.pid)) {\n // BM Harware is the only businessRuleProduct which can be added to basket several times\n // Other businessRuleProducts do not support that, that's why this.businessRulesProducts includes each product ID only ones\n // If deviceIndex is filled in, then the BM Hardware with the same ID was already processes as part of toBeAdded array\n if (!product.deviceIndex) {\n product.recurringPrice = Number.parseInt(this.businessRulesProducts[key].recurringPrice, 10);\n product.oneOffPrice = Number.parseFloat(this.businessRulesProducts[key].oneOffPrice, 10);\n product.contractDuration = Number.parseInt(this.businessRulesProducts[key].contractDuration, 10);\n product.deviceIndex = key.split('---device')[1];\n product.quantity = this.businessRulesProducts[key].qty;\n } else {\n // Saving current BM Hardware with duplicated ID to duplicatesToAdd array\n // This product was not added to basket as part of toBeAdded array\n duplicatesToAdd.push({\n pid: product.pid,\n quantity: this.businessRulesProducts[key].qty,\n recurringPrice: Number.parseInt(this.businessRulesProducts[key].recurringPrice, 10),\n oneOffPrice: Number.parseFloat(this.businessRulesProducts[key].oneOffPrice, 10),\n contractDuration: Number.parseInt(this.businessRulesProducts[key].contractDuration, 10),\n deviceIndex: key.split('---device')[1]\n });\n }\n }\n return product;\n });\n if (isMobileHardwareContract) {\n contractPid = `RCTSTBET${Number.parseInt(this.businessRulesProducts[key].contractDuration, 10) === 12 ? '1' : '2'}J${Number.parseInt(\n this.businessRulesProducts[key].recurringPrice,\n 10\n )}EUF`;\n optionalBusinessRulesAddons.push({\n pid: contractPid,\n quantity: this.businessRulesProducts[key].qty\n });\n contractsToAdd.push({ pid: contractPid, quantity: this.businessRulesProducts[key].qty });\n }\n });\n if (duplicatesToAdd.length) duplicatesToAdd.forEach((duplicate) => optionalBusinessRulesAddons.push(duplicate));\n this.form.querySelector('#optionalBusinessRulesAddons').value = JSON.stringify(optionalBusinessRulesAddons);\n }\n\n if (duplicatesToAdd.length > 0) {\n // Adding to basket BM Hardware devices with duplicated IDs\n await this.submitLinkedProducts.bind(this)(duplicatesToAdd, inJourney, this.addToCartUrl, 'POST');\n }\n if (contractsToAdd.length > 0) {\n // Adding to basket zakelijk products\n await this.submitLinkedProducts.bind(this)(contractsToAdd, inJourney, this.addToCartUrl, 'POST');\n }\n\n const formData = new FormData(this.form);\n // If the previous call returned csSolutionId, this call has to use the same solution\n if (this.csSolutionId !== null) {\n formData.set('csSolutionId', this.csSolutionId);\n }\n\n fetch(this.form.action, {\n method: 'post',\n body: formData\n })\n .then((response) => response.json())\n .then((response) => {\n if (!response.success) throw new Error('Error');\n // After having added the product to the cart, show the \"added to basket\" modal or journey modal\n const modal = document.getElementById(inJourney ? 'journey-modal' : 'add-to-basket-modal');\n const hasNonCsProductsSelected = !inJourney && Array.from(document.getElementsByClassName('js-non_cs_product') ?? '').some(({ checked }) => checked);\n const bodyText = document.getElementById('addToBasketBodyNonCPQText')?.value;\n if (!inJourney && response.hideAddToBasketModal) {\n window.location.href = response.basketUrl;\n } else {\n modal.render(hasNonCsProductsSelected ? { bodyText } : {});\n }\n\n /* eslint-disable no-underscore-dangle */\n if (response.ecommerceObject && window._ddm) {\n window._ddm.trigger('ecommerce.add_to_cart', {\n data: response.ecommerceObject.ecommerce.addToCart\n });\n }\n /* eslint-enable no-underscore-dangle */\n })\n .catch(() => {\n this.constructor.handleNetworkError();\n })\n .finally(() => {\n this.spinner.stop();\n });\n }\n\n /**\n * @function updateContractDurations\n * @return {Promise} - A promise\n * @description Will return a promise that can update the contract durations of other products\n */\n updateContractDurations() {\n // Create an empty array here, because we always need to return a Promise.\n let promises = [];\n const newDuration = document.querySelector('.js-contract-duration input:checked')?.id;\n\n if (this.configuratorType === 'business-mobile' && newDuration !== '1') {\n promises = [...document.querySelectorAll('.js-contract-update')].reduce((result, updateSection) => {\n // Get all \"contract update\" forms based on the newly selected duration\n const formEqualsSelectedDuration = updateSection.querySelector(`form[id^=\"${newDuration}-\"]`);\n if (!formEqualsSelectedDuration) return result;\n\n const formData = new FormData();\n\n [...formEqualsSelectedDuration.elements].forEach((currentForm) => {\n formData.append(currentForm.name, currentForm.value);\n });\n\n result.push(\n fetch(formEqualsSelectedDuration.action, {\n body: formData,\n method: 'post'\n })\n );\n\n return result;\n }, []);\n }\n\n return Promise.all(promises);\n }\n\n /**\n * @function onClick\n * @description Handles the onClick\n * @param {Event} event - The click event fired from the add to basket button.\n */\n onClick(event) {\n event.preventDefault();\n const quantityField = document.querySelector('.js-quantity-field');\n const quantityValid = quantityField && quantityField.checkValidity();\n\n if (!quantityValid) return;\n [...this.form.querySelectorAll('[name=\"addon\"]')].forEach((field) => field.setAttribute('disabled', 'disabled'));\n [...this.form.querySelectorAll('[name=\"mobileDeviceAddons\"]')].forEach((field) => field.setAttribute('disabled', 'disabled'));\n this.submitForm.call(this, event);\n }\n\n /**\n * @function submitLinkedProducts\n * @return {Promise} - A resolved promise\n * @param {Array} products - Array of linked products\n * @param {boolean} inJourney - Is in journey\n * @param {string} url - Request URL\n * @param {string} type - Type of Request\n * @description Submits all the products which are linked to the configured one.\n */\n submitLinkedProducts(products, inJourney, url, type) {\n const formData = new FormData();\n formData.set('productData', JSON.stringify(products));\n formData.set('belongsToGuidedJourney', inJourney);\n\n // Add mandatory addons for BM Hardware products\n const mobileDeviceAddons = document.querySelector('[name=\"mobileDeviceAddons\"]')?.value;\n if (mobileDeviceAddons) {\n formData.set('addons', mobileDeviceAddons);\n }\n // If the previous call returned csSolutionId, this call has to use the same solution\n if (this.csSolutionId !== null) {\n formData.set('csSolutionId', this.csSolutionId);\n }\n\n return fetch(url, {\n method: type,\n ...(type === 'POST' && { body: formData })\n })\n .then((response) => response.json())\n .then((response) => {\n if (response && response.csSolutionId) this.csSolutionId = response.csSolutionId;\n })\n .catch(() => {\n this.spinner.stop();\n this.constructor.handleNetworkError();\n });\n }\n}\n\nif (!window.customElements.get('vz-add-group')) {\n window.customElements.define('vz-add-group', VZAddGroup);\n}\n","'use strict';\n\nimport VZAddBase from './VZAddBase';\nimport { getJourney } from 'Root/journey/journeyHelper';\n\nexport default class VZAddLocation extends VZAddBase {\n constructor() {\n super();\n this.onSubmit = this.onSubmit.bind(this);\n this.submitForm = this.submitForm.bind(this);\n this.addToCartUrl = this.dataset.addToCartUrl;\n this.removeFromCartUrl = this.dataset.removeFromCartUrl;\n this.csSolutionId = null;\n }\n\n connectedCallback() {\n this.querySelector('button').addEventListener('click', this.onSubmit);\n }\n\n disconnectedCallback() {\n this.querySelector('button').removeEventListener('click', this.onSubmit);\n }\n\n /**\n * @function getLinkedProducts\n * @return {Array} - An array of linked products or an empty Array.\n * @description Looks for the links products\n */\n static getLinkedProducts() {\n return [document.getElementById('linkedProducts'), document.getElementById('optionalBusinessRulesAddons')]\n .map((element) => JSON.parse(element.value))\n .flat()\n .filter((product) => typeof product === 'string' || (product.pid && product.quantity))\n .map((product) => {\n if (typeof product === 'string') {\n return { pid: product, quantity: 1 };\n }\n return product;\n });\n }\n\n /**\n * @function getMainProductId\n * @return {string} - Main product ID\n * @description Returns the main product ID which the addons are linked to\n */\n static getMainProductId() {\n return document.getElementById('mainProductId').value || '';\n }\n\n /**\n * @function submitLinkedProducts\n * @return {Promise} - A resolved promise\n * @param {boolean} inJourney - Is in journey\n * @description Submits all the products which are linked to the configured one.\n */\n submitLinkedProducts(inJourney) {\n const products = this.constructor.getLinkedProducts().map((product) => {\n const formData = new FormData();\n formData.set('quantity', 1);\n formData.set('pid', product.pid);\n formData.set('paid', this.constructor.getPAID().value);\n formData.set('belongsToGuidedJourney', inJourney);\n if (product.pid === this.constructor.getMainProductId()) {\n formData.set('addons', this.constructor.getAddons());\n }\n ['postalCode', 'houseNumber', 'houseNumberAddition'].forEach((field) => {\n formData.append(field, document.getElementById(`js-active-address-${field}`)?.value || '');\n });\n // If the previous call returned csSolutionId, this call has to use the same solution\n if (this.csSolutionId !== null) {\n formData.set('csSolutionId', this.csSolutionId);\n }\n return formData;\n });\n const submitProductsAsync = async () => {\n /* eslint-disable no-await-in-loop */\n for (let i = 0; i < products.length; i++) {\n // If the previous call returned csSolutionId, this call has to use the same solution\n if (this.csSolutionId !== null) {\n products[i].set('csSolutionId', this.csSolutionId);\n }\n await fetch(this.form.action, {\n // eslint-disable-line\n method: 'POST',\n body: products[i]\n })\n .then((response) => {\n if (response.status === 500) throw new Error('Network error');\n return response.json();\n })\n .then((response) => {\n if (response && response.csSolutionId) this.csSolutionId = response.csSolutionId;\n })\n .catch(this.constructor.handleNetworkError);\n }\n };\n return submitProductsAsync();\n }\n\n /**\n * @function submitPresets\n * @description Submits all products within a package\n * @returns {Promise} a promise\n */\n submitPresets() {\n const presets = document.querySelector('input[name=\"presets\"]')?.value;\n if (presets) {\n const parsedPresets = JSON.parse(presets);\n const promises = Object.keys(parsedPresets)\n .reduce((prev, current) => {\n prev.push(parsedPresets[current].products);\n return prev;\n }, [])\n .flat()\n .map(({ ajaxAttributes }) => {\n const formData = new FormData();\n if (this.csSolutionId !== null) {\n formData.set('csSolutionId', this.csSolutionId);\n }\n Object.keys(ajaxAttributes).forEach((key) => {\n if (key === 'paid' && ajaxAttributes[key] === null) {\n ajaxAttributes[key] = this.constructor.getPAID()?.value;\n }\n\n if (typeof ajaxAttributes[key] === 'object') {\n ajaxAttributes[key] = JSON.stringify(ajaxAttributes[key]);\n }\n\n formData.append(key, ajaxAttributes[key]);\n });\n\n return fetch(this.form.action, {\n method: 'post',\n body: formData\n });\n });\n\n return Promise.all(promises);\n }\n return Promise.all([]);\n }\n\n /**\n * @function onSubmit\n * @param {SubmitEvent} event - The form submit\n * @description Perform different actions based on whether the user is in editing mode or not\n */\n async onSubmit(event) {\n event.preventDefault();\n this.classList.add('pe-none');\n\n // If we are in editing mode, remove the old location first\n if (this.editMode) {\n await fetch(document.querySelector('#remove-location').action, {\n method: 'POST'\n });\n }\n\n this.form.appendChild(this.constructor.getPAID());\n [...this.form.querySelectorAll('input[name=\"tier\"]')].forEach((field) => field.setAttribute('disabled', 'disabled'));\n\n await this.submitPresets();\n this.submitForm.call(this);\n }\n\n /**\n * @function submitForm\n * @description Submits all linked products, followed by the configured product\n */\n async submitForm() {\n this.spinner.start();\n\n const isPartOfJourney = document.querySelector('[name=\"isPartOfJourney\"]')?.value;\n const inJourney = getJourney()?.length > 0 && isPartOfJourney === 'true' && document.getElementById('journey-modal');\n\n await this.submitLinkedProducts(inJourney);\n\n // prepare configuratorType field\n const configuratorType = document.createElement('input');\n configuratorType.setAttribute('type', 'hidden');\n configuratorType.setAttribute('name', 'configuratorType');\n configuratorType.setAttribute('value', 'business-internet');\n this.form.appendChild(configuratorType);\n\n if (inJourney) {\n const belongsToGuidedJourney = document.createElement('input');\n belongsToGuidedJourney.setAttribute('type', 'hidden');\n belongsToGuidedJourney.setAttribute('name', 'belongsToGuidedJourney');\n belongsToGuidedJourney.setAttribute('value', inJourney);\n this.form.appendChild(belongsToGuidedJourney);\n }\n\n const formData = new FormData(this.form);\n ['city', 'street', 'room'].forEach((field) => {\n formData.append(field, document.querySelector(`.js-postcode-response input#${field}`)?.value || '');\n });\n ['postalCode', 'houseNumber', 'houseNumberAddition'].forEach((field) => {\n formData.append(field, document.getElementById(`js-active-address-${field}`)?.value || '');\n });\n if (this.csSolutionId !== null) {\n formData.set('csSolutionId', this.csSolutionId);\n }\n\n fetch(this.form.action, {\n method: 'post',\n body: formData\n })\n .then((response) => response.json())\n .then((response) => {\n if (!response.success) throw new Error('Error');\n\n // After having added the product to the cart, show the \"added to basket\" modal or journey modal\n const modal = document.getElementById(inJourney ? 'journey-modal' : 'add-to-basket-modal');\n const hasNonCsProductsSelected = !inJourney && Array.from(document.getElementsByClassName('js-non_cs_product') ?? '').some(({ checked }) => checked);\n const bodyText = document.getElementById('addToBasketBodyNonCPQText')?.value;\n if (!inJourney && response.hideAddToBasketModal) {\n window.location.href = response.basketUrl;\n } else {\n modal.render(hasNonCsProductsSelected ? { bodyText } : {});\n }\n\n /* eslint-disable no-underscore-dangle */\n if (response.ecommerceObject && window._ddm) {\n window._ddm.trigger('ecommerce.add_to_cart', {\n data: response.ecommerceObject.ecommerce.addToCart\n });\n }\n /* eslint-enable no-underscore-dangle */\n })\n .catch(this.constructor.handleNetworkError)\n .finally(this.spinner.stop);\n }\n}\n\nif (!window.customElements.get('vz-add-location')) {\n window.customElements.define('vz-add-location', VZAddLocation);\n}\n","'use strict';\n\nimport VZAddBase from './VZAddBase';\nimport { getJourney, clearJourney } from 'Root/journey/journeyHelper';\nimport { chunkArrayInGroups } from 'app_vodafone_ziggo/util/util';\nexport default class VZAddOneNet extends VZAddBase {\n constructor() {\n super();\n this.onSubmit = this.onSubmit.bind(this);\n this.submitForm = this.submitForm.bind(this);\n this.prepareForm = this.prepareForm.bind(this);\n this.journey = getJourney();\n }\n\n connectedCallback() {\n this.querySelector('button').addEventListener('click', this.onSubmit);\n }\n\n disconnectedCallback() {\n this.querySelector('button').removeEventListener('click', this.onSubmit);\n }\n\n /**\n * @function getURL\n * @return {string} url - the add to cart endpoint\n * @description Returns the endpoint for adding products to the cart\n */\n static getURL() {\n return document.getElementById('product-form').action;\n }\n\n /**\n * @function submitLinkedProducts\n * @return {Promise} - A promise\n * @param {Array} products - Array of linked products\n * @param {boolean} inJourney - Is in journey\n * @description Submits all the products which are linked to the configured one.\n */\n submitLinkedProducts(products, inJourney) {\n const productChunks = chunkArrayInGroups(products, 3);\n const promises = productChunks.map((productData) => {\n const formData = new FormData();\n formData.set('productData', JSON.stringify(productData));\n formData.set('paid', this.constructor.getPAID().value);\n if (inJourney) {\n formData.set('belongsToGuidedJourney', true);\n }\n ['postalCode', 'houseNumber', 'houseNumberAddition'].forEach((field) => {\n formData.append(field, document.getElementById(`js-active-address-${field}`)?.value || '');\n });\n\n return fetch(this.constructor.getURL(), {\n method: 'POST',\n body: formData\n })\n .then((response) => {\n if (response.status === 500) throw new Error('Network error');\n })\n .catch(this.constructor.handleNetworkError);\n });\n return Promise.all(promises);\n }\n\n /**\n * @function prepareForm\n * @description Adds the PAID and disables unrelated fields for the backend\n * @param {boolean} inJourney - Is in journey\n */\n prepareForm(inJourney) {\n this.form.appendChild(this.constructor.getPAID());\n [...this.form.querySelectorAll('input[name=\"addon\"], input[name=\"tier\"]')].forEach((field) => field.setAttribute('disabled', 'disabled'));\n\n const formData = new FormData(this.form);\n formData.set('addons', this.constructor.getAddons());\n\n const salesRepStatus = this.constructor.getSalesRepStatus();\n formData.set('allowSalesRepToContact', salesRepStatus);\n\n formData.set('configuratorType', 'one-net');\n\n formData.set('handsetMode', document.querySelector('#handset-mode')?.value ?? 'rent');\n\n if (inJourney) {\n formData.set('belongsToGuidedJourney', true);\n }\n\n ['city', 'street', 'room'].forEach((field) => {\n formData.append(field, document.querySelector(`.js-postcode-response input#${field}`)?.value || '');\n });\n\n ['postalCode', 'houseNumber', 'houseNumberAddition'].forEach((field) => {\n formData.append(field, document.getElementById(`js-active-address-${field}`)?.value || '');\n });\n\n fetch(this.form.action, {\n method: 'post',\n body: formData\n })\n .then((response) => response.json())\n .then((response) => {\n if (!response.success) throw new Error('Error');\n\n // After having added the product to the cart, show the \"added to basket\" modal\n const modal = document.getElementById(inJourney ? 'journey-modal' : 'add-to-basket-modal');\n if (!inJourney && response.hideAddToBasketModal) {\n window.location.href = response.basketUrl;\n } else {\n modal.render(); // Overriding default options.\n }\n\n /* eslint-disable no-underscore-dangle */\n if (response.ecommerceObject && window._ddm) {\n window._ddm.trigger('ecommerce.add_to_cart', {\n data: response.ecommerceObject.ecommerce.addToCart\n });\n }\n /* eslint-enable no-underscore-dangle */\n })\n .catch(this.constructor.handleNetworkError)\n .finally(this.spinner.stop);\n }\n\n /**\n * @function onSubmit\n * @param {SubmitEvent} event - The form submit\n * @description Perform different actions based on whether the user is in editing mode or not\n */\n onSubmit(event) {\n event.preventDefault();\n this.classList.add('pe-none');\n /**\n * If we are in editing mode, remove the old location first\n * On success, submit the new form\n */\n if (this.editMode) {\n this.spinner.start();\n let url = document.querySelector('#remove-location').action;\n url = url.concat('&type=one-net');\n fetch(url, {\n method: 'POST'\n }).then(this.submitForm.bind(this));\n } else {\n this.submitForm.call(this);\n }\n }\n\n /**\n * @function submitPresets\n * @description Submits all products within a package\n * @returns {Promise} a promise\n */\n submitPresets() {\n const presets = document.querySelector('input[name=\"presets\"]')?.value;\n if (presets) {\n const parsedPresets = JSON.parse(presets);\n const promises = Object.keys(parsedPresets)\n .reduce((prev, current) => {\n prev.push(parsedPresets[current].products);\n return prev;\n }, [])\n .flat()\n .map(({ ajaxAttributes }) => {\n const formData = new FormData();\n Object.keys(ajaxAttributes).forEach((key) => {\n if (key === 'paid' && ajaxAttributes[key] === null) {\n ajaxAttributes[key] = this.constructor.getPAID()?.value;\n }\n\n if (typeof ajaxAttributes[key] === 'object') {\n ajaxAttributes[key] = JSON.stringify(ajaxAttributes[key]);\n }\n\n formData.append(key, ajaxAttributes[key]);\n });\n\n return fetch(this.form.action, {\n method: 'post',\n body: formData\n });\n });\n\n return Promise.all(promises);\n }\n return Promise.all([]);\n }\n\n /**\n * @function submitForm\n * @description Submits all linked products, followed by the configured product\n */\n async submitForm() {\n const products = this.constructor.getAllProducts();\n if (products.length === 0) return;\n\n this.spinner.start();\n\n const inJourney = (document.querySelector('#internet')?.checked || document.querySelector('#business-mobile')?.checked) && document.getElementById('journey-modal');\n\n if (this.journey && this.journey.length > 0 && !inJourney) {\n // Journey was canceled in edit mode\n clearJourney();\n }\n\n await this.submitLinkedProducts(products, inJourney);\n await this.submitPresets();\n await this.prepareForm(inJourney);\n this.spinner.stop();\n }\n\n /**\n * @function getSalesRepStatus\n * @description Checks if sales is allowed to contact\n * @returns {boolean} hardware type\n */\n static getSalesRepStatus() {\n const element = document.getElementById('noAddon');\n return element ? element.checked : true;\n }\n}\n\nif (!window.customElements.get('vz-add-one-net')) {\n window.customElements.define('vz-add-one-net', VZAddOneNet);\n}\n","'use strict';\n\nimport CONST from 'Util/constants';\nimport Animation from '../../Animation';\nimport VZConfirmationModal from '../../ConfirmationModal';\nimport Modal from 'bootstrap/js/dist/modal';\nimport { setScrollClasses } from 'Util/domUtils';\n\n/**\n * @class VZHardware\n */\nexport default class VZHardware extends HTMLInputElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.hardwareWrapper = this.closest('.js-hardware-phones');\n this.hardwareCardWrapper = this.closest('.js-hardware-device-card');\n this.phoneWrapper = this.closest('.js-hardware-phone-wrapper');\n this.phonesScrollableArea = this.closest('.js-phones-scrollable-area');\n this.productCard = this.closest('.js-product-card');\n this.cardOrderIsReversed = this.productCard.getAttribute('data-reversed') === 'true';\n\n if (!this.phoneWrapper.classList.contains('out-of-stock')) {\n this.onChange = this.onChange.bind(this);\n this.addEventListener('change', this.onChange);\n\n [...this.hardwareWrapper.querySelectorAll('.js-quantity-increase')].forEach((el) => el.addEventListener('click', this.constructor.onQuantityChange));\n\n this.hardwareWrapper.querySelector('.js-quantity-selector').addEventListener('input', this.constructor.onQuantityInput);\n\n this.phoneWrapper.querySelector('.js-hardware-phone-toggle')?.addEventListener('click', this.toggleDevice.bind(this));\n\n this.phoneWrapper.querySelector('.js-hardware-phone-delete')?.addEventListener('click', this.showConfirmationModal.bind(this));\n\n this.phoneWrapper.querySelector('.js-hardware-phone-edit')?.addEventListener('click', this.editConfiguration.bind(this));\n\n // Listen for scroll events on the phones scrollable area to show/hide scroll indicators\n this.phonesScrollableArea.addEventListener('scroll', (e) => {\n const el = e.currentTarget;\n setScrollClasses(el);\n });\n\n setScrollClasses(this.phonesScrollableArea);\n\n // Listen for scroll events on the phones scrollable area to show/hide scroll indicators\n this.phonesScrollableArea.addEventListener('scroll', (e) => {\n const el = e.currentTarget;\n setScrollClasses(el);\n });\n\n setScrollClasses(this.phonesScrollableArea);\n\n document.dispatchEvent(new CustomEvent('pdp:update'));\n\n this.constructor.updateTabIndex();\n\n // Modals\n this.modal = document.getElementById('hardware-specifications-modal');\n\n if (this.modal) {\n this.modalInstance = new Modal(this.modal, {});\n\n this.modal.querySelector('.js-hardware-specifications-modal-close')?.addEventListener('click', this.dismissModal.bind(this));\n\n this.modalTitle = this.modal.querySelector('.modal-title');\n this.modalBody = this.modal.querySelector('.modal-body');\n\n this.phoneWrapper.querySelector('.js-hardware-specifications')?.addEventListener('click', this.injectModalContent.bind(this));\n }\n }\n }\n\n disconnectedCallback() {\n this.removeEventListener('change', this.onChange);\n\n [...this.hardwareWrapper.querySelectorAll('.js-quantity-increase')].forEach((el) => el.removeEventListener('click', this.constructor.onQuantityChange));\n\n this.hardwareWrapper.querySelector('.js-quantity-selector').removeEventListener('input', this.constructor.onQuantityInput);\n\n this.phoneWrapper.querySelector('.js-hardware-phone-toggle')?.removeEventListener('click', this.toggleDevice.bind(this));\n\n this.phoneWrapper.querySelector('.js-hardware-phone-edit')?.removeEventListener('click', this.editConfiguration.bind(this));\n\n // Modals\n if (this.modal) this.phoneWrapper.querySelector('.js-hardware-specifications')?.removeEventListener('click', this.injectModalContent.bind(this));\n }\n\n /**\n * Hides hardware specs modal\n */\n dismissModal() {\n this.modalInstance.hide();\n }\n\n /**\n * Shows hardware specs modal\n */\n showModal() {\n this.modalInstance.show();\n }\n\n /**\n * Injects the hardware specs modal with the correct device's specs when toggled and displays the modal\n */\n injectModalContent() {\n const modalContent = this.phoneWrapper.querySelector('.js-hardware-specifications-content');\n const modalTitle = modalContent.getAttribute('data-title');\n const modalBody = modalContent.innerHTML;\n\n this.modalTitle.innerHTML = modalTitle;\n this.modalBody.innerHTML = modalBody;\n\n this.showModal();\n }\n\n /**\n * Overwrites the default checkbox toggle functionality when the hardware device is selected. It then triggers a confirmation modal.\n *\n * @param {Event} e - The event object associated with the toggle action.\n */\n toggleDevice(e) {\n // Ignore modal trigger link\n if (e.target.classList.contains('js-hardware-specifications')) return;\n\n if (this && this.checked) {\n e.preventDefault();\n\n this.showConfirmationModal();\n }\n }\n\n /**\n * Displays a confirmation modal and will remove the selected device when the user confirms.\n */\n showConfirmationModal() {\n const confirmationModal = new VZConfirmationModal();\n\n confirmationModal.toggleConfirmationModal().then((userConfirmed) => {\n if (userConfirmed) {\n this.checked = !this.checked;\n\n this.dispatchEvent(new Event('change'));\n }\n });\n }\n\n /**\n * This function collapses all hardware device cards and expands the current card\n * to allow configuration editing.\n * @function editConfiguration\n * @returns {void}\n */\n editConfiguration() {\n Array.from(document.querySelectorAll('.js-hardware-device-card')).forEach((card) => card && card.classList.add('is-collapsed'));\n this.hardwareCardWrapper?.classList.remove('is-collapsed');\n }\n\n /**\n * Handles the change event and performs necessary actions, such as updating attributes and DOM elements, based on the checked value.\n *\n * @function onChange\n * @param {Event} e - The event object.\n * @returns {void}\n */\n onChange(e) {\n const phoneWrapper = e.target.parentElement;\n\n if (e.target.checked) {\n this.hardwareWrapper.classList.add('active');\n this.hardwareCardWrapper.classList.add('is-configured');\n phoneWrapper.parentElement.classList.add('is-selected');\n\n const attributeContainer = phoneWrapper.querySelector('input:not([disabled]) + .js-variation-label').parentElement;\n attributeContainer.querySelector('input').click();\n\n // Remove full-width class (delay until all CSS animations finish)\n setTimeout(() => {\n phoneWrapper.querySelector('.js-hardware-phone-content-inner').classList.remove('w-lg-100');\n }, 1000);\n } else {\n this.hardwareWrapper.classList.remove('active');\n this.hardwareCardWrapper.classList.remove('is-configured');\n\n phoneWrapper.parentElement.classList.remove('is-selected');\n phoneWrapper.querySelector('.js-quantity-selector').value = 1;\n phoneWrapper.querySelector('.js-quantity-decrease').click();\n\n // Add full-width class back\n phoneWrapper.querySelector('.js-hardware-phone-content-inner').classList.add('w-lg-100');\n }\n\n this.constructor.updateTabIndex();\n }\n\n /**\n * Handles the click event on the quantity increase button and displays an error message if the maximum quantity is reached.\n *\n * @function onQuantityChange\n * @param {Event} e - The event object.\n * @returns {void}\n */\n static onQuantityChange(e) {\n const quantityWrapper = e.target.closest('.js-quantity-and-actions');\n const quantitySelector = quantityWrapper.querySelector('.js-quantity-selector');\n const notification = quantityWrapper.querySelector('.js-hardware-quantity-error');\n\n if (quantitySelector.value === quantitySelector.getAttribute('max')) {\n if (notification.classList.contains('d-none')) {\n notification.classList.remove('d-none');\n } else {\n Animation.shakeSubtle(notification);\n }\n }\n }\n\n /**\n * Handles the input event on the quantity selector and displays an error message if the maximum quantity is reached.\n *\n * @function onQuantityInput\n * @param {Event} e - The event object.\n * @returns {void}\n */\n static onQuantityInput(e) {\n const quantityWrapper = e.target.closest('vz-variation-attribute');\n\n if (e.target.value > e.target.getAttribute('max') && !this.cardOrderIsReversed) {\n quantityWrapper.querySelector('.js-hardware-quantity-error').classList.remove('d-none');\n }\n }\n\n /**\n * Updates the tabindex of child elements based on the selection status of the parent wrapper.\n * If the parent wrapper is selected, the tabindex of child elements is set to 0, otherwise -1.\n *\n * @function updateTabIndex\n * @returns {void}\n */\n static updateTabIndex() {\n const elements = document.querySelectorAll('.js-hardware-phone-config');\n\n elements.forEach((element) => {\n const wrapper = element.closest('.js-hardware-phone-wrapper');\n const childElements = element.querySelectorAll(CONST.selectors.interactiveElements);\n const tabIndexValue = wrapper && wrapper.classList.contains('is-selected') ? '0' : '-1';\n\n childElements.forEach((child) => {\n child.setAttribute('tabindex', tabIndexValue);\n });\n });\n }\n}\n\nif (!window.customElements.get('vz-hardware')) {\n window.customElements.define('vz-hardware', VZHardware, {\n extends: 'input'\n });\n}\n","import VZSpinner from 'Components/VZSpinner';\nimport { getUrlFromAttributes } from 'Util/urlUtils';\nimport { showErrorModal } from 'Root/modal';\n\nexport default class VZSorting extends HTMLSelectElement {\n constructor() {\n super();\n this.excludedAttributes = ['class', 'data-configurator-type', 'data-url', 'data-general-error'];\n }\n\n connectedCallback() {\n this.addEventListener('change', this.onChange);\n this.spinner = document.querySelector('vz-spinner') || new VZSpinner();\n }\n\n onChange(evt) {\n const vZProductCard = this.closest('vz-product-card');\n const urlAttribute = evt.target.options[evt.target.selectedIndex].value;\n const url = getUrlFromAttributes(urlAttribute, vZProductCard, this.excludedAttributes);\n\n this.spinner.start();\n\n fetch(url)\n .then((res) => res.text())\n .then((response) => {\n this.closest('vz-product-card').dispatchEvent(new CustomEvent('variationChange', { detail: { response: response } }));\n document.getElementById('product-configurator').dispatchEvent(new CustomEvent('variationChange'));\n document.getElementById('product-configurator').dispatchEvent(new CustomEvent('pdp:sorting'));\n })\n .catch((e) => {\n console.log(e);\n const { title, body, cta } = JSON.parse(this.closest('vz-product-card').getAttribute('data-general-error'));\n showErrorModal(title, body, cta);\n })\n .finally(() => {\n this.spinner.stop();\n });\n }\n}\n\nif (!window.customElements.get('vz-sorting')) {\n window.customElements.define('vz-sorting', VZSorting, {\n extends: 'select'\n });\n}\n","import { formatToPriceString } from 'Util/util';\nimport VZSpinner from 'Components/VZSpinner';\n\nexport default class VZRangeSlider extends HTMLElement {\n constructor() {\n super();\n }\n\n /**\n * @function connectedCallback\n * @description Initializes the component and sets up event listeners for user input\n * @returns {void}\n */\n connectedCallback() {\n this.initializeElements();\n this.setupEventListeners();\n this.initSlider();\n }\n\n /**\n * @function disconnectedCallback\n * @description Removes event listeners for user input when the component is disconnected from the DOM\n * @returns {void}\n */\n disconnectedCallback() {\n this.removeEventListeners();\n }\n\n /**\n * @function initializeElements\n * @description Initialize all DOM elements and component properties\n */\n initializeElements() {\n // Input\n this.triggerInput = this.querySelector('.js-range-slider-input');\n\n this.minValue = this.triggerInput.getAttribute('min');\n this.maxValue = this.triggerInput.getAttribute('max');\n\n // Buttons\n this.decrementBtn = this.querySelector('.js-range-slider-decrease');\n this.incrementBtn = this.querySelector('.js-range-slider-increase');\n\n // Initialize spinner\n this.spinner = document.querySelector('vz-spinner') || new VZSpinner();\n }\n\n /**\n * @function setupEventListeners\n * @description Set up all event listeners\n */\n setupEventListeners() {\n this.boundInputChange = this.onInputChange.bind(this);\n this.boundDecrementClick = this.onDecrementClick.bind(this);\n this.boundIncrementClick = this.onIncrementClick.bind(this);\n\n this.triggerInput.addEventListener('input', this.boundInputChange);\n this.decrementBtn.addEventListener('click', this.boundDecrementClick);\n this.incrementBtn.addEventListener('click', this.boundIncrementClick);\n }\n\n /**\n * @function removeEventListeners\n * @description Remove all event listeners\n */\n removeEventListeners() {\n this.triggerInput.removeEventListener('input', this.boundInputChange);\n this.decrementBtn.removeEventListener('click', this.boundDecrementClick);\n this.incrementBtn.removeEventListener('click', this.boundIncrementClick);\n }\n\n /**\n * @function initSlider\n * @description Initialize the slider with default values\n */\n initSlider() {\n this.updateSliderFill();\n }\n\n /**\n * @function updateSliderFill\n * @description Update the slider's fill visual\n */\n updateSliderFill() {\n const percentage = ((this.triggerInput.value - this.minValue) / (this.maxValue - this.minValue)) * 100;\n this.triggerInput.style.setProperty('--slider-filled-percentage', `${percentage}%`);\n }\n\n /**\n * @function onInputChange\n * @description Handle input changes\n * @param {Event} evt - The input event\n */\n onInputChange(evt) {\n this.updateSliderFill();\n this.dispatchSliderUpdate(evt.target.value);\n }\n\n /**\n * @function onDecrementClick\n * @description Handle decrement button click\n * @param {Event} evt - The click event\n */\n onDecrementClick(evt) {\n evt.preventDefault();\n const newValue = Math.max(this.minValue, parseInt(this.triggerInput.value, 10) - 1);\n this.updateValue(newValue);\n }\n\n /**\n * @function onIncrementClick\n * @description Handle increment button click\n * @param {Event} evt - The click event\n */\n onIncrementClick(evt) {\n evt.preventDefault();\n const newValue = Math.min(this.maxValue, parseInt(this.triggerInput.value, 10) + 1);\n this.updateValue(newValue);\n }\n\n /**\n * @function updateValue\n * @description Update the slider value\n * @param {number} value - The new value\n */\n updateValue(value) {\n if (this.triggerInput.value !== value.toString()) {\n this.triggerInput.value = value;\n this.triggerInput.dispatchEvent(new Event('input', { bubbles: true }));\n }\n }\n\n /**\n * @function dispatchSliderUpdate\n * @description Dispatch a custom event when the slider value changes\n * @param {number} value - The new value\n */\n dispatchSliderUpdate(value) {\n const updateEvent = new CustomEvent('vzslider:update', {\n bubbles: true,\n detail: {\n value: value\n }\n });\n this.dispatchEvent(updateEvent);\n }\n\n /**\n * @function updatePriceDisplay\n * @description Update price displays in the slider\n * @param {Object} priceData - Object containing price information\n */\n updatePriceDisplay(priceData) {\n if (this.priceContainer && priceData.formattedPrice) {\n this.priceContainer.innerHTML = priceData.formattedPrice;\n }\n\n if (this.recurringPriceMsg && priceData.recurringPrice) {\n VZRangeSlider.updatePriceHtml(this.recurringPriceMsg, priceData.recurringPrice);\n }\n\n if (this.oneOffPriceMsg && priceData.oneOffPrice) {\n VZRangeSlider.updatePriceHtml(this.oneOffPriceMsg, priceData.oneOffPrice);\n }\n }\n\n /**\n * @function updatePriceHtml\n * @param {HTMLElement} elem - The element to update\n * @param {number|string} newPrice - The new price value\n */\n static updatePriceHtml(elem, newPrice) {\n const regex = /€.*/g;\n elem.innerHTML = elem.innerHTML.replace(regex, formatToPriceString(newPrice));\n }\n}\n\nif (!window.customElements.get('vz-range-slider')) {\n window.customElements.define('vz-range-slider', VZRangeSlider);\n}\n","import VZRangeSlider from './VZRangeSlider';\nimport * as debounce from 'lodash/debounce';\nimport { getUrlFromAttributes, appendParamToURL, getParamFromURL, appendBmHardwareCardIndex } from 'Util/urlUtils';\n\n/**\n * @function calculateOneTimePrice\n * @param {number} netPrice - net price\n * @param {number} monthlyCost - monthly cost\n * @param {number} contractDuration - contract duration\n * @description calculates one time cost for selected monthly price\n * @returns {number} - one time cost\n */\nfunction calculateOneTimePrice(netPrice, monthlyCost, contractDuration) {\n const maxMonthlyCost = Math.min(40, Math.floor(netPrice / (contractDuration + 1)));\n if (monthlyCost > maxMonthlyCost) {\n return null;\n }\n return (netPrice - contractDuration * monthlyCost).toFixed(2);\n}\n\nexport default class VZPriceBalanceSlider extends VZRangeSlider {\n constructor() {\n super();\n }\n\n /**\n * @function observedAttributes\n * @description observes the mentioned attribute and fires attributeChangedCallback when the value has changed\n * @returns {string[]} Array of attributes to observe\n */\n static get observedAttributes() {\n return ['recurring', 'one-off'];\n }\n\n /**\n * @function attributeChangedCallback\n * @description fired when an observed attribute changes\n * @param {string} name the name of the attribute\n * @param {any} oldValue the previous value of the attribute\n * @param {any} newValue the new value of the attribute\n */\n attributeChangedCallback(name, oldValue, newValue) {\n if (oldValue === newValue) return;\n\n if (name === 'recurring') {\n this.recurringPrice = newValue;\n }\n if (name === 'one-off') {\n this.oneOffPrice = newValue;\n }\n }\n\n /**\n * @function initializeElements\n * @description Initialize all DOM elements and component properties\n */\n initializeElements() {\n super.initializeElements();\n\n this.oneOffPrice = this.getAttribute('one-off');\n this.netPrice = this.getAttribute('net-price');\n this.recurringPrice = this.getAttribute('recurring');\n this.contractDuration = this.getAttribute('contract-duration');\n this.priceContainer = this.querySelector('.js-range-slider-select-price');\n this.recurringPriceMsg = this.querySelector('.js-hardware-recurring');\n this.oneOffPriceMsg = this.querySelector('.js-hardware-one-off');\n this.hardwareWrapper = this.closest('.js-hardware-phones');\n this.cardIndex = this.hardwareWrapper?.dataset.index;\n this.editMode = document.querySelector('.js-edit-mode');\n\n this.debouncedChangeEvent = debounce(this.dispatchChange.bind(this), 1000);\n }\n\n /**\n * @function onInputChange\n * @description Handle input changes\n * @param {Event} evt - The input event\n */\n onInputChange(evt) {\n super.onInputChange(evt);\n\n this.updateUI(evt.target.value);\n this.debouncedChangeEvent();\n }\n\n /**\n * @function updatePriceDisplay\n * @description Update the price display with new values\n * @param {number} recurringPrice - The new recurring price\n */\n updateUI(recurringPrice) {\n const oneTimeCost = calculateOneTimePrice(Number(this.netPrice), Number(recurringPrice), Number(this.contractDuration));\n\n this.setAttribute('one-off', oneTimeCost);\n this.setAttribute('recurring', recurringPrice);\n\n super.updatePriceDisplay({\n recurringPrice,\n oneOffPrice: oneTimeCost\n });\n }\n\n /**\n * @function dispatchChange\n * @description Dispatch change event and update product configuration\n */\n async dispatchChange() {\n const detail = {\n identifier: this.cardIndex,\n oneOffPrice: Number.parseFloat(this.oneOffPrice),\n recurringPrice: Number.parseInt(this.recurringPrice, 10),\n contractDuration: Number.parseInt(this.contractDuration, 10)\n };\n\n // Dispatch price balance update event\n const updateEvent = new CustomEvent('vzpricebalance:update', {\n bubbles: true,\n detail\n });\n this.dispatchEvent(updateEvent);\n\n // Handle product card update if needed\n const VZProductCard = this.closest('vz-product-card');\n const urlAttribute = this.hardwareWrapper?.querySelector('input[name^=\"hardware_storageCapacity\"]:checked')?.getAttribute('data-url');\n\n if (!urlAttribute || !VZProductCard) return;\n\n this.spinner.start();\n try {\n const url = this.buildRequestUrl(urlAttribute, VZProductCard, detail);\n const response = await fetch(url);\n const responseText = await response.text();\n\n VZProductCard.dispatchEvent(\n new CustomEvent('variationChange', {\n detail: { response: responseText }\n })\n );\n } catch (error) {\n console.error('Error updating product configuration:', error);\n } finally {\n this.spinner.stop();\n }\n }\n\n /**\n * @function buildRequestUrl\n * @description Builds the request URL with all necessary parameters\n * @param {string} urlAttribute - Base URL from the storage capacity input\n * @param {HTMLElement} productCard - The product card element\n * @param {Object} priceDetails - Price details to update\n * @returns {string} Complete URL with all parameters\n * @private\n */\n buildRequestUrl(urlAttribute, productCard, priceDetails) {\n const url = getUrlFromAttributes(urlAttribute, productCard, ['class', 'data-configurator-type', 'data-url', 'data-general-error']);\n\n // Handle business rules products\n let businessRulesProducts = productCard.getAttribute('businessrules-products');\n if (businessRulesProducts) {\n businessRulesProducts = JSON.parse(businessRulesProducts);\n Object.keys(businessRulesProducts).forEach((key) => {\n const deviceIndex = key && key.split('---device')[1];\n if (businessRulesProducts[key].isMobileHardware && this.cardIndex === deviceIndex) {\n Object.assign(businessRulesProducts[key], {\n oneOffPrice: priceDetails.oneOffPrice,\n recurringPrice: priceDetails.recurringPrice,\n contractDuration: priceDetails.contractDuration\n });\n }\n });\n\n let finalUrl = appendBmHardwareCardIndex(\n this,\n appendParamToURL(\n appendParamToURL(url, 'businessrulesproducts', JSON.stringify(businessRulesProducts)),\n 'reversed',\n productCard?.getAttribute('data-reversed') === 'true'\n )\n );\n\n if (this.editMode) {\n const pliId = getParamFromURL(window.location.href, 'pliId');\n if (pliId) {\n finalUrl = appendParamToURL(finalUrl, 'pliId', pliId);\n }\n }\n\n return finalUrl;\n }\n\n let finalUrl = appendBmHardwareCardIndex(this, appendParamToURL(url, 'reversed', productCard?.getAttribute('data-reversed') === 'true'));\n\n if (this.editMode) {\n const pliId = getParamFromURL(window.location.href, 'pliId');\n if (pliId) {\n finalUrl = appendParamToURL(finalUrl, 'pliId', pliId);\n }\n }\n\n return finalUrl;\n }\n}\n\nif (!window.customElements.get('vz-price-balance-slider')) {\n window.customElements.define('vz-price-balance-slider', VZPriceBalanceSlider);\n}\n","'use strict';\n\nimport VZSpinner from 'Components/VZSpinner';\nimport { appendParamToURL } from 'Root/util/urlUtils';\nimport { getJourney, updateJourney, clearJourney } from '../../journey/journeyHelper';\n\nclass VZDeleteGroup extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.addEventListener('click', this.onClick);\n this.deleteBtn = this.querySelector('a');\n }\n\n disconnectedCallback() {\n this.removeEventListener('click', this.onClick);\n }\n\n /**\n * @function removeDeletedGroup\n * @description removes the deleted group from the DOM after it has been removed from the basket and dispatches an\n * event to update the monthly total\n */\n removeDeletedGroup() {\n const isMiniCart = !!this.deleteBtn.closest('vz-drawer');\n window.location = isMiniCart ? appendParamToURL(window.location.href, 'showMinicart', 'true') : window.location.href;\n }\n\n onClick(evt) {\n const spinner = document.querySelector('vz-spinner') || new VZSpinner();\n spinner.start();\n evt.preventDefault();\n\n const removeFromJourneyEmptyProduct = this.deleteBtn.getAttribute('data-empty-journey-remove');\n const removeFromJourneyExistingProduct = this.deleteBtn.getAttribute('data-journey-remove');\n\n if (removeFromJourneyEmptyProduct || removeFromJourneyExistingProduct) {\n let journey = getJourney();\n if (journey.length > 0) {\n journey = journey.filter((item) => item !== removeFromJourneyEmptyProduct && item !== removeFromJourneyExistingProduct);\n if (journey.every((id) => id === 'one-net') || removeFromJourneyExistingProduct === 'one-net') {\n clearJourney();\n } else {\n updateJourney(journey);\n }\n if (removeFromJourneyEmptyProduct) {\n spinner.stop();\n window.location.reload();\n return;\n }\n }\n }\n\n fetch(this.deleteBtn.href, {\n method: this.deleteBtn.getAttribute('data-type') || 'GET'\n })\n .then(this.removeDeletedGroup.bind(this))\n .finally(spinner.stop);\n }\n}\n\nexport default window.customElements.get('vz-delete-group') || VZDeleteGroup;\n\nif (!window.customElements.get('vz-delete-group')) {\n window.customElements.define('vz-delete-group', VZDeleteGroup);\n}\n","'use strict';\n\nimport VZSpinner from 'Components/VZSpinner';\nimport { getUrlFromAttributes } from 'Util/urlUtils';\n\nclass VZFilter extends HTMLElement {\n constructor() {\n super();\n this.scope = null;\n this.excludedAttributes = ['class', 'data-configurator-type', 'data-url', 'data-general-error'];\n }\n\n connectedCallback() {\n this.addEventListener('change', this.onChange);\n }\n\n disconnectedCallback() {\n this.removeEventListener('change', this.onChange);\n }\n\n onChange() {\n this.applyFilter();\n }\n\n async applyFilter() {\n if (!this.scope) {\n this.scope = document.querySelector(`[data-scope=\"${this.getAttribute('scope')}\"]`) || document;\n }\n\n const urlAttribute = this.getAttribute('url');\n const vZProductCard = this.closest('vz-product-card');\n\n if (urlAttribute != null && vZProductCard != null) {\n const spinner = document.querySelector('vz-spinner') || new VZSpinner();\n spinner.start();\n\n const url = getUrlFromAttributes(urlAttribute, vZProductCard, this.excludedAttributes);\n\n await fetch(url)\n .then((res) => res.text())\n .then((res) => {\n const productCard = this.closest('vz-product-card') || document.querySelector('vz-product-card');\n productCard.dispatchEvent(\n new CustomEvent('variationChange', {\n detail: {\n response: res\n }\n })\n );\n document.getElementById('product-configurator').dispatchEvent(new CustomEvent('variationChange'));\n document.getElementById('product-configurator').dispatchEvent(new CustomEvent('pdp:filter'));\n });\n spinner.stop();\n }\n\n this.scope.setAttribute('data-active-filter', this.getAttribute('for'));\n }\n}\n\nif (!window.customElements.get('vz-filter')) {\n window.customElements.define('vz-filter', VZFilter);\n}\n","'use strict';\n\nexport default class VZGroupSummary extends HTMLElement {\n constructor() {\n super();\n this.summaryList = this.querySelector('.js-configurator-summary-group-list');\n }\n\n connectedCallback() {\n this.addEventListener('portingChange', this.onPortingChange);\n }\n\n disconnectedCallback() {\n this.removeEventListener('portingChange', this.onPortingChange);\n }\n\n /**\n * @function onPortingChange\n * @private\n * @description updates the porting list item in the group summary\n * @param {Event} evt a portingChange event fired from VZPorting\n */\n onPortingChange(evt) {\n const { value: portingValue } = evt.detail;\n const portingListItem = this.querySelector('.js-porting-list-item');\n if (!portingListItem) return;\n const portingString = this.summaryList.dataset.portingString;\n portingListItem.textContent = `${portingValue} ${portingString}`;\n }\n}\n\nif (!window.customElements.get('vz-group-summary')) {\n window.customElements.define('vz-group-summary', VZGroupSummary);\n}\n","export default class Alert {\n constructor(container) {\n this.container = container || document.body;\n this.iconClasses = {\n danger: 'icon-warning',\n warning: 'icon-attention-circle',\n success: 'icon-checkmark-circle',\n info: 'icon-info-inversed'\n };\n }\n\n /**\n * Inserts an alert of a specified type into the DOM after the this.container element.\n *\n * @param {string} alertTitle - The title of the alert.\n * @param {string} alertDescription - The description of the alert.\n * @param {string} type - The type of the alert. It can be 'danger', 'warning', 'success', or 'info'. Defaults to 'danger' if not specified.\n * @param {string} additionalClasses - Additional CSS classes to add to the alert element. Defaults to empty string.\n */\n show(alertTitle, alertDescription, type = 'danger', additionalClasses = '') {\n const iconClass = this.iconClasses[type] || 'icon-warning';\n const iconHMTL =\n type === 'idea'\n ? ''\n : `\n
\n \n
\n `;\n const alertHTML = `\n \n
\n ${iconHMTL}\n
\n

\n ${alertTitle}\n

\n

\n ${alertDescription}\n

\n
\n
\n
\n `;\n\n this.container.insertAdjacentHTML('afterend', alertHTML);\n }\n}\n","'use strict';\n\nimport VZSpinner from 'Components/VZSpinner';\nimport * as debounce from 'lodash/debounce';\nimport { appendParamToURL, getParamFromURL, getUrlFromAttributes, removeParamFromURL } from 'Util/urlUtils';\nimport Alert from 'Components/Alert';\nimport Animation from '../../Animation';\nimport { scrollToElement } from 'Util/domUtils';\nimport VZConfirmationModal from '../../ConfirmationModal';\n\nconst PRODUCT_CARD_SELECTORS = 'vz-product-card, vz-tc-product-card';\n\nexport default class VZQuantitySelector extends HTMLElement {\n constructor() {\n super();\n this.excludedAttributes = ['class', 'data-configurator-type', 'data-url', 'data-general-error'];\n\n this.onInput = this.onInput.bind(this);\n this.toggleIncreaseAndDecreaseButtons = this.toggleIncreaseAndDecreaseButtons.bind(this);\n this.confirmRemove = this.getAttribute('data-confirm-remove') === 'true';\n }\n\n connectedCallback() {\n this.spinner = document.querySelector('vz-spinner') || new VZSpinner();\n this.sidebar = document.querySelector('.js-configurator-sidebar');\n this.editMode = document.querySelector('.js-edit-mode');\n\n // reset ID to ensure unique selector and native label feature still works\n this.setAttribute('id', Date.now());\n\n this.forbiddenValues = ['e', '+', ',', '-', '.', 69, 187, 188, 189, 190];\n this.debounceRate = parseFloat(this.getAttribute('debounce-rate')) || 500;\n this.debouncedChange = debounce(this.onChange.bind(this), this.debounceRate);\n this.quantityField = this.querySelector('.js-quantity-field');\n this.formControl = this.querySelector('.form-control');\n this.quantityFieldOrgValue = this.quantityField.value;\n\n if (this.quantityField.value !== '0') {\n this.formControl.classList.add('border-turquoise');\n }\n\n this.quantityField.addEventListener('blur', this.onBlur.bind(this));\n this.addEventListener('input', this.onInput.bind(this));\n this.addEventListener('keydown', this.onKeyDown.bind(this));\n this.addEventListener('paste', this.onPaste);\n this.businessMobileWrapper = this.closest('.js-business-mobile-quantity-card');\n\n [...this.querySelectorAll('.js-quantity-decrease, .js-quantity-increase')].forEach((element) => {\n element.addEventListener('click', this.decreaseOrIncrease.bind(this));\n });\n }\n\n /**\n * @function toggleIncreaseAndDecreaseButtons\n * @description Toggles the increase and decrease button state based on the string passed in. This is so that\n * values are not changeable while a network call is happening.\n * @param {string} disableOrEnable - Expects 'disable' or 'enable'.\n */\n toggleIncreaseAndDecreaseButtons(disableOrEnable) {\n const buttons = [...this.querySelectorAll('.js-quantity-decrease, .js-quantity-increase')];\n buttons.forEach((button) => (disableOrEnable === 'disable' ? button.setAttribute('disabled', true) : button.removeAttribute('disabled')));\n }\n\n onBlur(evt) {\n if (evt.target.value.length !== 0) return;\n evt.target.value = '0';\n this.validateMinMax();\n this.debouncedChange();\n }\n\n onInput(evt) {\n if (evt.target.value.length === 0) return;\n\n this.validateMinMax();\n this.debouncedChange();\n }\n\n onKeyDown(evt) {\n if (this.forbiddenValues.indexOf(evt.key || evt.keyCode) !== -1) {\n evt.preventDefault();\n }\n }\n\n onPaste(evt) {\n // Replace all non-digits on copy paste\n evt.preventDefault();\n const newValue = evt.clipboardData.getData('text').replace(/\\D/g, '');\n evt.target.value = ''; // required, otherwise it won't remove the dot\n evt.target.value = newValue;\n\n this.validateMinMax();\n this.debouncedChange();\n }\n\n decreaseOrIncrease(evt) {\n evt.preventDefault();\n\n const field = this.quantityField;\n const currentValue = parseInt(field.value, 10);\n const decrease = evt.target.classList.contains('js-quantity-decrease');\n const manuallyTriggered = evt.isTrusted;\n\n // Show a confirmation modal when the quantity is manually decreased to 0, and the confirmation modal is enabled.\n if (this.confirmRemove && decrease && currentValue === 1 && manuallyTriggered) {\n const confirmationModal = new VZConfirmationModal();\n confirmationModal.toggleConfirmationModal().then((confirmed) => {\n if (confirmed) {\n this.updateQuantity(field, 0);\n }\n });\n } else {\n this.updateQuantity(field, decrease ? currentValue - 1 : currentValue + 1);\n }\n }\n\n updateQuantity(field, newValue) {\n if (window.isNaN(newValue)) {\n field.value = field.min;\n } else {\n field.value = newValue;\n }\n\n this.validateMinMax();\n this.debouncedChange();\n\n // Highlight info card if applicable\n if (this.quantityField.classList.contains('js-highlight-container-when-not-empty')) this.highlightInfoCard(field.value !== '0');\n }\n\n highlightInfoCard(highlight) {\n const infoCard = this.quantityField.closest('.js-info-card');\n\n if (infoCard) infoCard.classList.toggle('info-card--bordered-primary', highlight);\n }\n\n validateMinMax() {\n const field = this.quantityField;\n const moreThanMax = parseInt(field.value, 10) > field.max;\n const lessThanMin = parseInt(field.value, 10) < field.min;\n\n if (field.max && moreThanMax) field.value = field.max;\n if (lessThanMin) {\n field.value = field.min;\n\n // Display an alert when an attempt is made to reduce the quantity below the existing number of phones on Business Mobile\"\n if (field.value > 1 && this.businessMobileWrapper) {\n if (this.businessMobileWrapper.innerHTML.includes('alert')) {\n Animation.shakeSubtle(this.businessMobileWrapper.querySelector('.alert'));\n } else {\n const alertTitle = this.businessMobileWrapper.getAttribute('alert-title');\n const alertDescription = this.businessMobileWrapper.getAttribute('alert-desc');\n const alert = new Alert(this.businessMobileWrapper.querySelector('.js-quantity-selector-wrapper'));\n alert.show(alertTitle, alertDescription, 'danger', 'mt-2');\n\n // Scroll to BM Devices\n const addDevicesLink = document.querySelector('.js-add-devices-link');\n const devicesContainer = document.querySelector('.js-hardware-device-cards');\n if (addDevicesLink && devicesContainer) {\n addDevicesLink.addEventListener('click', (event) => {\n event.preventDefault();\n scrollToElement(devicesContainer);\n });\n }\n }\n }\n }\n }\n\n onChange() {\n const field = this.quantityField;\n\n // Double check to see if there has been an actual change in value\n if (field.value === this.quantityFieldOrgValue) return;\n\n field.setAttribute('value', field.value);\n field.dispatchEvent(new CustomEvent('fieldUpdated'));\n\n if (this.quantityField.value !== '0') {\n this.formControl.classList.add('border-turquoise');\n }\n\n const vZProductCard = this.closest(PRODUCT_CARD_SELECTORS);\n const urlAttributeValue = this.quantityField.getAttribute('data-url');\n if (!urlAttributeValue || !vZProductCard) {\n return;\n }\n\n let fieldUrl = getUrlFromAttributes(urlAttributeValue, vZProductCard, this.excludedAttributes);\n fieldUrl = removeParamFromURL(fieldUrl, 'quantity');\n fieldUrl = appendParamToURL(fieldUrl, 'quantity', this.quantityField.value);\n\n // Disable the buttons - Has to be before the return statement to work for one net quantity selectors.\n this.toggleIncreaseAndDecreaseButtons('disable');\n\n if (!fieldUrl) return;\n\n if (this.editMode) {\n const pliId = getParamFromURL(window.location.href, 'pliId');\n fieldUrl = appendParamToURL(fieldUrl, 'pliId', pliId);\n }\n\n this.spinner.start();\n\n fetch(fieldUrl)\n .then((res) => res.text())\n .then((response) => {\n vZProductCard.dispatchEvent(new CustomEvent('variationChange', { detail: { response: response } }));\n })\n .finally(() => {\n this.toggleIncreaseAndDecreaseButtons('enable'); // Enable buttons\n this.spinner.stop();\n });\n }\n}\n\nif (!window.customElements.get('vz-quantity-selector')) {\n window.customElements.define('vz-quantity-selector', VZQuantitySelector);\n}\n","'use strict';\n\nimport Modal from 'bootstrap/js/dist/modal';\nimport VZSpinner from 'Components/VZSpinner';\nimport { showErrorModal } from 'Root/modal';\nimport { getParamFromURL, appendParamToURL, getUrlFromAttributes, appendBmHardwareCardIndex } from 'Util/urlUtils';\nimport { CONST } from 'app_vodafone_ziggo/util/util';\n\n/**\n * @class VZVariationAttribute\n */\nclass VZVariationAttribute extends HTMLElement {\n constructor() {\n super();\n this.editMode = document.querySelector('.js-edit-mode');\n this.excludedAttributes = ['class', 'data-configurator-type', 'data-url', 'data-general-error'];\n\n // The variation input should always be the first input inside the vz-variation-attribute element\n this.variationInput = this.querySelector('input');\n\n this.setupURL = this.setupURL.bind(this);\n this.postUpdate = this.postUpdate.bind(this);\n this.onVariationChange = this.onVariationChange.bind(this);\n this.onQuantityChange = this.onQuantityChange.bind(this);\n this.handleAddonClick = this.handleAddonClick.bind(this);\n }\n\n handleAddonClick(event) {\n event.preventDefault();\n\n if (this.variationInput) {\n this.variationInput.checked = !this.variationInput.checked;\n this.variationInput.dispatchEvent(new Event('change'));\n\n const addText = this.addonToggle.querySelector('.js-addon-btn-add');\n const removeText = this.addonToggle.querySelector('.js-addon-btn-remove');\n\n addText.classList.toggle(CONST.classes.dNone);\n removeText.classList.toggle(CONST.classes.dNone);\n this.classList.toggle('info-card--bordered-primary');\n }\n }\n\n onVariationChange(evt) {\n if (evt.target === this.variationInput) {\n const url = this.setupURL();\n this.postUpdate(url);\n }\n }\n\n onQuantityChange() {\n const url = this.setupURL(this.quantityField.value > 0 ? 'data-quantity-url' : 'data-remove-url');\n this.postUpdate(url);\n }\n\n setupURL(attributeToUse) {\n const { type, checked } = this.variationInput;\n let urlAttributeName = attributeToUse || 'data-url';\n\n if (!attributeToUse && type === 'checkbox') {\n urlAttributeName = checked ? 'data-add-url' : 'data-remove-url';\n }\n\n const urlAttributeValue = this.variationInput.getAttribute(urlAttributeName);\n const vZProductCard = this.closest('vz-product-card');\n\n // Stop in case there's no url to work with (which can happen when the type is checkbox)\n if (urlAttributeValue === 'null' || urlAttributeValue === 'false' || vZProductCard == null) {\n return null;\n }\n\n let url = getUrlFromAttributes(urlAttributeValue, vZProductCard, this.excludedAttributes);\n\n // Decode the URI as that's sometimes necessary.\n // There's no hurt in always doing this even if it's not required.\n url = decodeURIComponent(url);\n\n // Replace placeholders with quantity data\n if (this.quantityField && url.includes('{0}')) {\n const productQty = this.quantityField.value;\n url = url.replace('{0}', `${productQty}`);\n }\n\n if (this.editMode) {\n const pliId = getParamFromURL(window.location.href, 'pliId');\n url = appendParamToURL(url, 'pliId', pliId);\n }\n\n // handle BM Mobile Hardware case, since contractDuration is not a variation attr on the product and businessRuleProduct has pricing and additional info\n if (vZProductCard.getAttribute('data-configurator-type') === 'business-mobile') {\n // Pass along the reversed parameter to change the order of cards\n const isReversed = vZProductCard?.getAttribute('data-reversed') === 'true';\n if (isReversed) {\n url = appendParamToURL(url, 'reversed', isReversed);\n }\n\n // Calculate the total hardware amount\n const totalHardwareAmount = [...document.querySelectorAll('.js-hardware-phone-wrapper.is-selected .js-quantity-field')].reduce(\n (acc, el) => acc + Number(el.value) || 0,\n 0\n );\n\n // Updated the BM subscription quantity so that it matches the total amount of phones\n const currentQuantity = Number(getParamFromURL(url, 'quantity')) || 0;\n const updatedQuantity = Math.max(currentQuantity, totalHardwareAmount);\n url = appendParamToURL(url, 'quantity', updatedQuantity);\n\n let businessRulesProducts = vZProductCard.getAttribute('businessrules-products');\n businessRulesProducts = businessRulesProducts && JSON.parse(businessRulesProducts);\n if (!businessRulesProducts) return url;\n Object.keys(businessRulesProducts).forEach((key) => {\n // Only apply changes to the device with matching index\n const hardwareWrapper = this.closest('.js-hardware-phones');\n const deviceIndex = key && key.split('---device')[1];\n const cardIndex = hardwareWrapper && hardwareWrapper.dataset.index;\n if (this.classList.contains('js-hardware-duration-label')) {\n vZProductCard.querySelectorAll('.js-hardware-duration-label').forEach((el) => el.querySelector('label').classList.remove('label-checked'));\n if (businessRulesProducts[key].isMobileHardware && deviceIndex === cardIndex) {\n const priceSlider = hardwareWrapper.querySelector('vz-price-balance-slider');\n const contractDuration = Number.parseInt(this.querySelector('input')?.value, 10);\n const netPrice = Number.parseFloat(priceSlider.getAttribute('net-price'), 10);\n let recurringPrice = Number.parseInt(priceSlider.getAttribute('recurring'), 10);\n const maxMonthlyCost = Math.min(40, Math.floor(netPrice / (contractDuration + 1)));\n recurringPrice = Math.min(recurringPrice, maxMonthlyCost);\n let oneOffPrice = Number.parseFloat((netPrice - contractDuration * recurringPrice).toFixed(2));\n\n // Minimum monthly cost is 1 euro with recurring payment\n if (contractDuration !== -1 && oneOffPrice === netPrice) {\n recurringPrice = 1;\n oneOffPrice = netPrice - contractDuration * recurringPrice;\n }\n if (contractDuration === -1) {\n recurringPrice = 0;\n oneOffPrice = netPrice;\n }\n\n businessRulesProducts[key].contractDuration = contractDuration;\n businessRulesProducts[key].recurringPrice = recurringPrice;\n businessRulesProducts[key].oneOffPrice = oneOffPrice;\n }\n url = appendParamToURL(url, 'businessrulesproducts', JSON.stringify(businessRulesProducts));\n }\n if (this.classList.contains('js-mobile-hardware-qty')) {\n if (businessRulesProducts[key].isMobileHardware && deviceIndex === cardIndex) {\n if (this.quantityField.value > 0) {\n businessRulesProducts[key].qty = this.quantityField.value;\n } else {\n delete businessRulesProducts[key];\n }\n }\n url = appendParamToURL(url, 'businessrulesproducts', JSON.stringify(businessRulesProducts));\n }\n // Remember which BM hardware card to keep open after ajax\n url = appendBmHardwareCardIndex(this, url);\n });\n }\n return url;\n }\n\n postUpdate(url) {\n if (!url) return;\n\n this.spinner.start();\n\n fetch(url)\n .then((res) => res.text())\n .then((response) => {\n this.closest('vz-product-card').dispatchEvent(new CustomEvent('variationChange', { detail: { response: response } }));\n\n const fragment = document.createElement('template');\n fragment.innerHTML = response;\n\n document.getElementById('product-configurator').dispatchEvent(new CustomEvent('variationChange'));\n\n // If in edit mode, and when contract duration has changed, show a modal with extra info\n this.showExtraInfoModal.bind(this);\n })\n .catch((e) => {\n console.log(e);\n const { title, body, cta } = JSON.parse(this.closest('vz-product-card').getAttribute('data-general-error'));\n showErrorModal(title, body, cta);\n })\n .finally(() => {\n this.spinner.stop();\n });\n }\n\n showExtraInfoModal() {\n const {\n dataset: { displayValue },\n id,\n name\n } = this.variationInput;\n const changeDurationModalElement = document.getElementById('change-duration-modal');\n const configuratorType = this.closest('vz-product-card')?.dataset.configuratorType;\n let isModalRequired = true;\n\n if (configuratorType === 'business-mobile') {\n // Only query for committed groups that have a duration that's not \"monthly\"\n const committedGroups = document.querySelectorAll('.js-configurator-summary-committed-group [data-selected-duration]:not([data-selected-duration=\"1\"]');\n const existingDuration = document.querySelector('[data-existing-duration]')?.dataset.existingDuration;\n isModalRequired = committedGroups.length > 0 && id !== '1' && displayValue !== existingDuration;\n }\n\n if (isModalRequired && name === 'contractDuration' && changeDurationModalElement) {\n const changeDurationModal = new Modal(changeDurationModalElement, { backdrop: 'static', keyboard: false });\n changeDurationModal.show();\n\n // Dispose and remove the modal when it is closed so it won't be shown again\n changeDurationModalElement.addEventListener('hidden.bs.modal', () => {\n changeDurationModal.dispose();\n changeDurationModalElement.remove();\n });\n }\n }\n\n connectedCallback() {\n this.spinner = document.querySelector('vz-spinner') || new VZSpinner();\n this.variationInput.addEventListener('change', this.onVariationChange);\n\n if (this.classList.contains('js-addon')) {\n this.addonToggle = this.querySelector('.js-addon-toggle');\n if (this.addonToggle) {\n this.addonToggle.addEventListener('click', this.handleAddonClick);\n }\n }\n\n this.quantityField = this.querySelector('.js-quantity-field');\n if (this.quantityField) {\n this.quantityField.addEventListener('fieldUpdated', this.onQuantityChange);\n }\n\n // https://stackoverflow.com/questions/62962138/how-to-get-the-contents-of-a-custom-element#answer-62966393\n setTimeout(() => {\n const input = this.querySelector('input[type=\"radio\"]') || this.querySelector('input[type=\"checkbox\"]');\n if (input) {\n input.addEventListener('blur', () => {\n this.parentElement.classList.remove('focus');\n [...this.parentElement.children].forEach((child) => {\n child.removeAttribute('style');\n });\n });\n }\n });\n }\n\n disconnectedCallback() {\n this.removeEventListener('change', this.onVariationChange);\n }\n}\n\nexport default window.customElements.get('vz-variation-attribute') || VZVariationAttribute;\n\nif (!window.customElements.get('vz-variation-attribute')) {\n window.customElements.define('vz-variation-attribute', VZVariationAttribute);\n}\n","'use strict';\n\nimport { appendParamToURL, removeParamFromURL } from 'Util/urlUtils';\n\nclass VZPorting extends HTMLElement {\n constructor() {\n super();\n }\n\n static get observedAttributes() {\n return ['visible'];\n }\n\n connectedCallback() {\n this.notifyProductCard = this.notifyProductCard.bind(this);\n this.quantityField = this.querySelector('.js-quantity-field');\n this.quantityField.addEventListener('fieldUpdated', this.notifyProductCard);\n\n // Execute immediately, since this element will be replaced (and have it's value be reset)\n // when the vz-quantity-selector element is updated.\n this.notifyProductCard();\n }\n\n notifyProductCard() {\n const value = this.quantityField.value;\n const quantity = this.closest('form').querySelector('.js-quantity-selector').value;\n const valueToSend = Number(value) > Number(quantity) ? quantity : value;\n\n const element = this.querySelector('[data-url]');\n let url = element.getAttribute('data-url');\n url = removeParamFromURL(url, 'porting');\n url = appendParamToURL(url, 'porting', valueToSend);\n element.setAttribute('data-url', url);\n\n document.querySelector('vz-group-summary').dispatchEvent(\n new CustomEvent('portingChange', {\n detail: {\n value: valueToSend\n }\n })\n );\n }\n}\n\nexport default window.customElements.get('vz-porting') || VZPorting;\nif (!window.customElements.get('vz-porting')) {\n window.customElements.define('vz-porting', VZPorting);\n}\n","'use strict';\n\nimport './VZQuantitySelector';\nimport './VZVariationAttribute';\nimport './VZPorting';\n\nclass VZProductCard extends HTMLElement {\n constructor() {\n super();\n this.sidebar = document.querySelector('.js-configurator-sidebar');\n this.isOneNet = this.dataset.configuratorType === 'one-net';\n this.hardwarePhoneThresholdBtn = document.querySelector('.js-hardware-phone-treshold-btn');\n }\n\n static updateJourneyModal(fragment) {\n const journeyModal = document.querySelector('vz-journey-modal');\n if (journeyModal) {\n journeyModal.replaceWith(fragment.content.querySelector('vz-journey-modal'));\n }\n }\n\n static updateChatInfo(fragment) {\n // Update the hidden input field for chat info\n const activeConfiguratorGroup = document.querySelector('#activeConfiguratorGroup');\n if (activeConfiguratorGroup) {\n activeConfiguratorGroup.value = fragment.content.querySelector('#activeConfiguratorGroup').value;\n\n // Manually dispatch change event as programmatic changes to an input field don't natively trigger an event\n const event = new Event('change');\n activeConfiguratorGroup.dispatchEvent(event);\n }\n }\n\n connectedCallback() {\n this.addEventListener('variationChange', this.onVariationChange);\n this.hardwarePhoneThresholdBtn?.addEventListener('click', VZProductCard.removeShowMoreBtn.bind(this));\n }\n\n disconnectedCallback() {\n this.hardwarePhoneThresholdBtn?.removeEventListener('click', VZProductCard.removeShowMoreBtn.bind(this));\n }\n\n onVariationChange(evt) {\n const { response } = evt.detail;\n const fragment = document.createElement('template');\n fragment.innerHTML = response;\n this.updateCard(fragment.content.querySelector('vz-product-card').outerHTML);\n this.updateSideBar(fragment);\n this.checkOneNetSeats(fragment);\n this.constructor.updateJourneyModal(fragment);\n this.constructor.updateChatInfo(fragment);\n }\n\n updateCard(productCardHTML) {\n if (this.outerHTML) this.outerHTML = productCardHTML;\n }\n\n updateSideBar(fragment) {\n this.sidebar.dispatchEvent(\n new CustomEvent('variationChange', {\n detail: {\n fragment: fragment\n }\n })\n );\n\n // Set the postcode on the current configuration\n const postCodeCheck = document.querySelector('[is=\"vz-postcode-check\"]');\n const MACDconfigurator = document.querySelector('.js-macd-configurator');\n if (postCodeCheck && !MACDconfigurator) {\n postCodeCheck.setAddress();\n }\n }\n\n checkOneNetSeats(fragment) {\n // If one-net, and no seat is selected OR the number of seatsSelected is below seatsThreshold, dispatch an event to disable the configurator.\n if (this.isOneNet) {\n const { shouldDisableSubmit } = fragment.content.querySelector('[data-should-disable-submit]').dataset;\n const allQuantitySelectors = [...this.querySelectorAll('.js-quantity-field')];\n const combinedQuantity = allQuantitySelectors.reduce((total, currentElement) => total + parseInt(currentElement.value, 10), 0);\n\n document.dispatchEvent(\n new CustomEvent('oneNet:seatSelection', {\n detail: {\n isOneNetSeatSelected: combinedQuantity > 0,\n areOneNetSeatsBelowThreshold: shouldDisableSubmit && shouldDisableSubmit === 'true'\n }\n })\n );\n\n if (fragment.content.querySelector('.js-pdp-error')) {\n [...document.querySelectorAll('.js-pdp-submit-button button')].forEach((button) => {\n button.classList.add('pe-none', 'opacity-50');\n button.setAttribute('disabled', '');\n });\n }\n }\n }\n\n /**\n * Removes the Hardware Phones show more button when clicked\n * @param {Event} e - The event object.\n */\n static removeShowMoreBtn(e) {\n e.target.parentElement.remove();\n }\n}\n\nexport default window.customElements.get('vz-product-card') || VZProductCard;\n\nif (!window.customElements.get('vz-product-card')) {\n window.customElements.define('vz-product-card', VZProductCard);\n}\n","'use-strict';\n\nimport { CONST, documentReady, assignStyling } from 'Util/util';\nimport * as debounce from 'lodash/debounce';\n\nclass Sidebar {\n constructor() {\n this.sidebar = document.querySelector('.js-configurator-sidebar');\n if (!this.sidebar) return;\n this.sidebarScrollContainer = this.sidebar.closest('.js-configurator-sidebar-scroll-container');\n\n this.sidebarOffscreen = this.sidebarScrollContainer.classList.contains('offscreen');\n\n this.sidebarTopOffset = 16; // The space between the sticky header and sticky sidebar\n this.sidebarBottomOffset = 48; // Adjust to your preference\n\n this.stickyBreakpoint = parseInt(CONST.breakpoints.lg, 10); // The breakpoint at which to become sticky\n\n this.siteHeader = document.querySelector('header');\n this.headerHeight = parseInt(this.siteHeader.offsetHeight, 10);\n this.configuratorType = document.querySelector('[data-configurator-type]')?.dataset?.configuratorType;\n\n this.isSidebarOverflowing = false;\n\n this.assignMobileVariables();\n this.initAccordions();\n\n this.handleFloatingSidebar = this.handleFloatingSidebar.bind(this);\n this.handleScroll = this.handleScroll.bind(this);\n this.isSidebarAtBottom = this.isSidebarAtBottom.bind(this);\n this.isSidebarAtBottomContainer = this.isSidebarAtBottomContainer.bind(this);\n this.isSidebarInContainer = this.isSidebarInContainer.bind(this);\n this.replaceSidebarHtml = this.replaceSidebarHtml.bind(this);\n this.isStep1InViewport = this.isStep1InViewport.bind(this);\n this.openMobileSidebar = this.openMobileSidebar.bind(this);\n this.closeMobileSidebar = this.closeMobileSidebar.bind(this);\n this.calculateMaxHeightMobileSidebarBody = this.calculateMaxHeightMobileSidebarBody.bind(this);\n this.mobileSidebarScrollHandler = this.mobileSidebarScrollHandler.bind(this);\n this.mobileSidebarSlideIn = this.mobileSidebarSlideIn.bind(this);\n this.mobileSidebarSlideOut = this.mobileSidebarSlideOut.bind(this);\n this.assignAccordionsEvents = this.assignAccordionsEvents.bind(this);\n this.initAccordions = this.initAccordions.bind(this);\n\n this.initialize();\n }\n\n /**\n * @function initialize\n * @private\n * @description initializes the file\n */\n initialize() {\n documentReady(this.handleFloatingSidebar);\n\n window.addEventListener(\n 'resize',\n debounce(() => {\n this.assignMobileVariables();\n this.initAccordions();\n\n if (window.innerWidth < this.stickyBreakpoint) {\n this.assignMobileEvents();\n this.closeMobileSidebar();\n } else {\n this.sidebarHeader.classList.remove('d-none');\n this.sidebarBody.classList.remove('d-none');\n\n this.openMobileSidebar();\n }\n\n this.handleFloatingSidebar();\n }),\n 150\n );\n\n window.addEventListener('scroll', this.handleScroll);\n\n this.assignAccordionsEvents();\n\n this.sidebar.addEventListener('variationChange', this.replaceSidebarHtml);\n\n this.assignMobileEvents();\n }\n\n /**\n * @function assignMobileVariables\n * @private\n * @description initializes variables for mobile sidebar\n */\n assignMobileVariables() {\n this.sidebarHeader = document.querySelector('.js-configurator-sidebar-header');\n this.sidebarBody = document.querySelector('.js-configurator-sidebar-body');\n this.sidebarFooter = document.querySelector('.js-configurator-sidebar-footer');\n this.sidebarSubmitBtn = document.querySelector('.js-configurator-submit-btn');\n this.productForm = document.querySelector('#product-form');\n this.tapAreaFooter = document.querySelector('.js-card-footer-tap-area');\n this.tapAreaHeader = document.querySelector('.js-card-header-tap-area');\n this.pageHeader = document.querySelector('.js-page-header');\n this.chatButton = document.querySelector('.dimelo_chat_item_markup');\n }\n\n /**\n * @function assignMobileEvents\n * @private\n * @description initializes event listeners for mobile sidebar\n */\n assignMobileEvents() {\n this.tapAreaFooter.addEventListener('click', this.openMobileSidebar);\n this.tapAreaHeader.addEventListener('click', this.closeMobileSidebar);\n }\n\n /**\n * @function notifyQuantityCard\n * @description Notifies the quantity card that shared data info has changed and should be updated.\n * @param {HTMLTemplateElement} fragment - The fragment received from the variationChange event.\n */\n static notifyQuantityCard(fragment) {\n // Grab the shared data container which is part of the current configuration so in vz-group-summary\n const sharedDataContainer = fragment.content.querySelector('vz-group-summary .js-shared-data-container');\n const quantitySelector = document.querySelector('.js-business-mobile-quantity-card vz-quantity-selector');\n\n if (quantitySelector && sharedDataContainer) {\n quantitySelector.dispatchEvent(\n new CustomEvent('updateSharedData', {\n detail: {\n sharedDataContainer\n }\n })\n );\n }\n }\n\n /**\n * @function replaceSidebarHtml\n * @param { event } event - The custom event\n * @description Replaces the sidebar with new html from an ajax call, and notifies the quantity card so it can add and update the shared data info.\n */\n replaceSidebarHtml(event) {\n const {\n detail: { fragment }\n } = event;\n\n // Notify the product card so the shared data container can be added to it\n Sidebar.notifyQuantityCard(fragment);\n\n // Replace the sidebar summary html with the new html\n this.sidebar.querySelector('.configurator-summary').innerHTML = '';\n // Add new HTML AFTER removal to ensure order of connectedCallback & disconnectedCallback\n this.sidebar.querySelector('.configurator-summary').innerHTML = fragment.content.querySelector('.js-configurator-sidebar .configurator-summary').innerHTML;\n\n // Update the share button\n const shareButton = this.sidebar.querySelector('vz-copy-to-clipboard');\n if (shareButton) shareButton.replaceWith(fragment.content.querySelector('vz-copy-to-clipboard'));\n\n // Update variables and event listeners after replacing HTML for mobile sidebar\n this.assignMobileVariables();\n this.initAccordions();\n this.handleScroll();\n\n if (window.innerWidth < this.stickyBreakpoint) this.assignMobileEvents();\n\n this.assignAccordionsEvents();\n this.handleFloatingSidebar();\n }\n\n /**\n * @function handleFloatingSidebar\n * @private\n * @description Handles the styling required for the sidebar to become sticky at certain resolutions\n */\n handleFloatingSidebar() {\n // Show bottom fixed sidebar (mobile)\n if (window.innerWidth < this.stickyBreakpoint) {\n this.mobileSidebarScrollHandler();\n\n this.sidebar.style.removeProperty('position');\n this.sidebar.style.removeProperty('top');\n this.sidebar.style.removeProperty('bottom');\n this.sidebar.style.removeProperty('width');\n\n if (this.isStep1InViewport()) {\n this.sidebarScrollContainer.classList.add('visible-on-mobile');\n } else {\n this.sidebarScrollContainer.classList.remove('visible-on-mobile');\n }\n\n if (this.sidebar.classList.contains('open')) {\n this.openMobileSidebar();\n } else {\n this.closeMobileSidebar();\n }\n } else {\n this.sidebarScrollContainer.classList.remove('visible-on-mobile');\n\n this.openMobileSidebar();\n\n this.sidebarBody.style.removeProperty('max-height');\n\n // Adjust and display chat button for desktop\n if (this.chatButton) this.chatButton.classList.remove('adjust-for-sidebar', 'd-none');\n\n if (this.isSidebarOverflowing) {\n if (this.isSidebarAtBottom() && this.isSidebarInContainer()) {\n if (this.isSidebarAtBottomContainer()) {\n // Sidebar is larger than screen height + the sidebar bottom is at the bottom of the screen\n // Bottom of sidebar is aligned with configurator -> position absolute\n assignStyling(this.sidebar, {\n position: 'absolute',\n bottom: '30px',\n width: `${this.sidebarScrollContainer.clientWidth - 24}px`,\n top: 'auto'\n });\n } else {\n // As long as we can scroll down and the sidebar bottom is not aligned with configurator bottom -> position fixed\n assignStyling(this.sidebar, {\n position: 'fixed',\n bottom: `${this.sidebarBottomOffset}px`,\n width: `${this.sidebarScrollContainer.clientWidth - 24}px`,\n top: 'auto'\n });\n }\n } else {\n this.sidebar.style.removeProperty('position');\n }\n } else {\n // Sidebar is smaller than screen height or at the top -> position sticky\n assignStyling(this.sidebar, {\n position: 'sticky',\n top: `${this.headerHeight + this.sidebarTopOffset}px`,\n bottom: 'auto',\n width: 'initial'\n });\n }\n }\n }\n\n mobileSidebarSlideOut() {\n this.sidebarScrollContainer.classList.add('offscreen');\n\n if (this.chatButton) this.chatButton.classList.remove('adjust-for-sidebar');\n\n this.sidebarOffscreen = true;\n }\n\n mobileSidebarSlideIn() {\n this.sidebarScrollContainer.classList.remove('offscreen');\n\n if (this.chatButton) this.chatButton.classList.add('adjust-for-sidebar');\n\n this.sidebarOffscreen = false;\n }\n\n mobileSidebarScrollHandler() {\n // Get latest height for accuracy\n this.sidebarScrollContainer = this.sidebar.closest('.js-configurator-sidebar-scroll-container');\n\n if (window.scrollY >= this.sidebarScrollContainer.offsetHeight || this.sidebar.classList.contains('open')) {\n this.mobileSidebarSlideIn();\n } else {\n this.mobileSidebarSlideOut();\n }\n }\n\n isSidebarAtBottom() {\n return window.innerHeight - this.sidebar.getBoundingClientRect().bottom - this.sidebarBottomOffset + 1 > 0;\n }\n\n isSidebarAtBottomContainer() {\n return window.innerHeight - this.sidebarScrollContainer.getBoundingClientRect().bottom - this.sidebarBottomOffset + 30 > 0;\n }\n\n isSidebarInContainer() {\n return this.sidebar.getBoundingClientRect().top - this.sidebarScrollContainer.getBoundingClientRect().top >= 0;\n }\n\n handleScroll() {\n this.isSidebarOverflowing = this.sidebar.offsetHeight >= window.innerHeight - this.headerHeight - this.sidebarTopOffset - this.sidebarBottomOffset;\n\n this.handleFloatingSidebar();\n }\n\n isStep1InViewport() {\n return window.innerHeight > this.productForm.getBoundingClientRect().top + 2 * this.sidebarBottomOffset;\n }\n\n openMobileSidebar() {\n this.sidebarHeader.classList.remove('d-none');\n this.sidebarBody.classList.remove('d-none');\n this.sidebar.classList.remove('closed');\n this.sidebar.classList.add('open');\n this.sidebarFooter.classList.add('py-2');\n\n if (this.configuratorType !== 'business-mobile') this.sidebarFooter.classList.add('mt-2');\n\n this.sidebarFooter.classList.remove('py-1');\n\n if (this.sidebarSubmitBtn) {\n this.sidebarSubmitBtn.classList.add('mt-3');\n this.sidebarSubmitBtn.classList.remove('mt-1');\n }\n\n if (window.innerWidth < this.stickyBreakpoint) {\n assignStyling(this.sidebarBody, {\n 'max-height': `${this.calculateMaxHeightMobileSidebarBody()}px`\n });\n }\n\n if (this.chatButton) this.chatButton.classList.add('d-none');\n }\n\n closeMobileSidebar() {\n this.sidebarHeader.classList.add('d-none');\n this.sidebarBody.classList.add('d-none');\n this.sidebar.classList.add('closed');\n this.sidebar.classList.remove('open');\n this.sidebarFooter.classList.remove('mt-2', 'py-2');\n this.sidebarFooter.classList.add('py-1');\n\n if (this.sidebarSubmitBtn) {\n this.sidebarSubmitBtn.classList.remove('mt-3');\n this.sidebarSubmitBtn.classList.add('mt-1');\n }\n\n if (this.chatButton) this.chatButton.classList.remove('d-none');\n\n // Only slide out on close when at the top of the page\n if (window.scrollY === 0) this.mobileSidebarSlideOut();\n }\n\n calculateMaxHeightMobileSidebarBody() {\n return (\n window.innerHeight -\n this.pageHeader.clientHeight -\n this.sidebarFooter.clientHeight -\n this.sidebarHeader.clientHeight -\n 0.5 * this.sidebarTopOffset -\n this.sidebarBottomOffset\n );\n }\n\n /**\n * @function assignAccordionsEvents\n * @description\n * This method assigns event listeners to each accordion element on the sidebar.\n * When an accordion is collapsed (hidden), the 'handleScroll' method is invoked to recalculate sticky sidebar position.\n */\n assignAccordionsEvents() {\n Array.from(document.querySelectorAll('.js-sidebar-accordion-content')).forEach((accordion) => accordion.addEventListener('hidden.bs.collapse', this.handleScroll));\n }\n\n /**\n * @function initAccordions\n * @description\n * Initializes the accordion functionality based on window width.\n */\n initAccordions() {\n if (this.configuratorType !== 'business-mobile') return;\n\n this.summaryGroup = document.querySelector('vz-group-summary');\n this.accordions = document.querySelectorAll('.js-sidebar-accordion-content');\n\n if (window.innerWidth < this.stickyBreakpoint) {\n this.summaryGroup?.classList.remove('accordion');\n\n if (this.accordions.length) {\n Array.from(this.accordions).forEach((element) => element.classList.remove('collapse', 'collapsed'));\n }\n } else {\n this.summaryGroup?.classList.add('accordion');\n\n if (this.accordions.length) {\n Array.from(this.accordions).forEach((element) => element.classList.add('collapse', 'collapsed'));\n }\n }\n }\n}\n\n(() => new Sidebar())();\n","'use strict';\n\nconst computedStyles = getComputedStyle(document.documentElement);\n\n/**\n * @constant {Object} events - All common events\n * @property {string} blur - Blur event\n * @property {string} change - Change event\n * @property {string} click - Click event\n * @property {string} keyUp - Keyup event\n * @property {string} load - Load event\n * @property {string} mousedown - Mouse down event\n * @property {string} mouseleave - Mouse leave event\n * @property {string} mouseover - Mouse over event\n * @property {string} popstate - Popstate event\n * @property {string} resize - Resize event\n * @property {string} scroll - Scroll event\n * @property {string} submit - Submit event\n * @property {string} update - Custom update event\n */\nconst events = {\n blur: 'blur',\n change: 'change',\n click: 'click',\n input: 'input',\n keyUp: 'keyup',\n load: 'load',\n mousedown: 'mousedown',\n mouseleave: 'mouseleave',\n mouseover: 'mouseover',\n paste: 'paste',\n popstate: 'popstate',\n resize: 'resize',\n responseError: 'responseError',\n scroll: 'scroll',\n submit: 'submit',\n transitionEnd: 'transitionend',\n update: 'update',\n invalid: 'invalid'\n};\n\n/**\n * @constant {Object} selectors - Common selectors\n * @property {string} body - body\n * @property {Object} form - form related selectors\n * @property {string} checkbox - checkbox\n * @property {string} form - form\n * @property {string} input - input\n * @property {string} inputFieldClear - .js-input-clear\n * @property {string} inputFieldFeedback - .js-invalid-feedback\n * @property {string} label - label\n * @property {string} radio - radio\n * @property {string} select - select\n * @property {string} submit - [type=\"submit\"]\n * @property {string} textarea - textarea\n * @property {string} html - html\n * @property {string} htmlBody - html, body\n * @property {string} img - img\n * @property {string} input - input\n */\nconst selectors = {\n body: 'body',\n form: {\n checkbox: 'input[type=\"checkbox\"]',\n file: 'input[type=\"file\"]',\n form: 'form',\n input: 'input',\n inputFieldClear: '.js-input-clear',\n inputFieldFeedback: '.js-invalid-feedback',\n label: 'label',\n radio: 'input[type=\"radio\"]',\n select: 'select',\n submit: '[type=\"submit\"]',\n textarea: 'textarea'\n },\n html: 'html',\n htmlBody: 'html, body',\n img: 'img',\n input: 'input',\n interactiveElements: 'input, button, select, textarea, a[href]'\n};\n\n/**\n * @constant {Object} classes - Common classes\n * @property {string} active - active\n * @property {Object} buttons - buttons\n * @property {string} next - next\n * @property {string} previous - previous\n * @property {string} warning - warning\n * @property {string} dBlock - d-block\n * @property {string} dFlex - d-flex\n * @property {string} dInlineBlock - d-inline-block\n * @property {string} dNone - d-none\n * @property {string} disabled - disabled\n * @property {string} empty - empty\n * @property {string} inactive - inactive\n * @property {string} invalid - invalid\n * @property {string} hidden - hidden\n * @property {string} last - last\n * @property {string} show - show\n * @property {string} valid - valid\n */\nconst classes = {\n active: 'active',\n buttons: {\n next: 'js-button-next',\n previous: 'js-button-previous',\n warning: 'js-button-warning'\n },\n dBlock: 'd-block',\n dFlex: 'd-flex',\n dInlineBlock: 'd-inline-block',\n dNone: 'd-none',\n disabled: 'disabled',\n empty: 'empty',\n inactive: 'inactive',\n invalid: 'invalid',\n hidden: 'hidden',\n last: 'last',\n show: 'show',\n valid: 'valid'\n};\n\n/**\n * @constant {Object} attributes - Common attributes\n * @property {string} action - action\n * @property {string} class - class\n * @property {string} csrfToken - data-csrf-token\n * @property {string} csrfName - data-csrf-name\n * @property {string} disabled - disabled\n * @property {string} exclude - data-exclude\n * @property {string} href - href\n * @property {string} id - id\n * @property {string} pattern - pattern\n * @property {string} url - url\n * @property {string} readonly - readonly\n * @property {string} target - data-bs-target\n * @property {string} value - value\n * @property {Object} validation - Validation related attributes\n * @property {string} patternMismatch - data-pattern-mismatch\n * @property {string} valueMissing - data-missing-error\n */\nconst attributes = {\n action: 'action',\n class: 'class',\n checked: 'checked',\n csrfToken: 'data-csrf-token',\n csrfName: 'data-csrf-name',\n disabled: 'disabled',\n exclude: 'data-exclude',\n href: 'href',\n id: 'id',\n pattern: 'pattern',\n placeholder: 'placeholder',\n required: 'required',\n readonly: 'readonly',\n selected: 'selected',\n target: 'data-bs-target',\n url: 'url',\n value: 'value',\n validation: {\n patternMismatch: 'data-pattern-mismatch',\n valueMissing: 'data-missing-error',\n tooShort: 'data-too-short'\n }\n};\n\n/**\n * @constant {Object} breakpoints - Common reusable breakpoints\n * @property {string} xxs - 0\n * @property {string} xs - 368\n * @property {string} sm - 576\n * @property {string} md - 768\n * @property {string} lg - 992\n * @property {string} xl - 1200\n * @property {string} xxl - 1400\n */\n\nconst breakpoints = {\n xxs: parseInt(computedStyles.getPropertyValue('--breakpoint-xxs'), 10),\n xs: parseInt(computedStyles.getPropertyValue('--breakpoint-xs'), 10),\n sm: parseInt(computedStyles.getPropertyValue('--breakpoint-sm'), 10),\n md: parseInt(computedStyles.getPropertyValue('--breakpoint-md'), 10),\n lg: parseInt(computedStyles.getPropertyValue('--breakpoint-lg'), 10),\n xl: parseInt(computedStyles.getPropertyValue('--breakpoint-xl'), 10),\n xxl: parseInt(computedStyles.getPropertyValue('--breakpoint-xxl'), 10)\n};\n\n/**\n * @constant {Object} localStorage - constants for local storage items\n * @property {string} preferredLayoutId - preferredLayoutId\n */\nconst localStorage = {\n preferredLayoutId: 'preferredLayoutId'\n};\n\n/**\n * @constant {Object} bscanSteps - constants for Business Scan Steps\n * @property {string} ADVICE - The advice Step\n * @property {string} INTRO - The intro Step\n * @property {string} GROUPED_QUESTIONS - The grouped questions Step\n * @property {string} THANKYOU - The thank you Step\n */\nconst bscanSteps = {\n INTRO: 'intro',\n STATEMENTS_DONE: 'bs-statements-done',\n GROUPED_QUESTIONS: 'js-bscan-question-group',\n ADVICE: 'bs-advice',\n THANKYOU: 'bs-thank-you'\n};\n\n/**\n * @constant {Object} vzLayoutToggle - Attributes used for VZLayoutToggle\n * @property {string} class - data-layout-class\n * @property {string} container - data-layout-container\n * @property {string} enabledBreakpoint - data-layout-enabled-breakpoint\n * @property {string} id - data-layout-id\n * @property {string} idDefault - data-layout-id-default\n * @property {string} localStorageKey - data-layout-key\n */\nconst vzLayoutToggle = {\n class: 'data-layout-class',\n container: 'data-layout-container',\n enabledBreakpoint: 'data-layout-enabled-breakpoint',\n id: 'data-layout-id',\n idDefault: 'data-layout-id-default',\n localStorageKey: 'data-layout-key'\n};\n\nexport default {\n bscanSteps,\n attributes,\n breakpoints,\n classes,\n events,\n selectors,\n localStorage,\n vzLayoutToggle\n};\n","'use stict';\n\nimport 'core-js/features/array/at';\n\n/**\n * @private splitUpUrl\n * @param {string} url - The url to split up\n * @returns {Object} values\n *\n * @description\n * Will return an object with different parts of the url\n */\nexport function splitUpUrl(url) {\n if (!url.includes('?')) return {};\n\n let hash;\n let paramUrl = url.split('?').at(1);\n\n // if there is a hash at the end, store the hash\n if (paramUrl.includes('#')) {\n hash = paramUrl.split('#').at(1);\n paramUrl = paramUrl.split('#').at(0);\n }\n\n return {\n domain: url.split('?').at(0),\n params: paramUrl.split('&'),\n hash: hash\n };\n}\n\n/**\n * @public removeParamFromURL\n * @param {string} url - The url from which the parameter will be removed\n * @param {string} name - The name of the parameter that will be removed from url\n * @returns {string} url\n *\n * @description\n * remove the parameter and its value from the given url and returns the\n * changed url\n */\nexport function removeParamFromURL(url, name) {\n if (!url.includes('?') || !url.includes(`${name}=`)) return url;\n\n const urlValues = splitUpUrl(url);\n const newParams = urlValues.params.filter((param) => param.split('=').at(0) !== name);\n\n return `${urlValues.domain}?${newParams.join('&')}${urlValues.hash ? `#${urlValues.hash}` : ''}`;\n}\n\n/**\n * @public getParamFromURL\n * @param {string} url - The url from which the parameter will be retrieved\n * @param {string} name - The name of the parameter that will be retrieved from url\n * @returns {string} The value of the parameter\n *\n * @description\n * remove the parameter and its value from the given url and returns the\n * changed url\n */\nexport function getParamFromURL(url, name) {\n if (!url.includes('?') || !url.includes(`${name}=`)) return url;\n\n const urlValues = splitUpUrl(url);\n const nameMatch = urlValues.params.find((item) => item.includes(`${name}=`));\n\n return nameMatch && nameMatch.split('=').at(1);\n}\n\n/**\n * @public appendParamToURL\n * @param {string} url - The url to which the parameter will be added\n * @param {string} name - The name of the parameter\n * @param {string} value the value of the parameter\n * @returns {string} url\n *\n * @description\n * appends the parameter with the given name and value to the given url\n * and returns the changed url\n */\nexport function appendParamToURL(url, name, value) {\n let newURL = url;\n // remove if the param already exists\n if (url.includes(`${name}=`)) {\n newURL = removeParamFromURL(url, name);\n }\n const separator = newURL.includes('?') ? '&' : '?';\n return `${newURL}${separator}${name}=${encodeURIComponent(value)}`;\n}\n\n/**\n * @public appendCsrfToUrl\n * @description Takes a URL and adds a CSRF token to it\n * @param {string} url - The URL to append the CSRF token on\n * @returns {string} The URL with the CSRF token appended\n */\nexport function appendCsrfToUrl(url) {\n const separator = url.includes('?') ? '&' : '?';\n return `${url}${separator}${window.csrf.tokenName}=${window.csrf.token}`;\n}\n\n/**\n * @public removeHash\n * @description Will remove the hash from the url\n */\nexport function removeHash() {\n window.history.replaceState({}, document.title, window.location.pathname + window.location.search);\n}\n\nexport const getUrlFromAttributes = (url, component, excludedAttributes) => {\n const newUrl = new URL(url);\n const urlParams = newUrl.searchParams;\n\n // Get all attributeNames except for the irrelevant ones.\n const attributeNames = component.getAttributeNames().filter((attributeName) => !excludedAttributes.includes(attributeName));\n\n // Filter the attributeNames which will be replaced by the new URL.\n attributeNames\n .filter((param) => !urlParams.has(param.replaceAll('-', '')))\n .forEach((attr) => {\n const attrValue = component.getAttribute(attr);\n if (attrValue) {\n const attrName = attr.replaceAll('-', '');\n // Append all other attributes to the new URL\n urlParams.append(attrName, attrValue);\n }\n });\n\n return `${newUrl.origin}${newUrl.pathname}?${urlParams}`;\n};\n\n/**\n * This function checks if the provided element is a part of BM Hardware card. In case of true it appends\n * the 'editIndex' parameter to the URL with the index of the current BM Hardware card, in order to keep the\n * card open after Product-Variation ajax.\n *\n * @public appendBmHardwareCardIndex\n * @param {HTMLElement} element - The HTML element triggering the ajax.\n * @param {string} url - The URL to which the parameter will be appended.\n * @returns {string} The modified URL with the appended parameter.\n */\nexport function appendBmHardwareCardIndex(element, url) {\n let newURL = url;\n if (!element.closest('.js-hardware-device-card')?.classList.contains('is-collapsed') && element.closest('.js-hardware-phones')) {\n newURL = appendParamToURL(url, 'editIndex', element.closest('.js-hardware-phones').dataset.index);\n }\n return newURL;\n}\n","'use strict';\n\nimport CONST from './constants';\n\n/**\n * addEvent - Will add an event listener to an element inside a parent\n *\n * @param {string} parent - The parent element\n * @param {string} passedEvent - The event\n * @param {string} selector - The targeted element\n * @param {function} handler - The handler\n */\nfunction addEvent(parent, passedEvent, selector, handler) {\n parent.addEventListener(\n passedEvent,\n function fnAddEvent(event) {\n // If the clicked element matches the selector, or is a child of the selector\n if (event.target.matches(`${selector} , ${selector} *`)) {\n handler.apply(event.target.closest(selector), arguments);\n }\n },\n false\n );\n}\n\n/**\n * @public documentReady\n * @param {Function} fn - function to be called after document is done loading.\n */\nfunction documentReady(fn) {\n if (document.readyState !== 'loading') {\n fn();\n } else {\n document.addEventListener('DOMContentLoaded', fn);\n }\n}\n\n/**\n * @public exists\n * @param {*} selection - The element or nodelist to verify for existence\n * @returns {boolean} - Boolean value stating the existance of the selection\n * @description\n * Verifies existance of a certain element by checking for type, null and length\n * Usage: use with either querySelector() or querySelectorAll()\n * querySelector will not have a 'length', e.g. this would return true if other conditions are true\n * querySelectorAll will have a 'length', e.g. this would return true if all conditions are true\n */\nfunction exists(selection) {\n return typeof selection !== 'undefined' && selection !== null && ('length' in selection ? selection.length > 0 : true);\n}\n\n/**\n * @public getPosition\n * @param {*} element - The element to get the position for\n * @returns {Object} - An object containing the left and top position of the element\n *\n * @description\n * Will get the position of an element relative to the document\n */\nfunction getPosition(element) {\n let top = element.offsetTop;\n let left = element.offsetLeft;\n\n let currentElement = element;\n while (currentElement.offsetParent && currentElement.offsetParent !== window) {\n currentElement = currentElement.offsetParent;\n top += currentElement.offsetTop;\n left += currentElement.offsetLeft;\n }\n\n return { left, top };\n}\n\n/**\n * isKeyInObject\n * @param {Object} object - The object\n * @param {string} key - The key\n * @returns {boolean} - True or false\n */\nfunction isKeyInObject(object, key) {\n return Object.prototype.hasOwnProperty.call(object, key);\n}\n\n/**\n * @private isAemMobileView\n * @returns {boolean} - Whether the user is on a \"mobile\" viewport or not based on AEM rules\n *\n * @description\n * Checks to see whether the user is on a \"mobile\" viewport or not based on AEM rules\n * Please note that www.vodafone.nl/zakelijk will show the mobile menu from viewports 1023 and smaller\n */\nfunction isAemMobileView() {\n return window.innerWidth < 1024;\n}\n\n/**\n * @memberof util\n * @param {string} breakpointKey from constants that should match css breakpoint\n * @param {boolean} [isUp] by default is true since mobile first, reverses condition\n * @return {boolean} whether window is larger than specified breakpoint\n */\nfunction isMediaBreakpoint(breakpointKey, isUp = true) {\n if (!isKeyInObject(CONST.breakpoints, breakpointKey)) {\n console.error(`fn isMediaBreakpoint: ${breakpointKey} -- does not exist in constants breakpoints object`); // eslint-disable-line\n }\n\n const outerWidth = window.innerWidth;\n const breakpointValue = parseInt(CONST.breakpoints[breakpointKey], 10);\n\n return isUp ? outerWidth > breakpointValue : outerWidth < breakpointValue - 1;\n}\n\n/**\n * @memberof util\n * @return {Object} An object containing the name and value of the current breakpoint\n */\nfunction getCurrentBreakpoint() {\n const breakpoints = CONST.breakpoints;\n const screenSize = document.documentElement.clientWidth;\n const currentBreakpoint = [...Object.keys(breakpoints)].reverse().find((key) => screenSize > breakpoints[key]);\n\n return {\n name: currentBreakpoint,\n value: breakpoints[currentBreakpoint]\n };\n}\n\n/**\n * @memberof util\n * @return {number} a unique number\n */\nfunction generateUniqueNumber() {\n return performance.now().toString().replace('.', 0);\n}\n\n/**\n * @public empty\n * @param {*} element - The element to remove child nodes from\n * @description\n * Empties a given element completely while the given element has child nodes.\n * Plain strings are also considered child nodes and are thus also removed.\n */\nfunction removeChildNodes(element) {\n while (element.hasChildNodes()) {\n element.removeChild(element.lastChild);\n }\n}\n\n/**\n * @public tryParseJSON\n * @param {string} string - The possible JON string\n * @returns {Object} - Either the JSON object or an empty object for consistent return\n * @description\n * Copied from https://stackoverflow.com/a/20392392\n */\nfunction tryParseJSON(string) {\n try {\n const o = JSON.parse(string);\n\n // Handle non-exception-throwing cases:\n // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,\n // but... JSON.parse(null) returns null, and typeof null === \"object\",\n // so we must check for that, too. Thankfully, null is falsey, so this suffices:\n if (o && typeof o === 'object') {\n return o;\n }\n } catch (e) {} // eslint-disable-line no-empty\n\n return {};\n}\n\n/**\n * @function isIOS\n * @public\n * @description returns a boolean to determine whether a device's OS is IOS or not\n * @returns {boolean} whether the device OS is IOS or not\n */\nfunction isIOS() {\n return (/iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) && !window.MSStream;\n}\n\n/**\n * @function isMobile\n * @returns {boolean} whether the device is an mobile device or not\n */\nfunction isMobile() {\n return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);\n}\n\n/**\n * @public scrollTo\n * @param {Object} data - The optional object containing the top & left positions to scroll to\n */\nfunction scrollTo(data) {\n const position = data || {\n top: 0,\n left: 0\n };\n\n const stickyHeader = document.querySelector('.page-header');\n const headerHeight = stickyHeader ? stickyHeader.offsetHeight : 0;\n const supportsNativeSmoothScroll = 'scrollBehavior' in document.documentElement.style;\n let positionTop = position.top;\n\n if (headerHeight > 0) {\n positionTop = position.top - headerHeight - 15; // Removing an additional 15px to put some space between the sticky site header and the element\n }\n\n if (supportsNativeSmoothScroll) {\n document.documentElement.scrollTo({\n top: positionTop,\n left: position.left,\n behavior: 'smooth'\n });\n } else {\n document.documentElement.scrollTop = positionTop;\n }\n}\n\n/**\n * @function toggleButtonState\n * @description Enables or disabled the button passed in based on the value of the second parameter.\n * @param {HTMLElement} button - A button element to be enabled or disabled.\n * @param {boolean} enable - True for enable and false for disable.\n */\nfunction toggleButtonState(button, enable) {\n if (enable) {\n button.classList.remove('disabled');\n button.removeAttribute('disabled');\n } else {\n button.classList.add('disabled');\n button.setAttribute('disabled', 'disabled');\n }\n}\n\n/**\n * @function removeAccentCharacters\n * @description Removes a accents from a string.\n * @param {string} string - The string from which we want to remove accents.\n * @returns {string} The string without accents.\n */\nfunction removeAccentCharacters(string) {\n return string.normalize('NFD').replace(/\\p{Diacritic}/gu, '');\n}\n\n/**\n * @function chunkArrayInGroups\n * @param {Array} arr - Array to be splitted\n * @param {number} size - Max size of the array chunk\n * @return {Array} - Array of grouped chunks\n * @description Splitting an array up into chunks of a given size\n */\nfunction chunkArrayInGroups(arr, size) {\n var groupedChunks = [];\n for (let i = 0; i < arr.length; i += size) {\n groupedChunks.push(arr.slice(i, i + size));\n }\n return groupedChunks;\n}\n\n/**\n * @function chunkGroupArrayInGroups\n * @param {Array} groupArr - Array to be splitted\n * @return {Array} - Array of grouped chunks\n * @description Splitting an array up into chunks of a given size\n */\nfunction chunkGroupArrayInGroups(groupArr) {\n // This one sorts and groups the alike product groups together\n // We need to send the requests to backend in a specific order, so we make it grouped\n const chunkGroups = [];\n Object.keys(groupArr).forEach((groupKey) => {\n const arr = groupArr[groupKey];\n const groupedChunks = [];\n // Sorts the product objects based on pids\n arr.sort((a, b) => {\n return a.pid >= b.pid ? 1 : -1;\n });\n for (let i = 0; i < arr.length; i += Math.round(arr.length / 3)) {\n groupedChunks.push(arr.slice(i, i + Math.round(arr.length / 3)));\n }\n // This makes sure that we have a separate business mobile group to send to backend\n groupedChunks.forEach((chunk, chunkIndex) => {\n Object.keys(chunk).forEach((key, index) => {\n const item = chunk[key];\n if (item?.pdpConfiguratorType === 'business-mobile') {\n chunk.splice(index, 1);\n if (chunk.length < 1) groupedChunks.splice(chunkIndex, 1);\n groupedChunks.push(item);\n }\n });\n });\n chunkGroups.push(groupedChunks);\n });\n return chunkGroups;\n}\n\n/**\n * @function trackPdpEccomerceEvent\n * @param {string} productType - Configurator type\n * @param {Object} step - Step to track\n * @description Builds and submits ecommerce event to track btn clicks on PDP\n */\nfunction trackPdpEccomerceEvent(productType, step) {\n const products = {\n brand: 'vodafone',\n category: `business-sme/acquisition/postpaid/${productType.replace(/\\s|business-/gi, '')}`,\n market: 'b2b'\n };\n\n const ecommerceObject = {\n event: 'checkout',\n events: {\n category: 'ecommerce',\n action: 'checkout'\n },\n ecommerce: {\n checkout: {\n action: 'checkout',\n has_vodafone: true,\n has_ziggo: true,\n products: products,\n step_name: step.name,\n step_nr: step.number\n }\n }\n };\n\n /* eslint-disable no-underscore-dangle */\n if (ecommerceObject && window._ddm) {\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push(ecommerceObject);\n window._ddm.trigger('ecommerce.checkout', {\n data: ecommerceObject.ecommerce.checkout\n });\n }\n /* eslint-enable no-underscore-dangle */\n}\n\n/**\n * @function assignStyling\n * @private\n * @param {Element} el - Element\n * @param {Object} styles - Styles\n * @description Assign a style object to an element\n */\nfunction assignStyling(el, styles) {\n Object.assign(el.style, styles);\n}\n\n/**\n * Calculate the total width of a collection of elements.\n *\n * @param {NodeListOf} elements - A collection of HTML elements.\n * @param {number} spacing - flex gap value in px.\n * @returns {number} The total width of all elements.\n */\nfunction getTotalWidth(elements, spacing = 0) {\n return Array.from(elements).reduce((totalWidth, element) => {\n const elementStyles = window.getComputedStyle(element);\n const elementWidth = element.offsetWidth + parseFloat(elementStyles.marginLeft) + parseFloat(elementStyles.marginRight);\n return totalWidth + elementWidth;\n }, spacing);\n}\n\n/**\n * Checks if a flex container is wrapped by comparing the total width of its flex items\n * with the container's width.\n *\n * @param {HTMLElement} flexContainer - The HTML element representing the flex container.\n * @param {NodeListOf} flexItems - A collection of HTML elements representing the flex items.\n * @param {number} spacing - flex gap value in px.\n * @returns {boolean} True if the flex container is wrapped, false if all items fit in a single row.\n */\nfunction isFlexContainerWrapped(flexContainer, flexItems, spacing) {\n const containerWidth = flexContainer.clientWidth;\n const itemsTotalWidth = getTotalWidth(flexItems, spacing);\n // Check if the items are wrapped by comparing their total width with the container width.\n const isWrapped = itemsTotalWidth > containerWidth;\n return isWrapped;\n}\n\n/**\n * @function loadCSS\n * @param {string} url - The URL of the CSS file to load.\n * @description Creates a link element and appends it to the document head to load a CSS file.\n */\nfunction loadCSS(url) {\n if (!url || document.querySelector(`link[href=\"${url}\"]`)) {\n return;\n }\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = url;\n document.head.appendChild(link);\n}\n\n/**\n * The function formats input to money string\n *\n * @param {number} num Source number\n * @returns {string} Formatted string € 1.111,11\n */\nfunction formatToPriceString(num) {\n const parts = Number.parseFloat(num, 10).toFixed(2).toString().split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, '.');\n if (parts[1] === '00') {\n return `€ ${parts[0]},00`;\n }\n return `€ ${parts.join(',')}`;\n}\n\n/**\n * Checks if two arrays of objects are equal by comparing their elements.\n *\n * @param {Array} arr1 - The first array to compare.\n * @param {Array} arr2 - The second array to compare.\n * @returns {boolean} True if the arrays are equal, false otherwise.\n */\nfunction arraysAreEqual(arr1, arr2) {\n if (arr1.length !== arr2.length) {\n return false;\n }\n\n return (\n !arr1.some((obj1) => !arr2.some((obj2) => JSON.stringify(obj1) === JSON.stringify(obj2))) &&\n !arr2.some((obj2) => !arr1.some((obj1) => JSON.stringify(obj1) === JSON.stringify(obj2)))\n );\n}\n\nexport {\n CONST,\n addEvent,\n documentReady,\n exists,\n generateUniqueNumber,\n getCurrentBreakpoint,\n getPosition,\n isIOS,\n isMobile,\n isKeyInObject,\n isAemMobileView,\n isMediaBreakpoint,\n removeChildNodes,\n scrollTo,\n tryParseJSON,\n toggleButtonState,\n removeAccentCharacters,\n chunkArrayInGroups,\n chunkGroupArrayInGroups,\n trackPdpEccomerceEvent,\n assignStyling,\n isFlexContainerWrapped,\n getTotalWidth,\n loadCSS,\n formatToPriceString,\n arraysAreEqual\n};\n","'use strict';\n\nimport { CONST } from 'Util/util';\nimport { getFieldValidationMessage } from 'Components/form/form';\n\nconst validationAttributes = ['valueMissing', 'patternMismatch', 'tooShort'];\n\n/**\n * toggleValidityClass\n * @param {boolean} [isValid] - valid or not - true or false\n * @param {HTMLElement} [target] - target element\n */\nfunction toggleValidityClass(isValid, target) {\n if (isValid) {\n target.classList.remove('invalid');\n target.classList.add('valid');\n } else {\n target.classList.add('invalid');\n target.classList.remove('valid');\n }\n}\n\n/**\n * removeValidationMessageElement\n * @param {HTMLElement} [target] - target element\n */\nfunction removeValidationMessageElement(target) {\n const element = target.parentElement.querySelector('.error-msg');\n if (element) element.remove();\n}\n\n/**\n * createValidationMessageElement\n * @param {string} [message] - validation message\n * @param {HTMLElement} [target] - target element\n */\nfunction createValidationMessageElement(message, target) {\n const element =\n target.parentElement.querySelector('.error-msg') ||\n (function createErrorElement() {\n const el = document.createElement('small');\n el.classList.add('error-msg', 'text-primary');\n return el;\n })();\n element.innerText = message;\n if (target.dataset.selectedId && target.dataset.selectedId.includes('verblijfsdocument')) element.classList.add('d-inline-flex');\n target.parentElement.insertAdjacentElement('beforeend', element);\n}\n\n/**\n * @public validateField\n * @param {HTMLFormElement} field - The form field\n * @return {boolean} valid - Whether the field is valid or not\n */\nfunction validateField(field) {\n let validField = true;\n\n validationAttributes.forEach((attribute) => {\n if (field.validity && field.validity[attribute]) {\n const errorMessage = field.getAttribute(CONST.attributes.validation[attribute]);\n validField = false;\n createValidationMessageElement(errorMessage, field);\n toggleValidityClass(false, field);\n }\n });\n\n if (validField) {\n removeValidationMessageElement(field);\n toggleValidityClass(true, field);\n }\n\n return validField;\n}\n\n/**\n * @public validateForm\n * @param {HTMLForm} form - The form\n * @return {boolean} valid - Whether the form is valid or not\n */\nfunction validateForm(form) {\n let validForm = true;\n const formFields = [...form.querySelectorAll(CONST.selectors.form.input), ...form.querySelectorAll(CONST.selectors.form.textarea)];\n const dropdowns = [...form.querySelectorAll('.js-custom-select-validation')];\n\n formFields.forEach((field) => {\n if (field.type === 'hidden') {\n return;\n }\n\n const validField = validateField(field);\n\n if (!validField) {\n validForm = false;\n }\n });\n\n dropdowns.forEach((dropdown) => {\n const validField = dropdown.checkValidity();\n\n if (!validField) {\n validForm = false;\n }\n });\n\n return validForm;\n}\n\n/**\n * @private validate\n * @param {Event} evt - blur or invalid event\n * @param {string} [msg] - validation message\n */\nfunction validate(evt, msg) {\n const message = msg || getFieldValidationMessage(evt.target);\n if (message) {\n createValidationMessageElement(message, evt.target);\n toggleValidityClass(false, evt.target);\n } else {\n removeValidationMessageElement(evt.target);\n toggleValidityClass(true, evt.target);\n }\n}\n\nexport { validateForm, validateField, validate, removeValidationMessageElement, toggleValidityClass };\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","__webpack_require__.amdO = {};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","__webpack_require__.j = 207;","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t207: 0,\n\t743: 0,\n\t124: 0,\n\t274: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = (parentChunkLoadingFunction, data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some((id) => (installedChunks[id] !== 0))) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = globalThis[\"webpackChunkvodafoneziggo\"] = globalThis[\"webpackChunkvodafoneziggo\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [395,661,139], () => (__webpack_require__(9742)))\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","Animation","shakeSubtle","element","classList","add","addEventListener","remove","once","VZConfirmationModal","constructor","window","bs","Modal","this","confirmationModal","document","getElementById","toggleConfirmationModal","bind","show","Promise","resolve","handleCancel","cleanup","handleConfirm","_element","querySelector","removeEventListener","reject","Error","redSpinnerData","require","VZSpinner","HTMLElement","parentEl","super","showing","stop","veil","parentElement","body","tagName","appendChild","lottie","Lottie","container","renderer","loop","autoplay","animationData","start","msg","getComputedStyle","getPropertyValue","style","position","insertAdjacentHTML","setTimeout","play","contains","content","connectedCallback","innerHTML","evt","stopPropagation","customElements","get","define","getFieldValidationMessage","field","validity","valid","required","value","length","getAttribute","checked","matches","pattern","RegExp","test","dataset","mask","invalid","invalidMin","invalidMax","multipleAdditions","selectors","errorModal","activeModal","modalStepContainer","modalStep","modalStepInputs","showErrorModal","title","cta","errorModalHtml","existingModal","getInstance","modal","CONST","events","popstate","hide","VZAlert","removeAlert","showAlert","hasCookie","then","catch","onClose","disconnectedCallback","name","cookie","split","find","indexOf","expirationDate","Date","setTime","getTime","cookieString","toGMTString","Alert","r","e","t","f","n","Array","isArray","arguments","ModalHelper","defaultOptions","headerBorder","backdrop","keyboard","closeBtn","getDefaultModalHtml","configurationOptions","bodyText","bodyTitle","closeBtnUrl","iconName","isSecondaryBtnDismiss","primaryBtnUrl","primaryBtnTarget","primaryBtnText","secondaryBtnTarget","secondaryBtnText","secondaryBtnUrl","titleText","modalFooterClasses","tertiaryBtnTarget","tertiaryBtnText","tertiaryBtnUrl","clsx","renderAbandonConfigurationModal","querySelectorAll","forEach","editButton","abandonConfigurationModalId","abandonConfigurationModal","render","VZModal","setAttribute","hasCustomHtml","customModal","modalHelper","createTemplate","templateHtml","template","createElement","cloneNode","options","showModal","defaultModalHTML","keyboardSetting","newModal","hideModal","ID_TYPES_CODES","ID_VALIDATION_RULES","ID_TYPE","setValidationPattern","target","id","closest","dispatchEvent","CustomEvent","detail","type","regex","CapsMask","onInput","selectionStart","toUpperCase","setSelectionRange","UNDO_KEYS","PostCodeMask","onKeyUp","key","toLocaleLowerCase","some","k","substring","replace","IBANMask","DateMask","cursorIndex","maskText","pressedCharacters","onPaste","replaceRemovedDigitWithLetter","onArrowRight","onArrowLeft","onCharacterRemoval","checkIfDashIsSelected","replaceAsYouType","onKeyDown","runRegexOnValue","totalLengthUntilLastDigit","newVal","totalLength","join","cursorOffset","removedCharacter","splice","addDashes","direction","offset","replaceAt","index","replacement","isDigit","isNaN","allowedDash","hasSelection","repeat","preventDefault","selectionEnd","push","val","charRemoved","firstPressedCharacter","shift","maskType","preventCharacters","event","bannedCharacters","includes","clipboardData","dataWithoutBannedCharacters","getData","filter","character","currValue","end","substr","preventEntry","keyCode","documentNumber","toString","lastIndex","originalErrorMsg","patternError","selectedId","toLowerCase","startsWith","patternX00Error","patternVError","idType","Object","defineProperty","enumerable","configurable","Mask","password","feedbackElement","showPassword","set","readonly","hasAttribute","bool","enable","disable","writable","VZInputField","HTMLInputElement","validatePattern","setFieldStatus","validate","decorators","disableExcludedFields","hasValue","placeholderIsShown","placeholderActive","selector","nodeName","extends","PostcodeCheckHelpers","stripLeadingZero","data","parseInt","preventDashDotComma","respectMaxLength","maxLength","slice","removePAID","hiddenInputWithPaid","hideForm","showForm","handleErrors","error","console","warn","JSON","parse","generalError","fetchAddressAndAvailability","endpoint","form","formData","FormData","append","csrf","tokenName","token","configuratorType","fetchOptions","method","response","fetch","ok","status","json","removeExistingFeedbackMessage","classNames","existingMessages","message","showFeedbackMessage","isError","templateString","messageElement","DOMParser","parseFromString","handleUnableToOrder","responseHeadingElement","textContent","addressCheckAddress","pushErrorsToDataLayer","addressParts","locationAlreadyInBasket","dataLayer","postalCode","houseNumber","extension","paid","elementToPush","payload","erroneousAddressCombination","AddressCheck","availabilityForm","additionSelectElement","addressCheckEndpoint","addressCheckUrl","spinner","addition","handleAdditionOnBlur","input","handleAddressCheckOnBlur","executeAddressCheckOnLoad","sortAddressExtensions","addressInfoArray","sort","a","b","indexOfNoExtension","address","extensionRequired","removeAdditionOptions","optionsArray","defaultOption","option","selectedIndex","generateAdditionElementOptions","addressInfo","hasMultipleExtensions","reduce","result","formattedAddress","stringifiedAddressParts","stringify","encodeURI","selectedExtensionOption","selected","addressCheckPAID","hiddenInputWithPAID","addressCheckAddressParts","decodeURI","checkValidity","toggleButtonState","submitButton","postcodeInputElement","houseNumberInputElement","every","executeAddressCheck","PCHelpers","handleAddressNotFound","handleMultipleAdditions","addressCheckResponseData","additionHelpText","removeAttribute","handleSuccessfulAddressCheck","Event","multipleExtensionsFound","success","serverErrors","finally","setCookie","cookieName","cookieValue","domain","expirationDays","date","toUTCString","getCookie","parts","pop","VZPostCodeCheck","HTMLFormElement","sidebar","pdpSubmitButtons","editMode","isPageDesignerComponent","parentSelector","isOneNet","isBusinessInternet","isSharedOneNetConfiguration","location","href","removeLocation","updateChatInfo","addressCheck","handleAvailabilityFormSubmit","autoSubmitForm","select","enableProductConfiguration","oneNetTierCard","map","card","isOneNetSeatSelectionEventFired","isOneNetSeatSelected","areOneNetSeatsBelowThreshold","shouldDisableOneNetConfiguration","elementsToEnable","Boolean","oneNetCriteria","unableToOrder","disableProductConfiguration","isEditLocation","nonTierOneNetCards","removeChild","elements","defaultDuration","showEditLocation","setAddress","houseNumberExtension","street","city","dataField","updateResult","availabilityCheckResponseData","isResponseSuccessful","speed","html","responseHtml","locationHasExistingSubscription","active","PAID","availableSpeed","isIOS","outputWrapper","scrollTo","getBoundingClientRect","call","addressData","postcode","hostname","setBiState","executeAvailabilityCheck","action","updateURLs","disableUnavailableSpeeds","trackPdpEccomerceEvent","number","url","newURL","appendParamToURL","speedNumber","elementValueNumber","nextElementSibling","selectHighestPossibleTier","highestPossibleSpeed","tier","bubbles","cancelable","getParamFromURL","availabilityFormAddressCookieName","customEvent","isOrderable","promptOpen","attributes","prompt","classes","promptClose","confirm","button","blur","getJourney","item","notifyJourneyModal","journey","journeyModal","updateJourney","urls","internet","clearJourney","documentReady","addEvent","click","VZJourney","onChange","setState","showOrHideDependingOnBusinessInternetAccess","removeStep","addStep","triggerLinkedProduct","inputField","linkedProductID","isBIAvailable","journeyCardElement","productID","journeyArray","Set","VZJourneyModal","observedAttributes","attributeChangedCallback","oldValue","newValue","toggleProductVisibility","updateModal","setInitialState","checkboxes","productIDS","concat","updateResources","getNextProduct","nextProduct","addtocart","subtitle","innerText","productsInJourney","product","VZAddBase","getAddons","getAllProducts","pid","quantity","getPAID","handleNetworkError","scrollToElement","headerOffset","offsetHeight","offsetPosition","top","scrollY","behavior","setScrollClasses","el","scrollHeight","clientHeight","isScrolledToBottom","scrollTop","isScrolledToTop","toggle","VZAddDevice","addDeviceBtn","devicesContainer","devicesCards","bmQuantityCard","addSimsLinks","addDevicesLink","onClick","toggleVisiblity","link","addNewDevice","startViewTransition","lastDeviceCard","VZAddGroup","addToCartUrl","removeFromCartUrl","csSolutionId","setDurationProperties","selectedDuration","submitForm","selectedOptionalBusinessRulesAddons","optionalBusinessRulesAddonsInCart","nonCsItemsInCart","toBeAdded","addon","toBeRemoved","isPartOfJourney","inJourney","belongsToGuidedJourney","async","submitLinkedProducts","URLSearchParams","uuid","updateContractDurations","businessRulesProductsString","businessRulesProducts","contractsToAdd","duplicatesToAdd","contractPid","optionalBusinessRulesAddons","keys","isMobileHardware","isMobileHardwareContract","Number","recurringPrice","deviceIndex","qty","oneOffPrice","parseFloat","contractDuration","duplicate","hasNonCsProductsSelected","from","getElementsByClassName","hideAddToBasketModal","basketUrl","ecommerceObject","_ddm","trigger","ecommerce","addToCart","promises","newDuration","updateSection","formEqualsSelectedDuration","currentForm","all","quantityField","products","mobileDeviceAddons","VZAddLocation","onSubmit","getLinkedProducts","flat","getMainProductId","i","submitProductsAsync","submitPresets","presets","parsedPresets","prev","current","ajaxAttributes","VZAddOneNet","prepareForm","getURL","chunkArrayInGroups","productData","salesRepStatus","getSalesRepStatus","VZHardware","hardwareWrapper","hardwareCardWrapper","phoneWrapper","phonesScrollableArea","productCard","cardOrderIsReversed","onQuantityChange","onQuantityInput","toggleDevice","showConfirmationModal","editConfiguration","currentTarget","updateTabIndex","modalInstance","dismissModal","modalTitle","modalBody","injectModalContent","modalContent","userConfirmed","quantityWrapper","quantitySelector","notification","wrapper","childElements","interactiveElements","tabIndexValue","child","VZSorting","HTMLSelectElement","excludedAttributes","vZProductCard","urlAttribute","getUrlFromAttributes","res","text","log","VZRangeSlider","initializeElements","setupEventListeners","initSlider","removeEventListeners","triggerInput","minValue","maxValue","decrementBtn","incrementBtn","boundInputChange","onInputChange","boundDecrementClick","onDecrementClick","boundIncrementClick","onIncrementClick","updateSliderFill","percentage","setProperty","dispatchSliderUpdate","Math","max","updateValue","min","updateEvent","updatePriceDisplay","priceData","priceContainer","formattedPrice","recurringPriceMsg","updatePriceHtml","oneOffPriceMsg","elem","newPrice","formatToPriceString","VZPriceBalanceSlider","netPrice","cardIndex","debouncedChangeEvent","debounce","dispatchChange","updateUI","oneTimeCost","monthlyCost","floor","toFixed","identifier","VZProductCard","buildRequestUrl","responseText","priceDetails","assign","finalUrl","appendBmHardwareCardIndex","pliId","VZDeleteGroup","deleteBtn","removeDeletedGroup","isMiniCart","removeFromJourneyEmptyProduct","removeFromJourneyExistingProduct","reload","VZFilter","scope","applyFilter","VZGroupSummary","summaryList","onPortingChange","portingValue","portingListItem","portingString","iconClasses","danger","warning","info","alertTitle","alertDescription","additionalClasses","iconClass","alertHTML","VZQuantitySelector","toggleIncreaseAndDecreaseButtons","confirmRemove","now","forbiddenValues","debounceRate","debouncedChange","formControl","quantityFieldOrgValue","onBlur","businessMobileWrapper","decreaseOrIncrease","disableOrEnable","validateMinMax","currentValue","decrease","manuallyTriggered","isTrusted","confirmed","updateQuantity","highlightInfoCard","highlight","infoCard","moreThanMax","lessThanMin","urlAttributeValue","fieldUrl","removeParamFromURL","VZVariationAttribute","variationInput","setupURL","postUpdate","onVariationChange","handleAddonClick","addText","addonToggle","removeText","dNone","attributeToUse","urlAttributeName","decodeURIComponent","productQty","isReversed","totalHardwareAmount","acc","currentQuantity","updatedQuantity","priceSlider","maxMonthlyCost","showExtraInfoModal","displayValue","changeDurationModalElement","isModalRequired","committedGroups","existingDuration","changeDurationModal","dispose","children","VZPorting","notifyProductCard","valueToSend","hardwarePhoneThresholdBtn","updateJourneyModal","fragment","replaceWith","activeConfiguratorGroup","removeShowMoreBtn","updateCard","outerHTML","updateSideBar","checkOneNetSeats","productCardHTML","postCodeCheck","MACDconfigurator","shouldDisableSubmit","combinedQuantity","total","currentElement","Sidebar","sidebarScrollContainer","sidebarOffscreen","sidebarTopOffset","sidebarBottomOffset","stickyBreakpoint","breakpoints","lg","siteHeader","headerHeight","isSidebarOverflowing","assignMobileVariables","initAccordions","handleFloatingSidebar","handleScroll","isSidebarAtBottom","isSidebarAtBottomContainer","isSidebarInContainer","replaceSidebarHtml","isStep1InViewport","openMobileSidebar","closeMobileSidebar","calculateMaxHeightMobileSidebarBody","mobileSidebarScrollHandler","mobileSidebarSlideIn","mobileSidebarSlideOut","assignAccordionsEvents","initialize","innerWidth","assignMobileEvents","sidebarHeader","sidebarBody","sidebarFooter","sidebarSubmitBtn","productForm","tapAreaFooter","tapAreaHeader","pageHeader","chatButton","notifyQuantityCard","sharedDataContainer","shareButton","removeProperty","assignStyling","bottom","width","clientWidth","innerHeight","accordion","summaryGroup","accordions","computedStyles","documentElement","bscanSteps","INTRO","STATEMENTS_DONE","GROUPED_QUESTIONS","ADVICE","THANKYOU","class","csrfToken","csrfName","disabled","exclude","placeholder","validation","patternMismatch","valueMissing","tooShort","xxs","xs","sm","md","xl","xxl","buttons","next","previous","dBlock","dFlex","dInlineBlock","empty","inactive","hidden","last","change","keyUp","load","mousedown","mouseleave","mouseover","paste","resize","responseError","scroll","submit","transitionEnd","update","checkbox","file","inputFieldClear","inputFieldFeedback","label","radio","textarea","htmlBody","img","localStorage","preferredLayoutId","vzLayoutToggle","enabledBreakpoint","idDefault","localStorageKey","splitUpUrl","hash","paramUrl","at","params","urlValues","newParams","param","nameMatch","separator","encodeURIComponent","component","newUrl","URL","urlParams","searchParams","getAttributeNames","attributeName","has","replaceAll","attr","attrValue","attrName","origin","pathname","parent","passedEvent","handler","apply","fn","readyState","navigator","platform","maxTouchPoints","MSStream","left","stickyHeader","supportsNativeSmoothScroll","positionTop","arr","size","groupedChunks","productType","step","category","checkout","has_vodafone","has_ziggo","brand","market","step_name","step_nr","styles","num","toggleValidityClass","isValid","removeValidationMessageElement","createValidationMessageElement","insertAdjacentElement","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","m","amdO","O","chunkIds","priority","notFulfilled","Infinity","fulfilled","j","getter","__esModule","d","definition","o","g","globalThis","Function","obj","prop","prototype","hasOwnProperty","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","chunkLoadingGlobal","__webpack_exports__"],"sourceRoot":""}