Layout

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Preview Layout</title>
    <link media="all" rel="stylesheet" href="../../css/styles.css">
    <script>
        window.APP = {
            modules: {},
            addModule: function(name, config) {
                this.modules[name] = this.modules[name] || [];
                this.modules[name].push(config);
            },
            DEBUG: 1,
            CONFIG: {},
        };
    </script>

    <style>
        body {
            margin: 25px !important;
        }
    </style>
</head>

<body class="antialiased text-body-base font-roboto">
    <script>
        'use strict';
        (function(hyva, undefined) {
            function lifetimeToExpires(options, defaults) {
                const lifetime = options.lifetime || defaults.lifetime;
                if (lifetime) {
                    const date = new Date;
                    date.setTime(date.getTime() + lifetime * 1000);
                    return date;
                }
                return null;
            }

            function generateRandomString() {
                const allowedCharacters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
                    length = 16;
                let formKey = '',
                    charactersLength = allowedCharacters.length;
                for (let i = 0; i < length; i++) {
                    formKey += allowedCharacters[Math.round(Math.random() * (charactersLength - 1))]
                }
                return formKey;
            }
            const sessionCookieMarker = {
                noLifetime: true
            }
            const cookieTempStorage = {};
            const internalCookie = {
                get(name) {
                    const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
                    return v ? v[2] : null;
                },
                set(name, value, days, skipSetDomain) {
                    let expires,
                        path,
                        domain,
                        secure,
                        samesite;
                    const defaultCookieConfig = {
                        expires: null,
                        path: '/',
                        domain: null,
                        secure: false,
                        lifetime: null,
                        samesite: 'lax'
                    };
                    const cookieConfig = window.COOKIE_CONFIG || {};
                    expires = days && days !== sessionCookieMarker ?
                        lifetimeToExpires({
                            lifetime: 24 * 60 * 60 * days,
                            expires: null
                        }, defaultCookieConfig) :
                        lifetimeToExpires(window.COOKIE_CONFIG, defaultCookieConfig) || defaultCookieConfig.expires;
                    path = cookieConfig.path || defaultCookieConfig.path;
                    domain = !skipSetDomain && (cookieConfig.domain || defaultCookieConfig.domain);
                    secure = cookieConfig.secure || defaultCookieConfig.secure;
                    samesite = cookieConfig.samesite || defaultCookieConfig.samesite;
                    document.cookie = name + "=" + encodeURIComponent(value) +
                        (expires && days !== sessionCookieMarker ? '; expires=' + expires.toGMTString() : '') +
                        (path ? '; path=' + path : '') +
                        (domain ? '; domain=' + domain : '') +
                        (secure ? '; secure' : '') +
                        (samesite ? '; samesite=' + samesite : 'lax');
                },
                isWebsiteAllowedToSaveCookie() {
                    const allowedCookies = this.get('user_allowed_save_cookie');
                    if (allowedCookies) {
                        const allowedWebsites = JSON.parse(unescape(allowedCookies));
                        return allowedWebsites[CURRENT_WEBSITE_ID] === 1;
                    }
                    return false;
                },
                getGroupByCookieName(name) {
                    const cookieConsentConfig = window.cookie_consent_config || {};
                    let group = null;
                    for (let prop in cookieConsentConfig) {
                        if (!cookieConsentConfig.hasOwnProperty(prop)) continue;
                        if (cookieConsentConfig[prop].includes(name)) {
                            group = prop;
                            break;
                        }
                    }
                    return group;
                },
                isCookieAllowed(name) {
                    const cookieGroup = this.getGroupByCookieName(name);
                    return cookieGroup ?
                        window.cookie_consent_groups[cookieGroup] :
                        this.isWebsiteAllowedToSaveCookie();
                },
                saveTempStorageCookies() {
                    for (const [name, data] of Object.entries(cookieTempStorage)) {
                        if (this.isCookieAllowed(name)) {
                            this.set(name, data['value'], data['days'], data['skipSetDomain']);
                            delete cookieTempStorage[name];
                        }
                    }
                }
            };
            hyva.getCookie = (name) => {
                const cookieConfig = window.COOKIE_CONFIG || {};
                if (cookieConfig.cookie_restriction_enabled && !internalCookie.isCookieAllowed(name)) {
                    return cookieTempStorage[name] ? cookieTempStorage[name]['value'] : null;
                }
                return internalCookie.get(name);
            }
            hyva.setCookie = (name, value, days, skipSetDomain) => {
                const cookieConfig = window.COOKIE_CONFIG || {};
                if (cookieConfig.cookie_restriction_enabled && !internalCookie.isCookieAllowed(name)) {
                    cookieTempStorage[name] = {
                        value,
                        days,
                        skipSetDomain
                    };
                    return;
                }
                return internalCookie.set(name, value, days, skipSetDomain);
            }
            hyva.setSessionCookie = (name, value, skipSetDomain) => {
                return hyva.setCookie(name, value, sessionCookieMarker, skipSetDomain)
            }
            hyva.getBrowserStorage = () => {
                const browserStorage = window.localStorage || window.sessionStorage;
                if (!browserStorage) {
                    console.warn('Browser Storage is unavailable');
                    return false;
                }
                try {
                    browserStorage.setItem('storage_test', '1');
                    browserStorage.removeItem('storage_test');
                } catch (error) {
                    console.warn('Browser Storage is not accessible', error);
                    return false;
                }
                return browserStorage;
            }
            hyva.postForm = (postParams) => {
                const form = document.createElement("form");
                let data = postParams.data;
                if (!postParams.skipUenc && !data.uenc) {
                    data.uenc = btoa(window.location.href);
                }
                form.method = "POST";
                form.action = postParams.action;
                Object.keys(postParams.data).map(key => {
                    const field = document.createElement("input");
                    field.type = 'hidden'
                    field.value = postParams.data[key];
                    field.name = key;
                    form.appendChild(field);
                });
                const form_key = document.createElement("input");
                form_key.type = 'hidden';
                form_key.value = hyva.getFormKey();
                form_key.name = "form_key";
                form.appendChild(form_key);
                document.body.appendChild(form);
                form.submit();
            }
            hyva.getFormKey = function() {
                let formKey = hyva.getCookie('form_key');
                if (!formKey) {
                    formKey = generateRandomString();
                    hyva.setCookie('form_key', formKey);
                }
                return formKey;
            }
            hyva.formatPrice = (value, showSign, options = {}) => {
                const formatter = new Intl.NumberFormat(
                    'en-US',
                    Object.assign({
                        style: 'currency',
                        currency: 'EUR',
                        signDisplay: showSign ? 'always' : 'auto'
                    }, options)
                );
                return (typeof Intl.NumberFormat.prototype.formatToParts === 'function') ?
                    formatter.formatToParts(value).map(({
                        type,
                        value
                    }) => {
                        switch (type) {
                            case 'currency':
                                return '€' || value;
                            case 'minusSign':
                                return '- ';
                            case 'plusSign':
                                return '+ ';
                            default:
                                return value;
                        }
                    }).reduce((string, part) => string + part) :
                    formatter.format(value);
            }
            /**
             * Internal string replacement function implementation, see hyva.str() for usage details.
             *
             * @param string str Template string with optional placeholders
             * @param int nStart Offset for placeholders, 0 means %0 is replaced with args[0], 1 means %1 is replaced with args[0]
             * @param array ...args Positional replacement arguments. Rest arguments support isn't at 97% yet, so Array.from(arguments).slice() is used instead.
             */
            const formatStr = function(str, nStart) {
                const args = Array.from(arguments).slice(2);
                return str.replace(/(%+)([0-9]+)/g, (m, p, n) => {
                    const idx = parseInt(n) - nStart;
                    if (args[idx] === null || args[idx] === void 0) {
                        return m;
                    }
                    return p.length % 2 ?
                        p.slice(0, -1).replace('%%', '%') + args[idx] :
                        p.replace('%%', '%') + n;
                })
            }
            /**
             * Replace positional parameters like %1 in string with the rest argument in the matching position.
             * The first rest argument replaces %1, the second %2 and so on.
             *
             * Example: hyva.str('%3 %2 %1', 'a', 'b', 'c') => "c b a"
             *
             * To insert a literal % symbol followed by a number, duplicate the %, for example %%2 is returned as %2.
             */
            hyva.str = function(string) {
                const args = Array.from(arguments);
                args.splice(1, 0, 1);
                return formatStr.apply(undefined, args);
            }
            /**
             * Zero based version of hyva.str(): the first rest argument replaces %0, the second %1 and so on.
             *
             * Example: hyva.strf('%2 %1 %0', 'a', 'b', 'c') => "c b a"
             *
             * If in doubt whether to use hyva.str() or hyva.strf(), prefer hyva.str() because it is more similar to __()
             * and it might be possible to reuse existing phrase translations with placeholders.
             */
            hyva.strf = function() {
                const args = Array.from(arguments);
                args.splice(1, 0, 0);
                return formatStr.apply(undefined, args);
            }
            /**
             * Take a html string as `content` parameter and
             * extract an element from the DOM to replace in
             * the current page under the same selector,
             * defined by `targetSelector`
             */
            hyva.replaceDomElement = (targetSelector, content) => {
                // Parse the content and extract the DOM node using the `targetSelector`
                const parser = new DOMParser();
                const doc = parser.parseFromString(content, 'text/html');
                const contentNode = doc.querySelector(targetSelector);
                // Bail if content can't be found
                if (!contentNode) {
                    return;
                }
                hyva.activateScripts(contentNode)
                // Replace the old DOM node with the new content
                document.querySelector(targetSelector).replaceWith(contentNode);
                // Reload customerSectionData and display cookie-messages if present
                window.dispatchEvent(new CustomEvent("reload-customer-section-data"));
                hyva.initMessages();
            }
            hyva.activateScripts = (contentNode) => {
                // Extract all the script tags from the content.
                // Script tags won't execute when inserted into a dom-element directly,
                // therefore we need to inject them to the head of the document.
                const tmpScripts = contentNode.getElementsByTagName('script');
                if (tmpScripts.length > 0) {
                    // Push all script tags into an array
                    // (to prevent dom manipulation while iterating over dom nodes)
                    const scripts = [];
                    for (let i = 0; i < tmpScripts.length; i++) {
                        scripts.push(tmpScripts[i]);
                    }
                    // Iterate over all script tags and duplicate+inject each into the head
                    for (let i = 0; i < scripts.length; i++) {
                        let script = document.createElement('script');
                        script.innerHTML = scripts[i].innerHTML;
                        document.head.appendChild(script);
                        // Remove the original (non-executing) node from the content
                        scripts[i].parentNode.removeChild(scripts[i]);
                    }
                }
                return contentNode;
            }
            /**
             * Return base64 encoded current URL that can be used by Magento to redirect the visitor back to the current page.
             * The func hyva.getUenc handles additional encoding of +, / and = like \Magento\Framework\Url\Encoder::encode().
             */
            const replace = {
                ['+']: '-',
                ['/']: '_',
                ['=']: ','
            };
            hyva.getUenc = () => btoa(window.location.href).replace(/[+/=]/g, match => replace[match]);
            let currentTrap;
            const focusableElements = (rootElement) => {
                const selector = 'button, [href], input, select, textarea, details, [tabindex]:not([tabindex="-1"]';
                return Array.from(rootElement.querySelectorAll(selector))
                    .filter(el => {
                        return el.style.display !== 'none' &&
                            !el.disabled &&
                            el.tabIndex !== -1 &&
                            (el.offsetWidth || el.offsetHeight || el.getClientRects().length)
                    })
            }
            const focusTrap = (e) => {
                const isTabPressed = e.key === 'Tab' || e.keyCode === 9;
                if (!isTabPressed) return;
                const focusable = focusableElements(currentTrap)
                const firstFocusableElement = focusable[0]
                const lastFocusableElement = focusable[focusable.length - 1]
                e.shiftKey ?
                    document.activeElement === firstFocusableElement && (lastFocusableElement.focus(), e.preventDefault()) :
                    document.activeElement === lastFocusableElement && (firstFocusableElement.focus(), e.preventDefault())
            };
            hyva.releaseFocus = (rootElement) => {
                if (currentTrap && (!rootElement || rootElement === currentTrap)) {
                    currentTrap.removeEventListener('keydown', focusTrap)
                    currentTrap = null
                }
            }
            hyva.trapFocus = (rootElement) => {
                if (!rootElement) return;
                hyva.releaseFocus()
                currentTrap = rootElement
                rootElement.addEventListener('keydown', focusTrap)
                const firstElement = focusableElements(rootElement)[0]
                firstElement && firstElement.focus()
            }
            hyva.alpineInitialized = (fn) => window.addEventListener('alpine:initialized', fn, {
                once: true
            })
            window.addEventListener('alpine:initialized', () => {
                console.log('Alpine.js initialized')
            })
            window.addEventListener('user-allowed-save-cookie', () => internalCookie.saveTempStorageCookies())
        }(window.hyva = window.hyva || {}));
    </script>
    <script>
        'use strict';
        (function(hyva) {
            const formValidationRules = {
                required(value, options, field, context) {
                    const el = field.element.type === 'hidden' ? createTextInputFrom(field.element) : field.element,
                        msg = 'This\u0020is\u0020a\u0020required\u0020field.';
                    if (el.type === 'radio' || el.type === 'checkbox') {
                        return (value === undefined || value.length === 0) ? msg : true;
                    }
                    el.setAttribute('required', '');
                    el.checkValidity();
                    return el.validity.valueMissing ? msg : true;
                },
                maxlength(value, options, field, context) {
                    const n = Number(options)
                    if (value.length > n) {
                        return n === 1 ?
                            hyva.strf('Please\u0020enter\u0020no\u0020more\u0020than\u00201\u0020character.') :
                            hyva.strf('Please\u0020enter\u0020no\u0020more\u0020than\u0020\u00250\u0020characters.', options)
                    }
                    return true;
                },
                minlength(value, options, field, context) {
                    const n = Number(options)
                    if (value.length > 0 && value.length < n) {
                        return n === 1 ?
                            hyva.strf('Please\u0020enter\u0020at\u0020least\u00201\u0020character.') :
                            hyva.strf('Please\u0020enter\u0020at\u0020least\u0020\u00250\u0020characters.', options)
                    }
                    return true;
                },
                max(value, options, field, context) {
                    field.element.setAttribute('max', options);
                    field.element.checkValidity();
                    if (field.element.validity.rangeOverflow) {
                        return hyva.strf('Please\u0020enter\u0020a\u0020value\u0020less\u0020than\u0020or\u0020equal\u0020to\u0020\u0022\u00250\u0022.', options);
                    }
                    return true;
                },
                min(value, options, field, context) {
                    field.element.setAttribute('min', options);
                    field.element.checkValidity();
                    if (field.element.validity.rangeUnderflow) {
                        return hyva.strf('Please\u0020enter\u0020a\u0020value\u0020greater\u0020than\u0020or\u0020equal\u0020to\u0020\u0022\u00250\u0022.', options);
                    }
                    return true;
                },
                step(value, options, field, context) {
                    field.element.setAttribute('step', options);
                    field.element.checkValidity();
                    if (field.element.validity.stepMismatch) {
                        const val = Number(value);
                        const step = Number(options);
                        const msg = 'Please\u0020enter\u0020a\u0020valid\u0020value.\u0020The\u0020two\u0020nearest\u0020valid\u0020values\u0020are\u0020\u0022\u00250\u0022\u0020and\u0020\u0022\u00251\u0022.';
                        return hyva.strf(msg, Math.floor(val / step) * step, Math.ceil(val / step) * step);
                    }
                    return true;
                },
                pattern(value, options, field, context) {
                    field.element.setAttribute('pattern', options);
                    field.element.checkValidity();
                    if (field.element.validity.patternMismatch) {
                        return field.element.title ?
                            hyva.strf('Please\u0020match\u0020the\u0020requested\u0020format\u003A\u0020\u00250.', field.element.title) :
                            'Please\u0020match\u0020the\u0020requested\u0020format.'
                    }
                    return true;
                },
                email(value, options, field, context) {
                    const rule = /^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i;
                    if (value.length > 0 && !rule.test(value)) {
                        return 'Please\u0020enter\u0020a\u0020valid\u0020email\u0020address.';
                    }
                    return true;
                },
                password(value, options, field, context) {
                    const rule = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/;
                    if (value.length > 0 && !rule.test(value)) {
                        return 'Please\u0020provide\u0020at\u0020least\u0020one\u0020upper\u0020case,\u0020one\u0020lower\u0020case,\u0020one\u0020digit\u0020and\u0020one\u0020special\u0020character\u0020\u0028\u0023\u003F\u0021\u0040\u0024\u0025\u005E\u0026\u002A\u002D\u0029';
                    }
                    return true;
                },
                equalTo(value, options, field, context) {
                    const dependencyField = context.fields[options].element;
                    if (value !== dependencyField.value) {
                        const dependencyFieldName =
                            dependencyField.label ||
                            dependencyField.title ||
                            (dependencyField.labels && dependencyField.labels[0] && dependencyField.labels[0].innerText) ||
                            dependencyField.name;
                        return hyva.strf('This\u0020field\u0020value\u0020must\u0020be\u0020the\u0020same\u0020as\u0020\u0022\u00250\u0022.', dependencyFieldName);
                    }
                    return true;
                }
            };

            function raceSome(promises, pred) {
                return new Promise((resolve, reject) => {
                    if (promises.length === 0) {
                        return resolve();
                    }
                    let settled = false,
                        nDone = 0;
                    const resolveIf = v => {
                        if (!settled && (pred(v) || ++nDone === promises.length)) {
                            settled = true;
                            resolve(v);
                        }
                        return v;
                    }
                    promises.map(promise => {
                        promise.then(resolveIf).catch(reason => {
                            settled = true;
                            reject(reason)
                        });
                        return promise;
                    });
                });
            }
            const INPUT_ATTRIBUTE_RULES = {
                min: 'min',
                max: 'max',
                required: 'required',
                minlength: 'minlength',
                maxlength: 'maxlength',
                step: 'step',
                pattern: 'pattern'
            }
            const INPUT_TYPE_RULES = {
                email: 'email'
            }

            function getRules(element) {
                let rules = {};
                Object.keys(INPUT_ATTRIBUTE_RULES).forEach(attrName => {
                    if (element.hasAttribute(attrName)) {
                        rules[INPUT_ATTRIBUTE_RULES[attrName]] = element.getAttribute(attrName);
                    }
                })
                if (INPUT_TYPE_RULES[element.type]) {
                    rules[INPUT_TYPE_RULES[element.type]] = true;
                }
                if (element.dataset.validate) {
                    try {
                        Object.assign(rules, JSON.parse(element.dataset.validate));
                    } catch (error) {
                        console.error('Validator error. Cannot parse data-validate attribute of element:\n', element);
                    }
                }
                return rules;
            }

            function isInvalidRuleResult(ruleState) {
                return typeof ruleState === 'string' || !ruleState || (ruleState.type && ruleState.content);
            }
            async function runValidateFn(rule, options, value, field) {
                return formValidationRules[rule](value, options, field, this);
            }

            function generateId() {
                let id;
                do {
                    id = `${this.idPrefix}-${++this.idSeq}`;
                } while (document.getElementById(id));
                return id;
            }

            function isVisible(element) {
                const el = element.type !== 'hidden' ? element : (element.parentElement || {});
                return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length)
            }

            function elementWillValidate(element) {
                return (element.willValidate || element.type === 'hidden') &&
                    element.tagName !== 'BUTTON' &&
                    element.disabled === false &&
                    !(element.tagName === 'INPUT' && element.type === 'submit') &&
                    (element.hasAttribute('data-validate-hidden') || isVisible(element))
            }

            function createMessageContainer(el, fieldWrapperClassName) {
                if (!el.parentElement) {
                    return;
                }
                const refocus = document.activeElement === el;
                const wrapper = document.createElement('div');
                wrapper.classList.add.apply(wrapper.classList, fieldWrapperClassName.split(' '));
                el.parentElement.insertBefore(wrapper, el);
                wrapper.appendChild(el);
                refocus && document.activeElement !== el && el.focus();
                return wrapper;
            }

            function containerNotFound(selector, el) {
                const msg = `Cannot find message container element ${selector} of ${el.name}`;
                console.error(msg, el);
                throw msg;
            }

            function createTextInputFrom(el) {
                const text = document.createElement('INPUT');
                text.type = 'text';
                text.value = el.value;
                return text;
            }

            function classNamesToSelector(classNames) {
                return classNames.split(' ')
                    .filter(className => className.length > 0)
                    .map(className => `.${className}`)
                    .join('')
            }

            function hasMessagesWrapper(field, messagesWrapperClassName) {
                return this.getMessageContainer(field).querySelector(classNamesToSelector(messagesWrapperClassName));
            }

            function getMessagesWrapper(field, messagesWrapperClassName) {
                if (hasMessagesWrapper.call(this, field, messagesWrapperClassName)) {
                    return this.getMessageContainer(field).querySelector(classNamesToSelector(messagesWrapperClassName));
                }
                const msgWrapper = document.createElement('ul');
                const msgId = generateId.call(this);
                msgWrapper.id = msgId;
                field.element.setAttribute('aria-errormessage', msgId);
                field.element.setAttribute('aria-describedby', msgId);
                msgWrapper.classList.add.apply(msgWrapper.classList, messagesWrapperClassName.split(' '));
                if (field.validateOnChange) {
                    msgWrapper.setAttribute('aria-live', 'polite');
                }
                this.getMessageContainer(field).appendChild(msgWrapper);
                return msgWrapper;
            }

            function getCheckedValues(field) {
                const name = field.element.name.replace(/([\\"])/g, '\\$1');
                const elements = field.element.form.querySelectorAll('input[name="' + name + '"]:checked');
                return Array.from(elements).map(el => el.value);
            }

            function escapeHtml(s) {
                const div = document.createElement('div')
                div.innerText = s;
                return div.innerHTML;
            }

            function formValidation(formElement, options) {
                // Disable browser default validation
                if (formElement.tagName === 'FORM') {
                    formElement.setAttribute('novalidate', '');
                } else {
                    console.error('formValidation can be initialized only on FORM element', formElement);
                    return;
                }
                options = Object.assign({
                    fieldWrapperClassName: 'field field-reserved',
                    messagesWrapperClassName: 'messages',
                    validClassName: 'field-success',
                    invalidClassName: 'field-error',
                    pageMessagesWrapperSelector: null,
                    scrollToFirstError: true,
                }, options || {});
                return {
                    state: {
                        valid: false,
                    },
                    fields: {},
                    idSeq: 0,
                    idPrefix: formElement.id || 'vld-msg',
                    setupFields(elements) {
                        this.fields = {};
                        Array.from(elements).forEach(element => {
                            if (elementWillValidate(element)) {
                                this.setupField(element);
                            }
                        });
                    },
                    setupField(element) {
                        if (!element) return;
                        const onChange = !!element.dataset.onChange;
                        if (elementWillValidate(element)) {
                            const rules = getRules(element);
                            if (Object.keys(rules).length > 0) {
                                if (this.fields[element.name]) {
                                    Object.assign(this.fields[element.name].rules, rules);
                                } else {
                                    this.fields[element.name] = {
                                        element,
                                        rules: rules,
                                        validateOnChange: onChange,
                                        state: {
                                            valid: null,
                                            rules: {}
                                        }
                                    }
                                }
                            }
                        } else {
                            console.error('Element will not validate', element);
                        }
                    },
                    onSubmit(event) {
                        if (event.target.tagName === 'FORM') {
                            event.preventDefault();
                            this.validate()
                                .then(() => event.target.submit())
                                .catch(invalidElements => {});
                        }
                    },
                    onChange(event) {
                        event.target.dataset.onChange = 'true';
                        if (!Object.keys(this.fields).length) {
                            this.setupFields(formElement.elements);
                        }
                        if (!Object.keys(this.fields).includes(event.target.name)) {
                            this.setupField(event.target);
                        }
                        const field = this.fields[event.target.name];
                        this.validateField(field);
                        field && field.element.removeAttribute('data-on-change')
                    },
                    validateSafe() {
                        return new Promise(resolve => this.validate().then(() => resolve(true)).catch(() => {}))
                    },
                    validate() {
                        if (!Object.keys(this.fields).length || !Object.keys(this.fields).length !== formElement.elements.length) {
                            this.setupFields(formElement.elements);
                        }
                        return new Promise(async (resolve, reject) => {
                            if (formElement.elements) {
                                await raceSome(this.validateFields(), result => result !== true)
                                const invalidFields = Object.values(this.fields).filter(field => !field.state.valid);
                                this.state.valid = invalidFields.length === 0;
                                if (this.state.valid) {
                                    resolve();
                                } else {
                                    if (options.scrollToFirstError && invalidFields.length > 0) {
                                        invalidFields[0].element.focus()
                                        invalidFields[0].element.select && invalidFields[0].element.select();
                                    }
                                    reject(invalidFields.map(field => field.element));
                                }
                            }
                        });
                    },
                    validateFields() {
                        const fields = Object.values(this.fields);
                        fields.forEach(field => {
                            this.getMessageContainer(field).classList.remove(options.validClassName, options.invalidClassName)
                        });
                        return fields.map(field => this.validateField(field))
                    },
                    validateField(field) {
                        if (!field || !elementWillValidate(field.element)) {
                            return new Promise(resolve => resolve(true))
                        }
                        let value;
                        if (field.element.type === 'checkbox') {
                            value = getCheckedValues(field);
                        } else if (field.element.type === 'radio') {
                            value = getCheckedValues(field)[0] || undefined;
                        } else if (field.element.tagName === 'SELECT' && field.element.multiple) {
                            value = Array.from(field.element.selectedOptions).map(opt => opt.value);
                        } else {
                            value = field.element.value;
                        }
                        const rules = field.rules || {};
                        field.state.valid = true;
                        this.showFieldState(field);
                        const fieldValidations = Object.keys(rules).filter(rule => formValidationRules[rule]).map(async rule => {
                            return runValidateFn.call(this, rule, rules[rule], value, field).then(result => {
                                field.state.rules[rule] = result;
                                return result;
                            })
                        });
                        return new Promise(resolve => {
                            Promise.all(fieldValidations).then(results => {
                                field.state.valid = !elementWillValidate(field.element) || rules.length === 0 || !results.some(isInvalidRuleResult)
                                this.showFieldState(field);
                                resolve(field.state.valid);
                            })
                        });
                    },
                    getMessagesByField(field) {
                        const messages = [];
                        const invalidRules = Object.keys(field.state.rules).filter(rule => isInvalidRuleResult(field.state.rules[rule]));
                        field.rules && Object.keys(field.rules).forEach((rule) => {
                            if (invalidRules.includes(rule)) {
                                const customMessage = field.element.getAttribute('data-msg-' + rule);
                                const message = customMessage ? customMessage : field.state.rules[rule];
                                const ruleOptions = JSON.parse(JSON.stringify(field.rules[rule]));
                                if (typeof message === 'undefined' || message === null || (typeof message !== 'string' && !message.type)) {
                                    messages.push(hyva.strf('Validation rule "%0" failed.', rule));
                                } else if (Array.isArray(ruleOptions)) {
                                    ruleOptions.unshift(message.type ? message.content : message);
                                    const content = hyva.strf.apply(null, ruleOptions);
                                    messages.push(message.type ? {
                                        type: message.type,
                                        content
                                    } : content);
                                } else {
                                    const content = hyva.strf(message.type ? message.content : message, ruleOptions)
                                    messages.push(message.type ? {
                                        type: message.type,
                                        content
                                    } : content);
                                }
                            }
                        });
                        return messages;
                    },
                    /** @deprecated */
                    getFieldWrapper(field) {
                        return this.getMessageContainer(field)
                    },
                    getMessageContainer(field) {
                        let container;
                        const pageSelector = field.element.getAttribute('data-validation-container') || options.pageMessagesContainerSelector;
                        if (pageSelector) {
                            container = document.querySelector(pageSelector) ||
                                containerNotFound(pageSelector, field.element)
                        } else {
                            const containerSelector = classNamesToSelector(options.fieldWrapperClassName);
                            container = field.element.closest(containerSelector) ||
                                createMessageContainer(field.element, options.fieldWrapperClassName) ||
                                containerNotFound(containerSelector, field.element);
                        }
                        return container;
                    },
                    showFieldState(field) {
                        const container = this.getMessageContainer(field),
                            hasErrorMessages = hasMessagesWrapper.call(this, field, options.messagesWrapperClassName),
                            messages = this.getMessagesByField(field).map(m => {
                                return m.type !== 'html' ? escapeHtml(m.type ? m.content : m) : m.content;
                            });
                        container.classList.toggle(options.validClassName, field.state.valid && !hasErrorMessages);
                        container.classList.toggle(options.invalidClassName, !field.state.valid || hasErrorMessages);
                        this.createHtmlErrorMessage(field, messages);
                        if (field.state.valid) {
                            field.element.removeAttribute('aria-invalid');
                        } else {
                            field.element.setAttribute('aria-invalid', 'true');
                            if (!document.activeElement) {
                                field.element.focus();
                            }
                        }
                    },
                    removeMessages(field, messagesClass) {
                        if (!hasMessagesWrapper.call(this, field, messagesClass || options.messagesWrapperClassName)) {
                            return;
                        }
                        const msgWrapper = getMessagesWrapper.call(this, field, messagesClass || options.messagesWrapperClassName);
                        const messages = msgWrapper.querySelectorAll(`[data-msg-field='${field.element.name}']`);
                        Array.from(messages).forEach(msg => msg.remove());
                        if (msgWrapper && msgWrapper.childElementCount === 0) {
                            field.element.removeAttribute('aria-errormessage');
                            field.element.removeAttribute('aria-describedby');
                            msgWrapper.remove();
                        }
                    },
                    createErrorMessage(field, messages) {
                        const htmlMessages = (Array.isArray(messages) ? messages : [messages]).map(escapeHtml)
                        this.createHtmlErrorMessage(field, htmlMessages);
                    },
                    createHtmlErrorMessage(field, messages) {
                        this.removeMessages(field, options.messagesWrapperClassName);
                        field.element.removeAttribute('aria-errormessage');
                        field.element.removeAttribute('aria-describedby');
                        if (!field.state.valid) {
                            const msgWrapper = this.addHtmlMessages(field, options.messagesWrapperClassName, messages);
                            field.element.setAttribute('aria-errormessage', msgWrapper.id);
                            field.element.setAttribute('aria-describedby', msgWrapper.id);
                        }
                    },
                    /** @deprecated */
                    createMessage(field, message) {
                        return this.addMessages(field, options.messagesWrapperClassName, message);
                    },
                    addMessages(field, messagesClass, messages) {
                        const htmlMessages = (Array.isArray(messages) ? messages : [messages]).map(escapeHtml)
                        return this.addHtmlMessages(field, messagesClass, htmlMessages);
                    },
                    addHtmlMessages(field, messagesClass, htmlMessages) {
                        const msgWrapper = getMessagesWrapper.call(this, field, messagesClass);
                        (Array.isArray(htmlMessages) ? htmlMessages : [htmlMessages]).forEach((htmlMessage) => {
                            const li = document.createElement('li');
                            li.innerHTML = htmlMessage;
                            li.setAttribute('data-msg-field', field.element.name);
                            msgWrapper.appendChild(li);
                        });
                        return msgWrapper;
                    },
                    setField(name, value) {
                        this.fields[name].element.value = value;
                        this.fields[name].element.dispatchEvent((new Event('input')));
                        this.validateField(this.fields[name]);
                    }
                }
            }
            hyva.formValidation = formValidation;
            hyva.formValidation.rules = formValidationRules;
            hyva.formValidation.setInputAttributeRuleName = (attrName, ruleName) => INPUT_ATTRIBUTE_RULES[attrName] = ruleName || attrName;
            hyva.formValidation.setInputTypeRuleName = (typeName, ruleName) => INPUT_TYPE_RULES[typeName] = ruleName || typeName;
            hyva.formValidation.addRule = (name, validator) => formValidationRules[name] = validator;
        }(window.hyva = window.hyva || {}));
    </script>

    <div class="">

    </div>

    <script type="module" src="../../js/anchor.min.js" defer crossorigin></script>
    <script type="module" src="../../js/intersect.min.js" defer crossorigin></script>
    <script type="module" src="../../js/collapse.min.js" defer crossorigin></script>
    <script type="module" src="../../js/alpine3.min.js" defer crossorigin></script>

    <script>
        (g => {
            var h, a, k, p = "The Google Maps JavaScript API",
                c = "google",
                l = "importLibrary",
                q = "__ib__",
                m = document,
                b = window;
            b = b[c] || (b[c] = {});
            var d = b.maps || (b.maps = {}),
                r = new Set,
                e = new URLSearchParams,
                u = () => h || (h = new Promise(async (f, n) => {
                    await (a = m.createElement("script"));
                    e.set("libraries", [...r] + "");
                    for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]);
                    e.set("callback", c + ".maps." + q);
                    a.src = `https://maps.${c}apis.com/maps/api/js?` + e;
                    d[q] = f;
                    a.onerror = () => h = n(Error(p + " could not load."));
                    a.nonce = m.querySelector("script[nonce]")?.nonce || "";
                    m.head.append(a)
                }));
            d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n))
        })({
            key: "AIzaSyDR6ZEfRdQeGl40JZj1jYumFJ_xZS2z1Gg",
            v: "weekly",
            // Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
            // Add other bootstrap parameters as needed, using camel case.
        });
    </script>
    <script src="../../js/markerclusterer.min.js" defer crossorigin></script>

    <script>
        window.addEventListener('alpine:init', () => {
            console.log('Alpine.js has been initialized');
            Alpine.store('screen', {
                isSmall: window.matchMedia('(max-width: 639px)').matches,
                isMobile: window.matchMedia('(max-width: 767px)').matches,
                isTablet: window.matchMedia('(max-width: 1023px)').matches,
                init() {
                    const smallMedia = window.matchMedia('(max-width: 639px)');
                    const mobileMedia = window.matchMedia('(max-width: 767px)');
                    const tabletMedia = window.matchMedia('(max-width: 1023px)');
                    this.isSmall = smallMedia.matches;
                    this.isMobile = mobileMedia.matches;
                    this.isTablet = tabletMedia.matches;
                    const updateScreen = (event, type) => {
                        if (type === 'small') this.isSmall = event.matches;
                        if (type === 'mobile') this.isMobile = event.matches;
                        if (type === 'tablet') this.isTablet = event.matches;
                    };
                    [{
                            media: smallMedia,
                            type: 'small'
                        },
                        {
                            media: mobileMedia,
                            type: 'mobile'
                        },
                        {
                            media: tabletMedia,
                            type: 'tablet'
                        }
                    ].forEach(({
                        media,
                        type
                    }) => {
                        if (typeof media.onchange !== 'object') {
                            media.addListener((e) => updateScreen(e, type));
                        } else {
                            media.addEventListener('change', (e) => updateScreen(e, type));
                        }
                    });
                }
            });
            Alpine.store('asideBlocs', {
                asides: [],
                // Add new aside block
                addAside(name, customProperties = {}) {
                    if (!this.asides.find(aside => aside.name === name)) {
                        this.asides.push({
                            name,
                            open: false,
                            ...customProperties,
                        });
                    }
                },
                removeAside(name) {
                    this.asides = this.asides.filter(aside => aside.name !== name);
                },
                toggleAside(name) {
                    const aside = this.asides.find(aside => aside.name === name);
                    if (aside) {
                        aside.open = !aside.open;
                        document.body.classList.toggle('overflow-hidden', aside.open);
                    }
                },
                closeAside(name) {
                    const aside = this.asides.find(aside => aside.name === name);
                    if (aside) {
                        aside.open = false;
                        document.body.classList.remove('overflow-hidden');
                    }
                },
                openAside(name) {
                    const aside = this.asides.find(aside => aside.name === name);
                    if (aside) {
                        aside.open = true;
                        document.body.classList.add('overflow-hidden');
                    }
                }
            });
            Alpine.store('locator', {
                days: [{
                        key: 'monday',
                        label: 'Lundi'
                    },
                    {
                        key: 'tuesday',
                        label: 'Mardi'
                    },
                    {
                        key: 'wednesday',
                        label: 'Mercredi'
                    },
                    {
                        key: 'thursday',
                        label: 'Jeudi'
                    },
                    {
                        key: 'friday',
                        label: 'Vendredi'
                    },
                    {
                        key: 'saturday',
                        label: 'Samedi'
                    },
                    {
                        key: 'sunday',
                        label: 'Dimanche'
                    },
                ],
                allStores: [],
                countStore: "",
                filteredDistanceStores: null,
                selectedStore: null,
                loading: true,
                mapCenter: null,
                mapInstance: null,
                async init() {
                    try {
                        await this.loadLibraries();
                        await this.loadStores();
                    } finally {
                        this.loading = false;
                    }
                },
                async loadLibraries() {
                    const [geometry] = await Promise.all([
                        google.maps.importLibrary("geometry"),
                    ]);
                },
                async loadStores() {
                    try {
                        const response = await fetch(`${window.location.origin}/js/json/getList.json`);
                        const data = await response.json();
                        if (data) {
                            this.countStore = data.length;
                            this.allStores = data;
                        }
                    } catch (error) {
                        console.error('Erreur lors du chargement des magasins:', error);
                        this.allStores = [];
                    }
                },
                selectStore(store) {
                    this.selectedStore = store;
                    if (typeof this.onSelectStore === 'function') {
                        this.onSelectStore(store);
                    }
                },
                updateDistances(minZoom = 12) {
                    if (!this.mapInstance) return;
                    const zoom = this.mapInstance.getZoom();
                    if (zoom < minZoom) {
                        return this.filteredDistanceStores = []
                    }
                    const center = this.mapInstance.getCenter();
                    if (!center) return;
                    this.filteredDistanceStores = this.allStores
                        .filter(store => this.validateCoordinates(store.lat, store.lng).isValid)
                        .map(store => {
                            const position = new google.maps.LatLng(parseFloat(store.lat), parseFloat(store.lng));
                            const distanceInMeters = google.maps.geometry.spherical.computeDistanceBetween(center, position);
                            const distanceInKm = distanceInMeters / 1000;
                            return {
                                ...store,
                                distanceInKm,
                                distance: `${distanceInKm.toFixed(1)} km`
                            };
                        })
                        .sort((a, b) => a.distanceInKm - b.distanceInKm);
                },
                validateCoordinates(lat, lng) {
                    const isEmpty = (v) => v === '' || v === null || v === undefined;
                    if (isEmpty(lat) || isEmpty(lng)) {
                        return {
                            isValid: false,
                            error: 'Les coordonnées ne peuvent pas être null, undefined ou vides'
                        };
                    }
                    const latitude = parseFloat(lat);
                    const longitude = parseFloat(lng);
                    if (isNaN(latitude) || isNaN(longitude)) {
                        return {
                            isValid: false,
                            error: 'Les coordonnées doivent être des nombres valides'
                        };
                    }
                    if (latitude < -90 || latitude > 90) {
                        return {
                            isValid: false,
                            error: 'La latitude doit être comprise entre -90 et 90'
                        };
                    }
                    if (longitude < -180 || longitude > 180) {
                        return {
                            isValid: false,
                            error: 'La longitude doit être comprise entre -180 et 180'
                        };
                    }
                    return {
                        isValid: true,
                        coordinates: {
                            lat: latitude,
                            lng: longitude
                        }
                    };
                },
                setMapCenter(lat, lng, zoom) {
                    const parsedLat = parseFloat(lat);
                    const parsedLng = parseFloat(lng);
                    if (!isNaN(parsedLat) && !isNaN(parsedLng)) {
                        this.mapInstance.panTo({
                            lat: parsedLat,
                            lng: parsedLng
                        })
                    }
                    if (zoom) {
                        this.mapInstance.setZoom(zoom)
                    }
                },
                goToStore(store) {
                    if (!this.mapInstance || !store) return;
                    const lat = parseFloat(store.lat);
                    const lng = parseFloat(store.lng);
                    if (isNaN(lat) || isNaN(lng)) return;
                    this.setMapCenter(lat, lng, 15)
                    this.selectStore(store);
                },
                getOpeningStatus(store) {
                    const now = new Date();
                    const days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
                    const currentDayKey = days[now.getDay()];
                    const schedule = store[currentDayKey];
                    if (!schedule || schedule.toLowerCase().includes('fermé')) {
                        return {
                            status: 'Fermé',
                            end: null
                        };
                    }
                    const [start, end] = schedule.split(' - ');
                    if (!start || !end) {
                        return {
                            status: 'Fermé',
                            end: null
                        };
                    }
                    const [startHour, startMin] = start.split(':').map(Number);
                    const [endHour, endMin] = end.split(':').map(Number);
                    const startTime = new Date();
                    startTime.setHours(startHour, startMin, 0);
                    const endTime = new Date();
                    endTime.setHours(endHour, endMin, 0);
                    if (now >= startTime && now <= endTime) {
                        return {
                            status: 'Ouvert',
                            end
                        };
                    }
                    return {
                        status: 'Fermé',
                        end: null
                    };
                }
            });
        });
    </script>

</body>

</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Preview Layout</title>
    <link media="all" rel="stylesheet" href="{{ '/css/styles.css' | path }}">
    <script>
        window.APP = {
            modules: {},
            addModule: function(name, config) {
                this.modules[name] = this.modules[name] || [];
                this.modules[name].push(config);
            },
            DEBUG: 1,
            CONFIG: {
            },
        };
    </script>

    <style>
        body {
        {% if _target.meta.noPad == true %}
            margin: 0px !important;
        {% else %}
            margin: 25px !important;
        {% endif %}
        }
    </style>
</head>
<body {{ _target.display.background is defined ? 'style="background-color: ' ~ _target.display.background ~ '"' }} class="antialiased text-body-base font-roboto">
<script>
    'use strict';
    (function( hyva, undefined ) {

        function lifetimeToExpires(options, defaults) {

            const lifetime = options.lifetime || defaults.lifetime;

            if (lifetime) {
                const date = new Date;
                date.setTime(date.getTime() + lifetime * 1000);
                return date;
            }

            return null;
        }

        function generateRandomString() {

            const allowedCharacters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
                length = 16;

            let formKey = '',
                charactersLength = allowedCharacters.length;

            for (let i = 0; i < length; i++) {
                formKey += allowedCharacters[Math.round(Math.random() * (charactersLength - 1))]
            }

            return formKey;
        }

        const sessionCookieMarker = {noLifetime: true}

        const cookieTempStorage = {};

        const internalCookie = {
            get(name) {
                const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
                return v ? v[2] : null;
            },
            set(name, value, days, skipSetDomain) {
                let expires,
                    path,
                    domain,
                    secure,
                    samesite;

                const defaultCookieConfig = {
                    expires: null,
                    path: '/',
                    domain: null,
                    secure: false,
                    lifetime: null,
                    samesite: 'lax'
                };

                const cookieConfig = window.COOKIE_CONFIG || {};

                expires = days && days !== sessionCookieMarker
                    ? lifetimeToExpires({lifetime: 24 * 60 * 60 * days, expires: null}, defaultCookieConfig)
                    : lifetimeToExpires(window.COOKIE_CONFIG, defaultCookieConfig) || defaultCookieConfig.expires;

                path = cookieConfig.path || defaultCookieConfig.path;
                domain = !skipSetDomain && (cookieConfig.domain || defaultCookieConfig.domain);
                secure = cookieConfig.secure || defaultCookieConfig.secure;
                samesite = cookieConfig.samesite || defaultCookieConfig.samesite;

                document.cookie = name + "=" + encodeURIComponent(value) +
                    (expires && days !== sessionCookieMarker ? '; expires=' + expires.toGMTString() : '') +
                    (path ? '; path=' + path : '') +
                    (domain ? '; domain=' + domain : '') +
                    (secure ? '; secure' : '') +
                    (samesite ? '; samesite=' + samesite : 'lax');
            },
            isWebsiteAllowedToSaveCookie() {
                const allowedCookies = this.get('user_allowed_save_cookie');
                if (allowedCookies) {
                    const allowedWebsites = JSON.parse(unescape(allowedCookies));

                    return allowedWebsites[CURRENT_WEBSITE_ID] === 1;
                }
                return false;
            },
            getGroupByCookieName(name) {
                const cookieConsentConfig = window.cookie_consent_config || {};
                let group = null;
                for (let prop in cookieConsentConfig) {
                    if (!cookieConsentConfig.hasOwnProperty(prop)) continue;
                    if (cookieConsentConfig[prop].includes(name)) {
                        group = prop;
                        break;
                    }
                }
                return group;
            },
            isCookieAllowed(name) {
                const cookieGroup = this.getGroupByCookieName(name);
                return cookieGroup
                    ? window.cookie_consent_groups[cookieGroup]
                    : this.isWebsiteAllowedToSaveCookie();
            },
            saveTempStorageCookies() {
                for (const [name, data] of Object.entries(cookieTempStorage)) {
                    if (this.isCookieAllowed(name)) {
                        this.set(name, data['value'], data['days'], data['skipSetDomain']);
                        delete cookieTempStorage[name];
                    }
                }
            }
        };

        hyva.getCookie = (name) => {
            const cookieConfig = window.COOKIE_CONFIG || {};

            if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) {
                return cookieTempStorage[name] ? cookieTempStorage[name]['value'] : null;
            }

            return internalCookie.get(name);
        }

        hyva.setCookie = (name, value, days, skipSetDomain) => {
            const cookieConfig = window.COOKIE_CONFIG || {};

            if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) {
                cookieTempStorage[name] = {value, days, skipSetDomain};
                return;
            }
            return internalCookie.set(name, value, days, skipSetDomain);
        }


        hyva.setSessionCookie = (name, value, skipSetDomain) => {
            return hyva.setCookie(name, value, sessionCookieMarker, skipSetDomain)
        }

        hyva.getBrowserStorage = () => {
            const browserStorage = window.localStorage || window.sessionStorage;
            if (!browserStorage) {
                console.warn('Browser Storage is unavailable');
                return false;
            }
            try {
                browserStorage.setItem('storage_test', '1');
                browserStorage.removeItem('storage_test');
            } catch (error) {
                console.warn('Browser Storage is not accessible', error);
                return false;
            }
            return browserStorage;
        }

        hyva.postForm = (postParams) => {
            const form = document.createElement("form");

            let data = postParams.data;

            if (! postParams.skipUenc && ! data.uenc) {
                data.uenc = btoa(window.location.href);
            }
            form.method = "POST";
            form.action = postParams.action;

            Object.keys(postParams.data).map(key => {
                const field = document.createElement("input");
                field.type = 'hidden'
                field.value = postParams.data[key];
                field.name = key;
                form.appendChild(field);
            });

            const form_key = document.createElement("input");
            form_key.type = 'hidden';
            form_key.value = hyva.getFormKey();
            form_key.name="form_key";
            form.appendChild(form_key);

            document.body.appendChild(form);

            form.submit();
        }

        hyva.getFormKey = function () {
            let formKey = hyva.getCookie('form_key');

            if (!formKey) {
                formKey = generateRandomString();
                hyva.setCookie('form_key', formKey);
            }

            return formKey;
        }

        hyva.formatPrice = (value, showSign, options = {}) => {
            const formatter = new Intl.NumberFormat(
                'en-US',
                Object.assign({
                    style: 'currency',
                    currency: 'EUR',
                    signDisplay: showSign ? 'always' : 'auto'
                }, options)
            );
            return (typeof Intl.NumberFormat.prototype.formatToParts === 'function') ?
                formatter.formatToParts(value).map(({type, value}) => {
                    switch (type) {
                        case 'currency':
                            return '€' || value;
                        case 'minusSign':
                            return '- ';
                        case 'plusSign':
                            return '+ ';
                        default :
                            return value;
                    }
                }).reduce((string, part) => string + part) :
                formatter.format(value);
        }


        /**
         * Internal string replacement function implementation, see hyva.str() for usage details.
         *
         * @param string str Template string with optional placeholders
         * @param int nStart Offset for placeholders, 0 means %0 is replaced with args[0], 1 means %1 is replaced with args[0]
         * @param array ...args Positional replacement arguments. Rest arguments support isn't at 97% yet, so Array.from(arguments).slice() is used instead.
         */
        const formatStr = function (str, nStart) {
            const args = Array.from(arguments).slice(2);

            return str.replace(/(%+)([0-9]+)/g, (m, p, n) => {
                const idx = parseInt(n) - nStart;

                if (args[idx] === null || args[idx] === void 0) {
                    return m;
                }
                return p.length % 2
                    ? p.slice(0, -1).replace('%%', '%') + args[idx]
                    : p.replace('%%', '%') + n;
            })
        }

        /**
         * Replace positional parameters like %1 in string with the rest argument in the matching position.
         * The first rest argument replaces %1, the second %2 and so on.
         *
         * Example: hyva.str('%3 %2 %1', 'a', 'b', 'c') => "c b a"
         *
         * To insert a literal % symbol followed by a number, duplicate the %, for example %%2 is returned as %2.
         */
        hyva.str = function (string) {
            const args = Array.from(arguments);
            args.splice(1, 0, 1);

            return formatStr.apply(undefined, args);
        }

        /**
         * Zero based version of hyva.str(): the first rest argument replaces %0, the second %1 and so on.
         *
         * Example: hyva.strf('%2 %1 %0', 'a', 'b', 'c') => "c b a"
         *
         * If in doubt whether to use hyva.str() or hyva.strf(), prefer hyva.str() because it is more similar to __()
         * and it might be possible to reuse existing phrase translations with placeholders.
         */
        hyva.strf = function () {
            const args = Array.from(arguments);
            args.splice(1, 0, 0);

            return formatStr.apply(undefined, args);
        }

        /**
         * Take a html string as `content` parameter and
         * extract an element from the DOM to replace in
         * the current page under the same selector,
         * defined by `targetSelector`
         */
        hyva.replaceDomElement = (targetSelector, content) => {
            // Parse the content and extract the DOM node using the `targetSelector`
            const parser = new DOMParser();
            const doc = parser.parseFromString(content, 'text/html');
            const contentNode = doc.querySelector(targetSelector);

            // Bail if content can't be found
            if (!contentNode) {
                return;
            }

            hyva.activateScripts(contentNode)

            // Replace the old DOM node with the new content
            document.querySelector(targetSelector).replaceWith(contentNode);

            // Reload customerSectionData and display cookie-messages if present
            window.dispatchEvent(new CustomEvent("reload-customer-section-data"));
            hyva.initMessages();
        }

        hyva.activateScripts = (contentNode) => {
            // Extract all the script tags from the content.
            // Script tags won't execute when inserted into a dom-element directly,
            // therefore we need to inject them to the head of the document.
            const tmpScripts = contentNode.getElementsByTagName('script');

            if (tmpScripts.length > 0) {
                // Push all script tags into an array
                // (to prevent dom manipulation while iterating over dom nodes)
                const scripts = [];
                for (let i = 0; i < tmpScripts.length; i++) {
                    scripts.push(tmpScripts[i]);
                }

                // Iterate over all script tags and duplicate+inject each into the head
                for (let i = 0; i < scripts.length; i++) {
                    let script = document.createElement('script');
                    script.innerHTML = scripts[i].innerHTML;

                    document.head.appendChild(script);

                    // Remove the original (non-executing) node from the content
                    scripts[i].parentNode.removeChild(scripts[i]);
                }
            }
            return contentNode;
        }

        /**
         * Return base64 encoded current URL that can be used by Magento to redirect the visitor back to the current page.
         * The func hyva.getUenc handles additional encoding of +, / and = like \Magento\Framework\Url\Encoder::encode().
         */
        const replace = {['+']: '-', ['/']: '_', ['=']: ','};
        hyva.getUenc = () => btoa(window.location.href).replace(/[+/=]/g, match => replace[match]);

        let currentTrap;

        const focusableElements = (rootElement) => {
            const selector = 'button, [href], input, select, textarea, details, [tabindex]:not([tabindex="-1"]';
            return Array.from(rootElement.querySelectorAll(selector))
                .filter(el => {
                    return el.style.display !== 'none'
                        && !el.disabled
                        && el.tabIndex !== -1
                        && (el.offsetWidth || el.offsetHeight || el.getClientRects().length)
                })
        }

        const focusTrap = (e) => {
            const isTabPressed = e.key === 'Tab' || e.keyCode === 9;
            if (!isTabPressed) return;

            const focusable = focusableElements(currentTrap)
            const firstFocusableElement = focusable[0]
            const lastFocusableElement = focusable[focusable.length - 1]

            e.shiftKey
                ? document.activeElement === firstFocusableElement && (lastFocusableElement.focus(), e.preventDefault())
                : document.activeElement === lastFocusableElement && (firstFocusableElement.focus(), e.preventDefault())
        };

        hyva.releaseFocus = (rootElement) => {
            if (currentTrap && (!rootElement || rootElement === currentTrap)) {
                currentTrap.removeEventListener('keydown', focusTrap)
                currentTrap = null
            }
        }
        hyva.trapFocus = (rootElement) => {
            if (!rootElement) return;
            hyva.releaseFocus()
            currentTrap = rootElement
            rootElement.addEventListener('keydown', focusTrap)
            const firstElement = focusableElements(rootElement)[0]
            firstElement && firstElement.focus()
        }

        hyva.alpineInitialized = (fn) => window.addEventListener('alpine:initialized', fn, {once: true})

        window.addEventListener('alpine:initialized', () => {
            console.log('Alpine.js initialized')
        })

        window.addEventListener('user-allowed-save-cookie', () => internalCookie.saveTempStorageCookies())

    }( window.hyva = window.hyva || {} ));
</script>
<script>
    'use strict';
    (function(hyva) {
        const formValidationRules = {
            required(value, options, field, context) {
                const el = field.element.type === 'hidden' ? createTextInputFrom(field.element) : field.element,
                    msg = 'This\u0020is\u0020a\u0020required\u0020field.';

                if (el.type === 'radio' || el.type === 'checkbox') {
                    return (value === undefined || value.length === 0) ? msg : true;
                }

                el.setAttribute('required', '');
                el.checkValidity();

                return el.validity.valueMissing ? msg : true;
            },
            maxlength(value, options, field, context) {
                const n = Number(options)
                if (value.length > n) {
                    return n === 1
                        ? hyva.strf('Please\u0020enter\u0020no\u0020more\u0020than\u00201\u0020character.')
                        : hyva.strf('Please\u0020enter\u0020no\u0020more\u0020than\u0020\u00250\u0020characters.', options)
                }
                return true;
            },
            minlength(value, options, field, context) {
                const n = Number(options)
                if (value.length > 0 && value.length < n) {
                    return n === 1
                        ? hyva.strf('Please\u0020enter\u0020at\u0020least\u00201\u0020character.')
                        : hyva.strf('Please\u0020enter\u0020at\u0020least\u0020\u00250\u0020characters.', options)
                }
                return true;
            },
            max(value, options, field, context) {
                field.element.setAttribute('max', options);
                field.element.checkValidity();
                if (field.element.validity.rangeOverflow) {
                    return hyva.strf('Please\u0020enter\u0020a\u0020value\u0020less\u0020than\u0020or\u0020equal\u0020to\u0020\u0022\u00250\u0022.', options);
                }
                return true;
            },
            min(value, options, field, context) {
                field.element.setAttribute('min', options);
                field.element.checkValidity();
                if (field.element.validity.rangeUnderflow) {
                    return hyva.strf('Please\u0020enter\u0020a\u0020value\u0020greater\u0020than\u0020or\u0020equal\u0020to\u0020\u0022\u00250\u0022.', options);
                }
                return true;
            },
            step(value, options, field, context) {
                field.element.setAttribute('step', options);
                field.element.checkValidity();
                if (field.element.validity.stepMismatch) {
                    const val = Number(value);
                    const step = Number(options);
                    const msg = 'Please\u0020enter\u0020a\u0020valid\u0020value.\u0020The\u0020two\u0020nearest\u0020valid\u0020values\u0020are\u0020\u0022\u00250\u0022\u0020and\u0020\u0022\u00251\u0022.';
                    return hyva.strf(msg, Math.floor(val / step) * step, Math.ceil(val / step) * step);
                }
                return true;
            },
            pattern(value, options, field, context) {
                field.element.setAttribute('pattern', options);
                field.element.checkValidity();
                if (field.element.validity.patternMismatch) {
                    return field.element.title
                        ? hyva.strf('Please\u0020match\u0020the\u0020requested\u0020format\u003A\u0020\u00250.', field.element.title)
                        : 'Please\u0020match\u0020the\u0020requested\u0020format.'
                }
                return true;
            },
            email(value, options, field, context) {
                const rule = /^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i;
                if (value.length > 0 && !rule.test(value)) {
                    return 'Please\u0020enter\u0020a\u0020valid\u0020email\u0020address.';
                }
                return true;
            },
            password(value, options, field, context) {
                const rule = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/;
                if (value.length > 0 && !rule.test(value)) {
                    return 'Please\u0020provide\u0020at\u0020least\u0020one\u0020upper\u0020case,\u0020one\u0020lower\u0020case,\u0020one\u0020digit\u0020and\u0020one\u0020special\u0020character\u0020\u0028\u0023\u003F\u0021\u0040\u0024\u0025\u005E\u0026\u002A\u002D\u0029';
                }
                return true;
            },
            equalTo(value, options, field, context) {
                const dependencyField = context.fields[options].element;
                if (value !== dependencyField.value) {
                    const dependencyFieldName =
                        dependencyField.label ||
                        dependencyField.title ||
                        (dependencyField.labels && dependencyField.labels[0] && dependencyField.labels[0].innerText) ||
                        dependencyField.name;
                    return hyva.strf('This\u0020field\u0020value\u0020must\u0020be\u0020the\u0020same\u0020as\u0020\u0022\u00250\u0022.', dependencyFieldName);
                }
                return true;
            }
        };

        function raceSome(promises, pred) {
            return new Promise((resolve, reject) => {

                if (promises.length === 0) {
                    return resolve();
                }

                let settled = false, nDone = 0;

                const resolveIf = v => {
                    if (!settled && (pred(v) || ++nDone === promises.length)) {
                        settled = true;
                        resolve(v);
                    }
                    return v;
                }

                promises.map(promise => {
                    promise.then(resolveIf).catch(reason => {
                        settled = true;
                        reject(reason)
                    });
                    return promise;
                });
            });
        }

        const INPUT_ATTRIBUTE_RULES = {min: 'min', max: 'max', required: 'required', minlength: 'minlength', maxlength: 'maxlength', step: 'step', pattern: 'pattern'}
        const INPUT_TYPE_RULES = {email: 'email'}

        function getRules(element) {
            let rules = {};
            Object.keys(INPUT_ATTRIBUTE_RULES).forEach(attrName => {
                if (element.hasAttribute(attrName)) {
                    rules[INPUT_ATTRIBUTE_RULES[attrName]] = element.getAttribute(attrName);
                }
            })
            if (INPUT_TYPE_RULES[element.type]) {
                rules[INPUT_TYPE_RULES[element.type]] = true;
            }

            if (element.dataset.validate) {
                try {
                    Object.assign(rules, JSON.parse(element.dataset.validate));
                } catch (error) {
                    console.error('Validator error. Cannot parse data-validate attribute of element:\n', element);
                }
            }

            return rules;
        }

        function isInvalidRuleResult(ruleState) {
            return typeof ruleState === 'string' || !ruleState || (ruleState.type && ruleState.content);
        }

        async function runValidateFn(rule, options, value, field) {
            return formValidationRules[rule](value, options, field, this);
        }

        function generateId() {
            let id;
            do {
                id = `${this.idPrefix}-${++this.idSeq}`;
            } while (document.getElementById(id));
            return id;
        }

        function isVisible(element) {
            const el = element.type !== 'hidden' ? element : (element.parentElement || {});
            return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length)
        }

        function elementWillValidate(element) {
            return (element.willValidate || element.type === 'hidden')
                && element.tagName !== 'BUTTON'
                && element.disabled === false
                && !(element.tagName === 'INPUT' && element.type === 'submit')
                && (element.hasAttribute('data-validate-hidden') || isVisible(element))
        }

        function createMessageContainer(el, fieldWrapperClassName) {
            if (! el.parentElement) {
                return;
            }
            const refocus = document.activeElement === el;
            const wrapper = document.createElement('div');
            wrapper.classList.add.apply(wrapper.classList, fieldWrapperClassName.split(' '));
            el.parentElement.insertBefore(wrapper, el);
            wrapper.appendChild(el);
            refocus && document.activeElement !== el && el.focus();
            return wrapper;
        }

        function containerNotFound(selector, el) {
            const msg = `Cannot find message container element ${selector} of ${el.name}`;
            console.error(msg, el);
            throw msg;
        }

        function createTextInputFrom(el) {
            const text = document.createElement('INPUT');
            text.type = 'text';
            text.value = el.value;
            return text;
        }

        function classNamesToSelector(classNames) {
            return classNames.split(' ')
                .filter(className => className.length > 0)
                .map(className => `.${className}`)
                .join('')
        }

        function hasMessagesWrapper(field, messagesWrapperClassName) {
            return this.getMessageContainer(field).querySelector(classNamesToSelector(messagesWrapperClassName));
        }

        function getMessagesWrapper(field, messagesWrapperClassName) {
            if (hasMessagesWrapper.call(this, field, messagesWrapperClassName)) {
                return this.getMessageContainer(field).querySelector(classNamesToSelector(messagesWrapperClassName));
            }

            const msgWrapper = document.createElement('ul');
            const msgId = generateId.call(this);
            msgWrapper.id = msgId;
            field.element.setAttribute('aria-errormessage', msgId);
            field.element.setAttribute('aria-describedby', msgId);
            msgWrapper.classList.add.apply(msgWrapper.classList, messagesWrapperClassName.split(' '));
            if (field.validateOnChange) {
                msgWrapper.setAttribute('aria-live', 'polite');
            }
            this.getMessageContainer(field).appendChild(msgWrapper);

            return msgWrapper;
        }

        function getCheckedValues(field) {
            const name = field.element.name.replace(/([\\"])/g, '\\$1');
            const elements = field.element.form.querySelectorAll('input[name="' + name + '"]:checked');
            return Array.from(elements).map(el => el.value);
        }

        function escapeHtml(s) {
            const div = document.createElement('div')
            div.innerText = s;
            return div.innerHTML;
        }


        function formValidation(formElement, options) {
            // Disable browser default validation
            if (formElement.tagName === 'FORM') {
                formElement.setAttribute('novalidate', '');
            } else {
                console.error('formValidation can be initialized only on FORM element', formElement);
                return;
            }

            options = Object.assign({
                fieldWrapperClassName: 'field field-reserved',
                messagesWrapperClassName: 'messages',
                validClassName: 'field-success',
                invalidClassName: 'field-error',
                pageMessagesWrapperSelector: null,
                scrollToFirstError: true,
            }, options || {});

            return {
                state: {
                    valid: false,
                },
                fields: {},
                idSeq: 0,
                idPrefix: formElement.id || 'vld-msg',
                setupFields(elements) {
                    this.fields = {};
                    Array.from(elements).forEach(element => {
                        if (elementWillValidate(element)) {
                            this.setupField(element);
                        }
                    });
                },
                setupField(element) {
                    if (! element) return;
                    const onChange = !!element.dataset.onChange;
                    if (elementWillValidate(element)) {
                        const rules = getRules(element);
                        if (Object.keys(rules).length > 0) {
                            if (this.fields[element.name]) {
                                Object.assign(this.fields[element.name].rules, rules);
                            } else {
                                this.fields[element.name] = {
                                    element,
                                    rules: rules,
                                    validateOnChange: onChange,
                                    state: {
                                        valid: null,
                                        rules: {}
                                    }
                                }
                            }
                        }
                    } else {
                        console.error('Element will not validate', element);
                    }
                },
                onSubmit(event) {
                    if (event.target.tagName === 'FORM') {
                        event.preventDefault();

                        this.validate()
                            .then(() => event.target.submit())
                            .catch(invalidElements => {});
                    }
                },
                onChange(event) {
                    event.target.dataset.onChange = 'true';
                    if (!Object.keys(this.fields).length) {
                        this.setupFields(formElement.elements);
                    }
                    if (!Object.keys(this.fields).includes(event.target.name)) {
                        this.setupField(event.target);
                    }
                    const field = this.fields[event.target.name];

                    this.validateField(field);
                    field && field.element.removeAttribute('data-on-change')
                },
                validateSafe() {
                    return new Promise(resolve => this.validate().then(() => resolve(true)).catch(() => {}))
                },
                validate() {
                    if (!Object.keys(this.fields).length || !Object.keys(this.fields).length !== formElement.elements.length) {
                        this.setupFields(formElement.elements);
                    }
                    return new Promise(async (resolve, reject) => {
                        if (formElement.elements) {
                            await raceSome(this.validateFields(), result => result !== true)
                            const invalidFields = Object.values(this.fields).filter(field => !field.state.valid);
                            this.state.valid = invalidFields.length === 0;
                            if (this.state.valid) {
                                resolve();
                            } else {
                                if (options.scrollToFirstError && invalidFields.length > 0) {
                                    invalidFields[0].element.focus()
                                    invalidFields[0].element.select && invalidFields[0].element.select();
                                }
                                reject(invalidFields.map(field => field.element));
                            }
                        }
                    });
                },
                validateFields() {
                    const fields = Object.values(this.fields);

                    fields.forEach(field => {
                        this.getMessageContainer(field).classList.remove(options.validClassName, options.invalidClassName)
                    });
                    return fields.map(field => this.validateField(field))
                },
                validateField(field) {
                    if (! field || ! elementWillValidate(field.element)) {
                        return new Promise(resolve => resolve(true))
                    }

                    let value;
                    if (field.element.type === 'checkbox') {
                        value = getCheckedValues(field);
                    } else if (field.element.type === 'radio') {
                        value = getCheckedValues(field)[0] || undefined;
                    } else if (field.element.tagName === 'SELECT' && field.element.multiple) {
                        value = Array.from(field.element.selectedOptions).map(opt => opt.value);
                    } else {
                        value = field.element.value;
                    }

                    const rules = field.rules || {};

                    field.state.valid = true;
                    this.showFieldState(field);


                    const fieldValidations = Object.keys(rules).filter(rule => formValidationRules[rule]).map(async rule => {
                        return runValidateFn.call(this, rule, rules[rule], value, field).then(result => {
                            field.state.rules[rule] = result;
                            return result;
                        })
                    });

                    return new Promise(resolve => {
                        Promise.all(fieldValidations).then(results => {
                            field.state.valid = !elementWillValidate(field.element) || rules.length === 0 || !results.some(isInvalidRuleResult)
                            this.showFieldState(field);
                            resolve(field.state.valid);
                        })
                    });
                },
                getMessagesByField(field) {
                    const messages = [];
                    const invalidRules = Object.keys(field.state.rules).filter(rule => isInvalidRuleResult(field.state.rules[rule]));

                    field.rules && Object.keys(field.rules).forEach((rule) => {
                        if (invalidRules.includes(rule)) {
                            const customMessage = field.element.getAttribute('data-msg-' + rule);
                            const message = customMessage ? customMessage : field.state.rules[rule];
                            const ruleOptions = JSON.parse(JSON.stringify(field.rules[rule]));

                            if (typeof message === 'undefined' || message === null || (typeof message !== 'string' && ! message.type)) {
                                messages.push(hyva.strf('Validation rule "%0" failed.', rule));
                            } else if (Array.isArray(ruleOptions)) {
                                ruleOptions.unshift(message.type ? message.content : message);
                                const content = hyva.strf.apply(null, ruleOptions);
                                messages.push(message.type ? {type: message.type, content} : content);
                            } else {
                                const content = hyva.strf(message.type ? message.content : message, ruleOptions)
                                messages.push(message.type ? {type: message.type, content} : content);
                            }
                        }
                    });
                    return messages;
                },
                /** @deprecated */
                getFieldWrapper(field) {
                    return this.getMessageContainer(field)
                },
                getMessageContainer(field) {
                    let container;
                    const pageSelector = field.element.getAttribute('data-validation-container') || options.pageMessagesContainerSelector;
                    if (pageSelector) {
                        container = document.querySelector(pageSelector)
                            || containerNotFound(pageSelector, field.element)
                    } else {
                        const containerSelector = classNamesToSelector(options.fieldWrapperClassName);
                        container = field.element.closest(containerSelector)
                            || createMessageContainer(field.element, options.fieldWrapperClassName)
                            || containerNotFound(containerSelector, field.element);
                    }

                    return container;
                },
                showFieldState(field) {
                    const container = this.getMessageContainer(field),
                        hasErrorMessages = hasMessagesWrapper.call(this, field, options.messagesWrapperClassName),
                        messages = this.getMessagesByField(field).map(m => {
                            return m.type !== 'html' ? escapeHtml(m.type ? m.content : m) : m.content;
                        });
                    container.classList.toggle(options.validClassName, field.state.valid && ! hasErrorMessages);
                    container.classList.toggle(options.invalidClassName, !field.state.valid || hasErrorMessages);
                    this.createHtmlErrorMessage(field, messages);

                    if (field.state.valid) {
                        field.element.removeAttribute('aria-invalid');
                    } else {
                        field.element.setAttribute('aria-invalid', 'true');
                        if (! document.activeElement) {
                            field.element.focus();
                        }
                    }
                },
                removeMessages(field, messagesClass) {
                    if (! hasMessagesWrapper.call(this, field, messagesClass || options.messagesWrapperClassName)) {
                        return;
                    }

                    const msgWrapper = getMessagesWrapper.call(this, field, messagesClass || options.messagesWrapperClassName);
                    const messages = msgWrapper.querySelectorAll(`[data-msg-field='${field.element.name}']`);
                    Array.from(messages).forEach(msg => msg.remove());
                    if (msgWrapper && msgWrapper.childElementCount === 0) {
                        field.element.removeAttribute('aria-errormessage');
                        field.element.removeAttribute('aria-describedby');
                        msgWrapper.remove();
                    }
                },
                createErrorMessage(field, messages) {
                    const htmlMessages = (Array.isArray(messages) ? messages : [messages]).map(escapeHtml)
                    this.createHtmlErrorMessage(field, htmlMessages);
                },
                createHtmlErrorMessage(field, messages) {
                    this.removeMessages(field, options.messagesWrapperClassName);
                    field.element.removeAttribute('aria-errormessage');
                    field.element.removeAttribute('aria-describedby');

                    if (!field.state.valid) {
                        const msgWrapper = this.addHtmlMessages(field, options.messagesWrapperClassName, messages);
                        field.element.setAttribute('aria-errormessage', msgWrapper.id);
                        field.element.setAttribute('aria-describedby', msgWrapper.id);
                    }
                },
                /** @deprecated */
                createMessage(field, message) {
                    return this.addMessages(field, options.messagesWrapperClassName, message);
                },
                addMessages(field, messagesClass, messages) {
                    const htmlMessages = (Array.isArray(messages) ? messages : [messages]).map(escapeHtml)
                    return this.addHtmlMessages(field, messagesClass, htmlMessages);
                },
                addHtmlMessages(field, messagesClass, htmlMessages) {
                    const msgWrapper = getMessagesWrapper.call(this, field, messagesClass);

                    (Array.isArray(htmlMessages) ? htmlMessages : [htmlMessages]).forEach((htmlMessage) => {
                        const li = document.createElement('li');
                        li.innerHTML = htmlMessage;
                        li.setAttribute('data-msg-field', field.element.name);
                        msgWrapper.appendChild(li);
                    });

                    return msgWrapper;
                },
                setField(name, value) {
                    this.fields[name].element.value = value;
                    this.fields[name].element.dispatchEvent((new Event('input')));
                    this.validateField(this.fields[name]);
                }
            }
        }

        hyva.formValidation = formValidation;
        hyva.formValidation.rules = formValidationRules;
        hyva.formValidation.setInputAttributeRuleName = (attrName, ruleName) => INPUT_ATTRIBUTE_RULES[attrName] = ruleName || attrName;
        hyva.formValidation.setInputTypeRuleName = (typeName, ruleName) => INPUT_TYPE_RULES[typeName] = ruleName || typeName;
        hyva.formValidation.addRule = (name, validator) => formValidationRules[name] = validator;
    }(window.hyva = window.hyva || {}));
</script>


{% block yield %}
    <div {{ createCustomAttributes(_target.meta.customAttributes) }} class="{{ layout_wrapper_class is defined ? layout_wrapper_class : _target.meta.layout_wrapper_class }}">
        {{ yield }}
    </div>
{% endblock %}

<script type="module"
        src="{{ '/js/anchor.min.js' | path }}"
        defer
        crossorigin
></script>
<script type="module"
        src="{{ '/js/intersect.min.js' | path }}"
        defer
        crossorigin
></script>
<script type="module"
        src="{{ '/js/collapse.min.js' | path }}"
        defer
        crossorigin
></script>
<script type="module"
        src="{{ '/js/alpine3.min.js' | path }}"
        defer
        crossorigin
></script>

<script>
	(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
		key: "AIzaSyDR6ZEfRdQeGl40JZj1jYumFJ_xZS2z1Gg",
		v: "weekly",
		// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
		// Add other bootstrap parameters as needed, using camel case.
	});
</script>
<script
        src="{{ '/js/markerclusterer.min.js' | path }}"
        defer
        crossorigin
></script>

{% render '@scripts' %}

</body>
</html>
/* No context defined. */

No notes defined.