PageSourceSearch

https://www.goyard.cn/static/version1790062722/frontend/Goyard/default/zh_Hans_CN/js/bundle/bundle13.js

js goyard.cn collected 2026-10-08 06:38:21 UTC 537,347 bytes, 3 lines download raw bytes

1require.config({"config": {
2        "jsbuild":{"Goyard_Catalog/js/customer_logged_status.js":"/**\n * Copyright Goyard Orkester\n * @author Orkester\n * @copyright Goyard\n */\ndefine([\n\t'Magento_Customer/js/customer-data'\n], function (customerData) {\n\t'use strict';\n\n\t/**\n\t * Synchronous read of customer data, may be empty not loaded yet\n\t */\n\tfunction getCustomer() {\n\t\treturn customerData.get('customer')();\n\t}\n\n\t/**\n\t * Wait for the customer data to be loaded\n\t */\n\tfunction getIsCustomerLoggedIn() {\n\t\treturn new Promise(function (resolve) {\n\t\t\tlet customer = customerData.get('customer');\n\n\t\t\tif (customer().firstname) {\n\t\t\t\tresolve(customer());\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet subscription = customer.subscribe(function () {\n\t\t\t\tsubscription.dispose();\n\t\t\t\tresolve(customer());\n\t\t\t});\n\n\t\t\tsetTimeout(function () {\n\t\t\t\tsubscription.dispose();\n\t\t\t\tresolve(customer());\n\t\t\t}, 1000);\n\t\t});\n\t}\n\n\treturn {\n\t\tgetCustomer: getCustomer,\n\t\tgetIsCustomerLoggedIn: getIsCustomerLoggedIn\n\t};\n});\n","Goyard_Catalog/js/swatch-renderer-mixin.js":"define(\n    ['jquery',\n        'underscore',\n        'mage/template',\n        'mage/smart-keyboard-handler',\n        'mage/translate',\n        'priceUtils',\n        'Magento_Ui/js/modal/modal',\n        'mage/url',\n        'Goyard_Wishlist/js/front-injector',\n        'Goyard_Wishlist/js/check-customer-wishlist',\n        'Magento_Customer/js/customer-data',\n        'Goyard_Catalog/js/category/change-carousel',\n        'slick',\n        'jquery-ui-modules/widget',\n        'jquery/jquery.parsequery',\n        'mage/validation/validation',\n        'access_key',\n        'Goyard_Catalog/js/product_page/handler-swatchcolor',\n    ],\n    function (\n        $,\n        _,\n        mageTemplate,\n        keyboardHandler,\n        $t,\n        priceUtils,\n        modal,\n        urlBuilder,\n        frontInjector,\n        customerWishlist,\n        customerData,\n        changeCarousel\n    ) {\n        'use strict';\n\n        return function (SwatchRenderer) {\n            $.widget('mage.SwatchRenderer', $['mage']['SwatchRenderer'], {\n\n                _init: function () {\n                    //Reinit UrlBuilder BASE URL\n                    this.initUrls();\n\n                    // Don't render the same set of swatches twice\n                    if ($(this.element).attr('data-rendered')) {\n                        return;\n                    }\n\n                    $(this.element).attr('data-rendered', true);\n\n                    if (_.isEmpty(this.options.jsonConfig.images)) {\n                        this.options.useAjax = true;\n                        // creates debounced variant of _LoadProductMedia()\n                        // to use it in events handlers instead of _LoadProductMedia()\n                        this._debouncedLoadProductMedia = _.debounce(this._LoadProductMedia.bind(this), 500);\n                    }\n\n                    this.options.tierPriceTemplate = $(this.options.tierPriceTemplateSelector).html();\n\n                    if (this.options.jsonConfig !== '' && this.options.jsonSwatchConfig !== '') {\n                        // store unsorted attributes\n                        this.options.jsonConfig.mappedAttributes = _.clone(this.options.jsonConfig.attributes);\n                        this._sortAttributes();\n                        this._RenderControls();\n                        this._setPreSelectedGallery();\n                        $(this.element).trigger('swatch.initialized', { swatchThis: this });\n                    }\n                },\n\n                /**\n                 *\n                 * @param {*} event\n                 */\n                setupFocus(event) {\n                    const $wrapper = $(event.currentTarget);\n                    const activeDescendantId = $wrapper.attr('aria-activedescendant');\n                    if (activeDescendantId) {\n                        $wrapper.find('.swatch-option').removeClass('borderBlue').removeAttr('tabindex');\n\n                        if (event.type === 'focus') {\n                            const selectedItem = $wrapper.find('.swatch-option#' + activeDescendantId);\n                            selectedItem.addClass('borderBlue');\n                        }\n                        else {\n                            $wrapper.find('.swatch-option').removeClass('borderBlue');\n                        }\n                    }\n                },\n\n                /**\n                 * Manage Product swatch option selection using left and right arrow\n                 * @param {*} event\n                 * @returns\n                 */\n                throughSwatchOptions(event) {\n                    const $wrapper = $(event.currentTarget);\n                    const allOptions = $wrapper.find('[role=\"option\"]');\n                    const activeDescendantId = $wrapper.attr('aria-activedescendant');\n                    const currentItem = activeDescendantId ? $wrapper.find('#' + activeDescendantId) : allOptions.eq(0);\n                    const currentOptionIndex = allOptions.index(currentItem);\n                    let nextItem = currentItem;\n\n                    if (!currentItem.length) {\n                        return;\n                    }\n\n                    if (event.keyCode === 37) {\n                        if (currentOptionIndex > -1 && currentOptionIndex > 0) {\n                            nextItem = allOptions.eq(currentOptionIndex - 1);\n                        }\n                        nextItem.trigger('click');\n                        nextItem.toggleClass('borderBlue');\n\n                    }\n\n                    if (event.keyCode === 39) {\n                        if (currentOptionIndex > -1 && currentOptionIndex < allOptions.length - 1) {\n                            nextItem = allOptions.eq(currentOptionIndex + 1);\n                        }\n                        nextItem.trigger('click');\n                        nextItem.toggleClass('borderBlue');\n                    }\n                },\n\n                _RenderControls: function () {\n                    var $widget = this,\n                        container = this.element,\n                        classes = this.options.classes,\
2n                        chooseText = this.options.jsonConfig.chooseText,\n                        showTooltip = this.options.showTooltip;\n                    $widget.optionsMap = {};\n\n                    $.each(this.options.jsonConfig.attributes, function () {\n                        var item = this,\n                            controlLabelId = 'option-label-' + item.code + '-' + item.id,\n                            options = $widget._RenderSwatchOptions(item, controlLabelId),\n                            select = $widget._RenderSwatchSelect(item, chooseText),\n                            input = $widget._RenderFormInput(item),\n                            listLabel = '',\n                            label = '';\n\n                        // Show only swatch controls\n                        if ($widget.options.onlySwatches && !$widget.options.jsonSwatchConfig.hasOwnProperty(item.id)) {\n                            return;\n                        }\n\n                        if ($widget.options.enableControlLabel) {\n                            label +=\n                                '<p id=\"' + controlLabelId + '\" class=\"' + classes.attributeLabelClass + '\">' +\n                                $('<i></i>').text(item.label).html() +\n                                '<span class=\"' + classes.attributeSelectedOptionLabelClass + '\"></span>' +\n                                '</p>';\n\n                        }\n\n                        if ($widget.inProductList) {\n                            $widget.productForm.append(input);\n                            input = '';\n                            listLabel = 'aria-label=\"' + $('<i></i>').text(item.label).html() + '\"';\n                        } else {\n                            listLabel = 'aria-labelledby=\"' + controlLabelId + '\"';\n                        }\n\n                        // Create new control\n                        container.append(\n                            '<div class=\"' + classes.attributeClass + ' ' + item.code + '\" ' +\n                            'data-attribute-code=\"' + item.code + '\" ' +\n                            'data-attribute-id=\"' + item.id + '\">' +\n                            label +\n                            '<ul aria-activedescendant=\"\" ' +\n                            'tabindex=\"0\" ' +\n                            'aria-invalid=\"false\" ' +\n                            'aria-required=\"true\" ' +\n                            'aria-label=\"' + $t('See all colours') + '\" ' +\n                            'role=\"listbox\" ' + listLabel +\n                            'class=\"' + classes.attributeOptionsWrapper + ' clearfix\">' +\n                            options + select +\n                            '</ul>' + input +\n                            '</div>'\n                        );\n\n                        $widget.optionsMap[item.id] = {};\n\n                        // Aggregate options array to hash (key => value)\n                        $.each(item.options, function () {\n                            if (this.products.length > 0) {\n                                $widget.optionsMap[item.id][this.id] = {\n                                    price: parseInt(\n                                        $widget.options.jsonConfig.optionPrices[this.products[0]].finalPrice.amount,\n                                        10\n                                    ),\n                                    products: this.products\n                                };\n                            }\n                        });\n                    });\n\n                    if (showTooltip === 1) {\n                        // Connect Tooltip\n                        container\n                            .find('[data-option-type=\"1\"], [data-option-type=\"2\"],' +\n                                ' [data-option-type=\"0\"], [data-option-type=\"3\"]')\n                            .SwatchRendererTooltip();\n                    }\n\n                    // Hide all elements below more button\n                    $('.' + classes.moreButton).nextAll().hide();\n\n                    // Handle events like click or change\n                    $widget._EventListener();\n\n                    // Rewind options\n                    $widget._Rewind(container);\n\n                    //Emulate click on all swatches from Request\n                    $widget._EmulateSelected($.parseQuery());\n                    $widget._EmulateSelected($widget._getSelectedAttributes());\n                },\n                initUrls: function () {\n                    urlBuilder.setBaseUrl(window.BASE_URL);\n                },\n\n                _OnClick: function ($this, $widget) {\n                    // check if the element in swatch-color is already selected and return nothing\n                    if ($this[0].classList.contains('selected')) {\n                        return;\n                    }\n                    this._super($this, $widget);\n\n                    if (!$this.hasClass('selected')) {\n                        $this.attr('aria-selected', false);\n                    }\n\n                    if (this.isProductViewPage()) {\n                        const swatchOptionClicked = new CustomEvent('swatchOptionClickedOnProductPage', {\n                            detail: {\n                                element: $this\n                            }\n                        });\n                        document.dispatchEvent(swatchOptionClicked);\n                    }\n\n                    if (!this.isProductViewPage()) {\n                        const swatchOptionClickedOnListingPageOrResultPage = new CustomEvent('swatchOptionClickedOnListingPageOrResultPage', {\n                            detail: {\n                                element: $this\n                            }\n                        })\n                        document.dispatchEvent(swatchOptionClickedOnListingPageOrResultPage);\n                    }\n\n                    // Globale Fixed Prices\n                    /* check setting add_data_fp_attribute_automatically from module configuration */\n                    if (window.addD
2ataFpAutomayically !== undefined || window.addDataFpAutomayically === '1') {\n                        var priceBox = $widget.element.parents($widget.options.selectorProduct)\n                        var productId = $widget.getProduct();\n                        var baseSalePrice = $(priceBox).find('.product-fixed-price .price').first().text();\n                        var baseRegularPrice = $(priceBox).find('.product-fixed-price .price').last().text();\n                        if (baseSalePrice === baseRegularPrice) {\n                            baseRegularPrice = null;\n                        }\n                        $.get('/international-ge/ProductSwatch/product/?productId=' + productId).done(function (data) {\n                            if ($(priceBox).find('.product-fixed-price').length != 0) {\n                                $(priceBox).find('.product-fixed-price .price').first().html(baseSalePrice);\n                                if (baseRegularPrice) {\n                                    $(priceBox).find('.product-fixed-price .price').last().html(baseRegularPrice);\n                                }\n                                if (data.finalFixedPrices !== undefined) {\n                                    $(priceBox).find('.product-fixed-price').first().attr('data-fp', data.finalFixedPrices);\n                                }\n                                if (baseRegularPrice && data.regularFixedPrices !== undefined) {\n                                    $(priceBox).find('.product-fixed-price').last().attr('data-fp', data.regularFixedPrices);\n                                }\n                                $(priceBox).find('.product-fixed-price').attr('product-vat', data.vat);\n                            }\n                        }).fail(function () { });\n                    }\n                },\n\n                _OnChange: function ($this, $widget) {\n                    this._super($this, $widget);\n\n                    if (this.isProductViewPage()) {\n                        $widget.element.find('li[data-option-id]').removeClass('disabled').prop('disabled', false);\n                        $widget._Rebuild();\n                    }\n                },\n\n                /**\n                 * Use aria-selected instead of aria-checked\n                 *\n                 * @param {Object} $this\n                 * @param {Object} $wrapper\n                 * @private\n                 */\n                _toggleCheckedAttributes: function ($this, $wrapper) {\n                    $wrapper.attr('aria-activedescendant', $this.attr('id'))\n                        .find('.' + this.options.classes.optionClass).attr('aria-selected', false);\n                    $this.attr('aria-selected', true);\n                },\n\n                /**\n                 * Render swatch options by part of config\n                 *\n                 * @param {Object} config\n                 * @param {String} controlId\n                 * @returns {String}\n                 * @private\n                 */\n                _RenderSwatchOptions: function (config, controlId) {\n                    var optionConfig = this.options.jsonSwatchConfig[config.id],\n                        optionJsonConfig = this.options.jsonConfig,\n                        optionClass = this.options.classes.optionClass,\n                        sizeConfig = this.options.jsonSwatchImageSizeConfig,\n                        moreLimit = parseInt(this.options.numberToShow, 10),\n                        moreClass = this.options.classes.moreButton,\n                        moreText = this.options.moreButtonText,\n                        colorFilterConfig = this.options.colorFilterConfig,\n                        countAttributes = 0,\n                        html = '';\n                    if (!this.options.jsonSwatchConfig.hasOwnProperty(config.id)) {\n                        return '';\n                    }\n\n                    // Get Json data in <ol></ol> from list.phtml\n                    let colorDigitalFilterIds = $('.product-items').data('json');\n\n                    $.each(config.options, function (index) {\n                        var id,\n                            type,\n                            value,\n                            thumb,\n                            label,\n                            width,\n                            height,\n                            attr,\n                            swatchImageWidth,\n                            swatchImageHeight;\n\n                        if (!optionConfig.hasOwnProperty(this.id)) {\n                            return '';\n                        }\n                        // Add more button\n                        if (moreLimit === countAttributes++) {\
2n                            html += '<a href=\"#\" class=\"' + moreClass + '\"><span>' + moreText + '</span></a>';\n                        }\n\n                        id = this.id;\n                        type = parseInt(optionConfig[id].type, 10);\n                        value = optionConfig[id].hasOwnProperty('value') ?\n                            $('<i></i>').text(optionConfig[id].value).html() : '';\n                        thumb = optionConfig[id].hasOwnProperty('thumb') ? optionConfig[id].thumb : '';\n                        width = _.has(sizeConfig, 'swatchThumb') ? sizeConfig.swatchThumb.width : 110;\n                        height = _.has(sizeConfig, 'swatchThumb') ? sizeConfig.swatchThumb.height : 90;\n                        label = this.label ? $('<i></i>').text(this.label).html() : '';\n\n                        // Get the att_color_digital_filter option ID corresponding with att_couleur LABEL\n                        let colorDigitalId = '';\n                        if (colorDigitalFilterIds) {\n                            colorDigitalId = colorFilterConfig[id];\n                        }\n\n                        let indexColors = optionJsonConfig.index;\n                        var targetValue = id;\n                        var targetKey = null;\n\n                        // Get Current SKU\n                        for (var key in indexColors) {\n                            if (indexColors.hasOwnProperty(key)) {\n                                if (indexColors[key][630] === targetValue) {\n                                    targetKey = key;\n                                    break;\n                                }\n                            }\n                        }\n\n                        attr =\n                            ' id=\"' + controlId + '-item-' + id + '\"' +\n                            ' index=\"' + index + '\"' +\n                            ' aria-selected=\"false\"' +\n                            ' aria-describedby=\"' + controlId + '\"' +\n                            ' data-option-type=\"' + type + '\"' +\n                            ' data-option-id=\"' + id + '\"' +\n                            ' data-option-filter-id=\"' + colorDigitalId + '\"' +\n                            ' data-option-sku=\"' + optionJsonConfig.sku[targetKey] + '\"' +\n                            ' title=\"' + label + '\"' +\n                            ' data-option-label=\"' + label + '\"' +\n                            ' aria-label=\"' + label + '\"' +\n                            ' role=\"option\"' +\n                            ' data-thumb-width=\"' + width + '\"' +\n                            ' data-thumb-height=\"' + height + '\"' +\n                            'data-testid=\"product-color-option-' + optionJsonConfig.sku[targetKey] + '-li\"';\n\n                        attr += thumb !== '' ? ' data-option-tooltip-thumb=\"' + thumb + '\"' : '';\n                        attr += value !== '' ? ' data-option-tooltip-value=\"' + value + '\"' : '';\n\n                        swatchImageWidth = _.has(sizeConfig, 'swatchImage') ? sizeConfig.swatchImage.width : 30;\n                        swatchImageHeight = _.has(sizeConfig, 'swatchImage') ? sizeConfig.swatchImage.height : 20;\n\n                        if (!this.hasOwnProperty('products') || this.products.length <= 0) {\n                            attr += ' data-option-empty=\"true\"';\n                        }\n\n                        if (type === 0) {\n                            // Text\n                            html += '<div class=\"' + optionClass + ' text\" ' + attr + '>' + (value ? value : label) +\n                                '</div>';\n                        } else if (type === 1) {\n                            // Color\n                            html += '<div class=\"' + optionClass + ' color\" ' + attr +\n                                ' style=\"background: ' + value +\n                                ' no-repeat center; background-size: initial;\">' + '' +\n                                '</div>';\n                        } else if (type === 2) {\n                            // Image\n                            html += '<li class=\"' + optionClass + ' image\" ' + attr +\n                                ' style=\"background: url(' + value + ') no-repeat center; background-size: initial;width:' +\n                                swatchImageWidth + 'px; height:' + swatchImageHeight + 'px\">' + '' +\n                                '</li>';\n                        } else if (type === 3) {\n                            // Clear\n                            html += '<div class=\"' + optionClass + '\" ' + attr + '></div>';\n                        } else {\n                            // Default\n                            html += '<div class=\"' + optionClass + '\" ' + attr + '>' + label + '</div>';\n                        }\n                    });\n\n                    return html;\n                }
2,\n\n                /**\n                 * Render select by part of config\n                 *\n                 * @param {Object} config\n                 * @param {String} chooseText\n                 * @returns {String}\n                 * @private\n                 */\n                _RenderSwatchSelect: function (config, chooseText) {\n                    var html;\n\n                    if (this.options.jsonSwatchConfig.hasOwnProperty(config.id)) {\n                        return '';\n                    }\n\n                    html = '<select class=\"' + this.options.classes.selectClass + ' ' + config.code + '\">';\n\n                    $.each(config.options, function () {\n                        var label = this.label,\n                            attr = ' value=\"' + this.id + '\" data-option-id=\"' + this.id + '\"';\n\n                        if (!this.hasOwnProperty('products') || this.products.length <= 0) {\n                            attr += ' data-option-empty=\"true\"';\n                        }\n\n                        html += '<option ' + attr + '>' + label + '</option>';\n                    });\n\n                    html += '</select>';\n\n                    return html;\n                },\n\n                /**\n                * Check if we are on a Product Detail Page (PDP)\n                * @returns {boolean}\n                */\n                isProductViewPage: function () {\n                    return $('body').hasClass('catalog-product-view');\n                },\n\n                /**\n                 * Update total price\n                 * Goyard TE\n                 */\n                _UpdatePrice: function () {\n                    var $widget = this,\n                        $product = $widget.element.parents($widget.options.selectorProduct),\n                        $productPrice = $product.find(this.options.selectorProductPrice),\n                        result = $widget._getNewPrices(),\n                        tierPriceHtml,\n                        isShow;\n\n                    var customerDataSection = customerData.get('customer');\n\n                    // Goyard TE : Check if $productPrice exists to avoid $productPrice.priceBox is not a function\n                    if ($productPrice.length > 0 && customerDataSection().firstname) {\n                        $productPrice.trigger(\n                            'updatePrice',\n                            {\n                                'prices': $widget._getPrices(result, $productPrice.priceBox('option').prices)\n                            }\n                        );\n                    }\n\n                    if (!customerDataSection().firstname) {\n                        $('.price').empty();\n                    }\n\n                    isShow = typeof result != 'undefined' && result.oldPrice.amount !== result.finalPrice.amount;\n\n                    // TEOP\n                    // Hide the price container if price = 0\n                    if (result.finalPrice.amount > 0 && customerDataSection().firstname) {\n                        $(\".product-info-main .product-info-price\").show();\n\n                        let selected_option = $('.swatch-attribute-options .swatch-option.selected').data('optionSku');\n                        // check if simple sku allow price display\n                        if (!this.options.priceDisplay[selected_option]) {\n                            $(\".product-info-main .product-info-price\").hide();\n                        }\n                    } else {\n                        $(\".product-info-main .product-info-price\").hide();\n                    }\n                    // --------\n                    $productPrice.find('span:first').toggleClass('special-price', isShow);\n\n                    $product.find(this.options.slyOldPriceSelector)[isShow ? 'show' : 'hide']();\n\n                    if (typeof result != 'undefined' && result.tierPrices && result.tierPrices.length) {\n                        if (this.options.tierPriceTemplate) {\n                            tierPriceHtml = mageTemplate(\n                                this.options.tierPriceTemplate,\n                                {\n                                    'tierPrices': result.tierPrices,\
2n                                    '$t': $t,\n                                    'currencyFormat': this.options.jsonConfig.currencyFormat,\n                                    'priceUtils': priceUtils\n                                }\n                            );\n                            $(this.options.tierPriceBlockSelector).html(tierPriceHtml).show();\n                        }\n                    } else {\n                        $(this.options.tierPriceBlockSelector).hide();\n                    }\n\n                    $(this.options.normalPriceLabelSelector).hide();\n\n                    _.each($('.' + this.options.classes.attributeOptionsWrapper), function (attribute) {\n                        if ($(attribute).find('.' + this.options.classes.optionClass + '.selected').length === 0) {\n                            if ($(attribute).find('.' + this.options.classes.selectClass).length > 0) {\n                                _.each($(attribute).find('.' + this.options.classes.selectClass), function (dropdown) {\n                                    if ($(dropdown).val() === '0') {\n                                        $(this.options.normalPriceLabelSelector).show();\n                                    }\n                                }.bind(this));\n                            } else {\n                                $(this.options.normalPriceLabelSelector).show();\n                            }\n                        }\n                    }.bind(this));\n                },\n            });\n            return $['mage']['SwatchRenderer'];\n        };\n    });","Goyard_Catalog/js/price-box-mixin.js":"define(\n\t'Goyard_Catalog/js/price-box-mixin', [\n\t'jquery',\n\t'Magento_Catalog/js/price-utils',\n\t'underscore',\n\t'mage/template',\n\t'jquery-ui-modules/widget'\n], function ($, utils, _, mageTemplate) {\n\t'use strict';\n\n\tvar globalOptions = {\n\t\tproductId: null,\n\t\tpriceConfig: null,\n\t\tprices: {},\n\t\tpriceTemplate: '<span style=\"display:none\" data-storefront-globale=\"data-ge-price\" class=\"price\"><%- data.formatted %></span>'\n\t};\n\tvar widgetMixin = {\n\t\toptions: globalOptions,\n\n\t\treloadPrice: function () {\n\t\t\tvar priceFormat = (this.options.priceConfig && this.options.priceConfig.priceFormat) || {},\n\t\t\t\tpriceTemplate = mageTemplate(this.options.priceTemplate);\n\n\t\t\t_.each(this.cache.displayPrices, function (price, priceCode) {\n\t\t\t\tprice.final = _.reduce(price.adjustments, function (memo, amount) {\n\t\t\t\t\treturn memo + amount;\n\t\t\t\t}, price.amount);\n\n\t\t\t\tprice.formatted = utils.formatPriceLocale(price.final, priceFormat);\n\n\t\t\t\t$('[data-price-type=\"' + priceCode + '\"]', this.element).html(priceTemplate({\n\t\t\t\t\tdata: price\n\t\t\t\t}));\n\n\t\t\t\t$('[data-price-type=\"' + priceCode + '\"]', this.element).find('.price').trigger('update-globale-element');\n\n\t\t\t}, this);\n\t\t}\n\t};\n\n\treturn function (targetWidget) {\n\t\t// Example how to extend a widget by mixin object\n\t\t$.widget('mage.priceBox', targetWidget, widgetMixin); // the widget alias should be like for the target widget\n\n\t\treturn $.mage.priceBox; //  the widget by parent alias should be returned\n\t};\n});","Goyard_Catalog/js/infinite-scroll.js":"require([\n    \"jquery\",\n    \"ias\",\n    \"Goyard_Catalog/js/columns-catalog\",\n    'Goyard_Catalog/js/category/custom-price-loader',\n    'Goyard_Catalog/js/video-playback'\n], function ($, InfiniteAjaxScroll, columnsCatalog, customPriceLoader, videoPlayback) {\n    $(document).ready(function () {\n\n        const customPriceListingPageEvent = new CustomEvent(\"plp-page:load\", {});\n        document.dispatchEvent(customPriceListingPageEvent);\n\n        if (!$('.products.list.items.product-items').length) {\n            return;\n        }\n\n        let ias = new InfiniteAjaxScroll(\".products.list.items.product-items\", {\n            item: \".item.product.product-item,.item.category-moodboard\",\n            next: \".toolbar-bottom .pages .item.current + .item a\",\n            pagination: \".toolbar-products.toolbar-bottom\",\n            loadOnScroll: false,\n            prefill: false,\n            spinner: '.loader.goyard-loader',\n            trigger: \".btn-more-products\"\n        });\n        let $lastProductItem;\n        $(\".btn-more-products\").on(\"click\", function () {\n            //Accces replace focus on last element in listing search (click / spacebar / enter)\n            $lastProductItem = $('ol.products.list.items.product-items > li:last-child');\n            $lastProductItem.find('.product-item-link').focus();\n            // --\n            $(\".loader.goyard-loader\").removeAttr(\"style\");\n            $('.more-products-wrapper').removeAttr(\"style\");\n\n        });\n\n        ias.on(\"appended\", function () {\n            $(\".products.list.items.product-items\").trigger(\"contentUpdated\");\n            $(\".loader.goyard-loader\").attr(\"style\", \"display: none;\");\n            $('.more-products-wrapper').attr(\"style\", \"margin-bottom: 40px\");\n\n            pageWidth = document.documentElement.clientWidth;\n            columnsCatalog.injectGridArea();\n\n            if (pageWidth < 769) {\n                $('.product-item-details').click(function () {\n                    $(\".product-items\").find(\".color-label\").css(\"display\", \"block\");\n                    $(\".product-items\").find(\".color-detail\").css(\"display\", \"none\");\n                    $(this).find(\".color-label\").css(\"display\", \"none\");\n                    $(this).find(\".color-detail\").css(\"display\", \"block\");\n                });\n            }\n\n            // Force load & play on video if not disabled by accessibility mode\n            $(\".products.list.items.product-items video\").each(function () {\n                if (!$('body').hasClass('accessibility_mode_animation')) {\n                    if ($(this).hasClass('play-on')) {\n                        if ($(this).get(0).videoHeight >
2 0) {\n                            // Do nothing\n                        } else {\n                            // reload the video\n                            $(this).get(0).load();\n                        }\n\n                    }\n                } else {\n                    videoPlayback.pause($(this)[0]);\n                }\n            });\n\n\n            //Listen reductAnimation Event & stop video in carousel on Hover\n            $(document).on(\"reductAnimation\", function (event) {\n                $(\".product-list-video\").hover(function () {\n                    if (event.detail.animation === true) {\n                        videoPlayback.pause($(this).find(\"video\").get(0));\n                    } else {\n                        videoPlayback.play($(this).find(\"video\").get(0));\n                    }\n                });\n            });\n            const $nextProduct = $lastProductItem.next();\n            $nextProduct.find('.product-item-link').focus();\n\n            // Dispatch Event for price in listing page\n            document.dispatchEvent(customPriceListingPageEvent);\n        })\n\n        ias.on('last', () => {\n            $('.more-products-wrapper').css(\"display\", \"none\");\n        })\n    });\n\n\n    $(document).on(\"reload_pagination\", function () {\n        if ($('.products.list.items.product-items').length > 0) {\n            let ias = new InfiniteAjaxScroll(\".products.list.items.product-items\", {\n                item: \".item.product.product-item,.item.category-moodboard\",\n                next: \".toolbar-bottom .pages .item.current + .item a\",\n                pagination: \".toolbar-products.toolbar-bottom\",\n                loadOnScroll: false,\n                prefill: false,\n                spinner: '.loader.goyard-loader',\n                trigger: \".btn-more-products\"\n            });\n            ias.on(\"appended\", function () {\n                console.error('reload_pagination appended');\n                $(\".products.list.items.product-items\").trigger(\"contentUpdated\");\n                $(\".loader.goyard-loader\").attr(\"style\", \"display: none;\");\n                $('.more-products-wrapper').attr(\"style\", \"margin-bottom: 40px\");\n            })\n\n            ias.on('last', () => {\n                $('.more-products-wrapper').css(\"display\", \"none\");\n            })\n        }\n\n        // Update moodboard\n        columnsCatalog.injectGridArea();\n\n        if ($(\".toolbar-bottom .pages .item.current + .item a\").length && !$('.more-products-wrapper').hasClass('no-product')) {\n            $('.more-products-wrapper').css(\"display\", \"block\");\n            $('.btn-more-products').css(\"opacity\", \"1\");\n        }\n        else {\n            $('.more-products-wrapper').css(\"display\", \"none\");\n        }\n    });\n});\n","Goyard_Catalog/js/category/handler-swatchcolor.js":"/**\n * Copyright Goyard Orkester\n * @author Orkester\n * @copyright Goyard\n */\n\ndefine('Goyard_Catalog/js/category/handler-swatchcolor', [\n    'jquery',\n    'Goyard_Catalog/js/category/change-carousel',\n], function (\n    $,\n    changeCarousel\n) {\n    'use strict';\n\n    const eventCatcherCategory = {\n        init: function () {\n            const event = new CustomEvent(\"plp-page:load\");\n            document.dispatchEvent(event);\n\n            $('body').on('swatch.initialized', function (event, data) {\n                eventCatcherCategory.applyColorFilterFromUrlOnListing(data.swatchThis);\n            });\n\n            document.addEventListener(\"swatchOptionClickedOnListingPageOrResultPage\", function (event) {\n                eventCatcherCategory.onSwatchOptionClick(event.detail.element);\n            });\n        },\n\n        /**\n         * Au click sur une couleur\n         * Change le carousel, updates le Hash dans l'url et lance l'ajax pour mettre \u00e0 jour le prix\n         */\n        onSwatchOptionClick: function (element) {\n            let color = element.attr('aria-label');\n            let parent = element.closest('li.item.product.product-item.text-center');\n            const name = parent.find('.product-item-link').text().trim();\n            parent.attr('aria-label', name + ' - ' + color);\n\n            changeCarousel.init(element);\n            this.updateHashInUrl(element);\n\n            const colorWrapper = element.closest('.product-item-info');\n            const priceContainer = colorWrapper.find('.custom-price-container');\n            const priceContainerSku = priceContainer.data('sku')\n\n            const customPriceListingPageEvent = new CustomEvent(\"plp-swatchcolor:click\", {\n                detail: {\n                    selector: \"#custom-price-plp-\" + priceContainerSku,\n                    sku: element.data('option-sku')\n                }\n            });\n            window.dispatchEvent(customPriceListingPageEvent);\n\n        },\n        /**\n            Update URl of product to add #SKU of the selected variation in any link\n            in a product-item parent element.\n        */\n        updateHashInUrl: function (element) {\n            const currentSku = element.data('option-sku');\n\n            if (currentSku) {\n                $(document).ready(function () {\n                    const listCarousel = element.closest('li.item.product.product-item.text-center');\n\n                    listCarousel.find('a').each(function () {\n                        const $link = $(this);\n                        const currentHref = $link.attr('href');\n\n                        if (!currentHref) return;\n\n                        if (currentHref.includes(\"/sku/\")) {\n                            const updatedUrl = currentHref.replace(/\\/sku\\/[^\\/]*/, '/sku/' + currentSku);\n                            $link.attr('href', updatedUrl);\n                        } else {\n                            const updatedUrl = currentHref.replace(/#.*/, '') + '#' + currentSku;\n                            $link.attr('href', updatedUrl);\n                        }\n                    });\n                });\n            }\n        },\n\n        applyColorFilterFromUrlOnListing: function (swatchThis) {\n            try {\n                if (!this.isListingPage()) return;\n\n                const colorIds = this.extractColorFilterIdsFromUrl();\n\n                if (colorIds.length > 0) {\n                    this.applyColorFilterToProducts(colorIds, swatchThis);\n                } else {\n                    this.applyMainVariantColorFallback(swatchThis);\n                }\n            } catch (error) {\n                console.error('Error in applyColorFilterFromUrlOnListing :', error);\n            }\n        },\n\n        isListingPage: function () {\n            return (\n                $('.catalog-category-view').length >
2 0 ||\n                $('.cms-index-index .product-carousel-widget-wrapper').length > 0 ||\n                $('.cms-page-view .product-carousel-widget-wrapper').length > 0 ||\n                $('.catalogsearch-result-index').length > 0 ||\n                $('.search.results .products.wrapper.grid.products-grid .products.list.items.product-items').length > 0\n            );\n        },\n\n        extractColorFilterIdsFromUrl: function () {\n            const regex = /att_color_digital_filter%5B%5D=(\\d+)/g;\n            const queryString = window.location.search;\n            const matches = queryString.matchAll(regex);\n\n            const colorIds = [];\n            for (const match of matches) {\n                colorIds.push(match[1]);\n            }\n            return colorIds;\n        },\n\n        applyColorFilterToProducts: function (colorIds, swatchThis) {\n            const products = $('[data-item-position]');\n            products.each((index, productElement) => {\n                const colorIndex = index % colorIds.length;\n                let colorId = colorIds[colorIndex];\n                if ($(productElement).find($(swatchThis.element)).length > 0) {\n                    let swatchOption = $(productElement).find(`.swatch-option[data-option-filter-id*=\"${colorId}\"]`).first();\n                    if (swatchOption.length) {\n                        swatchOption.click();\n                    } else {\n                        this.tryFallbackColorOptions(productElement, colorIds, colorIndex);\n                    }\n                }\n            });\n        },\n\n        tryFallbackColorOptions: function (element, colorIds, startIndex) {\n            const visited = [];\n\n            for (let i = startIndex; i < colorIds.length; i++) {\n                let colorId = colorIds[i];\n\n                if (visited.includes(colorId)) {\n                    // All options tried \u2192 fallback to main variant\n                    const mainId = $(element).find(\".product-item-details\").attr('data-main-variant-option-id');\n                    $(element).find(`.swatch-option[data-option-id=\"${mainId}\"]`).click();\n                    return;\n                }\n\n                visited.push(colorId);\n                let swatchOption = $(element).find(`.swatch-option[data-option-filter-id*=\"${colorId}\"]`);\n                if (swatchOption.length) {\n                    swatchOption.click();\n                    return;\n                }\n\n                if (i === colorIds.length - 1) i = -1; // restart loop\n            }\n        },\n\n        applyMainVariantColorFallback: function (swatchThis) {\n            const $el = $(swatchThis.element);\n            const mainVariantId = $el.parents('.product-item-details').attr('data-main-variant-option-id');\n            const swatch = $el.find(`.swatch-option[data-option-id=\"${mainVariantId}\"]`);\n            const color = swatch.attr('aria-label');\n            const productEl = swatch.closest('li.item.product.product-item.text-center');\n            const name = productEl.find('.product-item-link').text().trim();\n\n            swatch.attr('aria-selected', 'true');\n            productEl.attr('aria-label', name + ' - ' + color);\n        }\n    };\n\n    return eventCatcherCategory;\n});\n\nrequire(['Goyard_Catalog/js/category/handler-swatchcolor'], function (eventCatcherCategory) {\n    eventCatcherCategory.init();\n});\n","Goyard_Catalog/js/category/custom-price-loader.js":"define('Goyard_Catalog/js/category/custom-price-loader', [\n    'jquery',\n    'Magento_Customer/js/customer-data',\n    'mage/url'\n], function ($, customerData, urlBuilder) {\n    'use strict';\n\n    const customPriceLoader = {\n\n        displayPrice: function (item) {\n            const selector = item.selector;\n\n            if (selector === '.price') {\n                if (item.label_parts) {\n                    $(selector).closest('.goyard-price-box-inner')\n                        .find('.price-label-before').text(item.label_parts.text_before);\n                    $(selector).text(item.label_parts.price);\n                    $(selector).closest('.goyard-price-box-inner')\n                        .find('.price-label-after').text(item.label_parts.text_after);\n                } else {\n                    $(selector).text(item.price);\n                }\n                $(selector).show();\n            } else {\n                if (item.label_parts) {\n                    if (selector.indexOf('wishlist') !== -1) {\n                        $(selector).parent().find('.price-label-before').text(item.label_parts.text_before);\n                        $(selector).text(item.label_parts.price);\n                        $(selector).parent().find('.price-label-after').text(item.label_parts.text_after);\n                    } else {\n                        $(selector).find('.price-label-before').text(item.label_parts.text_before);\n                        $(selector).find('.price-plp-value').text(item.label_parts.price);\n                        $(selector).find('.price-label-after').text(item.label_parts.text_after);\n                        $(selector).show();\n                    }\n                } else {\n                    if (selector.indexOf('wishlist') !== -1) {\n                        $(selector).text(item.price);\n                    } else {\n                        $(selector).find('.price-plp-value').text(item.price);\n                        $(selector).show();\n                    }\n                }\n            }\n        },\n\n        waitForCustomerData: function () {\n            const dfd = $.Deferred();\n            const customer = customerData.get('customer');\n\n            if (customer().firstname) {\n                dfd.resolve();\n            } else {\n                customer.subscribe(function () {\n                    if (customer().firstname) dfd.resolve();\n                });\n            }\n\n            return dfd.promise();\n        },\n\n        getDatasOnCategoryPage: function () {\n            const datas = {};\n            if ($('body').hasClass('catalog-category-view') || $('body').hasClass('catalogsearch-result-index')) {\n                datas['selector'] = \"#custom-price-plp-\";\n                datas['sku'] = [];\n\n                $('.custom-price-container').each($.proxy(function (i, container) {\n                    const $container = $(container);\n                    const divId = $container.attr('id');\n                    const sku = $container.data('sku');\n\n                    if (divId && sku && !sessionStorage.getItem('price_' + sku)) {\n                        datas['sku'].push(sku);\n                    }\n                }, this));\n            }\n            if (datas['sku'] && datas['sku'].length) {\n                datas['sku'] = datas['sku'].join(',');\n                this.loadPrices(datas, 'plp');\n            }\n        },\n\n        getDatasOnProductPage: function (sku) {\n            if ($('body').hasClass('catalog-product-view') && !sessionStorage.getItem('price_' + sku)) {\n                this.loadPrices([{ selector: '.price', sku: sku }], 'pdp');\n            }\n        },\n\n        loadPrices: function (params, from) {\n            const self = this;\n            this.waitForCustomerData().done(function () {\n                const query = $.param({ datas: params, from: from });\n                const url = urlBuilder.build('goyard_catalog/ajax/marquageproductprice') + '?' + query;\n\n                $.ajax({\n                    url: url,\n                    type: 'GET',\n                    dataType: 'json',\n                    cache: true,\n                    success: function (response) {\n                        if (!Array.isArray(response)) return console.error('R\u00e9ponse inattendue :', response);\n\n                        $.each(response, function (i, item) {\n                            if (!item.selector) return;\n\n                            if (item.status) {\n                                self.dis
2playPrice(item);\n                            } else {\n                                $(item.selector).find('span').text('');\n                            }\n                        });\n\n\n                        if (from === 'pdp') $(\".price\").show();\n                    },\n                    error: function () {\n                        console.error('Error when loading prices');\n                    }\n                });\n            });\n        },\n\n        init: function () {\n\n            const self = this;\n            $(document).on('plp-page:load', function () { self.getDatasOnCategoryPage(); });\n            $(document).on('swatchOptionClicked', function (event) { self.getDatasOnProductPage(event.detail.optionSku); });\n            $(window).on('plp-swatchcolor:click', function (event) { self.loadPrices([event.detail], 'plp'); });\n\n            $(document).on('contentUpdated', '.products-grid', function () {\n                self.getDatasOnCategoryPage();\n            });\n        }\n    };\n\n    return customPriceLoader;\n});\n\nrequire(['Goyard_Catalog/js/category/custom-price-loader'], function (customPriceLoader) {\n    customPriceLoader.init();\n});\n","Goyard_Catalog/js/category/reassurance.js":"/**\n * Copyright Goyard Orkester\n * @author Orkester\n * @copyright Goyard\n */\n\ndefine([\n\t'jquery',\n\t'mage/url',\n\t'Magento_Customer/js/customer-data'\n], ($, urlBuilder, customerData) => {\n\t'use strict';\n\n\treturn function () {\n\t\t// Check if customer is logged and display reassurance block\n\t\tif (customerData.get('customer')().firstname) {\n\t\t\t$.ajax({\n\t\t\t\turl: urlBuilder.build('goyard_catalog/ajax/reassurance'),\n\t\t\t\ttype: 'GET',\n\t\t\t\tdataType: 'json',\n\t\t\t\tsuccess: function (response) {\n\t\t\t\t\tlet html = response.html?.replaceAll(\"&lt;\", '<').replaceAll(\"&gt;\", '>');\n\t\t\t\t\t$('.reassurance-block-container').append(html).show();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n});\n","Goyard_Catalog/js/category/change-carousel.js":"/**\n * Copyright Goyard Orkester\n * @author Orkester\n * @copyright Goyard\n */\n\ndefine('Goyard_Catalog/js/category/change-carousel', [\n    'jquery',\n], function ($) {\n    'use strict';\n    const BaseUrl = window.BASE_URL;\n    const urlForPersonalisationBrush = BaseUrl + 'goyard_catalog/ajax/personalisationBrush';\n    const urlForProductCarousel = BaseUrl + 'goyard_catalog/ajax/productCarousel';\n\n    const changeCarousel = {\n        init: function ($this) {\n            this.changeCarousel($this);\n        },\n\n        changeCarousel: function ($this) {\n            const ajaxParam = $this.data('option-sku');\n            let $product = $this.closest('.product-item');\n\n            let productCarouselParam = this.prepareParamForProductCarousel(ajaxParam, $product);\n\n            this.ajaxProductCarousel(productCarouselParam);\n\n            // If the carousel is on the category page, we need to load the brush\n            if ($('.catalog-category-view').length > 0 || $('.catalogsearch-result-index').length > 0) {\n                let personalisationBrushParam = this.prepareParamForPersonalisationBrush(ajaxParam, $product);\n                this.ajaxPersonalisationBrush(personalisationBrushParam);\n            }\n        },\n\n        ajaxProductCarousel: function (productCarouselParam) {\n            jQuery.ajax({\n                url: urlForProductCarousel,\n                type: 'GET',\n                cache: true,\n                timeout: 20000,\n                data: productCarouselParam,\n                dataType: 'json',\n                success: function (response) {\n                    $(\".carousel-block-\" + response.parent).children().remove();\n                    $(\".carousel-block-\" + response.parent).html($(response.html));\n                },\n                error: function (xhr, status, error) {\n                    console.error(error);\n                }\n            });\n        },\n\n        prepareParamForProductCarousel: function (ajaxParam, $product) {\n            let params = { 'sku': ajaxParam };\n\n            let personalisation_allowed = Boolean($product.data('personalisationAllowed'));\n            let first = Boolean($product.data('videoPosition'));\n            let video_allowed = Boolean($product.data('videoAllowed'));\n            let currentCategory = $product.data('category');\n\n            let brushEnable = (typeof $('.products.wrapper').data('brush') !== 'undefined') ? 1 : 0;\n\n            if (video_allowed) {\n                params['video_allowed'] = 1;\n\n            } else {\n                params['video_allowed'] = 0;\n            }\n            if (personalisation_allowed) {\n                params['personalisation_allowed'] = 1;\n            } else {\n                params['personalisation_allowed'] = 0;\n            }\n            if (first) {\n                params['video_allowed'] = 1;\n                if ($(window).width() < 768) {\n                    params['video_position'] = 2;\n                } else {\n                    params['video_position'] = 1;\n                }\n            } else {\n                params['video_position'] = 0;\n            }\n            if ($('.catalogsearch-result-index').length) {\n                params['cache_search'] = 1;\n            }\n            if (currentCategory) {\n                params['category_id'] = currentCategory;\n            }\n            params['brushEnable'] = brushEnable;\n\n            return params;\n        },\n\n        ajaxPersonalisationBrush: function (personalisationBrushParam) {\n            $.ajax({\n                url: urlForPersonalisationBrush,\n                type: 'GET',\n                cache: true,\n                timeout: 10000,\n                data: personalisationBrushParam,\n                dataType: 'json',\n                success: function (response) {\n                    $(\"#brush_\" + response.parent).remove();\n                    $(response.html).insertBefore(\".carousel-block-\" + response.parent);\n                },\n                error: function (xhr, status, error) {\n                    console.error(error);\n                }\n            });\n        },\n\n        prepareParamForPersonalisationBrush: function (ajaxParam, $product) {\n            let params = { 'sku': ajaxParam };\n            let personalisation_allowed = Boolean($product.data('personalisationAllowed'));\n            let brushEnable = (typeof $('.products.wrapper').data('brush') !== 'undefined') ? 1 : 0;\n\n            if (personalisation_allowed) {\n                params['personalisation_allowed'] = 1;\n            } else {\n                params['personalisation_allowed'] = 0;\n            }\n            params['brushEnable'] = brushEnable;\n\n            return params;\n        },\n    }\n\n    return changeCarousel;
2\n});","Goyard_Catalog/js/product_page/change_upsell.js":"define('Goyard_Catalog/js/product_page/change_upsell', [\n    'jquery',\n    'mage/url'\n], function ($, urlBuilder) {\n    'use strict';\n    const urlForProductUpsell = urlBuilder.build('goyard_catalog/ajax/productUpsell');\n\n    return {\n\n        init: function () {\n            document.addEventListener('swatchOptionClicked', (event) => {\n                const productSku = event.detail.optionSku;\n                this.changeUpsell(productSku);\n            });\n        },\n\n        changeUpsell: function (productSku) {\n            $('.product-upsell-container').addClass('ajax-refresh');\n            this.ajaxProductUpsell(productSku);\n        },\n\n        ajaxProductUpsell: function (productSku) {\n            $.ajax({\n                url: urlForProductUpsell,\n                type: 'GET',\n                cache: true,\n                timeout: 10000,\n                data: {\n                    'sku': productSku\n                },\n                dataType: 'json',\n                success: function (response) {\n                    $('#product_upsell_section').replaceWith(response.html);\n                    $('.product-upsell-container').removeClass('ajax-refresh');\n                    if (!$('#product_upsell_section').children().length) {\n                        $('#product_upsell_section').addClass('d-none');\n                    }\n                },\n                error: function (xhr, status, error) {\n                    console.error(error);\n                }\n            });\n        },\n\n    };\n});\n\nrequire(['Goyard_Catalog/js/product_page/change_upsell'], function (changeUpsell) {\n    changeUpsell.init();\n});\n","Goyard_Catalog/js/product_page/change_buttons.js":"/**\n * Copyright Goyard Orkester\n * @author Orkester\n * @copyright Goyard\n */\ndefine([\n\t'jquery',\n\t'mage/url',\n\t'Goyard_Catalog/js/customer_logged_status'\n], function ($, urlBuilder, customerLoggedStatus) {\n\t'use strict';\n\n\tdocument.addEventListener('swatchOptionClicked', (event) => {\n\t\tconst productSku = event.detail.optionSku;\n\t\t$('#product_addtocart_form').find('input[name=\"current_sku\"]').val(productSku);\n\t\tchangeAllButtons(productSku);\n\t});\n\n\t// Update product buttons section\n\tfunction changeAllButtons(productSku) {\n\t\tcustomerLoggedStatus.getIsCustomerLoggedIn().then(function (customer) {\n\t\t\tlet isLoggedIn = !!customer?.firstname;\n\t\t\tlet url = isLoggedIn ? urlBuilder.build('goyard_catalog/ajax/productAllButtons') : urlBuilder.build('goyard_catalog/ajax/productButtons');\n\t\t\t$('.product-buttons-container').addClass('disable');\n\n\t\t\tjQuery.ajax({\n\t\t\t\turl: url,\n\t\t\t\ttype: isLoggedIn ? 'POST' : 'GET',\n\t\t\t\tcache: true,\n\t\t\t\ttimeout: 10000,\n\t\t\t\tloader: true,\n\t\t\t\tdata: {\n\t\t\t\t\t'sku': productSku\n\t\t\t\t},\n\t\t\t\tdataType: 'json',\n\t\t\t\tsuccess: function (response) {\n\t\t\t\t\tlet featureContainer = $(response.html);\n\n\t\t\t\t\t$('.product-buttons-container').html(featureContainer);\n\n\t\t\t\t\t$('.product-buttons-container').removeClass('disable');\n\t\t\t\t},\n\t\t\t\terror: function (xhr, status, error) {\n\t\t\t\t\tconsole.error('changeAllButtonsThisProduct : ' + error);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n});\n","Goyard_Catalog/js/product_page/change_crosssell.js":"define('Goyard_Catalog/js/product_page/change_crosssell', [\n    'jquery',\n    'mage/url'\n], function ($, urlBuilder) {\n    'use strict';\n\n    const urlChangeCrosssel = urlBuilder.build('goyard_catalog/ajax/productCrosssell');\n\n    return {\n\n        init: function () {\n            document.addEventListener('swatchOptionClicked', (event) => {\n                const productSku = event.detail.optionSku;\n                this.changeCrosssell(productSku);\n            });\n        },\n\n        changeCrosssell: function (productSku) {\n            $('.product-crosssell-container').addClass('ajax-refresh');\n            this.ajaxProductCrosssell(productSku);\n        },\n\n        ajaxProductCrosssell: function (productSku) {\n            jQuery.ajax({\n                url: urlChangeCrosssel,\n                type: 'GET',\n                cache: true,\n                timeout: 10000,\n                data: {\n                    'sku': productSku\n                },\n                dataType: 'json',\n                success: function (response) {\n                    $('#product_crosssell_section').replaceWith(response.html);\n                    $('.product-crosssell-container').removeClass('ajax-refresh');\n                    if (!$('#product_crosssell_section').children().length) {\n                        $('#product_crosssell_section').addClass('d-none');\n                    }\n                },\n                error: function (xhr, status, error) {\n                    console.error(error);\n                }\n            });\n        }\n    };\n});\n\nrequire(['Goyard_Catalog/js/product_page/change_crosssell'], function (changeCrosssell) {\n    changeCrosssell.init(
2);\n});\n","Goyard_Catalog/js/product_page/handler-swatchcolor.js":"/**\n * Copyright Goyard Orkester\n * @author Orkester\n * @copyright Goyard\n */\n\ndefine('Goyard_Catalog/js/product_page/handler-swatchcolor', [\n    'jquery',\n    'Goyard_Wishlist/js/check-customer-wishlist',\n    'Goyard_Wishlist/js/front-injector',\n    'Goyard_Catalog/js/customer_logged_status',\n], function (\n    $,\n    customerWishlist,\n    frontInjector,\n    customerLoggedStatus,\n) {\n    'use strict';\n\n    const eventCatcherProduct = {\n        init: function () {\n            let swatchInitCount = 0;\n            const totalSwatches = $('.swatch-attribute').length;\n            let jsonConfig = null;\n\n            $('body').on('swatch.initialized', function (event, data) {\n                swatchInitCount++;\n                jsonConfig = data.swatchThis.options.jsonConfig;\n\n                // D\u00e9clenche l'observateur taille & mati\u00e8re une seule fois\n                if (swatchInitCount === 1) {\n                    eventCatcherProduct.watchAttSizeChange(jsonConfig);\n                    eventCatcherProduct.watchAttJewelryChange(jsonConfig);\n                }\n\n                // Quand TOUS les swatches sont pr\u00eats \u2192 on ex\u00e9cute selectVariantFromHash\n                if (swatchInitCount >= totalSwatches) {\n                    eventCatcherProduct.handleInitialSwatchState(data.swatchThis);\n                }\n            });\n\n            document.addEventListener(\"swatchOptionClickedOnProductPage\", function (event) {\n                let sku = event.detail.element.data('option-sku');\n                eventCatcherProduct.onSwatchOptionClick(sku, jsonConfig);\n            });\n\n            if ($('div.fotorama').length > 0) {\n                $(document).trigger(\"swatch_reloaded\");\n            }\n        },\n\n        /**\n         * Observe les changements de s\u00e9lection sur l\u2019attribut \u201cjewelry\u201d\n         * et d\u00e9clenche un event d\u00e8s que la s\u00e9lection change.\n         * @param {Object} jsonConfig - Configuration produit Magento (jsonConfig)\n         */\n        watchAttJewelryChange: function (jsonConfig) {\n            const $swatch = $('.swatch-attribute.att_jewelry');\n            const skuMap = jsonConfig.sku;\n            const indexMap = jsonConfig.index;\n\n            if (!$swatch.length) return;\n\n            // \ud83d\udd0d MutationObserver pour d\u00e9tecter le changement de data-option-selected\n            const observer = new MutationObserver(function (mutations) {\n                mutations.forEach(function (mutation) {\n                    if (mutation.type === 'attributes' && mutation.attributeName === 'data-option-selected') {\n                        const newSku = eventCatcherProduct.getSelectedJewelrySku(indexMap, skuMap, $swatch, \"567\");\n\n                        if (newSku) {\n                            eventCatcherProduct.updateUrlSku(newSku);\n                            eventCatcherProduct.createAndDispatchEvent(newSku);\n                        }\n                    }\n                });\n            });\n\n            observer.observe($swatch[0], { attributes: true });\n        },\n\n        /**\n         * R\u00e9cup\u00e8re le SKU correspondant \u00e0 la mati\u00e8re actuellement s\u00e9lectionn\u00e9e\n         * @param {Object} indexMap - jsonConfig.index\n         * @param {Object} skuMap - jsonConfig.sku\n         * @param {jQuery} $swatch - \u00c9l\u00e9ment .swatch-attribute.att_jewelry\n         * @param {String} jewelryAttrId - ID d\u2019attribut pour la bijouterie (ex: \"567\")\n         * @returns {String|null} - SKU trouv\u00e9 ou null si aucun ou si pas configur\u00e9\n         */\n        getSelectedJewelrySku: function (indexMap, skuMap, $swatch, jewelryAttrId) {\n            if (!indexMap || !skuMap) return null;\n            if (!$swatch || !$swatch.length) return null;\n\n            const selectedOption = $swatch.attr('data-option-selected');\n            if (!selectedOption) return null;\n\n            let foundKey = null;\n            for (const [key, attrs] of Object.entries(indexMap)) {\n                if (attrs[jewelryAttrId] && attrs[jewelryAttrId] === selectedOption) {\n                    foundKey = key;\n                    break;\n                }\n            }\n\n            if (!foundKey) return null;\n\n            const newSku = skuMap[foundKey] || null;\n            return newSku;\n        },\n\n        /**\n         * S\u00e9lectionne automatiquement la mati\u00e8re c
2orrespondant au SKU donn\u00e9.\n         * @param {String} sku - SKU actuel\n         * @param {Object} jsonConfig - Configuration produit (jsonConfig)\n         */\n        selectJewelryFromSku: function (sku, jsonConfig) {\n            if (!sku || !jsonConfig || !jsonConfig.index) return;\n\n            const indexMap = jsonConfig.index;\n            const skuMap = jsonConfig.sku;\n            const $jewelrySelect = $('.swatch-select.att_jewelry');\n\n            if (!$jewelrySelect.length) return;\n\n            const productId = Object.keys(skuMap).find(key => skuMap[key] === sku);\n            if (!productId || !indexMap[productId]) return;\n\n            const jewelryAttrId = Object.keys(indexMap[productId]).find(attrId => {\n                return $('.swatch-select.att_jewelry[data-attribute-id=\"' + attrId + '\"]').length > 0\n                    || $('.swatch-attribute.att_jewelry[data-attribute-id=\"' + attrId + '\"]').length > 0;\n            });\n\n            if (jewelryAttrId === undefined) return;\n\n            const jewelryOptionId = indexMap[productId][jewelryAttrId];\n            if (!jewelryOptionId) return;\n\n            const $targetOption = $jewelrySelect.find(`option[data-option-id=\"${jewelryOptionId}\"]`);\n            if ($targetOption.length) {\n                $jewelrySelect.val(jewelryOptionId);\n            }\n        },\n\n\n        watchAttSizeChange: function (jsonConfig) {\n\n            const $swatch = $('.swatch-attribute.att_size');\n            const skuMap = jsonConfig.sku;\n            const indexMap = jsonConfig.index;\n\n            if (!$swatch.length) return;\n\n            // MutationObserver pour d\u00e9tecter le changement de data-option-selected\n            const observer = new MutationObserver(function (mutations) {\n                mutations.forEach(function (mutation) {\n                    if (mutation.type === 'attributes' && mutation.attributeName === 'data-option-selected') {\n                        const newSku = eventCatcherProduct.getSelectedSizeSku(indexMap, skuMap, $swatch, \"602\");\n\n                        if (newSku) {\n                            eventCatcherProduct.updateUrlSku(newSku);\n                            eventCatcherProduct.createAndDispatchEvent(newSku);\n                        }\n                    }\n                });\n            });\n\n            observer.observe($swatch[0], { attributes: true });\n        },\n\n        /**\n         * R\u00e9cup\u00e8re le SKU correspondant \u00e0 la taille actuellement s\u00e9lectionn\u00e9e (si applicable)\n         * @param {Object} indexMap - jsonConfig.index\n         * @param {Object} skuMap - jsonConfig.sku\n         * @param {jQuery} $swatch - \u00c9l\u00e9ment .swatch-attribute.att_size\n         * @param {String} sizeAttrId - ID d'attribut de la taille (ex: \"602\")\n         * @returns {String|null} - SKU trouv\u00e9 ou null si aucun ou si pas de taille configur\u00e9e\n         */\n        getSelectedSizeSku: function (indexMap, skuMap, $swatch, sizeAttrId) {\n            // \ud83e\udde9 V\u00e9rifie si les structures de donn\u00e9es existent\n            if (!indexMap || !skuMap) {\n                return null;\n            }\n\n            // \ud83e\udde9 V\u00e9rifie si le swatch \"taille\" existe sur la page\n            if (!$swatch || !$swatch.length) {\n                return null;\n            }\n\n            const selectedOption = $swatch.attr('data-option-selected');\n            if (!selectedOption) {\n                return null;\n            }\n\n            let foundKey = null;\n            for (const [key, attrs] of Object.entries(indexMap)) {\n                if (attrs[sizeAttrId] && attrs[sizeAttrId] === selectedOption) {\n                    foundKey = key;\n                    break;\n                }\n            }\n\n            if (!foundKey) {\n                return null;\n            }\n\n            const newSku = skuMap[foundKey] || null;\n\n            return newSku;\n        },\n\n        /**\n         * S\u00e9lectionne automatiquement la taille correspondant au SKU donn\u00e9.\n         * @param {String} sku - SKU actuel (ex: celui de la couleur s\u00e9lectionn\u00e9e)\n         * @param {Object} jsonConfig - Configuration Magento (jsonConfig)\n         */\n        selectSizeFromSku: function (sku, jsonConfig) {\n            if (!sku || !jsonConfig || !jsonConfig.index) return;\n\n            const indexMap = jsonConfig.index;\n            const skuMap = jsonConfig.sku;\n            const $sizeSelect = $('.swatch-select.att_size');\n\n            if (!$sizeSelect.length) {\n                return;\n            }\n\n            const productId = Object.keys(skuMap).find(key => skuMap[key] === sku);\n            if (!productId || !indexMap[productId]) return;\n\n            const sizeAttrId = Object.keys(indexMap[productId]).find(attrId =>
2 {\n                return $('.swatch-select.att_size[data-attribute-id=\"' + attrId + '\"]').length > 0\n                    || $('.swatch-attribute.att_size[data-attribute-id=\"' + attrId + '\"]').length > 0;\n            });\n\n            if (sizeAttrId === undefined) {\n                return;\n            }\n\n            const sizeOptionId = indexMap[productId][sizeAttrId];\n            if (!sizeOptionId) {\n                return;\n            }\n\n            const $targetOption = $sizeSelect.find(`option[data-option-id=\"${sizeOptionId}\"]`);\n            if ($targetOption.length) {\n\n                $sizeSelect.val(sizeOptionId);\n            }\n        },\n\n        createAndDispatchEvent: function (sku) {\n            // Cr\u00e9er et diffuser un \u00e9v\u00e9nement personnalis\u00e9 avec les valeurs r\u00e9cup\u00e9r\u00e9es\n            let swatchOptionClicked = new CustomEvent('swatchOptionClicked', {\n                detail: {\n                    optionSku: sku\n                }\n            });\n\n            document.dispatchEvent(swatchOptionClicked);\n        },\n\n        onSwatchOptionClick: function (sku, jsonConfig) {\n            //update url hash in product page\n            this.updateUrlSku(sku);\n\n            this.createAndDispatchEvent(sku);\n\n            $('.swatch-option.selected').data('option-sku', sku);\n\n            if (jsonConfig) {\n                this.selectSizeFromSku(sku, jsonConfig);\n            }\n\n            // Update Wishlist star\n            this.updateWishlistStar(sku);\n        },\n\n        handleInitialSwatchState: function (swatchThis) {\n            try {\n                if (!this.isValidSwatchContext(swatchThis)) return;\n\n                const $element = $(swatchThis.element);\n                const config = swatchThis.options.jsonConfig;\n\n                if (window.location.hash) {\n                    this.selectVariantFromHash($element, config);\n                } else {\n                    this.selectDefaultVariant($element);\n                }\n\n                // Final UI/application tasks\n                this.removeSpinner();\n                this.setupAccessibilityEvents(swatchThis);\n                this.updatePrice(swatchThis);\n\n            } catch (error) {\n                console.error('Error dans handleInitialSwatchState :', error);\n                this.removeSpinner();\n            }\n        },\n\n        isValidSwatchContext: function (swatchThis) {\n            if (!swatchThis || !swatchThis.element || !swatchThis.options || !swatchThis.options.jsonConfig) {\n                console.error('swatchThis is invalid or missing required properties');\n                return false;\n            }\n            return true;\n        },\n\n        selectVariantFromHash: function ($element, config) {\n            const variant = window.location.hash.slice(1).replace('/', '');\n            const attributeCouleurId = $element.find('.swatch-attribute.couleur').attr('data-attribute-id');\n\n            if (!attributeCouleurId) {\n                console.error('swatch-attribute \"couleur\" not found');\n                return;\n            }\n\n            const attributes = config.attributes || [];\n            const attribute_couleur = attributes.find(attr => attr.id == attributeCouleurId);\n\n            if (!attribute_couleur) {\n                console.error('attribute \"' + attributeCouleurId + '\" not found');\n                return;\n            }\n\n            for (const [productId, sku] of Object.entries(config.sku)) {\n                if (variant === sku) {\n                    for (const attribute of attributes) {\n                        const option = attribute.options.find(opt => opt.products.includes(productId));\n                        if (!option) continue;\n\n                        const optionEl = $element.find(`.swatch-option[data-option-id=\"${option.id}\"]`);\n                        if (optionEl.length > 0) {\n                            optionEl.click();\n                        } else {\n                            $(`option[data-option-id=\"${option.id}\"]`).parent().val(option.id).trigger(\"change\");\n                        }\n                    }\n                }\n            }\n        },\n\n        selectDefaultVariant: function ($element) {\n            const mainVariantId = $element.parents('.product-options-wrapper-container').attr('data-main-variant-option-id');\n            if (mainVariantId) {\n                const defaultOption = $element.find(`.swatch-option[data-option-id=\"${mainVariantId}\"]`);\n                if (defaultOption.length) {\n                    defaultOption.click();\n                }\n            }\n        },\n\n        removeSpinner: function () {\n            $(\"#spinner-product-view\").remove();\n        },\n\n        setupAccessibilityEvents: function (swatchThis) {\n            // Accessibility focus and ke
2yboard navigation\n            const $colorOptions = $(swatchThis.element).find('.couleur .swatch-attribute-options');\n\n            $colorOptions.each(function () {\n                const selectedOptionId = $(this).find('[aria-selected=\"true\"]')?.attr('id') ?? '';\n                $(this).attr('aria-activedescendant', selectedOptionId)\n            })\n            $colorOptions.off('focus blur keydown');\n            $colorOptions.on('focus blur', swatchThis.setupFocus.bind(swatchThis));\n            $colorOptions.on('keydown', swatchThis.throughSwatchOptions.bind(swatchThis));\n\n            // Add border for contrast accessibility\n            $('.swatch-option').on('click', function () {\n                $('.swatch-option').removeClass('borderBlue');\n                if ($.mage.cookies.get('accessibility_mode_constrast') === \"true\") {\n                    $(this).addClass('borderBlue');\n                }\n            });\n\n            // Remove border on click outside swatch\n            $(document).on('click', function (event) {\n                if (!$(event.target).closest('.swatch-option').length) {\n                    $(\".swatch-option\").removeClass('borderBlue');\n                }\n            });\n        },\n\n        updatePrice: function (swatchThis) {\n            if ($('.catalog-product-view').length > 0) {\n                customerLoggedStatus.getIsCustomerLoggedIn().then((customer) => {\n                    const price = swatchThis._getNewPrices?.();\n                    const selectedOptionSku = $('.swatch-attribute-options .swatch-option.selected').data('optionSku');\n\n                    if (\n                        price?.finalPrice?.amount > 0 &&\n                        customer?.firstname &&\n                        swatchThis.options.priceDisplay?.[selectedOptionSku]\n                    ) {\n                        $(\".product-info-main .product-info-price\").show();\n                    } else {\n                        $(\".product-info-main .product-info-price\").hide();\n                    }\n                });\n            }\n        },\n\n        /**\n        Update URl sku after # in product page when changing color\n        */\n        updateUrlSku: function (newSku) {\n            const baseUrl = window.location.href.split('#')[0];\n            const updatedUrl = `${baseUrl}#${newSku}`;\n\n            window.history.replaceState({}, document.title, updatedUrl);\n        },\n\n        /**\n        Update Wishlist star\n        */\n        updateWishlistStar: function (sku) {\n            if (customerLoggedStatus.getCustomer()?.firstname && $('#add-to-wishlist').length) {\n                customerWishlist.checkIfAlreadyInWishlist(sku).then(function (data) {\
2n                    frontInjector.injectSvg(data.status);\n                });\n            } else {\n                frontInjector.injectSvg(false);\n            }\n        },\n    };\n\n    return eventCatcherProduct;\n});\n\nrequire(['Goyard_Catalog/js/product_page/handler-swatchcolor'], function (eventCatcherProduct) {\n    eventCatcherProduct.init();\n});","Goyard_Catalog/js/product_page/video_personalization.js":"define(['jquery', 'Goyard_Catalog/js/video-playback', 'mage/cookies'], function ($, videoPlayback) {\n    var videoPersonalization = {\n        init: function() {\n            $(document).ready(function () {\n                const playBtn = \"<button type='button' class='video-play-button play-on' aria-label='Pause'><div class='inner-button'></div></button>\";\n        \n                let personalization_video = $('.personalization-video-right .pagebuilder-video-container video');\n        \n                personalization_video.each(function () {\n                    $(this).removeAttr('controls');\n                    $(this).closest('.pagebuilder-video-wrapper').append(playBtn);\n        \n                    if ($(window).width() >= 768) {\n                        $(this).prop('autoplay', true).prop('muted', true).prop('loop', true);\n                        videoPlayback.play(this);\n                    }\n                });\n        \n                function loadVideo(video) {\n                    if (window.innerWidth < 768) {\n                        let source = $(video).parent().data('source-mobile');\n                        if (source) {\n                            video.src = source;\n                            video.load();\n                        }\n                    } else {\n                        let source = $(video).parent().data('source-desktop');\n                        if (source) {\n                            video.src = source;\n                            video.load();\n                        }\n                    }\n                }\n        \n                function loadFallBackImage(video) {\n                    if (window.innerWidth < 768) {\n                        let source = $(video).parent().data('fallback-mobile');\n                        if (source) {\n                            video.poster = source;\n                        }\n                    } else {\n                        let source = $(video).parent().data('fallback-desktop');\n                        if (source) {\n                            video.poster = source;\n                        }\n                    }\n                }\n        \n                function isStoppedAnimationInCookies() {\n                    let isAnimationMode = $.mage.cookies.get('accessibility_mode_animation') === \"true\";\n                    if (isAnimationMode) {\n                        personalization_video.each(function () {\n                            videoPlayback.pause(this);\n                            $(this).closest('.pagebuilder-video-wrapper').find('.video-play-button').attr('aria-label', 'Play');\n                        });\n                    }\n                }\n        \n                function reduceAnimation() {\n                    document.addEventListener(\"reductAnimation\", (event) => {\n                        if (event.detail.animation === true) {\n                            personalization_video.each(function () {\n                                videoPlayback.pause(this);\n                                $(this).closest('.pagebuilder-video-wrapper').find('.video-play-button').attr('aria-label', 'Play');\n                            });\n                        } else {\n                            personalization_video.each(function () {\n                                videoPlayback.play(this);\n                                $(this).closest('.pagebuilder-video-wrapper').find('.video-play-button').attr('aria-label', 'Pause');\n                            });\n                        }\n                    });\n                }\n        \n                let observer = new IntersectionObserver(function (entries, observer) {\n                    entr
2ies.forEach(function (entry) {\n                        if (entry.isIntersecting) {\n                            let video = entry.target.querySelector('video');\n                            loadFallBackImage(video);\n                            loadVideo(video);\n                            observer.unobserve(entry.target);\n                        }\n                    });\n                });\n        \n                let videos = document.querySelectorAll('.pagebuilder-video-wrapper');\n                videos.forEach(function (video) {\n                    observer.observe(video);\n                });\n        \n                isStoppedAnimationInCookies();\n                reduceAnimation();\n            });\n        }\n    };\n    return videoPersonalization;\n});\n","Goyard_Catalog/js/product_page/change_all_about.js":"/**\n * Copyright Goyard Orkester\n * @author Orkester\n * @copyright Goyard\n */\ndefine([\n\t'jquery',\n\t'mage/url',\n\t'Magento_Ui/js/modal/modal',\n\t'Goyard_Catalog/js/customer_logged_status'\n], function ($, urlBuilder, modal, customerLoggedStatus) {\n\t'use strict';\n\n\t$(document).on('click', '.accordion-trigger', function () {\n\t\tlet $content = $('.' + $(this).attr('aria-controls'));\n\t\tvar wasOpen = $(this).attr('aria-expanded') === 'true';\n\n\t\t$(this).attr('aria-expanded', !wasOpen);\n\t\tif (!wasOpen) {\n\t\t\t$content.addClass('show');\n\t\t} else {\n\t\t\t$content.removeClass('show');\n\t\t}\n\t});\n\n\t// \u00c9coute l'\u00e9v\u00e9nement personnalis\u00e9 \"swatchOptionClicked\"\n\tdocument.addEventListener('swatchOptionClicked', (event) => {\n\t\tconst productSku = event.detail.optionSku; // R\u00e9cup\u00e8re SKU depuis l'\u00e9v\u00e9nement\n\t\tchangeAllAbout(productSku); // Appelle la fonction changeAllAbout avec SKU\n\t});\n\n\tcheckIfUserIsLogged();\n\n\tlet options = {\n\t\tresponsive: true,\n\t\tinnerScroll: true,\n\t\tmodalClass: 'right-side-modal product-info-layer-modal',\n\t\toverlayClass: 'product-modal-overlay',\n\t\tbuttons: []\n\t};\n\t// Manage modals\n\tif (window.innerWidth >= 768) {\n\t\tlet modal_details = $('.product-info-details-layer');\n\t\tif (modal_details.length) {\n\t\t\tlet popup_details = modal(options, modal_details);\n\t\t\topenLayerModal(modal_details, '.product-info-details-layer-title')\n\t\t}\n\n\t\tlet modal_shipping = $('.product-info-shipping-layer');\n\t\tif (modal_shipping.length) {\n\t\t\tlet popup_shipping = modal(options, modal_shipping);\n\t\t\topenLayerModal(modal_shipping, '.product-info-shipping-layer-title')\n\t\t}\n\n\t\tlet modal_care = $('.product-info-care-layer');\n\t\tif (modal_care.length) {\n\t\t\tlet popup_care = modal(options, modal_care);\n\t\t\topenLayerModal(modal_care, '.product-info-care-layer-title')\n\t\t}\n\t}\n\n\tlet modal_size_guide = $('.product-size-guide');\n\tif (modal_size_guide.length) {\n\t\tlet popup_size_guide = modal(options, modal_size_guide);\n\t\topenLayerModal(modal_size_guide, '.product-size-guide-cta')\n\t}\n\n\t// Update product details section\n\tfunction changeAllAbout(productSku) {\n\t\tlet self = this;\n\t\tlet url = urlBuilder.build('goyard_catalog/ajax/productAllDetails');\n\t\tconst isMobile = window.innerWidth >= 768 ? false : true;\n\n\t\tif (isMobile) {\n\t\t\turl = urlBuilder.build('goyard_catalog/ajax/productAllDetailsLayers');\n\t\t}\n\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: 'GET',\n\t\t\tcache: true,\n\t\t\ttimeout: 10000,\n\t\t\tdata: {\n\t\t\t\t'sku': productSku,\n\t\t\t},\n\t\t\tdataType: 'json',\n\t\t\tsuccess: function (response) {\n\t\t\t\tlet featureContainer = $(response.html).filter('.product-feature-container').html();\n\n\t\t\t\t$('.product-feature-container').html(featureContainer);\n\t\t\t\t$('.product-feature-container').append(response.contact);\n\n\t\t\t\t// Update content of modals\n\t\t\t\tif (!isMobile) {\n\t\t\t\t\tlet detailsModalContent = $(response.html).filter('.product-info-details-layer').html();\n\t\t\t\t\tlet shippingModalContent = $(response.html).filter('.product-info-shipping-layer').html();\n\t\t\t\t\tlet careModalContent = $(response.html).filter('.product-info-care-layer').html();\n\n\t\t\t\t\t$('.modal-content >
2.product-info-details-layer').html(detailsModalContent);\n\t\t\t\t\t$('.modal-content >.product-info-shipping-layer').html(shippingModalContent);\n\t\t\t\t\t$('.modal-content >.product-info-care-layer').html(careModalContent);\n\t\t\t\t}\n\n\t\t\t\t// Remove layers if customer's not logged in\n\t\t\t\tif (!customerLoggedStatus.getCustomer().firstname) {\n\t\t\t\t\t$('.product-info-shipping-layer-title').remove();\n\t\t\t\t\t$('.product-info-shipping-layer').remove();\n\t\t\t\t}\n\n\t\t\t\t// Display contact button depending on add to cart button\n\t\t\t\tif ($('#add-to-cart-container').children().length) {\n\t\t\t\t\t$('.product-contact-container').addClass('d-none');\n\t\t\t\t} else {\n\t\t\t\t\t$('.product-contact-container').removeClass('d-none');\n\t\t\t\t}\n\n\t\t\t\t$('.product-feature-container').removeClass('disable');\n\t\t\t},\n\t\t\terror: function (xhr, status, error) {\n\t\t\t\tconsole.error('changeAllAboutThisProduct : ' + error);\n\t\t\t}\n\t\t});\n\t}\n\n\tfunction checkIfUserIsLogged() {\n\t\tcustomerLoggedStatus.getIsCustomerLoggedIn().then(function (customer) {\n\t\t\tvar cacheStorage = JSON.parse(localStorage.getItem('mage-cache-storage') || 'null');\n\n\t\t\tif (customer?.firstname || cacheStorage?.customer?.firstname) {\n\t\t\t\t$('.product-info-shipping-layer-title').show();\n\t\t\t\t$('.product-info-shipping-layer-title').show();\n\n\t\t\t} else {\n\t\t\t\t$('.product-info-shipping-layer-title').hide();\n\t\t\t\t$('.product-info-shipping-layer-title').hide();\n\t\t\t}\n\t\t});\n\t}\n\n\t// Open product layer modal and set its height\n\tfunction openLayerModal(modal, title) {\n\t\t$(document).on('click', title, function () {\n\t\t\t$('html, body').animate({ scrollTop: 0 });\n\t\t\t$('.product-info-layer-modal').find('.modal-inner-wrap')?.css({ 'maxHeight': $('.product-info-top').innerHeight() + 'px' });\n\t\t\tmodal.modal('openModal');\n\t\t});\n\t}\n});\n","Goyard_Catalog/js/product_page/contact_modal.js":"require([\n\t'jquery',\n\t'Magento_Ui/js/modal/modal'\n], function ($, modal) {\n\tlet options = {\n\t\ttype: 'popup',\n\t\tresponsive: true,\n\t\tinnerScroll: true,\n\t\ttitle: '',\n\t\tmodalClass: 'right-side-modal product-info-layer-modal',\n\t\toverlayClass: 'product-modal-overlay',\n\t\tbuttons: []\n\t};\n\n\tlet modal_element = $('#product-info-contact-modal');\n\tif (modal_element.length) {\n\t\tlet popup_contact = modal(options, modal_element);\n\t}\n\n\tlet autocompleteAdded = false;\n\n\t// Open product layer modal and set its height\n\t$(document).on('click', '.product-info-contact-layer-title, #product-contact-cta', function (e) {\n\n\t\tif (!autocompleteAdded) {\n\t\t\t$('[id*=\"amform-form-\"]').find('[class*=\"ac-\"]').each(function () {\n\t\t\t\tvar autocompleteClass = $(this).attr('class').match(/(?:^|\\s)ac-((\\w|\\-)+)/)?.[1];\n\t\t\t\t$(this).attr('autocomplete', autocompleteClass);\n\t\t\t});\n\t\t\tautocompleteAdded = true;\n\t\t}\n\n\t\tif ($(window).width() > 768) {\n\t\t\t$('.product-info-layer-modal').find('.modal-inner-wrap')?.css({ 'maxHeight': $('.product-info-top').innerHeight() + 'px' });\n\t\t}\n\t\tif (!($(window).width() < 768 && $(e.currentTarget).hasClass('product-info-contact-layer-title'))) {\n\t\t\t$('html, body').animate({ scrollTop: 0 });\n\t\t\tmodal_element.modal('openModal');\n\t\t\tif (typeof mtcaptchaConfig !== 'undefined' && modal_element.find('.mtcaptcha').length) {\n\t\t\t\tmtcaptchaConfig.renderQueue.push(\"mtcaptcha\");\n\t\t\t}\n\t\t}\n\n\t\tif ($(\".swatch-option.selected\").length > 0) {\n\t\t\tlet sku_product = window.location.hash.substring(1);\n\t\t\t$('#product-info-contact-modal').find('input[name=\"product\"').attr(\"value\", sku_product);\n\t\t}\n\t});\n\n\tlet modalKeyboard = false;\n\t$(document).on('keydown', function (event) {\n\t\tif ((event.keyCode === 13 || event.code == \"Space\") && $('#product-contact-cta').is(':focus')) {\n\t\t\tmodalKeyboard = true;\n\t\t}\n\t});\n\n\t$('.modal-header .action-close').on('focus', function () {\n\t\tif (modalKeyboard) {\n\t\t\t$(this).addClass('close-focus');\n\t\t}\n\t});\n\n\t$('.modal-header .action-close').on('blur', function () {\n\t\t$(this).removeClass('close-focus');\n\t});\n\n\t$('#product-contact-cta').on('mousedown', function () {\n\t\tmodalKeyboard = false;\n\t});\n});","Goyard_Catalog/js/product_page/video_wearing.js":"define(['jquery', 'Goyard_Catalog/js/video-playback', 'slick', 'mage/cookies'], function ($, videoPlayback) {\n    var videoWearing = {\n        init: function(){\n            $(document).ready(function () {\n                const playBtn = \"<button type='button' class='video-play-button play-on' aria-label='Pause'><div class='inner-button'></div></button>\";\n\n                // Ajoute le bouton play/pause \u00e0 chaque vid\u00e9o\n                $('.video-wrapper').each(function () {\n                    $(this).append(playBtn);\n                });\n\n                // V\u00e9rifie si l'animation est r\u00e9duite dans les cookies\n                function isAnimationReduced() {\n                    return $.mage.cookies.get('accessibility_mode_animation') === \"true\";\n                }\n\n                // Initialisation du slider Slick\n                $('.video-section').slick({\n                    dots: true,\n                    autoplay: false,\n                    initialSlide: 0,\n                    slidesToShow: 1,\n                    infinite: true,\n                    responsive: [\n                        {\n                            breakpoint: 1600,\n                            settings: {\n                                slidesToShow: 1,\n                            }\n                        },\n                        {\n                            breakpoint: 768,\n                            settings: {\n                                dots: true,\n                                slidesToShow: 1\n                            }\n                        }\n                    ]\n                });\n\n                // Fonction pour charger la source de la vid\u00e9o (adapt\u00e9e avec v\u00e9rification)\n                function loadVideoSource(video) {\n                    if (!video.src) {\n                        if (window.innerWidth < 768) {\n                            let source = $(video).parent().data('source-mobile');\n                            if (source) {\n                                video.src = source;\n                                video.load(); // Charger la vid\u00e9o avec la nouvelle source\n                                videoPlayback.pause(video);\n                            }\n                        } else {\n                            let source = $(video).parent().data('source-desktop');\n                            if (source) {\n                                video.src = source;\n                                video.load(); // Charger la vid\u00e9o avec la nouvelle source\n                                videoPlayback.pause(video);\n                            }\n                        }\n                    }\n                }\n\n                // Fonction pour g\u00e9rer l'\u00e9tat du bouton Play/Pause\n                function togglePlayPauseButton(video) {\n                    let button = $(video).parent().find('.video-play-button');\n                    if (video.paused) {\n                        button.removeClass('play-on').addClass('play-off').attr('aria-label', 'Play');\n                    } else {\n                        button.removeClass('play-off').addClass('play-on').attr('aria-label', 'Pause');\n                    }\n                }\n\n                // Gestion du clic sur le bouton Play/Pause\n                $(document).on('click', '.video-play-button', function () {\n                    let video = $(this).parent().find('video').get(0);\n                    loadVideoSource(video); // Charger la source si elle n'est pas encore d\u00e9finie\n\n                    if ($(this).hasClass('play-on')) {\n                        $(this).removeClass('play-on').addClass('play-off').attr('aria-label', 'Play');\n                        videoPlayback.pause(video);\n                    } else {\n                        $(this).removeClass('play-off').addClass('play-on').attr('aria-label', 'Pause');\n                        videoPlayback.play(video).then(function (isPlaying) {\n                            // Lecture bloqu\u
200e9e par le navigateur : on remet le bouton sur \"Play\"\n                            if (!isPlaying) {\n                                togglePlayPauseButton(video);\n                            }\n                        });\n                    }\n                });\n\n                // Fonction pour g\u00e9rer la visibilit\u00e9 de la vid\u00e9o et jouer/mettre en pause en fonction\n                function handleVideoVisibilityWithObserver() {\n                    // S\u00e9lectionner toutes les vid\u00e9os dans la section \"how-to-wear\"\n                    $('#how-to-wear-section .slick-active .video-wrapper video').each(function () {\n                        let videoElement = $(this)[0];\n                        loadVideoSource(videoElement);\n\n                        // Cr\u00e9er un nouvel observer pour observer les vid\u00e9os\n                        const observer = new IntersectionObserver(\n                            (entries) => {\n                                entries.forEach((entry) => {\n                                    if (entry.isIntersecting && entry.intersectionRatio >= 0.5) {\n                                        // Si la vid\u00e9o est visible \u00e0 au moins 50%, jouer la vid\u00e9o\n                                        if (videoElement.paused && !$('body').hasClass('accessibility_mode_animation')) {\n                                            loadVideoSource(videoElement); // Charger la source si n\u00e9cessaire\n                                            videoPlayback.play(videoElement).then(function () {\n                                                togglePlayPauseButton(videoElement); // Mettre \u00e0 jour le bouton\n                                            });\n                                        }\n                                    } else {\n                                        // Si la vid\u00e9o n'est pas assez visible, la mettre en pause\n                                        if (!videoElement.paused) {\n                                            videoPlayback.pause(videoElement).then(function () {\n                                                togglePlayPauseButton(videoElement); // Mettre \u00e0 jour le bouton\n                                            });\n                                        }\n                                    }\n                                });\n                            },\n                            {\n                                threshold: [0.5], // D\u00e9clencher quand 50% de la vid\u00e9o est visible\n                                root: null, // Utiliser la fen\u00eatre du navigateur comme racine\n                                rootMargin: '0px' // Pas de marge autour de la fen\u00eatre\n                            }\n                        );\n\n                        // D\u00e9marrer l'observation de la vid\u00e9o\n                        observer.observe(videoElement);\n                    });\n                }\n\n                // D\u00e9tecter le scroll et le redimensionnement pour v\u00e9rifier la visibilit\u00e9 des vid\u00e9os\n                $(window).on('scroll resize', handleVideoVisibilityWithObserver);\n\n                // Appel initial pour g\u00e9rer la visibilit\u00e9 des vid\u00e9os\n                handleVideoVisibilityWithObserver();\n\n\n                // Gestion des changements de slide dans le slider\n                $('.video-section').on('beforeChange', function (event, slick, currentSlide, nextSlide) {\n                    // Pause la vid\u00e9o sur l'ancienne slide\n                    let currentVideo = $(slick.$slides[currentSlide]).find('video').get(0);\n                    if (currentVideo) {\n                        videoPlayback.pause(currentVideo).then(function () {\n                            togglePlayPauseButton(currentVideo);\n                        });\n                    }\n\n                    // Si l'animation est r\u00e9duite, ne pas jouer la vid\u00e9o sur le slide suivant\n                    if (isAnimationReduced()) {\n                        return; // Emp\u00eache de jouer la vid\u00e9o du slide suivant\n                    }\n\n                    // Charger et jouer la vid\u00e9o sur la nouvelle slide\n                    let nextVideo = $(slick.$slides[nextSlide]).find('video').get(0);\n                    if (nextVideo) {\n                        loadVideoSource(nextVideo);\n                        videoPlayback.play(nextVideo).then(function () {\n                            togglePlayPauseButton(nextVideo);\n                        });\n                    }\n                });\n\n                // Fonction pour g\u00e9rer l'arr\u00eat de l'animation en fonction des cookies (accessibility_mode_animation)\n                function isStoppedAnimationInCookies() {\n                    let isAnimationMode = $.mage.cookies.get('accessibility_mode_animation') === \"true\";\n                    if (isAnimationMode) {\n                        $('.video-wrapper video').each(function () {\n                            videoPlayback.pause(this);\n                            $(this).closest('.pagebuilder-video-wrapper').find('.video-play-button')\n                                .removeClass('play-on')\n                                .addClass('play-off')\n                                .attr('aria-label', 'Play');\n                        });\n                    }\n                }\n\n                // Fonction pour r\u00e9duire l'animation (sur \u00e9v\u00e9nement custom)\n                function reduceAnimation() {\
2n                    document.addEventListener(\"reductAnimation\", (event) => {\n                        if (event.detail.animation === true) {\n                            $('.video-wrapper video').each(function () {\n                                videoPlayback.pause(this);\n                                $(this).closest('.pagebuilder-video-wrapper').find('.video-play-button')\n                                    .removeClass('play-on')\n                                    .addClass('play-off')\n                                    .attr('aria-label', 'Play');\n                            });\n                        } else {\n                            $('.video-wrapper video').each(function () {\n                                videoPlayback.play(this);\n                                $(this).closest('.pagebuilder-video-wrapper').find('.video-play-button')\n                                    .removeClass('play-off')\n                                    .addClass('play-on')\n                                    .attr('aria-label', 'Pause');\n                            });\n                        }\n                    });\n                }\n\n                // Appel initial pour v\u00e9rifier le mode d'animation\n                isStoppedAnimationInCookies();\n\n                // \u00c9coute les \u00e9v\u00e9nements de r\u00e9duction d'animation\n                reduceAnimation();\n\n                // G\u00e9rer les \u00e9v\u00e9nements de progression de la vid\u00e9o\n                $('.video-wrapper video').each(function () {\n                    var video = $(this)[0];\n                    // var progressBar = $(this).siblings('.progress-container').find('.progress-bar');\n\n                    // Met \u00e0 jour la barre de progression pendant la lecture\n                    // video.addEventListener('play', function () {\n                    //     requestAnimationFrame(function () {\n                    //         updateProgressBar(video, progressBar);\n                    //     });\n                    // });\n\n                    // R\u00e9initialise la barre de progression au d\u00e9but de la vid\u00e9o\n                    // video.addEventListener('started', function () {\n                    //     progressBar.css('width', '0%');\n                    // });\n\n                    // Met \u00e0 jour le bouton Play/Pause \u00e0 la fin de la vid\u00e9o\n                    video.addEventListener('ended', function () {\n                        $(video).parent().find('.video-play-button')\n                            .removeClass('play-on')\n                            .addClass('play-off')\n                            .attr('aria-label', 'Play');\n                    });\n                });\n\n                // Barre de progression pour les vid\u00e9os\n                // function updateProgressBar(video, progressBar) {\n                //     if (video.duration) {\n                //         var percentage = (video.currentTime / video.duration) * 100;\n                //         progressBar.css('width', percentage + '%');\n                //     }\n\n                //     if (!video.paused && !video.ended) {\n                //         requestAnimationFrame(function () {\n                //             updateProgressBar(video, progressBar);\n                //         });\n                //     }\n                // }\n            });\n        }\n    }\n    return videoWearing;\n});\n","Goyard_Catalog/js/product_page/change_art_of_marquage.js":"define('Goyard_Catalog/js/product_page/change_art_of_marquage', [\n    'jquery',\n    'mage/url'\n], function ($, urlBuilder) {\n    'use strict';\n\n    const urlArtOfMarquage = urlBuilder.build('goyard_catalog/ajax/artOfMarquage');\n\n    return {\n        init: function () {\n            document.addEventListener('swatchOptionClicked', (event) => {\n                const productSku = event.detail.optionSku;\n                this.changeArtOfMarquage(productSku);\n            });\n        },\n\n        changeArtOfMarquage: function (productSku) {\n            $('#product_artOfMarquage').addClass('ajax-refresh');\n            this.ajaxArtOfMarquage(productSku);\n        },\n\n        ajaxArtOfMarquage: function (productSku) {\n            $.ajax({\n                url: urlArtOfMarquage,\n                type: 'GET',\n                cache: true,\n                timeout: 10000,\n                data: {\n                    'sku': productSku\n                },\n                dataType: 'json',\n                success: function (response) {\n                    $('#product_artOfMarquage').replaceWith(response.html);\n                    $('#product_artOfMarquage').removeClass('ajax-refresh');\n                },\n                error: function (xhr, status, error) {\n                    console.error(error);\n                }\n            });\n        }\n    };\n});\n\n// Appel de l'initialisation imm\u00e9diatement apr\u00e8s la d\u00e9finition du module\nrequire(['Goyard_Catalog/js/product_page/change_art_of_marquage'], function (changeArtOfMarquage) {\n    changeArtOfMarquage.init(
2);\n});\n","Magento_ReCaptchaCheckout/js/webapiReCaptchaRegistry-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n    'use strict';\n\n    return function (originalFunction) {\n        /**\n         * {@inheritDoc}\n         */\n       originalFunction.addListener = function (id , func) {\n            this._listeners[id] = func;\n       };\n\n        return originalFunction;\n    };\n\n});\n","Magento_ReCaptchaCheckout/js/reCaptchaCheckout.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(\n    [\n        'Magento_ReCaptchaWebapiUi/js/webapiReCaptcha',\n        'jquery'\n    ],\n    function (Component, $) {\n        'use strict';\n\n        var reCaptchaIds = new WeakMap(),\n            uuid = 0;\n\n        return Component.extend({\n            defaults: {\n                template: 'Magento_ReCaptchaCheckout/reCaptcha',\n                skipPayments: [] // List of payment methods that do not require this reCaptcha\n            },\n\n            /**\n             * Render reCAPTCHA for payment method\n             *\n             * @param {Object} method\n             */\n            renderReCaptchaFor: function (method) {\n                var reCaptcha;\n\n                if (this.isCheckoutReCaptchaRequiredFor(method)) {\n                    reCaptcha = $.extend(true, {}, this, {reCaptchaId: this.getReCaptchaIdFor(method)});\n                    reCaptcha.renderReCaptcha();\n                }\n            },\n\n            /**\n             * Get reCAPTCHA ID for payment method\n             *\n             * @param {Object} method\n             * @returns {String}\n             */\n            getReCaptchaIdFor: function (method) {\n                if (!reCaptchaIds.has(method)) {\n                    reCaptchaIds.set(method, this.getReCaptchaId() + '-' + uuid++);\n                }\n                return reCaptchaIds.get(method);\n            },\n\n            /**\n             * Check whether checkout reCAPTCHA is required for payment method\n             *\n             * @param {Object} method\n             * @returns {Boolean}\n             */\n            isCheckoutReCaptchaRequiredFor: function (method) {\n                return !this.skipPayments || !this.skipPayments.hasOwnProperty(method.getCode());\n            },\n\n            /**\n             * @inheritdoc\n             */\n            initCaptcha: function () {\n                var $wrapper,\n                    $recaptchaResponseInput;\n\n                this._super();\n                // Since there will be multiple reCaptcha in the payment form,\n                // they may override each other if the form data is serialized and submitted.\n                // Instead, the reCaptcha response will be collected in the callback: reCaptchaCallback()\n                // and sent in the request header X-ReCaptcha\n                $wrapper = $('#' + this.getReCaptchaId() + '-wrapper');\n                $recaptchaResponseInput = $wrapper.find('[name=g-recaptcha-response]');\n                if ($recaptchaResponseInput.length) {\n                    $recaptchaResponseInput.prop('disabled', true);\n                }\n            }\n        });\n    }\n);\n","Magento_ReCaptchaCheckout/js/model/place-order-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* eslint-disable max-nested-callbacks */\n\ndefine([\n    'jquery',\n    'mage/utils/wrapper',\n    'Magento_ReCaptchaWebapiUi/js/webapiReCaptchaRegistry'\n], function ($, wrapper, recaptchaRegistry) {\n    'use strict';\n\n    return function (placeOrder) {\n        return wrapper.wrap(placeOrder, function (originalAction, serviceUrl, payload, messageContainer) {\n            var recaptchaDeferred,\n                reCaptchaId,\n                $activeReCaptcha;\n\n            $activeReCaptcha = $('.recaptcha-checkout-place-order:visible .g-recaptcha');\n\n            if ($activeReCaptcha.length > 0) {\n                reCaptchaId = $activeReCaptcha.last().attr('id');\n            }\n\n            if (reCaptchaId !== undefined && recaptchaRegistry.triggers.hasOwnProperty(reCaptchaId)) {\n                //ReCaptcha is present for checkout\n                recaptchaDeferred = $.Deferred();\n                recaptchaRegistry.addListener(reCaptchaId, function (token) {\n                    //Add reCaptcha value to place-order request and resolve deferred with the API call results\n                    payload.xReCaptchaValue = token;\n                    originalAction(serviceUrl, payload, messageContainer).done(function () {\n                        recaptchaDeferred.resolve.apply(recaptchaDeferred, arguments);\n                    }).fail(function () {\n                        recaptchaDeferred.reject.apply(recaptchaDeferred, arguments);\n                    });\n                });\n                //Trigger ReCaptcha validation\n                recaptchaRegistry.triggers[reCaptchaId]();\n\n                if (\n                    !recaptchaRegistry._isInvisibleType.hasOwnProperty(reCaptchaId) ||\n                    recaptchaRegistry._isInvisibleType[reCaptchaId] === false\n                ) {\n                    //remove listener so that place order action is only triggered by the 'Place Order' button\n                    recaptchaRegistry.removeListener(reCaptchaId);\n                }\n\n                return recaptchaDeferred;\n            }\n\n            //No ReCaptcha, just sending the request\n            return originalAction(serviceUrl, payload, messageContainer);\n        });\n    };\n});\n","Dnd_Core/js/panel.js":"/**\n * @package   Dnd\\Core\\view\n * @author    Agence Dn'D <[email protected]>\n * @copyright 2004-present Agence Dn'D\n * @license   https://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)\n * @link      https://www.dnd.fr/\n */\n\ndefine([\n  'jquery',\n  'dnd/core/utils/dom-parser',\n  'jquery/ui',\n  'domReady!',\n], function($, DomParser) {\n  'use strict';\n\n  $.widget('dnd.corePanel', {\n    options: {\n      closeAll: true,\n      openFirst: true,\n      onlyOneOpened: true,\n      eventPanelTrigger: 'click',\n      triggerSelector: '[data-role=dnd-panel-tr
2igger]',\n      contentSelector: '[data-role=dnd-panel-content]',\n      iconSelector: '[data-role=dnd-panel-icon]',\n      iconPanelOpenedClass: 'icon-angle-up',\n      iconPanelClosedClass: 'icon-angle-down',\n      activeClass: 'open',\n      stateDataKey: 'state',\n      indexDataKey: 'panel-index',\n      openedStateValue: 'opened',\n      closedStateValue: 'closed',\n      eventSelector: 'body',\n    },\n    privateOptions: {\n      eventPanelOpen: 'dndCorePanel:open',\n      eventPanelClose: 'dndCorePanel:close',\n    },\n    defaultIndex: 0,\n    currentIndex: 0,\n    /**\n     * Plugin init function\n     *\n     * @private\n     */\n    _create: function() {\n      this._applyStates();\n      this._initializeEvents();\n\n      if (this.options.closeAll) {\n        this._closeAll();\n      }\n      if (this.options.openFirst) {\n        this._openFirst();\n      }\n\n    },\n    /**\n     * Initialize all events\n     *\n     * @private\n     */\n    _initializeEvents: function() {\n      $(this.options.eventSelector).\n        on(this.options.eventPanelTrigger, this.options.triggerSelector,\n          $.proxy(this._triggerPanel, this));\n      $(this.options.eventSelector).\n        on(this.privateOptions.eventPanelOpen,\n          $.proxy(this._togglePanelOpenedClass, this));\n      $(this.options.eventSelector).\n        on(this.privateOptions.eventPanelClose,\n          $.proxy(this._togglePanelClosedClass, this));\n      $(this.options.eventSelector).\n        on(this.privateOptions.eventPanelOpen,\n          $.proxy(this._togglePanelOpenedIconClass, this));\n      $(this.options.eventSelector).\n        on(this.privateOptions.eventPanelClose,\n          $.proxy(this._togglePanelClosedIconClass, this));\n      $(this.options.eventSelector).\n        on(this.privateOptions.eventPanelOpen,\n          $.proxy(this._togglePanelOpenedState, this));\n      $(this.options.eventSelector).\n        on(this.privateOptions.eventPanelClose,\n          $.proxy(this._togglePanelClosedState, this));\n      $(this.options.eventSelector).\n        on(this.privateOptions.eventPanelOpen,\n          $.proxy(this._togglePanelOpenedState, this));\n    },\n    /**\n     * @private\n     */\n    _applyStates: function() {\n      var triggers = this._getTriggers();\n      var self = this;\n      var index = this.defaultIndex;\n\n      triggers.map(function(index, trigger) {\n        trigger = $(trigger);\n        var content = self._getPanelContent(trigger);\n        if (self._isContentVisible(content)) {\n          self._applyOpenedState(trigger);\n          self._applyOpenedState(content);\n        } else {\n          self._applyClosedState(trigger);\n          self._applyClosedState(content);\n        }\n\n        self._applyIndex(trigger, index++);\n      });\n    },\n    /**\n     * @param element\n     * @private\n     */\n    _applyIndex: function(element, index) {\n      element.attr('data-' + this.options.indexDataKey, index);\n      element.data(this.options.indexDataKey, index);\n    },\n    /**\n     * @param element\n     * @private\n     */\n    _setCurrentIndex: function(event) {\n      var panelTrigger = $(event.currentTarget);\n      var index = this._getElementIndex(panelTrigger);\n\n      this.currentIndex = index;\n    },\n    /**\n     * @returns {number}\n     */\n    getCurrentIndex: function() {\n      return this.currentIndex;\n    },\n    /**\n     * @param panelTrigger\n     */\n    getNextPanel: function(panelTrigger) {\n      var index = this._getElementIndex(panelTrigger);\n      var nextIndex = ++index;\n      var nextPanel = DomParser.getNextElement(\n        '[data-' + this.options.indexDataKey + '=' + nextIndex + ']',\n        panelTrigger);\n\n      return nextPanel;\n    },\n    /**\n     * @param element\n     * @private\n     */\n    _applyOpenedState: function(element) {\n      element.attr('data-' + this.options.stateDataKey,\n        this.options.openedStateValue);\n      element.data(this.options.stateDataKey, this.options.openedStateValue);\n    },\n    /**\n     * @param element\n     * @private\n     */\n    _applyClosedState: function(element) {\n      element.attr('data-' + this.options.stateDataKey,\n        this.options.closedStateValue);\n      element.data(this.options.stateDataKey, this.options.closedStateValue);\n    },\n    /**\n     * @private\n     */\n    _openFirst: function() {\
2n      var triggers = this._getTriggers();\n      var trigger = triggers.first();\n\n      this._closeAll();\n\n      // Hack to requeue the openPanel at the end of the execution queue : https://stackoverflow.com/a/779785/3853370\n      // Helps to trigger the event properly\n      setTimeout(function() {\n        this.openPanel(trigger);\n      }.bind(this));\n    },\n    /**\n     * @private\n     */\n    _closeAll: function() {\n      var triggers = this._getTriggers();\n      var self = this;\n\n      triggers.map(function(index, trigger) {\n        trigger = $(trigger);\n        self.closePanel(trigger);\n      });\n    },\n    /**\n     * Trigger panel\n     *\n     * @param event\n     * @private\n     */\n    _triggerPanel: function(event) {\n      var panelTrigger = $(event.currentTarget);\n\n      if (this._isStateOpened(panelTrigger)) {\n        this.closePanel(panelTrigger);\n      } else {\n        this.openPanel(panelTrigger);\n      }\n    },\n    /**\n     * @param panelTrigger\n     */\n    openPanel: function(panelTrigger) {\n      var panelContent = this._getPanelContent(panelTrigger);\n\n      if (this.options.onlyOneOpened) {\n        this._closeAll();\n      }\n\n      this._openContent(panelContent);\n      this._dispatchOpenEvent(panelTrigger, panelContent);\n    },\n    /**\n     * @param panelTrigger\n     */\n    closePanel: function(panelTrigger) {\n      var panelContent = this._getPanelContent(panelTrigger);\n\n      this._closeContent(panelContent);\n      this._dispatchCloseEvent(panelTrigger, panelContent);\n    },\n    /**\n     * @param panelContent\n     * @private\n     */\n    _openContent: function(panelContent) {\n      panelContent.show();\n    },\n    /**\n     * @param panelContent\n     * @private\n     */\n    _closeContent: function(panelContent) {\n      panelContent.hide();\n    },\n    /**\n     * Add class to trigger when panel is opened\n     *\n     * @param event\n     * @private\n     */\n    _togglePanelOpenedClass: function(event) {\n      var panelTrigger = $(event.currentTrigger);\n\n      panelTrigger.addClass(this.options.activeClass);\n    },\n    /**\n     * Remove class to trigger when panel is closed\n     *\n     * @param event\n     * @private\n     */\n    _togglePanelClosedClass: function(event) {\n      var panelTrigger = $(event.currentTrigger);\n\n      panelTrigger.removeClass(this.options.activeClass);\n    },\n    /**\n     * Apply opened state to trigger when panel is opened\n     *\n     * @param event\n     * @private\n     */\n    _togglePanelOpenedState: function(event) {\n      var panelTrigger = $(event.currentTrigger);\n      var panelContent = this._getPanelContent(panelTrigger);\n\n      this._applyOpenedState(panelTrigger);\n      this._applyOpenedState(panelContent);\n    },\n    /**\n     * Apply closed state to trigger when panel is closed\n     *\n     * @param event\n     * @private\n     */\n    _togglePanelClosedState: function(event) {\n      var panelTrigger = $(event.currentTrigger);\n      var panelContent = this._getPanelContent(panelTrigger);\n\n      this._applyClosedState(panelTrigger);\n      this._applyClosedState(panelContent);\n    },\n    /**\n     * Add class to icon when panel is opened\n     *\n     * @param event\n     * @private\n     */\n    _togglePanelOpenedIconClass: function(event) {\n      var panelTrigger = $(event.currentTrigger);\n      var panelIcon = this._getPanelIcon(panelTrigger);\n\n      panelIcon.addClass(this.options.iconPanelOpenedClass).\n        removeClass(this.options.iconPanelClosedClass);\n    },\n    /**\n     * Remove class to icon when panel is closed\n     *\n     * @param event\n     * @private\n     */\n    _togglePanelClosedIconClass: function(event) {\n      var panelTrigger = $(event.currentTrigger);\n      var panelIcon = this._getPanelIcon(panelTrigger);\n\n      panelIcon.addClass(this.options.iconPanelClosedClass).\n        removeClass(this.options.iconPanelOpenedClass);\n    },\n    /**\n     * Dispatch event when panel opened\n     *\n     * @param trigger\n     * @param content\n     * @private\n     */\n    _dispatchOpenEvent: function(trigger, 
2content) {\n      var eventName = this.privateOptions.eventPanelOpen;\n      var isOpened = this._isStateOpened(trigger);\n      var self = this;\n\n      $(this.options.eventSelector).trigger({\n        type: eventName,\n        currentClass: self,\n        currentTrigger: trigger,\n        currentContent: content,\n        isOpened: isOpened,\n      });\n    },\n    /**\n     * Dispatch event when panel closed\n     *\n     * @param trigger\n     * @param content\n     * @private\n     */\n    _dispatchCloseEvent: function(trigger, content) {\n      var eventName = this.privateOptions.eventPanelClose;\n      var isOpened = this._isStateOpened(trigger);\n      var self = this;\n\n      $(this.options.eventSelector).trigger({\n        type: eventName,\n        currentClass: self,\n        currentTrigger: trigger,\n        currentContent: content,\n        isOpened: isOpened,\n      });\n    },\n    /**\n     * @param content\n     * @private\n     */\n    _isContentVisible: function(content) {\n      return content.is(':visible');\n    },\n    /**\n     * @param element\n     * @returns {boolean}\n     * @private\n     */\n    _isStateOpened: function(element) {\n      if (this._getElementState(element) == this.options.openedStateValue) {\n        return true;\n      }\n\n      return false;\n    },\n    /**\n     * @param element\n     * @returns {*}\n     * @private\n     */\n    _getElementState: function(element) {\n      return element.data(this.options.stateDataKey);\n    },\n    /**\n     * @param element\n     * @returns {*}\n     * @private\n     */\n    _getElementIndex: function(element) {\n      return element.data(this.options.indexDataKey);\n    },\n    /**\n     * @returns {*|jQuery|HTMLElement}\n     * @private\n     */\n    _getTriggers: function() {\n      return $(this.options.triggerSelector);\n    },\n    /**\n     * @param panelTrigger\n     * @private\n     */\n    _getPanelContent: function(panelTrigger) {\n      return panelTrigger.next(this.options.contentSelector);\n    },\n    /**\n     * @param panelTrigger\n     * @private\n     */\n    _getPanelIcon: function(panelTrigger) {\n      return panelTrigger.find(this.options.iconSelector);\n    },\n  });\n\n  return $.dnd.corePanel;\n});\n","Dnd_Core/js/utils/dom-parser.js":"/**\n * @package   Dnd\\Core\\view\n * @author    Agence Dn'D <[email protected]>\n * @copyright 2004-present Agence Dn'D\n * @license   https://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)\n * @link      https://www.dnd.fr/\n */\n\ndefine([\n  'jquery',\n], function($) {\n  'use strict';\n\n  return {\n    /**\n     * @param _selector\n     * @param _subject\n     * @returns {*}\n     */\n    getNextElement: function(_selector, _subject) {\n      var next = this._next(_subject);\n      while (next.length != 0) {\n        var found = this._searchFor(_selector, next);\n        if (found != null) {\n          return found;\n        }\n        next = this._next(next);\n      }\n\n      return null;\n    },\n    /**\n     * @param _subject\n     * @returns {*}\n     * @private\n     */\n    _next: function(_subject) {\n      if (_subject.next().length > 0) {\n        return _subject.next();\n      }\n\n      return this._next(_subject.parent());\n    },\n    /**\n     * @param _selector\n     * @param _subject\n     * @returns {*}\n     * @private\n     */\n    _searchFor: function(_selector, _subject) {\n      if (_subject.is(_selector)) {\n        return _subject;\n      }\n\n      var found = null;\n      var self = this;\n      _subject.children().each(function() {\n        found = self._searchFor(_selector, $(this));\n        if (found != null) {\n          return false;\n        }\n      });\n\n      return found;\n    },\n  };\n});\n","Dnd_Core/js/utils/main.js":"/**\n * @package   Dnd\\Core\\view\n * @author    Agence Dn'D <[email protected]>\n * @copyright 2004-present Agence Dn'D\n * @license   https://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)\n * @link      https://www.dnd.fr/\n */\n\ndefine(function(require) {\n  'use strict';\n\n  var utils = {},\n    _ = require('underscore');\n\n  return _.extend(\n    utils,\n    require('./dom-parser'),\n  );\n});\n","Amasty_InvisibleCaptcha/js/model/am-recaptcha.js":"/**\n * reCaptcha model\n */\n\ndefine([\n    'ko',\n    'underscore'\n], function (ko, _) {\n    'use strict';\n\n    return {\n        onLoadCallback: 'amInvisibleCaptchaOnloadCallback',\n        isEnabledOnPayments: false,\n        isScriptLoaded: false,\n        tokenFields: [],\n        url: 'https://www.google.com/recaptcha/api.js',\n        isCaptchaAppended: false,\n        checkoutRecaptchaValidateUrl: null,\n        invisibleCaptchaCustomForm: false,\n        isValidationPassed: ko.observable(false),\n        recaptchaConfig: {\
2n            lang: 'hl=en',\n            size: 'invisible'\n        },\n        formToProtect: '',\n        reCaptchaErrorMessage: 'Prove you are not a robot',\n        recaptchaVersion: null,\n        isInvisible: null,\n\n        setConfig: function (config) {\n            if (_.has(config, 'recaptchaConfig')) {\n                this.setRecaptchaConfig(config.recaptchaConfig);\n            }\n\n            if (_.has(config, 'formsToProtect')) {\n                this.setFormsList(config.formsToProtect);\n            }\n\n            this.checkoutRecaptchaValidateUrl = config.checkoutRecaptchaValidateUrl;\n            this.invisibleCaptchaCustomForm = config.invisibleCaptchaCustomForm;\n            this.isEnabledOnPayments = !!config.isEnabledOnPayments;\n            this.reCaptchaErrorMessage = config.reCaptchaErrorMessage;\n            this.recaptchaVersion = config.recaptchaVersion;\n        },\n\n        setRecaptchaConfig: function (config) {\n            _.extend(this.recaptchaConfig, config);\n        },\n\n        getRecaptchaConfig: function () {\n            return this.recaptchaConfig;\n        },\n\n        setFormsList: function (formsList) {\n            this.formToProtect = formsList;\n        },\n\n        getFormsList: function () {\n            return this.formToProtect;\n        }\n    };\n});\n","Amasty_InvisibleCaptcha/js/action/am-recaptcha-validate.js":"/**\n * Ajax actions\n * @api\n */\n\ndefine([\n    'jquery',\n    'underscore',\n    'Amasty_InvisibleCaptcha/js/model/am-recaptcha',\n], function ($, _, amReCaptchaModel) {\n    'use strict';\n\n    return {\n        options : {\n            reCaptchaSelector: 'am-recaptcha-block',\n            reCaptchaErrorSelector: 'recaptcha-error',\n            reCaptchaErrorMessageSelector: '.recaptcha-error-message'\n        },\n\n        /**\n         * Ajax call\n         * @param {Element} tokenField\n         * @param {String} token\n         * @returns {Deferred}\n         */\n        validateCaptcha: function (tokenField, token) {\n            this.showErrorMessage(false);\n            return $.ajax({\n                url: amReCaptchaModel.checkoutRecaptchaValidateUrl,\n                data: {\n                    'g-recaptcha-response': token\n                },\n                type: 'POST'\n            });\n        },\n\n        showErrorMessage: function (show) {\n            var amReCaptchaBlock = $('.payment-method._active').find('#' + this.options.reCaptchaSelector);\n\n            if (show) {\n                amReCaptchaBlock.addClass(this.options.reCaptchaErrorSelector);\n                if (!amReCaptchaBlock.find(this.options.reCaptchaErrorMessageSelector).length > 0) {\n                    amReCaptchaBlock.append($('<div class=\"recaptcha-error-message\">').html(this.getErrorMessage()));\n                }\n                amReCaptchaBlock.find(this.options.reCaptchaErrorMessageSelector).show();\n            } else {\n                amReCaptchaBlock.removeClass(this.options.reCaptchaErrorSelector);\n                amReCaptchaBlock.find(this.options.reCaptchaErrorMessageSelector).hide();\n            }\n        },\n\n        getErrorMessage: function () {\n            return amReCaptchaModel.reCaptchaErrorMessage;\n        }\n    };\n});\n","Amasty_InvisibleCaptcha/js/action/am-recaptcha-loader.js":"/**\n * reCaptcha API loader\n */\n\ndefine([\n    'Amasty_InvisibleCaptcha/js/model/am-recaptcha'\n], function (amReCaptchaModel) {\n    'use strict';\n\n    return {\n        /**\n         *  Add script tag.\n         * @returns {void}\n         */\n        addReCaptchaScript: function () {\n            var element,\n                scriptTag;\n\n            if (amReCaptchaModel.isScriptLoaded) {\n                return;\n            }\n\n            scriptTag = document.getElementsByTagName('body')[0];\n            element = document.createElement('script');\n            element.async = true;\n            element.src = this.getUrl();\n            scriptTag.append(element);\n            amReCaptchaModel.isScriptLoaded = true;\n        },\n\n        /**\n         * Build url for captcha loading\n         * @returns {string}\n         */\n        getUrl: function () {\n            return amReCaptchaModel.url + '?onload=' + amReCaptchaModel.onLoadCallback\n                + '&render=explicit' + this.getLang();\n        },\n\n        getLang: function () {\n            return amReCaptchaModel.recaptchaConfig.lang ? '&' + amReCaptchaModel.recaptchaConfig.lang : '';\n        }\n    };\n});\n","Amasty_InvisibleCaptcha/js/action/am-recaptcha-configure.js":"define([\n    'Amasty_InvisibleCaptcha/js/model/am-recaptcha'\n], function (amReCaptchaModel) {\n    'use strict';\n\n    return function (config) {\n        amReCaptchaModel.setConfig(config);\n    }\n});\n","Amasty_InvisibleCaptcha/js/view/am-recaptcha-payment.js":"define([\n    'jquery',\n    'underscore',\n    'mageUtils',\n    'Amasty_InvisibleCaptcha/js/view/am-recaptcha-abstract',\n    'Amasty_InvisibleCaptcha/js/model/am-recaptcha',\n    'Amasty_InvisibleCaptcha/js/action/am-recaptcha-validate',\n    'Magento_Ui/js/model/messageList',\n    \"mage/translate\"\n], function (\n    $,\n    _,\n    utils,\n    Component,\n    amReCaptchaModel,\n    recaptchaValidate,\n    messageList\n) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Amasty_InvisibleCaptcha/payment-recaptcha-container',\n            isEnabledOnPayments: amReCaptchaModel.isEnabledOnPayments\n        },\n\n        renderReCaptcha: function (element) {\n            if (window.grecaptcha && window.grecaptcha.render) {\n                this.appendCaptcha();\n                this.initCaptcha(element);\n            } else {\n                $(window).on('amcaptchaReady', function () {\n                    this.appendCaptcha();\n                    this.initCaptcha(element);\n                }.bind(this));\n\n                this.loadApi();\n            }\n        },\n\n        getPaymentName: function (element) {\n            var $element = $(element),\n                // eslint-disable-next-line max-len\n                paymentMethodField = $element.closest('.payment-method').find('.payment-method-title > input[type=\"radio\"]');\n\n            return paymentMethodField.length ? paymentMethodField.val() : '';\n        },\n\n        /**\n         * Init captcha on each payment method\n         * @param {Element} element\n         * @return {void}\n         */\n        initCaptcha: function (element) {\n            var $element = $(element),\n                widgetId,\n                listeners,\n                id = utils.uniqueid(),\n                $button = $element.closest('.payment-method-content').find('button[type=\"submit\"]'),\n                messagesContainer = $element.closest('.am-recaptcha-container').find('.messages-container'),\n                paymentName = this.getPaymentName(element),\n                $recaptchaBlock = $('<div>', {'id': recaptchaValidate.options.reCaptchaSelector})\n\n            $(messagesContainer).attr('id', 'message-' + id);\n            $element.attr('id', id);\n\n            if (!$button.length) {\n                $button = $('<button type=\"button\" class=\"hidden\" data-payment-name=\"' + paymentName + '\"></button>');\n\n                $button.insertAfter($element);\n            }\n\n            $button.before($recaptchaBlock);\n            widgetId = window.grecaptcha.render($recaptchaBlock[0], this.getParameters($element, $button));\n            $recaptchaBlock.append(\n                $('<div class=\"recaptcha-error-message\">').html(recaptchaValidate.getErrorMessage()).hide()\n            );\n\n            $button.click(function (event, data) {\n                // Reset captcha in case of resubmitting the form\n                if (this.needResetCaptcha(data)) {\n                    this.resetCaptcha();\n                    $element.val('');\n                }\n\n                if (!$element.val()) {\n                    event.preventDefault(event);\n                    event.stopImmediatePropagation();\n\n                    if (amReCaptchaModel.getRecaptchaConfig().isInvisible) {\n                        $(event.currentTarget).prop('disabled', true);\n                        window.grecaptcha.execute(widgetId);\n                    } else {\n                        recaptchaValidate.showErrorMessage(true);\n                    }\n                } else {\n                    this.setIsCaptchaValidationPassed(true);\n                }\n            }.bind(this));\n\n            listeners = $._data($button[0], 'events').click;\n            listeners.unshift(listeners.pop());\n\n            amReCaptchaModel.tokenFields.push($element);\n        },\n\n        /**\n         * Need Reset Invisible Captcha\n         * @param {Object} data\n         * @return {Boolean}
2\n         */\n        needResetCaptcha: function (data) {\n            return data?.disableCaptchaReset !== true\n                && amReCaptchaModel.getRecaptchaConfig().isInvisible\n                && amReCaptchaModel.getRecaptchaConfig().recaptchaVersion === 3;\n        },\n\n        /**\n         * Get captcha parameters\n         * @param {Element} tokenField\n         * @param {Element} element\n         * @return {Object}\n         */\n        getParameters: function (tokenField, element) {\n            return _.extend(amReCaptchaModel.getRecaptchaConfig(), {\n                'callback': function (token) {\n                    recaptchaValidate.validateCaptcha(tokenField, token)\n                        .done(function (response) {\n                            var $element = $(element),\n                                isPlaceOrder = $element.prop('disabled');\n\n                            $element.prop('disabled', false);\n\n                            if (_.has(response, 'error') && response.error) {\n                                this.resetCaptcha();\n                                this.setIsCaptchaValidationPassed(false);\n                                this.handleTokenError($(tokenField).attr('id'), response.message);\n\n                                messageList.addErrorMessage({ message: response.message });\n                            } else {\n                                this.setIsCaptchaValidationPassed(true);\n                                recaptchaValidate.showErrorMessage(false);\n                                $(tokenField).val(token);\n\n                                if (!$(element).hasClass('hidden') && isPlaceOrder) {\n                                    $element.trigger('click', [{ disableCaptchaReset: true }]);\n                                }\n                            }\n                        }.bind(this));\n                }.bind(this),\n                'expired-callback': this.resetCaptcha\n            });\n        },\n\n        handleTokenError: function (tokenFieldId, message) {\n            var container = $('#message-' + tokenFieldId),\n                messageBlock = container.find('.message');\n\n            messageBlock.html(message);\n            container.show(0).delay(5000).hide('fast', function () {\n                messageBlock.html('');\n            });\n        }\n    });\n});\n","Amasty_InvisibleCaptcha/js/view/am-recaptcha.js":"define([\n    'jquery',\n    'ko',\n    'underscore',\n    'mageUtils',\n    'Amasty_InvisibleCaptcha/js/view/am-recaptcha-abstract',\n    'Amasty_InvisibleCaptcha/js/model/am-recaptcha',\n    'mage/loader',\n    'domReady!'\n], function (\n    $,\n    ko,\n    _,\n    utils,\n    Component,\n    amReCaptchaModel\n) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            formsToProtect: '',\n            captchaElementClass: 'am-recaptcha-block'\n        },\n\n        /**\n         * @inheritDoc\n         * @returns {Object}\n         */\n        initObservable: function () {\n            this._super();\n\n            this.formsToProtect = $(amReCaptchaModel.getFormsList());\n            this.renderCaptcha();\n\n            return this;\n        },\n\n        /**\n         * @returns {void}\n         */\n        renderCaptcha: function () {\n            $(window).on('amcaptchaReady', this.initFormHandler.bind(this));\n\n            // eslint-disable-next-line consistent-return\n            _.debounce(function () {\n                this._addListeners();\n\n                this.formsToProtect.on('submit', function (event) {\n                    const form = $(event.currentTarget);\n\n                    window.dispatchEvent(new CustomEvent('am-recaptcha-submit-event', {\n                        detail: {\n                            form: form\n                        }\n                    }));\n\n                    if (amReCaptchaModel.isScriptLoaded && !!event.target.dataset?.amCaptchaObserved) {\n                        form.off('submit:beforeSubmit');\n\n                        return;\n                    }\n\n                    event.preventDefault();\n                    event.stopImmediatePropagation();\n\n                    form.trigger('submit:beforeSubmit');\n                });\n\n                this._eventOrderChange();\n                this._enableSubmitButtons();\n            }.bind(this), 200)();\n        },\n\n        _enableSubmitButtons: function (forms) {\n            if (typeof forms === 'undefined') {\n                forms = this.formsToProtect;\n            }\n\n            forms.find('[am-captcha-protect=true]').removeAttr('disabled');\n        },\n\n        _addListeners: function () {\n            this.formsToProtect.on('submit:beforeSubmit', function (event) {\n                this.cachedForm = $(event.target);\n                event.target.dataset.amCaptchaObserved = 1;\n\n                if (amReCaptchaModel.isScriptLoaded) {\n                    $(window).trigger('amcaptchaReady');\n                    return;\n                }\n\n                this.loadApi();\n            }.bind(this));\n        },\n\n        /**\n         * @private\n         * @returns {void}\n         */\n        _eventOrderChange: function () {\n            _.each(this.formsToProtect, function (form) {\n                var $form = $(form);\n\n                $form.data('recaptchaFormId', utils.uniqueid());\n\n                if (+amReCaptchaModel.invisibleCaptchaCustomForm) {\n                    this._swapSubmit($form);\n                }\n            }.bind(this));\n        },\n\n        /**\n         * @param {Element} form\n         * @private\n         * @returns {void}\n         */\n        _swapSubmit: function (form) {\n            var $form = $(form),\n                listeners;\n\n            listeners = $._data($form[0], 'events').submit;\n            if (listeners) {\n                listeners.unshift(listeners.pop());\n            }\n        },\n\n        /**\n         * @param {Element} form\n         * @returns {Object}\n         */\n        getParameters: function (form) {\n            var $form = $(form);\n\n            return _.extend(amReCaptchaModel.getRecaptchaConfig(), {\n                'callback': function () {\n                    if (this.showLoaderOnCaptchaLoading) {\n                        $('body').trigger('processStop');\n                    }\n\n                    if ($form.valid()) {\n                        $form.submit();\n                    }\n                }.bind(this),\n                'expired-callback': this.resetCaptcha\n            });\n        },\n\n        /**\n         * @returns {void}\n         */\n        initFormHandler: function () {\n            var self = this;\n\n            amReCaptchaModel.isScriptLoaded = true;\n            this.appendCaptcha();\n            _.each(self.formsToProtect, function (form) {\n                if (self.cac
2hedForm && self.cachedForm[0] === form) {\n                    var $form = $(form),\n                        widgetId = self._initCaptchaOnForm(form);\n\n                    $form.on('ajaxFormLoaded', function () {\n                        self._formButtonClickEvent(form, widgetId);\n                    });\n\n                    $(document).on('am_form:ajax_complete', function (event, form) {\n                        self.renderCaptchaOnForm($(form));\n                    });\n                }\n            });\n        },\n\n        /**\n         * Render captcha element on form\n         *\n         * @param {jQuery} $form\n         * @param {jQuery|null} $captchaElement\n         * @returns {Number}\n         */\n        renderCaptchaOnForm: function ($form, $captchaElement = null) {\n            var $formCaptchaElement = $form.find('.' + this.captchaElementClass);\n\n            if ($formCaptchaElement.length) {\n                $formCaptchaElement.remove();\n            }\n\n            if (!$captchaElement) {\n                $captchaElement = this.getCaptchaElement();\n            }\n\n            $form.append($captchaElement);\n\n            var widgetId = window.grecaptcha.render($captchaElement[0], this.getParameters($form[0]));\n\n            $captchaElement.data('id', widgetId);\n            this._formButtonClickEvent($form[0], widgetId);\n\n            this._enableSubmitButtons($form);\n\n            return widgetId;\n        },\n\n        /**\n         * Get captcha element\n         *\n         * @returns {jQuery}\n         */\n        getCaptchaElement: function () {\n            return $('<div class=\"' + this.captchaElementClass + '\"></div>');\n        },\n\n        /**\n         * Init captcha on form\n         * @param {Element} form\n         * @returns {String|Number}\n         */\n        _initCaptchaOnForm: function (form) {\n            var $form = $(form),\n                widgetId,\n                $button = $form.find(\"[type='submit']\"),\n                $captchaElement = this.getCaptchaElement();\n\n            widgetId = this.renderCaptchaOnForm($form, $captchaElement);\n\n            this._submitCachedForm($form, $button);\n\n            amReCaptchaModel.tokenFields.push($captchaElement);\n\n            return widgetId;\n        },\n\n        /**\n         *\n         * @param {Element} $form\n         * @param {Element} $button\n         * @private\n         * @returns {void}\n         */\n        _submitCachedForm: function ($form, $button) {\n            if ($button.length && this.cachedForm\n                && this.cachedForm.data('recaptchaFormId') === $form.data('recaptchaFormId')) {\n                if (this.showLoaderOnCaptchaLoading) {\n                    $('body').trigger('processStart');\n                }\n\n                $button.trigger('click');\n                this.cachedForm = null;\n            }\n        },\n\n        /**\n         * Add Event to execute recaptcha widget on button click\n         * @private\n         * @param {Element} form\n         * @param {Number} widgetId\n         * @returns {void}\n         */\n        _formButtonClickEvent: function (form, widgetId) {\n            var $form = $(form),\n                $button = $form.find(\"[type='submit']\"),\n                buttonClickListeners = null,\n                buttonListeners = {};\n\n            if ($button.length) {\n                buttonListeners = $._data($button[0], 'events');\n            }\n\n            if (_.has(buttonListeners, 'click')) {\n                buttonClickListeners = _.clone(buttonListeners.click);\n            }\n\n            $button.off('click').on('click', function (e) {\n                e.preventDefault();\n\n                if ($form.valid()) {\n                    $button.prop('disabled', true);\n                    window.grecaptcha.reset(widgetId);\n                    if (amReCaptchaModel.getRecaptchaConfig().isInvisible) {\n                        window.grecaptcha.execute(widgetId);\n                    }\n                }\n\n                if (buttonClickListeners) {\n                    $button.off('click');\n                    $.each(buttonClickListeners, function (index, event) {\n                        $button.bind(event.type, event.handler);\n                    });\n\n                    buttonClickListeners = null;\n                }\n            });\n\n            this._enableSubmitButtons($form);\n        }\n    });\n});\n","Amasty_InvisibleCaptcha/js/view/am-recaptcha-abstract.js":"define([\n    'uiComponent',\n    'jquery',\n    'ko',\n    'underscore',\n    'mageUtils',\n    'Amasty_InvisibleCaptcha/js/model/am-recaptcha',\n    'Amasty_InvisibleCaptcha/js/action/am-recaptcha-loader',\n    'mage/loader',\n    'domReady!'\n], function (\n    Component,\n    $,\n    ko,\n    _,\n    utils,\n    amReCaptchaModel,\n    amReCaptchaLoader\n) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            formsToProtect: '',\n            showLoaderOnCaptchaLoading: false,\n            reCaptchaId: 'am-recaptcha-place-order'\n        },\n\n        /**\n         * Loads reCaptcha API\n         * @returns {void}\n         */\n        loadApi: function () {\n            if (!amReCaptchaModel.isScriptLoaded) {\n                window[amReCaptchaModel.onLoadCallback] = function () {\n                    $(window).trigger('amcaptchaReady');\n                };\n\n                amReCaptchaLoader.addReCaptchaScript();\n            }\n        },\n\n        /**\n         * Add captcha\n         * @returns {void}\n         */\n        appendCaptcha: function () {\n            if (!amReCaptchaModel.isCaptchaAppended && amReCaptchaModel.getRecaptchaConfig().isInvisible) {\n                this.add();\n\n                window.grecaptcha.render(this.reCaptchaId, this.getParameters());\n\n                amReCaptchaModel.isCaptchaAppended = true;\n            }\n        },\n\n        /**\n         * Initialize additional reCaptcha instance.\n         * @returns {void}\n         */\n        add: function () {\n            var rendererReCaptcha = $('<div>', {\n                'id': this.reCaptchaId,\n                'class': this.reCaptchaId\n            });\n\n            $('body').append(rendererReCaptcha);\n        },\n\n        setIsCaptchaValidationPassed: function (flag) {\n            amReCaptchaModel.isValidationPassed(flag);\n            amReCaptchaModel.isValidationPassed.valueHasMutated();\n        },\n\n        /**\n         * Reset captcha\n         * @returns {void}\n         */\n        resetCaptcha: function () {\n            _.each(amReCaptchaModel.tokenFields, function (tokenBlock) {\n                window.grecaptcha.reset(tokenBlock.data('id'));\n            });\n\n            this.setIsCaptchaValidationPassed(false);\n        }\n    });\n});\n","Amasty_InvisibleCaptcha/js/view/paypal/in-context/checkout-express-mixin.js":"/**\n * Mixin paypal express checkout\n */\ndefine([\n    'jquery',\n    'underscore',\n    'Amasty_InvisibleCaptcha/js/model/am-recaptcha',\n    'Magento_Checkout/js/model/payment/additional-validators'\n], function ($, _, amReCaptchaModel, additionalValidators) {\n    'use strict';\n\n    var mixin = {\n        defaults: {\n            reCaptchaButton: fal
2se\n        },\n        isCaptchaValid: false,\n\n        /** @inheritDoc */\n        initListeners: function (context) {\n            this._super(context);\n\n            if (amReCaptchaModel.isEnabledOnPayments) {\n                $.async('button[data-payment-name=\"' + this.index + '\"]', function (element) {\n                    this.reCaptchaButton = $(element);\n                    this.validate();\n                }.bind(this));\n\n                amReCaptchaModel.isValidationPassed.subscribe(function (data) {\n                    this.isCaptchaValid = data;\n                }.bind(this));\n            }\n\n            return this;\n        },\n\n        /** @inheritDoc */\n        validate: function (actions) {\n            this.actions = actions || this.actions;\n\n            if (this.actions) {\n                if (amReCaptchaModel.isEnabledOnPayments && !this.isCaptchaValid) {\n                    this.actions.disable();\n                } else {\n                    additionalValidators.validate(true)\n                        ? this.actions.enable()\n                        : this.actions.disable();\n\n                }\n            }\n        },\n\n        /**\n         * Adding logic to be triggered onClick action for smart buttons component\n         * @returns {void}\n         */\n        onClick: function () {\n            var savedCallback = this._super;\n\n            if (!this.isCaptchaValid && amReCaptchaModel.isEnabledOnPayments) {\n                // eslint-disable-next-line one-var\n                var subscribe = amReCaptchaModel.isValidationPassed.subscribe(function (data) {\
2n                    if (this.actions) {\n                        if (data) {\n                            this.actions.enable();\n\n                            savedCallback.apply(this);\n                        } else {\n                            this.actions.disable();\n                        }\n                    }\n\n                    subscribe.dispose();\n                }.bind(this));\n\n                this.validateCaptcha();\n            } else {\n                savedCallback.apply(this);\n            }\n        },\n\n        /**\n         * Trigger captcha's invisible button\n         * @returns {void}\n         */\n        validateCaptcha: function () {\n            if (this.reCaptchaButton.length) {\n                this.reCaptchaButton.trigger('click');\n            }\n        }\n    };\n\n    return function (ExpressCheckout) {\n        return ExpressCheckout.extend(mixin);\n    };\n});\n","Goyard_Price/js/price-utils-mixin.js":"define([\n    'jquery',\n    'underscore'\n], function ($, _) {\n    'use strict';\n\n    var globalPriceFormat = {\n        requiredPrecision: 2,\n        integerRequired: 1,\n        decimalSymbol
2: ',',\n        groupSymbol: ',',\n        groupLength: ',',\n        vatMention: ''\n    }\n\n    return function (target) {\n\n        target.formatPriceLocale = function formatPriceLocale(amount, format, isShowSign) {\n            var s = '',\n            result = '',\n            defaultThousandSeparator = '',\n            precision, pattern, locale, r;\n\n            format = _.extend(globalPriceFormat, format);\n            if (Number.isInteger(amount)) {\n                precision = 0;\n            } else {\n                precision = isNaN(format.requiredPrecision = Math.abs(format.requiredPrecision)) ? 2 : format.requiredPrecision;\n            }\n            \n            if(precision > 0){\n                defaultThousandSeparator = ',';\n            }\n            \n            pattern = format.pattern || '%s';\n            locale = window.LOCALE || 'en-US';\n            if (isShowSign === undefined || isShowSign === true) {\n                s = amount < 0 ? '-' : isShowSign ? '+' : '';\n            } else if (isShowSign === false) {\n                s = '';\n            }\n            pattern = pattern.indexOf('{sign}') < 0 ? s + pattern : pattern.replace('{sign}', s);\n            amount = Number(Math.round(Math.abs(+amount || 0) + 'e+' + precision) + ('e-' + precision));\n            r = amount.toLocaleString(locale, { minimumFractionDigits: precision });\n            \n            return pattern.replace('%s', r).replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '').replace(/[,.\u202f]/g, (format.thousandSeparator ?? defaultThousandSeparator)) + \" \" + format.vatMention;\n        };\n\n        return target;\n    };\n});\n","Magento_Persistent/js/remember-me-config.js":"/**\n * Copyright 2024 Adobe\n * All Rights Reserved.\n */\n\ndefine(\n    [\n        'ko',\n        'uiComponent'\n    ],\n    function (ko, Component) {\n        'use strict';\n\n        return Component.extend({\n            dataScope: 'global',\n            config: {},\n\n            /** @inheritdoc */\n            initialize: function () {\n                this._super();\n\n                window.rememberMeConfig = this.config;\n            }\n        });\n    }\n);\n","Magento_Persistent/js/view/customer-data-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'mage/utils/wrapper'\n], function ($, wrapper) {\n    'use strict';\n\n    var mixin = {\n\n        /**\n         * Check if persistent section is expired due to lifetime.\n         *\n         * @param {Function} originFn - Original method.\n         * @return {Array}\n         */\n        getExpiredSectionNames: function (originFn) {\n            var expiredSections = originFn(),\n                storage = $.initNamespaceStorage('mage-cache-storage').localStorage,\n                currentTimestamp = Math.floor(Date.now() / 1000),\n                persistentIndex = expiredSections.indexOf('persistent'),\n                persistentLifeTime = 0,\n                sectionData;\n\n            if (window.persistent !== undefined && window.persistent.expirationLifetime !== undefined) {\n                persistentLifeTime = window.persistent.expirationLifetime;\n            }\n\n            if (persistentIndex !== -1) {\n                sectionData = storage.get('persistent');\n\n                if (typeof sectionData === 'object' &&\n                    sectionData['data_id'] + persistentLifeTime >= currentTimestamp\n                ) {\n                    expiredSections.splice(persistentIndex, 1);\n                }\n            }\n\n            return expiredSections;\n        },\n\n        /**\n         * @param {Object} settings\n         * @constructor\n         */\n        'Magento_Customer/js/customer-data': function (originFn) {\n            let mageCacheTimeout = new Date($.localStorage.get('mage-cache-timeout')),\n                mageCacheSessId = $.cookieStorage.isSet('mage-cache-sessid');\n\n            originFn();\n            if (window.persistent !== undefined && (mageCacheTimeout < new Date() || !mageCacheSessId)) {\n                this.reload(['persistent','cart'],true);\n            }\n        }\n    };\n\n    /**\n     * Override default customer-data.getExpiredSectionNames().\n     */\n    return function (target) {\n        return wrapper.extend(target, mixin);\n    };\n});\n","Magento_Persistent/js/view/remember-me-default.js":"/**\n * Copyright 2024 Adobe\n * All Rights Reserved.\n */\n\ndefine(\n    [\n        'ko',\n        'uiComponent',\n        'Magento_Customer/js/customer-data'\n    ],\n    function (ko, Component, customerData) {\n        'use strict';\n\n        return Component.extend({\n            defaults: {\n                template: 'Magento_Persistent/remember-me'\n            },\n            dataScope: 'global',\n            isRememberMeCheckboxVisible: ko.observable(false),\n            isRememberMeCheckboxChecked: ko.observable(false),\n\n            /** @inheritdoc */\n            initialize: function () {\n                this._super();\n\n                this.showElement();\n            },\n\n            /**\n             * Show remember me checkbox on certain conditions\n             */\n            showElement: function () {\n                let cart = customerData.get('cart'),\n                    persistenceConfig = window.rememberMeConfig.persistenceConfig;\n\n                if (cart().isGuestCheckoutAllowed !== false) {\n                    persistenceConfig.isRememberMeCheckboxVisible = false;\n                } else {\n                    cart.subscribe(function (cartData) {\n                        if (cartData.isGuestCheckoutAllowed !== false) {\n                            persistenceConfig.isRememberMeCheckboxVisible = false;\n                        }\n                    }, this);\n                }\n\n                this.isRememberMeCheckboxChecked = ko.observable(persistenceConfig.isRememberMeCheckboxChecked);\n                this.isRememberMeCheckboxVisible = ko.observable(persistenceConfig.isRememberMeCheckboxVisible);\n            }\n        });\n    }\n);\n","Magento_Persistent/js/view/additional-welcome.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/translate',\n    'Magento_Customer/js/customer-data'\n], function ($, $t, customerData) {\n    'use strict';\n\n    return {\n        /**\n         * Init.\n         */\n        init: function () {\n            var persistent = customerData.get('persistent');
2\n\n            if (persistent().fullname === undefined) {\n                customerData.get('persistent').subscribe(this.replacePersistentWelcome);\n            } else {\n                this.replacePersistentWelcome();\n            }\n        },\n\n        /**\n         * Replace welcome message for customer with persistent cookie.\n         */\n        replacePersistentWelcome: function () {\n            var persistent = customerData.get('persistent'),\n                welcomeElems;\n\n            if (persistent().fullname !== undefined) {\n                welcomeElems = $('li.greet.welcome > span.not-logged-in');\n\n                if (welcomeElems.length) {\n                    $(welcomeElems).each(function () {\n                        var html = $t('Welcome, %1!').replace('%1', persistent().fullname);\n\n                        $(this).attr('data-bind', html);\n                        $(this).html(html);\n                    });\n                    $(welcomeElems).append(' <span><a ' + window.notYouLink + '>' + $t('Not you?') + '</a>');\n                }\n            }\n        },\n\n        /**\n         * @constructor\n         */\n        'Magento_Persistent/js/view/additional-welcome': function () {\n            this.init();\n        }\n    };\n});\n","Magento_Persistent/js/view/remember-me.js":"/**\n * Copyright 2024 Adobe\n * All Rights Reserved.\n */\n\ndefine(\n    [\n        'ko',\n        'uiComponent'\n    ],\n    function (ko, Component) {\n        'use strict';\n\n        let persistenceConfig = window.checkoutConfig.persistenceConfig;\n\n        return Component.extend({\n            defaults: {\n                template: 'Magento_Persistent/remember-me'\n            },\n            isRememberMeCheckboxVisible: ko.observable(persistenceConfig.isRememberMeCheckboxVisible),\n            isRememberMeCheckboxChecked: ko.observable(persistenceConfig.isRememberMeCheckboxChecked)\n        });\n    }\n);\n","Magento_GiftRegistry/advanced-search.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.advancedSearch', {\n        options: {\n            ajaxSpinnerSelector: '#gr-please-wait',\n            ajaxResultSelector: '#gr-type-specific-options',\n            ajaxResultContainerSelector: '#gr-type-specific-fieldset'\n        },\n\n        /**\n         * bind handlers\n         * @private\n         */\n        _create: function () {\n            this.element.on('change', $.proxy(this._ajaxUpdate, this));\n            this.options.selectedOption && this.element.val(this.options.selectedOption).trigger('change');\n        },\n\n        /**\n         * ajax call for search option list\n         * @private\n         */\n        _ajaxUpdate: function () {\n            var typeId = this.element.val();\n\n            $(this.options.ajaxSpinnerSelector).show();\n\n            $.post(this.options.url, {\n                'type_id': typeId\n            }
2, $.proxy(function (data) {\n                $(this.options.ajaxSpinnerSelector).hide();\n                $(this.options.ajaxResultSelector).html(data);\n                $(this.options.ajaxResultContainerSelector).toggle(!!typeId);\n                $('body').trigger('contentUpdated');\n            }, this));\n        }\n    });\n\n    return $.mage.advancedSearch;\n});\n","Magento_GiftRegistry/properties.js":"/**\r\n * Copyright \u00a9 Magento, Inc. All rights reserved.\r\n * See COPYING.txt for license details.\r\n */\r\n\r\ndefine(['jquery'], function ($) {\r\n    'use strict';\r\n\r\n    return function (config, element) {\r\n        $(element).prop(config);\r\n    };\r\n});\r\n","Magento_GiftRegistry/address-option.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/template',\n    'Magento_Ui/js/modal/alert',\n    'jquery-ui-modules/widget',\n    'mage/translate'\n], function ($, mageTemplate, alert) {\n    'use strict';\n\n    /**\n     * Gift registry multi-ship address option\n     */\n    $.widget('mage.addressOption', {\n        options: {\n            addressOptionTmpl: '#address-option-tmpl' // 'Use gift registry shipping address' option.\n        },\n\n        /**\n         * Add the gift registry shipping address option to every gift registry item on the multishipping page.\n         * @private\n         */\n        _create: function () {\n            this.addressOptionTmpl = mageTemplate(this.options.addressOptionTmpl);\n\n            $.each(this.options.registryItems, $.proxy(this._addAddressOption, this));\n        },\n\n        /**\n         * Add a 'Use gift registry shipping address' option to items on the multishipping page. Bind a change\n         * handler on the quantity field of gift registry items to prevent changing the value.\n         * @private\n         * @param {Number} x - Index value from $.each() - Unused.\n         * @param {Object} object - JSON Object - {\"item\": #, \"address\": #}\n         */\n        _addAddressOption: function (x, object) {\n            var _this = this;\n\n            this.element.find('select[id^=\"ship_\"]').each(function (y, element) {\n                var arr = $(element).attr('id').split('_'),\n                    selectedIndices = _this.options.selectedAddressIndices,\n                    selectOption;\n\n                if (arr[2] && parseInt(arr[2], 10) === object.item) {\n                    selectOption = _this.addressOptionTmpl({\n                        data: {\n                            _text_: $.mage.__('Use gift registry shipping address'),\n                            _value_: _this.options.addressItemPrefix + object.address\n                        }\n                    });\n\n                    selectOption = $(selectOption).appendTo(element);\n\n                    if (selectedIndices.length > 0) {\n                        _this._setSelected(selectOption, parseInt(arr[1], 10), selectedIndices);\n                    }\n\n                    $(element).closest('tr').find('input[type=\"text\"]').on('focus', function (event) {\n                        $(event.target).trigger('blur');\n                        alert({\n                            content: $.mage.__('The only place to change the number of gift registry items is on the Gift Registry Info page or directly in your cart.') //eslint-disable-line max-len\n                        });\n                    });\n                }\n            });\n        },\n\n        /**\n         * Search for the target index and set the selected attribute when there is a match. This will mark\n         * the 'Use gift registry shipping address' option as 'selected'.\n         * @private\n         * @param {Object} option - Select option object.\n         * @param {Number} index - The target index value being searched for.\n         * @param {Array} indices - An array of indices to iterate through looking for the target.\n         */\n        _setSelected: function (option, index, indices) {\n            var i;\n\n            for (i = 0; i < indices.length;
2 i++) {\n                if (indices[i] === index) {\n                    option.prop('selected', true);\n                    break;\n                }\n            }\n        }\n    });\n\n    return $.mage.addressOption;\n});\n","Magento_GiftRegistry/gift-registry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Theme/js/row-builder',\n    'jquery-ui-modules/widget'\n], function ($, rowBuilder) {\n    'use strict';\n\n    /**\n     * Extending the rowBuilder widget and adding custom formProcessing for rendering recipients\n     */\n    $.widget('mage.giftRegistry', rowBuilder, {\n\n        options: {\n            rowIdPrefix: 'registrant:',\n            rowCustomIdPrefix: 'registrant:custom:',\n            addrTypeSelector: '#address_type_or_id',\n            newShipAddrFormSelector: '#shipping-new-address-form',\n            shipAddrDataSelector: 'div[data-shipping-address]',\n            shipAddrDataAttr: 'shipping-address',\n            newAddrTypeVal: 'new'\n        },\n\n        /**\n         *\n         * @private\n         */\n        _create: function () {\n            this._super();\n\n            if ($(this.options.shipAddrDataSelector).data(this.options.shipAddrDataAttr)) {\n                $(this.options.addrTypeSelector).val(this.options.newAddrTypeVal);\n                $(this.options.newShipAddrFormSelector).show();\n            }\n            this.element.on('change', this.options.addrTypeSelector, $.proxy(this._handleShipAddrChange, this));\n        },\n\n        /**\n         * @override\n         * Process and loop through all row data to create preselected values. This is used for any error on submit.\n         * For complex implementations the inheriting widget can override this behavior\n         * @public\n         * @param {Object} formDataArr\n         */\n        processFormDataArr: function (formDataArr) {\n            var formData = formDataArr.formData,\n                i;\n\n            for (i = this.options.rowIndex = 0; i < formData.length; this.options.rowIndex = i++) {\n                this.addRow(i);\n                this._processFormDataArrKey(i, formData[i], false);\n            }\n\n        },\n\n        /**\n         * Function to recursively process json encoded form data\n         * This utility helps in processing formData values which are objects/json themselves\n         * @private\n         * @param {Number} index - index of the curr row\n         * @param {Object}
2 formRow - row object containing field name and value\n         * @param {Boolean} isCustom - if the registrant has custom fields\n         *\n         */\n        _processFormDataArrKey: function (index, formRow, isCustom) {\n            var idPrefix = isCustom ? this.options.rowCustomIdPrefix : this.options.rowIdPrefix,\n                key;\n\n            for (key in formRow) {\n                if (formRow.hasOwnProperty(key)) {\n                    if (Object.prototype.toString.call(formRow[key]) === '[object Object]') { //eslint-disable-line\n                        this._processFormDataArrKey(index, formRow[key], true);\n                    } else {\n                        this.setFieldById(idPrefix + key + index, formRow[key]);\n                    }\n                }\n            }\n        },\n\n        /**\n         * Function to handle shipping address change\n         * @private\n         * @param {Object} e - native event object\n         */\n        _handleShipAddrChange: function (e) {\n            $(this.options.newShipAddrFormSelector).toggle(e.target.value === this.options.newAddrTypeVal);\n        }\n    });\n\n    return $.mage.giftRegistry;\n});\n","Magento_GiftRegistry/js/search-by-changed.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['jquery'], function ($) {\n    'use strict';\n\n    return function (config, element) {\n        $(element).on('change', function (event) {\n            event.preventDefault();\n            $('form[id^=\"gr-quick-search-widget\"]').hide();\n            $('#gr-quick-search-widget-' + this.value + '-form').show();\n        });\n    };\n});\n","Magento_GiftRegistry/js/model/checkout-data-resolver-ext.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'underscore',\n    'mage/utils/wrapper',\n    'Magento_Checkout/js/checkout-data'\n], function (\n    $,\n    _,\n    wrapper,\n    checkoutData\n) {\n    'use strict';\n\n    return function (checkoutDataResolver) {\n        function isGetShippingAddressDataEmpty() {\n            return !checkoutData.getShippingAddressFromData() &&\n                window.checkoutConfig.shippingAddressFromData;\n        }\n\n        function isGiftShippingAddressDataEmpty(giftRegistryShippingAddressData) {\n            return !_.isEmpty(giftRegistryShippingAddressData) &&\n                giftRegistryShippingAddressData.length !== 0;\n        }\n\n        checkoutDataResolver.resolveShippingAddress = wrapper.wrapSuper(\n            checkoutDataResolver.resolveShippingAddress,\n            function () {\n                var giftRegistryShippingAddressData = $.extend(\n                        true,\n                        {},\n                        window.checkoutConfig.giftRegistry.giftRegistryShippingAddress\n                    ),\n                    addressData = [];\n\n                if (!window.checkoutConfig.giftRegistry.available\n                    || !window.checkoutConfig.giftRegistry.id\n                    || !window.checkoutConfig.giftRegistry.giftRegistryShippingAddress\n                ) {\n                    return this._super();\n                }\n\n                $.each(giftRegistryShippingAddressData, function (key, value) {\n                    if (giftRegistryShippingAddressData.hasOwnProperty(key)\n                        && !_.isEmpty(value)\n                    ) {\n                        if (key === 'street') {\n                            addressData[key] = Object.assign(\n                                {},\n                                value.split('\\n')\n                            );\n                        } else {\n                            addressData[key] = value;\n                        }\n                    }\n                });\n\n                if (isGetShippingAddressDataEmpty() ||\n                    isGiftShippingAddressDataEmpty(giftRegistryShippingAddressData)\n                ) {\n                    checkoutData.setShippingAddressFromData(addressData);\n                }\n                this._super();\n            });\n\n        return checkoutDataResolver;\n    };\n});\n","Magento_GiftRegistry/js/model/gift-registry-customer-addresses.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'ko',\n    'Magento_Customer/js/model/customer/address'\n], function ($, ko, Address) {\n    'use strict';\n\n    var isLoggedIn = ko.observable(window.isCustomerLoggedIn);\n\n    return {\n\n        /**\n         * Override gift registry addresses on default address list\n         *\n         * @return {Array}\n         */\n        getAddressItems: function () {\n            var items = [],\n                customerData = window.customerData;\n\n            if (isLoggedIn()) {\n                if (Object.keys(customerData).length) {\n                    $.each(customerData.addresses, function (key, item) {\n                        items.push(new Address(item));\n                    });\n                }\n            }\n\n            return items;\n        }\n    };\n});\n","Magento_GiftRegistry/js/model/recipient-address.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n    'use strict';\n\n    /**\n     * @param {Number} registryId\n     * @return {Object} new address object\n     */\n    return function (registryId) {\n        return {\n            giftRegistryId: registryId,\n\n            /**\n             * @return {Boolean}\n             */\n            isDefaultShipping: function () {\n                return false;\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            isDefaultBilling: function () {\n                return false;\n            },\n\n            /**\n             * @return {String}\n             */\n            getType: function () {\n                return 'gift-registry';
2\n            },\n\n            /**\n             * @return {String}\n             */\n            getKey: function () {\n                return this.getType() + this.giftRegistryId;\n            },\n\n            /**\n             * @return {String}\n             */\n            getCacheKey: function () {\n                return this.getKey();\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            isEditable: function () {\n                return false;\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            canUseForBilling: function () {\n                return false;\n            }\n        };\n    };\n});\n","Magento_GiftRegistry/js/model/resource-url-manager.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Checkout/js/model/resource-url-manager'\n], function ($, resourceUrlManager) {\n    'use strict';\n\n    return $.extend(resourceUrlManager, {\n        /**\n         * @param {Object} quote\n         * @return {*|String}\n         */\n        getUrlForEstimationShippingMethodsForGiftRegistry: function (quote) {\n            var params = this.getCheckoutMethod() ===  'guest' ? {\n                    quoteId: quote.getQuoteId()\n                } : {},\n                urls = {\n                    'guest': '/guest-giftregistry/:quoteId/estimate-shipping-methods',\n                    'customer': '/giftregistry/mine/estimate-shipping-methods'\n                };\n\n            return this.getUrl(urls, params);\n        }\n    });\n});\n","Magento_GiftRegistry/js/model/shipping-save-processor/gift-registry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Checkout/js/model/quote',\n    'Magento_Checkout/js/model/resource-url-manager',\n    'mage/storage',\n    'Magento_Checkout/js/model/payment-service',\n    'Magento_Checkout/js/model/error-processor',\n    'Magento_Checkout/js/model/payment/method-converter',\n    'Magento_Checkout/js/model/full-screen-loader'\n], function (quote, resourceUrlManager, storage, paymentService, errorProcessor, methodConverter, fullScreenLoader) {\n    'use strict';\n\n    return {\n        /**\n         * Save shipping information.\n         */\n        saveShippingInformation: function () {\n            var shippingAddress = {},\n                payload;\n\n            shippingAddress['extension_attributes'] = {\n                'gift_registry_id': quote.shippingAddress().giftRegistryId\n            };\n\n            payload = {\n                addressInformation: {\n                    'shipping_address': shippingAddress,\n                    'shipping_method_code': quote.shippingMethod()['method_code'],\n                    'shipping_carrier_code': quote.shippingMethod()['carrier_code']\n                }\n            };\n\n            fullScreenLoader.startLoader();\n\n            return storage.post(\n                resourceUrlManager.getUrlForSetShippingInformation(quote),\n                JSON.stringify(payload)\n            ).done(function (response) {\n                paymentService.setPaymentMethods(methodConverter(response['payment_methods']));\n                quote.setTotals(response.totals);\n                fullScreenLoader.stopLoader();\n            }).fail(function (response) {\n                errorProcessor.process(response);\n                fullScreenLoader.stopLoader();\n            });\n        }\n    };\n});\n","Magento_GiftRegistry/js/model/shipping-rate-processor/gift-registry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_GiftRegistry/js/model/resource-url-manager',\n    'Magento_Checkout/js/model/quote',\n    'mage/storage',\n    'Magento_Checkout/js/model/shipping-service',\n    'Magento_Checkout/js/model/shipping-rate-registry',\n    'Magento_Checkout/js/model/error-processor'\n], function (resourceUrlManager, quote, storage, shippingService, rateRegistry, errorProcessor) {\n    'use strict';\n\n    return {\n        /**\n         * @param {Object} address\n         */\n        getRates: function (address) {\n            var cache;\n\n            shippingService.isLoading(true);\n            cache = rateRegistry.get(address.getKey());\n\n            if (cache) {\n                shippingService.setShippingRates(cache);\n                shippingService.isLoading(false);\n            } else {\n                storage.post(\n                    resourceUrlManager.getUrlForEstimationShippingMethodsForGiftRegistry(quote),\n                    JSON.stringify({\n                        registryId: address.giftRegistryId\n                    }),\n                    false\n                ).done(function (result) {\n                    rateRegistry.set(address.getKey(), result);\n                    shippingService.setShippingRates(result);\n                }).fail(function (response) {\n                    shippingService.setShippingRates([]);\n                    errorProcessor.process(response);\n                }).always(function () {\n                    shippingService.isLoading(false);\n                });\n            }\n        }\n    };\n});\n","Magento_GiftRegistry/js/view/shipping-address/gift-registry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'Magento_GiftRegistry/js/model/recipient-address',\n    'Magento_Customer/js/model/address-list',\n    'Magento_Checkout/js/model/shipping-rate-service',\n    'Magento_GiftRegistry/js/model/shipping-rate-processor/gift-registry',\n    'Magento_Checkout/js/model/shipping-save-processor',\n    'Magento_GiftRegistry/js/model/shipping-save-processor/gift-registry'\n], function (\n    Component,\n    RecipientAddress,\n    addressList,\n    shippingRateService,\n    shippingRateProcessor,\n    shippingSaveProcessor,\n    giftRegistryShippingSaveProcessor\n) {\n    'use strict';\n    function checkExistingAddress() {\n        let giftRegistry = window.checkoutConfig.giftRegistry;\n\n        return giftRegistry.isLoggedIn && addressList().length !== 0 &&\n            giftRegistry.id && giftRegistry.available;\n    }\n\n    //Register gift registry address provider\n    if (checkExistingAddress()) {\n        addressList.push(new RecipientAddress(window.checkoutConfig.giftRegistry.id));\n    }\n\n    //Register gift registry rate processor\n    shippingRateService.registerProcessor('gift-registry', shippingRateProcessor);\n\n    //Register gist registry save shipping address processor\n    shippingSaveProcessor.registerProcessor('gift-registry', giftRegistryShippingSaveProcessor);\n\n    /** Add view logic here if needed */\n    return Component.extend({});\n});\n","Magento_GiftRegistry/js/view/shipping-address/address-renderer/gift-registry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko',\n    'uiComponent',\n    'Magento_Checkout/js/action/select-shipping-address',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Checkout/js/checkout-data'\n], function (ko, Component, selectShippingAddressAction, quote, checkoutData) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_GiftRegistry/shipping-address/address-renderer/gift-registry'\n        }
2,\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super();\n            this.isSelected = ko.computed(function () {\n                var isSelected = false,\n                    shippingAddress = quote.shippingAddress();\n\n                if (shippingAddress) {\n                    isSelected = shippingAddress.getKey() == this.address().getKey(); //eslint-disable-line eqeqeq\n                }\n\n                return isSelected;\n            }, this);\n\n            return this;\n        },\n\n        /** Set selected customer shipping address  */\n        selectAddress: function () {\n            selectShippingAddressAction(this.address());\n            checkoutData.setSelectedShippingAddress(this.address().getKey());\n        }\n    });\n});\n","Magento_ProductVideo/js/fotorama-add-video-events.js":"/**\n * Copyright 2015 Adobe\n * All Rights Reserved.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget',\n    'catalogGallery',\n    'loadPlayer'\n], function ($) {\n    'use strict';\n\n    /**\n     * @private\n     */\n    var allowBase = true; //global var is needed because fotorama always fully reloads events in case of fullscreen\n\n    /**\n     * @private\n     */\n    function parseHref(href) {\n        var a = document.createElement('a');\n\n        a.href = href;\n\n        return a;\n    }\n\n    /**\n     * @private\n     */\n    function parseURL(href, forceVideo) {\n        var id,\n            type,\n            ampersandPosition,\n            vimeoRegex,\n            useYoutubeNocookie = false;\n\n        /**\n         * Get youtube ID\n         * @param {String} srcid\n         * @returns {{}}\n         */\n        function _getYoutubeId(srcid) {\n            if (srcid) {\n                ampersandPosition = srcid.indexOf('&');\n\n                if (ampersandPosition === -1) {\n                    return srcid;\n                }\n\n                srcid = srcid.substring(0, ampersandPosition);\n            }\n\n            return srcid;\n        }\n\n        if (typeof href !== 'string') {\n            return href;\n        }\n\n        href = parseHref(href);\n\n        if (href.host.match(/youtube\\.com/) && href.search) {\n            id = href.search.split('v=')[1];\n\n            if (id) {\n                id = _getYoutubeId(id);\n                type = 'youtube';\n            }\n        } else if (href.host.match(/youtube\\.com|youtu\\.be|youtube-nocookie.com/)) {\n            id = href.pathname.replace(/^\\/(embed\\/|v\\/)?/, '').replace(/\\/.*/, '');\n            type = 'youtube';\n\n            if (href.host.match(/youtube-nocookie.com/)) {\n                useYoutubeNocookie = true;\n            }\n        } else if (href.host.match(/vimeo\\.com/)) {\n            type = 'vimeo';\n            vimeoRegex = new RegExp(['https?:\\\\/\\\\/(?:www\\\\.|player\\\\.)?vimeo.com\\\\/(?:channels\\\\/(?:\\\\w+\\\\/)',\n                '?|groups\\\\/([^\\\\/]*)\\\\/videos\\\\/|album\\\\/(\\\\d+)\\\\/video\\\\/|video\\\\/|)(\\\\d+)(?:$|\\\\/|\\\\?)'\n            ].join(''));\n            id = href.href.match(vimeoRegex)[3];\n        }\n\n        if ((!id || !type) && forceVideo) {\n            id = href.href;\n            type = 'custom';\n        }\n\n        return id ? {\n            id: id, type: type, s: href.search.replace(/^\\?/, ''), useYoutubeNocookie: useYoutubeNocookie\n        } : false;\n    }\n\n    //create AddFotoramaVideoEvents widget\n    $.widget('mage.AddFotoramaVideoEvents', {\n        options: {\n            videoData: '',\n            videoSettings: '',\n            optionsVideoData: '',\n            dataMergeStrategy: 'replace'\n        },\n\n        /**\n         * @private\n         */\n        onVimeoJSFramework: function () {},\n        defaultVideoData: [],\n        PV: 'product-video', // [CONST]\n        VU: 'video-unplayed',\n        PVLOADED: 'fotorama__product-video--loaded', // [CONST]\n        PVLOADING: 'fotorama__product-video--loading', // [CONST]\n        VID: 'video', // [CONST]\n        VI: 'vimeo', // [CONST]\n        FTVC: 'fotorama__video-close',\n        FTAR: 'fotorama__arr',\n        fotoramaSpinner: 'fotorama__spinner',\n        fotoramaSpinnerShow: 'fotorama__spinner--show',\n        TI: 'video-thumb-icon',\n        isFullscreen: false,\n        FTCF: '[data-gallery-role=\"fotorama__fullscreen-icon\"]',\n        Base: 0, //on check for video is base this setting become true if there is any video with base role\n        MobileMaxWidth: 767,\n        GP: 'gallery-placeholder', //gallery placeholder class is needed to find and erase <script> tag\n        videoData: null,\n        videoDataPlaceholder: [{\n            id: '',\n            isBase: true,\n            mediaType: 'image',\n            provider: ''\n        }
2],\n\n        /**\n         * Creates widget\n         * @private\n         */\n        _create: function () {\n            if (!this.defaultVideoData.length) {\n                this.defaultVideoData = this.options.videoData;\n            }\n\n            // If product does not have images, no video data generated,\n            // but for configurable product we still need a video data, in case of 'prepend' gallery strategy.\n            if (!this.defaultVideoData.length && !this.options.videoData.length) {\n                this.defaultVideoData = this.options.videoData = this.videoDataPlaceholder;\n            }\n            this._initializeOnGalleryLoaded();\n        },\n\n        /**\n         *\n         * @private\n         */\n        _initialize: function () {\n            this.clearEvents();\n\n            if (this._checkForVideoExist()) {\n                this._checkFullscreen();\n                this._listenForFullscreen();\n                this._isVideoBase();\n                this._initFotoramaVideo();\n                this._attachFotoramaEvents();\n            }\n        },\n\n        /**\n         * Initializes after gallery is loaded\n         *\n         * @private\n         */\n        _initializeOnGalleryLoaded: function () {\n            $(this.element).data('gallery') ?\n                this._onGalleryLoaded() :\n                $(this.element).on('gallery:loaded', this._onGalleryLoaded.bind(this));\n        },\n\n        /**\n         * Callback which fired after gallery gets initialized.\n         */\n        _onGalleryLoaded: function () {\n            this.fotoramaItem = $(this.element).find('.fotorama-item');\n            this._initialize();\n        },\n\n        /**\n         * Clear gallery events to prevent duplicated calls.\n         *\n         * @private\n         */\n        clearEvents: function () {\n            if (this.fotoramaItem !== undefined) {\n                this.fotoramaItem.off(\n                    'fotorama:show.' + this.PV +\n                    ' fotorama:showend.' + this.PV +\n                    ' fotorama:fullscreenenter.' + this.PV +\n                    ' fotorama:fullscreenexit.' + this.PV\n                );\n            }\n        },\n\n        /**\n         *\n         * @param {Object} options\n         * @private\n         */\n        _setOptions: function (options) {\n            if (options.videoData && options.videoData.length) {\n                this.options.videoData = options.videoData;\n            }\n\n            this._loadVideoData(options);\n            this._initializeOnGalleryLoaded();\n        },\n\n        /**\n         * Set video data for configurable product.\n         *\n         * @param {Object} options\n         * @private\n         */\n        _loadVideoData: function (options) {\n            if (options.selectedOption) {\n                if (options.dataMergeStrategy === 'prepend') {\n                    this.options.videoData = [].concat(\n                        this.options.optionsVideoData[options.selectedOption],\n                        this.defaultVideoData\n                    );\n                } else {\n                    this.options.videoData = this.options.optionsVideoData[options.selectedOption];\n                }\n            } else {\n                this.options.videoData = this.defaultVideoData;\n            }\n        },\n\n        /**\n         *\n         * @private\n         */\n        _checkFullscreen: function () {\n            if (this.fotoramaItem.data('fotorama').fullScreen || false) {\n                this.isFullscreen = true;\n            }\n        },\n\n        /**\n         *\n         * @private\n         */\n        _listenForFullscreen: function () {\n            this.fotoramaItem.on('fotorama:fullscreenenter.' + this.PV, $.proxy(function () {\n                this.isFullscreen = true;\n            }, this));\n\n            this.fotoramaItem.on('fotorama:fullscreenexit.' + this.PV, $.proxy(function () {\n                this.isFullscreen = false;\n                this._hideVideoArrows();\n            }, this));\n        },\n\n        /**\n         *\n         * @param {Object} inputData\n         * @param {bool} isJSON\n         * @returns {{}}\n         * @private\n         */\n        _createVideoData: function (inputData, isJSON) {\n            var videoData = [],\n                dataUrl,\n                tmpVideoData,\n                tmpInputData,\n                i;\n\n            if (isJSON) {\n                inputData = JSON.parse(inputData);\n            }\n\n            for (i = 0; i < inputData.length;
2 i++) {\n                tmpInputData = inputData[i];\n                dataUrl = '';\n                tmpVideoData = {\n                    mediaType: '',\n                    isBase: '',\n                    id: '',\n                    provider: ''\n                };\n                tmpVideoData.mediaType = this.VID;\n\n                if (tmpInputData.mediaType !== 'external-video') {\n                    tmpVideoData.mediaType = tmpInputData.mediaType;\n                }\n\n                tmpVideoData.isBase = tmpInputData.isBase;\n\n                if (tmpInputData.videoUrl && tmpInputData.videoUrl !== null) {\n                    dataUrl = tmpInputData.videoUrl;\n                    dataUrl = parseURL(dataUrl);\n                    tmpVideoData.id = dataUrl.id;\n                    tmpVideoData.provider = dataUrl.type;\n                    tmpVideoData.videoUrl = tmpInputData.videoUrl;\n                    tmpVideoData.useYoutubeNocookie = dataUrl.useYoutubeNocookie;\n                }\n\n                videoData.push(tmpVideoData);\n            }\n\n            return videoData;\n        },\n\n        /**\n         *\n         * @param {Object} fotorama\n         * @param {bool} isBase\n         * @private\n         */\n        _createCloseVideo: function (fotorama, isBase) {\n            var closeVideo;\n\n            this.fotoramaItem.find('.' + this.FTVC).remove();\n            this.fotoramaItem.append('<div class=\"' + this.FTVC + '\"></div>');\n            this.fotoramaItem.css('position', 'relative');\n            closeVideo = this.fotoramaItem.find('.' + this.FTVC);\n            this._closeVideoSetEvents(closeVideo, fotorama);\n\n            if (\n                isBase &&\n                this.options.videoData[fotorama.activeIndex].isBase &&\n                $(window).width() > this.MobileMaxWidth) {\n                this._showCloseVideo();\n            }\n        },\n\n        /**\n         *\n         * @private\n         */\n        _hideCloseVideo: function () {\n            this.fotoramaItem\n                .find('.' + this.FTVC)\n                .removeClass('fotorama-show-control');\n        },\n\n        /**\n         *\n         * @private\n         */\n        _showCloseVideo: function () {\n            this.fotoramaItem\n                .find('.' + this.FTVC)\n                .addClass('fotorama-show-control');\n        },\n\n        /**\n         *\n         * @param {jQuery} $closeVideo\n         * @param {jQuery} fotorama\n         * @private\n         */\n        _closeVideoSetEvents: function ($closeVideo, fotorama) {\n            $closeVideo.on('click', $.proxy(function () {\n                this._unloadVideoPlayer(fotorama.activeFrame.$stageFrame.parent(), fotorama, true);\n                this._hideCloseVideo();\n            }, this));\n        },\n\n        /**\n         *\n         * @returns {Boolean}\n         * @private\n         */\n        _checkForVideoExist: function () {\n            var key, result, checker, videoSettings;\n\n            if (!this.options.videoData) {\n                return false;\n            }\n\n            if (!this.options.videoSettings) {\n                return false;\n            }\n\n            result = this._createVideoData(this.options.videoData, false);\n            checker = false;\n            videoSettings = this.options.videoSettings[0];\n            videoSettings.playIfBase = parseInt(videoSettings.playIfBase, 10);\n            videoSettings.showRelated = parseInt(videoSettings.showRelated, 10);\n            videoSettings.videoAutoRestart = parseInt(videoSettings.videoAutoRestart, 10);\n\n            for (key in result) {\n                if (result[key].mediaType === this.VID) {\n                    checker = true;\n                }\n            }\n\n            if (checker) {\n                this.options.videoData = result;\n            }\n\n            return checker;\n        },\n\n        /**\n         *\n         * @private\n         */\n        _isVideoBase: function () {\n            var allVideoData = this.options.videoData,\n                videoItem,\n                allVideoDataKeys,\n                key,\n                i;\n\n            allVideoDataKeys = Object.keys(allVideoData);\n\n            for (i = 0; i < allVideoDataKeys.length;
2 i++) {\n                key = allVideoDataKeys[i];\n                videoItem = allVideoData[key];\n\n                if (\n                    videoItem.mediaType === this.VID && videoItem.isBase &&\n                    this.options.videoSettings[0].playIfBase && allowBase\n                ) {\n                    this.Base = true;\n                    allowBase = false;\n                }\n            }\n\n            if (!this.isFullscreen) {\n                this._createCloseVideo(this.fotoramaItem.data('fotorama'), this.Base);\n            }\n        },\n\n        /**\n         *\n         * @param {Event} e\n         * @private\n         */\n        _initFotoramaVideo: function (e) {\n            var fotorama = this.fotoramaItem.data('fotorama'),\n                thumbsParent,\n                thumbs,\n                t;\n\n            if (!fotorama.activeFrame.$navThumbFrame) {\n                this.fotoramaItem.on('fotorama:showend.' + this.PV, $.proxy(function (evt, fotoramaData) {\n                    $(fotoramaData.activeFrame.$stageFrame).removeAttr('href');\n                }, this));\n\n                this._startPrepareForPlayer(e, fotorama);\n\n                return null;\n            }\n\n            fotorama.data.map($.proxy(this._setItemType, this));\n            thumbsParent = fotorama.activeFrame.$navThumbFrame.parent();\n            thumbs = thumbsParent.find('.fotorama__nav__frame:visible');\n\n            for (t = 0; t < thumbs.length; t++) {\n                this._setThumbsIcon(thumbs.eq(t), t);\n                this._checkForVideo(e, fotorama, t + 1);\n            }\n\n            this.fotoramaItem.on('fotorama:showend.' + this.PV, $.proxy(function (evt, fotoramaData) {\n                $(fotoramaData.activeFrame.$stageFrame).removeAttr('href');\n            }, this));\n        },\n\n        /**\n         *\n         * @param {Object} elem\n         * @param {Number} i\n         * @private\n         */\n        _setThumbsIcon: function (elem, i) {\n            var fotorama = this.fotoramaItem.data('fotorama');\n\n            if (fotorama.options.nav === 'dots' && elem.hasClass(this.TI)) {\n                elem.removeClass(this.TI);\n            }\n\n            if (this.options.videoData[i] &&\n                this.options.videoData[i].mediaType === this.VID &&\n                fotorama.data[i].type ===  this.VID &&\n                fotorama.options.nav === 'thumbs') {\n                elem.addClass(this.TI);\n            }\n        },\n\n        /**\n         * Temporary solution with adding types for configurable product items\n         *\n         * @param {Object} item\n         * @param {Number} i\n         * @private\n         */\n        _setItemType: function (item, i) {\n            !item.type && (item.type = this.options.videoData[i].mediaType);\n        },\n\n        /**\n         * Attach\n         *\n         * @private\n         */\n        _attachFotoramaEvents: function () {\n            this.fotoramaItem.on('fotorama:showend.' + this.PV, $.proxy(function (e, fotorama) {\n                this._startPrepareForPlayer(e, fotorama);\n            }, this));\n\n            this.fotoramaItem.on('fotorama:show.' + this.PV, $.proxy(function (e, fotorama) {\n                this._unloadVideoPlayer(fotorama.activeFrame.$stageFrame.parent(), fotorama, true);\n            }, this));\n\n            this.fotoramaItem.on('fotorama:fullscreenexit.' + this.PV, $.proxy(function (e, fotorama) {\n                fotorama.activeFrame.$stageFrame.find('.' + this.PV).remove();\n                this._startPrepareForPlayer(e, fotorama);\n            }, this));\n        },\n\n        /**\n         * Start prepare for player\n         *\n         * @param {Event} e\n         * @param {jQuery} fotorama\n         * @private\n         */\n        _startPrepareForPlayer: function (e, fotorama) {\n            this._unloadVideoPlayer(fotorama.activeFrame.$stageFrame.parent(), fotorama, false);\n            this._checkForVideo(e, fotorama, fotorama.activeFrame.i);\n            this._checkForVideo(e, fotorama, fotorama.activeFrame.i - 1);\n            this._checkForVideo(e, fotorama, fotorama.activeFrame.i + 1);\n        },\n\n        /**\n         * Check for video\n         *\n         * @param {Event} e\n         * @param {jQuery} fotorama\n         * @param {Number} number\n         * @private\n         */\n        _checkForVideo: function (e, fotorama, number) {\n            var videoData = this.options.videoData[number - 1],\n                $image = fotorama.data[number - 1];\n\n            if ($image) {\n                !$image.type && this._setItemType($image, number - 1);\n\n                if ($image.type === 'image') {\n                    $image.$navThumbFrame && $image.$navThumbFrame.removeClass(this.TI);\n                    this._hideCloseVideo();\n\n                    return;\n                } else if ($image.$navThumbFrame && $image.type === 'video') {\n                    !$image.$navThumbFrame.hasClass(this.TI) && $image.$navThumbFrame.addClass(this.TI);\n                }\n\n                $image = $image.$stageFrame;\n            }\n\n            if ($image && videoData && videoData.mediaType === this.VID) {\n                $(fotorama.activeFrame.$stageFrame).removeAttr('href');\n                this._prepareForVideoContainer($image, videoData, fotorama, number);\n            }\n\n            if (this.isFullscreen && this.fotoramaItem.data('fotorama').activeFrame.i === number) {\n                this.fotoramaItem.data('fotorama').activeFrame.$stageFrame.trigger('click');\n            }\n        },\n\n        /**\n         * Prepare for video container\n         *\n         * @param {jQuery} $image\n         * @param {Object} videoData\n         * @param {Object} fotorama\n         * @param {Number} number\n         * @private\n         */\n        _prepareForVideoContainer: function ($image, videoData, fotorama, number) {\n            $image.addClass('fotorama-video-container').addClass(this.VU);\n            this._createVideoContainer(videoData, $image);\n            this._setVideoEvent($image, this.PV, fotorama, number);\n        },\n\n        /**\n         * Create video container\n         *\n         * @param {Object} videoData\n         * @param {jQuery} $image\n         * @private\n         */\n        _createVideoContainer: function (videoData, $image) {\n            var videoSettings;\n\n            videoSettings = this.options.videoSettings[0];\n            $image.find('.' + this.PV).remove();\n            $image.append(\n                '<div class=\"' +\n                this.PV +\n                '\" data-related=\"' +\n                videoSettings.showRelated +\n                '\" data-loop=\"' +\n                videoSettings.videoAutoRestart +\n                '\" data-type=\"' +\n                videoData.provider +\n                '\" data-code=\"' +\n                videoData.id +\n                '\"  data-youtubenocookie=\"' +\n                videoData.useYoutubeNocookie +\n                '\" data-width=\"100%\" data-height=\"100%\"></div>'\n            );\n        },\n\n        /**\n         *\n         * @param {Object} $image\n         * @param {Object} PV\n         * @param {Object} fotorama\n         * @param {Number} number\n         * @private\n         */\n        _setVideoEvent: function ($image, PV, fotorama, number) {\n            $image.find('.magnify-lens').remove();\n            $image\n                .off('click tap', $.proxy(this._clickHandler, this))\n                .on('click tap', $.proxy(this._clickHandler, this));\n            this._handleBaseVideo(fotorama, number); //check for video is it base and handle it if it's base\n        },\n\n        /**\n         * Hides preview arrows above video player.\n         * @private\n         */\n        _hideVideoArrows: function () {\n            var arrows = $('.' + this.FTAR);\n\n            arrows.removeClass('fotorama__arr--shown');\n            arrows.removeClass('fotorama__arr--hidden');\n        },\n\n        /**\n         * @private\n         */\n        _showLoader: function () {\n            var spinner = this.fotoramaItem.find('.' + this.fotoramaSpinner);\n\n            spinner.addClass(this.fotoramaSpinnerShow);\n            this.fotoramaItem.data('fotorama').activeFrame.$stageFrame.addClass(this.PVLOADING);\n        },\n\n        /**\n         * @private\n         */\n        _hideLoader: function () {\n            var spinner = this.fotoramaItem.find('.' + this.fotoramaSpinner);\n\n            spinner.removeClass(this.fotoramaSpinnerShow);\n            this.fotoramaItem.data('fotorama').activeFrame.$stageFrame.removeClass(this.PVLOADING);\n        },\n\n        /**\n         * @param {Event} event\n         * @private\n         */\n        _clickHandler: function (event) {\n            var type;\n\n            if ($(event.target).hasClass(this.VU) && $(event.target).find('iframe').length === 0) {\n                $(event.target).removeClass(this.VU);\n                type = $(event.target).find('.' + this.PV).data('type');\n\n                if (type === this.VI) {\n                    $(event.target).find('.' + this.PV).productVideoLoader();\n                } else if (type === this.VI) {\n                    this._showLoader();\n                    this.onVimeoJSFramework = function () {\n                        $(event.target).find('.' + this.PV).productVideoLoader();\n                        this._hideLoader();\n                    }.bind(this);\n                } else {\n                    $(event.target).find('.' + this.PV).productVideoLoader();\n                }\n\n                $('.' + this.FTAR).addClass(this.isFullscreen ? 'fotorama__arr--shown' : 'fotorama__arr--hidden');\n                $('.' + this.FTVC).addClass('fotorama-show-control');\n            }\n        },\n\n        /**\n         * Handle base video\n         * @param {Object} fotorama\n         * @param {Number} srcNumber\n         * @private\n         */\n        _handleBaseVideo: function (fotorama, srcNumber) {\n            var videoData = this.options.videoData,\n                activeIndex = fotorama.activeIndex,\n                number = parseInt(srcNumber, 10),\n                activeIndexIsBase = videoData[activeIndex];\n\n            if (!this.Base) {\n                return;\n            }\n\n            if (activeIndexIsBase && number === 1 && $(window).width() > this.MobileMaxWidth) {\n                setTimeout($.proxy(function () {\n                    fotorama.requestFullScreen();\n                    this.fotoramaItem.data('fotorama').activeFrame.$stageFrame.trigger('click');\n                    this.Base = false;\n                }, this), 50);\n            }\n        },\n\n        /**\n         * Destroy video player\n         * @param {jQuery} $wrapper\n         * @param {jQuery} current\n         * @param {bool} close\n         * @private\n         */\n        _unloadVideoPlayer: function ($wrapper, current, close) {\n            var self = this;\n\n            if (!$wrapper) {\n                return;\n            }\n\n            $wrapper.find('.' + this.PVLOADED).removeClass(this.PVLOADED);\n            this._hideLoader();\n\n            $wrapper.find('.' + this.PV).each(function () {\n                var $item = $(this).parent(),\n                    cloneVideoDiv,\n                    iframeElement = $(this).find('iframe'),\n                    currentIndex,\n                    itemIndex;\n\n                if (iframeElement.length === 0) {\n                    return;\n                }\n\n                currentIndex = current.activeFrame.$stageFrame.index();\n                itemIndex = $item.index();\n\n                if (currentIndex === itemIndex && !close) {\n                    return;\n                }\n\n                if (currentIndex !== itemIndex && close) {\n                    return;\n                }\n\n                iframeElement.remove();\n                cloneVideoDiv = $(this).clone();\n                $(this).remove();\n                $item.append(cloneVideoDiv);\n                $item.addClass(self.VU);\n\n                self._hideCloseVideo();\n                self._hideVideoArrows();\n\n                if (self.isFullscreen && !self.fotoramaItem.data('fotorama').options.fullscreen.arrows) {\n                    if ($('.' + self.FTAR + '--prev').is(':focus') || $('.' + self.FTAR + '--next').is(':focus')) {\
2n                        $(self.FTCF).trigger('focus');\n                    }\n                }\n            });\n        }\n    });\n\n    return $.mage.AddFotoramaVideoEvents;\n});\n","Magento_ProductVideo/js/load-player.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n @version 0.0.1\n @requires jQuery & jQuery UI\n */\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget',\n    'vimeoWrapper'\n], function ($) {\n    'use strict';\n\n    var videoRegister = {\n        _register: {},\n\n        /**\n         * Checks, if api is already registered\n         *\n         * @param {String} api\n         * @returns {bool}\n         */\n        isRegistered: function (api) {\n            return this._register[api] !== undefined;\n        },\n\n        /**\n         * Checks, if api is loaded\n         *\n         * @param {String} api\n         * @returns {bool}\n         */\n        isLoaded: function (api) {\n            return this._register[api] !== undefined && this._register[api] === true;\n        },\n\n        /**\n         * Register new video api\n         * @param {String} api\n         * @param {bool} loaded\n         */\n        register: function (api, loaded) {\n            loaded = loaded || false;\n            this._register[api] = loaded;\n        }\n    };\n\n    $.widget('mage.productVideoLoader', {\n\n        /**\n         * @private\n         */\n        _create: function () {\n            switch (this.element.data('type')) {\n                case 'youtube':\n                    this.element.videoYoutube();\n                    this._player = this.element.data('mageVideoYoutube');\n                    break;\n\n                case 'vimeo':\n                    this.element.videoVimeo();\n                    this._player = this.element.data('mageVideoVimeo');\n                    break;\n                default:\n                    throw {\n                        name: 'Video Error',\n                        message: 'Unknown video type',\n\n                        /**\n                         * join name with message\n                         */\n                        toString: function () {\n                            return this.name + ': ' + this.message;\n                        }\n                    };\n            }\n        },\n\n        /**\n         * Initializes variables\n         * @private\n         */\n        _initialize: function () {\n            this._params = this.element.data('params') || {};\n            this._code = this.element.data('code');\n            this._width = this.element.data('width');\n            this._height = this.element.data('height');\n            this._autoplay = !!this.element.data('autoplay');\n            this._playing = this._autoplay || false;\n            this._loop = this.element.data('loop');\n            this._rel = this.element.data('related');\n            this.useYoutubeNocookie = this.element.data('youtubenocookie') || false;\n\n            this._responsive = this.element.data('responsive') !== false;\n\n            if (this._responsive === true) {\n                this.element.addClass('responsive');\n            }\n\n            this._calculateRatio();\n        },\n\n        /**\n         * Abstract play command\n         */\n        play: function () {\n            this._player.play();\n        },\n\n        /**\n         * Abstract pause command\n         */\n        pause: function () {\n            this._player.pause();\n        },\n\n        /**\n         * Abstract stop command\n         */\n        stop: function () {\n            this._player.stop();\n        },\n\n        /**\n         * Abstract playing command\n         */\n        playing: function () {\n            return this._player.playing();\n        },\n\n        /**\n         * Calculates ratio for responsive videos\n         * @private\n         */\n        _calculateRatio: function () {\n            if (!this._responsive) {\n                return;\n            }\n            this.element.css('paddingBottom', this._height / this._width * 100 + '%');\n        }\n    });\n\n    $.widget('mage.videoYoutube', $.mage.productVideoLoader, {\n\n        /**\n         * Initialization of the Youtube widget\n         * @private\n         */\n        _create: function () {\n            var self = this;\n\n            this._initialize();\n\n            this.element.append('<div></div>');\n\n            this._on(window, {\n\n                /**\n                 * Handle event\n                 */\n                'youtubeapiready': function () {\n                    var host = 'https://www.youtube.com';\n\n                    if (self.useYoutubeNocookie) {\n                        host = 'https://www.youtube-nocookie.com';\n                    }\n\n                    if (self._player !== undefined) {\n                        return;\n                    }\n                    self._autoplay = true;\n\n                    if (self._autoplay) {\n                        self._params.autoplay = 1;\n                    }\n\n                    if (!self._rel) {\n                        self._params.rel = 0;\n                    }\n\n                    self._player = new window.YT.Player(self.element.children(':first')[0], {\n                        height: self._height,\n                        width: self._width,\n                        videoId: self._code,\n                        playerVars: self._params,\n                        host: host,\n                        events: {\n\n                            /**\n                             * Get duration\n                             */\n                            'onReady': function onPlayerReady() {\
2n                                self._player.getDuration();\n                                self.element.closest('.fotorama__stage__frame')\n                                    .addClass('fotorama__product-video--loaded');\n                            },\n\n                            /**\n                             * Event observer\n                             */\n                            onStateChange: function (data) {\n                                switch (window.parseInt(data.data, 10)) {\n                                    case 1:\n                                        self._playing = true;\n                                        break;\n                                    default:\n                                        self._playing = false;\n                                        break;\n                                }\n\n                                self._trigger('statechange', {}, data);\n\n                                if (data.data === window.YT.PlayerState.ENDED && self._loop) {\n                                    self._player.playVideo();\n                                }\n                            }\n                        }\n\n                    });\n                }\n            });\n\n            this._loadApi();\n        },\n\n        /**\n         * Loads Youtube API and triggers event, when loaded\n         * @private\n         */\n        _loadApi: function () {\n            var element,\n                scriptTag;\n\n            if (videoRegister.isRegistered('youtube')) {\n                if (videoRegister.isLoaded('youtube')) {\n                    $(window).trigger('youtubeapiready');\n                }\n\n                return;\n            }\n\n            // if script already loaded by other library\n            if (window.YT) {\n                videoRegister.register('youtube', true);\n                $(window).trigger('youtubeapiready');\n\n                return;\n            }\n            videoRegister.register('youtube');\n\n            element = document.createElement('script');\n            scriptTag = document.getElementsByTagName('script')[0];\n\n            element.async = true;\n            element.src = 'https://www.youtube.com/iframe_api';\n            scriptTag.parentNode.insertBefore(element, scriptTag);\n\n            /**\n             * Event observe and handle\n             */\n            window.onYouTubeIframeAPIReady = function () {\n                $(window).trigger('youtubeapiready');\n                videoRegister.register('youtube', true);\n            };\n        },\n\n        /**\n         * Play command for Youtube\n         */\n        play: function () {\n            this._player.playVideo();\n            this._playing = true;\n        },\n\n        /**\n         * Pause command for Youtube\n         */\n        pause: function () {\n            this._player.pauseVideo();\n            this._playing = false;\n        },\n\n        /**\n         * Stop command for Youtube\n         */\n        stop: function () {\n            this._player.stopVideo();\n            this._playing = false;\n        },\n\n        /**\n         * Playing command for Youtube\n         */\n        playing: function () {\n            return this._playing;\n        },\n\n        /**\n         * stops and unloads player\n         * @private\n         */\n        _destroy: function () {\n            this.stop();\n        }\n    });\n\n    $.widget('mage.videoVimeo', $.mage.productVideoLoader, {\n\n        /**\n         * Initialize the Vimeo widget\n         * @private\n         */\n        _create: function () {\n            var timestamp,\n                additionalParams = '',\n                src,\n                id;\n\n            this._initialize();\n            timestamp = new Date().getTime();\n            this._autoplay = true;\n\n            if (this._autoplay) {\n                additionalParams += '&autoplay=1';\n            }\n\n            if (this._loop) {\n                additionalParams += '&loop=1';\n            }\n            src = 'https://player.vimeo.com/video/' +\n                this._code + '?api=1&player_id=vimeo' +\n                this._code +\n                timestamp +\n                additionalParams;
2\n            id = 'vimeo' + this._code + timestamp;\n            this.element.append(\n                $('<iframe></iframe>')\n                    .attr('frameborder', 0)\n                    .attr('id', id)\n                    .attr('width', this._width)\n                    .attr('height', this._height)\n                    .attr('src', src)\n                    .attr('webkitallowfullscreen', '')\n                    .attr('mozallowfullscreen', '')\n                    .attr('allowfullscreen', '')\n                    .attr('referrerPolicy', 'origin')\n                    .attr('allow', 'autoplay')\n            );\n\n            /* eslint-disable no-undef */\n            this._player = new Vimeo.Player(this.element.children(':first')[0]);\n\n            this._player.ready().then(function () {\n                $('#' + id).closest('.fotorama__stage__frame').addClass('fotorama__product-video--loaded');\n            });\n        },\n\n        /**\n         * Play command for Vimeo\n         */\n        play: function () {\n            this._player.play();\n            this._playing = true;\n        },\n\n        /**\n         * Pause command for Vimeo\n         */\n        pause: function () {\n            this._player.pause();\n            this._playing = false;\n        },\n\n        /**\n         * Stop command for Vimeo\n         */\n        stop: function () {\n            this._player.unload();\n            this._playing = false;\n        },\n\n        /**\n         * Playing command for Vimeo\n         */\n        playing: function () {\n            return this._playing;\n        }\n    });\n});\n","Magento_Banner/js/model/banner.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'underscore',\n    'ko',\n    'jquery/jquery-storageapi'\n], function ($, _, ko) {\n    'use strict';\n\n    var options = {\n            cacheTtl: 0,\n            sectionLoadUrl: ''\n        },\n        selectors = {\n            productIdSelector: '#product_addtocart_form [name=\"product\"]'\n        },\n        storage = $.initNamespaceStorage('mage-banners-cache-storage').localStorage,\n        productId = $(selectors.productIdSelector).val(),\n\n        /**\n         * Cache invalidation. Banner cache ttl is 30 sec by default.\n         */\n        invalidateCacheBySessionTimeOut = function () {\n            var cacheEol = new Date($.localStorage.get('mage-banners-cache-timeout')),\n                dateTo = new Date(Date.now() + options.cacheTtl),\n                cartDataId = null,\n                globalStoreId = $.cookieStorage.get('store') || 'default';\n\n            if ($.localStorage.get('mage-banners-storeId') === null) {\n                $.localStorage.set('mage-banners-storeId', globalStoreId);\n            }\n\n            if ($.localStorage.get('mage-cache-storage') !== null &&\n                $.localStorage.get('mage-cache-storage').hasOwnProperty('cart')) {\n                cartDataId = $.localStorage.get('mage-cache-storage').cart['data_id'];\n            }\n\n            if (cacheEol < new Date() ||\n                $.localStorage.get('mage-banners-storeId') !== globalStoreId ||\n                $.localStorage.get('mage-banners-cartDataId') !== cartDataId) {\n                storage.removeAll();\n                $.localStorage.set('mage-banners-cache-timeout', dateTo);\n                $.localStorage.set('mage-banners-storeId', globalStoreId);\n\n                if (cartDataId) {\n                    $.localStorage.set('mage-banners-cartDataId', cartDataId);\n                }\n            }\n        },\n        dataProvider = {\n\n            /**\n             * Request data from storage\n             *\n             * @param {Array} sectionNames\n             * @returns {Object}\n             */\n            getFromStorage: function (sectionNames) {\n                var result = {};\n\n                _.each(sectionNames, function (sectionName) {\n                    result[sectionName] = storage.get(sectionName);\n                });\n\n                return result;\n            },\n\n            /**\n             * Request data from server\n             *\n             * @param {Array} sectionNames\n             * @returns {Object}\n             */\n            getFromServer: function (sectionNames) {\n                var parameters = {\n                    'requesting_page_url': window.location.href\n                };\n\n                if (productId) {\n                    parameters.data = {\n                        'product_id': productId\n                    };\n                }\n\n                if (_.isArray(sectionNames)) {\n                    parameters.sections = sectionNames.join(',');\n                }\n\n                return $.getJSON(options.sectionLoadUrl, parameters).fail(function (jqXHR) {\n                    throw new Error(jqXHR);\n                });\n            }\n        },\n        buffer = {\n            data: {},\n\n            /**\n             * Binding parameter\n             *\n             * @param {String} sectionName\n             */\n            bind: function (sectionName) {\n                this.data[sectionName] = ko.observable({});\n            },\n\n            /**\n             *\n             * @param {String} sectionName\n             * @returns {Object}\n             */\n            get: function (sectionName) {\n                if (!this.data[sectionName]) {\n                    this.bind(sectionName);\n                }\n\n                return this.data[sectionName];\n            },\n\n            /**\n             * Get keys\n             *\n             * @returns {Array}\n             */\n            keys: function () {\n                return _.keys(this.data);\n            },\n\n            /**\n             * Notify storage\n             *\n             * @param {String} sectionName\n             * @param {Object} sectionData\n             */\n            notify: function (sectionName, sectionData) {\
2n                if (!this.data[sectionName]) {\n                    this.bind(sectionName);\n                }\n                this.data[sectionName](sectionData);\n            },\n\n            /**\n             * Update sections\n             *\n             * @param {Array} sections\n             */\n            update: function (sections) {\n                _.each(sections, function (sectionData, sectionName) {\n                    storage.set(sectionName, sectionData);\n                    buffer.notify(sectionName, sectionData);\n                });\n            }\n        },\n        banner = {\n\n            /**\n             * Initialization\n             */\n            init: function () {\n                var dataSectionName;\n\n                dataSectionName = this.getSectionName('data');\n\n                if (_.isEmpty(storage.keys()) || !storage.get(dataSectionName)) {\n                    this.reload([]);\n                } else {\n                    _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) {\n                        buffer.notify(sectionName, sectionData);\n                    });\n                }\n            },\n\n            /**\n             * Get data\n             *\n             * @param {String} sectionName\n             * @returns {*|Object}\n             */\n            get: function (sectionName) {\n                sectionName = this.getSectionName(sectionName);\n\n                return buffer.get(sectionName);\n            },\n\n            /**\n             * Set data\n             *\n             * @param {String} sectionName\n             * @param {Object} sectionData\n             */\n            set: function (sectionName, sectionData) {\n                var data = {};\n\n                sectionName = this.getSectionName(sectionName);\n                data[sectionName] = sectionData;\n                buffer.update(data);\n            },\n\n            /**\n             * Reloading from storage or server\n             *\n             * @param {Array} sectionNames\n             * @returns {Object}\n             */\n            reload: function (sectionNames) {\n                return dataProvider.getFromServer(sectionNames).done(function (sections) {\n                    _.each(sections, function (sectionData, sectionName) {\n                        this.set(sectionName, sectionData);\n                    }.bind(this));\n                }.bind(this));\n            },\n\n            /**\n             * Get section name\n             *\n             * @returns {String}\n             */\n            getSectionName: function (sectionName) {\n                var result;\n\n                result = productId && sectionName === 'data' ? 'data_product_' + productId : sectionName;\n\n                return result;\n            },\n\n            /**\n             * Init helper\n             *\n             * @param {Array} settings\n             */\n            'Magento_Banner/js/model/banner': function (settings) {\n                options = _.extend(options, settings);\n                invalidateCacheBySessionTimeOut(settings);\n                banner.init();\n            }\n        };\n\n    //TODO: remove global change, in this case made for initNamespaceStorage\n    $.cookieStorage.setConf({\n        path: '/'\n    });\n\n    return banner;\n});\n","Magento_Banner/js/view/banner.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'Magento_Banner/js/model/banner',\n    'underscore',\n    'jquery',\n    'Magento_Ui/js/lib/core/storage/local'\n], function (Component, Banner, _, $, storage) {\n    'use strict';\n\n    /**\n     * Stores banners initialized in getItems() method\n     *\n     * Prevent series reinitialization on consecutive calls to getItems() method\n     *\n     * @type {Array}\n     */\n    var initializedItems = [];\n\n    /**\n     * Returns next banner in series\n     *\n     * @param {Array} applicableBanners\n     * @param {String} rotationType\n     * @param {String} bannerId\n     * @returns {Object}\n     */\n    function getBannerFromSeries(applicableBanners, rotationType, bannerId) {\n        var storageKey,\n            series,\n            itemToDisplay,\n            storeId;\n\n        storeId = Banner.get('data')()['store_id'];\n        storageKey = rotationType + '_' + bannerId + '_' + storeId;\n        series = storage.get(storageKey);\n\n        if (!series || !series.length) {\n            series = applicableBanners;\n        }\n\n        itemToDisplay = series.shift();\n\n        if (!series.length) {\n            series = applicableBanners;\n        }\n\n        storage.set(storageKey, series);\n\n        return itemToDisplay;\n    }\n\n    /**\n     *\n     * @param {Array} applicableBanners\n     * @param {String} rotationType\n     * @param {String} bannerId\n     * @returns {Array}\n     */\n    function applyRotation(applicableBanners, rotationType, bannerId) {\n\n        var result = applicableBanners;\n\n        switch (rotationType) {\n\n            case 'random':\n                result = [applicableBanners[_.random(applicableBanners.length - 1)]];\n                break;\n\n            case 'shuffle':\n                result = _.shuffle(applicableBanners);\n                result = [getBannerFromSeries(result, rotationType, bannerId)];\n                break;\n\n            case 'series':\n                result = [getBannerFromSeries(applicableBanners, rotationType, bannerId)];\n                break;\n        }\n\n        return result;\n    }\n\n    /**\n     * @param {Object} bannerConfig\n     */\n    function getItems(bannerConfig) {\n        var applicableBanners = [],\n            displayMode = bannerConfig.data('display-mode'),\n            allowedBannerTypes = bannerConfig.data('types'),\n            assignedBannerIds = bannerConfig.data('ids') + '',\n            rotationType = bannerConfig.data('rotate'),\n            blockId = bannerConfig.data('banner-id');\n\n        if (!initializedItems[blockId] && !_.isEmpty(Banner.get('data')().items)) {\n            applicableBanners = _.toArray(Banner.get('data')().items[displayMode]);\n\n            if (!_.isEmpty(assignedBannerIds)) {\n                assignedBannerIds = assignedBannerIds ? assignedBannerIds.split(',') : null;\n                applicableBanners = _.filter(applicableBanners, function (banner) {\n                    return !assignedBannerIds ? true : _.contains(assignedBannerIds, banner.id);\n                });\n                applicableBanners = _.sortBy(applicableBanners, function (banner) {\n                    return _.indexOf(assignedBannerIds, banner.id);\n                });\n            }\n\n            if (_.isEmpty(assignedBannerIds) && displayMode === 'fixed') {\n                applicableBanners = [];\n            }\n\n            /**\n             * In case allowedBannerTypes is empty filtering by type must not be performed\n             */\n            if (!_.isEmpty(allowedBannerTypes) && !_.isEmpty(applicableBanners)) {\n                allowedBannerTypes = allowedBannerTypes ? allowedBannerTypes.split(',') : null;\n                applicableBanners = _.filter(applicableBanners, function (banner) {\n                    return !allowedBannerTypes || _.isEmpty(banner.types) ?  true : !_.isEmpty(\n                        _.intersection(allowedBannerTypes, banner.types)\n                    );\n                });\n            }\n\n            initializedItems[blockId] = [];\n\n            if (!_.isEmpty(applicableBanners)) {\n                applicableBanners = applyRotation(applicableBanners, rotationType, blockId);\n                _.each(applicableBanners, function (banner) {\n                    initializedItems[blockId].push({\n                        html: banner.content,\n                        bannerId: banner.id\n                    });\n                });\n            }\n        }\n\n        return initializedItems[blockId];\n    }\n\n    return Component.extend({\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n            this.banner = Banner.get('data');\n        },\n\n        /**\n         * Register method after element render to have access to banner items.\n         *\n         * @param {HTMLElement} el\n         */\n        registerBanner: function (el) {\n            var banner = $(el.parentElement);\n\n            this['getItems' + banner.data('banner-id')] = getItems.bind(\n                null,\n                banner\n            );\n        }\n    });\n});\n","Magento_CheckoutAddressSearch/js/modal-component.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Ui/js/modal/modal-component'\n], function (Modal) {\n    'use strict';\n\n    return Modal.extend({\n\n        /**\n         * Wrap content in a modal of certain type\n         *\n         * @param {HTMLElement} element\n         * @returns {Object} Chainable.\n         */\n        initModal: function (element) {\n            this.modal = null;\n            this._super(element);\n\n            return this;\n        }\n    });\n});\n","Magento_CheckoutAddressSearch/js/view/billing-address.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'jquery',\n    'mage/translate',\n    'Magento_Checkout/js/view/billing-address',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Checkout/js/action/select-billing-address',\n    'Magento_Checkout/js/checkout-data',\n    'Magento_Ui/js/modal/modal',\n    'Magento_Checkout/js/action/create-billing-address',\n    'Magento_Customer/js/model/address-list',\n    'Magento_Ui/js/lib/view/utils/async'\n], function (_, $, $t, Component, quote, selectBillingAddress, checkoutData, modal, createBillingAddress, addressList) {\n    'use strict';\n\n    var lastSelectedBillingAddress = null;\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_CheckoutAddressSearch/billing-address',\n            detailsTemplate: 'Magento_CheckoutAddressSearch/billing-address/details',\n            selectBillingAddressProvider: '',\n            isNewAddressAdded: false,\n            newCustomerBillingAddress: null,\n            popUpButtons: {\n                save: {\n                    text: $t('Save Address'),\n                    class: 'action primary action-save-address'\n                },\n                cancel: {\n                    text: $t('Cancel'),\n                    class: 'action secondary action-hide-popup'\n                }\n            },\n            popUpForm: {\n                element: '.new-billing-address-form',\n                options: {\n                    type: 'popup',\n                    responsive: true,\n                    innerScroll: true,\n                    title: $t('Billing Address')\n                }\n            },\n            modules: {\n                selectBillingAddress: '${ $.selectBillingAddressProvider }'\n            },\n            noAddressMessage: $t('No address selected')\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n            this.isNewAddressAdded(!!checkoutData.getNewCustomerBillingAddress());\n\n            if (this.isNewAddressAdded()) {\n                this.newCustomerBillingAddress(createBillingAddress(checkoutData.getNewCustomerBillingAddress()));\n            }\n\n            quote.billingAddress.subscribe(function (addressOption) {\n                if (!addressOption) {\n                    _.each(addressList(), function (address) {\n                        if (address.isDefaultBilling && address.isDefaultBilling()) {\n                            selectBillingAddress(address);\n                            checkoutData.setSelectedBillingAddress(address.getKey());\n                        }\n                    }, this);\n                }\n            }, this);\n\n            $.async({\n                component: this,\n                selector: this.popUpForm.element\n            }, this.initPopup.bind(this));\n\n            return this;\n        }
2,\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super()\n                .observe('isNewAddressAdded newCustomerBillingAddress');\n\n            quote.billingAddress.subscribe(function () {\n                this.isAddressFormVisible(false);\n            }, this);\n\n            return this;\n        },\n\n        /** @inheritdoc */\n        useShippingAddress: function () {\n            if (this.isAddressSameAsShipping()) {\n                lastSelectedBillingAddress = quote.billingAddress();\n                selectBillingAddress(quote.shippingAddress());\n                checkoutData.setSelectedBillingAddress(quote.shippingAddress().getKey());\n                this.updateAddresses();\n            } else if (lastSelectedBillingAddress &&\n                lastSelectedBillingAddress.getCacheKey() !== quote.billingAddress().getCacheKey()\n            ) {\n                selectBillingAddress(lastSelectedBillingAddress);\n                checkoutData.setSelectedBillingAddress(lastSelectedBillingAddress.getKey());\n                this.updateAddresses();\n            }\n\n            return true;\n        },\n\n        /**\n         * Edit address action.\n         */\n        editAddress: function () {\n            this.showFormPopUp();\n        },\n\n        /**\n         * Cancel address edit action.\n         */\n        cancelAddressEdit: function () {\n            checkoutData.setBillingAddressFromData($.extend(true, {}, this.temporaryAddress));\n            this.closeFormPopUp();\n        },\n\n        /**\n         * Init form for billing address.\n         *\n         * @param {HTMLElement} element\n         */\n        initPopup: function (element) {\n            this.popUpForm.options.buttons = [\n                {\n                    text: this.popUpButtons.save.text,\n                    class: this.popUpButtons.save.class,\n                    click: function () {\n                        this.updateAddress();\n\n                        if (!this.source.get('params.invalid')) {\n                            this.isNewAddressAdded(true);\n                            this.closeFormPopUp();\n                        }\n                    }.bind(this)\n                },\n                {\n                    text: this.popUpButtons.cancel.text,\n                    class: this.popUpButtons.cancel.class,\n                    click: this.cancelAddressEdit.bind(this)\n                }\n            ];\n\n            this.popUpForm.options.modalCloseBtnHandler = this.cancelAddressEdit.bind(this);\n            this.popUpForm.options.keyEventHandlers = {\n                escapeKey: this.cancelAddressEdit.bind(this)\n            };\n\n            /** @inheritdoc */\n            this.popUpForm.options.opened = function () {\n                // Store temporary address for revert action in case when user click cancel action\n                this.temporaryAddress = $.extend(true, {}, checkoutData.getBillingAddressFromData());\n            }.bind(this);\n\n            this.popUp = modal(this.popUpForm.options, $(element));\n        },\n\n        /**\n         * Show from popUp.\n         */\n        showFormPopUp: function () {\n            this.isAddressFormVisible(true);\n            this.popUp.openModal();\n        },\n\n        /**\n         * Close from popUp.\n         */\n        closeFormPopUp: function () {\n            this.isAddressFormVisible(false);\n            this.popUp.closeModal();\n        },\n\n        /**\n         * Open address selection modal.\n         */\n        openAddressSelection: function () {\n            this.selectBillingAddress().openModal();\n        },\n\n        /** @inheritdoc */\n        updateAddress: function () {\n            this._super();\n\n            if (!this.selectedAddress() || this.isAddressFormVisible()) {\n                this.newCustomerBillingAddress(createBillingAddress(checkoutData.getNewCustomerBillingAddress()));\n            }\n        },\n\n        /**\n         * Is address editable.\n         *\n         * @param {Object} address\n         * @returns {Boolean}\n         */\n        isAddressEditable: function (address) {\n            if (address) {\n                return address.getType() === 'new-customer-billing-address';\n            }\n        }\n    });\n});\n","Magento_CheckoutAddressSearch/js/view/billing-address/ui-select.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'Magento_Ui/js/form/element/ui-select',\n    'Magento_Checkout/js/action/select-billing-address',\n    'Magento_Checkout/js/checkout-data',\n    'Magento_Customer/js/model/customer/address',\n    'Magento_Customer/js/customer-data',\n    'Magento_Checkout/js/model/quote'\n], function (_, Select, selectBillingAddress, checkoutData, Address, customerData, quote) {\n    'use strict';\n\n    var countryData = customerData.get('directory-data');\n\n    return Select.extend({\n        defaults: {\n            addressTmpl: 'Magento_CheckoutAddressSearch/billing-address/address-renderer/item',\n            modal: '${$.parentName}',\n            quantityPlaceholder: 'addresses',\n            value: {},\n            billingAddressProvider: '',\n            isNewAddressAdded: false,\n            imports: {\n                isNewAddressAdded: '${ $.billingAddressProvider }:isNewAddressAdded',\n                newCustomerBillingAddress: '${ $.billingAddressProvider }:newCustomerBillingAddress'\n            },\n            listens: {\n                newCustomerBillingAddress: 'onChangeNewCustomerBillingAddress'\n            },\n            modules: {\n                modal: '${ $.modal }',\n                billingAddress: '${ $.billingAddressProvider }'\n            },\n            newAddressInSearchResult: false\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n\n            this._setItemsQuantity(this.total);\n        },\n\n        /** @inheritdoc */\n        initConfig: function () {\n            var existingOptions = [];\n\n            this._super();\n\n            if (this.newCustomerBillingAddress) {\n                existingOptions.push(this.newCustomerBillingAddress);\n            }\n\n            _.each(this.options, function (option) {\n                existingOptions.push(new Address(option));\n            });\n\n            this.options = this.sortAddresses(existingOptions);\n\n            return this;\n        }
2,\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super()\n                .observe('isNewAddressAdded');\n\n            quote.billingAddress.subscribe(function (address) {\n                if (address) {\n                    this.value(address);\n                }\n            }, this);\n\n            return this;\n        },\n\n        /**\n         * Set selected customer billing address.\n         *\n         * @param {Object} option\n         */\n        selectBillingAddress: function (option) {\n            delete option.level;\n            delete option.isVisited;\n            delete option.path;\n\n            this.value(option);\n            this.modal().closeModal();\n            selectBillingAddress(option);\n            checkoutData.setSelectedBillingAddress(option.getKey());\n            this.billingAddress().updateAddresses(true);\n        },\n\n        /**\n         * Edit address\n         */\n        editAction: function () {\n            this.modal().closeModal();\n            this.billingAddress().editAddress();\n        },\n\n        /** @inheritdoc */\n        success: function (response) {\n            var existingOptions = this.options();\n\n            _.each(response.options, function (opt) {\n                var address = new Address(opt);\n\n                // add options only if they were not added yet\n                if (!_.findWhere(existingOptions, {\n                    customerAddressId: address.id\n                })) {\n                    existingOptions.push(address);\n                }\n            });\n\n            this.total = response.total;\n            this.newAddressInSearchResult = false;\n\n            if (this.newCustomerBillingAddress) {\n                existingOptions.push(this.newCustomerBillingAddress);\n            }\n\n            this.options(this.sortAddresses(existingOptions));\n        },\n\n        /**\n         * Sort addresses.\n         *\n         * Sort addresses in such way that new address and default one are displayed on the top of results\n         * if one of them matches search criteria or search is empty.\n         *\n         * @param {Array} existingOptions\n         * @return {Array}\n         */\n        sortAddresses: function (existingOptions) {\n            var resultOptions = [],\n                defaultAddress;\n\n            if (!_.isEmpty(this.newCustomerBillingAddress) &&\n                this.canShowNewAddress(this.newCustomerBillingAddress, this.currentSearchKey)\n            ) {\n                if (this.newAddressInSearchResult === false) {\n                    this._setItemsQuantity(++this.total);\n                }\n                this.newAddressInSearchResult = true;\n                resultOptions.push(this.newCustomerBillingAddress);\n            }\n\n            defaultAddress = _.find(existingOptions, function (address) {\n                return address.isDefaultShipping();\n            });\n\n            !_.isEmpty(defaultAddress) && resultOptions.push(defaultAddress);\n\n            return resultOptions.concat(_.filter(existingOptions, function (address) {\n                return address.getType() !== 'new-customer-billing-address' && !address.isDefaultShipping();\n            }));\n        },\n\n        /**\n         * Check if we can show address.\n         *\n         * @param {Object} address\n         * @param {String} searchKey\n         * @return {Boolean}\n         */\n        canShowNewAddress: function (address, searchKey) {\n            var searchFields = ['city', 'postcode', 'region', ['street']],\n                filteredResults = [],\n                value = '';\n\n            if (!searchKey) {\n                return true;\n            }\n\n            filteredResults = searchFields.filter(function (elem) {\n                value = address[elem];\n\n                if (_.isArray(value)) {\n                    value = value.join(' ');\n                }\n\n                return value.toLowerCase().indexOf(searchKey.toLowerCase()) !== -1;\n            });\n\n            return !!filteredResults.length;\n        },\n\n        /**\n         * Get country name.\n         *\n         * @param {String} countryId\n         * @return {String}\n         */\n        getCountryName: function (countryId) {\n            return countryData()[countryId] !== undefined ? countryData()[countryId].name : '';\n        },\n\n        /**\n         * Is address selected.\n         *\n         * @param {Object} address\n         * @returns {Boolean}\n         */\n        isAddressSelected: function (address) {\n            return !_.isEmpty(this.value()) && this.value().getKey() === address.getKey();\n        },\n\n        /**\n         * Is address editable.\n         *\n         * @param {Object} address\n         * @returns {Boolean}\n         */\n        isAddressEditable: function (address) {\n            return address.getType() === 'new-customer-billing-address';\n        },\n\n        /**\n         * On new customer billing address change.\n         *\n         * @param {Object} address\n         */\n        onChangeNewCustomerBillingAddress: function (address) {\n            var options = _.filter(this.options(), function (option) {\n                return option.getType() !== 'new-customer-billing-address';\n            });\n\n            options.push(address);\n            this.options(this.sortAddresses(options));\n        },\n\n        /**\n         * Return formatted items placeholder.\n         *\n         * @param {Object} data - option data\n         * @returns {String}
2\n         */\n        getItemsPlaceholder: function (data) {\n            var prefix = '';\n\n            if (this.lastSearchKey) {\n                prefix = 'Found ';\n            }\n\n            return prefix + data + ' ' + this.quantityPlaceholder;\n        },\n\n        /** @inheritdoc */\n        onScrollDown: function (data, event) {\n            if (this.loading() || this.options().length >= this.total) {\n                return;\n            }\n\n            this._super(data, event);\n        }\n    });\n});\n","Magento_CheckoutAddressSearch/js/view/shipping-address/selected.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'mage/translate',\n    'Magento_Customer/js/customer-data',\n    'Magento_Checkout/js/model/shipping-address/form-popup-state',\n    'Magento_Checkout/js/model/quote'\n], function (Component, $t, customerData, formPopUpState, quote) {\n    'use strict';\n\n    var countryData = customerData.get('directory-data');\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_CheckoutAddressSearch/shipping-address/selected',\n            selectShippingAddressProvider: '',\n            defaultAddress: quote.shippingAddress(),\n            isChangeAddressVisible: true,\n            modules: {\n                selectionModal: '${ $.selectShippingAddressProvider }'\n            },\n            noAddressMessage: $t('No address selected')\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super()\n                .observe('defaultAddress');\n            quote.shippingAddress.subscribe(this.onShippingAddressUpdate, this);\n\n            return this;\n        },\n\n        /**\n         * Get country name.\n         *\n         * @param {String} countryId\n         * @return {String}\n         */\n        getCountryName: function (countryId) {\n            return countryData()[countryId] !== undefined ? countryData()[countryId].name : '';\n        },\n\n        /**\n         * Edit address.\n         */\n        editAddress: function () {\n            formPopUpState.isVisible(true);\n        },\n\n        /**\n         * Open address selection modal.\n         */\n        openAddressSelection: function () {\n            this.selectionModal().openModal();\n        },\n\n        /**\n         * On shipping address update.\n         *\n         * @param {Object} address\n         */\n        onShippingAddressUpdate: function (address) {\n            this.defaultAddress(address);\n        }\n    });\n});\n","Magento_CheckoutAddressSearch/js/view/shipping-address/ui-select.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'Magento_Ui/js/form/element/ui-select',\n    'Magento_Checkout/js/action/select-shipping-address',\n    'Magento_Checkout/js/checkout-data',\n    'Magento_Customer/js/model/customer/address',\n    'Magento_Customer/js/model/address-list',\n    'Magento_Customer/js/customer-data',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Checkout/js/model/shipping-address/form-popup-state'\n], function (\n    _,\n    Select,\n    selectShippingAddressAction,\n    checkoutData,\n    Address,\n    addressList,\n    customerData,\n    quote,\n    formPopUpState\n) {\n    'use strict';\n\n    var countryData = customerData.get('directory-data');\n\n    return Select.extend({\n        defaults: {\n            addressTmpl: 'Magento_CheckoutAddressSearch/shipping-address/address-renderer/item',\n            modalProvider: '${ $.parentName }',\n            quantityPlaceholder: 'addresses',\n            modules: {\n                modal: '${ $.modalProvider }'\n            },\n            newAddressInSearchResult: false\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n\n            this._setItemsQuantity(this.total);\n        },\n\n        /** @inheritdoc */\n        initConfig: function () {\n            var existingOptions = [];\n\n            this._super();\n\n            _.each(this.options, function (option) {\n                existingOptions.push(new Address(option));\n            });\n\n            this.options = this.sortAddresses(existingOptions);\n\n            return this;\n        }
2,\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super();\n\n            this.onShippingAddressChange(quote.shippingAddress());\n            quote.shippingAddress.subscribe(this.onShippingAddressChange, this);\n\n            addressList.subscribe(function (changes) {\n                _.each(changes, function (change) {\n\n                    if (change.status === 'added' && change.value.getType() === 'new-customer-address') {\n                        this.options().push(change.value);\n                        this.options(this.sortAddresses(this.options()));\n                    }\n                }, this);\n            }, this, 'arrayChange');\n\n            return this;\n        },\n\n        /**\n         * On shipping address change.\n         *\n         * @param {Object} address\n         */\n        onShippingAddressChange: function (address) {\n            if (address) {\n                this.options(this.sortAddresses(this.options()));\n            }\n            this.value(address);\n        },\n\n        /**\n         * Set selected customer shipping address.\n         *\n         * @param {Object} option\n         */\n        selectShippingAddress: function (option) {\n            delete option.level;\n            delete option.isVisited;\n            delete option.path;\n\n            this.value(option);\n            this.modal().closeModal();\n            selectShippingAddressAction(option);\n            checkoutData.setSelectedShippingAddress(option.getKey());\n        },\n\n        /**\n         * Edit address.\n         */\n        editAction: function () {\n            this.modal().closeModal();\n            formPopUpState.isVisible(true);\n        },\n\n        /** @inheritdoc */\n        success: function (response) {\n            var existingOptions = this.options();\n\n            // eliminate duplicates from ui-select search result\n            _.each(response.options, function (opt) {\n                if (!_.findWhere(existingOptions, {\n                    customerAddressId: opt.id\n                })) {\n                    existingOptions.push(new Address(opt));\n                }\n            });\n\n            this.total = response.total;\n            this.newAddressInSearchResult = false;\n\n            this.options(this.sortAddresses(existingOptions));\n        },\n\n        /**\n         * Sort addresses.\n         *\n         * Sort addresses in such way that new address and default one are displayed on the top of results\n         * if one of them matches search criteria or search is empty.\n         *\n         * @param {Array} existingOptions\n         * @return {Array}\n         */\n        sortAddresses: function (existingOptions) {\n\n            var resultOptions = [],\n                defaultAddress, newAddress;\n\n            newAddress = _.find(addressList(), function (address) {\n                return address.getType() === 'new-customer-address';\n            });\n\n            if (!_.isEmpty(newAddress) && this.canShowNewAddress(newAddress, this.currentSearchKey)) {\n                if (this.newAddressInSearchResult === false) {\n                    this._setItemsQuantity(++this.total);\n                }\n                this.newAddressInSearchResult = true;\n                resultOptions.push(newAddress);\n            }\n\n            defaultAddress = _.find(existingOptions, function (address) {\n                return address.isDefaultShipping();\n            });\n\n            !_.isEmpty(defaultAddress) && resultOptions.push(defaultAddress);\n\n            return resultOptions.concat(_.filter(existingOptions, function (address) {\n                return address.getType() !== 'new-customer-address' && !address.isDefaultShipping();\n            }));\n        },\n\n        /**\n         * Check if we can show address.\n         *\n         * @param {Object} address\n         * @param {String} searchKey\n         * @return {Boolean}\n         */\n        canShowNewAddress: function (address, searchKey) {\n            var searchFields = ['city', 'postcode', 'region', ['street']],\n                filteredResults = [],\n                value = '';\n\n            if (!searchKey) {\n                return true;\n            }\n\n            filteredResults = searchFields.filter(function (elem) {\n                value = address[elem];\n\n                if (_.isArray(value)) {\n                    value = value.join(' ');\n                }\n\n                return value.toLowerCase().indexOf(searchKey.toLowerCase()) !== -1;\n            });\n\n            return !!filteredResults.length;\n        },\n\n        /**\n         * Get country name.\n         *\n         * @param {String} countryId\n         * @return {String}\n         */\n        getCountryName: function (countryId) {\n            return countryData()[countryId] !== undefined ? countryData()[countryId].name : '';\n        },\n\n        /**\n         * Is address selected.\n         *\n         * @param {Object} address\n         * @returns {Boolean}\n         */\n        isAddressSelected: function (address) {\n            return !_.isEmpty(this.value()) && this.value().getKey() === address.getKey();\n        },\n\n        /**\n         * Return formatted items placeholder.\n         *\n         * @param {Object} data - option data\n         * @returns {String}
2\n         */\n        getItemsPlaceholder: function (data) {\n            var prefix = '';\n\n            if (this.lastSearchKey) {\n                prefix = 'Found ';\n            }\n\n            return prefix + data + ' ' + this.quantityPlaceholder;\n        },\n\n        /** @inheritdoc */\n        onScrollDown: function (data, event) {\n            if (this.loading() || this.options().length >= this.total) {\n                return;\n            }\n\n            this._super(data, event);\n        }\n    });\n});\n","Magento_Reports/js/recently-viewed.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.recentlyViewedProducts', {\n        options: {\n            localStorageKey: 'recently-viewed-products',\n            productBlock: '#widget_viewed_item',\n            viewedContainer: 'ol'\n        },\n\n        /**\n         * Bind events to the appropriate handlers.\n         * @private\n         */\n        _create: function () {\n            var productHtml = $(this.options.productBlock).html(),\n                productSku = $(this.options.productBlock).data('sku'),\n                products = JSON.parse(window.localStorage.getItem(this.options.localStorageKey)),\n                productsLength, maximum, showed, index;\n\n            if (products) {\n                productsLength = products.sku.length;\n                maximum = $(this.element).data('count');\n                showed = 0;\n\n                for (index = 0; index <= productsLength; index++) {\n                    if (products.sku[index] == productSku || showed >= maximum) { //eslint-disable-line\n                        products.sku.splice(index, 1);\n                        products.html.splice(index, 1);\n                    } else {\n                        $(this.element).find(this.options.viewedContainer).append(products.html[index]);\n                        $(this.element).show();\n                        showed++;\n                    }\n                }\n                $(this.element).find(this.options.productBlock).show();\n            } else {\n                products = {};\n                products.sku = [];\n                products.html = [];\n            }\n            products.sku.unshift(productSku);\n            products.html.unshift(productHtml);\n            window.localStorage.setItem(this.options.localStorageKey, JSON.stringify(products));\n        }\n    });\n\n    return $.mage.recentlyViewedProducts;\n});\n","Amasty_DatePicker/js/autoload-datepicker-extend.js":"define([], function() {\n    'use strict';\n\n    return function(widget) {\n        require(['Amasty_DatePicker/js/datepicker-extend']);\n\n        return widget;\n    };\n});\n","Amasty_DatePicker/js/datepicker-extend.js":"/**\n * Amasty DatePicker Extension\n *\n * This module overrides jQuery UI Datepicker's _showDatepicker method\n * to apply accessibility enhancements.\n */\ndefine([\n    'jquery',\n    'Amasty_DatePicker/js/datepicker-accessibility',\n    'domReady!'\n], function ($, DatePickerAccessibility) {\n    'use strict';\n\n    if (!$.datepicker) {\n        return;\n    }\n\n    const accessibility = new DatePickerAccessibility();\n\n    const originalConnect = $.datepicker._connectDatepicker;\n\n    $.datepicker._connectDatepicker = function(target, inst) {\n        originalConnect.call(this, target, inst);\n\n        if (!$(target).hasClass('am-datepicker-observed')) {\n            return;\n        }\n\n        requestAnimationFrame(() => accessibility.updateInputLabel($(target)));\n    };\n\n    const originalSelectDate = $.datepicker._selectDate;\n\n    $.datepicker._selectDate = function(id, dateStr) {\n        const inputElement = typeof id === 'string' ? document.querySelector(id) : (id?.currentTarget || id);\n\n        originalSelectDate.call(this, id, dateStr);\n\n        if (!inputElement || !inputElement.closest || !inputElement.closest('.am-datepicker-observed')) {\n            return;\n        }\n\n        requestAnimationFrame(() =>
2 {\n            const $updatedCalendar = $(accessibility.calendarSelector);\n            accessibility.makeCalendarAccessible($updatedCalendar, inputElement, true);\n        });\n    };\n\n    const originalHide = $.datepicker._hideDatepicker;\n\n    $.datepicker._hideDatepicker = function() {\n        originalHide.apply(this, arguments);\n        accessibility.markClosed();\n    };\n\n    const originalShow = $.datepicker._showDatepicker;\n\n    /**\n     * Override of jQuery UI Datepicker's _showDatepicker method\n     * @param {HTMLElement|Event} datepickerInput - The input element or event object\n     */\n    $.datepicker._showDatepicker = function(datepickerInput) {\n        const actualInput = datepickerInput?.currentTarget || datepickerInput;\n\n        if (datepickerInput?.type === 'focus'\n            && !!actualInput?.closest?.('.am-datepicker-observed')\n        ) {\n            return;\n        }\n\n        const skipInitialFocus = !!$.datepicker?._datepickerShowing;\n\n        if (!skipInitialFocus) {\n            accessibility.setOpenerElement(document.activeElement);\n        }\n\n        originalShow.call(this, datepickerInput);\n\n        if (!actualInput || !actualInput.closest || !actualInput.closest('.am-datepicker-observed')) {\n            return;\n        }\n\n        accessibility.makeCalendarAccessible($('#ui-datepicker-div'), actualInput, skipInitialFocus);\n\n        $(actualInput).on('click', function () {\n            $(this).datepicker('hide');\n        });\n    };\n\n    $('.am-datepicker-observed').each(function() {\n        let inst;\n\n        try {\n            inst = $.datepicker._getInst(this);\n        } catch (e) {\n            return;\n        }\n\n        if (inst?.trigger?.length) {\n            accessibility.updateInputLabel($(this));\n        }\n    });\n\n    return accessibility;\n});\n","Amasty_DatePicker/js/datepicker-accessibility.js":"/**\n * Amasty DatePicker Accessibility Class\n *\n * This module provides accessibility features for jQuery UI Datepicker\n * to comply with WCAG 2.1 standards and improve keyboard navigation.\n *\n * Features:\n * - ARIA attributes for screen reader support\n * - Full keyboard navigation (Arrow keys, Home, End, PageUp, PageDown)\n * - Focus trap within the calendar dialog\n * - Roving tabindex for grid navigation\n * - Custom OK/Cancel buttons\n * - Accessible labels and announcements\n *\n * Keyboard shortcuts:\n * - Arrow keys: Navigate between dates\n * - Home/End: Jump to first/last day of week\n * - PageUp/PageDown: Navigate to previous/next month\n * - Shift+PageUp/PageDown: Navigate to previous/next year\n * - Enter/Space: Select date or activate button\n * - Tab: Navigate between focusable elements\n * - Esc: Close calendar\n */\ndefine([\n    'jquery',\n    'Amasty_DatePicker/js/accessibility/aria-manager',\n    'Amasty_DatePicker/js/accessibility/focus-manager',\n    'Amasty_DatePicker/js/accessibility/keyboard-handler',\n    'Amasty_DatePicker/js/accessibility/ui-manager'\n], function ($, AriaManager, FocusManager, KeyboardHandler, UiManager) {\n    'use strict';\n\n    /**\n     * DatePicker Accessibility Class\n     */\n    class DatePickerAccessibility {\n        /**\n         * Constructor\n         */\n        constructor() {\n            this.calendarSelector = '#ui-datepicker-div';\n            this.rowLength = 7;\n\n            this.ariaManager = new AriaManager();\n            this.focusManager = new FocusManager();\n\n            this.keyboardHandler = new KeyboardHandler({\n                calendarSelector: this.calendarSelector,\n                rowLength: this.rowLength,\n                focusManager: this.focusManager,\n                makeCalendarAccessible: this.makeCalendarAccessible.bind(this),\n                focusOnDay: this.focusOnDay.bind(this),\n                focusAfterClose: this.focusAfterClose.bind(this),\n                handleCancelButton: () => this.uiManager.handleCancelButton(),\n            });\n\n            this.uiManager = new UiManager({\n                calendarSelector: this.calendarSelector,\n                replaceSelectsWithLabelCallback: this.replaceSelectsWithLabel.bind(this),\n                updateInputLabelCallback: this.updateInputLabel.bind(this),\n                makeCalendarAccessibleCallback: this.makeCalendarAccessible.bind(this)\n            });\n        }\n\n        /**\n         * Replaces month/year select dropdowns with a text label\n         * @param {jQuery} $calendar - The calendar jQuery element\n         */\n        replaceSelectsWithLabel($calendar) {\n            this.uiManager.replaceSelectsWithLabel($calendar);\n        }\n\n        /**\n         * Updates the ARIA label of the input field with the selected date\n         * @param {jQuery} $input - The input jQuery element\n         */\n        updateInputLabel($input) {\n            this.ariaManager.updateInputLabel($input);\n        }
2\n\n        /**\n         * Focuses on a specific day number in the calendar\n         * @param {jQuery} $calendar - The calendar jQuery element\n         * @param {number} targetDay - The day number to focus (1-31)\n         */\n        focusOnDay($calendar, targetDay) {\n            this.focusManager.focusOnDay($calendar, targetDay);\n        }\n\n        focusAfterClose() {\n            this.uiManager.focusAfterClose();\n        }\n\n        markClosed() {\n            this.uiManager.markClosed();\n        }\n\n        setOpenerElement(el) {\n            this.uiManager.setOpenerElement(el);\n        }\n\n        /**\n         * Main function to make the calendar accessible with ARIA attributes and keyboard navigation\n         * @param {jQuery} $calendar - The calendar jQuery element\n         * @param {HTMLElement} inputElement - The input element associated with the calendar\n         * @param {boolean} [skipInitialFocus=false] - Whether to skip setting initial focus\n         */\n        makeCalendarAccessible($calendar, inputElement, skipInitialFocus) {\n            $calendar.addClass('amasty-custom-datepicker');\n            this.uiManager.setInputElement(inputElement);\n            this.ariaManager.setAriaAttributes($calendar);\n            this.replaceSelectsWithLabel($calendar);\n\n            const {$table, $title} = this.ariaManager.setupTableGrid($calendar);\n\n            this.uiManager.setupNavigationButtons($calendar);\n            this.ariaManager.setupTimeLabels($calendar);\n            this.ariaManager.setupTableStructure($table);\n            this.ariaManager.setupDateCells($table, $title);\n            this.focusManager.removeTableFocus($table);\n            this.ariaManager.updateInputLabel($(inputElement));\n\n            this.keyboardHandler.setupKeyboardNavigation($calendar, $table, inputElement);\n            this.focusManager.setupFocusTrap($calendar);\n\n            if (!skipInitialFocus) {\n                requestAnimationFrame(() => this.focusManager.setInitialFocus($calendar));\n            }\n        }\n    }\n\n    return DatePickerAccessibility;\n});\n\n","Amasty_DatePicker/js/accessibility/ui-manager.js":"/**\n * UI Elements Manager\n *\n * Manages UI elements (buttons, labels) for the datepicker calendar\n */\ndefine([\n    'jquery',\n    'mage/translate'\n], function ($, $t) {\n    'use strict';\n\n    /**\n     * UI Manager Class\n     */\n    class UiManager {\n        /**\n         * Constructor\n         * @param {Object} config - Configuration object\n         * @param {string} config.calendarSelector - Calendar selector\n         * @param {Function} config.replaceSelectsWithLabelCallback - Callback to replace selects\n         * @param {Function} config.updateInputLabelCallback - Callback to update input label\n         * @param {Function} config.makeCalendarAccessibleCallback - Callback to fully reinitialize calendar accessibility\n         */\n        constructor(config) {\n            this.calendarSelector = config.calendarSelector;\n            this.replaceSelectsWithLabelCallback = config.replaceSelectsWithLabelCallback;\n            this.updateInputLabelCallback = config.updateInputLabelCallback;\n            this.makeCalendarAccessibleCallback = config.makeCalendarAccessibleCallback;\n            this.inputElement = null;\n            this.originalValue = null;\n            this.isOpen = false;\n            this.openerElement = null;\n        }\n\n        /**\n         * Sets the current input element associated with the open calendar\n         * @param {HTMLElement} inputElement\n         */\n        setInputElement(inputElement) {\n            if (!this.isOpen) {\n                this.originalValue = $(inputElement).val();\n                this.isOpen = true;\n            }\n            this.inputElement = inputElement;\n        }\n\n        setOpenerElement(el) {\n            this.openerElement = el;\n        }\n\n        resetOpenState() {\n            this.isOpen = false;\n            this.originalValue = null;\n        }\n\n        markClosed() {\n            this.isOpen = false;\n        }\n\n        /**\n         * Replaces month/year select dropdowns with a text label\n         * @param {jQuery} $calendar - The calendar jQuery element\n         */\n        replaceSelectsWithLabel($calendar) {\n            const $monthSelect = $calendar.find('.ui-datepicker-month');\n            const $yearSelect = $calendar.find('.ui-datepicker-year');\n            const $title = $calendar.find('.ui-datepicker-title');\n\n            if (($monthSelect.length > 0 || $yearSelect.length > 0) && !$title.hasClass('label-replaced')) {\n                const monthText = $monthSelect.length > 0 ? $monthSelect.find('option:selected').text() : '';\n                const yearText = $yearSelect.length > 0 ? $yearSelect.find('option:selected').text() : '';\n                const labelText = monthText && yearText ? `${monthText} ${yearText}` :\n                    monthText ? monthText : yearText;\n\n                $monthSelect.remove();\n                $yearSelect.remove();\n\n                if (labelText) {\n                    const $label = $('<span>')\n                        .addClass('ui-datepicker-month-year-label')\n                        .text(labelText);\n\n                    $title.empty().append($label).addClass('label-replaced');\n                }\n            } else if ($title.length > 0 && !$title.hasClass('label-replaced')) {\n                $title.addClass('label-replaced');\n            }\n        }\n\n        /**\n         * Sets up navigation buttons (prev/next) with ARIA attributes and event handlers\n         * @param {jQuery} $calendar - The calendar jQuery element\n         */\n        setupNavigationButtons($calendar) {\n            const $prevButton = $calendar.find('.ui-datepicker-prev');\n            const $nextButton = $calendar.find('.ui-datepicker-next');\n\n            $prevButton.attr({\n                'role': 'button',\n                'aria-label': $t('Previous Month'),\n                'tabindex': '0'\n            }).removeAttr('title');\n\n            $nextButton.attr({\n                'role': 'button',\n                'aria-label': $t('Next Month'),\n                'tabindex': '0'\n            }).removeAttr('title');\n\n            $calendar.find('.ui-datepicker-prev, .ui-datepicker-next')\n                .off('click.update-label')\n                .on('click.update-label', () => requestAnimationFrame(() =>
2 {\n                    this.makeCalendarAccessibleCallback($(this.calendarSelector), this.inputElement, false);\n                }));\n\n            this.createActionButtons($calendar);\n        }\n\n        /**\n         * Creates and sets up custom OK/Cancel buttons for the calendar\n         * @param {jQuery} $calendar - The calendar jQuery element\n         */\n        createActionButtons($calendar) {\n            $calendar.find('.ui-datepicker-buttonpane').hide();\n\n            if ($calendar.find('.custom-datepicker-buttonpane').length === 0) {\n                const $buttonPane = $('<div>')\n                    .addClass('custom-datepicker-buttonpane');\n\n                const $cancelButton = $('<button>')\n                    .addClass('custom-datepicker-cancel')\n                    .attr({\n                        'type': 'button',\n                        'role': 'button',\n                        'aria-label': $t('Cancel'),\n                        'tabindex': '0'\n                    })\n                    .text($t('Cancel'));\n\n                const $okButton = $('<button>')\n                    .addClass('custom-datepicker-ok')\n                    .attr({\n                        'type': 'button',\n                        'role': 'button',\n                        'aria-label': $t('OK'),\n                        'tabindex': '0'\n                    })\n                    .text($t('OK'));\n\n                $buttonPane.append($cancelButton, $okButton);\n                $calendar.append($buttonPane);\n\n                $cancelButton.on('click', (e) => {\n                    e.preventDefault();\n                    this.handleCancelButton();\n                });\n\n                $okButton.on('click', (e) => {\n                    e.preventDefault();\n                    this.handleOkButton();\n                });\n\n                $cancelButton.on('keydown', (e) => {\n                    if (e.key === 'Enter' || e.key === ' ') {\n                        e.preventDefault();\n                        this.handleCancelButton();\n                    } else if (e.key === 'Escape') {\n                        e.preventDefault();\n                        this.handleCancelButton();\n                    }\n                });\n\n                $okButton.on('keydown', (e) => {\n                    if (e.key === 'Enter' || e.key === ' ') {\n                        e.preventDefault();\n                        this.handleOkButton();\n                    } else if (e.key === 'Escape') {\n                        e.preventDefault();\n                        this.handleCancelButton();\n                    }\n                });\n            }\n        }\n\n        /**\n         * Resolves the trigger button or input to return focus to after closing\n         * @returns {jQuery} - The element to focus\n         */\n        resolveFocusTarget() {\n            const $opener = this.openerElement ? $(this.openerElement) : null;\n\n            if ($opener?.length && !$opener.is('body') && $opener.is(':visible') && !$opener.prop('disabled')) {\n                return $opener;\n            }\n\n            const $input = this.inputElement\n                ? $(this.inputElement)\n                : $('input.hasDatepicker').first();\n\n            if (!$input.length) {\n                return $();\n            }\n\n            let inst;\n\n            try {\n                inst = $.datepicker._getInst($input[0]);\n            } catch (e) {\n                return $input;\n            }\n\n            const $trigger = inst?.trigger;\n\n            if ($trigger?.length && $trigger.is(':visible')) {\n                return $trigger;\n            }\n\n            return $input;\n        }\n\n        /**\n         * Focuses the trigger element after the calendar is closed\n         */\n        focusAfterClose() {\n            const [el] = this.resolveFocusTarget();\n\n            if (!el) {\n                return;\n            }\n\n            if (el.tagName === 'INPUT') {\n                //prevent calendar reopen for showOn: 'both' or 'focus'\n                $.datepicker._lastInput = el;\n            }\n\n            el?.focus();\n            $.datepicker._lastInput = null;\n        }\n\n        /**\n         * Handles cancel button click\n         */\n        handleCancelButton() {\n            const originalValue = this.originalValue;\n            const $input = this.inputElement ? $(this.inputElement) : $('input.hasDatepicker').first();\n\n            this.resetOpenState();\n            $.datepicker._hideDatepicker();\n\n            if (originalValue !== null) {\n                $input.val(originalValue);\n            }\n\n            this.focusAfterClose();\n        }\n\n        /**\n         * Handles OK button click\n         */\n        handleOkButton() {\n            const $input = this.inputElement ? $(this.inputElement) : $('input.hasDatepicker').first();\n            const $selected = $(this.calendarSelector).find('td.ui-datepicker-current-day a').first();\n\n            if ($selected.length) $selected.click();\n\n            this.resetOpenState();\n            $.datepicker._hideDatepicker();\n\n            const [inputEl] = $input;\n\n            if (inputEl) this.updateInputLabelCallback($input);\n\n            this.focusAfterClose();\n        }\n    }\n\n    return UiManager;\n});\n\n","Amasty_DatePicker/js/accessibility/aria-manager.js":"/**\n * ARIA Attributes Manager\n *\n * Manages ARIA attributes for the datepicker calendar\n */\ndefine([\n    'jquery',\n    'mage/translate',\n    'mage/utils/misc'\n], function ($, $t, utils) {\n    'use strict';\n\n    /**\n     * ARIA Manager Class\n     */\n    class AriaManager {\n        /**\n         * Sets ARIA attributes for the calendar dialog\n         * @param {jQuery} $calendar - The calendar jQuery element\n         */\n        isDateTimePicker($calendar) {\n            return $calendar && $calendar.find('.ui-timepicker-div').length > 0;\n        }\n\n        setAriaAttributes($calendar) {\n            const label = this.isDateTimePicker($calendar) ? $t('Choose Date and Time') : $t('Choose Date');\n\n            $calendar.attr({\n                'role': 'dialog',\n                'aria-modal'
2: 'true',\n                'aria-label': label,\n                'tabindex': '-1'\n            });\n        }\n\n        /**\n         * Sets up the calendar table grid with proper ARIA attributes\n         * @param {jQuery} $calendar - The calendar jQuery element\n         * @returns {{$table: jQuery, $title: jQuery}} Object containing table and title elements\n         */\n        setupTableGrid($calendar) {\n            const $table = $calendar.find('.ui-datepicker-calendar');\n\n            $table.attr({\n                'role': 'grid',\n                'aria-labelledby': 'ui-datepicker-title'\n            });\n\n            const $header = $calendar.find('.ui-datepicker-header');\n            const $title = $header.find('.ui-datepicker-title');\n\n            if (!$title.attr('id')) {\n                $title.attr('id', 'ui-datepicker-title');\n            }\n\n            $title.attr('aria-live', 'polite');\n\n            return {$table, $title};\n        }\n\n        /**\n         * Sets up table structure with proper ARIA roles for rows and headers\n         * @param {jQuery} $table - The table jQuery element\n         */\n        setupTableStructure($table) {\n            $table.find('thead tr').attr('role', 'row');\n            $table.find('tbody tr').attr('role', 'row');\n\n            $table.find('thead th').each(function() {\n                $(this).attr({\n                    'role': 'columnheader',\n                    'aria-label': $(this).text()\n                });\n            });\n        }\n\n        /**\n         * Builds a human-readable aria-label for a date cell link\n         * @param {string} day - Day number as text\n         * @param {string} month - Month/year string from the calendar title\n         * @param {boolean} isToday\n         * @param {boolean} isSelected\n         * @returns {string}\n         */\n        buildDateAriaLabel(day, month, isToday, isSelected) {\n            let label = day + ' ' + month;\n\n            if (isToday) label += ', ' + $t('today');\n            if (isSelected) label += ', ' + $t('selected');\n\n            return label;\n        }\n\n        /**\n         * Formats a data-date attribute value (YYYY-MM-DD) from link data attributes.\n         * Returns null when the required attributes are missing or invalid.\n         * @param {jQuery} $link\n         * @returns {string|null}\n         */\n        formatDataDate($link) {\n            const dayNum = parseInt($link.text());\n\n            if (isNaN(dayNum) || !$link.attr('data-month') || !$link.attr('data-year')) {\n                return null;\n            }\n\n            const monthNum = parseInt($link.attr('data-month'));\n            const yearNum = parseInt($link.attr('data-year'));\n            const d = String(dayNum).padStart(2, '0');\n            const m = String(monthNum + 1).padStart(2, '0');\n\n            return yearNum + '-' + m + '-' + d;\n        }\n\n        /**\n         * Sets up date cells with ARIA attributes and labels\n         * @param {jQuery} $table - The table jQuery element\n         * @param {jQuery} $title - The title jQuery element containing month/year\n         */\n        setupDateCells($table, $title) {\n            const month 
2= $title.text();\n\n            $table.find('tbody td').each((_, el) => {\n                const $cell = $(el);\n                const $link = $cell.find('a');\n                const $span = $cell.find('span');\n\n                $cell.attr('role', 'gridcell');\n\n                if ($link.length > 0) {\n                    const isToday = $cell.hasClass('ui-datepicker-today');\n                    const isSelected = $cell.hasClass('ui-datepicker-current-day');\n                    const dataDate = this.formatDataDate($link);\n\n                    if (dataDate) {\n                        $cell.attr('data-date', dataDate);\n                    }\n\n                    $link.attr({\n                        'role': 'button',\n                        'aria-label': this.buildDateAriaLabel($link.text(), month, isToday, isSelected),\n                        'aria-current': isToday ? 'date' : null,\n                        'tabindex': '-1'\n                    });\n\n                    if (isSelected) {\n                        $cell.attr('aria-selected', 'true');\n                    } else {\n                        $cell.removeAttr('aria-selected');\n                    }\n                } else if ($span.length > 0) {\n                    $cell.attr('aria-disabled', 'true');\n                    $span.attr('aria-hidden', 'true');\n                }\n            });\n        }\n\n        /**\n         * Builds a verbose \"Change Date, Monday 1 January, 2026\" label\n         * from a datepicker instance. Returns null when data is unavailable.\n         * @param {Object} inst - jQuery UI datepicker instance\n         * @returns {string|null}\n         */\n        formatSelectedDateLabel(inst, isDateTime) {\n            if (!inst || !inst.selectedYear || inst.selectedMonth === undefined || !inst.selectedDay) {\n                return null;\n            }\n\n            const dayLabels = [\n                $t('Sunday'), $t('Monday'), $t('Tuesday'), $t('Wednesday'),\n                $t('Thursday'), $t('Friday'), $t('Saturday')\n            ];\n            const monthLabels = [\n                $t('January'), $t('February'), $t('March'), $t('April'),\n                $t('May'), $t('June'), $t('July'), $t('August'),\n                $t('September'), $t('October'), $t('November'), $t('December')\n            ];\n\n            const date = new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay);\n            const prefix = isDateTime ? $t('Change Date and Time') : $t('Change Date');\n\n            return prefix\n                + ', ' + dayLabels[date.getDay()]\n                + ' ' + date.getDate()\n                + ' ' + monthLabels[date.getMonth()]\n                + ', ' + date.getFullYear();\n        }\n\n        /**\n         * @param {jQuery} $calendar - The calendar jQuery element\n         */\n        setupTimeLabels($calendar) {\n            const $timepickerDiv = $calendar.find('.ui-timepicker-div');\n\n            if (!$timepickerDiv.length) {\n                return;\n            }\n\n            const $timeInputs = $timepickerDiv.find('dd:not(.ui_tpicker_unit_hide) [data-unit]');\n\n            $timeInputs.each((key, el) => {\n                const $el = $(el);\n                const unit = el.dataset.unit;\n                const id = utils.uniqueid();\n                const labelContainer = $timepickerDiv.find('.ui_tpicker_' + unit + '_label');\n                const label = document.createElement('label');\n\n                el.id = id;\n                label.textContent = labelContainer.text();\n                label.setAttribute('for', id);\n                label.classList.add('label');\n                labelContainer.html(label);\n\n                $el.off('change.am-timepicker-focus').on('change.am-timepicker-focus', (e) => {\n                    this.retainTimeSelectFocus($calendar, e.target.dataset.unit);\n                });\n            })\n        }\n\n        /**\n         * jQuery UI Timepicker Addon (controlType: 'select') discards and recreates\n         * every unit <select> on each change to apply updated min/max/step constraints,\n         * which drops focus from the option the user just picked. Restores ARIA labels\n         * and refocuses the freshly created control for the same time unit once the\n         * rebuild completes.\n         * @param {jQuery} $calendar - The calendar jQuery element\n         * @param {string} unit - The time unit of the changed control (e.g. 'hour', 'minute')\n         */\n        retainTimeSelectFocus($calendar, unit) {\n            if (!unit) {\n                return;\n            }\n\n            requestAnimationFrame(() =>
2 {\n                this.setupTimeLabels($calendar);\n\n                const [select] = $calendar.find(`.ui-timepicker-select[data-unit=\"${unit}\"]`);\n\n                select?.focus();\n            });\n        }\n\n        /**\n         * Updates the ARIA label of the input field with the selected date\n         * @param {jQuery} $input - The input jQuery element\n         */\n        updateInputLabel($input) {\n            let label;\n            const inst = $.datepicker._getInst($input[0]);\n            const isDateTime = inst ? this.isDateTimePicker(inst.dpDiv) : false;\n            const choosePlaceholder = isDateTime ? $t('Choose Date and Time') : $t('Choose Date');\n\n            if (!$input.val()) {\n                label = choosePlaceholder;\n            } else {\n                try {\n                    label = this.formatSelectedDateLabel(inst, isDateTime) || choosePlaceholder;\n                } catch (e) {\n                    label = choosePlaceholder;\n                }\n            }\n\n            $input.attr('aria-label', label);\n\n            const $trigger = $input.next('.ui-datepicker-trigger');\n\n            if ($trigger.length) {\n                $trigger.attr('aria-label', label);\n            }\n        }\n    }\n\n    return AriaManager;\n});\n\n","Amasty_DatePicker/js/accessibility/keyboard-handler.js":"/**\n * Keyboard Navigation Handler\n *\n * Handles keyboard navigation for the datepicker calendar\n */\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    /**\n     * Keyboard Handler Class\n     */\n    class KeyboardHandler {\n        /**\n         * Constructor\n         * @param {Object} config - Configuration object\n         * @param {string} config.calendarSelector - Calendar selector\n         * @param {number} config.rowLength - Number of columns in grid\n         * @param {FocusManager} config.focusManager - Focus manager instance\n         * @param {Function} config.makeCalendarAccessible - Callback to reinitialize calendar\n         * @param {Function} config.focusOnDay - Callback to focus on specific day\n         * @param {Function} config.focusAfterClose - Callback to handle focus after calendar close\n         */\n        constructor(config) {\n            this.calendarSelector = config.calendarSelector;\n            this.rowLength = config.rowLength;\n            this.focusManager = config.focusManager;\n            this.makeCalendarAccessible = config.makeCalendarAccessible;\n            this.focusOnDay = config.focusOnDay;\n            this.focusAfterClose = config.focusAfterClose;\n            this.handleCancelButton = config.handleCancelButton;\n        }\n\n        /**\n         * Clicks a prev/next navigation button, restores focus to the same day,\n         * then returns focus to the nav button.\n         * @param {jQuery} $btn - The nav button element\n         * @param {HTMLElement} inputElement\n         */\n        activateNavButton($btn, inputElement) {\n            const isPrev = $btn.hasClass('ui-datepicker-prev');\n            const $activeTd = this.focusManager.getSelectableCells($(this.calendarSelector))\n                .filter((_, td) => $(td).attr('tabindex') === '0')\n                .first();\n            const currentDay = parseInt($activeTd.find('a').text()) || 1;\n\n            this.navigateByMonthCount(inputElement, isPrev ? -1 : +1, currentDay, ($updated) => {\n                const $activeCell = this.focusManager.getSelectableCells($updated)\n                    .filter((_, td) => $(td).attr('tabindex') === '0')\n                    .first();\n\n                $activeCell.addClass('am-datepicker-cell-active');\n\n                const [btnEl] = isPrev\n                    ? $updated.find('.ui-datepicker-prev')\n                    : $updated.find('.ui-datepicker-next');\n\n                btnEl?.focus();\n\n                $updated.one('focusin.cell-active', 'td', () => {\n                    $updated.find('.am-datepicker-cell-active').removeClass('am-datepicker-cell-active');\n                });\n            });\n        }\n\n        /**\n         * Navigates to an adjacent month and focuses the boundary cell.\n         * Used by ArrowLeft (prev month, last cell) and ArrowRight (next month, first cell).\n         * @param {HTMLElement} inputElement\n         * @param {number} offset - Month offset: -1 for previous, +1 for next\n         * @param {'first'|'last'} edge - Which boundary cell to focus after navigation\n         */\n        navigateToMonth(inputElement, offset, edge) {\n            $.datepicker._adjustDate($(inputElement), offset, 'M');\n\n            requestAnimationFrame(() =>
2 {\n                const $updatedCalendar = $(this.calendarSelector);\n\n                this.makeCalendarAccessible($updatedCalendar, inputElement, true);\n\n                const $cells = this.focusManager.getSelectableCells($updatedCalendar);\n\n                if (!$cells.length) return;\n\n                const newIndex = edge === 'first' ? 0 : $cells.length - 1;\n                const [cellEl] = edge === 'first' ? $cells : [...$cells].reverse();\n\n                this.focusManager.updateRovingTabindex($cells, newIndex);\n                cellEl?.focus();\n            });\n        }\n\n        /**\n         * Navigates forward or backward by months/years and restores focus to the same day.\n         * Used by PageUp (back) and PageDown (forward).\n         * @param {HTMLElement} inputElement\n         * @param {number} offset - Signed month count (negative = back, positive = forward)\n         * @param {number} targetDay - Day number to restore focus to after navigation\n         * @param {Function} [afterNavigate] - Optional callback run after focusOnDay\n         */\n        navigateByMonthCount(inputElement, offset, targetDay, afterNavigate) {\n            $.datepicker._adjustDate($(inputElement), offset, 'M');\n\n            requestAnimationFrame(() => {\n                const $updated = $(this.calendarSelector);\n\n                this.makeCalendarAccessible($updated, inputElement, true);\n                this.focusOnDay($updated, targetDay);\n                afterNavigate?.($updated);\n            });\n        }\n\n        /**\n         * Finds the nearest selectable <td> sibling in the given direction\n         * by walking through all tbody cells in DOM order.\n         * @param {jQuery} $calendar\n         * @param {jQuery} $fromCell - Currently focused cell\n         * @param {'left'|'right'} direction\n         * @returns {jQuery|null}\n         */\n        findAdjacentCell($calendar, $fromCell, direction) {\n            const $allTd = $calendar.find('tbody td');\n            const domIndex = $allTd.index($fromCell);\n            const step = direction === 'left' ? -1 : 1;\n            const limit = direction === 'left' ? -1 : $allTd.length;\n\n            for (let i = domIndex + step; i !== limit; i += step) {\n                const $td = $allTd.eq(i);\n\n                if (this.focusManager.isSelectableCell($td)) {\n                    return $td;\n                }\n            }\n\n            return null;\n        }\n\n        /**\n         * Moves focus to an adjacent cell in the same column, one row up or down.\n         * @param {jQuery} $focused - Currently focused cell\n         * @param {jQuery} $allCells - All selectable cells\n         * @param {'prev'|'next'} rowDirection\n         */\n        navigateVertical($focused, $allCells, rowDirection) {\n            const $currentRow = $focused.closest('tr');\n            const colIndex = $currentRow.find('td').index($focused);\n            const $target = $currentRow[rowDirection]('tr').find('td').eq(colIndex);\n            const [targetEl] = $target;\n\n            if (targetEl && this.focusManager.isSelectableCell($target)) {\n                this.focusManager.updateRovingTabindex($allCells, $allCells.index($target));\n                targetEl.focus();\n            }\n        }\n\n        /**\n         * Moves focus to the nearest selectable cell left or right,\n         * crossing into the adjacent month when at the boundary.\n         * @param {jQuery} $focused - Currently focused cell\n         * @param {jQuery} $calendar\n         * @param {jQuery} $allCells\n         * @param {HTMLElement} inputElement\n         * @param {'left'|'right'} direction\n         */\n        navigateHorizontal($focused, $calendar, $allCells, inputElement, direction) {\n            const $target = this.findAdjacentCell($calendar, $focused, direction);\n\n            if ($target) {\n                this.focusManager.updateRovingTabindex($allCells, $allCells.index($target));\n                $target.focus();\n            } else {\n                this.navigateToMonth(inputElement, direction === 'left' ? -1 : +1, direction === 'left' ? 'last' : 'first');\n            }\n        }\n\n        /**\n         * Handles arrow key navigation within the calendar grid\n         * @param {KeyboardEvent} e - The keyboard event\n         * @param {jQuery} $calendar - The calendar jQuery element\n         * @param {HTMLElement} inputElement - The input element associated with the calendar\n         * @param {jQuery} $allCells - Collection of all selectable <td> elements\n         * @param {number} currentIndex - Current focused cell index\n         * @returns {{handled: boolean}}\n         */\n        handleArrowNavigation(e, $calendar, inputElement, $allCells, currentIndex) {\n            const $focused = $allCells.eq(currentIndex);\n\n            switch (e.key) {\n                case 'ArrowLeft':\n                    e.preventDefault();\n                    this.navigateHorizontal($focused, $calendar, $allCells, inputElement, 'left');\n                    return {handled: true};\n\n                case 'ArrowRight':\n                    e.preventDefault();\n                    this.navigateHorizontal($focused, $calendar, $allCells, inputElement, 'right');\n                    return {handled: true};\n\n                case 'ArrowUp':\n                    e.preventDefault();\n                    this.navigateVertical($focused, $allCells, 'prev');\n                    return {handled: true};\n\n                case 'ArrowDown':\n                    e.preventDefault();\n                    this.navigateVertical($focused, $allCells, 'next');\n                    return {handled: true};\n\n                default:\n                    return {handled: false};\n            }\n        }\n\n        /**\n         * Handles grid navigation keys (Home/End/PageUp/PageDown/Arrows) for a focused date cell.\n         * @param {KeyboardEvent} e\n         * @param {jQuery} $calendar\n         * @param {HTMLElement} inputElement\n         * @returns {false|undefined}\n         */\n        handleGridNavigation(e, $calendar, inputElement) {\n            const $focused = $(document.activeElement);
2\n            const $activeTd = $focused.is('td') ? $focused : $focused.closest('td');\n\n            if (!$activeTd.length || !$.contains($calendar[0], $activeTd[0])) return;\n\n            e.preventDefault();\n\n            const $allCells = this.focusManager.getSelectableCells($calendar);\n\n            if (!$allCells.length) return false;\n\n            let currentIndex = $allCells.index($activeTd);\n\n            if (currentIndex === -1) currentIndex = 0;\n\n            switch (e.key) {\n                case 'Home':\n                case 'End': {\n                    const $rowCells = $activeTd.closest('tr').find('td').filter((_, td) => this.focusManager.isSelectableCell($(td)));\n                    const [$target] = e.key === 'Home' ? $rowCells : [...$rowCells].reverse();\n                    const newIndex = $allCells.index($target);\n\n                    if (newIndex >= 0) {\n                        this.focusManager.updateRovingTabindex($allCells, newIndex);\n                        $target?.focus();\n                    }\n\n                    return false;\n                }\n\n                case 'PageUp':\n                case 'PageDown': {\n                    const currentDay = parseInt($activeTd.find('a').text());\n\n                    if (isNaN(currentDay)) return false;\n\n                    const sign = e.key === 'PageUp' ? -1 : +1;\n\n                    this.navigateByMonthCount(inputElement, sign * (e.shiftKey ? 12 : 1), currentDay);\n                    return false;\n                }\n\n                case 'ArrowLeft':\n                case 'ArrowUp':\n                case 'ArrowRight':\n                case 'ArrowDown':\n                    this.handleArrowNavigation(e, $calendar, inputElement, $allCells, currentIndex);\n                    return false;\n            }\n        }\n\n        /**\n         * Sets up comprehensive keyboard navigation for the calendar\n         * @param {jQuery} $calendar - The calendar jQuery element\n         * @param {jQuery} $table - The table jQuery element\n         * @param {HTMLElement} inputElement - The input element associated with the calendar\n         */\n        setupKeyboardNavigation($calendar, $table, inputElement) {\n            $calendar.off('keydown.datepicker-navigation').off('keydown.focus-trap');\n\n            $calendar.on('keydown.datepicker-navigation', (e) => {\n                const $focused = $(document.activeElement);\n\n                switch (e.key) {\n                    case 'Escape': {\n                        if ($focused.is('option')) {\n                            //time element option\n                            return true;\n                        }\n                        e.preventDefault();\n                        this.handleCancelButton();\n                        return false;\n                    }\n\n                    case 'Tab': {\n                        const $focusable = this.focusManager.getFocusableElements($calendar);\n\n                        if (!$focusable.length) return;\n\n                        const $target = e.shiftKey\n                            ? this.focusManager.resolveBackwardFocusTarget($calendar, $focused, $focusable.first(), $focusable.last())\n                            : this.focusManager.resolveForwardFocusTarget($calendar, $focused, $focusable.first(), $focusable.last());\n\n                        if (!$target) return;\n\n                        e.preventDefault();\n                        $target.focus();\n                        return false;\n                    }\n\n                    case 'Enter':\n                    case ' ': {\n                        if ($focused.is('select') || $focused.is('option')) {\n                            //time elements\n                            return true;\n                        }\n                        e.preventDefault();\n\n                        const isNavButton = $focused.hasClass('ui-datepicker-prev') || $focused.hasClass('ui-datepicker-next');\n\n                        if (isNavButton) {\n                            this.activateNavButton($focused, inputElement);\n                            return false;\n                        }\n\n                        if (!this.focusManager.isDateCell($focused) || $focused.hasClass('ui-datepicker-unselectable')) {\n                            return false;\n                        }\n\n                        if (e.key === 'Enter') {\n                            $focused.find('a').click();\n                            $.datepicker._hideDatepicker();\n                            requestAnimationFrame(() => this.focusAfterClose());\n                        } else {\n                            $table.find('td.ui-datepicker-current-day')\n                                .removeClass('ui-datepicker-current-day')\n                                .removeAttr('aria-selected');\n                            $focused.addClass('ui-datepicker-current-day').attr('aria-selected', 'true');\n                        }\n\n                        return false;\n                    }\n\n                    case 'Home':\n                    case 'End':\n                    case 'PageUp':\n                    case 'PageDown':\n                    case 'ArrowLeft':\n                    case 'ArrowUp':\n                    case 'ArrowRight':\n                    case 'ArrowDown':\n                        return this.handleGridNavigation(e, $calendar, inputElement);\n                }\n            });\n        }\n    }\n\n    return KeyboardHandler;\n});\n\n","Amasty_DatePicker/js/accessibility/focus-manager.js":"/**\n * Focus Manager\n *\n * Manages focus behavior for the datepicker calendar\n */\ndefine([\n    'jquery',\n    'jquery/ui-modules/focusable',\n    'jquery/ui-modules/tabbable',\n], function ($) {\n    'use strict';\n\n    /**\n     * Focus Manager Class\n     */\n    class FocusManager {\n        /**\n         * Updates the roving tabindex for date navigation.\n         * Tabindex is placed on <td> elements (not <a>) so screen readers\n         * announce only the focused cell, not the entire dialog.\n         * @param {jQuery} $allCells - Collection of all selectable <td> elements\n         * @param {number} newIndex - Index of the element to receive tabindex=\"0\"\n         */\n        updateRovingTabindex($allCells, newIndex) {\n            $allCells.attr('tabindex', '-1');\n\n            if (newIndex >= 0 && newIndex < $allCells.length) {\n                $allCells.eq(newIndex).attr('tabindex', '0');\n            }\n        }\n\n        /**\n         * Returns true when a <td> is selectable (not disabled and contains a date link)\n         * @param {jQuery} $td\n         * @returns {boolean}\n         */\n        isSelectableCell($td) {\n            return !$td.hasClass('ui-datepicker-unselectable') && $td.find('a').length > 0;\n        }\n\n        /**\n         * Returns all selectable date cells (<td>) in the calendar\n         * @param {jQuery} $calendar\n         * @returns {jQuery}\n         */\n        getSelectableCells($calendar) {\n            return $calendar.find('td').filter((_, td) => this.isSelectableCell($(td)));\n        }\n\n        /**\n         * Sets up focus handling for the calendar table\n         * @param {jQuery} $table - The table jQuery element\n         */\n        removeTableFocus($table) {\n            $table.removeAttr('tabindex').off('focus.table-focus');\n        }\n\n        /**\n         * Returns focusable elements within the calendar (excluding decorative icons)\n         * @param {jQuery} $calendar\n         * @returns {jQuery}\n         */\n        getFocusableElements($calendar) {\n            return $calendar\n                .find(':tabbable');\n        }\n\n        /**\n         * Returns true when the given element is a selectable date cell\n         * @param {jQuery} $el\n         * @returns {boolean}\n         */\n        isDateCell($el) {\n            return $el.is('td') && $el.find('a').length > 0;\n        }\n\n        /**\n         * Returns true when the given element is outside the calendar\n         * @param {jQuery} $calendar\n         * @param {jQuery} $el\n         * @returns {boolean}\n         */\n        isOutsideCalendar($calendar, $el) {\n            return !$.contains($calendar[0], $el[0]);\n        }\n\n        /**\n         * Resolves the element that should receive focus on Shift+Tab traversal.\n         * @param {jQuery} $calendar\n         * @param {jQuery} $current - Currently focused element\n         * @param {jQuery} $first - First focusable element\n         * @param {jQuery} $last - Last focusable element\n         * @returns {jQuery|null} Target element, or null when no redirect is needed\n         */\n        resolveBackwardFocusTarget($calendar, $current, $first, $last) {\n            if (this.isOutsideCalendar($calendar, $current) || $current.is($first)) {\n                return $last;\n            }\n\n            if (this.isDateCell($current)) {\n                const $nextBtn = $calendar.find('.ui-datepicker-next');\n\n                return $nextBtn.length ? $nextBtn : $first;\n            }\n\n            return null;\n        }\n\n        /**\n         * Resolves the element that should receive focus on forward Tab traversal.\n         * @param {jQuery} $calendar\n         * @param {jQuery} $current - Currently focused element\n         * @param {jQuery} $first - First focusable element\n         * @param {jQuery} $last - Last focusable element\n         * @returns {jQuery|null} Target element, or null when no redirect is needed\n         */\n        resolveForwardFocusTarget($calendar, $current, $first, $last) {\n            if (this.isOutsideCalendar($calendar, $current) || $current.is($last)) {\n                return $first;\n            }\n\n            if (this.isDateCell($current)) {\n                const timePickerInput = $calendar.find('.ui-timepicker-select:visible');\n\n                if (timePickerInput.length) {\n                    return timePickerInput.first();\n                }\n\n                const $cancelBtn = $calendar.find('.custom-datepicker-cancel');\n\n                return $cancelBtn.length ? $cancelBtn : $last;\n            }\n\n            return null;\n        }\n\n        /**\n         * Sets up a focus trap to keep keyboard focus within the calendar dialog\n         * @param {jQuery} $calendar - The calendar jQuery element\n         */\n        setupFocusTrap($calendar) {\n            $calendar.off('keydown.focus-trap').on('keydown.focus-trap', (e) => {\n                if (e.key !== 'Tab') return;\n\n                const $focusable = this.getFocusableElements($calendar);\n\n                if ($focusable.length === 0) return;\n\n                const $first = $focusable.first();\n                const $last = $focusable.last();\n                const $current = $(document.activeElement);\n\n                const $target = e.shiftKey\n                    ? this.resolveBackwardFocusTarget($calendar, $current, $first, $last)\n                    : this.resolveForwardFocusTarget($calendar, $current, $first, $last);\n\n                if (!$target) return;\n\n                e.preventDefault();
2\n                $target.focus();\n            });\n        }\n\n        /**\n         * Sets the initial focus to the appropriate date cell (<td>) when the calendar opens.\n         * Focusing <td role=\"gridcell\"> instead of the inner <a> prevents screen readers\n         * from reading the entire dialog content on open.\n         * @param {jQuery} $calendar - The calendar jQuery element\n         */\n        setInitialFocus($calendar) {\n            const [selectedCell] = $calendar.find('td.ui-datepicker-current-day');\n            const [todayCell] = $calendar.find('td.ui-datepicker-today');\n            const [firstCell] = this.getSelectableCells($calendar);\n            const toFocus = selectedCell ?? todayCell ?? firstCell;\n\n            toFocus && $(toFocus).attr('tabindex', '0').focus();\n        }\n\n        /**\n         * Focuses on a specific day number in the calendar\n         * @param {jQuery} $calendar - The calendar jQuery element\n         * @param {number} targetDay - The day number to focus (1-31)\n         */\n        focusOnDay($calendar, targetDay) {\n            const $selectableCells = this.getSelectableCells($calendar);\n\n            if ($selectableCells.length === 0) return;\n\n            const day = String(targetDay);\n            const [matchedLink] = $selectableCells.find(`a:contains(${day})`).filter((_, a) => $(a).text().trim() === day);\n            const $targetCell = matchedLink ? $(matchedLink).closest('td') : $selectableCells.last();\n            const newIndex = $selectableCells.index($targetCell);\n\n            if (newIndex >= 0) {\n                this.updateRovingTabindex($selectableCells, newIndex);\n                $targetCell.focus();\n            }\n        }\n    }\n\n    return FocusManager;\n});\n\n","Magento_GroupedProduct/js/product-ids-resolver.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'Magento_Catalog/js/product/view/product-ids',\n    'Magento_Catalog/js/product/view/product-info'\n], function ($, productIds, productInfo) {\n    'use strict';\n\n    /**\n     * Returns id's of products in form.\n     *\n     * @param {Object} config\n     * @param {HTMLElement} element\n     * @return {Array}\n     */\n    return function (config, element) {\n        $(element).find('div[data-product-id]').each(function () {\n            productIds.push($(this).data('productId').toString());\n            productInfo.push(\n                {\n                    'id': $(this).data('productId').toString()\n                }\n            );\n        });\n\n        return productIds();\n    };\n});\n","Magento_GroupedProduct/js/grouped-product.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'underscore',\n    'jquery-ui-modules/widget',\n    'jquery/jquery.parsequery'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.groupedProduct', {\n        options: {\n            qtySelector: 'input.qty',\n            qtyNameSelector: 'super_group'\n        },\n\n        /**\n         * Creates widget\n         * @private\n         */\n        _create: function () {\n            // Override defaults with URL query parameters and/or inputs values\n            this._overrideDefaults();\n        },\n\n        /**\n         * Override default options values settings with either URL query parameters or\n         * initialized inputs values.\n         * @private\n         */\n        _overrideDefaults: function () {\n            var hashIndex = window.location.href.indexOf('#');\n\n            if (hashIndex !== -1) {\n                this._parseQueryParams(window.location.href.substr(hashIndex + 1));\n            }\n        },\n\n        /**\n         * Parse query parameters from a query string and set options values based on the\n         * key value pairs of the parameters.\n         * @param {*} queryString - URL query string containing query parameters.\n         * @private\n         */\n        _parseQueryParams: function (queryString) {\n            var queryParams = $.parseQuery({\n                    query: queryString\n                }),\n                form = this.element,\n                qtyNameSelector = this.options.qtyNameSelector,\n                qtys = $(this.options.qtySelector, form);\n\n            $.each(queryParams, $.proxy(function (key, value) {\n                qtys.each(function (index, qty) {\n                    var nameSelector = qtyNameSelector.concat('[', key, ']');\n\n                    if (qty.name === nameSelector) {\n                        $(qty).val(value);\n                    }\n                });\n            }, this));\n        }\n    });\n\n    return $.mage.groupedProduct;\n});\n","Goyard_Adyen/js/model/adyen-wallet-registry.js":"/**\n * @copyright Copyright (c) 2026 Goyard\n * @author Orkester https://orkester.fr/\n *\n * Shared registry holding Adyen wallet component instances (Google Pay, Apple Pay).\n * Allows payment.js to call submit() on the component without a direct dependency.\n */\ndefine([], function () {\n    'use strict';\n\n    var components = {};\n\n    return {\n        set: function (methodCode, component) {\n            components[methodCode] = component;\n        },\n        get: function (methodCode) {\n            return components[methodCode] || null;\n        }\n    };\n});\n","Goyard_Adyen/js/model/adyen-checkout-mixin.js":"/**\n * @copyright Copyright (c) 2026 Goyard\n * @author Orkester https://orkester.fr/\n *\n * Mixin to override Adyen Web Components translations with Magento i18n\n */\n\ndefine([\n\t'jquery',\n\t'Adyen_Payment/js/model/adyen-configuration'\n], function ($, adyenConfiguration) {\n\t'use strict';\n\n\treturn function (originalAdyenCheckout) {\n\t\t// Build checkout with custom translations for validation messages\n\t\toriginalAdyenCheckout.buildCheckoutComponent = function (\n\t\t\tpaymentMethodsResponse,\n\t\t\tcountryCode,\n\t\t\thandleOnAdditionalDetails,\
2n\t\t\thandleOnSubmit,\n\t\t\thandleOnError\n\t\t) {\n\t\t\tif (!paymentMethodsResponse.paymentMethodsResponse) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar locale = adyenConfiguration.getLocale().replace('_', '-');\n\t\t\tvar translations = {};\n\t\t\t// Goyard custom translations\n\t\t\ttranslations[locale] = {\n\t\t\t\t'creditCard.cardNumber.label': $.mage.__('Card number'),\n\t\t\t\t'creditCard.expiryDate.label': $.mage.__('Expiration'),\n\t\t\t\t'creditCard.securityCode.label': $.mage.__('Security code'),\n\t\t\t\t'creditCard.securityCode.contextualText.3digits': $.mage.__('CVC'),\n\t\t\t\t'creditCard.holderName': $.mage.__('Name on the card'),\n\t\t\t\t'cc.num.900': $.mage.__('Enter a valid card number'),\n\t\t\t\t'cc.num.901': $.mage.__('Enter a valid card number'),\n\t\t\t\t'cc.num.902': $.mage.__('Enter a valid card number'),\n\t\t\t\t'cc.dat.910': $.mage.__('Enter a valid expiry date'),\n\t\t\t\t'cc.dat.911': $.mage.__('Enter a valid expiry date'),\n\t\t\t\t'cc.dat.912': $.mage.__('Enter a valid expiry date'),\n\t\t\t\t'cc.dat.913': $.mage.__('Enter a valid expiry date'),\n\t\t\t\t'cc.cvc.920': $.mage.__('Enter the security code'),\n\t\t\t\t'cc.cvc.921': $.mage.__('Enter the security code'),\n\t\t\t};\n\n\t\t\treturn window.AdyenWeb.AdyenCheckout({\n\t\t\t\tlocale: locale,\n\t\t\t\tcountryCode: countryCode,\n\t\t\t\tclientKey: adyenConfiguration.getClientKey(),\n\t\t\t\tenvironment: adyenConfiguration.getCheckoutEnvironment(),\n\t\t\t\tpaymentMethodsResponse: paymentMethodsResponse.paymentMethodsResponse,\n\t\t\t\ttranslations: translations,\n\t\t\t\tonAdditionalDetails: handleOnAdditionalDetails,\n\t\t\t\tonSubmit: handleOnSubmit,\n\t\t\t\tonError: handleOnError\n\t\t\t});\n\t\t};\n\n\t\tvar originalMount = originalAdyenCheckout.mountPaymentMethodComponent;\n\t\toriginalAdyenCheckout.mountPaymentMethodComponent = function (checkoutComponent, paymentMethodType, configuration, elementLabel, result) {\n\t\t\tif (paymentMethodType === 'card' && configuration) {\n\t\t\t\tconfiguration.placeholders = {\n\t\t\t\t\tcardNumber: $.mage.__('0000 0000 0000 0000'),\n\t\t\t\t\texpiryDate: $.mage.__('MM/YY'),\n\t\t\t\t\tsecurityCodeThreeDigits: $.mage.__('CVC'),\n\t\t\t\t\tholderName: $.mage.__('Mr. John Smith'),\n\t\t\t\t};\n\t\t\t}\n\t\t\t// Call parent with new configuration\n\t\t\treturn originalMount.call(this, checkoutComponent, paymentMethodType, configuration, elementLabel, result);\n\t\t};\n\n\t\treturn originalAdyenCheckout;\n\t};\n});\n","Goyard_Adyen/js/view/payment/method-renderer/adyen-cc-method-mixin.js":"/**\n * @copyright Copyright (c) 2026 Goyard\n * @author Orkester https://orkester.fr/\n */\n\ndefine([\n\t'jquery',\n\t'mage/url',\n\t'Adyen_Payment/js/model/adyen-payment-modal',\n\t'Magento_Checkout/js/model/full-screen-loader',\n\t'Adyen_Payment/js/model/adyen-payment-service',\n], function (\n\t$,\n\turl,\n\tAdyenPaymentModal,\n\tfullScreenLoader,\n\tadyenPaymentService,\n) {\n\t'use strict';\n\n\t/**\n\t * Maps an XHR error response to the appropriate user-facing message.\n\t * 5xx (technical/server errors) \u2192 ER001, all others \u2192 CCAM9.\n\t * NOTE: We do NOT use parsed.message for non-5xx because AfterPaymentsDetailsPlugin\n\t * only intercepts /paymentsDetails (3DS flow). Direct refusals go through\n\t * savePaymentInformationAndPlaceOrder and return the raw Adyen message\n\t * (e.g. \"The payment is REFUSED.\") which must not be shown to the user.\n\t */\n\tfunction resolveAdyenErrorMessage(response) {\n\t\tif (response.status >= 500) {\n\t\t\treturn $.mage.__('[ER001] An error occured while placing order.');\n\t\t}\n\n\t\treturn $.mage.__('Unfortunately the order could not be processed. Please contact us or try again later.');\n\t}\n\n\treturn function (Component) {\n\t\treturn Component.extend({\n\n\t\t\tdefaults: {\n\t\t\t\ttemplate: 'Goyard_Adyen/payment/cc-form',\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Returns the title for the component.\n\t\t\t * @returns {String} The title of the component.\n\t\t\t */\n\t\t\tgetTitle: function () {\n\t\t\t\treturn $.mage.__('Credit Cards');\n\t\t\t},\n\n\t\t\t// Removed in Adyen v10 but needed by Signifyd\n\t\t\tgetAllInstallments: function () {\n\t\t\t\treturn window.checkoutConfig.payment.adyenCc.installments;\n\t\t\t},\n\n\t\t\t// Removed in Adyen v10 but needed by Signifyd\n\t\t\tgetCcCodeByAltCode: function (altCode) {\n\t\t\t\tvar adyenCcTypes = window.checkoutConfig.payment.adyenCc.adyenCcTypes;\n\t\t\t\tif (adyenCcTypes && adyenCcTypes[altCode]) {\n\t\t\t\t\treturn adyenCcTypes[altCode].code;\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Intercepts place-order failures (direct card refusal, no 3DS).\
2n\t\t\t * The parent sends the AJAX and rejects the deferred on failure.\n\t\t\t * We read the mapped PHP message from responseText and store it in\n\t\t\t * sessionStorage before redirecting \u2014 sessionStorage survives the navigation\n\t\t\t * and is immune to Magento's section reload (which would overwrite customerData).\n\t\t\t * filter-cart-messages.js reads the value on cart page load and injects it.\n\t\t\t */\n\t\t\tgetPlaceOrderDeferredObject: function () {\n\t\t\t\tvar deferred = $.Deferred();\n\n\t\t\t\tthis._super()\n\t\t\t\t\t.done(function () {\n\t\t\t\t\t\tdeferred.resolve.apply(deferred, arguments);\n\t\t\t\t\t})\n\t\t\t\t\t.fail(function (response) {\n\t\t\t\t\t\tvar msg = resolveAdyenErrorMessage(response);\n\t\t\t\t\t\twindow.sessionStorage.setItem('adyen_payment_error', msg);\n\t\t\t\t\t\twindow.location.replace(url.build('checkout/cart'));\n\t\t\t\t\t\tdeferred.reject.apply(deferred, arguments);\n\t\t\t\t\t});\n\n\t\t\t\treturn deferred.promise();\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * On payment error, AfterPaymentsDetailsPlugin maps the Adyen exception to\n\t\t\t * CCAM9 (\"Unfortunately the order could not be processed...\") and re-throws it.\n\t\t\t * The HTTP error response contains that message in responseText.message \u2014\n\t\t\t * we store it in sessionStorage (survives navigation) and redirect to the cart page.\n\t\t\t * filter-cart-messages.js reads the value on cart load and injects it via customerData.\n\t\t\t */\n\t\t\thandleOnAdditionalDetails: function (result) {\n\t\t\t\tvar self = this;\n\t\t\t\tvar request = result.data;\n\n\t\t\t\tAdyenPaymentModal.hideModalLabel(this.modalLabel);\n\t\t\t\tfullScreenLoader.startLoader();\n\t\t\t\tvar popupModal = self.showModal();\n\n\t\t\t\tadyenPaymentService.paymentDetails(request, self.orderId)\n\t\t\t\t\t.done(function (responseJSON) {\n\t\t\t\t\t\tself.handleAdyenResult(responseJSON, self.orderId);\n\t\t\t\t\t})\n\t\t\t\t\t.fail(function (response) {\n\t\t\t\t\t\tself.closeModal(popupModal);\n\t\t\t\t\t\tfullScreenLoader.stopLoader();\n\t\t\t\t\t\tself.isPlaceOrderActionAllowed(true);\n\n\t\t\t\t\t\twindow.sessionStorage.setItem('adyen_payment_error', resolveAdyenErrorMessage(response));\n\t\t\t\t\t\twindow.location.replace(url.build('checkout/cart'));\n\t\t\t\t\t});\n\t\t\t},\n\t\t});\n\t};\n});\n","Goyard_Adyen/js/view/payment/method-renderer/adyen-googlepay-method-mixin.js":"/**\n * @copyright Copyright (c) 2026 Goyard\n * @author Orkester https://orkester.fr/\n *\n * Hides the native Google Pay button so the generic \"Valider et Payer\" CTA\n * can be used instead. The component instance is stored in adyen-wallet-registry\n * so payment.js can call submit() on it programmatically.\n * On payment failure (refusal or 3DS error), stores the error in sessionStorage\n * and redirects to cart \u2014 matching the CC payment error behaviour.\n */\ndefine([\n    'jquery',\n    'mage/url',\n    'Magento_Checkout/js/model/full-screen-loader',\n    'Adyen_Payment/js/model/adyen-payment-service',\n    'Adyen_Payment/js/model/adyen-payment-modal',\n    'Goyard_Adyen/js/model/adyen-wallet-registry'\n], function (\n    $,\n    url,\n    fullScreenLoader,\n    adyenPaymentService,\n    adyenPaymentModal,\n    walletRegistry\n) {\n    'use strict';\n\n    function resolveAdyenErrorMessage(response) {\n        if (response && response.status >= 500) {\n            return $.mage.__('[ER001] An error occured while placing order.');\n        }\n        return $.mage.__('Unfortunately the order could not be processed. Please contact us or try again later.');\n    }\n\n    /**\n     * Result codes meaning the payment went through, as classified by\n     * Adyen\\Payment\\Helper\\PaymentResponseHandler::formatPaymentResponse(). Refused and Error\n     * are flagged isFinal there too, so isFinal alone cannot stand for \"paid\".\n     */\n    var SUCCESSFUL_RESULT_CODES = ['Authorised', 'Received', 'PresentToShopper'];\n\n    return function (TargetComponent) {\n        return TargetComponent.extend({\n            defaults: {\n                template: 'Goyard_Adyen/payment/googlepay-form',\n                logoUrl: require.toUrl('images/payment_method/googlepay.svg'),\n                paymentAuthorised: fal
2se\n            },\n\n            buildComponentConfiguration: function (paymentMethod, paymentMethodsExtraInfo) {\n                var config = this._super(paymentMethod, paymentMethodsExtraInfo);\n                config.showPayButton = false;\n                return config;\n            },\n\n            selectPaymentMethod: function () {\n                var result = this._super();\n                this._markAsWallet();\n                return result;\n            },\n\n            mountPaymentMethodComponent: function (paymentMethod, configuration, methodCode) {\n                this._super(paymentMethod, configuration, methodCode);\n                if (this.paymentComponent) {\n                    walletRegistry.set(this.getCode(), this.paymentComponent);\n                }\n                this._markAsWallet();\n            },\n\n            _markAsWallet: function () {\n                var radioEl = document.getElementById(this.getCode());\n                if (radioEl) {\n                    var wrapper = radioEl.closest('.payment-method');\n                    if (wrapper) {\n                        wrapper.classList.add('adyen-wallet-method');\n                    }\n                }\n            },\n\n            /**\n             * Latch the payment as paid, which handleOnFailure() needs to spot late failures.\n             * The parent only tracks orderId on its non-final branch.\n             */\n            validateActionOrPlaceOrder: function (responseJSON, orderId, component) {\n                var response = JSON.parse(responseJSON);\n\n                if (response.isFinal && SUCCESSFUL_RESULT_CODES.indexOf(response.resultCode) !== -1) {\n                    this.paymentAuthorised = true;\n                    this.orderId = orderId;\n                }\n\n                return this._super(responseJSON, orderId, component);\n            },\n\n            /**\n             * Called when placeRedirectOrder fails (payment refused, network error, etc.).\n             * Also called via handleOnError for Adyen component-level errors.\n             * Redirects to cart with a sanitised message instead of showing it inline\n             * in the checkout \u2014 matches the behaviour of the CC mixin.\n             *\n             * Failures reported after the payment was authorised are ignored: the Google Pay\n             * sheet is still open when the parent starts navigating to the success page, and its\n             * teardown makes the Google Pay SDK reject with statusCode CANCELED. Redirecting on\n             * that would replace the in-flight success navigation with the cart, dropping the\n             * shopper on an empty cart with a paid order.\n             */\n            handleOnFailure: function (error, component) {\n                if (this.paymentAuthorised) {\n                    // Keep the loader up: the browser is on its way to the success page.\n                    return;\n                }\n\n                fullScreenLoader.stopLoader();\n                window.sessionStorage.setItem('adyen_payment_error', resolveAdyenErrorMessage(error));\n                window.location.replace(url.build('checkout/cart'));\n            },\n\n            /**\n             * Called after a 3DS challenge (edge case for wallet payments).\n             * On success, redirects to the Adyen success page.\n             * On failure, redirects to cart with a sanitised error message.\n             */\n            handleOnAdditionalDetails: function (state, component) {\n                var self = this;\n                adyenPaymentModal.hideModalLabel(this.modalLabel);\n                fullScreenLoader.startLoader();\n\n                var request = (state && state.data) ? state.data : {};\n\n                adyenPaymentService.paymentDetails(request, self.orderId)\n                    .done(function () {\n                        $.mage.redirect(window.checkoutConfig.payment.adyen.successPage);\n                    })\n                    .fail(function (response) {\n                        if (self.popupModal) {\n                            self.closeModal(self.popupModal);\n                        }\n                        window.sessionStorage.setItem('adyen_payment_error', resolveAdyenErrorMessage(response));\n                        window.location.replace(url.build('checkout/cart'));\n                    });\n            }\n        });\n    };\n});\n","Goyard_Adyen/js/view/payment/method-renderer/adyen-applepay-method-mixin.js":"/**\n * @copyright Copyright (c) 2026 Goyard\n * @author Orkester https://orkester.fr/\n *\n * Hides the native Apple Pay button so the generic \"Valider et Payer\" CTA\n * can be used instead. The component instance is stored in adyen-wallet-registry\n * so payment.js can call submit() on it programmatically.\n * On payment failure (refusal or 3DS error), stores the error in sessionStorage\n * and redirects to cart \u2014 matching the CC payment error behaviour.\n */\ndefine([\n    'jquery',\n    'mage/url',\n    'Magento_Checkout/js/model/full-screen-loader',\n    'Adyen_Payment/js/model/adyen-payment-service',\n    'Adyen_Payment/js/model/adyen-payment-modal',\n    'Goyard_Adyen/js/model/adyen-wallet-registry'\n], function (\n    $,\n    url,\n    fullScreenLoader,\n    adyenPaymentService,\n    adyenPaymentModal,\n    walletRegistry\n) {\n    'use strict';\n\n    function resolveAdyenErrorMessage(response) {\n        if (response && response.status >= 500) {\n            return $.mage.__('[ER001] An error occured while placing order.');\n        }
2\n        return $.mage.__('Unfortunately the order could not be processed. Please contact us or try again later.');\n    }\n\n    return function (TargetComponent) {\n        return TargetComponent.extend({\n            defaults: {\n                template: 'Goyard_Adyen/payment/applepay-form',\n                logoUrl: require.toUrl('images/payment_method/applepay.svg')\n            },\n\n            buildComponentConfiguration: function (paymentMethod, paymentMethodsExtraInfo) {\n                var config = this._super(paymentMethod, paymentMethodsExtraInfo);\n                config.showPayButton = false;\n                return config;\n            },\n\n            selectPaymentMethod: function () {\n                var result = this._super();\n                this._markAsWallet();\n                return result;\n            },\n\n            mountPaymentMethodComponent: function (paymentMethod, configuration, methodCode) {\n                this._super(paymentMethod, configuration, methodCode);\n                if (this.paymentComponent) {\n                    walletRegistry.set(this.getCode(), this.paymentComponent);\n                }\n                this._markAsWallet();\n            },\n\n            _markAsWallet: function () {\n                var radioEl = document.getElementById(this.getCode());\n                if (radioEl) {\n                    var wrapper = radioEl.closest('.payment-method');\n                    if (wrapper) {\n                        wrapper.classList.add('adyen-wallet-method');\n                    }\n                }\n            },\n\n            /**\n             * Called when placeRedirectOrder fails (payment refused, network error, etc.).\n             * Also called via handleOnError for Adyen component-level errors.\n             * Redirects to cart with a sanitised message instead of showing it inline\n             * in the checkout \u2014 matches the behaviour of the CC mixin.\n             */\n            handleOnFailure: function (error, component) {\n                fullScreenLoader.stopLoader();\n                window.sessionStorage.setItem('adyen_payment_error', resolveAdyenErrorMessage(error));\n                window.location.replace(url.build('checkout/cart'));\n            },\n\n            /**\n             * Called after a 3DS challenge (edge case for wallet payments).\n             * On success, redirects to the Adyen success page.\n             * On failure, redirects to cart with a sanitised error message.\n             */\n            handleOnAdditionalDetails: function (state, component) {\n                var self = this;\n                adyenPaymentModal.hideModalLabel(this.modalLabel);\n                fullScreenLoader.startLoader();\n\n                var request = (state && state.data) ? state.data : {};\n\n                adyenPaymentService.paymentDetails(request, self.orderId)\n                    .done(function () {\n                        $.mage.redirect(window.checkoutConfig.payment.adyen.successPage);\n                    })\n                    .fail(function (response) {\n                        if (self.popupModal) {\n                            self.closeModal(self.popupModal);\n                        }\n                        window.sessionStorage.setItem('adyen_payment_error', resolveAdyenErrorMessage(response));\n                        window.location.replace(url.build('checkout/cart'));\n                    });\n            }\n        });\n    };\n});\n","Magento_Tax/js/price/adjustment.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Ui/js/grid/columns/column',\n    'mage/translate'\n], function (Element, $t) {\n    'use strict';\n\n    return Element.extend({\n        defaults: {\n            bodyTmpl: 'Magento_Tax/price/adjustment',\n            taxPriceType: 'final_price',\n            taxPriceCssClass: 'price-including-tax',\n            bothPrices: 3,\n            inclTax: 2,\n            exclTax: 1,\n            modules: {\n                price: '${ $.parentName }'\n            },\n            listens: {\n                price: 'initializePriceAttributes'\n            }\n        },\n\n        /**\n         * {@inheritdoc}\n         */\n        initialize: function () {\n            this._super()\n                .initializePriceAttributes();\n\n            return this;\n        },\n\n        /**\n         * Update parent price.\n         *\n         * @returns {Object} Chainable.\n         */\n        initializePriceAttributes: function () {\n            if (this.displayBothPrices && this.price()
2) {\n                this.price().priceWrapperCssClasses = this.taxPriceCssClass;\n                this.price().priceWrapperAttr = {\n                    'data-label': $t('Incl. Tax')\n                };\n            }\n\n            return this;\n        },\n\n        /**\n         * Get price tax adjustment.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} tax html\n         */\n        getTax: function (row) {\n            return row['price_info']['extension_attributes']['tax_adjustments']['formatted_prices'][this.taxPriceType];\n        },\n\n        /**\n         * UnsanitizedHtml version of getTax.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} tax html\n         */\n        getTaxUnsanitizedHtml: function (row) {\n            return this.getTax(row);\n        },\n\n        /**\n         * Set price tax type.\n         *\n         * @param {String} priceType\n         * @return {Object}\n         */\n        setPriceType: function (priceType) {\n            this.taxPriceType = priceType;\n\n            return this;\n        },\n\n        /**\n         * Return whether display setting is to display\n         * both price including tax and price excluding tax.\n         *\n         * @return {Boolean}\n         */\n        displayBothPrices: function () {\n            return +this.source.data.displayTaxes === this.bothPrices;\n        },\n\n        /**\n         * Return whether display setting is to display price including tax.\n         *\n         * @return {Boolean}\n         */\n        displayPriceIncludeTax: function () {\n            return +this.source.data.displayTaxes === this.inclTax;\n        },\n\n        /**\n         * Return whether display setting is to display price excluding tax.\n         *\n         * @return {Boolean}\n         */\n        displayPriceExclTax: function () {\n            return +this.source.data.displayTaxes === this.exclTax;\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/shipping_method/price.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'uiComponent',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Catalog/js/price-utils'\n], function (Component, quote, priceUtils) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_Tax/checkout/shipping_method/price'\n        },\n        isDisplayShippingPriceExclTax: window.checkoutConfig.isDisplayShippingPriceExclTax,\n        isDisplayShippingBothPrices: window.checkoutConfig.isDisplayShippingBothPrices,\n\n        /**\n         * @param {Object} item\n         * @return {Boolean}\n         */\n        isPriceEqual: function (item) {\n            return item['price_excl_tax'] != item['price_incl_tax']; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @param {*} price\n         * @return {*|String}\n         */\n        getFormattedPrice: function (price) {\n            //todo add format data\n            return priceUtils.formatPriceLocale(price, quote.getPriceFormat());\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/minicart/subtotal/totals.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'ko',\n    'uiComponent',\n    'Magento_Customer/js/customer-data'\n], function (ko, Component, customerData) {\n    'use strict';\n\n    return Component.extend({\n        displaySubtotal: ko.observable(true),\n\n        /**\n         * @override\n         */\n        initialize: function () {\n            this._super();\n            this.cart = customerData.get('cart');\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/summary/subtotal.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Checkout/js/view/summary/abstract-total',\n    'Magento_Checkout/js/model/quote'\n], function (Component, quote) {\n    'use strict';\n\n    var displaySubtotalMode = window.checkoutConfig.reviewTotalsDisplayMode;\n\n    return Component.extend({\n        defaults: {\n            displaySubtotalMode: displaySubtotalMode,\n            template: 'Magento_Tax/checkout/summary/subtotal'\n        },\n        totals: quote.getTotals(),\n\n        /**\n         * @return {*|String}\n         */\n        getValue: function () {\n            var price = 0;\n\n            if (this.totals()) {\n                price = this.totals().subtotal;\n            }\n\n            return this.getFormattedPrice(price);\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isBothPricesDisplayed: function () {\n            return this.displaySubtotalMode == 'both'; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isIncludingTaxDisplayed: function () {\n            return this.displaySubtotalMode == 'including'; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @return {*|String}\n         */\n        getValueInclTax: function () {\n            var price = 0;\n\n            if (this.totals()) {\n                price = this.totals()['subtotal_incl_tax'];\n            }\n\n            return this.getFormattedPrice(price);\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/summary/grand-total.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Checkout/js/view/summary/abstract-total',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Catalog/js/price-utils',\n    'Magento_Checkout/js/model/totals'\n], function (Component, quote, priceUtils, totals) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            isFullTaxSummaryDisplayed: window.checkoutConfig.isFullTaxSummaryDisplayed || false,\n            template: 'Magento_Tax/checkout/summary/grand-total'\n        },\n        totals: quote.getTotals(),\n        isTaxDisplayedInGrandTotal: window.checkoutConfig.includeTaxInGrandTotal || false,\n\n        /**\n         * @return {*}\n         */\n        isDisplayed: function () {\n            return this.isFullMode();\n        },\n\n        /**\n         * @return {*|String}\n         */\n        getValue: function () {\n            var price = 0;\n\n            if (this.totals()) {\n                price = totals.getSegment('grand_total').value;\n            }\n\n            return this.getFormattedPrice(price);\n        },\n\n        /**\n         * @return {*|String}\n         */\n        getBaseValue: function () {\n            var price = 0;\n\n            if (this.totals()) {\n                price = this.totals()['base_grand_total'];\n            }
2\n\n            return priceUtils.formatPriceLocale(price, quote.getBasePriceFormat());\n        },\n\n        /**\n         * @return {*}\n         */\n        getGrandTotalExclTax: function () {\n            var total = this.totals(),\n                amount;\n\n            if (!total) {\n                return 0;\n            }\n\n            amount = total['grand_total'] - total['tax_amount'];\n\n            if (amount < 0) {\n                amount = 0;\n            }\n\n            return this.getFormattedPrice(amount);\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isBaseGrandTotalDisplayNeeded: function () {\n            var total = this.totals();\n\n            if (!total) {\n                return false;\n            }\n\n            return total['base_currency_code'] != total['quote_currency_code']; //eslint-disable-line eqeqeq\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/summary/tax.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'ko',\n    'Magento_Checkout/js/view/summary/abstract-total',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Checkout/js/model/totals',\n    'mage/translate',\n    'underscore'\n], function (ko, Component, quote, totals, $t, _) {\n    'use strict';\n\n    var isTaxDisplayedInGrandTotal = window.checkoutConfig.includeTaxInGrandTotal,\n        isFullTaxSummaryDisplayed = window.checkoutConfig.isFullTaxSummaryDisplayed,\n        isZeroTaxDisplayed = window.checkoutConfig.isZeroTaxDisplayed,\n        taxAmount = 0,\n        rates = 0;\n\n    return Component.extend({\n        defaults: {\n            isTaxDisplayedInGrandTotal: isTaxDisplayedInGrandTotal,\n            notCalculatedMessage: $t('Not yet calculated'),\n            template: 'Magento_Tax/checkout/summary/tax'\n        },\n        totals: quote.getTotals(),\n        isFullTaxSummaryDisplayed: isFullTaxSummaryDisplayed,\n\n        /**\n         * @return {Boolean}\n         */\n        ifShowValue: function () {\n            if (this.isFullMode() && this.getPureValue() == 0) { //eslint-disable-line eqeqeq\n                return isZeroTaxDisplayed;\n            }\n\n            return true;\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        ifShowDetails: function () {\n            if (!this.isFullMode()) {\n                return false;\n            }\n\n            return this.getPureValue() > 0 && isFullTaxSummaryDisplayed;\n        },\n\n        /**\n         * @return {Number}\n         */\n        getPureValue: function () {\n            var amount = 0,\n                taxTotal;\n\n            if (this.totals()) {\n                taxTotal = totals.getSegment('tax');\n\n                if (taxTotal) {\n                    amount = taxTotal.value;\n                }\n            }\n\n            return amount;\n        },\n\n        /**\n         * @return {*|Boolean}\n         */\n        isCalculated: function () {\n            return this.totals() && this.isFullMode() && totals.getSegment('tax') != null;\n        },\n\n        /**\n         * @return {*}\n         */\n        getValue: function () {\n            var amount;\n\n            if (!this.isCalculated()) {\n                return this.notCalculatedMessage;\n            }\n            amount = totals.getSegment('tax').value;\n\n            return this.getFormattedPrice(amount);\n        },\n\n        /**\n         * @param {*} amount\n         * @return {*|String}\n         */\n        formatPrice: function (amount) {\n            return this.getFormattedPrice(amount);\n        },\n\n        /**\n         * @param {*} parent\n         * @param {*} percentage\n         * @return {*|String}\n         */\n        getTaxAmount: function (parent, percentage) {\n            var totalPercentage = 0;\n\n            taxAmount = parent.amount;\n            rates = parent.rates;\n            _.each(rates, function (rate) {\n                totalPercentage += parseFloat(rate.percent);\n            });\n\n            return this.getFormattedPrice(this.getPercentAmount(taxAmount, totalPercentage, percentage));\n        },\n\n        /**\n         * @param {*} amount\n         * @param {*} totalPercentage\n         * @param {*} percentage\n         * @return {*|String}\n         */\n        getPercentAmount: function (amount, totalPercentage, percentage) {\n            return parseFloat(amount * percentage / totalPercentage);\n        },\n\n        /**\n         * @return {Array}\n         */\n        getDetails: function () {\n            var taxSegment = totals.getSegment('tax');\n\n            if (taxSegment && taxSegment['extension_attributes']) {\n                return taxSegment['extension_attributes']['tax_grandtotal_details'];\n            }\n\n            return [];\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/summary/shipping.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'jquery',\n    'Magento_Checkout/js/view/summary/shipping',\n    'Magento_Checkout/js/model/quote'\n], function ($, Component, quote) {\n    'use strict';\n\n    var displayMode = window.checkoutConfig.reviewShippingDisplayMode;\n\n    return Component.extend({\n        defaults: {\n            displayMode: displayMode,\n            template: 'Magento_Tax/checkout/summary/shipping'\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isBothPricesDisplayed: function () {\n            return this.displayMode == 'both'; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isIncludingDisplayed: function () {\n            return this.displayMode == 'including'; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isExcludingDisplayed: function () {\n            return this.displayMode == 'excluding'; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @return {*|Boolean}\n         */\n        isCalculated: function () {\n            return this.totals() && this.isFullMode() && quote.shippingMethod() != null;\n        },\n\n        /**\n         * @return {*}\n         */\n        getIncludingValue: function () {\n            var price;\n\n            if (!this.isCalculated()) {\n                return this.notCalculatedMessage;\n            }\n            price = this.totals()['shipping_incl_tax'];\n\n            return this.getFormattedPrice(price);\n        },\n\n        /**\n         * @return {*}\n         */\n        getExcludingValue: function () {\n            var price;\n\n            if (!this.isCalculated()) {\n                return this.notCalculatedMessage;\n            }\n            price = this.totals()['shipping_amount'];\n\n            return this.getFormattedPrice(price);\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/summary/item/details/subtotal.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Checkout/js/view/summary/item/details/subtotal'\n], function (subtotal) {\n    'use strict';\n\n    var displayPriceMode = window.checkoutConfig.reviewItemPriceDisplayMode || 'including';\n\n    return subtotal.extend({\n        defaults: {\n            displayPriceMode: displayPriceMode,\n            template: 'Magento_Tax/checkout/summary/item/details/subtotal'\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isPriceInclTaxDisplayed: function () {\n            return dis
2playPriceMode == 'both' || displayPriceMode == 'including'; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isPriceExclTaxDisplayed: function () {\n            return displayPriceMode == 'both' || displayPriceMode == 'excluding'; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * @param {Object} quoteItem\n         * @return {*|String}\n         */\n        getValueInclTax: function (quoteItem) {\n            return this.getFormattedPrice(quoteItem['row_total_incl_tax']);\n        },\n\n        /**\n         * @param {Object} quoteItem\n         * @return {*|String}\n         */\n        getValueExclTax: function (quoteItem) {\n            return this.getFormattedPrice(quoteItem['row_total']);\n        }\n\n    });\n});\n","Magento_Tax/js/view/checkout/cart/totals/grand-total.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Tax/js/view/checkout/summary/grand-total'\n], function (Component) {\n    'use strict';\n\n    return Component.extend({\n        /**\n         * @override\n         */\n        isDisplayed: function () {\n            return true;\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/cart/totals/tax.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Tax/js/view/checkout/summary/tax',\n    'Magento_Checkout/js/model/totals'\n], function (Component, totals) {\n    'use strict';\n\n    var isFullTaxSummaryDisplayed = window.checkoutConfig.isFullTaxSummaryDisplayed,\n        isZeroTaxDisplayed = window.checkoutConfig.isZeroTaxDisplayed;\n\n    return Component.extend({\n        /**\n         * @override\n         */\n        ifShowValue: function () {\n            if (this.isFullMode() && this.getPureValue() == 0) { //eslint-disable-line eqeqeq\n                return isZeroTaxDisplayed;\n            }\n\n            return true;\n        },\n\n        /**\n         * @override\n         */\n        ifShowDetails: function () {\n            return this.getPureValue() > 0 && isFullTaxSummaryDisplayed;\n        },\n\n        /**\n         * @override\n         */\n        isCalculated: function () {\n            return this.totals() && totals.getSegment('tax') !== null;\n        }\n    });\n});\n","Magento_Tax/js/view/checkout/cart/totals/shipping.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Tax/js/view/checkout/summary/shipping',\n    'Magento_Checkout/js/model/quote'\n], function (Component, quote) {\n    'use strict';\n\n    return Component.extend({\n        /**\n         * @override\n         */\n        isCalculated: function () {\n            return !!quote.shippingMethod();\n        },\n\n        /**\n         * @override\n         */\n        getShippingMethodTitle: function () {\n            return '(' + this._super() + ')';\n        }\n    });\n});\n","js/address-popup.js":"/**\n * Copyright Goyard\n * Customer Addresses Page\n * Front Js to Open and Close Popup when user click on Delete\n */\n\nrequire([\n    'jquery',\n], function($) {\n    $(document).ready(function() {\n\n        //open popup with button \"delete\"\n        $('.address-delete').off('click').on('click', function() {\n            let addressBlock = $(this).closest('.block-content').find('.block-address');\n            let popUp = $(this).closest('.block-content').find('.block-address-popup');\n\n            popUp.show();\n\n            if(addressBlock.hasClass('blur0')){\n                addressBlock.removeClass('blur0').addClass('blur4');\n            } else {\n                addressBlock.addClass('blur4');\n            }\n        });\n\n\n        //Close popup with Cross \"X\" or Button \"No\"\n        $('.address-popup-close').off('click').on('click', function() {\n            let addressBlock = $(this).closest('.block-content').find('.block-address');\n            let popUp = $(this).closest('.block-content').find('.block-address-popup');\n\n            popUp.hide();\n\n            if(addressBlock.hasClass('blur4')){\n                addressBlock.removeClass('blur4').addClass('blur0');\n            } else {\n                addressBlock.addClass('blur0');\n            }\n        });\n\n        //Close popup when click outside popup\n        $(document).on('click', function(event) { \n            if (!$(event.target).closest('.block-address-popup').length && (!$(event.target).closest('.address-delete').length) ) {\n                $('.block-address.blur4').parent().find('.block-address-popup').hide();\n                $('.block-address.blur4').removeClass('blur4').addClass('blur0');\n            };\n        });
2\n\n        //Construct URL to redirect on /customer/address/delete/id/ when user click on 'Yes'\n        $('.action.delete').on('click', function(){\n            window.location =  $(this).data('address').toString() + '/form_key/' + $.mage.cookies.get('form_key')\n        });\n    });\n});","js/plp-focus-scroll.js":"/**\n * @copyright Copyright (c) 2026 Goyard\n * @author Orkester https://orkester.fr/\n *\n * GOYARDCOM-3875 - On the PLP, a tile focused via keyboard (Shift+Tab) can stay\n * hidden under the fixed header stack (page header, nav, category title, filters\n * bar) because Firefox does not scroll focused elements out from under fixed\n * overlays. Scroll the page so the whole tile is visible below the stack.\n */\ndefine([\n    \"jquery\",\n    \"access_key\"\n], function ($) {\n    \"use strict\";\n\n    var overlaySelectors = \".page-header, .sections.nav-sections, .page-title-wrapper.fixed-title, .block.filter.fixed-title\";\n    var clearance = 10;\n    var keyboardNavigation = false;\n\n    function fixedOverlayBottom() {\n        var bottom = 0;\n\n        $(overlaySelectors).each(function () {\n            var style = window.getComputedStyle(this),\n                rect;\n\n            if (style.position !== \"fixed\" && style.position !== \"sticky\") {\n                return;\n            }\n            if (style.display === \"none\" || style.visibility === \"hidden\") {\n                return;\n            }\n            rect = this.getBoundingClientRect();\n\n            // ignore overlays that are collapsed or not pinned to the top of the viewport\n            if (rect.height === 0 || rect.bottom <= 0 || rect.top > window.innerHeight / 2) {\n                return;\n            }\n            bottom = Math.max(bottom, rect.bottom);\n        });\n\n        return bottom;\n    }\n\n    function clearFocusedTile(element) {\n        var tile, tileTop, overlayBottom;\n\n        if (document.activeElement !== element) {\n            return;\n        }\n        tile = element.closest(\".product-item\") || element;\n        tileTop = tile.getBoundingClientRect().top;\n        overlayBottom = fixedOverlayBottom();\n\n        if (tileTop < overlayBottom + clearance) {\n            window.scrollBy(0, tileTop - overlayBottom - clearance);\n        }\n    }\n\n    $(document).ready(function () {\n        var $grid = $(\".catalog-category-view .products.wrapper\");\n\n        if (!$grid.length) {\n            return;\n        }\n\n        $(document).on(\"keydown\", function (event) {\n            keyboardNavigation = eventTab(event);\n        });\n        $(document).on(\"mousedown\", function () {\n            keyboardNavigation = false;\n        });\n\n        $grid.on(\"focusin\", function (event) {\n            if (!keyboardNavigation) {\n                return;\n            }\n            window.requestAnimationFrame(function () {\n                clearFocusedTile(event.target);\n            });\n\n            // scrolling up makes the nav, title and filters bar reappear\n            // (sticky-header.js / category-top-of-page.js), re-check once settled\n            setTimeout(function () {\n                clearFocusedTile(event.target);\n            }, 250);\n        });\n    });\n});\n","js/skip-links.js":"/**\n * Copyright Goyard\n */\ndefine([\n    \"jquery\",\n    \"access_key\"\n], function ($) {\n    \"use strict\";\n    $(document).ready(function () {\n        // Skip links are hidden off-screen and brought back into the flow on focus,\n        // see web/css/source/header/_header.less -> .header-skip-links\n        var $mainContent = $('#maincontent');\n\n        // The main content area must be programmatically focusable\n        if ($mainContent.length > 0) {\n            $mainContent.attr('tabindex', '-1');\n        }\n        if($('li.header-skip-link-navbar a').length > 0) {\n        \tdocument.querySelector('li.header-skip-link-navbar a').addEventListener('keyup', function(event) {\n\t            if (event.type === 'keyup' && eventEnter(event)) {\n\t                let navSectionElement = document.getElementById(\"store.menu\");\n\t                if(navSectionElement){\n\t                    $(navSectionElement).find('a').first().focus();\n\t                }\n\t            }\n        \t});\n        }\n        // Enter on a link natively fires a click event : a single click handler covers\n        // keyboard, mouse and assistive technologies activation\n        $('li.header-skip-link-body a').on('click', function (event) {\n            if ($mainContent.length > 0) {\n                event.preventDefault();\n                $mainContent.trigger('focus');\n            }\n        });\n        if($('li.header-skip-link-footer a').length > 0) {\n\t        document.querySelector('li.header-skip-link-footer a').addEventListener('keydown', function(event) {\n\t            if (event.type === 'keydown' && eventEnter(event)) {\n\t                let newsletterInput = document.getElementById('newsletter');\n\t                if (newsletterInput) {\n\t                    newsletterInput.focus();\n\t                }\n\t            }\n\t        });\n        }\n    });\n});","js/ajax-link-modal.js":"/**\n * Copyright Goyard\n */\nrequire(\n    ['jquery',\n    'Magento_Ui/js/modal/modal',\n    'mage/url',\n    'jquery/ui'],\n    function($,modal,urlBuilder,ui){\n    'use strict';\n\n    $(document).ready(function(){\n        const element = $('[data-role=\"ajaxLinkModal\"]');\n        const href = element.attr('href');\n        const title = element.attr('data-modal-title');\n\n        const linkModal = `<div id=\"link-modal\" class=\"link-modal\">\n                    <div class=\"link-modal goyard-loader\" style=\"display:none; display:flex; justify-content:center; align-items: center\">\n                    <img src=\"${require.toUrl('images/loader-white.gif')}\" alt=\"Loader\"/>\n                    </div>\n                </div>`;\n\n        $('body').append(linkModal).promise().done(function(){\n            let options = {\n                responsive: true,\n                innerScroll: true,\n                modalClass: title,\n                clickableOverlay: true,\n                buttons: []\n            };\n            let modal_element = $('#link-modal');\n            let popup = modal(options, modal_element);\n            let pageWrapper = $('.page-wrapper');\n            let pageFooter = $('.page-footer');\n\n\n            // Open modal & had blur around\n            $('[data-role=\"ajaxLinkModal\"]').on('click', function(e){\n                e.preventDefault();
2\n                modal_element.modal('openModal');\n                $('.link-modal.goyard-loader').show();\n                \n                pageWrapper.addClass('blur4');\n                if(pageWrapper.hasClass('blur0')){\n                    pageWrapper.removeClass('blur0');\n                }\n                pageFooter.addClass('blur4');\n                if(pageFooter.hasClass('blur0')){\n                    pageFooter.removeClass('blur0');\n                }\n            })\n            // Close modal & delete blur around\n            $('#link-modal').on('modalclosed', function() {\n                $(\".page-wrapper\").removeClass('blur4').addClass('blur0');\n                $(\".page-footer\").removeClass('blur4').addClass('blur0');\n            });\n            // On modal open\n            modal_element.modal({\n                opened: function() {\n                    $.ajax({\n                        url: href,\n                        type: 'GET',\n                        success: function (response) {\n                            const $reponseHtml = $(response);\n                            const content = $reponseHtml.find('#maincontent').html();\n                            $('#link-modal').empty();\n                            modal_element.append(content);\n                            modal_element.trigger('contentUpdated');\n                            $('.link-modal.goyard-loader').hide();\n                        },\n                        error: function(xhr, status, error) {\n                            console.error(error);\n                        }\n                    });\n                }\n            });\n        });\n           \n    })\n});","js/globale-attributes.js":"define([\n\t'jquery',\n\t'Magento_Customer/js/customer-data'\n], function ($, customerData) {\n\t'use strict';\n\n\t$(document).ready(function () {\n\t\tfindGlobaleAttributes();\n\t});\n\n\t/**\n\t * Check user is logged\n\t */\n\tfunction getCustomerData() {\n\t\treturn new Promise(function (resolve, reject) {\n\t\t\tlet customer = customerData.get('customer');\n\t\t\tlet firstname = customer().firstname;\n\t\t\tif (firstname) {\n\t\t\t\tresolve();\n\t\t\t} else {\n\t\t\t\tcustomer.subscribe(function () {\n\t\t\t\t\tif (customer().firstname) {\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Manage summary\n\t * @returns void\n\t */\n\tfunction observeSummary() {\n\t\tvar summaryNode = $('cart-totals').find('.table-wrapper');\n\t\tvar subtotal = $('.totals.sub').find('.price');\n\t\tvar total = $('.grand.totals').find('.price');\n\n\t\tif (summaryNode.hasClass('_block-content-loading') || !subtotal.length || !total.length) {\n\t\t\twindow.setTimeout(observeSummary, 500);\n\t\t\treturn;\n\t\t}\n\t\t// When item in totals exist, add globale attributes\n\t\t$('.totals.sub').find('.price').trigger('update-globale-element');\n\t\t$('.grand.totals').find('.price').trigger('update-globale-element');\n\t}\n\n\t// Check reload/insert of element\n\t$(document).on('update-globale-element', function (e, eventInfo) {\n\t\tgetCustomerData()\n\t\t\t.then(function () {\n\t\t\t\t// TODO - Check global-e is enable current storefront\n\t\t\t\t// if (window.globale_config) {\n\t\t\t\taddGlobaleAttributes($(e.target));\n\t\t\t\t// }\n\t\t\t})\n\t\t\t.catch(function (error) {\n\t\t\t\tconsole.error('Error while fetching data:', error);\n\t\t\t});\n\t});\n\n\t// Price attribute need to be add using js\n\tfunction findGlobaleAttributes() {\n\t\tgetCustomerData()\n\t\t\t.then(function () {\n\t\t\t\t// TODO - Check global-e is enable current storefront\n\t\t\t\t// if (window.globale_config) {\n\t\t\t\t// Add global-e attribute to element which should have it\n\t\t\t\t$('[data-storefront-globale]').each(function () {\n\t\t\t\t\taddGlobaleAttributes($(this));\n\t\t\t\t})\n\n\t\t\t\t// Check minicart\n\t\t\t\t// observeMinicart();\n\t\t\t\t// Price in product page\n\t\t\t\tif ($('.catalog-product-view').length > 0) {\n\t\t\t\t\t$('.product-info-main .product-info-price').find('.price').attr('data-ge-price', '');\n\t\t\t\t}\n\n\t\t\t\t// Price in cart\n\t\t\t\tif (window.basket_conversion_allowed && $('.checkout-cart-index').length > 0) {\n\t\t\t\t\tobserveSummary();\n\n\t\t\t\t\t$('#shopping-cart-table').find('.price').each(function () {\n\t\t\t\t\t\t$(this).attr('data-ge-basket-producttotalprice', '');\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\t// }\n\t\t\t})\n\t\t\t.catch(function (error) {\n\t\t\t\tconsole.error('Error while fetching data:', error);\n\t\t\t});\n\t}\n\n\t// Add global-e attribute to element\n\tfunction addGlobaleAttributes($element) {\n\t\tif ($element.length) {\n\t\t\tlet globaleAttribute = $element.data('storefront-globale')?.split('=')\n\t\t\t$element.attr(globaleAttribute?.[0], globaleAttribute?.[1] ?? '');\n\t\t}\n\t}\n});","js/horizontal-top.js":"/**\n * Copyright \u00a9 2017 Magento. All rights reserved.\n * See COPYING.txt for license details.\n */\n\nrequire([\n    'jquery',\n    'matchMedia',\n    \"preheader\",\n    'domReady!'\n], function ($, mediaCheck) {\n    'use strict';\n\n    function closeMenu() {\n        $(\"html\").removeClass(\"nav-before-open nav-open\");\n        $('.vertical-menu').removeClass(\"active\");\n        $('.navigation').removeClass('active-level-1 active-level-2');\n        $('.megamenu-item').removeClass('active show-child');\n        $('.action.nav-toggle').removeClass(\"menu-open\");\n        $('.action.nav-toggle').trigger('focus');\n    }
2\n\n    function isPreheaderReady() {\n        return Boolean($('#preheader-wrapper').data('mage-preheader'));\n    }\n\n    function adjustBlockRightPosition() {\n        let header = $('.sections.nav-sections').scrollTop(0);\n        let preheaderHeight = $('.preheader-wrapper').length ? $('.preheader-wrapper').height() : 0;\n        let pageHeaderHeight = $('.page-header').height();\n        let navBarHeight = $('.nav-sections').height();\n        let navigationMaxHeight = document.documentElement.clientHeight - (preheaderHeight + pageHeaderHeight + navBarHeight);\n\n        if (!$(\".megamenu-item\").hasClass(\"active\")) {\n            if (header == 0) {\n                $(\"#block-right-broken\").remove();\n            } else {\n                $(\".block-right\").attr(\"style\", \"top:\" + (preheaderHeight + 120).toString() + \"px\");\n                let block_right_broken = document.querySelector(\"#block-right-broken\");\n\n                if (!block_right_broken) {\n                    block_right_broken = document.createElement(\"input\");\n                    block_right_broken.setAttribute(\"id\", \"block-right-broken\");\n                    block_right_broken.setAttribute(\"type\", \"hidden\");\n                    document.body.appendChild(block_right_broken);\n                }\n            }\n        }\n\n        // Update navigation menu position\n        $('.megamenu-dropdown > .block-main > .megamenu-sub-items').css('max-height', navigationMaxHeight);\n        $('.megamenu-item').children('.megamenu-dropdown').css('max-height', navigationMaxHeight);\n        $('.block-right').css('max-height', navigationMaxHeight - 15);\n    }\n\n    function toggleMenuAction(element) {\n        $('.megamenu-item').removeClass(\"active\");\n        element.addClass(\"active\");\n        $('.megamenu-item').find('.megamenu-item-link').first().attr('aria-expanded', 'false');\n        element.find('.megamenu-item-link').first().attr(\"aria-expanded\", \"true\");\n\n        if (element.hasClass('has-content')) {\n            $('.magemenu-menu li.megamenu-item.close-button').addClass('active');\n        }\n        if (!$('.preheader-wrapper').length > 0 && $('.nav-sections').hasClass('opaque-nav-sections')) {\n            let pageHeaderHeight = $('.page-header').height();\n            let navBarHeight = $('.nav-sections').height();\n            $('.magemenu-menu li.megamenu-item .megamenu-dropdown').css('top', (pageHeaderHeight + navBarHeight).toString() + 'px');\n        }\n        if ($('.preheader-wrapper').hasClass('initialized') && isPreheaderReady()) {\n            $(\"#preheader-wrapper\").preheader(\"adjustToPreheader\");\n        }\n    }\n\n    function closeAction() {\n        let header = $(window).scrollTop();\n        $('.megamenu-item').find('.megamenu-item-link').attr('aria-expanded', 'false');\n        $('.page-main, #marquage-goyard, .page-footer').removeAttr(\"style\");\n        $('.page-main').removeClass('blur-page');\n        if ($('.magemenu-menu li.megamenu-item.close-button').hasClass('active')) {\n            $('.magemenu-menu li.megamenu-item.close-button').removeClass('active');\n            $('.nav-sections').removeAttr(\"style\");\n            $('.magemenu-menu li.megamenu-item .megamenu-dropdown').removeAttr(\"style\");\n            $('.nav-sections').removeClass(\"opaque-nav-sections\");\n            $('.magemenu-menu').find('li.megamenu-item').removeClass(\"active\");\n            if (header === 0) {\n                let windowsize = $(window).width();\n                if (windowsize > 768) {\n                    $('.page-header').addClass(\"anim-top\");\n                    $('.nav-sections').addClass(\"anim-top\");\n                    $('.page-header').removeAttr(\"style\");\n                    if ($('.preheader-wrapper').hasClass('initialized') && isPreheaderReady()) {\n                        $(\"#preheader-wrapper\").preheader(\"adjustToPreheader\");\n                    }\n                }\n                $('.nav-sections').removeClass(\"opaque-nav-sections\");\n                $('.page-header').removeClass(\"opaque-header\");\n                $('.page-header').removeClass(\"anim-top\");\n                $('.nav-sections').removeClass(\"anim-top\");\n            } else {\n                let windowsize = $(window).width();\n                if (windowsize > 768) {\n                    !$('.page-header').hasClass('opaque-header') ?? $('.page-header').addClass('opaque-header');\n                }\n            }\n        }\n\n        // Remove style\n        $('.megamenu-dropdown > .block-main > .megamenu-sub-items').removeAttr('style');\n        $('.megamenu-item').children('.megamenu-dropdown').removeAttr('style');\n        $('.block-right').removeAttr('style');\n    }
2\n\n    function setBlurStyleOnMenuClick() {\n        $('.page-main, #marquage-goyard, .page-footer').attr(\"style\", \"filter: blur(5px) !important\");\n    }\n\n    function handleSubMenuClick(element) {\n        $('.magemenu-menu li.megamenu-sub-item').not($(element).parent()).removeClass('active');\n        $(element).parent().toggleClass(\"active\");\n        let currentExpandedStatus = element.attr(\"aria-expanded\") === \"true\";\n        $('.megamenu-item').find('.megamenu-sub-item.has-child').find('.megamenu-item-link').attr('aria-expanded', 'false');\n        element.attr(\"aria-expanded\", !currentExpandedStatus);\n    }\n\n    function handleMegamenuHover() {\n        $(this).find('.tab-menu-content').css({ \"z-index\": \"6\", \"position\": \"absolute\" });\n    }\n\n    function handleMegamenuHoverOut() {\n        $(this).find('.tab-menu-content').removeAttr('style');\n    }\n\n    function registerEventHandlers() {\n        $('.magemenu-menu li.megamenu-item').on(\"click keydown\", function (e) {\n            if (e.type === \"click\" || (e.type === \"keydown\" && (e.key === 'Enter' || e.key === ' '))) {\n                e.preventDefault();\n                toggleMenuAction($(this));\n            }\n        });\n\n        $('.magemenu-menu li.megamenu-item.close-button').on(\"keydown click\", function (e) {\n            if (e.type === \"click\" || (e.type === \"keydown\" && (e.key === 'Enter' || e.key === ' '))) {\n                e.preventDefault();\n                closeAction();\n            }\n        });\n        $('body').on('click', function (event) {\n            var container = $('.nav-sections');\n            if ((!container.is(event.target) && !container.has(event.target).length)) {\n                closeAction();\n            }\n        });\n        $(document).on('keyup', function (e) {\n            //ESCAPE KEY\n            if (e.which === 27) {\n                closeAction();\n                $('body').removeClass('_keyfocus');\n            }\n        });\n        //D\u00e9clenchement sur les liens des sous-sous-menus\n        $('.megamenu-item-link').on({\n            focus: function () {\n                if ($('body').hasClass('_keyfocus') && $(this).parent().hasClass('has-child')) {\n                    let $customDiv = $('<div class=\"access-focus-menu-item\"></div>');\n                    $(this).append($customDiv);\n                }\n            },\n            blur: function () {\n                $(this).find('.access-focus-menu-item').remove();\n            },\n            keydown: function (e) {\n                if (e.key === ' ') {\n                    e.preventDefault();\n                    if ($(e.target).is('[href]') && $(e.target).attr('href') !== '#') {\n                        window.location.href = $(e.target).attr('href');\n                    }\n                } else if (e.key === 'Enter') {\n                    if ($(e.target).is('[href]') && $(e.target).attr('href') !== '#') {\n                        window.location.href = $(e.target).attr('href');\n                    }\n                }\n            },\n            click: function (e) {\n\n                if ($(e.target).is('[href]') && $(e.target).attr('href') !== '#') {\n                    $('.megamenu-item').find('.megamenu-sub-item.has-child').find('.megamenu-item-link').attr('aria-expanded', 'false');\n                    window.location.href = $(e.target).attr('href');\n                }\n            }\n        });\n        // D\u00e9clenchement sur la span des sous-sous-menus\n        $('.megamenu-item-inner').on({\n            click: function () {\n                if ($(this).parent().is('[href]') && $(this).parent().attr('href') !== '#') {\n                    window.location.href = $(this).parent().attr('href');\n                }\n            }\n        })\n\n        $('.magemenu-menu li.megamenu-item.has-content').on(\"keydown click\", function (e) {\n            if (e.type === \"click\" || (e.type === \"keydown\" && (e.key === 'Enter' || e.key === ' '))) {\n                e.preventDefault();\n                setBlurStyleOnMenuClick();\n            }\n        });\n\n        $('.magemenu-menu li.megamenu-sub-item > a').on(\"keydown click\", function (e) {\n            if (e.type === \"click\" || (e.type === \"keydown\" && (e.key === 'Enter' || e.key === ' '))) {\n                e.preventDefault();\n\n                handleSubMenuClick($(this));\n            }\n        });\n        $(\".magemenu-menu.horizontal-menu .megamenu-items > li .megamenu-sub-items li .megamenu-sub-items .megamenu-sub-item\").hover(\n            handleMegamenuHover,\n            handleMegamenuHoverOut\n        );\n    }\n\n    mediaCheck({\n        media: '(min-width: 768px)',\n        entry: function () {\n            $('.magemenu-menu li.megamenu-item').click(adjustBlockRightPosition);\n            registerEventHandlers();\n        },\n        exit: function () {\n            $('.magemenu-menu li.megamenu-item').click(function () {\n                $('.sections.nav-sections').scrollTop(0);\n            });\n        }\n    });\n\n    mediaCheck({\n        media: '(max-width: 768px)',\n        entry: function () {\n            $(document).on('keydown', function (event) {\n                if (event.key === 'Escape') {\n                    closeMenu();\n                }\n            });\n            // Menu and SubMenu collapse toggles\n            $('.magemenu-menu li.megamenu-item.has-content > .menu-collapse, .magemenu-menu li.megamenu-item.has-content .megamenu-dropdown li.megamenu-sub-item.has-child .menu-collapse').on(\"click keydown\", function (e) {\n                if (e.type === \"click\" || (e.type === \"keydown\" && (e.key === 'Enter' || e.key === ' '))) {\n                    e.preventDefault();\n                    let $link = $(this).parent().find('.megamenu-item-link').first();\n                    $link.attr('aria-expanded', $link.attr(\"aria-expanded\") !== \"true\");\n                }\n            });\n        }\n    });\n});\n","js/sticky-header.js":"/**\n * Copyright Goyard\n */\ndefine([\n    \"jquery\",\n    \"preheader\"\n], function ($) {\n    \"use strict\";\n    let scrollPosition = 0;
2\n\n    function isPreheaderReady() {\n        return Boolean($('#preheader-wrapper').data('mage-preheader'));\n    }\n    $(window).scroll(function () {\n\n        if ($(\".nav-sections\").length > 0) {\n            var top_of_nav = $(\".nav-sections\").offset().top;\n            var bottom_of_nav = $(\".nav-sections\").offset().top + $(\".nav-sections\").outerHeight();\n            var bottom_of_screen = $(window).scrollTop() + $(window).innerHeight();\n            var top_of_screen = $(window).scrollTop() + $(\".page-header\").innerHeight();\n\n            if ((bottom_of_screen > top_of_nav) && (top_of_screen < bottom_of_nav) && (!$('.searchBar-root_open-hxZ').is(':visible'))) {\n                var windowsize = $(window).width();\n                if (windowsize > 768) {\n                    $('.page-header').addClass(\"full-header\");\n                    if (!$('.modal-inner-wrap').hasClass('scroll-up')) {\n                        $('.modal-inner-wrap').addClass('mini-scroll');\n                    };\n                }\n            } else {\n                $('.page-header').addClass(\"opaque-header\");\n                $('.modal-inner-wrap').addClass('scroll-down');\n                $('.modal-inner-wrap').removeClass('mini-scroll');\n                $('.page-header').removeClass(\"full-header\");\n                // the element is not visible, do something else\n            }\n        }\n        $(window).on('scroll', function () {\n            let header = $(window).scrollTop();\n            if (!$('.magemenu-menu li.megamenu-item').hasClass('active')) {\n                if (header === 0 && (!$('.searchBar-root_open-hxZ').is(':visible'))) {\n                    //'header = 0 et search pas visible'\n                    var windowsize = $(window).width();\n                    $('.nav-sections').removeClass(\"opaque-nav-sections\");\n                    $('.page-header').removeClass(\"opaque-header\");\n                    $('.modal-inner-wrap').removeClass('scroll-down');\n                    $('.page-header').removeAttr(\"style\", \"position: fixed !important\");\n                    // pre-header\n                    if ($(window).width() > 768) {\n                        if ($('.preheader-wrapper').length > 0) {\n                            if (!$('.preheader-wrapper').hasClass('initialized')) {\n                                $('.preheader-wrapper').addClass('initialized');\n                                $('.preheader-wrapper').css('display', 'block');\n                            };\n                            if (isPreheaderReady()) {\n                                $(\"#preheader-wrapper\").preheader(\"adjustToPreheader\");\n                            }\n                        }\n                    }\n                    if ($(window).width() < 768) {\n                        if (!$(\"html\").hasClass(\"nav-before-open nav-open\")) {\n                            if ($('.preheader-wrapper').length > 0) {\n                                if (!$('.preheader-wrapper').hasClass('initialized')) {\n                                    $('.preheader-wrapper').addClass('initialized');\n                                    $('.preheader-wrapper').css('display', 'block');\n                                };\n                                if (isPreheaderReady()) {\n                                    $(\"#preheader-wrapper\").preheader(\"adjustToPreheader\");\n                                }\n                            }\n                        }\n                    }\n                    scrollPosition = header;\n\n                    if (windowsize > 768) {\n                        $('.page-header').addClass('anim-back');\n                        $('.nav-sections').addClass('anim-back-nav');\n                    }\n                } else {\n                    if ($(window).width() > 768) {\n                        if ($(window).scrollTop() > 0 && $(window).scrollTop() <= 100 && scrollPosition > header) {\n                            //entre 0 et 100 avec scroll up\n                            $('.page-header').removeAttr(\"style\");\n                            $('.page-header').addClass(\"opaque-header\");\n                        } else if ($(window).scrollTop() > 0 && $(window).scrollTop() <= 100) {\n                            //entre 0 et 100 sans scroll up\n                            scrollPosition = header;\n                        } else {\n                            //entre 0 et 100 avec scroll down\n                            scrollPosition = header;\n                            $('.page-header').removeAttr(\"style\");\n                        }\n                    }\n                    $('.page-header').removeClass(\"anim-back\");\n                    $('.nav-sections').removeClass(\"anim-back-nav\");\n                    if ($('.preheader-wrapper').hasClass('initialized') && isPreheaderReady()) {\n                        $(\"#preheader-wrapper\").preheader(\"unShowPreHeader\");\n                    }\n                }\n            }\n            else {\n                if (header >= 0 && header <= 100) {\n                    //header entre 0 et 100 et Menu OUVERT\n                    $('.nav-sections').attr(\"style\", \"position: fixed !important\");\n                    $('.page-header').attr(\"style\", \"position: fixed !important\");\n                    if ($('.preheader-wrapper').length > 0 && $(window).width() > 768) {\n                        if (!$('.preheader-wrapper').hasClass('initialized')) {\n                            $('.preheader-wrapper').addClass('initialized');\n                            $('.preheader-wrapper').css('display', 'block');\n                        };\n                        if (isPreheaderReady()) {\n                            $(\"#preheader-wrapper\").preheader(\"adjustToPreheader\");\n                        }\n                    }\n                } else {\n                    //header en dessous de 100 et Menu OUVERT\n                    $('.nav-sections').attr(\"style\", \"position: fixed !important\");\n                    $('.page-header').attr(\"style\", \"position: fixed !important\");\n                    if ($('.preheader-wrapper').length > 0 && $(window).width() > 768 && isPreheaderReady()) {\n                        if ($('.preheader-wrapper').hasClass('initialized')) {\n                            $(\"#preheader-wrapper\").preheader(\"unShowPreHeader\");\n                        }\n                        $(\"#preheader-wrapper\").preheader(\"adjustToPreheader\");\n                    }\n                }\n            }\n        });\n        $(function () {\n            var lastScrollTop = 0, delta = 5;\n            $(window).scroll(function () {\n                let header = $(window).scrollTop();\n                var nowScrollTop = $(this).scrollTop();\n                if (!$('.magemenu-menu li.megamenu-item').hasClass('active') && !$('.block-minicart').hasClass('active')) {\n                    if (Math.abs(lastScrollTop - nowScrollTop) >= delta && $(window).scrollTop() !== 0) {\n                        if (nowScrollTop > lastScrollTop && lastScrollTop !== 0) {\n                            // Scrolling down\n                            $('.nav-sections').removeClass('opaque-nav-sections');\n                            $('.modal-inner-wrap').removeClass('scroll-up');\n                        } else if (nowScrollTop < lastScrollTop && lastScrollTop !== 0 && header > 60) {\n                            // Scrolling up\n                            $('.nav-sections').addClass('opaque-nav-sections');\n                            $('.modal-inner-wrap').addClass('scroll-up');\n                            $('.modal-inner-wrap').removeClass('scroll-down');\n                        }\n                        lastScrollTop = nowScrollTop;\n                    }\n                }\n            });\n        });\n    });\n    $(document).on('mouseenter', 'header.page-header.opaque-header', function () {\n        var windowsize = $(window).width();\n        if (windowsize > 768) {\n            $('.sections.nav-sections').addClass('opaque-nav-sections');\n        }\n    });\n});\n","js/navigation-menu.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/**\n * @deprecated\n * @see lib/web/mage/menu.js\n */\ndefine([\n    'jquery',\n    'matchMedia',\n    'mage/template',\n    'mage/dropdowns',\n    'mage/terms'\n], function ($, mediaCheck, mageTemplate) {\n    'use strict';\n\n    $.widget('mage.navigationMenu', {\n        options: {\n            itemsContainer: '> ul',\n            topLevel: 'li.level0',\n            topLevelSubmenu: '> .submenu',\n            topLevelHoverClass: 'hover',\n            expandedTo
2pLevel: '.more',\n            hoverInTimeout: 300,\n            hoverOutTimeout: 500,\n            submenuAnimationSpeed: 200,\n            collapsable: true,\n            collapsableDropdownTemplate:\n                '<script type=\"text/x-magento-template\">' +\n                    '<li class=\"level0 level-top more parent\">' +\n                        '<div class=\"submenu\">' +\n                            '<ul><%= elems %></ul>' +\n                        '</div>' +\n                    '</li>' +\n                '</script>'\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            this.itemsContainer = $(this.options.itemsContainer, this.element);\n            this.topLevel = $(this.options.topLevel, this.element);\n            this.topLevelSubmenu = $(this.options.topLevelSubmenu, this.topLevel);\n\n            this._bind();\n        },\n\n        /**\n         * @private\n         */\n        _init: function () {\n            if (this.options.collapsable) {\n                setTimeout($.proxy(function () {\n                    this._checkToCollapseOrExpand();\n                }, this), 100);\n            }\n        },\n\n        /**\n         * @private\n         */\n        _bind: function () {\n            this._on({\n                /**\n                 * @param {jQuery.Event} e\n                 */\n                'mouseenter > ul > li.level0': function (e) {\n                    if (!this.entered) { // fix IE bug with 'mouseenter' event\n                        this.timeoutId && clearTimeout(this.timeoutId);\n                        this.timeoutId = setTimeout($.proxy(function () {\n                            this._openSubmenu(e);\n                        }, this), this.options.hoverInTimeout);\n                        this.entered = true;\n                    }\n                },\n\n                /**\n                 * @param {jQuery.Event} e\n                 */\n                'mouseleave > ul > li.level0': function (e) {\n                    this.entered = null;\n\n                    this.timeoutId && clearTimeout(this.timeoutId);\n                    this.timeoutId = setTimeout($.proxy(function () {\n                        this._closeSubmenu(e.currentTarget);\n                    }, this), this.options.hoverOutTimeout);\n                },\n\n                /**\n                 * @param {jQuert.Event} e\n                 */\n                'click': function (e) {\n                    e.stopPropagation();\n                }\n            });\n\n            $(document)\n                .on('click.hideMenu', $.proxy(function () {\n                    var isOpened = this.topLevel.filter(function () {\n                        return $(this).data('opened');\n                    });\n\n                    if (isOpened) {\n                        this._closeSubmenu(null, false);\n                    }\n                }, this));\n\n            $(window)\n                .on('resize', $.proxy(function () {\n                    this.timeoutOnResize && clearTimeout(this.timeoutOnResize);\n                    this.timeoutOnResize = setTimeout($.proxy(function () {\n                        if (this.options.collapsable) {\n                            if ($(this.options.expandedTopLevel, this.element).length) {\n                                this._expandMenu();\n                            }\n                            this._checkToCollapseOrExpand();\n                        }\n                    }, this), 300);\n                }, this));\n        },\n\n        /**\n         * @param {jQuery.Event} e\n         * @private\n         */\n        _openSubmenu: function (e) {\n            var menuItem = e.currentTarget;\n\n            if (!$(menuItem).data('opened')) {\n                this._closeSubmenu(menuItem, true, true);\n\n                $(this.options.topLevelSubmenu, menuItem)\n                    .slideDown(this.options.submenuAnimationSpeed, $.proxy(function () {\n                        $(menuItem).addClass(this.options.topLevelHoverClass);\n                        $(menuItem).data('opened', true);\n                    }, this));\n            } else if ($(e.target).closest(this.options.topLevel)) {\n                $(e.target)\n                    .addClass(this.options.topLevelHoverClass)\n                    .siblings(this.options.topLevel)\n                        .removeClass(this.options.topLevelHoverClass);\n            }\n        },\n\n        /**\n         * @param {*} menuItem\n         * @param {*} excludeCurrent\n         * @param {*} fast\n         * @private\n         */\n        _closeSubmenu: function (menuItem, excludeCurrent, fast) {\n            var topLevel = $(this.options.topLevel, this.element),\n                activeSubmenu = $(this.options.topLevelSubmenu, menuItem || null);\n\n            $(this.options.topLevelSubmenu, topLevel)\n                .filter(function () {\n                    return excludeCurrent ? $(this).not(activeSubmenu) : true;\n                })\n                .slideUp(fast ? 0 : this.options.submenuAnimationSpeed);\n\n            topLevel\n                .removeClass(this.options.topLevelHoverClass)\n                .data('opened', false);\n        },\n\n        /**\n         * @private\n         */\n        _checkToCollapseOrExpand: function () {\n            var navWidth, totalWidth, startCollapseIndex;\n\n            if ($('html').hasClass('lt-640') || $('html').hasClass('w-640')) {\
2n                return;\n            }\n\n            navWidth = this.itemsContainer.width();\n            totalWidth = 0;\n            startCollapseIndex = 0;\n\n            $.each($(this.options.topLevel, this.element), function (index, item) {\n                totalWidth += $(item).outerWidth(true);\n\n                if (totalWidth > navWidth && !startCollapseIndex) {\n                    startCollapseIndex = index - 2;\n                }\n            });\n\n            this[startCollapseIndex ? '_collapseMenu' : '_expandMenu'](startCollapseIndex);\n        },\n\n        /**\n         * @param {*} startCollapseIndex\n         * @private\n         */\n        _collapseMenu: function (startCollapseIndex) {\n            this.elemsToCollapse = this.topLevel.filter(function (index) {\n                return index > startCollapseIndex;\n            });\n            this.elemsToCollapseClone = $('<div></div>').append(this.elemsToCollapse.clone()).html();\n\n            this.collapsableDropdown = $(\n                mageTemplate(\n                    this.options.collapsableDropdownTemplate,\n                    {\n                        elems: this.elemsToCollapseClone\n                    }\n                )\n            );\n\n            this.itemsContainer.append(this.collapsableDropdown);\n            this.elemsToCollapse.detach();\n        },\n\n        /**\n         * @private\n         */\n        _expandMenu: function () {\n            this.elemsToCollapse && this.elemsToCollapse.appendTo(this.itemsContainer);\n            this.collapsableDropdown && this.collapsableDropdown.remove();\n        },\n\n        /**\n         * @private\n         */\n        _destroy: function () {\n            this._expandMenu();\n        }\n    });\n\n    /*\n     * Provides \"Continium\" effect for submenu\n     * */\n    $.widget('mage.navigationMenu', $.mage.navigationMenu, {\n        options: {\n            parentLevel: '> ul > li.level0',\n            submenuAnimationSpeed: 150,\n            submenuContiniumEffect: false\n        },\n\n        /**\n         * @private\n         */\n        _init: function () {\n            this._super();\n            this._applySubmenuStyles();\n        },\n\n        /**\n         * @private\n         */\n        _applySubmenuStyles: function () {\n            $(this.options.topLevelSubmenu, $(this.options.topLevel, this.element))\n                .removeAttr('style');\n\n            $(this.options.topLevelSubmenu, $(this.options.parentLevel, this.element))\n                .css({\n                    display: 'block',\n                    height: 0,\n                    overflow: 'hidden'\n                });\n        },\n\n        /**\n         * @param {jQuery.Event} e\n         * @private\n         */\n        _openSubmenu: function (e) {\n            var menuItem = e.currentTarget,\n                submenu = $(this.options.topLevelSubmenu, menuItem),\n                openedItems = $(this.options.topLevel, this.element).filter(function () {\n                    return $(this).data('opened');\n                });\n\n            if (submenu.length) {\n                this.heightToAnimate = $(this.options.itemsContainer, submenu).outerHeight(true);\n\n                if (openedItems.length) {\n                    this._closeSubmenu(menuItem, true, this.heightToAnimate, $.proxy(function () {\n                        submenu.css({\n                            height: 'auto'\n                        });\n                        $(menuItem)\n                            .addClass(this.options.topLevelHoverClass);\n                    }, this), e);\n                } else {\n                    submenu.animate({\n                        height: this.heightToAnimate\n                    }, this.options.submenuAnimationSpeed, $.proxy(function () {\n                        $(menuItem)\n                            .addClass(this.options.topLevelHoverClass);\n                    }, this));\n                }\n\n                $(menuItem)\n                    .data('opened', true);\n            } else {\n                this._closeSubmenu(menuItem);\n            }\n        },\n\n        /**\n         * @param {*} menuItem\n         * @param {*} excludeCurrent\n         * @param {*} heightToAnimate\n         * @param {Function} callback\n         * @private\n         */\n        _closeSubmenu: function (menuItem, excludeCurrent, heightToAnimate, callback) {\n            var topLevel = $(this.options.topLevel, this.itemsContainer),\n                prevOpenedItem, prevOpenedSubmenu;\n\n            if (!excludeCurrent) {\n                $(this.options.topLevelSubmenu, $(this.options.parentLevel, this.element))\n                    .animate({\n                        height: 0\n                    });\n\n                topLevel\n                    .data('opened', false)\n                    .removeClass(this.options.topLevelHoverClass);\n            } else {\n                prevOpenedItem = topLevel.filter(function () {\n                    return $(this).data('opened');\n                });\n                prevOpenedSubmenu = $(this.options.topLevelSubmenu, prevOpenedItem);\n\n                prevOpenedSubmenu.animate({\n                    height: heightToAnimate\n                }, this.options.submenuAnimationSpeed, 'linear', function () {\n                    $(this).css({\n                        height: 0\n                    });\n                    callback && callback();\n                });\n\n                prevOpenedItem\n                    .data('opened', false)\n                    .removeClass(this.options.topLevelHoverClass);\n            }\n        },\n\n        /**\n         * @private\n         */\n        _collapseMenu: function () {\n            this._superApply(arguments);\n            this._applySubmenuStyles();\n        }\n    });\n\n    //  Responsive menu\n    $.widget('mage.navigationMenu', $.mage.navigationMenu, {\n        options: {\n            responsive: false,\n            origNavPlaceholder: '.page-header',\n            mainContainer: 'body',\n            pageWrapper: '.page-wrapper',\n            openedMenuClass: 'o
2pened',\n            toggleActionPlaceholder: '.block-search',\n            itemWithSubmenu: 'li.parent',\n            titleWithSubmenu: 'li.parent > a',\n            submenu: 'li.parent > .submenu',\n            toggleActionTemplate:\n                '<script type=\"text/x-magento-template\">' +\n                    '<span data-action=\"toggle-nav\" class=\"action toggle nav\">Toggle Nav</span>' +\n                '</script>',\n            submenuActionsTemplate:\n                '<script type=\"text/x-magento-template\">' +\n                    '<li class=\"action all\">' +\n                        '<a href=\"<%= categoryURL %>\"><span>All <%= category %></span></a>' +\n                    '</li>' +\n                '</script>',\n            navigationSectionsWrapperTemplate:\n                '<script type=\"text/x-magento-template\">' +\n                    '<dl class=\"navigation-tabs\" data-sections=\"tabs\">' +\n                    '</dl>' +\n                '</script>',\n            navigationItemWrapperTemplate:\n                '<script type=\"text/x-magento-template\">' +\n                    '<dt class=\"item title <% if (active) { %>active<% } %>\" data-section=\"title\">' +\n                        '<a class=\"switch\" data-toggle=\"switch\" href=\"#TODO\"><%= title %></a>' +\n                    '</dt>' +\n                    '<dd class=\"item content <% if (active) { %>active<%}%>\" data-section=\"content\">' +\n                    '</dd>' +\n                '</script>'\n        },\n\n        /**\n         * @private\n         */\n        _init: function () {\n            this._super();\n\n            this.mainContainer = $(this.options.mainContainer);\n            this.pageWrapper = $(this.options.pageWrapper);\n            this.toggleAction = $(mageTemplate(this.options.toggleActionTemplate, {}));\n\n            if (this.options.responsive) {\n                mediaCheck({\n                    media: '(min-width: 768px)',\n                    entry: $.proxy(function () {\n                        this._toggleDesktopMode();\n                    }, this),\n                    exit: $.proxy(function () {\n                        this._toggleMobileMode();\n                    }, this)\n                });\n            }\n        },\n\n        /**\n         * @private\n         */\n        _bind: function () {\n            this._super();\n            this._bindDocumentEvents();\n        },\n\n        /**\n         * @private\n         */\n        _bindDocumentEvents: function () {\n            if (!this.eventsBound) {\n                $(document)\n                    .on('click.toggleMenu', '.action.toggle.nav', $.proxy(function (e) {\n                        if ($(this.element).data('opened')) {\n                            this._hideMenu();\n                        } else {\n                            this._showMenu();\n                        }\n                        e.stopPropagation();\n                        this.mobileNav.scrollTop(0);\n                        this._fixedBackLink();\n                    }, this))\n                    .on('click.hideMenu', this.options.pageWrapper, $.proxy(function () {\n                        if ($(this.element).data('opened')) {\n                            this._hideMenu();\n                            this.mobileNav.scrollTop(0);\n                            this._fixedBackLink();\n                        }\n                    }, this))\n                    .on('click.showSubmenu', this.options.titleWithSubmenu, $.proxy(function (e) {\n                        this._showSubmenu(e);\n\n                        e.preventDefault();\n                        this.mobileNav.scrollTop(0);\n                        this._fixedBackLink();\n                    }, this))\n                    .on('click.hideSubmenu', '.action.back', $.proxy(function (e) {\n                        this._hideSubmenu(e);\n                        this.mobileNav.scrollTop(0);\n                        this._fixedBackLink();\n                    }, this));\n\n                this.eventsBound = true;\n            }\n        },\n\n        /**\n         * @private\n         */\n        _showMenu: function () {\n            $(this.element).data('opened', true);\n            this.mainContainer.add('html').addClass(this.options.openedMenuClass);\n        },\n\n        /**\n         * @private\n         */\n        _hideMenu: function () {\n            $(this.element).data('opened', false);\n            this.mainContainer.add('html').removeClass(this.options.openedMenuClass);\n        },\n\n        /**\n         * @param {jQuery.Event} e\n         * @private\n         */\n        _showSubmenu: function (e) {\n            var submenu;\n\n            $(e.currentTarget).addClass('action back');\n            submenu = $(e.currentTarget).siblings('.submenu');\n\n            submenu.addClass('opened');\n        },\n\n        /**\n         * @param {jQuery.Event} e\n         * @private\n         */\n        _hideSubmenu: function (e) {\n            var submenuSelector = '.submenu',\n                submenu = $(e.currentTarget).next(submenuSelector);\n\n            $(e.currentTarget).removeClass('action back');\n            submenu.removeClass('opened');\n        },\n\n        /**\n         * @private\n         */\n        _renderSubmenuActions: function () {\n            $.each(\n                $(this.options.itemWithSubmenu),\n                $.proxy(function (index, item) {\n                    var actions = $(mageTemplate(\n                            this.options.submenuActionsTemplate,\n                            {\n                                category: $('> a > span', item).text(),\n                                categoryURL: $('> a', item).attr('href')\n                            }\n                        )),\n                        submenu = $('> .submenu', item),\n                        items = $('> ul', submenu);\n\n                    items.prepend(actions);\n                }, this)\n            );\n        },\n\n        /**\n         * @private\n         */\n        _toggleMobileMode: function () {\n            this._expandMenu();\n\n            $(this.options.topLevelSubmenu, $(this.options.topLevel, this.element))\n                .removeAttr('style');\n\n            this.toggleAction.insertBefore(this.options.toggleActionPlaceholder);\n            this.mobileNav = $(this.element).detach().clone();\n            this.mainContainer.prepend(this.mobileNav);\n            this.mobileNav.find('> ul').addClass('nav');\n            this._insertExtraItems();\n            this._wrapItemsInSections();\n            this.mobileNav.scroll($.proxy(function () {\n                this._fixedBackLink();\n            }, this));\n\n            this._renderSubmenuActions();\n            this._bindDocumentEvents();\n        },\n\n        /**\n         * @private\n         */\n        _toggleDesktopMode: function () {\n            this.mobileNav && this.mobileNav.remove();\n            this.toggleAction.detach();\n            $(this.element).insertAfter(this.options.origNavPlaceholder);\n\n            $(document)\n                .off('click.toggleMenu', '.action.toggle.nav')\n                .off('click.hideMenu', this.options.pageWrapper)\n                .off('click.showSubmenu', this.options.titleWithSubmenu)\n                .off('click.hideSubmenu', '.action.back');\n\n            this.eventsBound = false;\n\n            this._applySubmenuStyles();\n        },\n\n        /**\n         * @private\n         */\n        _insertExtraItems: function () {\n            var settings, footerSettings, account;\n\n            if ($('.header.panel .switcher').length) {\n                settings = $('.header.panel .switcher')\n                    .clone()\n                    .addClass('settings');\n\n                this.mobileNav.prepend(settings);\n            }\n\n            if ($('.footer .switcher').length) {\n                footerSettings = $('.footer .switcher')\n                    .clone()\n                    .addClass('settings');\n\n                this.mobileNav.prepend(footerSettings);\n            }\n\n            if ($('.header.panel .header.links li').length) {\n                account = $('.header.panel > .header.links')\n                    .clone()\n                    .addClass('account');\n\n                this.mobileNav.prepend(account);\n            }\n        },\n\n        /**\n         * @private\n         */\n        _wrapItemsInSections: function () {\n            var account = $('> .account', this.mobileNav),\n                settings = $('> .settings', this.mobileNav),\n                nav = $('> .nav', this.mobileNav),\n                navigationSectionsWrapper = $(mageTemplate(this.options.navigationSectionsWrapperTemplate, {})),\n                navigationItemWrapper;\n\n            this.mobileNav.append(navigationSectionsWrapper);\n\n            if (nav.length) {\n                navigationItemWrapper = $(mageTemplate(this.options.navigationItemWrapperTemplate, {\n                    title: 'Menu'\n                }));\n                navigationSectionsWrapper.append(navigationItemWrapper);\n                navigationItemWrapper.eq(1).append(nav);\n            }\n\n            if (account.length) {\n                navigationItemWrapper = $(mageTemplate(this.options.navigationItemWrapperTemplate, {\n                    title: 'Account'\n                }));\n                navigationSectionsWrapper.append(navigationItemWrapper);\n                navigationItemWrapper.eq(1).append(account);\n            }\n\n            if (settings.length) {\n                navigationItemWrapper = $(\n                    mageTemplate(this.options.navigationItemWrapperTemplate, {\n                        title: 'Settings'\n                    })\n                );\n                navigationSectionsWrapper.append(navigationItemWrapper);\n                navigationItemWrapper.eq(1).append(settings);\n            }\n\n            navigationSectionsWrapper.addClass(\n                'navigation-tabs-' + navigationSectionsWrapper.find('[data-section=\"title\"]').length\n            );\n            navigationSectionsWrapper.terms();\n        },\n\n        /**\n         * @private\n         */\n        _fixedBackLink: function () {\n            var linksBack = this.mobileNav.find('.submenu .action.back'),\n                linkBack = this.mobileNav.find('.submenu.opened > ul >
2 .action.back').last(),\n                subMenu, navOffset, linkBackHeight;\n\n            linksBack.removeClass('fixed');\n\n            if (linkBack.length) {\n                subMenu = linkBack.parent();\n                navOffset = this.mobileNav.find('.nav').position().top;\n                linkBackHeight = linkBack.height();\n\n                if (navOffset <= 0) {\n                    linkBack.addClass('fixed');\n                    subMenu.css({\n                        paddingTop: linkBackHeight\n                    });\n                } else {\n                    linkBack.removeClass('fixed');\n                    subMenu.css({\n                        paddingTop: 0\n                    });\n                }\n            }\n        }\n    });\n\n    return $.mage.navigationMenu;\n});\n","js/accessibility-mode.js":"/**\n* Copyright Goyard\n*/\ndefine([\n    \"jquery\",\n    \"mage/cookies\",\n    'mage/translate'\n], function ($) {\n    \"use strict\";\n\n    const CLASS_ACCESSIBILITY_CONTRAST = 'accessibility_mode_constrast';\n    const CLASS_ACCESSIBILITY_ANIMATION = 'accessibility_mode_animation';\n    const EVENT_REDUCED_ANIMATION = new CustomEvent(\"reductAnimation\", { detail: { animation: true } });\n\n    function init() {\n        const isContrastMode = $.mage.cookies.get('accessibility_mode_constrast') === \"true\";\n        const isAnimationMode = $.mage.cookies.get('accessibility_mode_animation') === \"true\";\n\n        setContrastMode(isContrastMode);\n        setAnimationMode(isAnimationMode);\n\n        $('#upgradeConstrast').click(function () {\n            toggleContrastMode();\n        });\n\n        $('#reductAnimation').click(function () {\n            toggleAnimationMode();\n        });\n    }\n\n    function setContrastMode(enabled) {\n        $('body').toggleClass(CLASS_ACCESSIBILITY_CONTRAST, enabled);\n        if (document.getElementById('upgradeConstrast')) {\n            document.getElementById('upgradeConstrast').checked = enabled;\n        }\n    }\n\n    function setAnimationMode(enabled) {\n        $('body').toggleClass(CLASS_ACCESSIBILITY_ANIMATION, enabled);\n        if (document.getElementById('reductAnimation')) {\n            document.getElementById('reductAnimation').checked = enabled;\n            document.dispatchEvent(enabled ? EVENT_REDUCED_ANIMATION : new CustomEvent(\"reductAnimation\", { detail: { animation: false } }));\n        }\n    }\n\n\n    function toggleContrastMode() {\n        setContrastMode(!$('body').hasClass(CLASS_ACCESSIBILITY_CONTRAST));\n        $.mage.cookies.set('accessibility_mode_constrast', $('body').hasClass(CLASS_ACCESSIBILITY_CONTRAST), 24);\n    }\n\n    function toggleAnimationMode() {\n        setAnimationMode(!$('body').hasClass(CLASS_ACCESSIBILITY_ANIMATION));\n        $.mage.cookies.set('accessibility_mode_animation', $('body').hasClass(CLASS_ACCESSIBILITY_ANIMATION), 24);\n    }\n\n    $(document).ready(init);\n});","js/breadcrumb-navigation.js":"/**\n * Copyright Goyard Orkester\n *\n * Dynamic breadcrumb override based on navigation context.\n *\n * On category pages  : persists the current breadcrumb path + page URL into\n *                      sessionStorage on every page load (no click dependency).\n * On product pages   : reads sessionStorage and verifies via document.referrer\n *                      that the user actually came from the stored category before\n *                      replacing the server-rendered breadcrumb.\n *\n * The server-rendered canonical breadcrumb is never altered server-side,\n * so crawlers and direct URL access always see the canonical path (SEO safe).\n */\ndefine(['jquery'], function ($) {\n    'use strict';\n\n    var STORAGE_KEY = 'goyard_nav_breadcrumb';\n\n    /**\n     * Reads all breadcrumb items from the current category page DOM.\n     * The last item has no <a> tag (it is the current page), so we assign\n     * window.location.href as its URL so it becomes a link on the product page.\n     *\n     * @returns {Array<{label: string, url: string, cssClass: string}>}\n     */\n    function readCategoryBreadcrumbs() {\n        var crumbs = [];\n\n        $('.breadcrumbs .items .item').each(function () {\n            var $item  = $(this);\n            var $link  = $item.find('a');\n            var label, url;\n\n            if ($link.length) {\n                label = $.trim($link.text());\n                url   = $link.attr('href');\n            } else {\n                var $strong = $item.find('strong');\n                label = $.trim($strong.length ? $strong.text() : $item.text());\n                url   = window.location.href;\n            }\n\n            crumbs.push({ label: label, url: url, cssClass: $item.attr('class') || '' });\n        });\n\n        return crumbs;\n    }\n\n    /**\n     * Persists the current category breadcrumb path and page URL into sessionStorage.\n     * Runs on every category page load \u2014 no click handler needed \u2014 so the stored\n     * data always reflects the last visited category regardless of how the user\n     * navigates within the page (image click, title click, keyboard, etc.).\n     */\n    function storeCategoryBreadcrumbs() {\n        var crumbs = readCategoryBreadcrumbs();\n\n        if (crumbs.length < 2) {\n            return;\n        }\n\n        try {\n            sessionStorage.setItem(STORAGE_KEY, JSON.stringify({\n                crumbs: crumbs,\n                categoryUrl: window.location.href\n            }));\n        } catch (e) {\n            console.warn('[Goyard Breadcrumb] Could not write to sessionStorage:', e.message);\n        }\n    }\n\n    /**\n     * Overrides the server-rendered breadcrumb with the stored navigation path.\n     * Guards against stale data by comparing document.referrer with the stored\n     * categoryUrl \u2014 the override only applies when the user actually navigated\n     * from that exact category page in this page load.\n     */\n    function overrideBreadcrumbsFromSession() {\n        var raw;\n\n        try {\n            raw = sessionStorage.getItem(STORAGE_KEY);\n        } catch (e) {\n            console.warn('[Goyard Breadcrumb] Could not read from sessionStorage:', e.message);\n            return;\n        }\n\n        if (!raw) {\n            return;\n        }\n\n        var data;\n\n        try {\n            data = JSON.parse(raw);\n        } catch (e) {\n            return;\n        }\n\n        if (!data || !data.crumbs || !data.crumbs.length || !data.categoryUrl) {\n            return;\n        }\n\n        // Verify the user actually navigated from the stored category.\n        // W
2ithout this check, stale sessionStorage data from a previous category\n        // would pollute direct URL access or navigation from unrelated pages.\n        if (!document.referrer) {\n            return;\n        }\n\n        var referrer    = document.referrer.replace(/\\/$/, '');\n        var categoryUrl = data.categoryUrl.replace(/\\/$/, '');\n\n        if (referrer !== categoryUrl) {\n            return;\n        }\n\n        $('.breadcrumbs .items').each(function () {\n            var $list = $(this);\n            $list.empty();\n\n            $.each(data.crumbs, function (i, crumb) {\n                var $li = $('<li>').addClass(crumb.cssClass);\n\n                if (crumb.url) {\n                    $li.append($('<a>').attr({ href: crumb.url, title: '' }).text(crumb.label));\n                } else {\n                    $li.append($('<strong>').text(crumb.label));\n                }\n\n                $list.append($li);\n            });\n        });\n    }\n\n    $(document).ready(function () {\n        if (document.body.classList.contains('catalog-category-view')) {\
2n            storeCategoryBreadcrumbs();\n        } else if (document.body.classList.contains('catalog-product-view')) {\n            overrideBreadcrumbsFromSession();\n        }\n    });\n});\n","js/category-top-of-page.js":"/**\n * Copyright Goyard\n */\nrequire([\n    'jquery'\n], function ($) {\n    // Add page title to category description\n    $(document).ready(function () {\n        if ($('.pagebuilder-banner-wrapper').length > 0) {\n            $('.page-title-wrapper').prependTo('.pagebuilder-banner-wrapper');\n        }\n    });\n\n    let lastScroll = 0;\n    let filterTop = $('.block.filter').offset()?.top ?? 0;\n    let titleTop = $('.page-title-wrapper').offset()?.top ?? 0;\n    let headerTop = ($('.page-header').height() ?? 0);\n    let navHeight = $(window).width() > 768 ? $('.nav-sections').height() ?? 0 : 0;\n    let banner = $('.pagebuilder-banner-wrapper').css('background-image');\n    $(window).scroll(function () {\n        let scrollPosition = $(this).scrollTop();\n        let titleHeight = $('.page-title-wrapper').height() ?? 0;\n\n        if (scrollPosition > lastScroll) { // Scroll down\n            $('.block.filter').addClass('scroll-down');\n            $('.block.filter').removeClass('scroll-up');\n            $('.page-title-wrapper').addClass('scroll-down');\n            $('.page-title-wrapper').removeClass('scroll-up');\n        } else { // Scroll up\n            $('.block.filter').removeClass('scroll-down');\n            $('.block.filter').addClass('scroll-up');\n            $('.page-title-wrapper').removeClass('scroll-down');\n            $('.page-title-wrapper').addClass('scroll-up');\n        }\n        lastScroll = scrollPosition;\n\n        // Manage filters\n        if ((scrollPosition + headerTop + titleHeight + navHeight) > filterTop) {\n            $('.block.filter').css('position', 'fixed');\n            if ($('.block.filter').hasClass('scroll-down')) {\n                $('.block.filter').css('top', headerTop + titleHeight + 'px');\n            }\n            else if ($('.block.filter').hasClass('scroll-up')) {\n                $('.block.filter').css('top', headerTop + titleHeight + navHeight + 'px');\n            }\n            $('.block.filter').addClass('fixed-title');\n            $('.pagebuilder-banner-wrapper').css('background-image', 'none');\n        }\n        else {\n            $('.block.filter').css('position', 'static');\n            $('.block.filter').removeClass('fixed-title');\n            $('.pagebuilder-banner-wrapper').css('background-image', banner);\n        }\n\n        // Manage page title\n        if ((scrollPosition + headerTop + navHeight) > titleTop) {\n            $('.page-title-wrapper').css('position', 'fixed');\n            if ($('.page-title-wrapper').hasClass('scroll-down')) {\n                $('.page-title-wrapper').css('top', headerTop + 'px');\n            }\n            else if ($('.page-title-wrapper').hasClass('scroll-up')) {\n                $('.page-title-wrapper').css('top', headerTop + navHeight + 'px');\n            }\n            $('.page-title-wrapper').addClass('fixed-title');\n            $('.breadcrumbs').css('visibility', 'hidden');\n        }\n        else {\n            $('.page-title-wrapper').css('position', 'static');\n            $('.page-title-wrapper').removeClass('fixed-title');\n            $('.breadcrumbs').css('visibility', 'visible');\n        }\n\n        // Reset positions\n        if ($(this).scrollTop() < 1) {\n            $('.block.filter').css('position', 'static');\n            $('.block.filter').removeClass('fixed-title');\n            $('.page-title-wrapper').css('position', 'static');\n            $('.page-title-wrapper').removeClass('fixed-title');\n        }\n    });\n\n    // Update position of title and filter when nav is visible\n    $(document).on('mouseenter', 'header.page-header.opaque-header', function () {\n        if ($('.page-title-wrapper').hasClass('fixed-title')) {\n            let titleHeight = $('.page-title-wrapper').height() ?? 0;\n\n            $('.page-title-wrapper').css('top', headerTop + navHeight + 'px');\n            $('.block.filter').css('top', headerTop + titleHeight + navHeight + 'px');\n        }\n    });\n});\n","js/pagebuilder-video.js":"define([\n    \"jquery\",\n    \"Goyard_Catalog/js/video-playback\"\n], function ($, videoPlayback) {\n    \"use strict\";\n    $(document).ready(function () {\n        $(\"video[autoplay]\", \".background-video-cover\").each(function (i,video) {\n\t\t\tvideo.playsinline=true;\n\t\t\tvideo.muted=true;\t\t\t\n            video.controls=false;\n            video.loop=true;\n            $(video).attr('playsinline','');\n        });\n      \n        $('[data-background-type=\"video\"], .background-video-cover').each(function () {\n\t\t\tconst buttonList = \"<ul class='video-button-list' aria-label='video controls'></ul>\";\n\t\t\t$(this).append(buttonList);\n\n\t\t\t// add test on CSS class to check if behavior apply to the video\n\t\t\t// CSS : no-play\n\t\t\tif(!$(this).hasClass('no-play')){\n\t\t\t\tcreatePlayButton(this);\n\t\t\t}\n\t\t\t\n\t\t\t// CSS : no-sound\n\t\t\tif(!$(this).hasClass('no-sound')){\n\t\t\t\tcreateSoundButton(this);\t\n\t\t\t}\n        });\n        \n        document.addEventListener(\"reductAnimation\", (event) => {\n\t\t\tlet pageBuilderVideo = $('.pagebuilder-video-container').find('video');\n\n\t\t\t$(\"video[autoplay]\", \".background-video-cover\").each(function(i,video){\n                event.detail.animation ?  videoPlayback.pause(video) : videoPlayback.play(video);\n\t\t\t\t$(video).attr('aria-label',event.detail.animation ? 'Pause' : 'Play');\n            })\n\t\t\t\n            if (event.detail.animation === false) {\n            \t$('.video-play-button.play-off').each(function(){\n\t\t\t\t\t$(this).removeClass('play-off').addClass('play-on');\n\t\t\t\t\t$(this).attr('aria-label','Pause');\n\t\t\t\t});\n\t\t\t\t$(pageBuilderVideo).each(function(){\n\t\t\t\t\tvideoPlayback.play(this);\n\t\t\t\t\t$(this).attr('aria-label','Pause');\n\t\t\t\t});\n            }
2else{\n\t\t\t\t$('.video-play-button.play-on').each(function(){\n\t\t\t\t\t$(this).removeClass('play-on').addClass('play-off');\n\t\t\t\t\t$(this).attr('aria-label','Play');\n\t\t\t\t}); \n\t\t\t\t$(pageBuilderVideo).each(function(){\n\t\t\t\t\tvideoPlayback.pause(this);\n\t\t\t\t\t$(this).attr('aria-label','Play');\n\t\t\t\t});\n\t\t\t}\n        });\n    });\n        \n    /**\n     *\n     */\n    function createSoundButton(videoWrapper){\t\t\n\t\t\n\t\tlet soundBtn = \"<li><button type='button' class='video-sound-button sound-off' tabindex='0' aria-label='Sound on'></button></li>\";\n\t\t$(videoWrapper).find('.video-button-list').append(soundBtn);\n\t\t\n\t\t$(videoWrapper).find('.video-sound-button').click(function(){\n\t\t\tif($(this).hasClass('sound-off')){\n\t\t\t\t$(this).closest('[data-background-type=\"video\"], .background-video-cover').find(\"video\").get(0).muted = false;\n\t\t\t\t$(this).removeClass('sound-off').addClass('sound-on');\n\t\t\t\t$(this).attr('aria-label','Sound off');\n\t\t\t}else{\n\t\t\t\t$(this).closest('[data-background-type=\"video\"], .background-video-cover').find(\"video\").get(0).muted = true;\n\t\t\t\t$(this).removeClass('sound-on').addClass('sound-off');\n\t\t\t\t$(this).attr('aria-label','Sound on');\n\t\t\t}\n\t\t});\n\t}\n\t\n\t/**\n\t*\n\t*/\n\tfunction createPlayButton(videoWrapper){\n\t\tlet playBtn = \"<li><button type='button' class='video-play-button play-on' tabindex='0' aria-label='Pause'></button></li>\";\n\t\t$(videoWrapper).find('.video-button-list').append(playBtn);\n\n\t\t$(videoWrapper).find('.video-play-button').click(function(){\n\t\t\tif($(this).hasClass('play-off')){\n\t\t\t\t$(this).removeClass('play-off').addClass('play-on');\n\t\t\t\tvideoPlayback.play($(this).closest('[data-background-type=\"video\"], .background-video-cover').find(\"video\").get(0));\n\t\t\t\t$(this).attr('aria-label','Pause');\n\n\t\t\t}else{\n\t\t\t\t$(this).removeClass('play-on').addClass('play-off');\n\t\t\t\tvideoPlayback.pause($(this).closest('[data-background-type=\"video\"], .background-video-cover').find(\"video\").get(0));\n\t\t\t\t$(this).attr('aria-label','Play');\n\t\t\t}\n\t\t});\n\n\t}\n\t\n\tfunction isVideoInViewport(element) {\n\t\tconst percentVisible = 2;\n\t    const rect = element.getBoundingClientRect();\n\t    const windowHeight = (window.innerHeight || document.documentElement.clientHeight);\n\t    \t\n\t\treturn !(\n\t\t    Math.floor(100 - (((rect.top >= 0 ? 0 : rect.top) / +-rect.height) * 100)) < percentVisible ||\n\t\t    Math.floor(100 - ((rect.bottom - windowHeight) / rect.height) * 100) < percentVisible\n\t\t  );\n\t}\n\t\n\t/**\n\t* Catch scroll event to pause/mute video when outside of the viewport windows\n\t*/\n\t$( window ).scroll(function() {\n\t\t// Sound\n\t\t$('.video-sound-button.sound-on').each(function(){\n\t\t\tif($(this).parent().find(\"video\").length > 0)\n\t\t\t{\n\t\t\t\tlet isVisible = isVideoInViewport($(this).parent().find(\"video\").get(0));\n\t\t\t\tif(!isVisible){\n\t\t\t\t\t$(this).parent().find(\"video\").get(0).muted = true;\n\t\t\t\t\t$(this).removeClass('sound-on').addClass('sound-off');\n\t\t\t\t\t$(this).attr('aria-label','Sound on');\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\t\n\t\t// Play\n\t\t$('.video-play-button.play-on').each(function(){\n\t\t\tif($(this).parent().find(\"video\").length > 0)\n\t\t\t{\n\t\t\t\tlet video = $(this).parent().find(\"video\").get(0);\n\t\t\t\tlet isVisible = isVideoInViewport(video);\n\n\t\t\t\tif(!isVisible){\n\t\t\t\t\tvideoPlayback.pause(video);\n\t\t\t\t}else if(video.paused){\n\t\t\t\t\t// HTMLVideoElement n'expose pas de propriete \"playing\" : sans ce\n\t\t\t\t\t// test sur \"paused\", chaque evenement de scroll relance un play()\n\t\t\t\t\tvideoPlayback.play(video);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n})","js/gallery-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'fotorama/fotorama',\n    'underscore',\n    'matchMedia',\n    'mage/template',\n    'text!mage/gallery/gallery.html',\n    'uiClass',\n    'mage/translate'\n], function ($, fotorama, _, mediaCheck, template, galleryTpl, Class, $t) {\n    'use strict';\n    return function (gallery) {\n        return gallery.extend({\n\n            /**\n             * GOYARD - allow arrow on touch devices\n             * \n             * Checks if device has touch interface.\n             * @return {Boolean} The result of searching touch events on device.\n             */\n            isTouchEnabled: (function () {\n                return false;\n            })(),\n\n            initFullscreenSettings: function () {\n                var settings = this.settings,\n                    self = this;\n\n                settings.$gallery = this.settings.$element.find('[data-gallery-role=\"gallery\"]');\n                settings.$fullscreenIcon = this.settings.$element.find('[data-gallery-role=\"fotorama__fullscreen-icon\"]');\n                settings.focusableStart = this.settings.$element.find('[data-gallery-role=\"fotorama__focusable-start\"]');\n                settings.focusableEnd = this.settings.$element.find('[data-gallery-role=\"fotorama__focusable-end\"]');\n                settings.closeIcon = this.settings.$element.find('[data-gallery-role=\"fotorama__fullscreen-icon\"]');\n                settings.fullscreenConfig.swipe = true;\n\n                settings.$gallery.on('fotorama:fullscreenenter', function () {\n                    settings.closeIcon.show();\n                    settings.focusableStart.attr('tabindex', '0');\n                    settings.focusableEnd.attr('tabindex', '0');\n                    settings.focusableStart.on('focusin', self._focusSwitcher);\n                    settings.focusableEnd.on('focusin', self._focusSwitcher);\n                    settings.api.updateOptions(settings.defaultConfig.options, true);\n                    settings.api.updateOptions(settings.fullscreenConfig, true);\n\n                    if (!_.isEqual(settings.activeBreakpoint, {}) && settings.breakpoints) {\n                        settings.api.updateOptions(settings.activeBreakpoint.options, true);\n                    }\n                    settings.isFullscreen = true;\n                    $(\".logo\").toggleClass(\"pointer-events\");\n                });\n\n                settings.$gallery.on('fotorama:fullscreenexit', function () {\n                    settings.closeIcon.hide();\n                    settings.focusableStart.attr('tabindex', '-1');\n                    settings.focusableEnd.attr('tabindex', '-1');\n                    settings.api.updateOptions(settings.defaultConfig.options, true);\n                    settings.focusableStart.off('focusin', this._focusSwitcher);\n                    settings.focusableEnd.off('focusin', this._focusSwitcher);\n                    settings.closeIcon.hide();\n\n                    if (!_.isEqual(settings.activeBreakpoint, {}) && settings.breakpoints) {\n                        settings.api.updateOptions(settings.activeBreakpoint.options, true);\n                    }\n                    settings.isFullscreen = false;\n                    settings.$element.data('gallery').updateOptions({\n                        swipe: true\n                    });\n                    setTimeout(() =>
2 {\n                        $(\".logo\").toggleClass(\"pointer-events\");\n                    }\n                        , 200);\n                });\n            }\n        });\n    }\n});\n","js/category-filter-display.js":"/**\r\n * Copyright Goyard\r\n */\r\ndefine([\r\n    \"jquery\"\r\n], function($){\r\n    \"use strict\";\r\n\r\n   \t$(document).ready(function(){\r\n\r\n   \t\t$('.block-title.filter-title').click(function(){\r\n   \t\t\tif(!$('.filter-top').first().hasClass(\"active\")){\r\n\t\t\t\t$('.filter-content').show();\r\n\t\t\t\t$(this).addClass('active');\r\n\t\t\t\t$('.filter-top').addClass('active');\r\n\t\t\t\t$('.page-main').addClass('filter-above');\r\n\t\t\t\t$('.page-main').addClass('filter-above');\r\n\t\t\t\t$('#back_top').hide();\r\n\t\t\t\t$('html').addClass('filter-opened');\r\n\r\n\t\t\t\t// Add test if block filter is bigger than the screen height\r\n                const windowHeight = $(window).height() - $(\".nav-sections\").height() - $(\".page-header\").height();\r\n                const filterHeight = $(\".block.filter\").height();\r\n                if ($(window).width() > 1024 && filterHeight > windowHeight) {\r\n                    $('.block.filter').addClass('position-relative');\r\n                }\r\n\t\t\t}else{\r\n                $('.filter-content').hide();\r\n\t\t\t\t$(this).removeClass('active');\r\n\t\t\t\t$('.filter-top').removeClass('active');\r\n\t\t\t\t$('.page-main').removeClass('filter-above');\r\n                $('#back_top').show();\r\n\t\t\t\t$('html').removeClass('filter-opened');\r\n                if ($(window).width() > 1024) {\r\n                    $('.block.filter').removeClass('position-relative');\r\n                }\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t$('#filter-close').click(function(){\r\n\t\t\t$('.block-title.filter-title').removeClass('active');\r\n\t\t\t$('.filter-top').removeClass('active');\r\n            $('.page-main').removeClass('filter-above');\r\n            $('#back_top').show();\r\n\t\t\t$('.filter-content').hide();\r\n\t\t\t$('html').removeClass('filter-opened');\r\n\t\t});\r\n\r\n   \t});\r\n\r\n});\r\n","js/validation-mixin.js":"/**\n * Copyright Goyard\n */\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    return function (target) {\n        $.validator.addMethod(\n            'required-email',\n            function (v) {\n                return !(v == '' || (v == null) || (v.length == 0) || /^\\s+$/.test(v));\n            },\n            $.mage.__('The field e-mail address is required')\n        );\n\n        $.validator.addMethod(\n            'validate-name-goyard',\n            function (v) {\n                return $.mage.isEmptyNoTrim(v) || /^[\\p{L}\\p{M},\\-_.'\u2019`&\\s\\d]{1,255}$/u.test(v);\n            },\n            $.mage.__('Please enter a valid name.')\n        );\n\n        $.widget('mage.validation', $.mage.validation, {\n            options: {\n                errorElement: 'p',\n            },\n\n            /**\n             * GOYARD - prevent scroll on validation for .no-scroll form\n             *\n             * Handle form validation. Focus on first invalid form field.\n             *\n             * @param {jQuery.Event} event\n             * @param {Object} validation\n            */\n            listenFormValidateHandler: function (event, validation) {\n                // Usual behaviour\n                if (!$(validation?.currentForm)?.hasClass('no-scroll')) {\n                    return this._super(event, validation);\n                }\n\n                try {\n                    var successList = validation.successList;\n\n                    if (successList.length) {\n                        $.each(successList, function () {\n                            $(this)\n                                .removeAttr('aria-describedby')\n                                .removeAttr('aria-invalid');\n                        });\n                    }\n                } catch (e) {\n                    // Don't do anything\n                }\n\n                return true;\n            }\n        });\n\n        var showLabel = $.validator.prototype.showLabel;\n        $.validator.prototype.showLabel = function (element, message) {\n            var label, elem, ariaDescribedby = $(element).attr('aria-describedby');\n\n            showLabel.call(this, element, message);\n\n            // ARIA (adding aria-invalid & aria-describedby)\n            label = this.errorsFor(element);\n            elem = $(element);
2\n\n            if (!label.attr('id')) {\n                label.attr('id', this.idOrName(element) + '-error');\n            }\n\n            elem.attr('aria-invalid', 'true');\n            // GOYARD accessibility changes to add error message id in aria-describedby instead of override it\n            if (!(elem.attr('aria-describedby') || '').includes(label.attr('id')))\n                elem.attr('aria-describedby', (elem.attr('aria-describedby') || '') + ' ' + label.attr('id'));\n            ariaDescribedby = ariaDescribedby?.replaceAll(label.attr('id') + ' ', '');\n            if (!(elem.attr('aria-describedby') || '').includes(ariaDescribedby))\n                elem.attr('aria-describedby', (elem.attr('aria-describedby') || '') + ' ' + ariaDescribedby);\n        };\n\n        return target\n    }\n\n});\n","js/smooth-scrolling.js":"/**\r\n * Copyright Goyard\r\n */\r\ndefine([\r\n    \"jquery\"\r\n], function($){\r\n    \"use strict\";\r\n\r\n   \t$(document).ready(function(){\r\n\t\r\n   \t\tdocument.querySelectorAll('a[href^=\"#\"]:not(.cancel-order)').forEach(anchor => {\r\n\t\t    // Skip links move the focus themselves, see skip-links.js\r\n\t\t    if (anchor.closest('.header-skip-links')) {\r\n\t\t        return;\r\n\t\t    }\r\n\r\n\t\t    anchor.addEventListener('click', function (e) {\r\n\t\t        e.preventDefault();\r\n\t\t\r\n\t\t        var href = this.getAttribute('href');\r\n\t        \tif(href !== \"#\" && /^#[a-zA-Z]/.test(href))\r\n\t        \t{\r\n\t\t        \tdocument.querySelector(href).scrollIntoView({\r\n\t\t            behavior: 'smooth'\r\n\t\t        \t});\r\n\t        \t}\r\n\t\t    });\r\n\t\t});\r\n  \t\t\r\n   \t});         \r\n    \r\n});","js/header-menu-align-items.js":"/**\r\n * Copyright Goyard\r\n */\r\ndefine([\r\n    \"jquery\"\r\n], function($){\r\n    \"use strict\"; \r\n    \r\n    var left_submenu_margin = 5;\r\n    \r\n    $(document).ready(function(){\r\n\t\t\r\n\t\t// Align the submenu column with the horizontal top menu item\r\n    \t/*$(\".magemenu-menu.horizontal-menu .megamenu-items > li\").hover(function(evt){    \t\t\r\n    \t\tvar submenu_content = $(this).find('.megamenu-dropdown > .block-main > .megamenu-sub-items');\r\n    \t\tif(submenu_content.length > 0){\r\n\t    \t\tvar topmenu_left_offset = $(this).offset().left;\r\n\t    \t\tvar submenu_left_offset = submenu_content.offset().left;\r\n\t    \t\tvar submenu_content_left_padding = topmenu_left_offset - submenu_left_offset + left_submenu_margin;\r\n\t    \t\tsubmenu_content.css(\"padding-left\",submenu_content_left_padding + \"px\");\r\n\t    \t\tvar submenu_content_li = submenu_content.find('li').first();\r\n\t    \t\tsubmenu_content.find('.tab-menu-content').css('left',(submenu_content_left_padding + submenu_content_li.width()) + \"px\");\r\n    \t\t}\r\n    \t});*/\r\n    \t    \t\r\n    \t\r\n    \t// Display backgound of the 3th level item over the 2nd level background display on hover\r\n    \t$(\".magemenu-menu.horizontal-menu .megamenu-items > li .megamenu-sub-items li .megamenu-sub-items .megamenu-sub-item\").hover(\r\n\t\tfunction(evt){    \t\t\r\n\t\t\tvar bg_sub_item = $(this).find('.megamenu-dropdown-background');\r\n\t\t\tif(bg_sub_item.length > 0)\r\n\t\t\t{\r\n\t\t\t\tvar bg_sub_item_url = bg_sub_item.css('background-image');\t\t\t\t\r\n\t\t\t\tvar bg_sub_item_copy = \"<div id='megamenu_bg_sub_item_copy' style='background-image:\"+bg_sub_item_url+\"'></div>\";\r\n\t\t\t\t$(this).parents('.megamenu-sub-item').find('.megamenu-dropdown-background').first().append(bg_sub_item_copy);\r\n\t\t\t}\r\n\t\t\t \r\n    \t},\r\n    \tfunction(evt){    \t\t\r\n\t\t\t$('#megamenu_bg_sub_item_copy').remove();\r\n    \t}\r\n    \t);\r\n    });    \r\n\t\r\n});","js/mute-migrate.js":"/**\r\n* Mute jQuery migrate log in console\r\n*/\r\nrequirejs(['jquery'], function ($) {\r\n    $.migrateMute = true;\r\n    $.migrateTrace = false;\r\n});","js/webcreate/infinite-ajax-scroll.3.0.1.min.js":"/**\n * Infinite Ajax Scroll v3.0.1\n * Turn your existing pagination into infinite scrolling pages with ease\n *\n * Commercial use requires one-time purchase of a commercial license\n * https://infiniteajaxscroll.com/docs/license.html\n *\n * Copyright 2014-2022 Webcreate (Jeroen Fiege)\n * https://infiniteajaxscroll.com\n */\n!function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e():\"function\"==typeof define&&define.amd?define(e):(t=\"undefined\"!=typeof globalThis?globalThis:t||self).InfiniteAjaxScroll=e()}(this,(function(){\"use strict\";function t(t){return\"object\"==typeof window.Node?t instanceof window.Node:null!==t&&\"object\"==typeof t&&\"number\"==typeof t.nodeType&&\"string\"
2==typeof t.nodeName}function e(e,n){if(void 0===n&&(n=document),e instanceof Array)return e.filter(t);if(t(e))return[e];if(o=Object.prototype.toString.call(i=e),\"object\"==typeof window.NodeList?i instanceof window.NodeList:null!==i&&\"object\"==typeof i&&\"number\"==typeof i.length&&/^\\[object (HTMLCollection|NodeList|Object)\\]$/.test(o)&&(0===i.length||t(i[0])))return Array.prototype.slice.call(e);var i,o;if(\"string\"==typeof e)try{var r=n.querySelectorAll(e);return Array.prototype.slice.call(r)}catch(t){return[]}return[]}var n=Object.prototype.hasOwnProperty,i=Object.prototype.toString,o=Object.defineProperty,r=Object.getOwnPropertyDescriptor,s=function(t){return\"function\"==typeof Array.isArray?Array.isArray(t):\"[object Array]\"===i.call(t)},l=function(t){if(!t||\"[object Object]\"!==i.call(t))return!1;var e,o=n.call(t,\"constructor\"),r=t.constructor&&t.constructor.prototype&&n.call(t.constructor.prototype,\"isPrototypeOf\");if(t.constructor&&!o&&!r)return!1;for(e in t);return void 0===e||n.call(t,e)},a=function(t,e){o&&\"__proto__\"===e.name?o(t,e.name,{enumerable:!0,configurable:!0,value:e.newValue,writable:!0}):t[e.name]=e.newValue},h=function(t,e){if(\"__proto__\"===e){if(!n.call(t,e))return;if(r)return r(t,e).value}return t[e]},c=function t(){var e,n,i,o,r,c,u=arguments,d=arguments[0],p=1,f=arguments.length,m=!1;for(\"boolean\"==typeof d&&(m=d,d=arguments[1]||{},p=2),(null==d||\"object\"!=typeof d&&\"function\"!=typeof d)&&(d={});f>p;++p)if(null!=(e=u[p]))for(n in e)i=h(d,n),d!==(o=h(e,n))&&(m&&o&&(l(o)||(r=s(o)))?(r?(r=!1,c=i&&s(i)?i:[]):c=i&&l(i)?i:{},a(d,{name:n,newValue:t(m,c,o)})):void 0!==o&&a(d,{name:n,newValue:o}));return d},u=\"undefined\"!=typeof globalThis?globalThis:\"undefined\"!=typeof window?window:\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:{},d=\"Expected a function\",p=/^\\s+|\\s+$/g,f=/^[-+]0x[0-9a-f]+$/i,m=/^0b[01]+$/i,y=/^0o[0-7]+$/i,g=parseInt,v=\"object\"==typeof self&&self&&self.Object===Object&&self,b=\"object\"==typeof u&&u&&u.Object===Object&&u||v||Function(\"return this\")(),w=Object.prototype.toString,x=Math.max,O=Math.min,E=function(){return b.Date.now()};function S(t,e,n){var i,o,r,s,l,a,h=0,c=!1,u=!1,p=!0;if(\"function\"!=typeof t)throw new TypeError(d);function f(e){var n=i,r=o;return i=o=void 0,h=e,s=t.apply(r,n)}function m(t){return h=t,l=setTimeout(g,e),c?f(t):s}function y(t){var n=t-a;return void 0===a||n>=e||0>n||u&&t-h>=r}function g(){var t=E();if(y(t))return v(t);l=setTimeout(g,function(t){var n=e-(t-a);return u?O(n,r-(t-h)):n}(t))}function v(t){return l=void 0,p&&i?f(t):(i=o=void 0,s)}function b(){var t=E(),n=y(t);if(i=arguments,o=this,a=t,n){if(void 0===l)return m(a);if(u)return l=setTimeout(g,e),f(a)}return void 0===l&&(l=setTimeout(g,e)),s}return e=j(e)||0,T(n)&&(c=!!n.leading,r=(u=\"maxWait\"in n)?x(j(n.maxWait)||0,e):r,p=\"trailing\"in n?!!n.trailing:p),b.cancel=function(){void 0!==l&&clearTimeout(l),h=0,i=a=o=l=void 0},b.flush=function(){return void 0===l?s:v(E())},b}function T(t){var e=typeof t;return!!t&&(\"object\"==e||\"function\"==e)}function j(t){if(\"number\"==typeof t)return t;if(function(t){return\"symbol\"==typeof t||function(t){return!!t&&\"object\"==typeof t}(t)&&\"[object Symbol]\"==w.call(t)}(t))return NaN;if(T(t)){var e=\"function\"==typeof t.valueOf?t.valueOf():t;t=T(e)?e+\"\":e}if(\"string\"!=typeof t)return 0===t?t:+t;t=t.replace(p,\"\");var n=m.test(t);return n||y.test(t)?g(t.slice(2),n?2:8):f.test(t)?NaN:+t}var L=function(t,e,n){var i=!0,o=!0;if(\"function\"!=typeof t)throw new TypeError(d);return T(n)&&(i=\"leading\"in n?!!n.leading:i,o=\"trailing\"in n?!!n.trailing:o),S(t,e,{leading:i,maxWait:e,trailing:o})},I={item:void 0,next:void 0,pagination:void 0,responseType:\"document\",bind:!0,scrollContainer:window,spinner:!1,logger:!0,loadOnScroll:!0,negativeMargin:0,trigger:!1,prefill:!0},C=function(t,n){var i=e(t);if(i.length>1)throw Error('Expected single element for \"'+n+'\"');if(0===i.length)throw Error('Element \"'+t+'\" not found for \"'+n+'\"')},_=function(t,n){if(0===e(t).length)throw Error('Element \"'+t+'\" not found for \"'+n+'\"')},H=function(t){for(var e=[],n=arguments.length-1;n-- >0;)e[n]=arguments[n+1];try{t.apply(void 0,e)}catch(t){console&&console.warn&&console.warn(t.message)}};function N(t){if(t!==window)return{x:t.scrollLeft,y:t.scrollTop};var e=void 0!==window.pageXOffset,n=\"CSS1Compat\"===(document.compatMode||\"\");return{x:e?window.pageXOffset:n?document.documentElement.scrollLeft:document.body.scrollLeft,y:e?window.pageYOffset:n?document.documentElement.scrollTop:document.body.scrollTop}}function M(t){var e;if(t!==window)e=t.getBoundingClientRect();else{var n=document.documentElement,i=document.body;e={top:0,left:0,right:n.clientWidth||i.clientWidth,width:n.clientWidth||i.clientWidth,bottom:n.clientHeight||i.clientHeight,height:n.clientHeight||i.clientHeight}}return e}var P=\"append\",F=\"appended\",R=\"binded\",D=\"unbinded\",k=\"hit\",A=\"load\",B=\"loaded\",W=\"error\",z=\"last\",X=\"next\",q=\"nexted\",$=\"ready\",V=\"scrolled\",Y=\"resized\",G=\"page\",U=\"prefill\",J=\"prefilled\",K={y:0,x:0,deltaY:0,deltaX:0};function Q(t,e){var n=N(t);return n.deltaY=n.y-(e?e.y:n.y),n.deltaX=n.x-(e?e.x:n.x),n}
vendor: 2,884 bytes, line 2
2function Z(){var t=this,e=t._lastScroll=Q(t.scrollContainer,t._lastScroll||K);this.emitter.emit(V,{scroll:e})}function tt(){var t=this,e=t._lastScroll=Q(t.scrollContainer,t._lastScroll||K);this.emitter.emit(Y,{scroll:e})}function et(){}et.prototype={on:function(t,e,n){var i=this.e||(this.e={});return(i[t]||(i[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){var i=this;function o(){i.off(t,o),e.apply(n,arguments)}return o._=e,this.on(t,o,n)},emit:function(t){for(var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),i=0,o=n.length;o>i;i++)n[i].fn.apply(n[i].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),i=n[t],o=[];if(i&&e)for(var r=0,s=i.length;s>r;r++)i[r].fn!==e&&i[r].fn._!==e&&o.push(i[r]);return o.length?n[t]=o:delete n[t],this}};var nt=et;function it(t){var n=this,i=n._lastResponse||document,o=e(n.options.next,i)[0];if(o)return n.load(o.href).then((function(o){i=n._lastResponse=o.xhr.response;var r=e(n.options.next,i)[0];return n.append(o.items).then((function(){return!!r})).then((function(e){return!e&&1>=t&&console&&console.warn&&console.warn('Element \"'+n.options.next+'\" not found for \"options.next\" on \"'+o.url+'\"'),e}))}));H(C,n.options.next,\"options.next\")}nt.TinyEmitter=et;var ot={element:void 0,hide:!1};var rt=function(t,e){this.options=c({},ot,function(t){return\"string\"==typeof t||\"object\"==typeof t&&t.nodeType===Node.ELEMENT_NODE?t={element:t,hide:!0}:\"boolean\"==typeof t&&(t={element:void 0,hide:t}),t}(e)),this.originalDisplayStyles=new WeakMap,this.options.hide&&(H(_,this.options.element,\"pagination.element\"),t.on(R,this.hide.bind(this)),t.on(D,this.restore.bind(this)))};rt.prototype.hide=function(){var t=this;e(this.options.element).forEach((function(e){t.originalDisplayStyles.set(e,window.getComputedStyle(e).display),e.style.display=\"none\"}))},rt.prototype.restore=function(){var t=this;e(this.options.element).forEach((function(e){e.style.display=t.originalDisplayStyles.get(e)||\"block\"}))};var st={element:void 0,delay:600,show:function(t){t.style.opacity=\"1\"},hide:function(t){t.style.opacity=\"0\"}};var lt=function(t,n){!1!==n&&(this.ias=t,this.options=c({},st,function(t){return(\"string\"==typeof t||\"object\"==typeof t&&t.nodeType===Node.ELEMENT_NODE)&&(t={element:t}),t}(n)),void 0!==this.options.element&&C(this.options.element,\"spinner.element\"),this.element=e(this.options.element)[0],this.hideFn=this.options.hide,this.showFn=this.options.show,t.on(R,this.bind.bind(this)),t.on(R,this.hide.bind(this)))};lt.prototype.bind=function(){var t,e,n=this,i=this.ias;i.on(X,(function(){t=+new Date,n.show()})),i.on(z,(function(){n.hide()})),i.on(P,(function(i){e=Math.max(0,n.options.delay-(+new Date-t));var o=i.appendFn.bind({});i.appendFn=function(t,i,r){return new Promise((function(s){setTimeout((function(){n.hide().then((function(){o(t,i,r),s()}))}),e)}))}}))}
2,lt.prototype.show=function(){return Promise.resolve(this.showFn(this.element))},lt.prototype.hide=function(){return Promise.resolve(this.hideFn(this.element))};var at={hit:function(){console.log(\"Hit scroll threshold\")},binded:function(){console.log(\"Binded event handlers\")},unbinded:function(){console.log(\"Unbinded event handlers\")},next:function(t){console.log(\"Next page triggered [pageIndex=\"+t.pageIndex+\"]\")},nexted:function(t){console.log(\"Next page completed [pageIndex=\"+t.pageIndex+\"]\")},load:function(t){console.log(\"Start loading \"+t.url)},loaded:function(){console.log(\"Finished loading\")},append:function(){console.log(\"Start appending items\")},appended:function(t){console.log(\"Finished appending \"+t.items.length+\" item(s)\")},last:function(){console.log(\"No more pages left to load\")},page:function(t){console.log(\"Page changed [pageIndex=\"+t.pageIndex+\"]\")},prefill:function(t){console.log(\"Start prefilling\")},prefilled:function(t){console.log(\"Finished prefilling\")}};var ht=function(t,e){if(!1!==e){var n=function(t){return!0===t&&(t=at),t}(e);Object.keys(n).forEach((function(e){t.on(e,n[e])}))}};var ct=function(t){this.ias=t,this.pageBreaks=[],this.currentPageIndex=t.pageIndex,this.currentScrollTop=0,t.on(R,this.binded.bind(this)),t.on(X,this.next.bind(this)),t.on(V,this.scrolled.bind(this)),t.on(Y,this.scrolled.bind(this))};ct.prototype.binded=function(){this.ias.sentinel()&&this.pageBreaks.push({pageIndex:this.currentPageIndex,url:\"\"+document.location,title:document.title,sentinel:this.ias.sentinel()})},ct.prototype.next=function(){var t=this,e=\"\"+document.location,n=document.title,i=function(t){e=t.url,t.xhr.response&&(n=t.xhr.response.title)};this.ias.once(B,i),this.ias.once(q,(function(o){t.pageBreaks.push({pageIndex:o.pageIndex,url:e,title:n,sentinel:t.ias.sentinel()}),t.update(),t.ias.off(B,i)}))},ct.prototype.scrolled=function(t){this.update(t.scroll.y)},ct.prototype.update=function(t){this.currentScrollTop=t||this.currentScrollTop;var e=function(t,e,n){for(var i=e+M(n).height,o=t.length-1;o>=0;o--)if(i>t[o].sentinel.getBoundingClientRect().bottom+e)return t[Math.min(o+1,t.length-1)];return t[0]}(this.pageBreaks,this.currentScrollTop,this.ias.scrollContainer);e&&e.pageIndex!==this.currentPageIndex&&(this.ias.emitter.emit(G,e),this.currentPageIndex=e.pageIndex)};var ut={element:void 0,when:function(t){return!0},show:function(t){t.style.opacity=\"1\"},hide:function(t){t.style.opacity=\"0\"}};var dt=function(t,n){var i=this;!1!==n&&(this.ias=t,this.options=c({},ut,function(t){if((\"string\"==typeof t||\"function\"==typeof t||\"object\"==typeof t&&t.nodeType===Node.ELEMENT_NODE)&&(t={element:t}),\"function\"==typeof t.element&&(t.element=t.element()),t.when&&Array.isArray(t.when)){var e=t.when;t.when=function(t){return-1!==e.indexOf(t)}}return t}(n)),void 0!==this.options.element&&C(this.options.element,\"trigger.element\"),this.element=e(this.options.element)[0],this.hideFn=this.options.hide,this.showFn=this.options.show,this.voter=this.options.when,this.showing=void 0,this.enabled=void 0,t.on(R,this.bind.bind(this)),t.on(D,this.unbind.bind(this)),t.on(k,this.hit.bind(this)),t.on(X,(function(t){return i.ias.once(F,(function(){return i.update(t.pageIndex)}))})))};function pt(t,e,n){var i=n?n.nextSibling:null,o=document.createDocumentFragment();t.forEach((function(t){o.appendChild(t)})),e.insertBefore(o,i)}dt.prototype.bind=function(){this.hide(),this.update(this.ias.pageIndex),this.element.addEventListener(\"click\",this.clickHandler.bind(this))},dt.prototype.unbind=function(){this.element.removeEventListener(\"click\",this.clickHandler.bind(this))},dt.prototype.clickHandler=function(){this.hide().then(this.ias.next.bind(this.ias))},dt.prototype.update=function(t){this.enabled=this.voter(t),this.enabled?this.ias.disableLoadOnScroll():this.ias.enableLoadOnScroll()},dt.prototype.hit=function(){this.enabled&&this.show()},dt.prototype.show=function(){if(!this.showing)return this.showing=!0,Promise.resolve(this.show
2Fn(this.element))},dt.prototype.hide=function(){if(this.showing||void 0===this.showing)return this.showing=!1,Promise.resolve(this.hideFn(this.element))};var ft=window.ResizeObserver,mt=function(t,e){this.el=t,this.listener=e};mt.prototype.observe=function(){this.el.addEventListener(\"resize\",this.listener)},mt.prototype.unobserve=function(){this.el.removeEventListener(\"resize\",this.listener)};var yt=function(t,e){this.el=t,this.listener=e,this.ro=new ft(this.listener)};yt.prototype.observe=function(){this.ro.observe(this.el)},yt.prototype.unobserve=function(){this.ro.unobserve()};var gt=function(t,e){this.el=t,this.listener=e,this.interval=null,this.lastHeight=null};gt.prototype.pollHeight=function(){var t=Math.trunc(M(this.el).height);null!==this.lastHeight&&this.lastHeight!==t&&this.listener(),this.lastHeight=t},gt.prototype.observe=function(){this.interval=setInterval(this.pollHeight.bind(this),200)},gt.prototype.unobserve=function(){clearInterval(this.interval)};var vt=function(t,e){this.ias=t,this.enabled=e};vt.prototype.prefill=function(){var t=this;if(this.enabled&&0>=this.ias.distance())return this.ias.emitter.emit(U),this._prefill().then((function(){t.ias.emitter.emit(J),t.ias.measure()}))},vt.prototype._prefill=function(){var t=this;return this.ias.next().then((function(e){if(e)return 0>t.ias.distance()?t._prefill():void 0}))};var bt=function(t,n){var i,o,r,s=this;void 0===n&&(n={}),C(t,\"container\"),this.container=e(t)[0],this.options=c({},I,n),this.emitter=new nt,this.options.loadOnScroll?this.enableLoadOnScroll():this.disableLoadOnScroll(),this.negativeMargin=Math.abs(this.options.negativeMargin),this.scrollContainer=this.options.scrollContainer,this.options.scrollContainer!==window&&(C(this.options.scrollContainer,\"options.scrollContainer\"),this.scrollContainer=e(this.options.scrollContainer)[0]),this.nextHandler=it,!1===this.options.next?this.nextHandler=function(){}:\"function\"==typeof this.options.next&&(this.nextHandler=this.options.next),this.resizeObserver=(i=this,o=this.scrollContainer,r=L(tt,200).bind(i),o===window?new mt(o,r):ft?new yt(o,r):(console&&console.warn&&console.warn(\"ResizeObserver not supported. Falling back on polling.\"),new gt(o,r))),this._scrollListener=L(Z,200).bind(this),this.ready=!1,this.bindOnReady=!0,this.binded=!1,this.paused=!1,this.pageIndex=this.sentinel()?0:-1,this.on(k,(function(){s.loadOnScroll&&s.next()})),this.on(V,this.measure),this.on(Y,this.measure),this.pagination=new rt(this,this.options.pagination),this.spinner=new lt(this,this.options.spinner),this.logger=new ht(this,this.options.logger),this.paging=new ct(this),this.trigger=new dt(this,this.options.trigger),this.prefill=new vt(this,this.options.prefill),this.on(R,this.prefill.prefill.bind(this.prefill));var l=function(){s.ready||(s.ready=!0,s.emitter.emit($),s.bindOnReady&&s.options.bind&&s.bind())};\"complete\"===document.readyState||\"interactive\"===document.readyState?setTimeout(l,1):window.addEventListener(\"DOMContentLoaded\",l)};return bt.prototype.bind=function(){this.binded||(this.ready||(this.bindOnReady=!1),this.scrollContainer.addEventListener(\"scroll\",this._scrollListener),this.resizeObserver.observe(),this.binded=!0,this.emitter.emit(R))},bt.prototype.unbind=function(){this.binded?(this.resizeObserver.unobserve(),this.scrollContainer.removeEventListener(\"scroll\",this._scrollListener),this.binded=!1,this.emitter.emit(D)):this.ready||this.once(R,this.unbind)},bt.prototype.next=function(){var t=this;if(!this.binded)return this.ready?void 0:this.once(R,this.next);this.pause();var e=this.pageIndex+1;return this.emitter.emit(X,{pageIndex:this.pageIndex+1}),Promise.resolve(this.nextHandler(e)).then((function(n){if(t.pageIndex=e,n)return t.resume(),n;t.emitter.emit(z)})).then((function(e){return t.emitter.emit(q,{pageIndex:t.pageIndex}),e}))},bt.prototype.load=function(t){var n=this;return new Promise((function(i,o){var r=new XMLHttpRequest,s={url:t,xhr:r,method:\"GET\",body:null,nocache:!1,responseType:n.options.responseType,headers:{\"X-Requested-With\":\"XMLHttpRequest\"}};n.emitter.emit(A,s);var l=s.url,a=s.method,h=s.responseType,c=s.headers,u=s.body;for(var d in s.nocache||(l=l+(/\\?/.test(l)?\"&\":\"?\")+(new Date).getTime()),r.onreadystatechange=function(){if(r.readyState===4)if(0===r.
2status);else if(200===r.status){var t=r.response;\"document\"===h&&(t=e(n.options.item,r.response)),n.emitter.emit(B,{items:t,url:l,xhr:r}),i({items:t,url:l,xhr:r})}else n.emitter.emit(W,{url:l,method:a,xhr:r}),o(r)},r.onerror=function(){n.emitter.emit(W,{url:l,method:a,xhr:r}),o(r)},r.open(a,l,!0),r.responseType=h,c)r.setRequestHeader(d,c[d]);r.send(u)}))},bt.prototype.append=function(t,e){var n=this,i={items:t,parent:e=e||n.container,appendFn:pt};n.emitter.emit(P,i);return new Promise((function(o){window.requestAnimationFrame((function(){Promise.resolve(i.appendFn(i.items,i.parent,n.sentinel())).then((function(){o({items:t,parent:e})}))}))})).then((function(t){n.emitter.emit(F,t)}))},bt.prototype.sentinel=function(){var t=e(this.options.item,this.container);return t.length?t[t.length-1]:null},bt.prototype.pause=function(){this.paused=!0},bt.prototype.resume=function(){this.paused=!1},bt.prototype.enableLoadOnScroll=function(){this.loadOnScroll=!0},bt.prototype.disableLoadOnScroll=function(){this.loadOnScroll=!1},bt.prototype.distance=function(t,e){var n=t||M(this.scrollContainer),i=function(t,e,n){var i=n;if(!t)return-1*i.height;var o=e.y,r=t.getBoundingClientRect();return Math.trunc(o+r.bottom-i.top-(o+i.height))}(e||this.sentinel(),N(this.scrollContainer),n);return i-=this.negativeMargin,i},bt.prototype.measure=function(){if(!this.paused){var t=M(this.scrollContainer);if(0!==t.height){var e=this.sentinel(),n=this.distance(t,e);n>0||this.emitter.emit(k,{distance:n})}}},bt.prototype.on=function(t,e){this.emitter.on(t,e,this),t===R&&this.binded&&e.bind(this)()},bt.prototype.off=function(t,e){this.emitter.off(t,e,this)},bt.prototype.once=function(t,e){var n=this;return new Promise((function(i){n.emitter.once(t,(function(){Promise.resolve(e.apply(this,arguments)).then(i)}),n),t===R&&n.binded&&(e.bind(n)(),i())}))},bt}));\n","Magento_Csp/js/sri.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\nrequire.config({\n    onNodeCreated: function (node, config, moduleName, url) {\n        'use strict';\n        if ('sriHashes' in window && url in window.sriHashes) {\n            node.setAttribute('integrity', window.sriHashes[url]);\n            node.setAttribute('crossorigin', 'anonymous');\n        }\n    }\n});\n","Magento_Csp/js/nonce-injector.js":"/**\n * Copyright 2024 Adobe\n * All Rights Reserved.\n */\n\ndefine('Magento_Csp/js/nonce-injector', [], function () {\n    'use strict';\n\n    return function (config) {\n        window.cspNonce = config.nonce;\n    };\n});\n","Goyard_Xsearch/js/wrapper.js":"define([\n    'jquery',\n    'ko',\n    'amsearch_helpers',\n    'Amasty_Xsearch/js/wrapper'\n], function ($, ko, helpers, wrapperComponent) {\n    'use strict';\n\n    return wrapperComponent.extend({\n        /**\n         * init Input functionality\n         *\n         * @private\n         * @returns {void}\n         */\n        _initInput: function () {\n            this.readyForSearch = ko.computed(function () {\n                return this.inputValue().length >= this.data.minChars;\n            }.bind(this));\n\n            this.inputValue\n                .extend({\n                    rateLimit: {\n                        method: 'notifyWhenChangesStop',\n                        timeout: this.data.delay\n                    }\n                })\n                .subscribe(function (value) {\n                    var isSearch = value.length >= this.data.minChars,\n                        strippedValue = helpers.stripTags(value);\n\n                    if (isSearch && strippedValue) {\n                        this.inputValue.silentUpdate(strippedValue);\n\n                        return false;\n                    }\n\n                    this.message(false);\n\n                    if (isSearch) {\n                        this.searchProcess(value);\n                    } else {\n                        this.searchItems.removeAll();\n                        this.searchProducts(false);\n                        this.match(false);\n                        $('.searchbar-results .searchbar-news').css('visibility', 'visible');\n                        $('.searchbar-suggestions').removeAttr('inert');\n                        $('.searchbar-category-item:not(.searchbar-category-item-default)').remove();\n                        $('.searchbar-category-item-default').show();\n                    }\n                }.bind(this));\n        },\n        /**\n         * Parsing data from search request\n         *\n         * @private\n         * @param {Object} data\n         * @return {void}
2\n         */\n        _parseSearchData: function (data) {\n\n            var searchItems = [];\n\n            Object.keys(data).forEach(function (key) {\n                if (data[key].type === 'product') {\n                    if (!$.parseHTML(data[key].html.trim()).length) {\n                        this.searchProducts(false);\n                        this.message(this.messages.emptyProductSearch.replace('%search_query%', this.inputValue()));\n                        $('.searchbar-results .searchbar-news').css('visibility', 'visible');\n                        $('.searchbar-suggestions').removeAttr('inert');\n                    } else {\n                        this.searchProducts(data[key].html);\n                        if ($(data[key].html).find('.product-item').length) {\n                            $('.searchbar-suggestions').attr('inert', '');\n                        } else {\n                            $('.searchbar-suggestions').removeAttr('inert');\n                        }\n                        $('.searchbar-results .searchbar-news').css('visibility', 'hidden');\n                    }\n\n                    return;\n                }\n\n                if (data[key].type === 'category') {\n                    $('.searchbar-category-item:not(.searchbar-category-item-default)').remove();\n                    $('.searchbar-category-item-default').hide();\n\n                    /*if (data[key].html.trim().length) {\n                        $('.searchbar-category-items').append(data[key].html)\n\n                        // Then remove duplicate line\n                        $('.searchbar-category-items .searchbar-category-item:visible').each(function(){\n                            let cat_id = $(this).data('categoryId');\n                            if($('.searchbar-category-items .searchbar-category-item[data-category-id=\"'+cat_id+'\"]:visible').length > 1)\n                            {\n                                $('.searchbar-category-items .searchbar-category-item[data-category-id=\"'+cat_id+'\"]:visible').not('.force-visible').remove();\n                            }\n                        });\n                    }*/\n                }\n\n                if (data[key].html === undefined || data[key].html.length <= 1) {\n                    return;\n                }\n\n                searchItems.push(data[key]);\n            }.bind(this));\n\n            this.searchItems(searchItems);\n        }\n    })\n})","Goyard_Xsearch/js/products-categories.js":"define([\n\t'jquery',\n\t'matchMedia',\n\t'domReady!'\n], function ($) {\n\treturn function (config) {\n\t\tvar categoryIds = config.categoryIds;\n\t\tvar query = config.query;\n\n\t\t// Filter category list with array of ids\n\t\tfunction entry() {\n\n\t\t\tlet categoryIdsArray = categoryIds.split(',');\n\n\t\t\t$('.searchbar-category-items .searchbar-category-item').each(function () {\n\t\t\t\tif (categoryIdsArray.length > 0) {\n\t\t\t\t\tif (categoryIdsArray.includes(\"\" + $(this).data('categoryId'))) {\n\t\t\t\t\t\tif (!$(this).is(\":visible\")) {\n\t\t\t\t\t\t\t$(this).addClass('force-visible').fadeIn();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ($(this).is(\":visible\")) {\n\t\t\t\t\t\t\t$(this).removeClass('force-visible').fadeOut();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (!$(this).is(\":visible\")) {\n\t\t\t\t\t\t$(this).removeClass('force-visible').fadeIn();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tentry();\n\t}\n});\n","Magento_Variable/js/grid/columns/radioselect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'mage/translate',\n    'Magento_Ui/js/grid/columns/column',\n    'jquery'\n], function (_, $t, Column, jQuery) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            bodyTmpl: 'Magento_Variable/grid/cells/radioselect',\n            draggable: false,\n            sortable: false,\n            selectedVariableCode: null,\n            selectedVariableType: null\n        },\n\n        /**\n         * Calls 'initObservable' of parent\n         *\n         * @returns {Object}
2 Chainable.\n         */\n        initObservable: function () {\n            this._super().observe(['selectedVariableCode']);\n\n            return this;\n        },\n\n        /**\n         * Remove disable class from Insert Variable button after Variable has been chosen.\n         *\n         * @return {Boolean}\n         */\n        selectVariable: function () {\n            if (jQuery('#insert_variable').hasClass('disabled')) {\n                jQuery('#insert_variable').removeClass('disabled');\n            }\n\n            return true;\n        }\n    });\n});\n","Magento_PageCache/js/form-key-provider.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine(function () {\n    'use strict';\n\n    return function (settings) {\n        var formKey,\n            inputElements,\n            inputSelector = 'input[name=\"form_key\"]';\n\n        /**\n         * Set form_key cookie\n         * @private\n         */\n        function setFormKeyCookie(value) {\n            var expires,\n                secure,\n                date = new Date(),\n                cookiesConfig = window.cookiesConfig || {},\n                isSecure = !!cookiesConfig.secure,\n                samesite = cookiesConfig.samesite || 'lax';\n\n            date.setTime(date.getTime() + 86400000);\n            expires = '; expires=' + date.toUTCString();\n            secure = isSecure ? '; secure' : '';\n            samesite = '; samesite=' + samesite;\n\n            document.cookie = 'form_key=' + (value || '') + expires + secure + '; path=/' + samesite;\n        }\n\n        /**\n         * Retrieves form key from cookie\n         * @private\n         */\n        function getFormKeyCookie() {\n            var cookie,\n                i,\n                nameEQ = 'form_key=',\n                cookieArr = document.cookie.split(';');\n\n            for (i = 0; i < cookieArr.length; i++) {\n                cookie = cookieArr[i];\n\n                while (cookie.charAt(0) === ' ') {\n                    cookie = cookie.substring(1, cookie.length);\n                }\n\n                if (cookie.indexOf(nameEQ) === 0) {\n                    return cookie.substring(nameEQ.length, cookie.length);\n                }\n            }\n\n            return null;\n        }\n\n        /**\n         * Get form key from UI input hidden\n         * @private\n         */\n        function getFormKeyFromUI() {\n            return document.querySelector(inputSelector).value;\n        }\n\n        /**\n         * Generate form key string\n         * @private\n         */\n        function generateFormKeyString() {\n            var result = '',\n                length = 16,\n                chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n\n            while (length--) {\n                result += chars[Math.round(Math.random() * (chars.length - 1))];\n            }\n\n            return result;\n        }\n\n        /**\n         * Init form_key inputs with value\n         * @private\n         */\n        function initFormKey() {\n            formKey = getFormKeyCookie();\n\n            if (settings && settings.isPaginationCacheEnabled && !formKey) {\n                formKey = getFormKeyFromUI();\n                setFormKeyCookie(formKey);\n            }\n\n            if (!formKey) {\n                formKey = generateFormKeyString();\n                setFormKeyCookie(formKey);\n            }\n            inputElements = document.querySelectorAll(inputSelector);\n\n            if (inputElements.length) {\n                Array.prototype.forEach.call(inputElements, function (element) {\n                    element.setAttribute('value', formKey);\n                });\n            }\n        }\n\n        initFormKey();\n    };\n});\n","Magento_PageCache/js/page-cache.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'domReady',\n    'consoleLogger',\n    'Magento_PageCache/js/form-key-provider',\n    'jquery-ui-modules/widget',\n    'mage/cookies'\n], function ($, domReady, consoleLogger, formKeyInit) {\n    'use strict';\n\n    /**\n     * Helper. Generate random string\n     * TODO: Merge with mage/utils\n     * @param {String} chars - list of symbols\n     * @param {Number} length - length for need string\n     * @returns {String}\n     */\n    function generateRandomString(chars, length) {\n        var result = '';\n\n        length = length > 0 ? length : 1;\n\n        while (length--) {\n            result += chars[Math.round(Math.random() * (chars.length - 1))];\n        }\n\n        return result;\n    }\n\n    /**\n     * Nodes tree to flat list converter\n     * @returns {Array}\n     */\n    $.fn.comments = function () {\n        var elements = [],\n            contents,\n            elementContents;\n\n        /**\n         * @param {jQuery} element - Comment holder\n         */\n        (function lookup(element) {\n            var iframeHostName;\n\n            // prevent cross origin iframe content reading\n            if ($(element).prop('tagName') === 'IFRAME') {\n                iframeHostName = $('<a>').prop('href', $(element).prop('src'))\n                    .prop('hostname');\n\n                if (window.location.hostname !== iframeHostName) {\n                    return [];\n                }\n            }\n\n            /**\n             * Rewrite jQuery contents().\n             *\n             * @param {jQuery} elem\n             */\n            contents = function (elem) {\n                return $.map(elem, function (el) {\n                    try {\n                        return el.nodeName.toLowerCase() === 'iframe' ?\
2n                            el.contentDocument || (el.contentWindow ? el.contentWindow.document : []) :\n                            $.merge([], el.childNodes);\n                    } catch (e) {\n                        consoleLogger.error(e);\n\n                        return [];\n                    }\n                });\n            };\n\n            elementContents = contents($(element));\n\n            $.each(elementContents, function (index, el) {\n                switch (el.nodeType) {\n                    case 1: // ELEMENT_NODE\n                        lookup(el);\n                        break;\n\n                    case 8: // COMMENT_NODE\n                        elements.push(el);\n                        break;\n\n                    case 9: // DOCUMENT_NODE\n                        lookup($(el).find('body'));\n                        break;\n                }\n            });\n        })(this);\n\n        return elements;\n    };\n\n    /**\n     * FormKey Widget - this widget is generating from key, saves it to cookie and\n     * @deprecated see Magento/PageCache/view/frontend/web/js/form-key-provider.js\n     */\n    $.widget('mage.formKey', {\n        options: {\n            inputSelector: 'input[name=\"form_key\"]',\n            allowedCharacters: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',\n            length: 16\n        },\n\n        /**\n         * Creates widget 'mage.formKey'\n         * @private\n         */\n        _create: function () {\n            var formKey = $.mage.cookies.get('form_key'),\n                options = {\n                    secure: window.cookiesConfig ? window.cookiesConfig.secure : false\n                };\n\n            if (!formKey) {\n                formKey = generateRandomString(this.options.allowedCharacters, this.options.length);\n                $.mage.cookies.set('form_key', formKey, options);\n            }\n            $(this.options.inputSelector).val(formKey);\n        }\n    });\n\n    /**\n     * PageCache Widget\n     * Handles additional ajax request for rendering user private content.\n     */\n    $.widget('mage.pageCache', {\n        options: {\n            url: '/',\n            patternPlaceholderOpen: /^ BLOCK (.+) $/,\n            patternPlaceholderClose: /^ \\/BLOCK (.+) $/,\n            versionCookieName: 'private_content_version',\n            handles: []\n        },\n\n        /**\n         * Creates widget 'mage.pageCache'\n         * @private\n         */\n        _create: function () {\n            var placeholders,\n                version = $.mage.cookies.get(this.options.versionCookieName);\n\n            if (!version) {\n                return;\n            }\n            placeholders = this._searchPlaceholders(this.element.comments());\n\n            if (placeholders && placeholders.length) {\n                this._ajax(placeholders, version);\n            }\n        },\n\n        /**\n         * Parse page for placeholders.\n         * @param {Array} elements\n         * @returns {Array}\n         * @private\n         */\n        _searchPlaceholders: function (elements) {\n            var placeholders = [],\n                tmp = {},\n                ii,\n                len,\n                el, matches, name;\n\n            if (!(elements && elements.length)) {\n                return placeholders;\n            }\n\n            for (ii = 0, len = elements.length; ii < len; ii++) {\n                el = elements[ii];\n                matches = this.options.patternPlaceholderOpen.exec(el.nodeValue);\n                name = null;\n\n                if (matches) {\n                    name = matches[1];\n                    tmp[name] = {\n                        name: name,\n                        openElement: el\n                    };\n                } else {\n                    matches = this.options.patternPlaceholderClose.exec(el.nodeValue);\n\n                    if (matches) { //eslint-disable-line max-depth\n                        name = matches[1];\n\n                        if (tmp[name]) { //eslint-disable-line max-depth\n                            tmp[name].closeElement = el;\n                            placeholders.push(tmp[name]);\n                            delete tmp[name];\n                        }\n                    }\n                }\n            }\n\n            return placeholders;\n        },\n\n        /**\n         * Parse for page and replace placeholders\n         * @param {Object} placeholder\n         * @param {Object} html\n         * @protected\n         */\n        _replacePlaceholder: function (placeholder, html) {\n            var startReplacing = false,\n                prevSibling = null,\n                parent, contents, yy, len, element;\n\n            if (!placeholder || !html) {\n                return;\n            }\n\n            parent = $(placeholder.openElement).parent();\n            contents = parent.contents();\n\n            for (yy = 0, len = contents.length; yy < len; yy++) {\n                element = contents[yy];\n\n                if (element == placeholder.openElement) { //eslint-disable-line eqeqeq\n                    startReplacing = true;\n                }\n\n                if (startReplacing) {\n                    $(element).remove();\n                } else if (element.nodeType != 8) { //eslint-disable-line eqeqeq\n                    //due to comment tag doesn't have siblings we try to find it manually\n                    prevSibling = element;\n                }\n\n                if (element == placeholder.closeElement) { //eslint-disable-line eqeqeq\n                    break;\n                }\n            }\n\n            if (prevSibling) {\n                $(prevSibling).after(html);\n            } else {\n                $(parent).prepend(html);\n            }\n\n            // trigger event to use mage-data-init attribute\n            $(parent).trigger('contentUpdated');\n        },\n\n        /**\n         * AJAX helper\n         * @param {Object} placeholders\n         * @param {String} version\n         * @private\n         */\n        _ajax: function (placeholders, version) {\n            var ii,\n                data = {\n                    blocks: [],\n                    handles: this.options.handles,\n                    originalRequest: this.options.originalRequest,\n                    version: version\n                };\n\n            for (ii = 0; ii < placeholders.length; ii++) {\n                data.blocks.push(placeholders[ii].name);\n            }\n            data.blocks = JSON.stringify(data.blocks.sort());\n            data.handles = JSON.stringify(data.handles);\n            data.originalRequest = JSON.stringify(data.originalRequest);\n            $.ajax({\n                url: this.options.url,\n                data: data,\n                type: 'GET',\n                cache: true,\n                dataType: 'json',\n                context: this,\n\n                /**\n                 * Response handler\n                 * @param {Object} response\n                 */\n                success: function (response) {\n                    var placeholder, i;\n\n                    for (i = 0; i < placeholders.length;
2 i++) {\n                        placeholder = placeholders[i];\n\n                        if (response.hasOwnProperty(placeholder.name)) {\n                            this._replacePlaceholder(placeholder, response[placeholder.name]);\n                        }\n                    }\n                }\n            });\n        }\n    });\n\n    domReady(function () {\n        formKeyInit();\n    });\n\n    return {\n        'pageCache': $.mage.pageCache,\n        'formKey': $.mage.formKey\n    };\n});\n","Goyard_Cms/js/pre-header.js":"/**\n * Copyright Goyard TE\n * @author Technology-everywhere\n * @author Sebastien GILBERT <[email protected]>\n * @copyright Technology-Everywhere\n */\n\n// search : $('body').hasClass('pre-header-active') in the code to know where we use it\ndefine([\n    \"jquery\",\n    'mage/template',\n    'jquery-ui-modules/widget',\n    'mage/translate'\n], function ($) {\n    (\"use strict\");\n\n    $.widget(\"mage.preheader\", {\n        options: {\n        },\n        _create: function () {\n            var self = this;\n            // Initialize html element\n            $(document).ready(function () {\n                let preheader_closed = self.getPreheaderClosed();\n                if (preheader_closed) {\n                    if (preheader_closed.closed) {\n                        $('.preheader-wrapper').remove();\n                        return;\n                    }\n                }\n\n                if ($('.preheader-wrapper').length > 0 && $(document).scrollTop() === 0) {\n                    // Init preheader display :\n                    $('.preheader-wrapper').addClass('initialized').css({\n                        'position': 'fixed'\n                    });\n                    self.adjustToPreheader();\n                }\n                self.createAndPlaceCross(self);\n\n                // Add data attribute to preheader for automatisation\n                $('.preheader-wrapper .pre-header').attr('data-testid', 'preheader-div');\n\n                $('.action.nav-toggle').on('click keydown', function (e) {\n                    if (e.type === 'click' || e.type === 'keydown' && ((e.which === 13 || e.keyCode === 13) || (e.which === 32 || e.keyCode === 32))) {\n                        e.preventDefault();\n                        if ($(window).width() < 768) {\n                            if ($(\"html\").hasClass(\"nav-before-open nav-open\")) {\n                                self.unShowPreHeader();\n                            } else {\n                                if (!$('.preheader-wrapper').hasClass('initialized')) {\n                                    $('.preheader-wrapper').addClass('initialized');\n                                    $('.preheader-wrapper').css('display', 'block');\n                                };\n                                self.adjustToPreheader();\n                            }\n                        }\n                    }\n                });\n                $('.toggle-search').on('click', function () {\n                    if ($(window).width() < 768) {\n                        if ($(\"body\").hasClass(\"search-form-opened\")) {\n                            self.unShowPreHeader();\n                        } else if ($(window).scrollTop() > 0) {\n                            self.unShowPreHeader();\n                        } else {\n                            if (!$('.preheader-wrapper').hasClass('initialized')) {\n                                $('.preheader-wrapper').addClass('initialized');\n                                $('.preheader-wrapper').css('display', 'block');\n                            };\n                            self.adjustToPreheader();\n                        }\n                    }\n                });\n\n                $(document).on(\"show-wishlist-popup\", function (event) {\n                    self.adjustToPreheader();\n                });\n            });\n\n            //PUBLIC function for external use\n            this._on(this.element, {\n                'adjustToPreheader': this.adjustToPreheader,\n                'unShowPreHeader': this.unShowPreHeader\n            });\n        },\n\n        createAndPlaceCross: function (self) {\n            // Cross to disable pre header + data attribute for automatisation\n            const html = '<div id=\"no-pre-header\" aria-role=\"button\" aria-label=\"' + $.mage.__('Close pre-header') + '\" tabindex=\"0\" data-testid=\"preheader-close-div\">X</div>';\n            const textElement = $('.preheader-wrapper').find('div[data-content-type=\"text\"]');\n            // recovers the same color as the text for the cross\n            const color = textElement.find('span').css('color');\n            $(html).appendTo($('.preheader-wrapper'));\n\n            // CSS for cross\n            $('#no-pre-header').css({\n                \"position\": \"absolute\",\n                \"color\": color,\n                \"right\": \"5px\",\n                \"font-family\": \"'Goyard', sans-serif\",\n                \"padding\": \"2px 5px\",\n                \"top\": \"50%\",\n                \"cursor\": \"pointer\",\n                \"transform\": \"translateY(-50%)\"\n            });
2\n\n            function handleNoPreHeaderClick() {\n                self.adjustToPreheader();\n                self.unShowPreHeader();\n                $('.preheader-wrapper').remove();\n                self.savePreheaderClosed();\n            }\n            $('#no-pre-header').on('click', handleNoPreHeaderClick);\n\n            $(\"#no-pre-header\").on('keydown', function (event) {\n                if (event.key === 'Enter' || event.code === 'Enter' || event.which === 13) {\n                    handleNoPreHeaderClick();\n                }\n            });\n        },\n\n        // register in local storage\n        savePreheaderClosed: function (name, value) {\n            const now = new Date();\n            const item = {\n                value: value,\n                closed: true,\n                expiry: now.getTime() + (24 * 60 * 60 * 1000)\n            };\n            localStorage.setItem('goyard_preheader_closed', JSON.stringify(item));\n        },\n\n        // get info from local storage\n        getPreheaderClosed: function (name) {\n            const preHeadClosedItem = localStorage.getItem('goyard_preheader_closed');\n\n            if (!preHeadClosedItem) {\n                return null;\n            }\n\n            const itemParsed = JSON.parse(preHeadClosedItem);\n            const now = new Date();\n            if (now.getTime() > itemParsed.expiry) {\n                localStorage.removeItem('goyard_preheader_closed');\n                return null;\n            }\n            return itemParsed;\n        },\n\n        adjustToPreheader: function () {\n            let preheader_closed = this.getPreheaderClosed();\n            if (!preheader_closed || (preheader_closed && !preheader_closed.closed)) {\n                let preheaderHeight = $('.preheader-wrapper').length ? $('.preheader-wrapper').height() : 0;\n                let pageHeaderHeight = $('.page-header').height();\n                let navBarHeight = $('.nav-sections').height();\n\n                $('.page-header').css({\n                    'top': preheaderHeight.toString() + 'px',\n                    'transition': '0s'\n                });\n                $('.nav-sections').css({\n                    'top': (preheaderHeight + pageHeaderHeight).toString() + 'px',\n                    'transform': $('.nav-sections').hasClass('opaque-nav-sections') ? 'none' : 'none',\n                });\n                $('.megamenu-dropdown').css('top', (preheaderHeight + pageHeaderHeight + navBarHeight).toString() + 'px');\n                $('.searchBar-root_open-hxZ').css('top', (preheaderHeight + pageHeaderHeight).toString() + 'px');\n                $('.page-wrapper.page-main.column.main').css('padding-top', (preheaderHeight + pageHeaderHeight + navBarHeight).toString() + 'px');\n                $('body.cms-index-index #maincontent .page.messages .messages .message').attr(\"margin-top\", (preheaderHeight) + \"px !important\");\n                $('#wishlist-popup').css(\"padding-top\", (preheaderHeight).toString() + 'px');\n\n                if (!$('body').hasClass('cms-index-index') && !$('body').hasClass('page-layout-1column-transparent-header')) {\n                    var dynamicPaddingPre = 0;\n                    dynamicPaddingPre = preheaderHeight;\n\n                    if ($('body[class^=\"customer-\"]').length > 0 || $('body[class^=\"accountmanager-\"]').length > 0 || $('body').hasClass('account')) {\n                        $('.breadcrumbs').addClass(\"padding-preheader-calculate\");\n                    } else {\n                        if ($(window).width() < 768) {\n                            dynamicPaddingPre = preheaderHeight + pageHeaderHeight;\n                            $('#maincontent').addClass(\"padding-preheader-calculate\");\n                        } else {\n                            dynamicPaddingPre = preheaderHeight + pageHeaderHeight + navBarHeight;\n                            $('#maincontent').addClass(\"padding-preheader-calculate\");\n                        }\n                    }\n\n                    document.documentElement.style.setProperty('--dynamic-padding-top', dynamicPaddingPre + \"px\");\n                }\n\n                $('.block-right').each(function (index, element) {\n                    $(element).css('top', (preheaderHeight + 140).toString() + 'px');\n                })\n            }\n        },\n\n        unShowPreHeader: function () {\n            $('.preheader-wrapper').removeClass('initialized');\n            $('.preheader-wrapper').css('display', 'none');\n            $('div.page-wrapper .breadcrumbs').removeClass(\"padding-preheader-calculate\");\n            $('#wishlist-popup').css(\"padding-top\", '0' + 'px');\n            $('.page.messages .messages .message').removeClass(\"padding-preheader-calculate\")\n            $('.page-main').removeClass(\"padding-preheader-calculate\");\n            $('.nav-sections').removeAttr('style');\n            $('.page-header').removeAttr('style');\n            $('.megamenu-dropdown').removeAttr('style');\n            $('.searchBar-root_open-hxZ').removeAttr('style');\n\n            $('.block-right').each(function (element) {\n                $(element).removeAttr('style');\n            })\n        }\n    });\n    return $.mage.preheader;\n});","Goyard_Cms/js/footer_links.js":"require([\n\t\"jquery\",\n\t'Magento_Customer/js/customer-data',\n], function ($, customerData) {\n\t$(document).ready(function () {\n\t\t//Accessibility for \"Co
2okies\" link - work with didomi code\n\t\tdocument.addEventListener('keydown', function (e) {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tif (!$('body').hasClass('_keyfocus')) {\n\t\t\t\t\t$('body').addClass('_keyfocus');\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t$(document).on('keydown', '.footer-button', function (event) {\n\t\t\tif (event.type === 'keydown' && event.keyCode === 32) {\n\t\t\t\t$(this)[0].click();\n\t\t\t}\n\t\t});\n\n\t\tdisplayEmptyCartMsg()\n\n\t\tfunction displayEmptyCartMsg() {\n\t\t\treturn new Promise(function (resolve, reject) {\n\t\t\t\tlet customer = customerData.get('customer');\n\t\t\t\tlet firstname = customer().firstname;\n\t\t\t\tif (firstname) {\n\t\t\t\t\tresolve();\n\t\t\t\t\t$('.footer-item.hidden').removeClass('hidden');\n\t\t\t\t} else {\n\t\t\t\t\tcustomer.subscribe(function () {\n\t\t\t\t\t\tif (customer().firstname) {\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t$('.footer-item.hidden').removeClass('hidden');\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$('.footer-item.hidden').remove();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t})\n});","Goyard_Cms/js/content-type/slider/appearance/default/widget.js":"/**\r\n * Copyright \u00a9 Magento, Inc. All rights reserved.\r\n * See COPYING.txt for license details.\r\n */\r\n\r\ndefine([\r\n    'jquery',\r\n    'Magento_PageBuilder/js/events',\r\n    'slick',\r\n    'mage/translate'\r\n], function ($, events) {\r\n    'use strict';\r\n    return function (config, sliderElement) {\r\n        var $element = $(sliderElement);\r\n        /**\r\n         * Prevent each slick slider from being initialized more than once which could throw an error.\r\n         */\r\n        if ($element.hasClass('slick-initialized')) {\r\n            $element.slick('unslick');\r\n        }\r\n        $element.slick({\r\n            slidesToShow: $element.data('slide-to-show') || 1,\r\n            centerMode: $element.data('center-mode') || false,\r\n            centerPadding: '20%',\r\n            autoplay: $element.data('autoplay'),\r\n            autoplaySpeed: $element.data('autoplay-speed') || 0,\r\n            fade: $element.data('fade'),\r\n            infinite: $element.data('infinite-loop'),\r\n            arrows: $element.data('show-arrows'),\r\n            dots: $element.data('show-dots'),\r\n            prevArrow: '<button type=\"button\" class=\"slick-prev\" aria-label=\"'+$.mage.__('See the previous boutique')+'\"></button>',\r\n            nextArrow: '<button type=\"button\" class=\"slick-next\"  aria-label=\"'+$.mage.__('See the next boutique')+'\"></button>',\r\n            responsive: [\r\n                {\r\n                  breakpoint: 1500,\r\n                  settings: {\r\n                    centerMode: $element.data('center-mode') || false,\r\n                    centerPadding: '19%'\r\n                  }\r\n                },\r\n                {\r\n                  breakpoint: 1280,\r\n                  settings: {\r\n                    centerMode: $element.data('center-mode') || false,\r\n                    centerPadding: '17%'\r\n                  }\r\n                },\r\n                {\r\n                  breakpoint: 1024,\r\n                  settings: {\r\n                    centerMode: $element.data('center-mode-mobile') || false,\r\n                    centerPadding: '50px',\r\n                    slidesToShow: $element.data('slide-to-show-mobile') || 1,\r\n                    dots: $element.data('show-dots-mobile'),\r\n                    arrows: $element.data('show-arrows-mobile')\r\n                  }\r\n                }\r\n            ]\r\n        });\r\n\r\n        // Redraw slide after content type gets redrawn\r\n        events.on('contentType:redrawAfter', function (args) {\r\n            if ($element.closest(args.element).length) {\r\n                $element.slick('setPosition');\r\n            }\r\n        });\r\n        // eslint-disable-next-line jquery-no-bind-unbind\r\n        events.on('stage:viewportChangeAfter', $element.slick.bind($element, 'setPosition'));\r\n\r\n        $('.color-wrapper').click(function(e) {\r\n          e.stopPropagation();\r\n          $(\".product-items\").find(\".color-label\").css(\"display\", \"block\");\r\n          $(\".product-items\").find(\".color-detail\").css(\"display\", \"none\");\r\n          $(this).find(\".color-label\").css(\"display\", \"none\");\r\n          $(this).find(\".color-detail\").css(\"display\", \"block\");\r\n        });\r\n    };\r\n});\r\n","Goyard_Cms/js/widget/language_form.js":"/**\r\n * Copyright Goyard TE\r\n * @author Technology-everywhere\r\n */\r\nrequire([\r\n    'jquery',\r\n    'underscore',\r\n    'mage/translate',\r\n    'Magento_Ui/js/modal/modal'\r\n],\r\n    function ($, _, $t, modal) {\r\n        'use strict';\r\n\r\n        $(document).ready(function () {\r\n           \r\n        \tlet element = $('[data-content-type=\"language_form\"]');\r\n        \t\r\n        \t// Used for declari\r\n        \tconst language_translation_array = [\r\n                $.mage.__('Language name fr'),\r\n                $.mage.__('Language name en'),\r\n                $.mage.__('Language name jp'),\r\n                $.mage.__('Language name kr'),\r\n                $.mage.__('Language name ko'),\r\n                $.mage.__('Language name zh')\r\n            ];\r\n        \t\r\n        \tif(element.length > 0)\r\n    \t\t{\r\n\t\t\t\tlet dropdown_label = '<label for=\"crm-language_form-select\" class=\"title\">'+ $.mage.__('Choose the language') +'</label>';\r\n        \t\tlet dropdown = '<select id=\"crm-language_form-select\" class=\"language_form-select\">';
2   \r\n        \t\t\r\n        \t\t// Loop on allowed language\r\n        \t\tlet default_language = element.data('default_language');\r\n        \t\tlet allowed_language = element.data('allowed_language');\r\n        \t\t\r\n        \t\tlet json_url_config = element.data('url_configuration');\r\n        \t\tlet allowed_language_array = allowed_language.split(',');\r\n        \t\t\r\n        \t\tfor (const allowed_lang of allowed_language_array) {\t\t\t\t\r\n\t\t\t\t\tif(default_language == allowed_lang)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tdropdown = dropdown + '<option value=\"'+json_url_config[allowed_lang]+'\" selected=\"selected\">' + $.mage.__('Language name '+allowed_lang) + '</option>';\r\n\t\t\t\t\t}else{\r\n\t\t\t\t\t\tdropdown = dropdown + '<option value=\"'+json_url_config[allowed_lang]+'\">' + $.mage.__('Language name '+allowed_lang) + '</option>';\t\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t}\r\n\t\t\t\t        \t\t\r\n        \t\tdropdown = dropdown + '</select>'; \r\n        \t\telement.append(dropdown_label);        \t\t\r\n        \t\telement.append(dropdown);\r\n        \t\t\r\n\t            let target_iframe = $('#' + element.data('targetIframe'));\t            \r\n\t            var target_lang = \"\";\t            \r\n\t            \r\n\t            element.find('select').on('change',function(){\r\n\t            \ttarget_lang = $(this).val();\r\n\t            \t\r\n\t            \tvar queryString = window.top.location.search; \t            \t\r\n\t            \tlet target_url = target_lang + queryString;\r\n\t            \t\r\n\t            \twindow.location.href = target_url;\r\n\t            });\r\n\t            \r\n        \t}\r\n        })\r\n    }\r\n);","Magento_Cookie/js/notices.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget',\n    'mage/cookies'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.cookieNotices', {\n        /** @inheritdoc */\n        _create: function () {\n            if ($.mage.cookies.get(this.options.cookieName)) {\n                this.element.hide();\n            } else {\n                this.element.show();\n            }\n            $(this.options.cookieAllowButtonSelector).on('click', $.proxy(function () {\n                var cookieExpires = new Date(new Date().getTime() + this.options.cookieLifetime * 1000);\n\n                $.mage.cookies.set(this.options.cookieName, JSON.stringify(this.options.cookieValue), {\n                    expires: cookieExpires\n                });\n\n                if ($.mage.cookies.get(this.options.cookieName)) {\n                    this.element.hide();\n                    $(document).trigger('user:allowed:save:cookie');\n                } else {\n                    window.location.href = this.options.noCookiesUrl;\n                }\n            }, this));\n        }\n    });\n\n    return $.mage.cookieNotices;\n});\n","Magento_Cookie/js/require-cookie.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'Magento_Ui/js/modal/alert',\n    'jquery-ui-modules/widget',\n    'mage/mage',\n    'mage/translate'\n], function ($, alert) {\n    'use strict';\n\n    $.widget('mage.requireCookie', {\n        options: {\n            event: 'click',\n            noCookieUrl: 'enable-cookies',\n            triggers: ['.action.login', '.action.submit'],\n            isRedirectCmsPage: true\n        },\n\n        /**\n         * Constructor\n         * @private\n         */\n        _create: function () {\n            this._bind();\n        },\n\n        /**\n         * This method binds elements found in this widget.\n         * @private\n         */\n        _bind: function () {\n            var events = {};\n\n            $.each(this.options.triggers, function (index, value) {\n                events['click ' + value] = '_checkCookie';\n            });\n            this._on(events);\n        },\n\n        /**\n         * This method set the url for the redirect.\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _checkCookie: function (event) {\n            if (navigator.cookieEnabled) {\n                return;\n            }\n\n            event.preventDefault();\n\n            if (this.options.isRedirectCmsPage) {\n                window.location = this.options.noCookieUrl;\n            } else {\n                alert({\n                    content: $.mage.__('Cookies are disabled in your browser.')\n                });\n            }\n        }\n    });\n\n    return $.mage.requireCookie;\n});\n","js-storage/js.storage.js":"/*\n * JS Storage Plugin\n *\n * Copyright (c) 2019 Julien Maurel\n *\n * 
2Licensed under the MIT license:\n * http://www.opensource.org/licenses/mit-license.php\n *\n * Project home:\n * https://github.com/julien-maurel/js-storage\n *\n * Version: 1.1.0\n */\n(function (factory) {\n    var registeredInModuleLoader = false;\n    if (typeof define === 'function' && define.amd) {\n        define(['jquery', 'jquery/jquery.cookie'], factory);\n        registeredInModuleLoader = true;\n    }\n    if (typeof exports === 'object') {\n        module.exports = factory();\n        registeredInModuleLoader = true;\n    }\n    if (!registeredInModuleLoader) {\n        var OldStorages = window.Storages;\n        var api = window.Storages = factory();\n        api.noConflict = function () {\n            window.Storages = OldStorages;\n            return api;\n        };\n    }\n}(function () {\n    // Variables used by utilities functions (like isPlainObject...)\n    var class2type = {};\n    var toString = class2type.toString;\n    var hasOwn = class2type.hasOwnProperty;\n    var fnToString = hasOwn.toString;\n    var ObjectFunctionString = fnToString.call(Object);\n    var getProto = Object.getPrototypeOf;\n    var apis = {};\n\n    // Prefix to use with cookie fallback\n    var cookie_local_prefix = \"ls_\";\n    var cookie_session_prefix = \"ss_\";\n\n    // Get items from a storage\n    function _get() {\n        var storage = this._type, l = arguments.length, s = window[storage], a = arguments, a0 = a[0], vi, ret, tmp, i, j;\n        if (l < 1) {\n            throw new Error('Minimum 1 argument must be given');\n        } else if (Array.isArray(a0)) {\n            // If second argument is an array, return an object with value of storage for each item in this array\n            ret = {};\n            for (i in a0) {\n                if (a0.hasOwnProperty(i)) {\n                    vi = a0[i];\n                    try {\n                        ret[vi] = JSON.parse(s.getItem(vi));\n                    } catch (e) {\n                        ret[vi] = s.getItem(vi);\n                    }\n                }\n            }\n            return ret;\n        } else if (l == 1) {\n            // If only 1 argument, return value directly\n            try {\n                return JSON.parse(s.getItem(a0));\n            } catch (e) {\n                return s.getItem(a0);\n            }\n        } else {\n            // If more than 1 argument, parse storage to retrieve final value to return it\n            // Get first level\n            try {\n                ret = JSON.parse(s.getItem(a0));\n                if (!ret) {\n                    throw new ReferenceError(a0 + ' is not defined in this storage');\n                }\n            } catch (e) {\n                throw new ReferenceError(a0 + ' is not defined in this storage');\n            }\n            // Parse next levels\n            for (i = 1; i < l - 1; i++) {\n                ret = ret[a[i]];\n                if (ret === undefined) {\n                    throw new ReferenceError([].slice.call(a, 0, i + 1).join('.') + ' is not defined in this storage');\n                }\n            }\n            // If last argument is an array, return an object with value for each item in this array\n            // Else return value normally\n            if (Array.isArray(a[i])) {\n                tmp = ret;\n                ret = {};\n                for (j in a[i]) {\n                    if (a[i].hasOwnProperty(j)) {\n                        ret[a[i][j]] = tmp[a[i][j]];\n                    }\n                }\n                return ret;\n            } else {\n                return ret[a[i]];\n            }\n        }\n    }\n\n    // Set items of a storage\n    function _set() {\n        var storage = this._type, l = arguments.length, s = window[storage], a = arguments, a0 = a[0], a1 = a[1], vi, to_store = isNaN(a1) ? {} : [], type, tmp, i;\n        if (l < 1 || !_isPlainObject(a0) && l < 2) {\n            throw new Error('Minimum 2 arguments must be given or first parameter must be an object');\n        } else if (_isPlainObject(a0)) {\n            // If first argument is an object, set values of storage for each property of this object\n            for (i in a0) {\n                if (a0.hasOwnProperty(i)) {\n                    vi = a0[i];\n                    if (!_isPlainObject(vi) && !this.alwaysUseJson) {\n                        s.setItem(i, vi);\n                    } else {\n                        s.setItem(i, JSON.stringify(vi));\n                    }\n                }\n            }\n            return a0;\n        } else if (l == 2) {\n            // If only 2 arguments, set value of storage directly\n            if (typeof a1 === 'object' || this.alwaysUseJson) {\n                s.setItem(a0, JSON.stringify(a1));\n            } else {\n                s.setItem(a0, a1);\n            }\n            return a1;\n        } else {\n            // If more than 3 arguments, parse storage to retrieve final node and set value\n            // Get first level\n            try {\n                tmp = s.getItem(a0);\n                if (tmp != null) {\n                    to_store = JSON.parse(tmp);\n                }\n            } catch (e) {\n            }\n            tmp = to_store;\n            // Parse next levels and set value\n            for (i = 1; i < l - 2;
2 i++) {\n                vi = a[i];\n                type = isNaN(a[i + 1]) ? \"object\" : \"array\";\n                if (!tmp[vi] || type == \"object\" && !_isPlainObject(tmp[vi]) || type == \"array\" && !Array.isArray(tmp[vi])) {\n                    if (type == \"array\") tmp[vi] = [];\n                    else tmp[vi] = {};\n                }\n                tmp = tmp[vi];\n            }\n            tmp[a[i]] = a[i + 1];\n            s.setItem(a0, JSON.stringify(to_store));\n            return to_store;\n        }\n    }\n\n    // Remove items from a storage\n    function _remove() {\n        var storage = this._type, l = arguments.length, s = window[storage], a = arguments, a0 = a[0], to_store, tmp, i, j;\n        if (l < 1) {\n            throw new Error('Minimum 1 argument must be given');\n        } else if (Array.isArray(a0)) {\n            // If first argument is an array, remove values from storage for each item of this array\n            for (i in a0) {\n                if (a0.hasOwnProperty(i)) {\n                    s.removeItem(a0[i]);\n                }\n            }\n            return true;\n        } else if (l == 1) {\n            // If only 2 arguments, remove value from storage directly\n            s.removeItem(a0);\n            return true;\n        } else {\n            // If more than 2 arguments, parse storage to retrieve final node and remove value\n            // Get first level\n            try {\n                to_store = tmp = JSON.parse(s.getItem(a0));\n            } catch (e) {\n                throw new ReferenceError(a0 + ' is not defined in this storage');\n            }\n            // Parse next levels and remove value\n            for (i = 1; i < l - 1; i++) {\n                tmp = tmp[a[i]];\n                if (tmp === undefined) {\n                    throw new ReferenceError([].slice.call(a, 1, i).join('.') + ' is not defined in this storage');\n                }\n            }\n            // If last argument is an array,remove value for each item in this array\n            // Else remove value normally\n            if (Array.isArray(a[i])) {\n                for (j in a[i]) {\n                    if (a[i].hasOwnProperty(j)) {\n                        delete tmp[a[i][j]];\n                    }\n                }\n            } else {\n                delete tmp[a[i]];\n            }\n            s.setItem(a0, JSON.stringify(to_store));\n            return true;\n        }\n    }\n\n    // Remove all items from a storage\n    function _removeAll(reinit_ns) {\n        var keys = _keys.call(this), i;\n        for (i in keys) {\n            if (keys.hasOwnProperty(i)) {\n                _remove.call(this, keys[i]);\n            }\n        }\n        // Reinitialize all namespace storages\n        if (reinit_ns) {\n            for (i in apis.namespaceStorages) {\n                if (apis.namespaceStorages.hasOwnProperty(i)) {\n                    _createNamespace(i);\n                }\n            }\n        }\n    }\n\n    // Check if items of a storage are empty\n    function _isEmpty() {\n        var l = arguments.length, a = arguments, a0 = a[0], i;\n        if (l == 0) {\n            // If no argument, test if storage is empty\n            return (_keys.call(this).length == 0);\n        } else if (Array.isArray(a0)) {\n            // If first argument is an array, test each item of this array and return true only if all items are empty\n            for (i = 0; i < a0.length; i++) {\n                if (!_isEmpty.call(this, a0[i])) {\n                    return false;\n                }\n            }\n            return true;\n        } else {\n            // If at least 1 argument, try to get value and test it\n            try {\n                var v = _get.apply(this, arguments);\n                // Convert result to an object (if last argument is an array, _get return already an object) and test each item\n                if (!Array.isArray(a[l - 1])) {\n                    v = {'totest': v};\n                }\n                for (i in v) {\n                    if (v.hasOwnProperty(i) && !(\n                        (_isPlainObject(v[i]) && _isEmptyObject(v[i])) ||\n                        (Array.isArray(v[i]) && !v[i].length) ||\n                        (typeof v[i] !== 'boolean' && !v[i])\n                    )) {\n                        return false;\n                    }\n                }\n                return true;\n            } catch (e) {\n                return true;\n            }\n        }\n    }\n\n    // Check if items of a storage exist\n    function _isSet() {\n        var l = arguments.length, a = arguments, a0 = a[0], i;\n        if (l < 1) {\n            throw new Error('Minimum 1 argument must be given');\n        }\n        if (Array.isArray(a0)) {\n            // If first argument is an array, test each item of this array and return true only if all items exist\n            for (i = 0; i < a0.length;
2 i++) {\n                if (!_isSet.call(this, a0[i])) {\n                    return false;\n                }\n            }\n            return true;\n        } else {\n            // For other case, try to get value and test it\n            try {\n                var v = _get.apply(this, arguments);\n                // Convert result to an object (if last argument is an array, _get return already an object) and test each item\n                if (!Array.isArray(a[l - 1])) {\n                    v = {'totest': v};\n                }\n                for (i in v) {\n                    if (v.hasOwnProperty(i) && !(v[i] !== undefined && v[i] !== null)) {\n                        return false;\n                    }\n                }\n                return true;\n            } catch (e) {\n                return false;\n            }\n        }\n    }\n\n    // Get keys of a storage or of an item of the storage\n    function _keys() {\n        var storage = this._type, l = arguments.length, s = window[storage], keys = [], o = {};\n        // If at least 1 argument, get value from storage to retrieve keys\n        // Else, use storage to retrieve keys\n        if (l > 0) {\n            o = _get.apply(this, arguments);\n        } else {\n            o = s;\n        }\n        if (o && o._cookie) {\n            // If storage is a cookie, use js-cookie to retrieve keys\n            var cookies = Cookies.get();\n            for (var key in cookies) {\n                if (cookies.hasOwnProperty(key) && key != '') {\n                    keys.push(key.replace(o._prefix, ''));\n                }\n            }\n        } else {\n            for (var i in o) {\n                if (o.hasOwnProperty(i)) {\n                    keys.push(i);\n                }\n            }\n        }\n        return keys;\n    }\n\n    // Create new namespace storage\n    function _createNamespace(name) {\n        if (!name || typeof name != \"string\") {\n            throw new Error('First parameter must be a string');\n        }\n        if (storage_available) {\n            if (!window.localStorage.getItem(name)) {\n                window.localStorage.setItem(name, '{}');\n            }\n            if (!window.sessionStorage.getItem(name)) {\n                window.sessionStorage.setItem(name, '{}');\n            }\n        } else {\n            if (!window.localCookieStorage.getItem(name)) {\n                window.localCookieStorage.setItem(name, '{}');\n            }\n            if (!window.sessionCookieStorage.getItem(name)) {\n                window.sessionCookieStorage.setItem(name, '{}');\n            }\n        }\n        var ns = {\n            localStorage: _extend({}, apis.localStorage, {_ns: name}),\n            sessionStorage: _extend({}, apis.sessionStorage, {_ns: name})\n        };\n        if (cookies_available) {\n            if (!window.cookieStorage.getItem(name)) {\n                window.cookieStorage.setItem(name, '{}');\n            }\n            ns.cookieStorage = _extend({}, apis.cookieStorage, {_ns: name});\n        }\n        apis.namespaceStorages[name] = ns;\n        return ns;\n    }\n\n    // Test if storage is natively available on browser\n    function _testStorage(name) {\n        var foo = 'jsapi';\n        try {\n            if (!window[name]) {\n                return false;\n            }\n            window[name].setItem(foo, foo);\n            window[name].removeItem(foo);\n            return true;\n        } catch (e) {\n            return false;\n        }\n    }\n\n    // Test if a variable is a plain object (from jQuery)\n    function _isPlainObject(obj) {\n        var proto, Ctor;\n\n        // Detect obvious negatives\n        // Use toString instead of jQuery.type to catch host objects\n        if (!obj || toString.call(obj) !== \"[object Object]\") {\n            return false;\n        }\n\n        proto = getProto(obj);\n\n        // Objects with no prototype (e.g., `Object.create( null )`) are plain\n        if (!proto) {\n            return true;\n        }\n\n        // Objects with prototype are plain iff they were constructed by a global Object function\n        Ctor = hasOwn.call(proto, \"constructor\") && proto.constructor;\n        return typeof Ctor === \"function\" && fnToString.call(Ctor) === ObjectFunctionString;\n    }\n\n    // Test if a variable is an empty object (from jQuery)\n    function _isEmptyObject(obj) {\n        var name;\n\n        for (name in obj) {\n            return false;\n        }\n        return true;\n    }\n\n    // Merge objects\n    function _extend() {\n        var i = 1;\n        var result = arguments[0];\n        for (; i < arguments.length;
2 i++) {\n            var attributes = arguments[i];\n            for (var key in attributes) {\n                if (attributes.hasOwnProperty(key)) {\n                    result[key] = attributes[key];\n                }\n            }\n        }\n        return result;\n    }\n\n    // Check if storages are natively available on browser and check is js-cookie is present\n    var storage_available = _testStorage('localStorage');\n    var cookies_available = typeof Cookies !== 'undefined';\n\n    // Namespace object\n    var storage = {\n        _type: '',\n        _ns: '',\n        _callMethod: function (f, a) {\n            a = Array.prototype.slice.call(a);\n            var p = [], a0 = a[0];\n            if (this._ns) {\n                p.push(this._ns);\n            }\n            if (typeof a0 === 'string' && a0.indexOf('.') !== -1) {\n                a.shift();\n                [].unshift.apply(a, a0.split('.'));\n            }\n            [].push.apply(p, a);\n            return f.apply(this, p);\n        },\n        // Define if plugin always use JSON to store values (even to store simple values like string, int...) or not\n        alwaysUseJson: false,\n        // Get items. If no parameters and storage have a namespace, return all namespace\n        get: function () {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_get, arguments);\n        },\n        // Set items\n        set: function () {\n            var l = arguments.length, a = arguments, a0 = a[0];\n            if (l < 1 || !_isPlainObject(a0) && l < 2) {\n                throw new Error('Minimum 2 arguments must be given or first parameter must be an object');\n            }\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            // If first argument is an object and storage is a namespace storage, set values individually\n            if (_isPlainObject(a0) && this._ns) {\n                for (var i in a0) {\n                    if (a0.hasOwnProperty(i)) {\n                        this._callMethod(_set, [i, a0[i]]);\n                    }\n                }\n                return a0;\n            } else {\n                var r = this._callMethod(_set, a);\n                if (this._ns) {\n                    return r[a0.split('.')[0]];\n                } else {\n                    return r;\n                }\n            }\n        },\n        // Delete items\n        remove: function () {\n            if (arguments.length < 1) {\n                throw new Error('Minimum 1 argument must be given');\n            }\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_remove, arguments);\n        },\n        // Delete all items\n        removeAll: function (reinit_ns) {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            if (this._ns) {\n                this._callMethod(_set, [{}]);\n                return true;\n            } else {\n                return this._callMethod(_removeAll, [reinit_ns]);\n            }\n        },\n        // Items empty\n        isEmpty: function () {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_isEmpty, arguments);\n        },\n        // Items exists\n        isSet: function () {\n            if (arguments.length < 1) {\n                throw new Error('Minimum 1 argument must be given');\n            }\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_isSet, arguments);\n        },\n        // Get keys of items\n        keys: function () {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_keys, arguments);\n        }\n    };\n\n    // Use js-cookie for compatibility with old browsers and give access to cookieStorage\n    if (cookie
2s_available) {\n        // sessionStorage is valid for one window/tab. To simulate that with cookie, we set a name for the window and use it for the name of the cookie\n        if (!window.name) {\n            window.name = Math.floor(Math.random() * 100000000);\n        }\n        var cookie_storage = {\n            _cookie: true,\n            _prefix: '',\n            _expires: null,\n            _path: null,\n            _domain: null,\n            _secure: false,\n            setItem: function (n, v) {\n                Cookies.set(this._prefix + n, v, {expires: this._expires, path: this._path, domain: this._domain, secure: this._secure});\n            },\n            getItem: function (n) {\n                return Cookies.get(this._prefix + n);\n            },\n            removeItem: function (n) {\n                return Cookies.remove(this._prefix + n, {path: this._path});\n            },\n            clear: function () {\n                var cookies = Cookies.get();\n                for (var key in cookies) {\n                    if (cookies.hasOwnProperty(key) && key != '') {\n                        if (!this._prefix && key.indexOf(cookie_local_prefix) === -1 && key.indexOf(cookie_session_prefix) === -1 || this._prefix && key.indexOf(this._prefix) === 0) {\n                            Cookies.remove(key);\n                        }\n                    }\n                }\n            },\n            setExpires: function (e) {\n                this._expires = e;\n                return this;\n            },\n            setPath: function (p) {\n                this._path = p;\n                return this;\n            },\n            setDomain: function (d) {\n                this._domain = d;\n                return this;\n            },\n            setSecure: function (s) {\n                this._secure = s;\n                return this;\n            },\n            setConf: function (c) {\n                if (c.path) {\n                    this._path = c.path;\n                }\n                if (c.domain) {\n                    this._domain = c.domain;\n                }\n                if (c.secure) {\n                    this._secure = c.secure;\n                }\n                if (c.expires) {\n                    this._expires = c.expires;\n                }\n                return this;\n            },\n            setDefaultConf: function () {\n                this._path = this._domain = this._expires = null;\n                this._secure = false;\n            }\n        };\n        if (!storage_available) {\n            window.localCookieStorage = _extend({}, cookie_storage, {\n                _prefix: cookie_local_prefix,\n                _expires: 365 * 10,\n                _secure: true\n            });\n            window.sessionCookieStorage = _extend({}, cookie_storage, {\n                _prefix: cookie_session_prefix + window.name + '_',\n                _secure: true\n            });\n        }\n        window.cookieStorage = _extend({}, cookie_storage);\n        // cookieStorage API\n        apis.cookieStorage = _extend({}, storage, {\n            _type: 'cookieStorage',\n            setExpires: function (e) {\n                window.cookieStorage.setExpires(e);\n                return this;\n            },\n            setPath: function (p) {\n                window.cookieStorage.setPath(p);\n                return this;\n            },\n            setDomain: function (d) {\n                window.cookieStorage.setDomain(d);\n                return this;\n            },\n            setSecure: function (s) {\n                window.cookieStorage.setSecure(s);\n                return this;\n            },\n            setConf: function (c) {\n                window.cookieStorage.setConf(c);\n                return this;\n            },\n            setDefaultConf: function () {\n                window.cookieStorage.setDefaultConf();\n                return this;\n            }\n        });\n    }\n\n    // Get a new API on a namespace\n    apis.initNamespaceStorage = function (ns) {\n        return _createNamespace(ns);\n    };\n    if (storage_available) {\n        // localStorage API\n        apis.localStorage = _extend({}, storage, {_type: 'localStorage'});\n        // sessionStorage API\n        apis.sessionStorage = _extend({}, storage, {_type: 'sessionStorage'});\n    } else {\n        // localStorage API\n        apis.localStorage = _extend({}, storage, {_type: 'localCookieStorage'});\n        // sessionStorage API\n        apis.sessionStorage = _extend({}, storage, {_type: 'sessionCookieStorage'});\n    }\n    // List of all namespace storage\n    apis.namespaceStorages = {};\n    // Remove all items in all storages\n    apis.removeAllStorages = function (reinit_ns) {\n        apis.localStorage.removeAll(reinit_ns);\n        apis.sessionStorage.removeAll(reinit_ns);\n        if (apis.cookieStorage) {\n            apis.cookieStorage.removeAll(reinit_ns);\n        }\n        if (!reinit_ns) {\n            apis.namespaceStorages = {};\n        }\n    };\n    // About alwaysUseJson\n    // By default, all values are string on html storages and the plugin don't use json to store simple values (strings, int, float...)\n    // So by default, if you do storage.setItem('test',2), value in storage will be \"2\", not 2\n    // If you set this property to true, all values set with the plugin will be stored as json to have typed values in any cases\n    apis.alwaysUseJsonInStorage = function (value) {\n        storage.alwaysUseJson = value;\n        apis.localStorage.alwaysUseJson = value;\n        apis.sessionStorage.alwaysUseJson = value;\n        if (apis.cookieStorage) {\n            apis.cookieStorage.alwaysUseJson = value;\n        }\n    };\n\n    return apis;\n}));\n","js-storage/storage-wrapper.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'js-storage/js.storage'\n], function ($, storage) {\n    'use strict';\n\n    if (window.cookieStorage) {\n        var cookiesConfig = window.cookiesConfig || {};\n\n        $.extend(window.cookieStorage, {\n            _secure: !!cookiesConfig.secure,\n            _samesite: cookiesConfig.samesite ? cookiesConfig.samesite : 'lax',\n\n            /**\n             * Set value under name\n             * @param {String} name\n             * @param {String}
2 value\n             * @param {Object} [options]\n             */\n            setItem: function (name, value, options) {\n                var _default = {\n                    expires: this._expires,\n                    path: this._path,\n                    domain: this._domain,\n                    secure: this._secure,\n                    samesite: this._samesite\n                };\n\n                $.cookie(this._prefix + name, value, $.extend(_default, options || {}));\n            },\n\n            /**\n             * Set default options\n             * @param {Object} c\n             * @returns {storage}\n             */\n            setConf: function (c) {\n                if (c.path) {\n                    this._path = c.path;\n                }\n\n                if (c.domain) {\n                    this._domain = c.domain;\n                }\n\n                if (c.expires) {\n                    this._expires = c.expires;\n                }\n\n                if (typeof c.secure !== 'undefined') {\n                    this._secure = c.secure;\n                }\n\n                if (typeof c.samesite !== 'undefined') {\n                    this._samesite = c.samesite;\n                }\n\n                return this;\n            }\n        });\n    }\n\n    $.alwaysUseJsonInStorage = $.alwaysUseJsonInStorage || storage.alwaysUseJsonInStorage;\n    $.cookieStorage = $.cookieStorage || storage.cookieStorage;\n    $.initNamespaceStorage = $.initNamespaceStorage || storage.initNamespaceStorage;\n    $.localStorage = $.localStorage || storage.localStorage;\n    $.namespaceStorages = $.namespaceStorages || storage.namespaceStorages;\n    $.removeAllStorages = $.removeAllStorages || storage.removeAllStorages;\n    $.sessionStorage = $.sessionStorage || storage.sessionStorage;\n});\n","Magento_Fedex/js/model/shipping-rates-validation-rules.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n    'use strict';\n\n    return {\n        /**\n         * @return {Object}\n         */\n        getRules: function () {\n            return {\n                'postcode': {\n                    'required': true\n                },\n                'country_id': {\n                    'required': true\n                },\n                'city': {\n                    'required': true\n                }\n            };\n        }\n    };\n});\n","Magento_Fedex/js/model/shipping-rates-validator.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mageUtils',\n    'Magento_Fedex/js/model/shipping-rates-validation-rules',\n    'mage/translate'\n], function ($, utils, validationRules, $t) {\n    'use strict';\n\n    return {\n        validationErrors: [],\n\n        /**\n         * @param {Object} address\n         * @return {Boolean}\n         */\n        validate: function (address) {\n            var self = this;\n\n            this.validationErrors = [];\n            $.each(validationRules.getRules(), function (field, rule) {\n                var message;\n\n                if (rule.required && utils.isEmpty(address[field])) {\n                    message = $t('Field ') + field + $t(' is required.');\n\n                    self.validationErrors.push(message);\n                }\n            });\n\n            return !this.validationErrors.length;\n        }\n    };\n});\n","Magento_Fedex/js/view/shipping-rates-validation.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'Magento_Checkout/js/model/shipping-rates-validator',\n    'Magento_Checkout/js/model/shipping-rates-validation-rules',\n    'Magento_Fedex/js/model/shipping-rates-validator',\n    'Magento_Fedex/js/model/shipping-rates-validation-rules'\n], function (\n    Component,\n    defaultShippingRatesValidator,\n    defaultShippingRatesValidationRules,\n    fedexShippingRatesValidator,\n    fedexShippingRatesValidationRules\n) {\n    'use strict';\n\n    defaultShippingRatesValidator.registerValidator('fedex', fedexShippingRatesValidator);\n    defaultShippingRatesValidationRules.registerRules('fedex', fedexShippingRatesValidationRules);\n\n    return Component;\n});\n","Goyard_Store/js/modal-store-redirect-location.js":"define([\r\n\t'jquery',\r\n\t'Magento_Ui/js/modal/modal',\r\n\t'mage/url',\r\n\t'mage/cookies'\r\n], function ($, modal, urlBuilder) {\r\n\t'use strict';\r\n\r\n\treturn function (config) {\r\n\t\tlet options = {\r\n\t\t\ttype: 'popup',\r\n\t\t\tresponsive: true,\r\n\t\t\tmodalClass: 'redirection-store-modal',\r\n\t\t\tinnerScroll: true,\r\n\t\t\tbuttons: []\r\n\t\t};\r\n\r\n\t\t$(document).ready(function () {\r\n\t\t\tlet currentUrl = window.location.href;\r\n\t\t\tlet pageType = config.pageType;\r\n\t\t\tlet cmsPageId = config.cmsPageId;\r\n\t\t\tlet closedDurationCookie = parseInt(config.closedDurationCookie);\r\n\t\t\tlet excludedCountryGE = config.excludedCountryGE;\r\n\t\t\tlet preferredLocaleCookieLifetime = parseInt(config.preferredLocaleCookieLifetime);\r\n\t\t\tlet isPreferredLocaleCookieEnabled = Boolean(config.isPreferredLocaleCookieEnabled);\r\n\t\t\tconst now = new Date();\r\n\t\t\tconst expirationDate = new Date(now.getTime() + closedDurationCookie);\r\n\t\t\tconst preferredLocaleExpirationDate = new Date(now.getTime() + preferredLocaleCookieLifetime * 24 * 60 * 60 * 1000);\r\n\t\t\tconst forcingPopupNoCookieGlobalE = config.forcingPopupNoCookieGlobalE;\r\n\t\t\tconst mappedCountries = config.mappedCountries;\r\n\r\n\t\t\tlet hasClosedCookie = $.mage.cookies.get('closed_redirection_popup') !== null;\r\n\t\t\tlet hasGlobalECookie = $.mage.cookies.get('GlobalE_Data') !== null;\r\n\t\t\tlet hasFromStore = currentUrl.includes('from_store=');\r\n\t\t\tlet shouldForcePopup = forcingPopupNoCookieGlobalE === true || forcingPopupNoCookieGlobalE === 1 || forcingPopupNoCookieGlobalE === \"1\";\r\n\t\t\tlet global_e_enabled = window.globale_config;\r\n\r\n\t\t\tlet showModal = false;
2\r\n\r\n\t\t\t// CASE 1 : NO GLOBAL-E\r\n\t\t\tif (!global_e_enabled) {\r\n\t\t\t\tif (!hasClosedCookie) {\r\n\t\t\t\t\tshowModal = true;\r\n\t\t\t\t}\r\n\t\t\t\t// CASE 2 : GOLBAL-E Activated : Check if GEcookie is set\r\n\t\t\t} else {\r\n\t\t\t\tif (!hasGlobalECookie && !hasFromStore) {\r\n\t\t\t\t\tshowModal = true;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// if Cookie match with excluded Country , show the switch popin\r\n\t\t\t\tlet globalECookieData = JSON.parse($.mage.cookies.get('GlobalE_Data'));\r\n\t\t\t\tlet currentCookieCountry = globalECookieData ? globalECookieData.countryISO : '';\r\n\t\t\t\tif (excludedCountryGE.includes(currentCookieCountry)) {\r\n\t\t\t\t\tshowModal = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tlet $modalStoreRedirectLocationContent = $('#modal-store-redirect-location-content');\r\n\r\n\t\t\t// Keyboard event helper functions\r\n\t\t\tconst eventSpaceBar = (event) => event.which === 32 || event.keyCode === 32;\r\n\t\t\tconst eventEnter = (event) => event.which === 13 || event.keyCode === 13;\r\n\t\t\tconst eventArrowLeft = (event) => event.which === 37 || event.keyCode === 37;\r\n\t\t\tconst eventArrowRight = (event) => event.which === 39 || event.keyCode === 39;\r\n\t\t\tconst eventHome = (event) => event.key === 'Home' || event.keyCode === 36;\r\n\t\t\tconst eventEnd = (event) => event.key === 'End' || event.keyCode === 35;\r\n\r\n\t\t\t// Focus only on focusable tab element, Magento_Ui/js/modal/modal \":focusable\" selector does not exclude tabindex=\"-1\" bug\r\n\t\t\t$modalStoreRedirectLocationContent.on('focusin', '.sr-accordion-trigger[tabindex=\"-1\"]', function () {\r\n\t\t\t\t$modalStoreRedirectLocationContent.find('.regions-header [role=\"tab\"][tabindex=\"0\"]').trigger('focus');\r\n\t\t\t});\r\n\r\n\t\t\t// Tabs pattern\r\n\t\t\tfunction activateTab($tab) {\r\n\t\t\t\tlet $tabs = $modalStoreRedirectLocationContent.find('.regions-header [role=\"tab\"]');\r\n\r\n\t\t\t\t$tabs.attr({ 'aria-selected': 'false', tabindex: '-1' });\r\n\t\t\t\t$modalStoreRedirectLocationContent.find('.sr-accordion-panel').removeClass('show').attr('hidden', true);\r\n\r\n\t\t\t\t$tab.attr({ 'aria-selected': 'true', tabindex: '0' });\r\n\t\t\t\t$('#' + $tab.attr('aria-controls')).addClass('show').removeAttr('hidden');\r\n\t\t\t\t$tab.trigger('focus');\r\n\t\t\t}\r\n\r\n\t\t\tfunction moveFocusToTab($tab) {\r\n\t\t\t\t$modalStoreRedirectLocationContent.find('.regions-header [role=\"tab\"]').attr('tabindex', '-1');\r\n\t\t\t\t$tab.attr('tabindex', '0');\r\n\t\t\t\t$tab.trigger('focus');\r\n\t\t\t}\r\n\r\n\t\t\t$(document).on('click', '.sr-accordion-trigger', function () {\r\n\t\t\t\tactivateTab($(this));\r\n\t\t\t});\r\n\r\n\t\t\t$(document).on('keydown', '.sr-accordion-trigger', function (event) {\r\n\t\t\t\tlet $tabs = $modalStoreRedirectLocationContent.find('.regions-header [role=\"tab\"]');\r\n\t\t\t\tlet currentIndex = $tabs.index(this);\r\n\r\n\t\t\t\tif (eventArrowRight(event)) {\r\n\t\t\t\t\tevent.preventDefault();\r\n\t\t\t\t\tmoveFocusToTab($tabs.eq((currentIndex + 1) % $tabs.length));\r\n\t\t\t\t} else if (eventArrowLeft(event)) {\r\n\t\t\t\t\tevent.preventDefault();\r\n\t\t\t\t\tmoveFocusToTab($tabs.eq((currentIndex - 1 + $tabs.length) % $tabs.length));\r\n\t\t\t\t} else if (eventHome(event)) {\r\n\t\t\t\t\tevent.preventDefault();\r\n\t\t\t\t\tmoveFocusToTab($tabs.first());\r\n\t\t\t\t} else if (eventEnd(event)) {\r\n\t\t\t\t\tevent.preventDefault();\r\n\t\t\t\t\tmoveFocusToTab($tabs.last());\r\n\t\t\t\t} else if (eventEnter(event) || eventSpaceBar(event)) {\r\n\t\t\t\t\tevent.preventDefault();\r\n\t\t\t\t\tactivateTab($(this));\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\t// Close tabs and reset tabindex on close modal\r\n\t\t\t$modalStoreRedirectLocationContent.on('modalclosed', function () {\r\n\t\t\t\tlet $tabs = $modalStoreRedirectLocationContent.find('.regions-header [role=\"tab\"]');\r\n\r\n\t\t\t\t$tabs.attr({ 'aria-selected': 'false', tabindex: '-1' });\r\n\t\t\t\t$tabs.first().attr('tabindex', '0');\r\n\t\t\t\t$modalStoreRedirectLocationContent.find('.sr-accordion-panel').removeClass('show').attr('hidden', true);\r\n\t\t\t});\r\n\r\n\t\t\t// If show modal mean that we have to call an ajax controller to get the data from the current visitor\r\n\t\t\tif (showModal) {\r\n\t\t\t\tconst queryString = window.location.search;
2\r\n\t\t\t\tconst urlParams = new URLSearchParams(queryString);\r\n\t\t\t\tconst fastlyCountryCode = urlParams.get('fastly-country-code');\r\n\r\n\t\t\t\tconst url = urlBuilder.build('goyard_store/ajax/data');\r\n\t\t\t\tjQuery.ajax({\r\n\t\t\t\t\turl: url,\r\n\t\t\t\t\ttype: 'POST',\r\n\t\t\t\t\tdataType: 'JSON',\r\n\t\t\t\t\tdata: {\r\n\t\t\t\t\t\t'current': currentUrl,\r\n\t\t\t\t\t\t'page_type': pageType,\r\n\t\t\t\t\t\t'cms_page_id': cmsPageId,\r\n\t\t\t\t\t\t'fastly_country_code': fastlyCountryCode\r\n\t\t\t\t\t},\r\n\t\t\t\t\tsuccess: function (response) {\r\n\r\n\t\t\t\t\t\tif (response.display_popup) {\r\n\t\t\t\t\t\t\t$('#popin_redirect_visiting_from').text(response.visiting_from || '');\r\n\t\t\t\t\t\t\tif (response.detected_country_label && response.detected_country_url) {\r\n\t\t\t\t\t\t\t\t$('#cta-detected-country')\r\n\t\t\t\t\t\t\t\t\t.attr('href', response.detected_country_url)\r\n\t\t\t\t\t\t\t\t\t.attr('data-url', response.detected_country_url)\r\n\t\t\t\t\t\t\t\t\t.attr('data-global', response.detected_country_global_e)\r\n\t\t\t\t\t\t\t\t\t.attr('data-store-code', response.detected_country_store_code)\r\n\t\t\t\t\t\t\t\t\t.text(response.detected_country_label);\r\n\t\t\t\t\t\t\t\t$('#popin_redirect_visiting_switch_to').show();\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\tmodal(options, $modalStoreRedirectLocationContent);\r\n\t\t\t\t\t\t\t$modalStoreRedirectLocationContent.modal('openModal');\r\n\r\n\t\t\t\t\t\t\t$('a[id^=\"modal-continue-to\"]').on('click keydown', function (e) {\r\n\t\t\t\t\t\t\t\tif (e.type === 'click' || (e.type === 'keydown' && (e.which === 13 || e.keyCode === 13))) {\r\n\t\t\t\t\t\t\t\t\t$modalStoreRedirectLocationContent.modal('closeModal');\r\n\t\t\t\t\t\t\t\t\t$.mage.cookies.set('closed_redirection_popup', true, { expires: expirationDate });\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\t\t$modalStoreRedirectLocationContent.find('a').on('click keydown', function (e) {\r\n\t\t\t\t\t\t\t\tif (e.type === 'click' || (e.type === 'keydown' && (e.which === 13 || e.keyCode === 13))) {\r\n\t\t\t\t\t\t\t\t\t$.mage.cookies.set('closed_redirection_popup', true, { expires: expirationDate });\r\n\t\t\t\t\t\t\t\t\tconst globalData = $(this).data('global');\r\n\t\t\t\t\t\t\t\t\tif (globalData) {\r\n\t\t\t\t\t\t\t\t\t\t$.mage.cookies.set('GlobalE_Data', JSON.stringify(globalData), { expires: expirationDate });\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\tconst storeCode = $(this).data('store-code');\r\n\t\t\t\t\t\t\t\t\tif (storeCode && isPreferredLocaleCookieEnabled) {\r\n\t\t\t\t\t\t\t\t\t\t$.mage.cookies.set('goyard_preferred_locale', storeCode, { expires: preferredLocaleExpirationDate });\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\tconst targetUrl = $(this).data('url');\r\n\t\t\t\t\t\t\t\t\tif (targetUrl) {\r\n\t\t\t\t\t\t\t\t\t\te.preventDefault();\r\n\t\t\t\t\t\t\t\t\t\twindow.location.href = targetUrl;\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t},\r\n\t\t\t\t\terror: function (xhr, status, error) {\r\n\t\t\t\t\t\t//console.error(\"Error white retrieving visiting information : \" + error);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t});\r\n\t};\r\n});\r\n"}
3}});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.