Spamworldpro Mini Shell
Spamworldpro


Server : Apache
System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64
User : corals ( 1002)
PHP Version : 7.4.33
Disable Function : exec,passthru,shell_exec,system
Directory :  /home/corals/cartforge.co/pub/static/frontend/Smartwave/porto_rtl/en_US/js/bundle/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/cartforge.co/pub/static/frontend/Smartwave/porto_rtl/en_US/js/bundle/bundle8.js
require.config({"config": {
        "jsbuild":{"StripeIntegration_Payments/js/action/get-checkout-methods.js":"define(\n    [\n        'Magento_Checkout/js/model/url-builder',\n        'mage/storage',\n        'Magento_Checkout/js/model/error-processor',\n        'Magento_Checkout/js/model/full-screen-loader',\n        'Magento_Checkout/js/model/quote'\n    ],\n    function (urlBuilder, storage, errorProcessor, fullScreenLoader, quote) {\n        'use strict';\n\n        var timesRequested = 0;\n\n        return function (quote, onDoneCallback)\n        {\n            var serviceUrl = urlBuilder.createUrl('/stripe/payments/get_checkout_payment_methods', {});\n\n            var payload = {\n                billingAddress: quote.billingAddress()\n            };\n\n            if (quote.shippingAddress())\n                payload.shippingAddress = quote.shippingAddress();\n\n            if (quote.shippingMethod())\n                payload.shippingMethod = quote.shippingMethod();\n\n            var totals = quote.totals();\n            if (typeof totals.coupon_code != \"undefined\" && totals.coupon_code && totals.coupon_code.length > 0)\n                payload.couponCode = totals.coupon_code;\n\n            try\n            {\n                if (!payload.billingAddress.countryId.length)\n                    return;\n\n                if (!quote.isVirtual())\n                {\n                    if (!payload.shippingAddress.countryId.length)\n                        return;\n                }\n\n                if (timesRequested > 0)\n                    return;\n            }\n            catch (e)\n            {\n                return;\n            }\n\n            timesRequested++;\n            return storage.post(serviceUrl, JSON.stringify(payload)).done(onDoneCallback);\n        };\n    }\n);\n","StripeIntegration_Payments/js/action/place-multishipping-order.js":"define(\n    [\n        'jquery',\n        'Magento_Checkout/js/model/url-builder',\n        'mage/storage',\n        'Magento_Customer/js/customer-data',\n        'Magento_Ui/js/modal/alert'\n    ],\n    function ($, urlBuilder, storage, customerData, alert) {\n        'use strict';\n\n        var showError = function(message, e)\n        {\n            alert( { content: message });\n\n            if (typeof e != \"undefined\")\n                console.error(e);\n        };\n\n        return function (callback, onAuthenticationRequired)\n        {\n            customerData.invalidate(['cart']);\n\n            var serviceUrl = urlBuilder.createUrl('/stripe/payments/place_multishipping_order', {});\n\n            return storage.post(serviceUrl)\n            .then(function(result, b, c)\n            {\n                var response = null;\n\n                try\n                {\n                    response = JSON.parse(result);\n                }\n                catch (e)\n                {\n                    return showError(\"Sorry, a server side error has occurred.\", e);\n                }\n\n                if (response.error)\n                    return showError(response.error, response.error);\n\n                if (response.redirect)\n                    return $.mage.redirect(response.redirect);\n\n                if (response.authenticate)\n                    return onAuthenticationRequired(response.authenticate);\n\n                return showError(response, response);\n            })\n            .fail(function(result)\n            {\n                return showError(\"Sorry, a server side error has occurred.\", result);\n            })\n            .always(callback);\n        };\n    }\n);\n","StripeIntegration_Payments/js/mixins/messages-mixin.js":"define([], function() {\n    'use strict';\n    return function(target) {\n        return target.extend({\n            isVisible: function () {\n                var msgs = this.messageContainer.errorMessages();\n                for (var i = 0; i < msgs.length; i++)\n                {\n                    if (typeof msgs[i] != 'string')\n                        continue;\n\n                    if (msgs[i].indexOf(\"Authentication Required: \") >= 0)\n                        return false;\n                }\n                return this.isHidden(this.messageContainer.hasMessages());\n            }\n        });\n    };\n});\n","StripeIntegration_Payments/js/mixins/checkout/payment/list.js":"define([\n    'StripeIntegration_Payments/js/helper/subscriptions',\n    'mage/translate',\n],\nfunction(\n    subscriptions,\n    $t\n) {\n    'use strict';\n    return function(target) {\n        return target.extend({\n            /**\n             * Returns payment group title\n             *\n             * @param {Object} group\n             * @returns {String}\n             */\n            getGroupTitle: function (group)\n            {\n                if (subscriptions.isSubscriptionUpdate())\n                    return $t(\"Subscription Update Review\");\n\n                var title = group().title;\n\n                if (group().isDefault() && this.paymentGroupsList().length > 1) {\n                    title = this.defaultGroupTitle;\n                }\n\n                return title;\n            },\n        });\n    };\n});\n","StripeIntegration_Payments/js/mixins/checkout/summary/grand_total.js":"define([\n    'Magento_Checkout/js/model/quote',\n    'Magento_Checkout/js/model/totals',\n    'Magento_Catalog/js/price-utils',\n    'StripeIntegration_Payments/js/view/checkout/trialing_subscriptions',\n    'StripeIntegration_Payments/js/view/checkout/summary/prorations'\n], function (\n    quote,\n    totals,\n    priceUtils,\n    trialingSubscriptions,\n    prorations\n) {\n    'use strict';\n\n    return function (grandTotal)\n    {\n        return grandTotal.extend(\n        {\n            totals: quote.getTotals(),\n\n            getValue: function()\n            {\n                var price = 0;\n\n                if (totals && totals.getSegment('grand_total'))\n                {\n                    price = parseFloat(totals.getSegment('grand_total').value);\n                    price += trialingSubscriptions().getPureValue();\n                    price += prorations().getPureValue();\n                }\n\n                return grandTotal().getFormattedPrice(price);\n            },\n\n            getBaseValue: function () {\n                var price = 0;\n\n                if (totals && totals.getSegment('base_grand_total'))\n                {\n                    price = parseFloat(totals.getSegment('base_grand_total').value);\n                    price += trialingSubscriptions().getBasePureValue();\n                    price += prorations().getBasePureValue();\n                }\n\n                return priceUtils.formatPrice(price, quote.getBasePriceFormat());\n            },\n\n            getTaxAmount: function()\n            {\n                if (totals.getSegment('tax_amount'))\n                {\n                    // Tax exclusive settings\n                    return parseFloat(totals.getSegment('tax_amount').value);\n                }\n\n                if (totals.getSegment('tax'))\n                {\n                    // Tax inclusive settings\n                    return parseFloat(totals.getSegment('tax').value);\n                }\n\n                // Core implementation should handle both cases\n                var total = this.totals();\n                if (total && total.tax_amount) {\n                    return total.tax_amount;\n                }\n\n                return 0;\n            },\n\n            getGrandTotalExclTax: function()\n            {\n                var price = 0;\n\n                if (totals.getSegment('grand_total'))\n                {\n                    price = parseFloat(totals.getSegment('grand_total').value);\n                    price -= parseFloat(this.getTaxAmount());\n                    price += trialingSubscriptions().getTaxAmount();\n                    price += trialingSubscriptions().getPureValue();\n                    price += prorations().getPureValue();\n                }\n\n                return grandTotal().getFormattedPrice(price);\n            }\n        });\n    };\n});\n","StripeIntegration_Payments/js/helper/subscriptions.js":"define(\n    [\n        'ko'\n    ],\n    function (\n        ko\n    ) {\n        'use strict';\n\n        return {\n            isSubscriptionUpdate: function()\n            {\n                return !!(window.checkoutConfig &&\n                    window.checkoutConfig.payment &&\n                    window.checkoutConfig.payment.stripe_payments &&\n                    window.checkoutConfig.payment.stripe_payments.subscriptionUpdateDetails);\n            },\n\n            getConfig: function(key)\n            {\n                var config = null;\n\n                if (window.checkoutConfig && window.checkoutConfig.payment && window.checkoutConfig.payment.stripe_payments)\n                {\n                    config = window.checkoutConfig.payment.stripe_payments;\n                }\n\n                if (!config || !config.subscriptionUpdateDetails)\n                {\n                    return null;\n                }\n\n                if (!config.subscriptionUpdateDetails[key])\n                {\n                    return \"--\";\n                }\n\n                return config.subscriptionUpdateDetails[key];\n            },\n\n            getSuccessUrl: function()\n            {\n                return this.getConfig(\"success_url\");\n            },\n\n            getCancelUrl: function()\n            {\n                return this.getConfig(\"cancel_url\");\n            },\n\n            displaySidebar: function()\n            {\n                return this.isSubscriptionUpdate();\n                    // && !window.checkoutConfig.payment.stripe_payments.subscriptionUpdateDetails.is_virtual\n                    // && window.location.href.indexOf('#payment') < 0;\n            }\n        };\n    }\n);\n","StripeIntegration_Payments/js/model/upcomingInvoice.js":"define(\n    [\n        'ko',\n        'Magento_Checkout/js/model/quote',\n        'StripeIntegration_Payments/js/action/get-upcoming-invoice',\n    ],\n    function (\n        ko,\n        quote,\n        getUpcomingInvoiceAction\n    ) {\n        'use strict';\n\n        return {\n            upcomingInvoiceRequest: null,\n            initialized: false,\n            currentTotals: null,\n            callbacks: [],\n\n            initialize: function()\n            {\n                if (this.initialized)\n                    return;\n\n                this.initialized = true;\n\n                this.watchTotals();\n                getUpcomingInvoiceAction(this.upcomingInvoiceChanged.bind(this));\n            },\n\n            watchTotals: function()\n            {\n                this.currentTotals = quote.totals();\n                var upcomingInvoiceChanged = this.upcomingInvoiceChanged.bind(this);\n                var self = this;\n\n                quote.totals.subscribe(function (totals)\n                {\n                    if (JSON.stringify(totals.total_segments) == JSON.stringify(self.currentTotals.total_segments))\n                        return;\n\n                    self.currentTotals = totals;\n\n                    getUpcomingInvoiceAction(upcomingInvoiceChanged);\n                }, self);\n            },\n\n            upcomingInvoiceChanged: function(result, outcome, response)\n            {\n                this.upcomingInvoiceRequest = {\n                    result: result,\n                    outcome: outcome,\n                    response: response\n                };\n\n                for (var i = 0; i < this.callbacks.length; i++)\n                {\n                    this.callbacks[i](result, outcome, response);\n                }\n            },\n\n            onChange: function(callback)\n            {\n                this.callbacks.push(callback);\n\n                if (this.upcominInvoiceRequest)\n                {\n                    callback(this.upcominInvoiceRequest.result, this.upcominInvoiceRequest.outcome, this.upcominInvoiceRequest.response);\n                }\n            }\n        };\n    }\n);\n","Webkul_PrivateShop/js/view/wishlist-view.js":"/**\n * Webkul Software\n *\n * @category  Webkul\n * @package   Webkul_PrivateShop\n * @author    Webkul Software Private Limited\n * @copyright Webkul Software Private Limited (https://webkul.com)\n * @license   https://store.webkul.com/license.html\n */\ndefine(\n    ['jquery'],\n    function ($) {\n        $.widget(\n            'webkul.privateProductLabel',\n            {\n                _create: function () {\n                    var self = this;\n                    $(\".price-box\").each(function () {\n                        var id= $(this).attr('data-product-id');\n                        var self1 = this;\n                        $.ajax({\n                            url: self.options.labetData.url,\n                            type: 'POST',\n                            data: { id : id},\n                            dataType: 'json',\n                            success: function (response) {\n                                if (response == 'true') {\n                                    $($(self1).parent().find(\"a\").find(\"span\").find(\"span\"))\n                                        .append(self.options.labetData.html);\n                                    $($(self1).parent().parent('.product-item-info').find(\"a\").find(\"span\").find(\"span\"))\n                                        .append(self.options.labetData.html);\n                                    $($(self1).parent().parent().find(\"div.product-item-img\").find(\"a.product-image\"))\n                                        .prepend(self.options.labetData.html);\n                                    $($(self1).parent().parent().find(\"div.product-item-photo\"))\n                                        .prepend(self.options.labetData.html);\n                                }                        \n                            }\n                        })\n                    });\n                }\n            }\n        );\n        return $.webkul.privateProductLabel;\n    }\n);","Webkul_PrivateShop/js/view/category-view.js":"/**\n * Webkul Software\n *\n * @category  Webkul\n * @package   Webkul_PrivateShop\n * @author    Webkul Software Private Limited\n * @copyright Webkul Software Private Limited (https://webkul.com)\n * @license   https://store.webkul.com/license.html\n */\ndefine(\n    ['jquery'],\n    function ($) {\n        $.widget(\n            'webkul.privateProductLabel',\n            {\n                _create: function () {\n                    var self = this;\n                    $(\".private-label-available\").each(function () {\n                        if ($(this).val() == 1) {\n                            $($(this).parent().find(\"a\").find(\"span\").find(\"span\"))\n                                .append(self.options.labetData.html);\n                            $($(this).parent().parent('.product-item-info').find(\"a\").find(\"span\").find(\"span\"))\n                                .append(self.options.labetData.html);\n\n                            $($(this).parent().parent().find(\"div.product-item-img\").find(\"a.product-image\"))\n                                .prepend(self.options.labetData.html);\n\n                            $($(this).parent().parent().find(\"div.product-item-photo\"))\n                                .prepend(self.options.labetData.html);\n                        }\n                    });\n                }\n            }\n        );\n        return $.webkul.privateProductLabel;\n    }\n);","Webkul_PrivateShop/js/view/product-view.js":"/**\n * Webkul Software\n *\n * @category  Webkul\n * @package   Webkul_PrivateShop\n * @author    Webkul Software Private Limited\n * @copyright Webkul Software Private Limited (https://webkul.com)\n * @license   https://store.webkul.com/license.html\n */\ndefine(\n    [\n        'jquery'\n    ],\n    function ($) {\n        $.widget(\n            'private.viewProduct',\n            {\n                _create: function () {\n                    var self = this;\n                    $(\".product.media\").prepend(self.options.labetData.html);\n                }\n            }\n        );\n        return $.private.viewProduct;\n    }\n);","Magento_Captcha/js/captcha.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    /**\n     * @api\n     */\n    $.widget('mage.captcha', {\n        options: {\n            refreshClass: 'refreshing',\n            reloadSelector: '.captcha-reload',\n            imageSelector: '.captcha-img',\n            imageLoader: ''\n        },\n\n        /**\n         * Method binds click event to reload image\n         * @private\n         */\n        _create: function () {\n            this.element.on('click', this.options.reloadSelector, $.proxy(this.refresh, this));\n        },\n\n        /**\n         * Method triggers an AJAX request to refresh the CAPTCHA image\n         */\n        refresh: function () {\n            var imageLoader = this.options.imageLoader;\n\n            if (imageLoader) {\n                this.element.find(this.options.imageSelector).attr('src', imageLoader);\n            }\n            this.element.addClass(this.options.refreshClass);\n\n            $.ajax({\n                url: this.options.url,\n                type: 'post',\n                dataType: 'json',\n                context: this,\n                data: {\n                    'formId': this.options.type\n                },\n\n                /**\n                 * @param {Object} response\n                 */\n                success: function (response) {\n                    if (response.imgSrc) {\n                        this.element.find(this.options.imageSelector).attr('src', response.imgSrc);\n                    }\n                },\n\n                /** Complete callback. */\n                complete: function () {\n                    this.element.removeClass(this.options.refreshClass);\n                }\n            });\n        }\n    });\n\n    return $.mage.captcha;\n});\n","Magento_Captcha/js/view/checkout/loginCaptcha.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Captcha/js/view/checkout/defaultCaptcha',\n    'Magento_Captcha/js/model/captchaList',\n    'Magento_Customer/js/action/login',\n    'underscore'\n],\nfunction (defaultCaptcha, captchaList, loginAction, _) {\n    'use strict';\n\n    return defaultCaptcha.extend({\n        /** @inheritdoc */\n        initialize: function () {\n            var self = this,\n                currentCaptcha;\n\n            this._super();\n            currentCaptcha = captchaList.getCaptchaByFormId(this.formId);\n\n            if (currentCaptcha != null) {\n                currentCaptcha.setIsVisible(true);\n                this.setCurrentCaptcha(currentCaptcha);\n\n                loginAction.registerLoginCallback(function (loginData) {\n                    if (loginData['captcha_form_id'] &&\n                        loginData['captcha_form_id'] === self.formId &&\n                        self.isRequired()\n                    ) {\n                        _.defer(self.refresh.bind(self));\n                    }\n                });\n            }\n        }\n    });\n});\n","Magento_Captcha/js/view/checkout/defaultCaptcha.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'uiComponent',\n    'Magento_Captcha/js/model/captcha',\n    'Magento_Captcha/js/model/captchaList',\n    'Magento_Customer/js/customer-data',\n    'underscore'\n], function ($, Component, Captcha, captchaList, customerData, _) {\n    'use strict';\n\n    var captchaConfig;\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_Captcha/checkout/captcha'\n        },\n        dataScope: 'global',\n        currentCaptcha: null,\n        subscribedFormIds: [],\n\n        /**\n         * @return {*}\n         */\n        captchaValue: function () {\n            return this.currentCaptcha.getCaptchaValue();\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n\n            if (window[this.configSource] && window[this.configSource].captcha) {\n                captchaConfig = window[this.configSource].captcha;\n                $.each(captchaConfig, function (formId, captchaData) {\n                    var captcha;\n\n                    captchaData.formId = formId;\n                    captcha = Captcha(captchaData);\n                    this.checkCustomerData(formId, customerData.get('captcha')(), captcha);\n                    this.subscribeCustomerData(formId, captcha);\n                    captchaList.add(captcha);\n                }.bind(this));\n            }\n        },\n\n        /**\n         * Check customer data for captcha configuration.\n         *\n         * @param {String} formId\n         * @param {Object} captchaData\n         * @param {Object} captcha\n         */\n        checkCustomerData: function (formId, captchaData, captcha) {\n            if (!_.isEmpty(captchaData) &&\n                !_.isEmpty(captchaData[formId]) &&\n                captchaData[formId].timestamp > captcha.timestamp\n            ) {\n                if (!captcha.isRequired() && captchaData[formId].isRequired) {\n                    captcha.refresh();\n                }\n                captcha.isRequired(captchaData[formId].isRequired);\n                captcha.timestamp = captchaData[formId].timestamp;\n            }\n        },\n\n        /**\n         * Subscribe for customer data updates.\n         *\n         * @param {String} formId\n         * @param {Object} captcha\n         */\n        subscribeCustomerData: function (formId, captcha) {\n            if (this.subscribedFormIds.includes(formId) === false) {\n                this.subscribedFormIds.push(formId);\n                customerData.get('captcha').subscribe(function (captchaData) {\n                    this.checkCustomerData(formId, captchaData, captcha);\n                }.bind(this));\n            }\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        getIsLoading: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.isLoading : false;\n        },\n\n        /**\n         * @return {null|Object}\n         */\n        getCurrentCaptcha: function () {\n            return this.currentCaptcha;\n        },\n\n        /**\n         * @param {Object} captcha\n         */\n        setCurrentCaptcha: function (captcha) {\n            this.currentCaptcha = captcha;\n        },\n\n        /**\n         * @return {String|null}\n         */\n        getFormId: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getFormId() : null;\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        getIsVisible: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getIsVisible() : false;\n        },\n\n        /**\n         * @param {Boolean} flag\n         */\n        setIsVisible: function (flag) {\n            this.currentCaptcha.setIsVisible(flag);\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isRequired: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getIsRequired() : false;\n        },\n\n        /**\n         * Set isRequired on current captcha model.\n         *\n         * @param {Boolean} flag\n         */\n        setIsRequired: function (flag) {\n            this.currentCaptcha.setIsRequired(flag);\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isCaseSensitive: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getIsCaseSensitive() : false;\n        },\n\n        /**\n         * @return {String|Number|null}\n         */\n        imageHeight: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getImageHeight() : null;\n        },\n\n        /**\n         * @return {String|null}\n         */\n        getImageSource: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getImageSource() : null;\n        },\n\n        /**\n         * Refresh captcha.\n         */\n        refresh: function () {\n            this.currentCaptcha.refresh();\n        }\n    });\n});\n","Magento_Captcha/js/action/refresh.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery', 'mage/url'\n], function ($, urlBuilder) {\n    'use strict';\n\n    return function (refreshUrl, formId, imageSource) {\n        return $.ajax({\n            url: urlBuilder.build(refreshUrl),\n            type: 'POST',\n            data: JSON.stringify({\n                'formId': formId\n            }),\n            global: false,\n            contentType: 'application/json'\n        }).done(\n            function (response) {\n                if (response.imgSrc) {\n                    imageSource(response.imgSrc);\n                }\n            }\n        );\n    };\n});\n","Magento_Captcha/js/model/captchaList.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    var captchaList = [];\n\n    return {\n        /**\n         * @param {Object} captcha\n         */\n        add: function (captcha) {\n            captchaList.push(captcha);\n        },\n\n        /**\n         * @param {String} formId\n         * @return {Object}\n         */\n        getCaptchaByFormId: function (formId) {\n            var captcha = null;\n\n            $.each(captchaList, function (key, item) {\n                if (formId === item.formId) {\n                    captcha = item;\n\n                    return false;\n                }\n            });\n\n            return captcha;\n        },\n\n        /**\n         * @return {Array}\n         */\n        getCaptchaList: function () {\n            return captchaList;\n        }\n    };\n});\n","Magento_Captcha/js/model/captcha.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'ko',\n    'Magento_Captcha/js/action/refresh'\n], function ($, ko, refreshAction) {\n    'use strict';\n\n    return function (captchaData) {\n        return {\n            formId: captchaData.formId,\n            imageSource: ko.observable(captchaData.imageSrc),\n            visibility: ko.observable(false),\n            captchaValue: ko.observable(null),\n            isRequired: ko.observable(captchaData.isRequired),\n            isCaseSensitive: captchaData.isCaseSensitive,\n            imageHeight: captchaData.imageHeight,\n            refreshUrl: captchaData.refreshUrl,\n            isLoading: ko.observable(false),\n            timestamp: null,\n\n            /**\n             * @return {String}\n             */\n            getFormId: function () {\n                return this.formId;\n            },\n\n            /**\n             * @param {String} formId\n             */\n            setFormId: function (formId) {\n                this.formId = formId;\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            getIsVisible: function () {\n                return this.visibility();\n            },\n\n            /**\n             * @param {Boolean} flag\n             */\n            setIsVisible: function (flag) {\n                this.visibility(flag);\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            getIsRequired: function () {\n                return this.isRequired();\n            },\n\n            /**\n             * @param {Boolean} flag\n             */\n            setIsRequired: function (flag) {\n                this.isRequired(flag);\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            getIsCaseSensitive: function () {\n                return this.isCaseSensitive;\n            },\n\n            /**\n             * @param {Boolean} flag\n             */\n            setIsCaseSensitive: function (flag) {\n                this.isCaseSensitive = flag;\n            },\n\n            /**\n             * @return {String|Number}\n             */\n            getImageHeight: function () {\n                return this.imageHeight;\n            },\n\n            /**\n             * @param {String|Number}height\n             */\n            setImageHeight: function (height) {\n                this.imageHeight = height;\n            },\n\n            /**\n             * @return {String}\n             */\n            getImageSource: function () {\n                return this.imageSource;\n            },\n\n            /**\n             * @param {String} imageSource\n             */\n            setImageSource: function (imageSource) {\n                this.imageSource(imageSource);\n            },\n\n            /**\n             * @return {String}\n             */\n            getRefreshUrl: function () {\n                return this.refreshUrl;\n            },\n\n            /**\n             * @param {String} url\n             */\n            setRefreshUrl: function (url) {\n                this.refreshUrl = url;\n            },\n\n            /**\n             * @return {*}\n             */\n            getCaptchaValue: function () {\n                return this.captchaValue;\n            },\n\n            /**\n             * @param {*} value\n             */\n            setCaptchaValue: function (value) {\n                this.captchaValue(value);\n            },\n\n            /**\n             * Refresh captcha.\n             */\n            refresh: function () {\n                var refresh,\n                    self = this;\n\n                this.isLoading(true);\n\n                refresh = refreshAction(this.getRefreshUrl(), this.getFormId(), this.getImageSource());\n                $.when(refresh).done(function () {\n                    self.isLoading(false);\n                });\n            }\n        };\n    };\n});\n","Magento_Sales/js/gift-message.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.giftMessage', {\n        options: {\n            rowPrefix: '#order-item-row-', // Selector prefix for item's row in the table.\n            linkPrefix: '#order-item-gift-message-link-', // Selector prefix for the 'Gift Message' link.\n            duration: 100, // Toggle duration.\n            expandedClass: 'expanded', // Class added/removed to/from the 'Gift Message' link.\n            expandedContentClass: 'expanded-content', // Class added/removed to/from the 'Gift Message' content.\n            lastClass: 'last' // Class added/removed to/from the last item's row in the products table.\n        },\n\n        /**\n         * Bind a click handler on the widget's element to toggle the gift message.\n         * @private\n         */\n        _create: function () {\n            this.element.on('click', $.proxy(this._toggleGiftMessage, this));\n        },\n\n        /**\n         * Toggle the display of the item's corresponding gift message.\n         * @private\n         * @param {jQuery.Event} event - Click event.\n         */\n        _toggleGiftMessage: function (event) {\n            var element = $(event.target), // Click target. The 'Gift Message' link or 'Close' button.\n                options = this.options, // Cached widget options.\n                itemId = element.data('item-id'), // The individual item's numeric id.\n                link = $(options.linkPrefix + itemId), // The 'Gift Message' expandable link.\n                row = $(options.rowPrefix + itemId), // The item's row in the products table.\n                region = $('#' + element.attr('aria-controls')); // The gift message container region.\n\n            region.toggleClass(options.expandedContentClass, options.duration, function () {\n                if (region.attr('aria-expanded') === 'true') {\n                    region.attr('aria-expanded', 'false');\n\n                    if (region.hasClass(options.lastClass)) {\n                        row.addClass(options.lastClass);\n                    }\n                } else {\n                    region.attr('aria-expanded', 'true');\n\n                    if (region.hasClass(options.lastClass)) {\n                        row.removeClass(options.lastClass);\n                    }\n                }\n                link.toggleClass(options.expandedClass);\n            });\n            event.preventDefault(); // Prevent event propagation and avoid going to the link's href.\n        }\n    });\n\n    return $.mage.giftMessage;\n});\n","Magento_Sales/js/orders-returns.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.ordersReturns', {\n        options: {\n            zipCode: '#oar-zip', // Search by zip code.\n            emailAddress: '#oar-email', // Search by email address.\n            searchType: '#quick-search-type-id' // Search element used for choosing between the two.\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            $(this.options.searchType).on('change', $.proxy(this._showIdentifyBlock, this)).trigger('change');\n        },\n\n        /**\n         * Show either the search by zip code option or the search by email address option.\n         * @private\n         * @param {jQuery.Event} e - Change event. Event target value is either 'zip' or 'email'.\n         */\n        _showIdentifyBlock: function (e) {\n            var value = $(e.target).val();\n\n            $(this.options.zipCode).toggle(value === 'zip');\n            $(this.options.emailAddress).toggle(value === 'email');\n        }\n    });\n\n    return $.mage.ordersReturns;\n});\n","Magento_Sales/js/view/last-ordered-items.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'Magento_Customer/js/customer-data',\n    'underscore'\n], function (Component, customerData, _) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            isShowAddToCart: false\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n            this.lastOrderedItems = customerData.get('last-ordered-items');\n            this.lastOrderedItems.subscribe(this.checkSalableItems.bind(this));\n            this.checkSalableItems();\n\n            return this;\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super()\n                .observe('isShowAddToCart');\n\n            return this;\n        },\n\n        /**\n         * Check if items is_saleable and change add to cart button visibility.\n         */\n        checkSalableItems: function () {\n            var isShowAddToCart = _.some(this.lastOrderedItems().items, {\n                'is_saleable': true\n            });\n\n            this.isShowAddToCart(isShowAddToCart);\n        }\n    });\n});\n","Magento_Customer/js/password-strength-indicator.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Customer/js/zxcvbn',\n    'mage/translate',\n    'mage/validation'\n], function ($, zxcvbn, $t) {\n    'use strict';\n\n    $.widget('mage.passwordStrengthIndicator', {\n        options: {\n            cache: {},\n            passwordSelector: '[type=password]',\n            passwordStrengthMeterSelector: '[data-role=password-strength-meter]',\n            passwordStrengthMeterLabelSelector: '[data-role=password-strength-meter-label]',\n            formSelector: 'form',\n            emailSelector: 'input[type=\"email\"]'\n        },\n\n        /**\n         * Widget initialization\n         * @private\n         */\n        _create: function () {\n            this.options.cache.input = $(this.options.passwordSelector, this.element);\n            this.options.cache.meter = $(this.options.passwordStrengthMeterSelector, this.element);\n            this.options.cache.label = $(this.options.passwordStrengthMeterLabelSelector, this.element);\n\n            // We need to look outside the module for backward compatibility, since someone can already use the module.\n            // @todo Narrow this selector in 2.3 so it doesn't accidentally finds the email field from the\n            // newsletter email field or any other \"email\" field.\n            this.options.cache.email = $(this.options.formSelector).find(this.options.emailSelector);\n            this._bind();\n        },\n\n        /**\n         * Event binding, will monitor change, keyup and paste events.\n         * @private\n         */\n        _bind: function () {\n            this._on(this.options.cache.input, {\n                'change': this._calculateStrength,\n                'keyup': this._calculateStrength,\n                'paste': this._calculateStrength\n            });\n\n            if (this.options.cache.email.length) {\n                this._on(this.options.cache.email, {\n                    'change': this._calculateStrength,\n                    'keyup': this._calculateStrength,\n                    'paste': this._calculateStrength\n                });\n            }\n        },\n\n        /**\n         * Calculate password strength\n         * @private\n         */\n        _calculateStrength: function () {\n            var password = this._getPassword(),\n                isEmpty = password.length === 0,\n                zxcvbnScore,\n                displayScore,\n                isValid;\n\n            // Display score is based on combination of whether password is empty, valid, and zxcvbn strength\n            if (isEmpty) {\n                displayScore = 0;\n            } else {\n                this.options.cache.input.rules('add', {\n                    'password-not-equal-to-user-name': this.options.cache.email.val()\n                });\n\n                // We should only perform this check in case there is an email field on screen\n                if (this.options.cache.email.length &&\n                    password.toLowerCase() === this.options.cache.email.val().toLowerCase()) {\n                    displayScore = 1;\n                } else {\n                    isValid = $.validator.validateSingleElement(this.options.cache.input);\n                    zxcvbnScore = zxcvbn(password).score;\n                    displayScore = isValid && zxcvbnScore > 0 ? zxcvbnScore : 1;\n                }\n            }\n\n            // Update label\n            this._displayStrength(displayScore);\n        },\n\n        /**\n         * Display strength\n         * @param {Number} displayScore\n         * @private\n         */\n        _displayStrength: function (displayScore) {\n            var strengthLabel = '',\n                className;\n\n            switch (displayScore) {\n                case 0:\n                    strengthLabel = $t('No Password');\n                    className = 'password-none';\n                    break;\n\n                case 1:\n                    strengthLabel = $t('Weak');\n                    className = 'password-weak';\n                    break;\n\n                case 2:\n                    strengthLabel = $t('Medium');\n                    className = 'password-medium';\n                    break;\n\n                case 3:\n                    strengthLabel = $t('Strong');\n                    className = 'password-strong';\n                    break;\n\n                case 4:\n                    strengthLabel = $t('Very Strong');\n                    className = 'password-very-strong';\n                    break;\n            }\n\n            this.options.cache.meter\n                .removeClass()\n                .addClass(className);\n            this.options.cache.label.text(strengthLabel);\n        },\n\n        /**\n         * Get password value\n         * @returns {*}\n         * @private\n         */\n        _getPassword: function () {\n            return this.options.cache.input.val();\n        }\n    });\n\n    return $.mage.passwordStrengthIndicator;\n});\n","Magento_Customer/js/checkout-balance.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.checkoutBalance', {\n        /**\n         * Initialize store credit events\n         * @private\n         */\n        _create: function () {\n            this.eventData = {\n                price: this.options.balance,\n                totalPrice: 0\n            };\n            this.element.on('change', $.proxy(function (e) {\n                if ($(e.target).is(':checked')) {\n                    this.eventData.price = -1 * this.options.balance;\n                } else {\n                    if (this.options.amountSubstracted) { //eslint-disable-line no-lonely-if\n                        this.eventData.price = parseFloat(this.options.usedAmount);\n                        this.options.amountSubstracted = false;\n                    } else {\n                        this.eventData.price = parseFloat(this.options.balance);\n                    }\n                }\n                this.element.trigger('updateCheckoutPrice', this.eventData);\n            }, this));\n        }\n    });\n\n    return $.mage.checkoutBalance;\n});\n","Magento_Customer/js/validation.js":"define([\n    'jquery',\n    'moment',\n    'mageUtils',\n    'jquery/validate',\n    'validation',\n    'mage/translate'\n], function ($, moment, utils) {\n    'use strict';\n\n    $.validator.addMethod(\n        'validate-date',\n        function (value, element, params) {\n            var dateFormat = utils.normalizeDate(params.dateFormat);\n\n            if (value === '') {\n                return true;\n            }\n\n            return moment(value, dateFormat, true).isValid();\n        },\n        $.mage.__('Invalid date')\n    );\n\n    $.validator.addMethod(\n        'validate-dob',\n        function (value, element, params) {\n            var dateFormat = utils.convertToMomentFormat(params.dateFormat);\n\n            if (value === '') {\n                return true;\n            }\n\n            return moment(value, dateFormat).isBefore(moment());\n        },\n        $.mage.__('The Date of Birth should not be greater than today.')\n    );\n});\n","Magento_Customer/js/customer-global-session-loader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Customer/js/customer-data'\n], function ($, customerData) {\n    'use strict';\n\n    return function () {\n        var customer;\n\n        // When the session is available, this customer menu will be available\n        if ($('.customer-menu').length > 0) {\n            customer = customerData.get('customer');\n\n            customerData.getInitCustomerData().done(function () {\n                // Check if the customer data is set in local storage, if not reload data from server\n                if (!customer().firstname) {\n                    customerData.reload([], false);\n                }\n            });\n        }\n    };\n});\n","Magento_Customer/js/addressValidation.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'underscore',\n    'mageUtils',\n    'mage/translate',\n    'Magento_Checkout/js/model/postcode-validator',\n    'jquery-ui-modules/widget',\n    'validation'\n], function ($, __, utils, $t, postCodeValidator) {\n    'use strict';\n\n    $.widget('mage.addressValidation', {\n        options: {\n            selectors: {\n                button: '[data-action=save-address]',\n                zip: '#zip',\n                country: 'select[name=\"country_id\"]:visible'\n            }\n        },\n\n        zipInput: null,\n        countrySelect: null,\n\n        /**\n         * Validation creation\n         *\n         * @protected\n         */\n        _create: function () {\n            var button = $(this.options.selectors.button, this.element);\n\n            this.zipInput = $(this.options.selectors.zip, this.element);\n            this.countrySelect = $(this.options.selectors.country, this.element);\n\n            this.element.validation({\n\n                /**\n                 * Submit Handler\n                 * @param {Element} form - address form\n                 */\n                submitHandler: function (form) {\n\n                    button.attr('disabled', true);\n                    form.submit();\n                }\n            });\n\n            this._addPostCodeValidation();\n        },\n\n        /**\n         * Add postcode validation\n         *\n         * @protected\n         */\n        _addPostCodeValidation: function () {\n            var self = this;\n\n            this.zipInput.on('keyup', __.debounce(function (event) {\n                    var valid = self._validatePostCode(event.target.value);\n\n                    self._renderValidationResult(valid);\n                }, 500)\n            );\n\n            this.countrySelect.on('change', function () {\n                var valid = self._validatePostCode(self.zipInput.val());\n\n                self._renderValidationResult(valid);\n            });\n        },\n\n        /**\n         * Validate post code value.\n         *\n         * @protected\n         * @param {String} postCode - post code\n         * @return {Boolean} Whether is post code valid\n         */\n        _validatePostCode: function (postCode) {\n            var countryId = this.countrySelect.val();\n\n            if (postCode === null) {\n                return true;\n            }\n\n            return postCodeValidator.validate(postCode, countryId, this.options.postCodes);\n        },\n\n        /**\n         * Renders warning messages for invalid post code.\n         *\n         * @protected\n         * @param {Boolean} valid\n         */\n        _renderValidationResult: function (valid) {\n            var warnMessage,\n                alertDiv = this.zipInput.next();\n\n            if (!valid) {\n                warnMessage = $t('Provided Zip/Postal Code seems to be invalid.');\n\n                if (postCodeValidator.validatedPostCodeExample.length) {\n                    warnMessage += $t(' Example: ') + postCodeValidator.validatedPostCodeExample.join('; ') + '. ';\n                }\n                warnMessage += $t('If you believe it is the right one you can ignore this notice.');\n            }\n\n            alertDiv.children(':first').text(warnMessage);\n\n            if (valid) {\n                alertDiv.hide();\n            } else {\n                alertDiv.show();\n            }\n        }\n    });\n\n    return $.mage.addressValidation;\n});\n","Magento_Customer/js/customer-data.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    'Magento_Customer/js/section-config',\n    'mage/url',\n    'mage/storage',\n    'jquery/jquery-storageapi'\n], function ($, _, ko, sectionConfig, url) {\n    'use strict';\n\n    var options = {},\n        storage,\n        storageInvalidation,\n        invalidateCacheBySessionTimeOut,\n        invalidateCacheByCloseCookieSession,\n        dataProvider,\n        buffer,\n        customerData,\n        deferred = $.Deferred();\n\n    url.setBaseUrl(window.BASE_URL);\n    options.sectionLoadUrl = url.build('customer/section/load');\n\n    /**\n     * @param {Object} invalidateOptions\n     */\n    invalidateCacheBySessionTimeOut = function (invalidateOptions) {\n        var date;\n\n        if (new Date($.localStorage.get('mage-cache-timeout')) < new Date()) {\n            storage.removeAll();\n        }\n        date = new Date(Date.now() + parseInt(invalidateOptions.cookieLifeTime, 10) * 1000);\n        $.localStorage.set('mage-cache-timeout', date);\n    };\n\n    /**\n     * Invalidate Cache By Close Cookie Session\n     */\n    invalidateCacheByCloseCookieSession = function () {\n        if (!$.cookieStorage.isSet('mage-cache-sessid')) {\n            storage.removeAll();\n        }\n\n        $.cookieStorage.set('mage-cache-sessid', true);\n    };\n\n    dataProvider = {\n\n        /**\n         * @param {Object} sectionNames\n         * @return {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         * @param {Object} sectionNames\n         * @param {Boolean} forceNewSectionTimestamp\n         * @return {*}\n         */\n        getFromServer: function (sectionNames, forceNewSectionTimestamp) {\n            var parameters;\n\n            sectionNames = sectionConfig.filterClientSideSections(sectionNames);\n            parameters = _.isArray(sectionNames) && sectionNames.indexOf('*') < 0 ? {\n                sections: sectionNames.join(',')\n            } : [];\n            parameters['force_new_section_timestamp'] = forceNewSectionTimestamp;\n\n            return $.getJSON(options.sectionLoadUrl, parameters).fail(function (jqXHR) {\n                throw new Error(jqXHR);\n            });\n        }\n    };\n\n    /**\n     * @param {Function} target\n     * @param {String} sectionName\n     * @return {*}\n     */\n    ko.extenders.disposableCustomerData = function (target, sectionName) {\n        var sectionDataIds, newSectionDataIds = {};\n\n        target.subscribe(function () {\n            setTimeout(function () {\n                storage.remove(sectionName);\n                sectionDataIds = $.cookieStorage.get('section_data_ids') || {};\n                _.each(sectionDataIds, function (data, name) {\n                    if (name !== sectionName) {\n                        newSectionDataIds[name] = data;\n                    }\n                });\n                $.cookieStorage.set('section_data_ids', newSectionDataIds);\n            }, 3000);\n        });\n\n        return target;\n    };\n\n    buffer = {\n        data: {},\n\n        /**\n         * @param {String} sectionName\n         */\n        bind: function (sectionName) {\n            this.data[sectionName] = ko.observable({});\n        },\n\n        /**\n         * @param {String} sectionName\n         * @return {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         * @return {Array}\n         */\n        keys: function () {\n            return _.keys(this.data);\n        },\n\n        /**\n         * @param {String} sectionName\n         * @param {Object} sectionData\n         */\n        notify: function (sectionName, sectionData) {\n            if (!this.data[sectionName]) {\n                this.bind(sectionName);\n            }\n            this.data[sectionName](sectionData);\n        },\n\n        /**\n         * @param {Object} sections\n         */\n        update: function (sections) {\n            var sectionId = 0,\n                sectionDataIds = $.cookieStorage.get('section_data_ids') || {};\n\n            _.each(sections, function (sectionData, sectionName) {\n                sectionId = sectionData['data_id'];\n                sectionDataIds[sectionName] = sectionId;\n                storage.set(sectionName, sectionData);\n                storageInvalidation.remove(sectionName);\n                buffer.notify(sectionName, sectionData);\n            });\n            $.cookieStorage.set('section_data_ids', sectionDataIds);\n        },\n\n        /**\n         * @param {Object} sections\n         */\n        remove: function (sections) {\n            _.each(sections, function (sectionName) {\n                storage.remove(sectionName);\n\n                if (!sectionConfig.isClientSideSection(sectionName)) {\n                    storageInvalidation.set(sectionName, true);\n                }\n            });\n        }\n    };\n\n    customerData = {\n\n        /**\n         * Customer data initialization\n         */\n        init: function () {\n            var expiredSectionNames = this.getExpiredSectionNames();\n\n            if (expiredSectionNames.length > 0) {\n                _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) {\n                    buffer.notify(sectionName, sectionData);\n                });\n                this.reload(expiredSectionNames, false);\n            } else {\n                _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) {\n                    buffer.notify(sectionName, sectionData);\n                });\n\n                if (!_.isEmpty(storageInvalidation.keys())) {\n                    this.reload(storageInvalidation.keys(), false);\n                }\n            }\n\n            if (!_.isEmpty($.cookieStorage.get('section_data_clean'))) {\n                this.reload(sectionConfig.getSectionNames(), true);\n                $.cookieStorage.set('section_data_clean', '');\n            }\n        },\n\n        /**\n         * Storage init\n         */\n        initStorage: function () {\n            $.cookieStorage.setConf({\n                path: '/',\n                expires: new Date(Date.now() + parseInt(options.cookieLifeTime, 10) * 1000)\n            });\n            storage = $.initNamespaceStorage('mage-cache-storage').localStorage;\n            storageInvalidation = $.initNamespaceStorage('mage-cache-storage-section-invalidation').localStorage;\n        },\n\n        /**\n         * Retrieve the list of sections that has expired since last page reload.\n         *\n         * Sections can expire due to lifetime constraints or due to inconsistent storage information\n         * (validated by cookie data).\n         *\n         * @return {Array}\n         */\n        getExpiredSectionNames: function () {\n            var expiredSectionNames = [],\n                cookieSectionTimestamps = $.cookieStorage.get('section_data_ids') || {},\n                sectionLifetime = options.expirableSectionLifetime * 60,\n                currentTimestamp = Math.floor(Date.now() / 1000),\n                sectionData;\n\n            // process sections that can expire due to lifetime constraints\n            _.each(options.expirableSectionNames, function (sectionName) {\n                sectionData = storage.get(sectionName);\n\n                if (typeof sectionData === 'object' && sectionData['data_id'] + sectionLifetime <= currentTimestamp) {\n                    expiredSectionNames.push(sectionName);\n                }\n            });\n\n            // process sections that can expire due to storage information inconsistency\n            _.each(cookieSectionTimestamps, function (cookieSectionTimestamp, sectionName) {\n                sectionData = storage.get(sectionName);\n\n                if (typeof sectionData === 'undefined' ||\n                    typeof sectionData === 'object' &&\n                    cookieSectionTimestamp !== sectionData['data_id']\n                ) {\n                    expiredSectionNames.push(sectionName);\n                }\n            });\n\n            //remove expired section names of previously installed/enable modules\n            expiredSectionNames = _.intersection(expiredSectionNames, sectionConfig.getSectionNames());\n\n            return _.uniq(expiredSectionNames);\n        },\n\n        /**\n         * Check if some sections have to be reloaded.\n         *\n         * @deprecated Use getExpiredSectionNames instead.\n         *\n         * @return {Boolean}\n         */\n        needReload: function () {\n            var expiredSectionNames = this.getExpiredSectionNames();\n\n            return expiredSectionNames.length > 0;\n        },\n\n        /**\n         * Retrieve the list of expired keys.\n         *\n         * @deprecated Use getExpiredSectionNames instead.\n         *\n         * @return {Array}\n         */\n        getExpiredKeys: function () {\n            return this.getExpiredSectionNames();\n        },\n\n        /**\n         * @param {String} sectionName\n         * @return {*}\n         */\n        get: function (sectionName) {\n            return buffer.get(sectionName);\n        },\n\n        /**\n         * @param {String} sectionName\n         * @param {Object} sectionData\n         */\n        set: function (sectionName, sectionData) {\n            var data = {};\n\n            data[sectionName] = sectionData;\n            buffer.update(data);\n        },\n\n        /**\n         * Avoid using this function directly 'cause of possible performance drawbacks.\n         * Each customer section reload brings new non-cached ajax request.\n         *\n         * @param {Array} sectionNames\n         * @param {Boolean} forceNewSectionTimestamp\n         * @return {*}\n         */\n        reload: function (sectionNames, forceNewSectionTimestamp) {\n            return dataProvider.getFromServer(sectionNames, forceNewSectionTimestamp).done(function (sections) {\n                $(document).trigger('customer-data-reload', [sectionNames]);\n                buffer.update(sections);\n            });\n        },\n\n        /**\n         * @param {Array} sectionNames\n         */\n        invalidate: function (sectionNames) {\n            var sectionDataIds,\n                sectionsNamesForInvalidation;\n\n            sectionsNamesForInvalidation = _.contains(sectionNames, '*') ? sectionConfig.getSectionNames() :\n                sectionNames;\n\n            $(document).trigger('customer-data-invalidate', [sectionsNamesForInvalidation]);\n            buffer.remove(sectionsNamesForInvalidation);\n            sectionDataIds = $.cookieStorage.get('section_data_ids') || {};\n\n            // Invalidate section in cookie (increase version of section with 1000)\n            _.each(sectionsNamesForInvalidation, function (sectionName) {\n                if (!sectionConfig.isClientSideSection(sectionName)) {\n                    sectionDataIds[sectionName] += 1000;\n                }\n            });\n            $.cookieStorage.set('section_data_ids', sectionDataIds);\n        },\n\n        /**\n         * Checks if customer data is initialized.\n         *\n         * @returns {jQuery.Deferred}\n         */\n        getInitCustomerData: function () {\n            return deferred.promise();\n        },\n\n        /**\n         * Reload sections on ajax complete\n         *\n         * @param {Object} jsonResponse\n         * @param {Object} settings\n         */\n        onAjaxComplete: function (jsonResponse, settings) {\n            var sections,\n                redirects;\n\n            if (settings.type.match(/post|put|delete/i)) {\n                sections = sectionConfig.getAffectedSections(settings.url);\n\n                if (sections && sections.length) {\n                    this.invalidate(sections);\n                    redirects = ['redirect', 'backUrl'];\n\n                    if (_.isObject(jsonResponse) && !_.isEmpty(_.pick(jsonResponse, redirects))) { //eslint-disable-line\n                        return;\n                    }\n                    this.reload(sections, true);\n                }\n            }\n        },\n\n        /**\n         * @param {Object} settings\n         * @constructor\n         */\n        'Magento_Customer/js/customer-data': function (settings) {\n            options = settings;\n            customerData.initStorage();\n            invalidateCacheBySessionTimeOut(settings);\n            invalidateCacheByCloseCookieSession();\n            customerData.init();\n            deferred.resolve();\n        }\n    };\n\n    /**\n     * Events listener\n     */\n    $(document).on('ajaxComplete', function (event, xhr, settings) {\n        customerData.onAjaxComplete(xhr.responseJSON, settings);\n    });\n\n    /**\n     * Events listener\n     */\n    $(document).on('submit', function (event) {\n        var sections;\n\n        if (event.target.method.match(/post|put|delete/i)) {\n            sections = sectionConfig.getAffectedSections(event.target.action);\n\n            if (sections) {\n                customerData.invalidate(sections);\n            }\n        }\n    });\n\n    return customerData;\n});\n","Magento_Customer/js/block-submit-on-send.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/mage'\n], function ($) {\n    'use strict';\n\n    return function (config) {\n        var dataForm = $('#' + config.formId);\n\n        dataForm.on('submit', function () {\n            $(this).find(':submit').attr('disabled', 'disabled');\n\n            if (this.isValid === false) {\n                $(this).find(':submit').prop('disabled', false);\n            }\n            this.isValid = true;\n        });\n        dataForm.on('invalid-form.validate', function () {\n            $(this).find(':submit').prop('disabled', false);\n            this.isValid = false;\n        });\n    };\n});\n","Magento_Customer/js/logout-redirect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/mage'\n], function ($) {\n    'use strict';\n\n    return function (data) {\n        $($.mage.redirect(data.url, 'assign', 5000));\n    };\n});\n","Magento_Customer/js/change-email-password.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.changeEmailPassword', {\n        options: {\n            changeEmailSelector: '[data-role=change-email]',\n            changePasswordSelector: '[data-role=change-password]',\n            mainContainerSelector: '[data-container=change-email-password]',\n            titleSelector: '[data-title=change-email-password]',\n            emailContainerSelector: '[data-container=change-email]',\n            newPasswordContainerSelector: '[data-container=new-password]',\n            confirmPasswordContainerSelector: '[data-container=confirm-password]',\n            currentPasswordSelector: '[data-input=current-password]',\n            emailSelector: '[data-input=change-email]',\n            newPasswordSelector: '[data-input=new-password]',\n            confirmPasswordSelector: '[data-input=confirm-password]'\n        },\n\n        /**\n         * Create widget\n         * @private\n         */\n        _create: function () {\n            this.element.on('change', $.proxy(function () {\n                this._checkChoice();\n            }, this));\n\n            this._checkChoice();\n            this._bind();\n        },\n\n        /**\n         * Event binding, will monitor change, keyup and paste events.\n         * @private\n         */\n        _bind: function () {\n            this._on($(this.options.emailSelector), {\n                'change': this._updatePasswordFieldWithEmailValue,\n                'keyup': this._updatePasswordFieldWithEmailValue,\n                'paste': this._updatePasswordFieldWithEmailValue\n            });\n        },\n\n        /**\n         * Check choice\n         * @private\n         */\n        _checkChoice: function () {\n            if ($(this.options.changeEmailSelector).is(':checked') &&\n                $(this.options.changePasswordSelector).is(':checked')) {\n                this._showAll();\n            } else if ($(this.options.changeEmailSelector).is(':checked')) {\n                this._showEmail();\n            } else if ($(this.options.changePasswordSelector).is(':checked')) {\n                this._showPassword();\n            } else {\n                this._hideAll();\n            }\n        },\n\n        /**\n         * Show email and password input fields\n         * @private\n         */\n        _showAll: function () {\n            $(this.options.titleSelector).html(this.options.titleChangeEmailAndPassword);\n\n            $(this.options.mainContainerSelector).show();\n            $(this.options.emailContainerSelector).show();\n            $(this.options.newPasswordContainerSelector).show();\n            $(this.options.confirmPasswordContainerSelector).show();\n\n            $(this.options.currentPasswordSelector).attr('data-validate', '{required:true}').prop('disabled', false);\n            $(this.options.emailSelector).attr('data-validate', '{required:true}').prop('disabled', false);\n            this._updatePasswordFieldWithEmailValue();\n            $(this.options.confirmPasswordSelector).attr(\n                'data-validate',\n                '{required:true, equalTo:\"' + this.options.newPasswordSelector + '\"}'\n            ).prop('disabled', false);\n        },\n\n        /**\n         * Hide email and password input fields\n         * @private\n         */\n        _hideAll: function () {\n            $(this.options.mainContainerSelector).hide();\n            $(this.options.emailContainerSelector).hide();\n            $(this.options.newPasswordContainerSelector).hide();\n            $(this.options.confirmPasswordContainerSelector).hide();\n\n            $(this.options.currentPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n            $(this.options.emailSelector).removeAttr('data-validate').prop('disabled', true);\n            $(this.options.newPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n            $(this.options.confirmPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n        },\n\n        /**\n         * Show email input fields\n         * @private\n         */\n        _showEmail: function () {\n            this._showAll();\n            $(this.options.titleSelector).html(this.options.titleChangeEmail);\n\n            $(this.options.newPasswordContainerSelector).hide();\n            $(this.options.confirmPasswordContainerSelector).hide();\n\n            $(this.options.newPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n            $(this.options.confirmPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n        },\n\n        /**\n         * Show password input fields\n         * @private\n         */\n        _showPassword: function () {\n            this._showAll();\n            $(this.options.titleSelector).html(this.options.titleChangePassword);\n\n            $(this.options.emailContainerSelector).hide();\n\n            $(this.options.emailSelector).removeAttr('data-validate').prop('disabled', true);\n        },\n\n        /**\n         * Update password validation rules with email input field value\n         * @private\n         */\n        _updatePasswordFieldWithEmailValue: function () {\n            $(this.options.newPasswordSelector).attr(\n                'data-validate',\n                '{required:true, ' +\n                '\\'validate-customer-password\\':true, ' +\n                '\\'password-not-equal-to-user-name\\':\\'' + $(this.options.emailSelector).val() + '\\'}'\n            ).prop('disabled', false);\n        }\n    });\n\n    return $.mage.changeEmailPassword;\n});\n","Magento_Customer/js/address.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Ui/js/modal/confirm',\n    'jquery-ui-modules/widget',\n    'mage/translate'\n], function ($, confirm) {\n    'use strict';\n\n    $.widget('mage.address', {\n        /**\n         * Options common to all instances of this widget.\n         * @type {Object}\n         */\n        options: {\n            deleteConfirmMessage: $.mage.__('Are you sure you want to delete this address?')\n        },\n\n        /**\n         * Bind event handlers for adding and deleting addresses.\n         * @private\n         */\n        _create: function () {\n            var options         = this.options,\n                addAddress      = options.addAddress,\n                deleteAddress   = options.deleteAddress;\n\n            if (addAddress) {\n                $(document).on('click', addAddress, this._addAddress.bind(this));\n            }\n\n            if (deleteAddress) {\n                $(document).on('click', deleteAddress, this._deleteAddress.bind(this));\n            }\n        },\n\n        /**\n         * Add a new address.\n         * @private\n         */\n        _addAddress: function () {\n            window.location = this.options.addAddressLocation;\n        },\n\n        /**\n         * Delete the address whose id is specified in a data attribute after confirmation from the user.\n         * @private\n         * @param {jQuery.Event} e\n         * @return {Boolean}\n         */\n        _deleteAddress: function (e) {\n            var self = this;\n\n            confirm({\n                content: this.options.deleteConfirmMessage,\n                actions: {\n\n                    /** @inheritdoc */\n                    confirm: function () {\n                        if (typeof $(e.target).parent().data('address') !== 'undefined') {\n                            window.location = self.options.deleteUrlPrefix + $(e.target).parent().data('address') +\n                                '/form_key/' + $.mage.cookies.get('form_key');\n                        } else {\n                            window.location = self.options.deleteUrlPrefix + $(e.target).data('address') +\n                                '/form_key/' + $.mage.cookies.get('form_key');\n                        }\n                    }\n                }\n            });\n\n            return false;\n        }\n    });\n\n    return $.mage.address;\n});\n","Magento_Customer/js/invalidation-processor.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'uiElement',\n    'Magento_Customer/js/customer-data'\n], function (_, Element, customerData) {\n    'use strict';\n\n    return Element.extend({\n        /**\n         * Initialize object\n         */\n        initialize: function () {\n            this._super();\n            this.process(customerData);\n        },\n\n        /**\n         * Process all rules in loop, each rule can invalidate some sections in customer data\n         *\n         * @param {Object} customerDataObject\n         */\n        process: function (customerDataObject) {\n            _.each(this.invalidationRules, function (rule, ruleName) {\n                _.each(rule, function (ruleArgs, rulePath) {\n                    require([rulePath], function (Rule) {\n                        var currentRule = new Rule(ruleArgs);\n\n                        if (!_.isFunction(currentRule.process)) {\n                            throw new Error('Rule ' + ruleName + ' should implement invalidationProcessor interface');\n                        }\n                        currentRule.process(customerDataObject);\n                    });\n                });\n            });\n        }\n    });\n});\n","Magento_Customer/js/show-password.js":"/**\n* Copyright \u00a9 Magento, Inc. All rights reserved.\n* See COPYING.txt for license details.\n*/\n\ndefine([\n    'jquery',\n    'uiComponent'\n], function ($, Component) {\n    'use strict';\n\n    return Component.extend({\n        passwordSelector: '',\n        passwordInputType: 'password',\n        textInputType: 'text',\n\n        defaults: {\n            template: 'Magento_Customer/show-password',\n            isPasswordVisible: false\n        },\n\n        /**\n         * @return {Object}\n         */\n        initObservable: function () {\n            this._super()\n                .observe(['isPasswordVisible']);\n\n            this.isPasswordVisible.subscribe(function (isChecked) {\n                this._showPassword(isChecked);\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Show/Hide password\n         * @private\n         */\n        _showPassword: function (isChecked) {\n            $(this.passwordSelector).attr('type',\n                isChecked ? this.textInputType : this.passwordInputType\n            );\n        }\n    });\n});\n","Magento_Customer/js/section-config.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['underscore'], function (_) {\n    'use strict';\n\n    var baseUrls = [],\n        sections = [],\n        clientSideSections = [],\n        sectionNames = [],\n        canonize;\n\n    /**\n     * @param {String} url\n     * @return {String}\n     */\n    canonize = function (url) {\n        var route = url;\n\n        _.some(baseUrls, function (baseUrl) {\n            route = url.replace(baseUrl, '');\n\n            return route !== url;\n        });\n\n        return route.replace(/^\\/?index.php\\/?/, '').toLowerCase();\n    };\n\n    return {\n        /**\n         * Returns a list of sections which should be invalidated for given URL.\n         * @param {String} url - URL which was requested.\n         * @return {Object} - List of sections to invalidate.\n         */\n        getAffectedSections: function (url) {\n            var route = canonize(url),\n                actions = _.find(sections, function (val, section) {\n                    var matched;\n\n                    // Covers the case where \"*\" works as a glob pattern.\n                    if (section.indexOf('*') >= 0) {\n                        section = section.replace(/\\*/g, '[^/]+') + '$';\n                        matched = route.match(section);\n\n                        return matched && matched[0] === route;\n                    }\n\n                    return route.indexOf(section) === 0;\n                });\n\n            return _.union(_.toArray(actions), sections['*']);\n        },\n\n        /**\n         * Filters the list of given sections to the ones defined as client side.\n         * @param {Object} allSections - List of sections to check.\n         * @return {Object} - List of filtered sections.\n         */\n        filterClientSideSections: function (allSections) {\n            return _.difference(allSections, clientSideSections);\n        },\n\n        /**\n         * Tells if section is defined as client side.\n         * @param {String} sectionName - Name of the section to check.\n         * @return {Boolean}\n         */\n        isClientSideSection: function (sectionName) {\n            return _.contains(clientSideSections, sectionName);\n        },\n\n        /**\n         * Returns array of section names.\n         * @returns {Array}\n         */\n        getSectionNames: function () {\n            return sectionNames;\n        },\n\n        /**\n         * @param {Object} options\n         * @constructor\n         */\n        'Magento_Customer/js/section-config': function (options) {\n            baseUrls = options.baseUrls;\n            sections = options.sections;\n            clientSideSections = options.clientSideSections;\n            sectionNames = options.sectionNames;\n        }\n    };\n});\n","Magento_Customer/js/view/authentication-popup.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'ko',\n    'Magento_Ui/js/form/form',\n    'Magento_Customer/js/action/login',\n    'Magento_Customer/js/customer-data',\n    'Magento_Customer/js/model/authentication-popup',\n    'mage/translate',\n    'mage/url',\n    'Magento_Ui/js/modal/alert',\n    'mage/validation'\n], function ($, ko, Component, loginAction, customerData, authenticationPopup, $t, url, alert) {\n    'use strict';\n\n    return Component.extend({\n        registerUrl: window.authenticationPopup.customerRegisterUrl,\n        forgotPasswordUrl: window.authenticationPopup.customerForgotPasswordUrl,\n        autocomplete: window.authenticationPopup.autocomplete,\n        modalWindow: null,\n        isLoading: ko.observable(false),\n\n        defaults: {\n            template: 'Magento_Customer/authentication-popup'\n        },\n\n        /**\n         * Init\n         */\n        initialize: function () {\n            var self = this;\n\n            this._super();\n            url.setBaseUrl(window.authenticationPopup.baseUrl);\n            loginAction.registerLoginCallback(function () {\n                self.isLoading(false);\n            });\n        },\n\n        /** Init popup login window */\n        setModalElement: function (element) {\n            if (authenticationPopup.modalWindow == null) {\n                authenticationPopup.createPopUp(element);\n            }\n        },\n\n        /** Is login form enabled for current customer */\n        isActive: function () {\n            var customer = customerData.get('customer');\n\n            return customer() == false; //eslint-disable-line eqeqeq\n        },\n\n        /** Show login popup window */\n        showModal: function () {\n            if (this.modalWindow) {\n                $(this.modalWindow).modal('openModal');\n            } else {\n                alert({\n                    content: $t('Guest checkout is disabled.')\n                });\n            }\n        },\n\n        /**\n         * Provide login action\n         *\n         * @return {Boolean}\n         */\n        login: function (formUiElement, event) {\n            var loginData = {},\n                formElement = $(event.currentTarget),\n                formDataArray = formElement.serializeArray();\n\n            event.stopPropagation();\n            formDataArray.forEach(function (entry) {\n                loginData[entry.name] = entry.value;\n            });\n            loginData['customerLoginUrl'] = window.authenticationPopup.customerLoginUrl;\n            if (formElement.validation() &&\n                formElement.validation('isValid')\n            ) {\n                this.isLoading(true);\n                loginAction(loginData);\n            }\n\n            return false;\n        }\n    });\n});\n","Magento_Customer/js/view/customer.js":"/**\n* Copyright \u00a9 Magento, Inc. All rights reserved.\n* See COPYING.txt for license details.\n*/\n\ndefine([\n    'uiComponent',\n    'Magento_Customer/js/customer-data'\n], function (Component, customerData) {\n    'use strict';\n\n    return Component.extend({\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n\n            this.customer = customerData.get('customer');\n        }\n    });\n});\n","Magento_Customer/js/action/login.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/storage',\n    'Magento_Ui/js/model/messageList',\n    'Magento_Customer/js/customer-data',\n    'mage/translate'\n], function ($, storage, globalMessageList, customerData, $t) {\n    'use strict';\n\n    var callbacks = [],\n\n        /**\n         * @param {Object} loginData\n         * @param {String} redirectUrl\n         * @param {*} isGlobal\n         * @param {Object} messageContainer\n         */\n        action = function (loginData, redirectUrl, isGlobal, messageContainer) {\n            messageContainer = messageContainer || globalMessageList;\n            let customerLoginUrl = 'customer/ajax/login';\n\n            if (loginData.customerLoginUrl) {\n                customerLoginUrl = loginData.customerLoginUrl;\n                delete loginData.customerLoginUrl;\n            }\n\n            return storage.post(\n                customerLoginUrl,\n                JSON.stringify(loginData),\n                isGlobal\n            ).done(function (response) {\n                if (response.errors) {\n                    messageContainer.addErrorMessage(response);\n                    callbacks.forEach(function (callback) {\n                        callback(loginData);\n                    });\n                } else {\n                    callbacks.forEach(function (callback) {\n                        callback(loginData);\n                    });\n                    customerData.invalidate(['customer']);\n\n                    if (response.redirectUrl) {\n                        window.location.href = response.redirectUrl;\n                    } else if (redirectUrl) {\n                        window.location.href = redirectUrl;\n                    } else {\n                        location.reload();\n                    }\n                }\n            }).fail(function () {\n                messageContainer.addErrorMessage({\n                    'message': $t('Could not authenticate. Please try again later')\n                });\n                callbacks.forEach(function (callback) {\n                    callback(loginData);\n                });\n            });\n        };\n\n    /**\n     * @param {Function} callback\n     */\n    action.registerLoginCallback = function (callback) {\n        callbacks.push(callback);\n    };\n\n    return action;\n});\n","Magento_Customer/js/action/check-email-availability.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'mage/storage',\n    'Magento_Checkout/js/model/url-builder'\n], function (storage, urlBuilder) {\n    'use strict';\n\n    return function (deferred, email) {\n        return storage.post(\n            urlBuilder.createUrl('/customers/isEmailAvailable', {}),\n            JSON.stringify({\n                customerEmail: email\n            }),\n            false\n        ).done(function (isEmailAvailable) {\n            if (isEmailAvailable) {\n                deferred.resolve();\n            } else {\n                deferred.reject();\n            }\n        }).fail(function () {\n            deferred.reject();\n        });\n    };\n});\n","Magento_Customer/js/model/address-list.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'ko',\n    './customer-addresses'\n], function (ko, defaultProvider) {\n    'use strict';\n\n    return ko.observableArray(defaultProvider.getAddressItems());\n});\n","Magento_Customer/js/model/authentication-popup.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Ui/js/modal/modal'\n], function ($, modal) {\n    'use strict';\n\n    return {\n        modalWindow: null,\n\n        /**\n         * Create popUp window for provided element\n         *\n         * @param {HTMLElement} element\n         */\n        createPopUp: function (element) {\n            var options = {\n                'type': 'popup',\n                'modalClass': 'popup-authentication',\n                'focus': '[name=username]',\n                'responsive': true,\n                'innerScroll': true,\n                'trigger': '.proceed-to-checkout',\n                'buttons': []\n            };\n\n            this.modalWindow = element;\n            modal(options, $(this.modalWindow));\n        },\n\n        /** Show login popup window */\n        showModal: function () {\n            $(this.modalWindow).modal('openModal').trigger('contentUpdated');\n        }\n    };\n});\n","Magento_Customer/js/model/customer-addresses.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    'ko',\n    './customer/address'\n], function ($, ko, Address) {\n    'use strict';\n\n    var isLoggedIn = ko.observable(window.isCustomerLoggedIn);\n\n    return {\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_Customer/js/model/customer.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    'ko',\n    'underscore',\n    './address-list'\n], function ($, ko, _, addressList) {\n    'use strict';\n\n    var isLoggedIn = ko.observable(window.isCustomerLoggedIn),\n        customerData = {};\n\n    if (isLoggedIn()) {\n        customerData = window.customerData;\n    } else {\n        customerData = {};\n    }\n\n    return {\n        customerData: customerData,\n        customerDetails: {},\n        isLoggedIn: isLoggedIn,\n\n        /**\n         * @param {Boolean} flag\n         */\n        setIsLoggedIn: function (flag) {\n            isLoggedIn(flag);\n        },\n\n        /**\n         * @return {Array}\n         */\n        getBillingAddressList: function () {\n            return addressList();\n        },\n\n        /**\n         * @return {Array}\n         */\n        getShippingAddressList: function () {\n            return addressList();\n        },\n\n        /**\n         * @param {String} fieldName\n         * @param {*} value\n         */\n        setDetails: function (fieldName, value) {\n            if (fieldName) {\n                this.customerDetails[fieldName] = value;\n            }\n        },\n\n        /**\n         * @param {String} fieldName\n         * @return {*}\n         */\n        getDetails: function (fieldName) {\n            if (fieldName) {\n                if (this.customerDetails.hasOwnProperty(fieldName)) {\n                    return this.customerDetails[fieldName];\n                }\n\n                return undefined;\n            }\n\n            return this.customerDetails;\n        },\n\n        /**\n         * @param {Array} address\n         * @return {Number}\n         */\n        addCustomerAddress: function (address) {\n            var fields = [\n                    'customer_id', 'country_id', 'street', 'company', 'telephone', 'fax', 'postcode', 'city',\n                    'firstname', 'lastname', 'middlename', 'prefix', 'suffix', 'vat_id', 'default_billing',\n                    'default_shipping'\n                ],\n                customerAddress = {},\n                hasAddress = 0,\n                existingAddress;\n\n            if (!this.customerData.addresses) {\n                this.customerData.addresses = [];\n            }\n\n            customerAddress = _.pick(address, fields);\n\n            if (address.hasOwnProperty('region_id')) {\n                customerAddress.region = {\n                    'region_id': address['region_id'],\n                    region: address.region\n                };\n            }\n\n            for (existingAddress in this.customerData.addresses) {\n                if (this.customerData.addresses.hasOwnProperty(existingAddress)) {\n                    if (_.isEqual(this.customerData.addresses[existingAddress], customerAddress)) { //eslint-disable-line\n                        hasAddress = existingAddress;\n                        break;\n                    }\n                }\n            }\n\n            if (hasAddress === 0) {\n                return this.customerData.addresses.push(customerAddress) - 1;\n            }\n\n            return hasAddress;\n        },\n\n        /**\n         * @param {*} addressId\n         * @return {Boolean}\n         */\n        setAddressAsDefaultBilling: function (addressId) {\n            if (this.customerData.addresses[addressId]) {\n                this.customerData.addresses[addressId]['default_billing'] = 1;\n\n                return true;\n            }\n\n            return false;\n        },\n\n        /**\n         * @param {*} addressId\n         * @return {Boolean}\n         */\n        setAddressAsDefaultShipping: function (addressId) {\n            if (this.customerData.addresses[addressId]) {\n                this.customerData.addresses[addressId]['default_shipping'] = 1;\n\n                return true;\n            }\n\n            return false;\n        }\n    };\n});\n","Magento_Customer/js/model/customer/address.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine(['underscore'], function (_) {\n    'use strict';\n\n    /**\n     * Returns new address object.\n     *\n     * @param {Object} addressData\n     * @return {Object}\n     */\n    return function (addressData) {\n        var regionId;\n\n        if (addressData.region['region_id'] && addressData.region['region_id'] !== '0') {\n            regionId = addressData.region['region_id'] + '';\n        }\n\n        return {\n            customerAddressId: addressData.id,\n            email: addressData.email,\n            countryId: addressData['country_id'],\n            regionId: regionId,\n            regionCode: addressData.region['region_code'],\n            region: addressData.region.region,\n            customerId: addressData['customer_id'],\n            street: addressData.street,\n            company: addressData.company,\n            telephone: addressData.telephone,\n            fax: addressData.fax,\n            postcode: addressData.postcode,\n            city: addressData.city,\n            firstname: addressData.firstname,\n            lastname: addressData.lastname,\n            middlename: addressData.middlename,\n            prefix: addressData.prefix,\n            suffix: addressData.suffix,\n            vatId: addressData['vat_id'],\n            sameAsBilling: addressData['same_as_billing'],\n            saveInAddressBook: addressData['save_in_address_book'],\n            customAttributes: _.toArray(addressData['custom_attributes']).reverse(),\n\n            /**\n             * @return {*}\n             */\n            isDefaultShipping: function () {\n                return addressData['default_shipping'];\n            },\n\n            /**\n             * @return {*}\n             */\n            isDefaultBilling: function () {\n                return addressData['default_billing'];\n            },\n\n            /**\n             * @return {*}\n             */\n            getAddressInline: function () {\n                return addressData.inline;\n            },\n\n            /**\n             * @return {String}\n             */\n            getType: function () {\n                return 'customer-address';\n            },\n\n            /**\n             * @return {String}\n             */\n            getKey: function () {\n                return this.getType() + this.customerAddressId;\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 true;\n            }\n        };\n    };\n});\n","Magento_Customer/js/invalidation-rules/website-rule.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'uiClass'\n], function (Element) {\n    'use strict';\n\n    return Element.extend({\n\n        defaults: {\n            scopeConfig: {}\n        },\n\n        /**\n         * Takes website id from current customer data and compare it with current website id\n         * If customer belongs to another scope, we need to invalidate current section\n         *\n         * @param {Object} customerData\n         */\n        process: function (customerData) {\n            var customer = customerData.get('customer');\n\n            if (this.scopeConfig && customer() &&\n                ~~customer().websiteId !== ~~this.scopeConfig.websiteId && ~~customer().websiteId !== 0) {\n                customerData.reload(['customer']);\n            }\n        }\n    });\n});\n","Magento_Directory/js/region-updater.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    'underscore',\n    'jquery-ui-modules/widget',\n    'mage/validation'\n], function ($, mageTemplate, _) {\n    'use strict';\n\n    $.widget('mage.directoryRegionUpdater', {\n        options: {\n            regionTemplate:\n                '<option value=\"<%- data.value %>\" <% if (data.isSelected) { %>selected=\"selected\"<% } %>>' +\n                '<%- data.title %>' +\n                '</option>',\n            isRegionRequired: true,\n            isZipRequired: true,\n            isCountryRequired: true,\n            currentRegion: null,\n            isMultipleCountriesAllowed: true\n        },\n\n        /**\n         *\n         * @private\n         */\n        _create: function () {\n            this._initCountryElement();\n\n            this.currentRegionOption = this.options.currentRegion;\n            this.regionTmpl = mageTemplate(this.options.regionTemplate);\n\n            this._updateRegion(this.element.find('option:selected').val());\n\n            $(this.options.regionListId).on('change', $.proxy(function (e) {\n                this.setOption = false;\n                this.currentRegionOption = $(e.target).val();\n            }, this));\n\n            $(this.options.regionInputId).on('focusout', $.proxy(function () {\n                this.setOption = true;\n            }, this));\n        },\n\n        /**\n         *\n         * @private\n         */\n        _initCountryElement: function () {\n\n            if (this.options.isMultipleCountriesAllowed) {\n                this.element.parents('div.field').show();\n                this.element.on('change', $.proxy(function (e) {\n                    // clear region inputs on country change\n                    $(this.options.regionListId).val('');\n                    $(this.options.regionInputId).val('');\n                    this._updateRegion($(e.target).val());\n                }, this));\n\n                if (this.options.isCountryRequired) {\n                    this.element.addClass('required-entry');\n                    this.element.parents('div.field').addClass('required');\n                }\n            } else {\n                this.element.parents('div.field').hide();\n            }\n        },\n\n        /**\n         * Remove options from dropdown list\n         *\n         * @param {Object} selectElement - jQuery object for dropdown list\n         * @private\n         */\n        _removeSelectOptions: function (selectElement) {\n            selectElement.find('option').each(function (index) {\n                if (index) {\n                    $(this).remove();\n                }\n            });\n        },\n\n        /**\n         * Render dropdown list\n         * @param {Object} selectElement - jQuery object for dropdown list\n         * @param {String} key - region code\n         * @param {Object} value - region object\n         * @private\n         */\n        _renderSelectOption: function (selectElement, key, value) {\n            selectElement.append($.proxy(function () {\n                var name = value.name.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&'),\n                    tmplData,\n                    tmpl;\n\n                if (value.code && $(name).is('span')) {\n                    key = value.code;\n                    value.name = $(name).text();\n                }\n\n                tmplData = {\n                    value: key,\n                    title: value.name,\n                    isSelected: false\n                };\n\n                if (this.options.defaultRegion === key) {\n                    tmplData.isSelected = true;\n                }\n\n                tmpl = this.regionTmpl({\n                    data: tmplData\n                });\n\n                return $(tmpl);\n            }, this));\n        },\n\n        /**\n         * Takes clearError callback function as first option\n         * If no form is passed as option, look up the closest form and call clearError method.\n         * @private\n         */\n        _clearError: function () {\n            var args = ['clearError', this.options.regionListId, this.options.regionInputId, this.options.postcodeId];\n\n            if (this.options.clearError && typeof this.options.clearError === 'function') {\n                this.options.clearError.call(this);\n            } else {\n                if (!this.options.form) {\n                    this.options.form = this.element.closest('form').length ? $(this.element.closest('form')[0]) : null;\n                }\n\n                this.options.form = $(this.options.form);\n\n                this.options.form && this.options.form.data('validator') &&\n                this.options.form.validation.apply(this.options.form, _.compact(args));\n\n                // Clean up errors on region & zip fix\n                $(this.options.regionInputId).removeClass('mage-error').parent().find('[generated]').remove();\n                $(this.options.regionListId).removeClass('mage-error').parent().find('[generated]').remove();\n                $(this.options.postcodeId).removeClass('mage-error').parent().find('[generated]').remove();\n            }\n        },\n\n        /**\n         * Update dropdown list based on the country selected\n         *\n         * @param {String} country - 2 uppercase letter for country code\n         * @private\n         */\n        _updateRegion: function (country) {\n            // Clear validation error messages\n            var regionList = $(this.options.regionListId),\n                regionInput = $(this.options.regionInputId),\n                postcode = $(this.options.postcodeId),\n                label = regionList.parent().siblings('label'),\n                container = regionList.parents('div.field'),\n                regionsEntries,\n                regionId,\n                regionData;\n\n            this._clearError();\n            this._checkRegionRequired(country);\n\n            // Populate state/province dropdown list if available or use input box\n            if (this.options.regionJson[country]) {\n                this._removeSelectOptions(regionList);\n                regionsEntries = _.pairs(this.options.regionJson[country]);\n                $.each(regionsEntries, $.proxy(function (key, value) {\n                    regionData = value[1];\n                    regionId = regionData.id;\n                    this._renderSelectOption(regionList, regionId.toString(), regionData);\n                }, this));\n\n                if (this.currentRegionOption) {\n                    regionList.val(this.currentRegionOption);\n                }\n\n                if (this.setOption) {\n                    regionList.find('option').filter(function () {\n                        return this.text === regionInput.val();\n                    }).attr('selected', true);\n                }\n\n                if (this.options.isRegionRequired) {\n                    regionList.addClass('required-entry').removeAttr('disabled');\n                    container.addClass('required').show();\n                } else {\n                    regionList.removeClass('required-entry validate-select').removeAttr('data-validate');\n                    container.removeClass('required');\n\n                    if (!this.options.optionalRegionAllowed) { //eslint-disable-line max-depth\n                        regionList.hide();\n                        container.hide();\n                    } else {\n                        regionList.removeAttr('disabled').show();\n                    }\n                }\n\n                regionList.show();\n                regionInput.hide();\n                label.attr('for', regionList.attr('id'));\n            } else {\n                this._removeSelectOptions(regionList);\n\n                if (this.options.isRegionRequired) {\n                    regionInput.addClass('required-entry').removeAttr('disabled');\n                    container.addClass('required').show();\n                } else {\n                    if (!this.options.optionalRegionAllowed) { //eslint-disable-line max-depth\n                        regionInput.attr('disabled', 'disabled');\n                        container.hide();\n                    }\n                    container.removeClass('required');\n                    regionInput.removeClass('required-entry');\n                }\n\n                regionList.removeClass('required-entry').prop('disabled', 'disabled').hide();\n                regionInput.show();\n                label.attr('for', regionInput.attr('id'));\n            }\n\n            // If country is in optionalzip list, make postcode input not required\n            if (this.options.isZipRequired) {\n                $.inArray(country, this.options.countriesWithOptionalZip) >= 0 ?\n                    postcode.removeClass('required-entry').closest('.field').removeClass('required') :\n                    postcode.addClass('required-entry').closest('.field').addClass('required');\n            }\n\n            // Add defaultvalue attribute to state/province select element\n            regionList.attr('defaultvalue', this.options.defaultRegion);\n            this.options.form.find('[type=\"submit\"]').removeAttr('disabled').show();\n        },\n\n        /**\n         * Check if the selected country has a mandatory region selection\n         *\n         * @param {String} country - Code of the country - 2 uppercase letter for country code\n         * @private\n         */\n        _checkRegionRequired: function (country) {\n            var self = this;\n\n            this.options.isRegionRequired = false;\n            $.each(this.options.regionJson.config['regions_required'], function (index, elem) {\n                if (elem === country) {\n                    self.options.isRegionRequired = true;\n                }\n            });\n        }\n    });\n\n    return $.mage.directoryRegionUpdater;\n});\n","Magento_Theme/js/cookie-status.js":"define([\n    'jquery',\n    'Magento_Ui/js/modal/modal',\n    'mage/translate'\n], function ($, modal) {\n    'use strict';\n\n    $.widget('mage.cookieStatus', {\n        options: {\n            type: 'popup',\n            responsive: true,\n            innerScroll: true,\n            autoOpen: true,\n            buttons: [{\n                text: $.mage.__('Close'),\n                class: 'cookie-status',\n\n                /**\n                 * Callback for click event\n                 */\n                click: function () {\n                    this.closeModal();\n                }\n            }]\n        },\n\n        /**\n         * Init object\n         * @private\n         */\n        _init: function () {\n\n            if (!navigator.cookieEnabled) {\n                modal(this.options, $('#cookie-status'));\n            }\n        }\n    });\n\n    return $.mage.cookieStatus;\n});\n","Magento_Theme/js/row-builder.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * JQuery UI Widget declaration: 'mage.rowBuilder'\n *\n * @api\n */\ndefine([\n    'jquery',\n    'mage/template',\n    'jquery-ui-modules/widget'\n], function ($, mageTemplate) {\n    'use strict';\n\n    $.widget('mage.rowBuilder', {\n\n        /**\n         * options with default values for setting up the template\n         */\n        options: {\n            //Default template options\n            rowTemplate: '#template-registrant',\n            rowContainer: '#registrant-container',\n            //Row index used by the template rows.\n            rowIndex: 0,\n            //Row count: Should not be set externally\n            rowCount: 0,\n            rowParentElem: '<li></li>',\n            rowContainerClass: 'fields',\n            addRowBtn: '#add-registrant-button',\n            btnRemoveIdPrefix: 'btn-remove',\n            btnRemoveSelector: '.btn-remove',\n            rowIdPrefix: 'row',\n            //This class is added to rows added after the first one. Adds the dotted separator\n            additionalRowClass: 'add-row',\n\n            /*\n             This is provided during widget instantiation. eg :\n             formDataPost : {\"formData\":formData,\"templateFields\":['field1-name','field2-name'] }\n             -\"formData\" is the multi-dimensional array of form field values : [['a','b'],['c','b']]\n             received from the server and encoded\n             -\"templateFields\" are the input fields in the template with index suffixed after the field name\n             eg field1-name{index}\n             */\n            formDataPost: null,\n            //Default selectors for add element of a template\n            addEventSelector: 'button',\n            //Default selectors for remove markup elements of a template\n            remEventSelector: 'a',\n            //This option allows adding first row delete option and a row separator\n            hideFirstRowAddSeparator: true,\n            //Max rows - This option should be set when instantiating the widget\n            maxRows: 1000,\n            maxRowsMsg: '#max-registrant-message'\n        },\n\n        /**\n         * Initialize create\n         * @private\n         */\n        _create: function () {\n            this.rowTemplate = mageTemplate(this.options.rowTemplate);\n\n            this.options.rowCount = this.options.rowIndex = 0;\n\n            //On document ready related tasks\n            $($.proxy(this.ready, this));\n\n            //Binding template-wide events handlers for adding and removing rows\n            this.element.on(\n                'click',\n                this.options.addEventSelector + this.options.addRowBtn,\n                $.proxy(this.handleAdd, this)\n            );\n            this.element.on(\n                'click',\n                this.options.remEventSelector + this.options.btnRemoveSelector,\n                $.proxy(this.handleRemove, this)\n            );\n        },\n\n        /**\n         * Initialize template\n         * @public\n         */\n        ready: function () {\n            if (this.options.formDataPost &&\n                this.options.formDataPost.formData &&\n                this.options.formDataPost.formData.length\n            ) {\n                this.processFormDataArr(this.options.formDataPost);\n            } else if (this.options.rowIndex === 0 && this.options.maxRows !== 0) {\n                //If no form data , then add default row\n                this.addRow(0);\n            }\n        },\n\n        /**\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                templateFields = formDataArr.templateFields,\n                formRow,\n                i, j;\n\n            for (i = this.options.rowIndex = 0; i < formData.length; this.options.rowIndex = i++) {\n                this.addRow(i);\n\n                formRow = formData[i];\n\n                for (j = 0; j < formRow.length; j++) {\n                    this.setFieldById(templateFields[j] + i, formRow[j]);\n                }\n            }\n\n        },\n\n        /**\n         * Initialize and create markup for template row. Add it to the parent container.\n         * The template processing will substitute row index at all places marked with _index_ in the template\n         * using the template\n         * @public\n         * @param {Number} index - current index/count of the created template. This will be used as the id\n         * @return {*}\n         */\n        addRow: function (index) {\n            var row = $(this.options.rowParentElem),\n                tmpl;\n\n            row.addClass(this.options.rowContainerClass).attr('id', this.options.rowIdPrefix + index);\n\n            tmpl = this.rowTemplate({\n                data: {\n                    _index_: index\n                }\n            });\n\n            $(tmpl).appendTo(row);\n\n            $(this.options.rowContainer).append(row).trigger('contentUpdated');\n\n            row.addClass(this.options.additionalRowClass);\n\n            //Remove 'delete' link and additionalRowClass for first row\n            if (this.options.rowIndex === 0 && this.options.hideFirstRowAddSeparator) {\n                $('#' + this._esc(this.options.btnRemoveIdPrefix) + '0').remove();\n                $('#' + this._esc(this.options.rowIdPrefix) + '0').removeClass(this.options.additionalRowClass);\n            }\n\n            this.maxRowCheck(++this.options.rowCount);\n\n            return row;\n        },\n\n        /**\n         * Remove return item information row\n         * @public\n         * @param {*} rowIndex - return item information row index\n         * @return {Boolean}\n         */\n        removeRow: function (rowIndex) {\n            $('#' + this._esc(this.options.rowIdPrefix) + rowIndex).remove();\n            this.maxRowCheck(--this.options.rowCount);\n\n            return false;\n        },\n\n        /**\n         * Function to check if maximum rows are exceeded and render/hide maxMsg and Add btn\n         * @public\n         * @param {Number} rowIndex\n         */\n        maxRowCheck: function (rowIndex) {\n            var addRowBtn = $(this.options.addRowBtn),\n                maxRowMsg = $(this.options.maxRowsMsg);\n\n            //liIndex starts from 0\n            if (rowIndex >= this.options.maxRows) {\n                addRowBtn.hide();\n                maxRowMsg.show();\n            } else if (addRowBtn.is(':hidden')) {\n                addRowBtn.show();\n                maxRowMsg.hide();\n            }\n        },\n\n        /**\n         * Set the value on given element\n         * @public\n         * @param {String} domId\n         * @param {String} value\n         */\n        setFieldById: function (domId, value) {\n            var x = $('#' + this._esc(domId));\n\n            if (x.length) {\n\n                if (x.is(':checkbox')) {\n                    x.attr('checked', true);\n                } else if (x.is('option')) {\n                    x.attr('selected', 'selected');\n                } else {\n                    x.val(value);\n                }\n            }\n        },\n\n        /**\n         * Delegated handler for adding a row\n         * @public\n         * @return {Boolean}\n         */\n        handleAdd: function () {\n            this.addRow(++this.options.rowIndex);\n\n            return false;\n        },\n\n        /**\n         * Delegated handler for removing a selected row\n         * @public\n         * @param {Object} e - Native event object\n         * @return {Boolean}\n         */\n        handleRemove: function (e) {\n            this.removeRow($(e.currentTarget).closest('[id^=\"' + this.options.btnRemoveIdPrefix + '\"]')\n                .attr('id').replace(this.options.btnRemoveIdPrefix, ''));\n\n            return false;\n        },\n\n        /**\n         * Utility function to add escape chars for jquery selector strings\n         * @private\n         * @param {String} str - String to be processed\n         * @return {String}\n         */\n        _esc: function (str) {\n            return str ? str.replace(/([ ;&,.+*~\\':\"!\\^$\\[\\]()=>|\\/@])/g, '\\\\$1') : str;\n        }\n    });\n\n    return $.mage.rowBuilder;\n});\n","Magento_Theme/js/theme.js":"/**\n * Copyright \u00a9 2015 Magento. All rights reserved.\n * See COPYING.txt for license details.\n */\nrequire([\n    'jquery',\n    'mage/smart-keyboard-handler',\n    'mage/mage',\n    'domReady!'\n], function ($, keyboardHandler) {\n    'use strict';\n    $(document).ready(function(){\n        $('.cart-summary').mage('sticky', {\n            container: '#maincontent'\n        });\n\n        $('.panel.header .header.links').clone().appendTo('#store\\\\.links');\n    });\n    keyboardHandler.apply();\n});\nrequire([\n    'jquery'\n], function ($) {\n    (function() {\n        var ev = new $.Event('classadded'),\n            orig = $.fn.addClass;\n        $.fn.addClass = function() {\n            $(this).trigger(ev, arguments);\n            return orig.apply(this, arguments);\n        }\n    })();\n    $.fn.extend({\n        scrollToMe: function(){\n            if($(this).length){\n                var top = $(this).offset().top - 100;\n                $('html,body').animate({scrollTop: top}, 300);\n            }\n        },\n        scrollToJustMe: function(){\n            if($(this).length){\n                var top = jQuery(this).offset().top;\n                $('html,body').animate({scrollTop: top}, 300);\n            }\n        }\n    });\n    $(document).ready(function(){\n        var windowScroll_t;\n        $(window).scroll(function(){\n            clearTimeout(windowScroll_t);\n            windowScroll_t = setTimeout(function(){\n                if(jQuery(this).scrollTop() > 100){\n                    $('#totop').fadeIn();\n                }else{\n                    $('#totop').fadeOut();\n                }\n            }, 500);\n        });\n        $('#totop').off(\"click\").on(\"click\",function(){\n            $('html, body').animate({scrollTop: 0}, 600);\n        });\n        if ($('body').hasClass('checkout-cart-index')) {\n            if ($('#co-shipping-method-form .fieldset.rates').length > 0 && $('#co-shipping-method-form .fieldset.rates :checked').length === 0) {\n                $('#block-shipping').on('collapsiblecreate', function () {\n                    $('#block-shipping').collapsible('forceActivate');\n                });\n            }\n        }\n        $(\".products-grid .weltpixel-quickview\").each(function(){\n            $(this).parent().parent().addClass('has-quickview');\n            if($(this).parents('.product-type-advanced').find(\".product-item-photo.porto-tb-featured-image .icon-absolute\").length > 0){\n              $(this).appendTo($(this).parents('.product-type-advanced').find(\".product-item-photo .porto-tb-featured-image .product-item-inner .product-item-actions\"));\n            }else{\n              $(this).appendTo($(this).parent().parent().children(\".product-item-photo\"));\n            }\n        });\n        $(\".word-rotate\").each(function() {\n\n            var $this = $(this),\n                itemsWrapper = $(this).find(\".word-rotate-items\"),\n                items = itemsWrapper.find(\"> span\"),\n                firstItem = items.eq(0),\n                firstItemClone = firstItem.clone(),\n                itemHeight = 0,\n                currentItem = 1,\n                currentTop = 0;\n\n            itemHeight = firstItem.height();\n\n            itemsWrapper.append(firstItemClone);\n\n            $this\n                .height(itemHeight)\n                .addClass(\"active\");\n\n            setInterval(function() {\n                currentTop = (currentItem * itemHeight);\n\n                itemsWrapper.animate({\n                    top: -(currentTop) + \"px\"\n                }, 300, function() {\n                    currentItem++;\n                    if(currentItem > items.length) {\n                        itemsWrapper.css(\"top\", 0);\n                        currentItem = 1;\n                    }\n                });\n\n            }, 2000);\n\n        });\n        $(\".top-links-icon\").off(\"click\").on(\"click\", function(e){\n            if($(this).parent().children(\"ul.links\").hasClass(\"show\")) {\n                $(this).parent().children(\"ul.links\").removeClass(\"show\");\n            } else {\n                $(this).parent().children(\"ul.links\").addClass(\"show\");\n            }\n            e.stopPropagation();\n        });\n        $(\".top-links-icon\").parent().click(function(e){\n            e.stopPropagation();\n        });\n        $(\".search-toggle-icon\").click(function(e){\n            if($(this).parent().children(\".block-search\").hasClass(\"show\")) {\n                $(this).parent().children(\".block-search\").removeClass(\"show\");\n                $(this).removeClass('open');\n            } else {\n                $(this).parent().children(\".block-search\").addClass(\"show\");\n                $(this).addClass('open');\n            }\n            e.stopPropagation();\n        });\n        $(\".search-toggle-icon\").parent().click(function(e){\n            e.stopPropagation();\n        });\n        $(\"html,body\").click(function(){\n            $(\".search-toggle-icon\").parent().children(\".block-search\").removeClass(\"show\");\n            $('.autocomplete-suggestions').hide();\n            $(\".search-toggle-icon\").removeClass('open');\n            $(\".top-links-icon\").parent().children(\"ul.links\").removeClass(\"show\");\n        });\n\n        /********************* Qty Holder **************************/\n        $(document).on(\"click\", \".qtyplus\", function(e) {\n            // Stop acting like a button\n            e.preventDefault();\n            // Get its current value\n            var currentVal = parseInt($(this).parents('form').find('input[name=\"qty\"]').val());\n            // If is not undefined\n            if (!isNaN(currentVal)) {\n                // Increment\n                $(this).parents('form').find('input[name=\"qty\"]').val(currentVal + 1);\n            } else {\n                // Otherwise put a 0 there\n                $(this).parents('form').find('input[name=\"qty\"]').val(0);\n            }\n        });\n        // This button will decrement the value till 0\n        $(document).on(\"click\", \".qtyminus\", function(e) {\n            // Stop acting like a button\n            e.preventDefault();\n            // Get the field name\n            fieldName = $(this).attr('field');\n            // Get its current value\n            var currentVal = parseInt($(this).parents('form').find('input[name=\"qty\"]').val());\n            // If it isn't undefined or its greater than 0\n            if (!isNaN(currentVal) && currentVal > 0) {\n                // Decrement one\n                $(this).parents('form').find('input[name=\"qty\"]').val(currentVal - 1);\n            } else {\n                // Otherwise put a 0 there\n                $(this).parents('form').find('input[name=\"qty\"]').val(0);\n            }\n        });\n        $(\".qty-inc\").unbind('click').click(function(){\n            if($(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").is(':enabled')){\n                $(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").val((+$(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").val() + 1) || 0);\n                $(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").trigger('change');\n                $(this).focus();\n            }\n        });\n        $(\".qty-dec\").unbind('click').click(function(){\n            if($(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").is(':enabled')){\n                $(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").val(($(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").val() - 1 > 0) ? ($(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").val() - 1) : 0);\n                $(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").trigger('change');\n                $(this).focus();\n            }\n        });\n    });\n});\nrequire([\n    'jquery',\n    'lazyload'\n], function ($) {\n    $(document).ready(function(){\n        $(\"img.porto-lazyload:not(.porto-lazyload-loaded)\").lazyload({effect:\"fadeIn\", effect_speed: 400 });\n        if ($('.porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').length) {\n            $('.porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').on('initialized.owl.carousel', function() {\n                $(this).find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\n            });\n            $('.porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').on('changed.owl.carousel', function() {\n                $(this).find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\n            });\n        }\n        window.setTimeout(function(){\n            $('.sidebar-filterproducts').find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\n        },500);\n    });\n});\n","Magento_Theme/js/view/add-home-breadcrumb.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/* eslint-disable max-nested-callbacks, no-undef */\ndefine([\n    'jquery',\n    'Magento_Theme/js/model/breadcrumb-list',\n    'mage/translate'\n], function ($, breadcrumbList) {\n    'use strict';\n\n    /**\n     * @return {Object}\n     */\n    var homeCrumb = function () {\n        return {\n            name: 'home',\n            label: $.mage.__('Home'),\n            title: $.mage.__('Go to Home Page'),\n            link: BASE_URL || ''\n        };\n    };\n\n    return function (breadcrumb) {\n\n        breadcrumbList.unshift(homeCrumb());\n\n        return breadcrumb;\n    };\n});\n","Magento_Theme/js/view/breadcrumbs.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_Theme/js/model/breadcrumb-list',\n    'text!Magento_Theme/templates/breadcrumbs.html',\n    'jquery-ui-modules/widget'\n], function ($, mageTemplate, breadcrumbList, tpl) {\n    'use strict';\n\n    /**\n     * Breadcrumb Widget.\n     */\n    $.widget('mage.breadcrumbs', {\n\n        /** @inheritdoc */\n        _init: function () {\n            this._super();\n            this._render();\n        },\n\n        /**\n         * Render breadcrumb.\n         *\n         * @private\n         */\n        _render: function () {\n            var html,\n                crumbs = breadcrumbList,\n                template = mageTemplate(tpl);\n\n            this._decorate(crumbs);\n\n            html = template({\n                'breadcrumbs': crumbs\n            });\n\n            if (html.length) {\n                $(this.element).html(html);\n            }\n        },\n\n        /**\n         * Decorate list.\n         *\n         * @param {Array} list\n         * @private\n         */\n        _decorate: function (list) {\n\n            if (list.length) {\n                list[0].first = true;\n            }\n\n            if (list.length > 1) {\n                list[list.length - 1].last = true;\n            }\n        }\n    });\n\n    return $.mage.breadcrumbs;\n});\n","Magento_Theme/js/view/messages.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    'uiComponent',\n    'Magento_Customer/js/customer-data',\n    'underscore',\n    'escaper',\n    'jquery/jquery-storageapi'\n], function ($, Component, customerData, _, escaper) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            cookieMessages: [],\n            messages: [],\n            allowedTags: ['div', 'span', 'b', 'strong', 'i', 'em', 'u', 'a']\n        },\n\n        /**\n         * Extends Component object by storage observable messages.\n         */\n        initialize: function () {\n            this._super();\n\n            this.cookieMessages = _.unique($.cookieStorage.get('mage-messages'), 'text');\n            this.messages = customerData.get('messages').extend({\n                disposableCustomerData: 'messages'\n            });\n\n            // Force to clean obsolete messages\n            if (!_.isEmpty(this.messages().messages)) {\n                customerData.set('messages', {});\n            }\n\n            $.mage.cookies.set('mage-messages', '', {\n                samesite: 'strict',\n                domain: ''\n            });\n        },\n\n        /**\n         * Prepare the given message to be rendered as HTML\n         *\n         * @param {String} message\n         * @return {String}\n         */\n        prepareMessageForHtml: function (message) {\n            return escaper.escapeHtml(message, this.allowedTags);\n        }\n    });\n});\n","Magento_Theme/js/model/breadcrumb-list.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","Magento_Wishlist/js/wishlist.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    'mage/template',\n    'Magento_Ui/js/modal/alert',\n    'jquery-ui-modules/widget',\n    'mage/validation/validation',\n    'mage/dataPost'\n], function ($, mageTemplate, alert) {\n    'use strict';\n\n    $.widget('mage.wishlist', {\n        options: {\n            dataAttribute: 'item-id',\n            nameFormat: 'qty[{0}]',\n            btnRemoveSelector: '[data-role=remove]',\n            qtySelector: '[data-role=qty]',\n            addToCartSelector: '[data-role=tocart]',\n            addAllToCartSelector: '[data-role=all-tocart]',\n            commentInputType: 'textarea',\n            infoList: false\n        },\n\n        /**\n         * Bind handlers to events.\n         */\n        _create: function () {\n            var _this = this;\n\n            if (!this.options.infoList) {\n                this.element\n                    .on('addToCart', function (event, context) {\n                        var urlParams;\n\n                        event.stopPropagation(event);\n                        $(context).data('stop-processing', true);\n                        urlParams = _this._getItemsToCartParams(\n                            $(context).parents('[data-row=product-item]').find(_this.options.addToCartSelector)\n                        );\n                        $.mage.dataPost().postData(urlParams);\n\n                        return false;\n                    })\n                    .on('click', this.options.btnRemoveSelector, $.proxy(function (event) {\n                        event.preventDefault();\n                        $.mage.dataPost().postData($(event.currentTarget).data('post-remove'));\n                    }, this))\n                    .on('click', this.options.addToCartSelector, $.proxy(this._beforeAddToCart, this))\n                    .on('click', this.options.addAllToCartSelector, $.proxy(this._addAllWItemsToCart, this))\n                    .on('focusin focusout', this.options.commentInputType, $.proxy(this._focusComment, this));\n            }\n\n            // Setup validation for the form\n            this.element.mage('validation', {\n                /** @inheritdoc */\n                errorPlacement: function (error, element) {\n                    error.insertAfter(element.next());\n                }\n            });\n        },\n\n        /**\n         * Process data before add to cart\n         *\n         * - update item's qty value.\n         *\n         * @param {Event} event\n         * @private\n         */\n        _beforeAddToCart: function (event) {\n            var elem = $(event.currentTarget),\n                itemId = elem.data(this.options.dataAttribute),\n                qtyName = $.validator.format(this.options.nameFormat, itemId),\n                qtyValue = elem.parents().find('[name=\"' + qtyName + '\"]').val(),\n                params = elem.data('post');\n\n            if (params) {\n                params.data = $.extend({}, params.data, {\n                    'qty': qtyValue\n                });\n                elem.data('post', params);\n            }\n        },\n\n        /**\n         * Add wish list items to cart.\n         * @private\n         * @param {jQuery} elem - clicked 'add to cart' button\n         */\n        _getItemsToCartParams: function (elem) {\n            var itemId, url, qtyName, qtyValue;\n\n            if (elem.data(this.options.dataAttribute)) {\n                itemId = elem.data(this.options.dataAttribute);\n                url = this.options.addToCartUrl;\n                qtyName = $.validator.format(this.options.nameFormat, itemId);\n                qtyValue = elem.parents().find('[name=\"' + qtyName + '\"]').val();\n                url.data.item = itemId;\n                url.data.qty = qtyValue;\n\n                return url;\n            }\n        },\n\n        /**\n         * Add all wish list items to cart\n         * @private\n         */\n        _addAllWItemsToCart: function () {\n            var urlParams = this.options.addAllToCartUrl,\n                separator = urlParams.action.indexOf('?') >= 0 ? '&' : '?';\n\n            this.element.find(this.options.qtySelector).each(function (index, element) {\n                urlParams.action += separator + $(element).prop('name') + '=' + encodeURIComponent($(element).val());\n                separator = '&';\n            });\n            $.mage.dataPost().postData(urlParams);\n        },\n\n        /**\n         * Toggle comment string.\n         * @private\n         * @param {Event} e\n         */\n        _focusComment: function (e) {\n            var commentInput = e.currentTarget;\n\n            if (commentInput.value === '' || commentInput.value === this.options.commentString) {\n                commentInput.value = commentInput.value === this.options.commentString ?\n                    '' : this.options.commentString;\n            }\n        }\n    });\n\n    // Extension for mage.wishlist - Select All checkbox\n    $.widget('mage.wishlist', $.mage.wishlist, {\n        options: {\n            selectAllCheckbox: '#select-all',\n            parentContainer: '#wishlist-table'\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            var selectAllCheckboxParent, checkboxCount;\n\n            this._super();\n            selectAllCheckboxParent = $(this.options.selectAllCheckbox).parents(this.options.parentContainer);\n            checkboxCount = selectAllCheckboxParent\n                .find('input:checkbox:not(' + this.options.selectAllCheckbox + ')').length;\n            // If Select all checkbox is checked, check all item checkboxes, if unchecked, uncheck all item checkboxes\n            $(this.options.selectAllCheckbox).on('click', function () {\n                selectAllCheckboxParent.find('input:checkbox').attr('checked', $(this).is(':checked'));\n            });\n            // If all item checkboxes are checked, check select all checkbox,\n            // if not all item checkboxes are checked, uncheck select all checkbox\n            selectAllCheckboxParent.on(\n                'click',\n                'input:checkbox:not(' + this.options.selectAllCheckbox + ')',\n                $.proxy(function () {\n                    var checkedCount = selectAllCheckboxParent\n                        .find('input:checkbox:checked:not(' + this.options.selectAllCheckbox + ')').length;\n\n                    $(this.options.selectAllCheckbox).attr('checked', checkboxCount === checkedCount);\n                }, this)\n            );\n        }\n    });\n    // Extension for mage.wishlist info add to cart\n    $.widget('mage.wishlist', $.mage.wishlist, {\n        /** @inheritdoc */\n        _create: function () {\n            this._super();\n\n            if (this.options.infoList) {\n                this.element.on('addToCart', $.proxy(function (event, context) {\n                    this.element.find('input:checkbox').attr('checked', false);\n                    $(context).closest('tr').find('input:checkbox').attr('checked', true);\n                    this.element.trigger('submit');\n                }, this));\n                this._checkBoxValidate();\n            }\n        },\n\n        /**\n         * validate checkbox selection.\n         * @private\n         */\n        _checkBoxValidate: function () {\n            this.element.validation({\n                submitHandler: $.proxy(function (form) {\n                    if ($(form).find('input:checkbox:checked').length) {\n                        form.submit();\n                    } else {\n                        alert({\n                            content: this.options.checkBoxValidationMessage\n                        });\n                    }\n                }, this)\n            });\n        }\n    });\n\n    // Extension for mage.wishlist - Add Wishlist item to Gift Registry\n    $.widget('mage.wishlist', $.mage.wishlist, {\n        options: {\n            formTmplSelector: '#form-tmpl',\n            formTmplId: '#wishlist-hidden-form'\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            var _this = this;\n\n            this._super();\n            this.element.on('click', '[data-wishlist-to-giftregistry]', function () {\n                var json = $(this).data('wishlist-to-giftregistry'),\n                    tmplJson = {\n                        item: json.itemId,\n                        entity: json.entity,\n                        url: json.url\n                    },\n                    html = mageTemplate(_this.options.formTmplSelector, {\n                        data: tmplJson\n                    });\n\n                $(html).appendTo('body');\n                $(_this.options.formTmplId).trigger('submit');\n            });\n        }\n    });\n\n    return $.mage.wishlist;\n});\n","Magento_Wishlist/js/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.wishlistSearch', {\n\n        /**\n         * Bind handlers to events\n         */\n        _create: function () {\n            this.element.on('change', $.proxy(this._toggleForm, this));\n        },\n\n        /**\n         * Toggle Form\n         * @private\n         */\n        _toggleForm: function () {\n            switch (this.element.val()) {\n                case 'name':\n                    $(this.options.emailFormSelector).hide();\n                    $(this.options.nameFormSelector).show();\n                    break;\n\n                case 'email':\n                    $(this.options.nameFormSelector).hide();\n                    $(this.options.emailFormSelector).show();\n                    break;\n                default:\n                    $(this.options.emailFormSelector).add(this.options.nameFormSelector).hide();\n            }\n        }\n    });\n\n    return $.mage.wishlistSearch;\n});\n","Magento_Wishlist/js/add-to-wishlist.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.addToWishlist', {\n        options: {\n            bundleInfo: 'div.control [name^=bundle_option]',\n            configurableInfo: '.super-attribute-select',\n            groupedInfo: '#super-product-table input',\n            downloadableInfo: '#downloadable-links-list input',\n            customOptionsInfo: '.product-custom-option',\n            qtyInfo: '#qty',\n            actionElement: '[data-action=\"add-to-wishlist\"]',\n            productListWrapper: '.product-item-info',\n            productPageWrapper: '.product-info-main'\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            this._bind();\n        },\n\n        /**\n         * @private\n         */\n        _bind: function () {\n            var options = this.options,\n                dataUpdateFunc = '_updateWishlistData',\n                validateProductQty = '_validateWishlistQty',\n                changeCustomOption = 'change ' + options.customOptionsInfo,\n                changeQty = 'change ' + options.qtyInfo,\n                updateWishlist = 'click ' + options.actionElement,\n                events = {},\n                key;\n\n            if ('productType' in options) {\n                if (typeof options.productType === 'string') {\n                    options.productType = [options.productType];\n                }\n            } else {\n                options.productType = [];\n            }\n\n            events[changeCustomOption] = dataUpdateFunc;\n            events[changeQty] = dataUpdateFunc;\n            events[updateWishlist] = validateProductQty;\n\n            for (key in options.productType) {\n                if (options.productType.hasOwnProperty(key) && options.productType[key] + 'Info' in options) {\n                    events['change ' + options[options.productType[key] + 'Info']] = dataUpdateFunc;\n                }\n            }\n            this._on(events);\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _updateWishlistData: function (event) {\n            var dataToAdd = {},\n                isFileUploaded = false,\n                handleObjSelector = null,\n                self = this;\n\n            if (event.handleObj.selector == this.options.qtyInfo) { //eslint-disable-line eqeqeq\n                this._updateAddToWishlistButton({}, event);\n                event.stopPropagation();\n\n                return;\n            }\n\n            handleObjSelector = $(event.currentTarget).closest('form').find(event.handleObj.selector);\n\n            handleObjSelector.each(function (index, element) {\n                if ($(element).is('input[type=text]') ||\n                    $(element).is('input[type=email]') ||\n                    $(element).is('input[type=number]') ||\n                    $(element).is('input[type=hidden]') ||\n                    $(element).is('input[type=checkbox]:checked') ||\n                    $(element).is('input[type=radio]:checked') ||\n                    $(element).is('textarea') ||\n                    $('#' + element.id + ' option:selected').length\n                ) {\n                    if ($(element).data('selector') || $(element).attr('name')) {\n                        dataToAdd = $.extend({}, dataToAdd, self._getElementData(element));\n                    }\n\n                    return;\n                }\n\n                if ($(element).is('input[type=file]') && $(element).val()) {\n                    isFileUploaded = true;\n                }\n            });\n\n            if (isFileUploaded) {\n                this.bindFormSubmit();\n            }\n            this._updateAddToWishlistButton(dataToAdd, event);\n            event.stopPropagation();\n        },\n\n        /**\n         * @param {Object} dataToAdd\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _updateAddToWishlistButton: function (dataToAdd, event) {\n            var self = this,\n                buttons = this._getAddToWishlistButton(event);\n\n            buttons.each(function (index, element) {\n                var params = $(element).data('post'),\n                    currentTarget = event.currentTarget,\n                    targetElement,\n                    targetValue;\n\n                if (!params) {\n                    params = {\n                        'data': {}\n                    };\n                } else if ($(currentTarget).data('selector') || $(currentTarget).attr('name')) {\n                    targetElement = self._getElementData(currentTarget);\n                    targetValue = Object.keys(targetElement)[0];\n\n                    if (params.data.hasOwnProperty(targetValue) && !dataToAdd.hasOwnProperty(targetValue)) {\n                        delete params.data[targetValue];\n                    }\n                }\n\n                params.data = $.extend({}, params.data, dataToAdd, {\n                    'qty': $(self.options.qtyInfo).val()\n                });\n                $(element).data('post', params);\n            });\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _getAddToWishlistButton: function (event) {\n            var productListWrapper = $(event.currentTarget).closest(this.options.productListWrapper);\n\n            if (productListWrapper.length) {\n                return productListWrapper.find(this.options.actionElement);\n            }\n\n            return $(this.options.actionElement);\n        },\n\n        /**\n         * @param {Object} array1\n         * @param {Object} array2\n         * @return {Object}\n         * @private\n         * @deprecated\n         */\n        _arrayDiffByKeys: function (array1, array2) {\n            var result = {};\n\n            $.each(array1, function (key, value) {\n                if (key.indexOf('option') === -1) {\n                    return;\n                }\n\n                if (!array2[key]) {\n                    result[key] = value;\n                }\n            });\n\n            return result;\n        },\n\n        /**\n         * @param {HTMLElement} element\n         * @return {Object}\n         * @private\n         */\n        _getElementData: function (element) {\n            var data, elementName, elementValue;\n\n            element = $(element);\n            data = {};\n            elementName = element.data('selector') ? element.data('selector') : element.attr('name');\n            elementValue = element.val();\n\n            if (element.is('select[multiple]') && elementValue !== null) {\n                if (elementName.substr(elementName.length - 2) == '[]') { //eslint-disable-line eqeqeq\n                    elementName = elementName.substring(0, elementName.length - 2);\n                }\n                $.each(elementValue, function (key, option) {\n                    data[elementName + '[' + option + ']'] = option;\n                });\n            } else if (elementName.substr(elementName.length - 2) == '[]') { //eslint-disable-line eqeqeq, max-depth\n                elementName = elementName.substring(0, elementName.length - 2);\n\n                data[elementName + '[' + elementValue + ']'] = elementValue;\n            } else {\n                data[elementName] = elementValue;\n            }\n\n            return data;\n        },\n\n        /**\n         * @param {Object} params\n         * @param {Object} dataToAdd\n         * @private\n         * @deprecated\n         */\n        _removeExcessiveData: function (params, dataToAdd) {\n            var dataToRemove = this._arrayDiffByKeys(params.data, dataToAdd);\n\n            $.each(dataToRemove, function (key) {\n                delete params.data[key];\n            });\n        },\n\n        /**\n         * Bind form submit.\n         */\n        bindFormSubmit: function () {\n            var self = this;\n\n            $('[data-action=\"add-to-wishlist\"]').on('click', function (event) {\n                var element, params, form, action;\n\n                event.stopPropagation();\n                event.preventDefault();\n\n                element = $('input[type=file]' + self.options.customOptionsInfo);\n                params = $(event.currentTarget).data('post');\n                form = $(element).closest('form');\n                action = params.action;\n\n                if (params.data.id) {\n                    $('<input>', {\n                        type: 'hidden',\n                        name: 'id',\n                        value: params.data.id\n                    }).appendTo(form);\n                }\n\n                if (params.data.uenc) {\n                    action += 'uenc/' + params.data.uenc;\n                }\n\n                $(form).attr('action', action).trigger('submit');\n            });\n        },\n\n        /**\n         * Validate product quantity before updating Wish List\n         *\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _validateWishlistQty: function (event) {\n            var element = $(this.options.qtyInfo);\n\n            if (!(element.validation() && element.validation('isValid'))) {\n                event.preventDefault();\n                event.stopPropagation();\n\n                return;\n            }\n        }\n    });\n\n    return $.mage.addToWishlist;\n});\n","Magento_Wishlist/js/view/wishlist.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'Magento_Customer/js/customer-data'\n], function (Component, customerData) {\n    'use strict';\n\n    return Component.extend({\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n\n            this.wishlist = customerData.get('wishlist');\n        }\n    });\n});\n","Magento_Wishlist/js/product/addtowishlist-button.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    'Magento_Catalog/js/product/uenc-processor',\n    'Magento_Catalog/js/product/list/column-status-validator'\n], function (Element, uencProcessor, columnStatusValidator) {\n    'use strict';\n\n    return Element.extend({\n        defaults: {\n            label: ''\n        },\n\n        /**\n         * Get request POST data.\n         *\n         * @param {Object} row\n         * @return {String}\n         */\n        getDataPost: function (row) {\n            return uencProcessor(row['extension_attributes']['wishlist_button'].url);\n        },\n\n        /**\n         * Check if component must be shown.\n         *\n         * @return {Boolean}\n         */\n        isAllowed: function () {\n            return columnStatusValidator.isValid(this.source(), 'add_to_wishlist', 'show_buttons');\n        },\n\n        /**\n         * Get button label.\n         *\n         * @return {String}\n         */\n        getLabel: function () {\n            return this.label;\n        }\n    });\n});\n","Magento_Downloadable/js/downloadable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget',\n    'Magento_Catalog/js/price-box'\n], function ($) {\n    'use strict';\n\n    /**\n     * Downloadable widget\n     */\n    $.widget('mage.downloadable', {\n        options: {\n            priceHolderSelector: '.price-box',\n            linkElement: '',\n            allElements: ''\n        },\n\n        /**\n         * @inheritdoc\n         */\n        _init: function initLinks() {\n            var element = this.element,\n                options = $(this.options.linkElement, element);\n\n            options.trigger('change');\n        },\n\n        /**\n         *  @inheritdoc\n         */\n        _create: function () {\n            var self = this;\n\n            this.element.find(this.options.linkElement).on('change', $.proxy(function () {\n                this._reloadPrice();\n            }, this));\n\n            this.element.find(this.options.allElements).on('change', function () {\n                if (this.checked) {\n                    $('label[for=\"' + this.id + '\"] > span').text($(this).attr('data-checked'));\n                    self.element.find(self.options.linkElement + ':not(:checked)').each(function () {\n                        $(this).trigger('click');\n                    });\n                } else {\n                    $('[for=\"' + this.id + '\"] > span').text($(this).attr('data-notchecked'));\n                    self.element.find(self.options.linkElement + ':checked').each(function () {\n                        $(this).trigger('click');\n                    });\n                }\n            });\n\n            this._reloadPrice();\n        },\n\n        /**\n         * Reload product price with selected link price included\n         * @private\n         */\n        _reloadPrice: function () {\n            var finalPrice = 0,\n                basePrice = 0;\n\n            this.element.find(this.options.linkElement + ':checked').each($.proxy(function (index, element) {\n                finalPrice += this.options.config.links[$(element).val()].finalPrice;\n                basePrice += this.options.config.links[$(element).val()].basePrice;\n            }, this));\n\n            $(this.options.priceHolderSelector).trigger('updatePrice', {\n                'prices': {\n                    'finalPrice': {\n                        'amount': finalPrice\n                    },\n                    'basePrice': {\n                        'amount': basePrice\n                    }\n                }\n            });\n\n            this.reloadAllCheckText();\n        },\n\n        /**\n         * Reload all-elements-checkbox's label\n         * @private\n         */\n        reloadAllCheckText: function () {\n            var allChecked = true,\n                allElementsCheck = $(this.options.allElements),\n                allElementsLabel = $('label[for=\"' + allElementsCheck.attr('id') + '\"] > span');\n\n            $(this.options.linkElement).each(function () {\n                if (!this.checked) {\n                    allChecked = false;\n                }\n            });\n\n            if (allChecked) {\n                allElementsLabel.text(allElementsCheck.attr('data-checked'));\n                allElementsCheck.prop('checked', true);\n            } else {\n                allElementsLabel.text(allElementsCheck.attr('data-notchecked'));\n                allElementsCheck.prop('checked', false);\n            }\n        }\n    });\n\n    return $.mage.downloadable;\n});\n","Magento_Newsletter/js/newsletter-sign-up.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'uiElement',\n    'mage/url',\n    'subscriptionStatusResolver',\n    'mage/validation'\n], function ($, Component, urlBuilder, subscriptionStatusResolver) {\n    'use strict';\n\n    return Component.extend({\n\n        defaults: {\n            signUpElement: '',\n            submitButton: '',\n            element: null\n        },\n\n        /** @inheritdoc */\n        initialize: function (config, element) {\n            this._super();\n            this.element = element;\n            $(element).on('change', $.proxy(this.updateSignUpStatus, this));\n            this.updateSignUpStatus();\n        },\n\n        /**\n         * Send status request and update subscription element according to result.\n         */\n        updateSignUpStatus: function () {\n            var element = $(this.element),\n                email = element.val(),\n                self = this,\n                newsletterSubscription;\n\n            if ($(self.signUpElement).is(':checked')) {\n                return;\n            }\n\n            if (!email || !$.validator.methods['validate-email'].call(this, email, element)) {\n                return;\n            }\n\n            newsletterSubscription = $.Deferred();\n\n            $(self.submitButton).prop('disabled', true);\n\n            subscriptionStatusResolver(email, newsletterSubscription);\n\n            $.when(newsletterSubscription).done(function (isSubscribed) {\n                if (isSubscribed) {\n                    $(self.signUpElement).prop('checked', true);\n                }\n            }).always(function () {\n                $(self.submitButton).prop('disabled', false);\n            });\n        }\n    });\n});\n","Magento_Newsletter/js/subscription-status-resolver.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/url'\n], function ($, urlBuilder) {\n    'use strict';\n\n    return function (email, deferred) {\n        return $.getJSON(\n            urlBuilder.build('newsletter/ajax/status'),\n            {\n                email: email\n            }\n        ).done(function (response) {\n            if (response.errors) {\n                deferred.reject();\n            } else {\n                deferred.resolve(response.subscribed);\n            }\n        }).fail(function () {\n            deferred.reject();\n        });\n    };\n});\n","Magento_Review/js/process-reviews.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'tabs',\n    'collapsible'\n], function ($) {\n    'use strict';\n\n    /**\n     * @param {String} url\n     * @param {*} fromPages\n     */\n    function processReviews(url, fromPages) {\n        $.ajax({\n            url: url,\n            cache: true,\n            dataType: 'html',\n            showLoader: false,\n            loaderContext: $('.product.data.items')\n        }).done(function (data) {\n            $('#product-review-container').html(data).trigger('contentUpdated'); \n            if($('.product.info.detailed').hasClass('vertical')) {\n              $('#product-review-container').parent().parent().css(\"min-height\",$('#product-review-container').parent().outerHeight()+\"px\");\n            }\n\n            $('[data-role=\"product-review\"] .pages a').each(function (index, element) {\n                $(element).on('click', function (event) { //eslint-disable-line max-nested-callbacks\n                    processReviews($(element).attr('href'), true);\n                    event.preventDefault();\n                });\n            });\n        }).always(function () {\n            if (fromPages == true) { //eslint-disable-line eqeqeq\n                $('html, body').animate({\n                    scrollTop: $('#reviews').offset().top - 50\n                }, 300);\n            }\n        });\n    }\n\n    return function (config) {\n        var reviewTab = $(config.reviewsTabSelector),\n            requiredReviewTabRole = 'tab';\n\n        if (reviewTab.attr('role') === requiredReviewTabRole && reviewTab.hasClass('active')) {\n            processReviews(config.productReviewUrl, location.hash === '#reviews');\n        } else {\n            reviewTab.one('beforeOpen', function () {\n                processReviews(config.productReviewUrl);\n            });\n        }\n\n        $(function () {\n            $('.product-info-main .reviews-actions a').on('click', function (event) {\n                var anchor, addReviewBlock;\n\n                event.preventDefault();\n                anchor = $(this).attr('href').replace(/^.*?(#|$)/, '');\n                addReviewBlock = $('#' + anchor);\n\n                if (addReviewBlock.length) {\n                    $('.product.data.items [data-role=\"content\"]').each(function (index) { //eslint-disable-line\n                        if (this.id == 'reviews') { //eslint-disable-line eqeqeq\n                            $('.product.data.items').tabs('activate', index);\n                        }\n                    });\n                    $('html, body').animate({\n                        scrollTop: addReviewBlock.offset().top - 50\n                    }, 300);\n                }\n\n            });\n        });\n    };\n});\n","Magento_Review/js/validate-review.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery/validate',\n    'mage/translate'\n], function ($) {\n    'use strict';\n\n    $.validator.addMethod(\n        'rating-required', function (value) {\n            return value !== undefined;\n        }, $.mage.__('Please select one of each of the ratings above.'));\n});\n","Magento_Review/js/error-placement.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/mage'\n], function ($) {\n    'use strict';\n\n    return function (config, element) {\n        $(element).mage('validation', {\n            /** @inheritdoc */\n            errorPlacement: function (error, el) {\n\n                if (el.parents('#product-review-table').length) {\n                    $('#product-review-table').siblings(this.errorElement + '.' + this.errorClass).remove();\n                    $('#product-review-table').after(error);\n                } else {\n                    el.after(error);\n                }\n            }\n        });\n    };\n});\n","Magento_Review/js/submit-review.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    return function (config, element) {\n        $(element).on('submit', function () {\n            if ($(this).valid()) {\n                $(this).find('.submit').attr('disabled', true);\n            }\n        });\n    };\n});\n","Magento_Review/js/view/review.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'Magento_Customer/js/customer-data',\n    'Magento_Customer/js/view/customer'\n], function (Component, customerData) {\n    'use strict';\n\n    return Component.extend({\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n\n            this.review = customerData.get('review').extend({\n                disposableCustomerData: 'review'\n            });\n        },\n\n        /**\n         * @return {*}\n         */\n        nickname: function () {\n            return this.review().nickname || customerData.get('customer')().firstname;\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","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' ?\n                            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; 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","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_ConfigurableProduct/js/configurable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'underscore',\n    'mage/template',\n    'mage/translate',\n    'priceUtils',\n    'priceBox',\n    'jquery-ui-modules/widget',\n    'jquery/jquery.parsequery',\n    'fotoramaVideoEvents'\n], function ($, _, mageTemplate, $t, priceUtils) {\n    'use strict';\n\n    $.widget('mage.configurable', {\n        options: {\n            superSelector: '.super-attribute-select',\n            selectSimpleProduct: '[name=\"selected_configurable_option\"]',\n            priceHolderSelector: '.price-box',\n            spConfig: {},\n            state: {},\n            priceFormat: {},\n            optionTemplate: '<%- data.label %>' +\n            '<% if (typeof data.finalPrice.value !== \"undefined\") { %>' +\n            ' <%- data.finalPrice.formatted %>' +\n            '<% } %>',\n            mediaGallerySelector: '[data-gallery-role=gallery-placeholder]',\n            mediaGalleryInitial: null,\n            slyOldPriceSelector: '.sly-old-price',\n            normalPriceLabelSelector: '.product-info-main .normal-price .price-label',\n\n            /**\n             * Defines the mechanism of how images of a gallery should be\n             * updated when user switches between configurations of a product.\n             *\n             * As for now value of this option can be either 'replace' or 'prepend'.\n             *\n             * @type {String}\n             */\n            gallerySwitchStrategy: 'replace',\n            tierPriceTemplateSelector: '#tier-prices-template',\n            tierPriceBlockSelector: '[data-role=\"tier-price-block\"]',\n            tierPriceTemplate: '',\n            selectorProduct: '.product-info-main',\n            selectorProductPrice: '[data-role=priceBox]',\n            qtyInfo: '#qty'\n        },\n\n        /**\n         * Creates widget\n         * @private\n         */\n        _create: function () {\n            // Initial setting of various option values\n            this._initializeOptions();\n\n            // Override defaults with URL query parameters and/or inputs values\n            this._overrideDefaults();\n\n            // Change events to check select reloads\n            this._setupChangeEvents();\n\n            // Fill state\n            this._fillState();\n\n            // Setup child and prev/next settings\n            this._setChildSettings();\n\n            // Setup/configure values to inputs\n            this._configureForValues();\n\n            $(this.element).trigger('configurable.initialized');\n            $(this.options.qtyInfo).on('input', this._reloadPrice.bind(this));\n        },\n\n        /**\n         * Initialize tax configuration, initial settings, and options values.\n         * @private\n         */\n        _initializeOptions: function () {\n            var options = this.options,\n                gallery = $(options.mediaGallerySelector),\n                priceBoxOptions = $(this.options.priceHolderSelector).priceBox('option').priceConfig || null;\n\n            if (priceBoxOptions && priceBoxOptions.optionTemplate) {\n                options.optionTemplate = priceBoxOptions.optionTemplate;\n            }\n\n            if (priceBoxOptions && priceBoxOptions.priceFormat) {\n                options.priceFormat = priceBoxOptions.priceFormat;\n            }\n            options.optionTemplate = mageTemplate(options.optionTemplate);\n            options.tierPriceTemplate = $(this.options.tierPriceTemplateSelector).html();\n\n            options.settings = options.spConfig.containerId ?\n                $(options.spConfig.containerId).find(options.superSelector) :\n                $(options.superSelector);\n\n            options.values = options.spConfig.defaultValues || {};\n            options.parentImage = $('[data-role=base-image-container] img').attr('src');\n\n            this.inputSimpleProduct = this.element.find(options.selectSimpleProduct);\n\n            gallery.data('gallery') ?\n                this._onGalleryLoaded(gallery) :\n                gallery.on('gallery:loaded', this._onGalleryLoaded.bind(this, gallery));\n\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            if (this.options.spConfig.inputsInitialized) {\n                this._setValuesByAttribute();\n            }\n\n            this._setInitialOptionsLabels();\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\n            $.each(queryParams, $.proxy(function (key, value) {\n                if (this.options.spConfig.attributes[key] !== undefined &&\n                    _.find(this.options.spConfig.attributes[key].options, function (element) {\n                        return element.id === value;\n                    })) {\n                    this.options.values[key] = value;\n                }\n            }, this));\n        },\n\n        /**\n         * Override default options values with values based on each element's attribute\n         * identifier.\n         * @private\n         */\n        _setValuesByAttribute: function () {\n            this.options.values = {};\n            $.each(this.options.settings, $.proxy(function (index, element) {\n                var attributeId;\n\n                if (element.value) {\n                    attributeId = element.id.replace(/[a-z]*/, '');\n\n                    if (this.options.spConfig.attributes[attributeId] !== undefined &&\n                        _.find(this.options.spConfig.attributes[attributeId].options, function (optionElement) {\n                            return optionElement.id === element.value;\n                        })) {\n                        this.options.values[attributeId] = element.value;\n                    }\n                }\n            }, this));\n        },\n\n        /**\n         * Set additional field with initial label to be used when switching between options with different prices.\n         * @private\n         */\n        _setInitialOptionsLabels: function () {\n            $.each(this.options.spConfig.attributes, $.proxy(function (index, element) {\n                $.each(element.options, $.proxy(function (optIndex, optElement) {\n                    this.options.spConfig.attributes[index].options[optIndex].initialLabel = optElement.label;\n                }, this));\n            }, this));\n        },\n\n        /**\n         * Set up .on('change') events for each option element to configure the option.\n         * @private\n         */\n        _setupChangeEvents: function () {\n            $.each(this.options.settings, $.proxy(function (index, element) {\n                $(element).on('change', this, this._configure);\n            }, this));\n        },\n\n        /**\n         * Iterate through the option settings and set each option's element configuration,\n         * attribute identifier. Set the state based on the attribute identifier.\n         * @private\n         */\n        _fillState: function () {\n            $.each(this.options.settings, $.proxy(function (index, element) {\n                var attributeId = element.id.replace(/[a-z]*/, '');\n\n                if (attributeId && this.options.spConfig.attributes[attributeId]) {\n                    element.config = this.options.spConfig.attributes[attributeId];\n                    element.attributeId = attributeId;\n                    this.options.state[attributeId] = false;\n                }\n            }, this));\n        },\n\n        /**\n         * Set each option's child settings, and next/prev option setting. Fill (initialize)\n         * an option's list of selections as needed or disable an option's setting.\n         * @private\n         */\n        _setChildSettings: function () {\n            var childSettings = [],\n                settings = this.options.settings,\n                index = settings.length,\n                option;\n\n            while (index--) {\n                option = settings[index];\n\n                if (index) {\n                    option.disabled = true;\n                } else {\n                    this._fillSelect(option);\n                }\n\n                _.extend(option, {\n                    childSettings: childSettings.slice(),\n                    prevSetting: settings[index - 1],\n                    nextSetting: settings[index + 1]\n                });\n\n                childSettings.push(option);\n            }\n        },\n\n        /**\n         * Setup for all configurable option settings. Set the value of the option and configure\n         * the option, which sets its state, and initializes the option's choices, etc.\n         * @private\n         */\n        _configureForValues: function () {\n            if (this.options.values) {\n                this.options.settings.each($.proxy(function (index, element) {\n                    var attributeId = element.attributeId;\n\n                    element.value = this.options.values[attributeId] || '';\n                    this._configureElement(element);\n                }, this));\n            }\n        },\n\n        /**\n         * Event handler for configuring an option.\n         * @private\n         * @param {Object} event - Event triggered to configure an option.\n         */\n        _configure: function (event) {\n            event.data._configureElement(this);\n        },\n\n        /**\n         * Configure an option, initializing it's state and enabling related options, which\n         * populates the related option's selection and resets child option selections.\n         * @private\n         * @param {*} element - The element associated with a configurable option.\n         */\n        _configureElement: function (element) {\n            this.simpleProduct = this._getSimpleProductId(element);\n\n            if (element.value) {\n                this.options.state[element.config.id] = element.value;\n\n                if (element.nextSetting) {\n                    element.nextSetting.disabled = false;\n                    this._fillSelect(element.nextSetting);\n                    this._resetChildren(element.nextSetting);\n                } else {\n                    if (!!document.documentMode) { //eslint-disable-line\n                        this.inputSimpleProduct.val(element.options[element.selectedIndex].config.allowedProducts[0]);\n                    } else {\n                        this.inputSimpleProduct.val(element.selectedOptions[0].config.allowedProducts[0]);\n                    }\n                }\n            } else {\n                this._resetChildren(element);\n            }\n\n            this._reloadPrice();\n            this._displayRegularPriceBlock(this.simpleProduct);\n            this._displayTierPriceBlock(this.simpleProduct);\n            this._displayNormalPriceLabel();\n            this._changeProductImage();\n        },\n\n        /**\n         * Change displayed product image according to chosen options of configurable product\n         *\n         * @private\n         */\n        _changeProductImage: function () {\n            var images,\n                initialImages = this.options.mediaGalleryInitial,\n                gallery = $(this.options.mediaGallerySelector).data('gallery');\n\n            if (_.isUndefined(gallery)) {\n                $(this.options.mediaGallerySelector).on('gallery:loaded', function () {\n                    this._changeProductImage();\n                }.bind(this));\n\n                return;\n            }\n\n            images = this.options.spConfig.images[this.simpleProduct];\n\n            if (images) {\n                images = this._sortImages(images);\n\n                if (this.options.gallerySwitchStrategy === 'prepend') {\n                    images = images.concat(initialImages);\n                }\n\n                images = $.extend(true, [], images);\n                images = this._setImageIndex(images);\n\n                gallery.updateData(images);\n                this._addFotoramaVideoEvents(false);\n            } else {\n                gallery.updateData(initialImages);\n                this._addFotoramaVideoEvents(true);\n            }\n        },\n\n        /**\n         * Add video events\n         *\n         * @param {Boolean} isInitial\n         * @private\n         */\n        _addFotoramaVideoEvents: function (isInitial) {\n            if (_.isUndefined($.mage.AddFotoramaVideoEvents)) {\n                return;\n            }\n\n            if (isInitial) {\n                $(this.options.mediaGallerySelector).AddFotoramaVideoEvents();\n\n                return;\n            }\n\n            $(this.options.mediaGallerySelector).AddFotoramaVideoEvents({\n                selectedOption: this.simpleProduct,\n                dataMergeStrategy: this.options.gallerySwitchStrategy\n            });\n        },\n\n        /**\n         * Sorting images array\n         *\n         * @private\n         */\n        _sortImages: function (images) {\n            return _.sortBy(images, function (image) {\n                return image.position;\n            });\n        },\n\n        /**\n         * Set correct indexes for image set.\n         *\n         * @param {Array} images\n         * @private\n         */\n        _setImageIndex: function (images) {\n            var length = images.length,\n                i;\n\n            for (i = 0; length > i; i++) {\n                images[i].i = i + 1;\n            }\n\n            return images;\n        },\n\n        /**\n         * For a given option element, reset all of its selectable options. Clear any selected\n         * index, disable the option choice, and reset the option's state if necessary.\n         * @private\n         * @param {*} element - The element associated with a configurable option.\n         */\n        _resetChildren: function (element) {\n            if (element.childSettings) {\n                _.each(element.childSettings, function (set) {\n                    set.selectedIndex = 0;\n                    set.disabled = true;\n                });\n\n                if (element.config) {\n                    this.options.state[element.config.id] = false;\n                }\n            }\n        },\n\n        /**\n         * Populates an option's selectable choices.\n         * @private\n         * @param {*} element - Element associated with a configurable option.\n         */\n        _fillSelect: function (element) {\n            var attributeId = element.id.replace(/[a-z]*/, ''),\n                options = this._getAttributeOptions(attributeId),\n                prevConfig,\n                index = 1,\n                allowedProducts,\n                allowedProductsByOption,\n                allowedProductsAll,\n                i,\n                j,\n                finalPrice = parseFloat(this.options.spConfig.prices.finalPrice.amount),\n                optionFinalPrice,\n                optionPriceDiff,\n                optionPrices = this.options.spConfig.optionPrices,\n                allowedOptions = [],\n                indexKey,\n                allowedProductMinPrice,\n                allowedProductsAllMinPrice,\n                canDisplayOutOfStockProducts = false,\n                filteredSalableProducts;\n\n            this._clearSelect(element);\n            element.options[0] = new Option('', '');\n            element.options[0].innerHTML = this.options.spConfig.chooseText;\n            prevConfig = false;\n\n            if (element.prevSetting) {\n                prevConfig = element.prevSetting.options[element.prevSetting.selectedIndex];\n            }\n\n            if (options) {\n                for (indexKey in this.options.spConfig.index) {\n                    /* eslint-disable max-depth */\n                    if (this.options.spConfig.index.hasOwnProperty(indexKey)) {\n                        allowedOptions = allowedOptions.concat(_.values(this.options.spConfig.index[indexKey]));\n                    }\n                }\n\n                if (prevConfig) {\n                    allowedProductsByOption = {};\n                    allowedProductsAll = [];\n\n                    for (i = 0; i < options.length; i++) {\n                        /* eslint-disable max-depth */\n                        for (j = 0; j < options[i].products.length; j++) {\n                            // prevConfig.config can be undefined\n                            if (prevConfig.config &&\n                                prevConfig.config.allowedProducts &&\n                                prevConfig.config.allowedProducts.indexOf(options[i].products[j]) > -1) {\n                                if (!allowedProductsByOption[i]) {\n                                    allowedProductsByOption[i] = [];\n                                }\n                                allowedProductsByOption[i].push(options[i].products[j]);\n                                allowedProductsAll.push(options[i].products[j]);\n                            }\n                        }\n                    }\n\n                    if (typeof allowedProductsAll[0] !== 'undefined' &&\n                        typeof optionPrices[allowedProductsAll[0]] !== 'undefined') {\n                        allowedProductsAllMinPrice = this._getAllowedProductWithMinPrice(allowedProductsAll);\n                        finalPrice = parseFloat(optionPrices[allowedProductsAllMinPrice].finalPrice.amount);\n                    }\n                }\n\n                for (i = 0; i < options.length; i++) {\n                    if (prevConfig && typeof allowedProductsByOption[i] === 'undefined') {\n                        continue; //jscs:ignore disallowKeywords\n                    }\n\n                    allowedProducts = prevConfig ? allowedProductsByOption[i] : options[i].products.slice(0);\n                    optionPriceDiff = 0;\n\n                    if (typeof allowedProducts[0] !== 'undefined' &&\n                        typeof optionPrices[allowedProducts[0]] !== 'undefined') {\n                        allowedProductMinPrice = this._getAllowedProductWithMinPrice(allowedProducts);\n                        optionFinalPrice = parseFloat(optionPrices[allowedProductMinPrice].finalPrice.amount);\n                        optionPriceDiff = optionFinalPrice - finalPrice;\n                        options[i].label = options[i].initialLabel;\n\n                        if (optionPriceDiff !== 0) {\n                            options[i].label += ' ' + priceUtils.formatPriceLocale(\n                                optionPriceDiff,\n                                this.options.priceFormat,\n                                true\n                            );\n                        }\n                    }\n\n                    if (allowedProducts.length > 0 || _.include(allowedOptions, options[i].id)) {\n                        options[i].allowedProducts = allowedProducts;\n                        element.options[index] = new Option(this._getOptionLabel(options[i]), options[i].id);\n\n                        if (this.options.spConfig.canDisplayShowOutOfStockStatus) {\n                            filteredSalableProducts = $(this.options.spConfig.salable[attributeId][options[i].id]).\n                            filter(options[i].allowedProducts);\n                            canDisplayOutOfStockProducts = filteredSalableProducts.length === 0;\n                        }\n\n                        if (typeof options[i].price !== 'undefined') {\n                            element.options[index].setAttribute('price', options[i].price);\n                        }\n\n                        if (allowedProducts.length === 0 || canDisplayOutOfStockProducts) {\n                            element.options[index].disabled = true;\n                        }\n\n                        element.options[index].config = options[i];\n                        index++;\n                    }\n\n                    /* eslint-enable max-depth */\n                }\n            }\n        },\n\n        /**\n         * Generate the label associated with a configurable option. This includes the option's\n         * label or value and the option's price.\n         * @private\n         * @param {*} option - A single choice among a group of choices for a configurable option.\n         * @return {String} The option label with option value and price (e.g. Black +1.99)\n         */\n        _getOptionLabel: function (option) {\n            return option.label;\n        },\n\n        /**\n         * Removes an option's selections.\n         * @private\n         * @param {*} element - The element associated with a configurable option.\n         */\n        _clearSelect: function (element) {\n            var i;\n\n            for (i = element.options.length - 1; i >= 0; i--) {\n                element.remove(i);\n            }\n        },\n\n        /**\n         * Retrieve the attribute options associated with a specific attribute Id.\n         * @private\n         * @param {Number} attributeId - The id of the attribute whose configurable options are sought.\n         * @return {Object} Object containing the attribute options.\n         */\n        _getAttributeOptions: function (attributeId) {\n            if (this.options.spConfig.attributes[attributeId]) {\n                return this.options.spConfig.attributes[attributeId].options;\n            }\n        },\n\n        /**\n         * Reload the price of the configurable product incorporating the prices of all of the\n         * configurable product's option selections.\n         */\n        _reloadPrice: function () {\n            $(this.options.priceHolderSelector).trigger('updatePrice', this._getPrices());\n        },\n\n        /**\n         * Get product various prices\n         * @returns {{}}\n         * @private\n         */\n        _getPrices: function () {\n            var prices = {},\n                elements = _.toArray(this.options.settings),\n                allowedProduct;\n\n            _.each(elements, function (element) {\n                var selected = element.options[element.selectedIndex],\n                    config = selected && selected.config,\n                    priceValue = this._calculatePrice({});\n\n                if (config && config.allowedProducts.length === 1) {\n                    priceValue = this._calculatePrice(config);\n                } else if (element.value) {\n                    allowedProduct = this._getAllowedProductWithMinPrice(config.allowedProducts);\n                    priceValue = this._calculatePrice({\n                        'allowedProducts': [\n                            allowedProduct\n                        ]\n                    });\n                }\n\n                if (!_.isEmpty(priceValue)) {\n                    prices.prices = priceValue;\n                }\n            }, this);\n\n            return prices;\n        },\n\n        /**\n         * Get product with minimum price from selected options.\n         *\n         * @param {Array} allowedProducts\n         * @returns {String}\n         * @private\n         */\n        _getAllowedProductWithMinPrice: function (allowedProducts) {\n            var optionPrices = this.options.spConfig.optionPrices,\n                product = {},\n                optionMinPrice, optionFinalPrice;\n\n            _.each(allowedProducts, function (allowedProduct) {\n                optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount);\n\n                if (_.isEmpty(product) || optionFinalPrice < optionMinPrice) {\n                    optionMinPrice = optionFinalPrice;\n                    product = allowedProduct;\n                }\n            }, this);\n\n            return product;\n        },\n\n        /**\n         * Returns prices for configured products\n         *\n         * @param {*} config - Products configuration\n         * @returns {*}\n         * @private\n         */\n        _calculatePrice: function (config) {\n            var displayPrices = $(this.options.priceHolderSelector).priceBox('option').prices,\n                newPrices = this.options.spConfig.optionPrices[_.first(config.allowedProducts)] || {};\n\n            _.each(displayPrices, function (price, code) {\n                displayPrices[code].amount = newPrices[code] ? newPrices[code].amount - displayPrices[code].amount : 0;\n            });\n\n            return displayPrices;\n        },\n\n        /**\n         * Returns Simple product Id\n         *  depending on current selected option.\n         *\n         * @private\n         * @param {HTMLElement} element\n         * @returns {String|undefined}\n         */\n        _getSimpleProductId: function (element) {\n            // TODO: Rewrite algorithm. It should return ID of\n            //        simple product based on selected options.\n            var allOptions = element.config.options,\n                value = element.value,\n                config;\n\n            config = _.filter(allOptions, function (option) {\n                return option.id === value;\n            });\n            config = _.first(config);\n\n            return _.isEmpty(config) ?\n                undefined :\n                _.first(config.allowedProducts);\n\n        },\n\n        /**\n         * Show or hide regular price block\n         *\n         * @param {*} optionId\n         * @private\n         */\n        _displayRegularPriceBlock: function (optionId) {\n            var shouldBeShown = true,\n                $priceBox = this.element.parents(this.options.selectorProduct)\n                    .find(this.options.selectorProductPrice);\n\n            _.each(this.options.settings, function (element) {\n                if (element.value === '') {\n                    shouldBeShown = false;\n                }\n            });\n\n            if (shouldBeShown &&\n                this.options.spConfig.optionPrices[optionId].oldPrice.amount !==\n                this.options.spConfig.optionPrices[optionId].finalPrice.amount\n            ) {\n                $(this.options.slyOldPriceSelector).show();\n            } else {\n                $(this.options.slyOldPriceSelector).hide();\n            }\n\n            $(document).trigger('updateMsrpPriceBlock',\n                [\n                    optionId,\n                    this.options.spConfig.optionPrices,\n                    $priceBox\n                ]\n            );\n        },\n\n        /**\n         * Show or hide normal price label\n         *\n         * @private\n         */\n        _displayNormalPriceLabel: function () {\n            var shouldBeShown = false;\n\n            _.each(this.options.settings, function (element) {\n                if (element.value === '') {\n                    shouldBeShown = true;\n                }\n            });\n\n            if (shouldBeShown) {\n                $(this.options.normalPriceLabelSelector).show();\n            } else {\n                $(this.options.normalPriceLabelSelector).hide();\n            }\n        },\n\n        /**\n         * Callback which fired after gallery gets initialized.\n         *\n         * @param {HTMLElement} element - DOM element associated with gallery.\n         */\n        _onGalleryLoaded: function (element) {\n            var galleryObject = element.data('gallery');\n\n            this.options.mediaGalleryInitial = galleryObject.returnCurrentImages();\n        },\n\n        /**\n         * Show or hide tier price block\n         *\n         * @param {*} optionId\n         * @private\n         */\n        _displayTierPriceBlock: function (optionId) {\n            var tierPrices = typeof optionId != 'undefined' && this.options.spConfig.optionPrices[optionId].tierPrices;\n\n            if (_.isArray(tierPrices) && tierPrices.length > 0) {\n\n                if (this.options.tierPriceTemplate) {\n                    $(this.options.tierPriceBlockSelector).html(\n                        mageTemplate(this.options.tierPriceTemplate, {\n                            'tierPrices': tierPrices,\n                            '$t': $t,\n                            'currencyFormat': this.options.spConfig.currencyFormat,\n                            'priceUtils': priceUtils\n                        })\n                    ).show();\n                }\n            } else {\n                $(this.options.tierPriceBlockSelector).hide();\n            }\n        }\n    });\n\n    return $.mage.configurable;\n});\n","Magento_ConfigurableProduct/js/catalog-add-to-cart.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\nrequire([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    /**\n     * Add selected configurable attributes to redirect url\n     *\n     * @see Magento_Catalog/js/catalog-add-to-cart\n     */\n    $('body').on('catalogCategoryAddToCartRedirect', function (event, data) {\n        $(data.form).find('select[name*=\"super\"]').each(function (index, item) {\n            data.redirectParameters.push(item.config.id + '=' + $(item).val());\n        });\n    });\n});\n","Magento_ConfigurableProduct/js/catalog-add-to-cart-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'jquery',\n    'Magento_ConfigurableProduct/js/product/view/product-info-resolver'\n], function (_, $, productInfoResolver) {\n    'use strict';\n\n    return function (widget) {\n\n        $.widget('mage.catalogAddToCart', widget, {\n            /**\n             * @param {jQuery} form\n             */\n            ajaxSubmit: function (form) {\n                var isConfigurable = !!_.find(form.serializeArray(), function (item) {\n                    return item.name.indexOf('super_attribute') !== -1;\n                });\n\n                if (isConfigurable) {\n                    this.options.productInfoResolver = productInfoResolver;\n                }\n\n                return this._super(form);\n            }\n        });\n\n        return $.mage.catalogAddToCart;\n    };\n});\n","Magento_ConfigurableProduct/js/configurable-customer-data.js":"require([\n    'jquery',\n    'Magento_ConfigurableProduct/js/options-updater'\n], function ($, Updater) {\n    'use strict';\n\n    var selectors = {\n            formSelector: '#product_addtocart_form'\n        },\n        configurableWidgetName = 'mageConfigurable',\n        widgetInitEvent = 'configurable.initialized',\n\n    /**\n    * Sets all configurable attribute's selected values\n    */\n    updateConfigurableOptions = function () {\n        var configurableWidget = $(selectors.formSelector).data(configurableWidgetName);\n\n        if (!configurableWidget) {\n            return;\n        }\n        configurableWidget.options.values = this.productOptions || {};\n        configurableWidget._configureForValues();\n    },\n    updater = new Updater(widgetInitEvent, updateConfigurableOptions);\n\n    updater.listen();\n});\n","Magento_ConfigurableProduct/js/options-updater.js":"define([\n    'jquery',\n    'underscore',\n    'Magento_Customer/js/customer-data',\n    'domReady!'\n], function ($, _, customerData) {\n    'use strict';\n\n    var selectors = {\n        formSelector: '#product_addtocart_form',\n        productIdSelector: '#product_addtocart_form [name=\"product\"]',\n        itemIdSelector: '#product_addtocart_form [name=\"item\"]'\n    },\n    cartData = customerData.get('cart'),\n    productId = $(selectors.productIdSelector).val(),\n    itemId = $(selectors.itemIdSelector).val(),\n\n    /**\n    * set productOptions according to cart data from customer-data\n    *\n    * @param {Object} data - cart data from customer-data\n    * @returns {Boolean} - whether the new options differ from previous\n    */\n    setProductOptions = function (data) {\n        var changedProductOptions;\n\n        if (!(data && data.items && data.items.length && productId)) {\n            return false;\n        }\n        changedProductOptions = _.find(data.items, function (item) {\n            if (item['item_id'] === itemId) {\n                return item['product_id'] === productId;\n            }\n        });\n        changedProductOptions = changedProductOptions && changedProductOptions.options &&\n            changedProductOptions.options.reduce(function (obj, val) {\n                obj[val['option_id']] = val['option_value'];\n\n                return obj;\n            }, {});\n\n        if (JSON.stringify(this.productOptions || {}) === JSON.stringify(changedProductOptions || {})) {\n            return false;\n        }\n\n        this.productOptions = changedProductOptions;\n\n        return true;\n    },\n\n    /**\n    * Listens to update of cart data or options initialization and update selected option according to customer data\n    *\n    */\n    listen = function () {\n        cartData.subscribe(function (updateCartData) {\n            if (this.setProductOptions(updateCartData)) {\n                this.updateOptions();\n            }\n        }.bind(this));\n        $(selectors.formSelector).on(this.eventName, function () {\n            this.setProductOptions(cartData());\n            this.updateOptions();\n        }.bind(this));\n    },\n\n    /**\n    * Updater constructor function\n    *\n    */\n    Updater = function (eventName, updateOptionsCallback) {\n        if (this instanceof Updater) {\n            this.eventName = eventName;\n            this.updateOptions = updateOptionsCallback;\n            this.productOptions = {};\n        }\n    };\n\n    Updater.prototype.setProductOptions = setProductOptions;\n    Updater.prototype.listen = listen;\n\n    return Updater;\n});\n","Magento_ConfigurableProduct/js/product/view/product-info-resolver.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'Magento_Catalog/js/product/view/product-info'\n], function (_, productInfo) {\n    'use strict';\n\n    /**\n     * Returns info about configurable products in form.\n     *\n     * @param {jQuery} $form\n     * @return {Array}\n     */\n    return function ($form) {\n        var optionValues = [],\n            product = _.findWhere($form.serializeArray(), {\n                name: 'product'\n            }),\n            productId;\n\n        if (!_.isUndefined(product)) {\n            productId = product.value;\n            _.each($form.serializeArray(), function (item) {\n                if (item.name.indexOf('super_attribute') !== -1) {\n                    optionValues.push(item.value);\n                }\n            });\n            optionValues.sort();\n            productInfo().push(\n                {\n                    'id': productId,\n                    'optionValues': optionValues\n                }\n            );\n        }\n\n        return _.uniq(productInfo(), function (item) {\n            var optionValuesStr = item.optionValues ? item.optionValues.join() : '';\n\n            return item.id + optionValuesStr;\n        });\n    };\n});\n\n","Magento_CatalogSearch/js/search-terms-log.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mageUtils'\n], function ($, utils) {\n    'use strict';\n\n    return function (data) {\n        $.ajax({\n            method: 'GET',\n            url: data.url,\n            data: {\n                'q': utils.getUrlParameters(window.location.href).q\n            }\n        });\n    };\n});\n","Magento_Shipping/js/view/checkout/shipping/shipping-policy.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'Magento_Shipping/js/model/config'\n\n], function (Component, config) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_Shipping/checkout/shipping/shipping-policy'\n        },\n        config: config()\n    });\n});\n","Magento_Shipping/js/model/config.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 () {\n        return window.checkoutConfig.shippingPolicy;\n    };\n});\n","Magento_Search/js/form-mini.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    'mage/template',\n    'matchMedia',\n    'jquery-ui-modules/widget',\n    'jquery-ui-modules/core',\n    'mage/translate'\n], function ($, _, mageTemplate, mediaCheck) {\n    'use strict';\n\n    /**\n     * Check whether the incoming string is not empty or if doesn't consist of spaces.\n     *\n     * @param {String} value - Value to check.\n     * @returns {Boolean}\n     */\n    function isEmpty(value) {\n        return value.length === 0 || value == null || /^\\s+$/.test(value);\n    }\n\n    $.widget('mage.quickSearch', {\n        options: {\n            autocomplete: 'off',\n            minSearchLength: 3,\n            responseFieldElements: 'ul li',\n            selectClass: 'selected',\n            template:\n                '<li class=\"<%- data.row_class %>\" id=\"qs-option-<%- data.index %>\" role=\"option\">' +\n                '<span class=\"qs-option-name\">' +\n                ' <%- data.title %>' +\n                '</span>' +\n                '<span aria-hidden=\"true\" class=\"amount\">' +\n                '<%- data.num_results %>' +\n                '</span>' +\n                '</li>',\n            submitBtn: 'button[type=\"submit\"]',\n            searchLabel: '[data-role=minisearch-label]',\n            isExpandable: null,\n            suggestionDelay: 300\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            this.responseList = {\n                indexList: null,\n                selected: null\n            };\n            this.autoComplete = $(this.options.destinationSelector);\n            this.searchForm = $(this.options.formSelector);\n            this.submitBtn = this.searchForm.find(this.options.submitBtn)[0];\n            this.searchLabel = this.searchForm.find(this.options.searchLabel);\n            this.isExpandable = this.options.isExpandable;\n\n            _.bindAll(this, '_onKeyDown', '_onPropertyChange', '_onSubmit');\n\n            this.submitBtn.disabled = true;\n\n            this.element.attr('autocomplete', this.options.autocomplete);\n\n            mediaCheck({\n                media: '(max-width: 768px)',\n                entry: function () {\n                    this.isExpandable = true;\n                }.bind(this),\n                exit: function () {\n                    this.isExpandable = true;\n                }.bind(this)\n            });\n\n            this.searchLabel.on('click', function (e) {\n                // allow input to lose its' focus when clicking on label\n                if (this.isExpandable && this.isActive()) {\n                    e.preventDefault();\n                }\n            }.bind(this));\n\n            this.element.on('blur', $.proxy(function () {\n                if (!this.searchLabel.hasClass('active')) {\n                    return;\n                }\n\n                setTimeout($.proxy(function () {\n                    if (this.autoComplete.is(':hidden')) {\n                        this.setActiveState(false);\n                    } else {\n                        this.element.trigger('focus');\n                    }\n                    this.autoComplete.hide();\n                    this._updateAriaHasPopup(false);\n                }, this), 250);\n            }, this));\n\n            if (this.element.get(0) === document.activeElement) {\n                this.setActiveState(true);\n            }\n\n            this.element.on('focus', this.setActiveState.bind(this, true));\n            this.element.on('keydown', this._onKeyDown);\n            // Prevent spamming the server with requests by waiting till the user has stopped typing for period of time\n            this.element.on('input propertychange', _.debounce(this._onPropertyChange, this.options.suggestionDelay));\n\n            this.searchForm.on('submit', $.proxy(function (e) {\n                this._onSubmit(e);\n                this._updateAriaHasPopup(false);\n            }, this));\n        },\n\n        /**\n         * Checks if search field is active.\n         *\n         * @returns {Boolean}\n         */\n        isActive: function () {\n            return this.searchLabel.hasClass('active');\n        },\n\n        /**\n         * Sets state of the search field to provided value.\n         *\n         * @param {Boolean} isActive\n         */\n        setActiveState: function (isActive) {\n            var searchValue;\n\n            this.searchForm.toggleClass('active', isActive);\n            this.searchLabel.toggleClass('active', isActive);\n\n            if (this.isExpandable) {\n                this.element.attr('aria-expanded', isActive);\n                searchValue = this.element.val();\n                this.element.val('');\n                this.element.val(searchValue);\n            }\n        },\n\n        /**\n         * @private\n         * @return {Element} The first element in the suggestion list.\n         */\n        _getFirstVisibleElement: function () {\n            return this.responseList.indexList ? this.responseList.indexList.first() : false;\n        },\n\n        /**\n         * @private\n         * @return {Element} The last element in the suggestion list.\n         */\n        _getLastElement: function () {\n            return this.responseList.indexList ? this.responseList.indexList.last() : false;\n        },\n\n        /**\n         * @private\n         * @param {Boolean} show - Set attribute aria-haspopup to \"true/false\" for element.\n         */\n        _updateAriaHasPopup: function (show) {\n            if (show) {\n                this.element.attr('aria-haspopup', 'true');\n            } else {\n                this.element.attr('aria-haspopup', 'false');\n            }\n        },\n\n        /**\n         * Clears the item selected from the suggestion list and resets the suggestion list.\n         * @private\n         * @param {Boolean} all - Controls whether to clear the suggestion list.\n         */\n        _resetResponseList: function (all) {\n            this.responseList.selected = null;\n\n            if (all === true) {\n                this.responseList.indexList = null;\n            }\n        },\n\n        /**\n         * Executes when the search box is submitted. Sets the search input field to the\n         * value of the selected item.\n         * @private\n         * @param {Event} e - The submit event\n         */\n        _onSubmit: function (e) {\n            var value = this.element.val();\n\n            if (isEmpty(value)) {\n                e.preventDefault();\n            }\n\n            if (this.responseList.selected) {\n                this.element.val(this.responseList.selected.find('.qs-option-name').text());\n            }\n        },\n\n        /**\n         * Executes when keys are pressed in the search input field. Performs specific actions\n         * depending on which keys are pressed.\n         * @private\n         * @param {Event} e - The key down event\n         * @return {Boolean} Default return type for any unhandled keys\n         */\n        _onKeyDown: function (e) {\n            var keyCode = e.keyCode || e.which;\n\n            switch (keyCode) {\n                case $.ui.keyCode.HOME:\n                    if (this._getFirstVisibleElement()) {\n                        this._getFirstVisibleElement().addClass(this.options.selectClass);\n                        this.responseList.selected = this._getFirstVisibleElement();\n                    }\n                    break;\n\n                case $.ui.keyCode.END:\n                    if (this._getLastElement()) {\n                        this._getLastElement().addClass(this.options.selectClass);\n                        this.responseList.selected = this._getLastElement();\n                    }\n                    break;\n\n                case $.ui.keyCode.ESCAPE:\n                    this._resetResponseList(true);\n                    this.autoComplete.hide();\n                    break;\n\n                case $.ui.keyCode.ENTER:\n                    if (this.element.val().length >= parseInt(this.options.minSearchLength, 10)) {\n                        this.searchForm.trigger('submit');\n                        e.preventDefault();\n                    }\n                    break;\n\n                case $.ui.keyCode.DOWN:\n                    if (this.responseList.indexList) {\n                        if (!this.responseList.selected) {  //eslint-disable-line max-depth\n                            this._getFirstVisibleElement().addClass(this.options.selectClass);\n                            this.responseList.selected = this._getFirstVisibleElement();\n                        } else if (!this._getLastElement().hasClass(this.options.selectClass)) {\n                            this.responseList.selected = this.responseList.selected\n                                .removeClass(this.options.selectClass).next().addClass(this.options.selectClass);\n                        } else {\n                            this.responseList.selected.removeClass(this.options.selectClass);\n                            this._getFirstVisibleElement().addClass(this.options.selectClass);\n                            this.responseList.selected = this._getFirstVisibleElement();\n                        }\n                        this.element.val(this.responseList.selected.find('.qs-option-name').text());\n                        this.element.attr('aria-activedescendant', this.responseList.selected.attr('id'));\n                        this._updateAriaHasPopup(true);\n                        this.autoComplete.show();\n                    }\n                    break;\n\n                case $.ui.keyCode.UP:\n                    if (this.responseList.indexList !== null) {\n                        if (!this._getFirstVisibleElement().hasClass(this.options.selectClass)) {\n                            this.responseList.selected = this.responseList.selected\n                                .removeClass(this.options.selectClass).prev().addClass(this.options.selectClass);\n\n                        } else {\n                            this.responseList.selected.removeClass(this.options.selectClass);\n                            this._getLastElement().addClass(this.options.selectClass);\n                            this.responseList.selected = this._getLastElement();\n                        }\n                        this.element.val(this.responseList.selected.find('.qs-option-name').text());\n                        this.element.attr('aria-activedescendant', this.responseList.selected.attr('id'));\n                        this._updateAriaHasPopup(true);\n                        this.autoComplete.show();\n                    }\n                    break;\n                default:\n                    return true;\n            }\n        },\n\n        /**\n         * Executes when the value of the search input field changes. Executes a GET request\n         * to populate a suggestion list based on entered text. Handles click (select), hover,\n         * and mouseout events on the populated suggestion list dropdown.\n         * @private\n         */\n        _onPropertyChange: function () {\n            var searchField = this.element,\n                clonePosition = {\n                    position: 'absolute',\n                    // Removed to fix display issues\n                    // left: searchField.offset().left,\n                    // top: searchField.offset().top + searchField.outerHeight(),\n                    width: searchField.outerWidth()\n                },\n                source = this.options.template,\n                template = mageTemplate(source),\n                dropdown = $('<ul role=\"listbox\"></ul>'),\n                value = this.element.val();\n\n            this.submitBtn.disabled = true;\n\n            if (value.length >= parseInt(this.options.minSearchLength, 10)) {\n                this.submitBtn.disabled = false;\n\n                if (this.options.url !== '') { //eslint-disable-line eqeqeq\n                    $.getJSON(this.options.url, {\n                        q: value\n                    }, $.proxy(function (data) {\n                        if (data.length) {\n                            $.each(data, function (index, element) {\n                                var html;\n\n                                element.index = index;\n                                html = template({\n                                    data: element\n                                });\n                                dropdown.append(html);\n                            });\n\n                            this._resetResponseList(true);\n\n                            this.responseList.indexList = this.autoComplete.html(dropdown)\n                                .css(clonePosition)\n                                .show()\n                                .find(this.options.responseFieldElements + ':visible');\n\n                            this.element.removeAttr('aria-activedescendant');\n\n                            if (this.responseList.indexList.length) {\n                                this._updateAriaHasPopup(true);\n                            } else {\n                                this._updateAriaHasPopup(false);\n                            }\n\n                            this.responseList.indexList\n                                .on('click', function (e) {\n                                    this.responseList.selected = $(e.currentTarget);\n                                    this.searchForm.trigger('submit');\n                                }.bind(this))\n                                .on('mouseenter mouseleave', function (e) {\n                                    this.responseList.indexList.removeClass(this.options.selectClass);\n                                    $(e.target).addClass(this.options.selectClass);\n                                    this.responseList.selected = $(e.target);\n                                    this.element.attr('aria-activedescendant', $(e.target).attr('id'));\n                                }.bind(this))\n                                .on('mouseout', function (e) {\n                                    if (!this._getLastElement() &&\n                                        this._getLastElement().hasClass(this.options.selectClass)) {\n                                        $(e.target).removeClass(this.options.selectClass);\n                                        this._resetResponseList(false);\n                                    }\n                                }.bind(this));\n                        } else {\n                            this._resetResponseList(true);\n                            this.autoComplete.hide();\n                            this._updateAriaHasPopup(false);\n                            this.element.removeAttr('aria-activedescendant');\n                        }\n                    }, this));\n                }\n            } else {\n                this._resetResponseList(true);\n                this.autoComplete.hide();\n                this._updateAriaHasPopup(false);\n                this.element.removeAttr('aria-activedescendant');\n            }\n        }\n    });\n\n    return $.mage.quickSearch;\n});\n","Magento_Vault/js/view/payment/vault.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*browser:true*/\n\n/* @api */\ndefine([\n    'underscore',\n    'uiComponent',\n    'Magento_Checkout/js/model/payment/renderer-list',\n    'uiLayout',\n    'uiRegistry'\n], function (_, Component, rendererList, layout, registry) {\n    'use strict';\n\n    var vaultGroupName = 'vaultGroup';\n\n    layout([{\n        name: vaultGroupName,\n        component: 'Magento_Checkout/js/model/payment/method-group',\n        alias: 'vault',\n        sortOrder: 10\n    }]);\n\n    registry.get(vaultGroupName, function (vaultGroup) {\n        _.each(window.checkoutConfig.payment.vault, function (config, index) {\n            rendererList.push(\n                {\n                    type: index,\n                    config: config.config,\n                    component: config.component,\n                    group: vaultGroup,\n\n                    /**\n                     * Custom payment method types comparator\n                     * @param {String} typeA\n                     * @param {String} typeB\n                     * @return {Boolean}\n                     */\n                    typeComparatorCallback: function (typeA, typeB) {\n                        // vault token items have the same name as vault payment without index\n                        return typeA.substring(0, typeA.lastIndexOf('_')) === typeB;\n                    }\n                }\n            );\n        });\n    });\n\n    /**\n     * Add view logic here if needed\n     */\n    return Component.extend({});\n});\n","Magento_Vault/js/view/payment/vault-enabler.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*browser:true*/\n\n/* @api */\ndefine(\n    [\n        'uiElement'\n    ],\n    function (\n        Component\n    ) {\n        'use strict';\n\n        return Component.extend({\n            defaults: {\n                isActivePaymentTokenEnabler: true\n            },\n\n            /**\n             * @param {String} paymentCode\n             */\n            setPaymentCode: function (paymentCode) {\n                this.paymentCode = paymentCode;\n            },\n\n            /**\n             * @returns {Object}\n             */\n            initObservable: function () {\n                this._super()\n                    .observe([\n                        'isActivePaymentTokenEnabler'\n                    ]);\n\n                return this;\n            },\n\n            /**\n             * @param {Object} data\n             */\n            visitAdditionalData: function (data) {\n                if (!this.isVaultEnabled()) {\n                    return;\n                }\n\n                if (!('additional_data' in data)) {\n                    data['additional_data'] = {};\n                }\n\n                data['additional_data']['is_active_payment_token_enabler'] = this.isActivePaymentTokenEnabler();\n            },\n\n            /**\n             * @returns {Boolean}\n             */\n            isVaultEnabled: function () {\n                return typeof window.checkoutConfig.vault[this.paymentCode] !== 'undefined' &&\n                    window.checkoutConfig.vault[this.paymentCode]['is_enabled'] === true;\n            }\n        });\n    }\n);\n","Magento_Vault/js/view/payment/method-renderer/vault.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*browser:true*/\n\ndefine(\n    [\n        'Magento_Checkout/js/view/payment/default',\n        'Magento_Checkout/js/action/select-payment-method',\n        'Magento_Checkout/js/checkout-data'\n    ],\n    function (Component, selectPaymentMethod, checkoutData) {\n        'use strict';\n\n        return Component.extend({\n            defaults: {\n                template: 'Magento_Vault/payment/form'\n            },\n\n            /**\n             * @returns {exports.initObservable}\n             */\n            initObservable: function () {\n                this._super()\n                    .observe([]);\n\n                return this;\n            },\n\n            /**\n             * @returns\n             */\n            selectPaymentMethod: function () {\n                selectPaymentMethod(\n                    {\n                        method: this.getId()\n                    }\n                );\n                checkoutData.setSelectedPaymentMethod(this.getId());\n\n                return true;\n            },\n\n            /**\n             * @returns {String}\n             */\n            getTitle: function () {\n                return '';\n            },\n\n            /**\n             * @returns {String}\n             */\n            getToken: function () {\n                return '';\n            },\n\n            /**\n             * @returns {String}\n             */\n            getId: function () {\n                return this.index;\n            },\n\n            /**\n             * @returns {String}\n             */\n            getCode: function () {\n                return this.code;\n            },\n\n            /**\n             * Get last 4 digits of card\n             * @returns {String}\n             */\n            getMaskedCard: function () {\n                return '';\n            },\n\n            /**\n             * Get expiration date\n             * @returns {String}\n             */\n            getExpirationDate: function () {\n                return '';\n            },\n\n            /**\n             * Get card type\n             * @returns {String}\n             */\n            getCardType: function () {\n                return '';\n            },\n\n            /**\n             * @param {String} type\n             * @returns {Boolean}\n             */\n            getIcons: function (type) {\n                return window.checkoutConfig.payment.ccform.icons.hasOwnProperty(type) ?\n                    window.checkoutConfig.payment.ccform.icons[type]\n                    : false;\n            },\n\n            /**\n             * Return state of place order button.\n             *\n             * @return {Boolean}\n             */\n            isButtonActive: function () {\n                return this.isActive() && this.isPlaceOrderActionAllowed();\n            },\n\n            /**\n             * Check if payment is active.\n             *\n             * @return {Boolean}\n             */\n            isActive: function () {\n                return this.isChecked() === this.getId();\n            },\n\n            /**\n             * @returns {*}\n             */\n            getData: function () {\n                var data = {\n                    method: this.getCode()\n                };\n\n                data['additional_data'] = {};\n                data['additional_data']['public_hash'] = this.getToken();\n\n                return data;\n            }\n        });\n    }\n);\n","Magento_Vault/js/customer_account/deleteWidget.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'Magento_Ui/js/modal/modalToggle',\n    'mage/translate'\n], function ($, modalToggle) {\n    'use strict';\n\n    return function (config, deleteButton) {\n        config.buttons = [\n            {\n                text: $.mage.__('Cancel'),\n                class: 'action secondary cancel'\n            }, {\n                text: $.mage.__('Delete'),\n                class: 'action primary',\n\n                /**\n                 * Default action on button click\n                 */\n                click: function (event) { //eslint-disable-line no-unused-vars\n                    $(deleteButton.form).trigger('submit');\n                }\n            }\n        ];\n\n        modalToggle(config, deleteButton);\n    };\n});\n","Magento_GiftMessage/js/gift-options.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.giftOptions', {\n        options: {\n            mageError: 'mage-error',\n            noDisplay: 'no-display',\n            requiredEntry: 'required-entry'\n        },\n\n        /**\n         * Initial toggle of the various gift options after widget instantiation.\n         * @private\n         */\n        _init: function () {\n            this._toggleVisibility();\n        },\n\n        /**\n         * Bind a click handler to the widget's context element.\n         * @private\n         */\n        _create: function () {\n            this.element.on('click', $.proxy(this._toggleVisibility, this));\n            $(this.element.data('selector').id).find('.giftmessage-area')\n                .on('change', $.proxy(this._toggleRequired, this));\n        },\n\n        /**\n         * Toggle the visibility of the widget's context element's selector(s).\n         * @private\n         * @param {jQuery.Event} event - Click event. Target is a checkbox.\n         */\n        _toggleVisibility: function (event) {\n            var checkbox = event ? $(event.target) : this.element,\n                container = $(checkbox.data('selector').id),\n                _this;\n\n            if (checkbox.is(':checked')) {\n                container.show()\n                    .find('.giftmessage-area:not(:visible)').each(function (x, element) {\n                        if ($(element).val().length > 0) {\n                            $(element).trigger('change');\n                            container.find('a').trigger('click');\n                        }\n                    });\n            } else {\n                _this = this;\n                container.hide()\n                    .find('.input-text:not(.giftmessage-area)').each(function (x, element) {\n                        $(element).val(element.defaultValue).removeClass(_this.options.mageError)\n                            .next('div.' + _this.options.mageError).remove();\n                    }).end()\n                    .find('.giftmessage-area').val('').change().end()\n                    .find('.select').val('').change().end()\n                    .find('.checkbox:checked').prop('checked', false).trigger('click').prop('checked', false).end()\n                    .find('.price-box').addClass(this.options.noDisplay).end();\n            }\n        },\n\n        /**\n         * Make the From and To input fields required if a gift message has been written.\n         * @private\n         * @param {jQuery.Event} event - Change event. Target is a textarea.\n         */\n        _toggleRequired: function (event) {\n            var textArea = $(event.target),\n                length = textArea.val().length;\n\n            textArea.closest('li').prev('.fields')\n                .find('.input-text').toggleClass(this.options.requiredEntry, length > 0);\n        }\n    });\n\n    return $.mage.giftOptions;\n});\n","Magento_GiftMessage/js/view/gift-message.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'Magento_GiftMessage/js/model/gift-message',\n    'Magento_GiftMessage/js/model/gift-options',\n    'Magento_GiftMessage/js/action/gift-options'\n], function (Component, GiftMessage, giftOptions, giftOptionsService) {\n    'use strict';\n\n    return Component.extend({\n        formBlockVisibility: null,\n        resultBlockVisibility: null,\n        model: {},\n\n        /**\n         * Component init\n         */\n        initialize: function () {\n            var self = this,\n                model;\n\n            this._super()\n                .observe('formBlockVisibility')\n                .observe({\n                    'resultBlockVisibility': false\n                });\n\n            this.itemId = this.itemId || 'orderLevel';\n            model = new GiftMessage(this.itemId);\n            this.model = model;\n            this.isResultBlockVisible();\n            giftOptions.addOption(model);\n\n            this.model.getObservable('isClear').subscribe(function (value) {\n                if (value == true) { //eslint-disable-line eqeqeq\n                    self.formBlockVisibility(false);\n                    self.model.getObservable('alreadyAdded')(true);\n                }\n            });\n        },\n\n        /**\n         * Is reslt block visible\n         */\n        isResultBlockVisible: function () {\n            var self = this;\n\n            if (this.model.getObservable('alreadyAdded')()) {\n                this.resultBlockVisibility(true);\n            }\n            this.model.getObservable('additionalOptionsApplied').subscribe(function (value) {\n                if (value == true) { //eslint-disable-line eqeqeq\n                    self.resultBlockVisibility(true);\n                }\n            });\n        },\n\n        /**\n         * @param {String} key\n         * @return {*}\n         */\n        getObservable: function (key) {\n            return this.model.getObservable(key);\n        },\n\n        /**\n         * Hide\\Show form block\n         */\n        toggleFormBlockVisibility: function () {\n            if (!this.model.getObservable('alreadyAdded')()) {\n                this.formBlockVisibility(!this.formBlockVisibility());\n            } else {\n                this.resultBlockVisibility(!this.resultBlockVisibility());\n            }\n        },\n\n        /**\n         * Edit options\n         */\n        editOptions: function () {\n            this.resultBlockVisibility(false);\n            this.formBlockVisibility(true);\n        },\n\n        /**\n         * Delete options\n         */\n        deleteOptions: function () {\n            giftOptionsService(this.model, true);\n        },\n\n        /**\n         * Hide form block\n         */\n        hideFormBlock: function () {\n            this.formBlockVisibility(false);\n\n            if (this.model.getObservable('alreadyAdded')()) {\n                this.resultBlockVisibility(true);\n            }\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        hasActiveOptions: function () {\n            var regionData = this.getRegion('additionalOptions'),\n                options = regionData(),\n                i;\n\n            for (i = 0; i < options.length; i++) {\n                if (options[i].isActive()) {\n                    return true;\n                }\n            }\n\n            return false;\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isActive: function () {\n            return this.model.isGiftMessageAvailable();\n        },\n\n        /**\n         * Submit options\n         */\n        submitOptions: function () {\n            giftOptionsService(this.model);\n        }\n    });\n});\n","Magento_GiftMessage/js/action/gift-options.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'Magento_GiftMessage/js/model/url-builder',\n    'mage/storage',\n    'Magento_Ui/js/model/messageList',\n    'Magento_Checkout/js/model/error-processor',\n    'mage/url',\n    'Magento_Checkout/js/model/quote',\n    'underscore'\n], function (urlBuilder, storage, messageList, errorProcessor, url, quote, _) {\n    'use strict';\n\n    return function (giftMessage, remove) {\n        var serviceUrl;\n\n        url.setBaseUrl(giftMessage.getConfigValue('baseUrl'));\n\n        if (giftMessage.getConfigValue('isCustomerLoggedIn')) {\n            serviceUrl = urlBuilder.createUrl('/carts/mine/gift-message', {});\n\n            if (giftMessage.itemId != 'orderLevel') { //eslint-disable-line eqeqeq\n                serviceUrl = urlBuilder.createUrl('/carts/mine/gift-message/:itemId', {\n                    itemId: giftMessage.itemId\n                });\n            }\n        } else {\n            serviceUrl = urlBuilder.createUrl('/guest-carts/:cartId/gift-message', {\n                cartId: quote.getQuoteId()\n            });\n\n            if (giftMessage.itemId != 'orderLevel') { //eslint-disable-line eqeqeq\n                serviceUrl = urlBuilder.createUrl(\n                    '/guest-carts/:cartId/gift-message/:itemId',\n                    {\n                        cartId: quote.getQuoteId(), itemId: giftMessage.itemId\n                    }\n                );\n            }\n        }\n        messageList.clear();\n\n        storage.post(\n            serviceUrl,\n            JSON.stringify({\n                'gift_message': giftMessage.getSubmitParams(remove)\n            })\n        ).done(function () {\n            giftMessage.reset();\n            _.each(giftMessage.getAfterSubmitCallbacks(), function (callback) {\n                if (_.isFunction(callback)) {\n                    callback();\n                }\n            });\n        }).fail(function (response) {\n            errorProcessor.process(response);\n        });\n    };\n});\n","Magento_GiftMessage/js/model/gift-message.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'uiElement',\n    'underscore',\n    'mage/url'\n], function (uiElement, _, url) {\n    'use strict';\n\n    var provider = uiElement();\n\n    return function (itemId) {\n        var model = {\n            id: 'message-' + itemId,\n            itemId: itemId,\n            observables: {},\n            additionalOptions: [],\n            submitParams: [\n                'recipient',\n                'sender',\n                'message'\n            ],\n\n            /**\n             * Initialize.\n             */\n            initialize: function () {\n                var message = false;\n\n                this.getObservable('alreadyAdded')(false);\n\n                if (this.itemId == 'orderLevel') { //eslint-disable-line eqeqeq\n                    message = window.giftOptionsConfig.giftMessage.hasOwnProperty(this.itemId) ?\n                        window.giftOptionsConfig.giftMessage[this.itemId] :\n                        null;\n                } else {\n                    message =\n                        window.giftOptionsConfig.giftMessage.hasOwnProperty('itemLevel') &&\n                        window.giftOptionsConfig.giftMessage.itemLevel.hasOwnProperty(this.itemId) ?\n                            window.giftOptionsConfig.giftMessage.itemLevel[this.itemId].message :\n                            null;\n                }\n\n                if (_.isObject(message)) {\n                    this.getObservable('recipient')(message.recipient);\n                    this.getObservable('sender')(message.sender);\n                    this.getObservable('message')(message.message);\n                    this.getObservable('alreadyAdded')(true);\n                }\n            },\n\n            /**\n             * @param {String} key\n             * @return {*}\n             */\n            getObservable: function (key) {\n                this.initObservable(this.id, key);\n\n                return provider[this.getUniqueKey(this.id, key)];\n            },\n\n            /**\n             * @param {String} node\n             * @param {String} key\n             */\n            initObservable: function (node, key) {\n                if (node && !this.observables.hasOwnProperty(node)) {\n                    this.observables[node] = [];\n                }\n\n                if (key && this.observables[node].indexOf(key) === -1) {\n                    this.observables[node].push(key);\n                    provider.observe(this.getUniqueKey(node, key));\n                }\n            },\n\n            /**\n             * @param {String} node\n             * @param {String} key\n             * @return {String}\n             */\n            getUniqueKey: function (node, key) {\n                return node + '-' + key;\n            },\n\n            /**\n             * @param {String} key\n             * @return {null}\n             */\n            getConfigValue: function (key) {\n                return window.giftOptionsConfig.hasOwnProperty(key) ?\n                    window.giftOptionsConfig[key]\n                    : null;\n            },\n\n            /**\n             * Reset.\n             */\n            reset: function () {\n                this.getObservable('isClear')(true);\n            },\n\n            /**\n             * @return {Array}\n             */\n            getAfterSubmitCallbacks: function () {\n                var callbacks = [];\n\n                callbacks.push(this.afterSubmit);\n                _.each(this.additionalOptions, function (option) {\n                    if (_.isFunction(option.afterSubmit)) {\n                        callbacks.push(option.afterSubmit);\n                    }\n                });\n\n                return callbacks;\n            },\n\n            /**\n             * After submit.\n             */\n            afterSubmit: function () {\n                window.location.href = url.build('checkout/cart/updatePost') +\n                    '?form_key=' + window.checkoutConfig.formKey +\n                    '&cart[]';\n            },\n\n            /**\n             * @param {Boolean} remove\n             * @return {Object}\n             */\n            getSubmitParams: function (remove) {\n                var params = {},\n                    self = this;\n\n                _.each(this.submitParams, function (key) {\n                    var observable = provider[self.getUniqueKey(self.id, key)];\n\n                    if (_.isFunction(observable)) {\n                        params[key] = remove ? null : observable();\n                    }\n                });\n\n                if (this.additionalOptions.length) {\n                    params['extension_attributes'] = {};\n                }\n                _.each(this.additionalOptions, function (option) {\n                    if (_.isFunction(option.getSubmitParams)) {\n                        params['extension_attributes'] = _.extend(\n                            params['extension_attributes'],\n                            option.getSubmitParams(remove)\n                        );\n                    }\n                });\n\n                return params;\n            },\n\n            /**\n             * Check if gift message can be displayed\n             *\n             * @returns {Boolean}\n             */\n            isGiftMessageAvailable: function () {\n                var isGloballyAvailable,\n                    giftMessageConfig,\n                    itemConfig;\n\n                // itemId represent gift message level: 'orderLevel' constant or cart item ID\n                if (this.itemId === 'orderLevel') {\n                    return this.getConfigValue('isOrderLevelGiftOptionsEnabled');\n                }\n\n                // gift message product configuration must override system configuration\n                isGloballyAvailable = this.getConfigValue('isItemLevelGiftOptionsEnabled');\n                giftMessageConfig = window.giftOptionsConfig.giftMessage;\n                itemConfig = giftMessageConfig.hasOwnProperty('itemLevel') &&\n                    giftMessageConfig.itemLevel.hasOwnProperty(this.itemId) ?\n                    giftMessageConfig.itemLevel[this.itemId] :\n                    {};\n\n                return itemConfig.hasOwnProperty('is_available') ? itemConfig['is_available'] : isGloballyAvailable;\n            }\n        };\n\n        model.initialize();\n\n        return model;\n    };\n});\n","Magento_GiftMessage/js/model/gift-options.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    'ko'\n], function (_, ko) {\n    'use strict';\n\n    return {\n        options: ko.observableArray([]),\n\n        /**\n         * @param {Object} option\n         */\n        addOption: function (option) {\n            if (!this.options().hasOwnProperty(option.itemId)) {\n                this.options.push({\n                        id: option.itemId, value: option\n                    }\n                );\n            }\n        },\n\n        /**\n         * @param {*} itemId\n         * @return {*}\n         */\n        getOptionByItemId: function (itemId) {\n            var option = null;\n\n            _.each(this.options(), function (data) {\n                if (data.id === itemId) {\n                    option = data.value;\n\n                    return false;\n                }\n            });\n\n            return option;\n        }\n    };\n});\n","Magento_GiftMessage/js/model/url-builder.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/url-builder'\n], function ($, urlBuilder) {\n    'use strict';\n\n    return $.extend(urlBuilder, {\n        storeCode: window.giftOptionsConfig.storeCode\n    });\n});\n","Magento_ReCaptchaFrontendUi/js/nonInlineReCaptchaRenderer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global grecaptcha */\ndefine([\n    'jquery',\n    'jquery/z-index'\n], function ($) {\n    'use strict';\n\n    var reCaptchaEntities = [],\n        initialized = false,\n        rendererRecaptchaId = 'recaptcha-invisible',\n        rendererReCaptcha = null;\n\n    return {\n        /**\n         * Add reCaptcha entity to checklist.\n         *\n         * @param {jQuery} reCaptchaEntity\n         * @param {Object} parameters\n         */\n        add: function (reCaptchaEntity, parameters) {\n            if (!initialized) {\n                this.init();\n                grecaptcha.render(rendererRecaptchaId, parameters);\n                setInterval(this.resolveVisibility, 100);\n                initialized = true;\n            }\n\n            reCaptchaEntities.push(reCaptchaEntity);\n        },\n\n        /**\n         * Show additional reCaptcha instance if any other should be visible, otherwise hide it.\n         */\n        resolveVisibility: function () {\n            reCaptchaEntities.some(function (entity) {\n                return entity.is(':visible') &&\n                    // 900 is some magic z-index value of modal popups.\n                    (entity.closest('[data-role=\\'modal\\']').length === 0 || entity.zIndex() > 900);\n            }) ? rendererReCaptcha.show() : rendererReCaptcha.hide();\n        },\n\n        /**\n         * Initialize additional reCaptcha instance.\n         */\n        init: function () {\n            rendererReCaptcha = $('<div/>', {\n                'id': rendererRecaptchaId\n            });\n            rendererReCaptcha.hide();\n            $('body').append(rendererReCaptcha);\n        }\n    };\n});\n","Magento_ReCaptchaFrontendUi/js/reCaptcha.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global grecaptcha */\ndefine(\n    [\n        'uiComponent',\n        'jquery',\n        'ko',\n        'underscore',\n        'Magento_ReCaptchaFrontendUi/js/registry',\n        'Magento_ReCaptchaFrontendUi/js/reCaptchaScriptLoader',\n        'Magento_ReCaptchaFrontendUi/js/nonInlineReCaptchaRenderer'\n    ], function (Component, $, ko, _, registry, reCaptchaLoader, nonInlineReCaptchaRenderer) {\n        'use strict';\n\n        return Component.extend({\n\n            defaults: {\n                template: 'Magento_ReCaptchaFrontendUi/reCaptcha',\n                reCaptchaId: 'recaptcha'\n            },\n\n            /**\n             * @inheritdoc\n             */\n            initialize: function () {\n                this._super();\n                this._loadApi();\n            },\n\n            /**\n             * Loads recaptchaapi API and triggers event, when loaded\n             * @private\n             */\n            _loadApi: function () {\n                if (this._isApiRegistered !== undefined) {\n                    if (this._isApiRegistered === true) {\n                        $(window).trigger('recaptchaapiready');\n                    }\n\n                    return;\n                }\n                this._isApiRegistered = false;\n\n                // global function\n                window.globalOnRecaptchaOnLoadCallback = function () {\n                    this._isApiRegistered = true;\n                    $(window).trigger('recaptchaapiready');\n                }.bind(this);\n\n                reCaptchaLoader.addReCaptchaScriptTag();\n            },\n\n            /**\n             * Checking that reCAPTCHA is invisible type\n             * @returns {Boolean}\n             */\n            getIsInvisibleRecaptcha: function () {\n                if (this.settings ===\n\n                    void 0) {\n                    return false;\n                }\n\n                return this.settings.invisible;\n            },\n\n            /**\n             * reCAPTCHA callback\n             * @param {String} token\n             */\n            reCaptchaCallback: function (token) {\n                if (this.getIsInvisibleRecaptcha()) {\n                    this.tokenField.value = token;\n                    this.$parentForm.submit();\n                }\n            },\n\n            /**\n             * Initialize reCAPTCHA after first rendering\n             */\n            initCaptcha: function () {\n                var $parentForm,\n                    $wrapper,\n                    $reCaptcha,\n                    widgetId,\n                    parameters;\n\n                if (this.captchaInitialized || this.settings ===\n\n                    void 0) {\n                    return;\n                }\n\n                this.captchaInitialized = true;\n\n                /*\n                 * Workaround for data-bind issue:\n                 * We cannot use data-bind to link a dynamic id to our component\n                 * See:\n                 * https://stackoverflow.com/questions/46657573/recaptcha-the-bind-parameter-must-be-an-element-or-id\n                 *\n                 * We create a wrapper element with a wrapping id and we inject the real ID with jQuery.\n                 * In this way we have no data-bind attribute at all in our reCAPTCHA div\n                 */\n                $wrapper = $('#' + this.getReCaptchaId() + '-wrapper');\n                $reCaptcha = $wrapper.find('.g-recaptcha');\n                $reCaptcha.attr('id', this.getReCaptchaId());\n\n                $parentForm = $wrapper.parents('form');\n\n                if (this.settings === undefined) {\n\n                    return;\n                }\n\n                parameters = _.extend(\n                    {\n                        'callback': function (token) { // jscs:ignore jsDoc\n                            this.reCaptchaCallback(token);\n                            this.validateReCaptcha(true);\n                        }.bind(this),\n                        'expired-callback': function () {\n                            this.validateReCaptcha(false);\n                        }.bind(this)\n                    },\n                    this.settings.rendering\n                );\n\n                if (parameters.size === 'invisible' && parameters.badge !== 'inline') {\n                    nonInlineReCaptchaRenderer.add($reCaptcha, parameters);\n                }\n\n                // eslint-disable-next-line no-undef\n                widgetId = grecaptcha.render(this.getReCaptchaId(), parameters);\n                this.initParentForm($parentForm, widgetId);\n\n                registry.ids.push(this.getReCaptchaId());\n                registry.captchaList.push(widgetId);\n                registry.tokenFields.push(this.tokenField);\n\n            },\n\n            /**\n             * Initialize parent form.\n             *\n             * @param {Object} parentForm\n             * @param {String} widgetId\n             */\n            initParentForm: function (parentForm, widgetId) {\n                var listeners;\n\n                if (this.getIsInvisibleRecaptcha() && parentForm.length > 0) {\n                    parentForm.submit(function (event) {\n                        if (!this.tokenField.value) {\n                            // eslint-disable-next-line no-undef\n                            grecaptcha.execute(widgetId);\n                            event.preventDefault(event);\n                            event.stopImmediatePropagation();\n                        }\n                    }.bind(this));\n\n                    // Move our (last) handler topmost. We need this to avoid submit bindings with ko.\n                    listeners = $._data(parentForm[0], 'events').submit;\n                    listeners.unshift(listeners.pop());\n\n                    // Create a virtual token field\n                    this.tokenField = $('<input type=\"text\" name=\"token\" style=\"display: none\" />')[0];\n                    this.$parentForm = parentForm;\n                    parentForm.append(this.tokenField);\n                } else {\n                    this.tokenField = null;\n                }\n                if ($('#send2').length > 0) {$('#send2').prop('disabled', false);}\n            },\n\n            /**\n             * Validates reCAPTCHA\n             * @param {*} state\n             * @returns {jQuery}\n             */\n            validateReCaptcha: function (state) {\n                if (!this.getIsInvisibleRecaptcha()) {\n                    return $(document).find('input[type=checkbox].required-captcha').prop('checked', state);\n                }\n            },\n\n            /**\n             * Render reCAPTCHA\n             */\n            renderReCaptcha: function () {\n                if (window.grecaptcha && window.grecaptcha.render) { // Check if reCAPTCHA is already loaded\n                    this.initCaptcha();\n                } else { // Wait for reCAPTCHA to be loaded\n                    $(window).on('recaptchaapiready', function () {\n                        this.initCaptcha();\n                    }.bind(this));\n                }\n            },\n\n            /**\n             * Get reCAPTCHA ID\n             * @returns {String}\n             */\n            getReCaptchaId: function () {\n                return this.reCaptchaId;\n            }\n        });\n    });\n","Magento_ReCaptchaFrontendUi/js/registry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['ko'], function (ko) {\n    'use strict';\n\n    return {\n        ids: ko.observableArray([]),\n        captchaList: ko.observableArray([]),\n        tokenFields: ko.observableArray([])\n    };\n});\n","Magento_ReCaptchaFrontendUi/js/reCaptchaScriptLoader.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    var scriptTagAdded = false;\n\n    return {\n        /**\n         * Add script tag. Script tag should be added once\n         */\n        addReCaptchaScriptTag: function () {\n            var element, scriptTag;\n\n            if (!scriptTagAdded) {\n                element = document.createElement('script');\n                scriptTag = document.getElementsByTagName('script')[0];\n\n                element.async = true;\n                element.src = 'https://www.google.com/recaptcha/api.js' +\n                    '?onload=globalOnRecaptchaOnLoadCallback&render=explicit';\n\n                scriptTag.parentNode.insertBefore(element, scriptTag);\n                scriptTagAdded = true;\n            }\n        }\n    };\n});\n","Magento_ReCaptchaFrontendUi/js/ui-messages-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['Magento_ReCaptchaFrontendUi/js/registry'], function (registry) {\n    'use strict';\n\n    return function (originalComponent) {\n        return originalComponent.extend({\n            /**\n             * Initialize reset on messages\n             * @returns {initialize}\n             */\n            initialize: function () {\n                this._super();\n\n                this.messageContainer.errorMessages.subscribe(function () {\n                    var\n                        i,\n                        captchaList = registry.captchaList(),\n                        tokenFieldsList = registry.tokenFields();\n\n                    for (i = 0; i < captchaList.length; i++) {\n                        // eslint-disable-next-line no-undef\n                        grecaptcha.reset(captchaList[i]);\n\n                        if (tokenFieldsList[i]) {\n                            tokenFieldsList[i].value = '';\n                        }\n                    }\n                }, null, 'arrayChange');\n\n                return this;\n            }\n        });\n    };\n});\n","Magento_InstantPurchase/js/view/instant-purchase.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    'jquery',\n    'underscore',\n    'uiComponent',\n    'Magento_Ui/js/modal/confirm',\n    'Magento_Customer/js/customer-data',\n    'mage/url',\n    'mage/template',\n    'mage/translate',\n    'text!Magento_InstantPurchase/template/confirmation.html',\n    'mage/validation'\n], function (ko, $, _, Component, confirm, customerData, urlBuilder, mageTemplate, $t, confirmationTemplate) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_InstantPurchase/instant-purchase',\n            buttonText: $t('Instant Purchase'),\n            purchaseUrl: urlBuilder.build('instantpurchase/button/placeOrder'),\n            showButton: false,\n            paymentToken: null,\n            shippingAddress: null,\n            billingAddress: null,\n            shippingMethod: null,\n            productFormSelector: '#product_addtocart_form',\n            confirmationTitle: $t('Instant Purchase Confirmation'),\n            confirmationData: {\n                message: $t('Are you sure you want to place order and pay?'),\n                shippingAddressTitle: $t('Shipping Address'),\n                billingAddressTitle: $t('Billing Address'),\n                paymentMethodTitle: $t('Payment Method'),\n                shippingMethodTitle: $t('Shipping Method')\n            }\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            var instantPurchase = customerData.get('instant-purchase');\n\n            this._super();\n\n            this.setPurchaseData(instantPurchase());\n            instantPurchase.subscribe(this.setPurchaseData, this);\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super()\n                .observe('showButton paymentToken shippingAddress billingAddress shippingMethod');\n\n            return this;\n        },\n\n        /**\n         * Set data from customerData.\n         *\n         * @param {Object} data\n         */\n        setPurchaseData: function (data) {\n            this.showButton(data.available);\n            this.paymentToken(data.paymentToken);\n            this.shippingAddress(data.shippingAddress);\n            this.billingAddress(data.billingAddress);\n            this.shippingMethod(data.shippingMethod);\n        },\n\n        /**\n         * Confirmation method\n         */\n        instantPurchase: function () {\n            var form = $(this.productFormSelector),\n                confirmTemplate = mageTemplate(confirmationTemplate),\n                confirmData = _.extend({}, this.confirmationData, {\n                    paymentToken: this.paymentToken().summary,\n                    shippingAddress: this.shippingAddress().summary,\n                    billingAddress: this.billingAddress().summary,\n                    shippingMethod: this.shippingMethod().summary\n                });\n\n            if (!(form.validation() && form.validation('isValid'))) {\n                return;\n            }\n\n            confirm({\n                title: this.confirmationTitle,\n                content: confirmTemplate({\n                    data: confirmData\n                }),\n                actions: {\n                    /** @inheritdoc */\n                    confirm: function () {\n                        $.ajax({\n                            url: this.purchaseUrl,\n                            data: form.serialize(),\n                            type: 'post',\n                            dataType: 'json',\n\n                            /** Show loader before send */\n                            beforeSend: function () {\n                                $('body').trigger('processStart');\n                            }\n                        }).always(function () {\n                            $('body').trigger('processStop');\n                        });\n                    }.bind(this)\n                }\n            });\n        }\n    });\n});\n","Magento_ReCaptchaWebapiUi/js/webapiReCaptcha.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n// jscs:disable jsDoc\n\n/* global grecaptcha */\ndefine(\n    [\n        'Magento_ReCaptchaFrontendUi/js/reCaptcha',\n        'Magento_ReCaptchaWebapiUi/js/webapiReCaptchaRegistry'\n    ],\n    function (Component, registry) {\n        'use strict';\n\n        return Component.extend({\n            defaults: {\n                autoTrigger: false\n            },\n\n            /**\n             * Provide the token to the registry.\n             *\n             * @param {String} token\n             */\n            reCaptchaCallback: function (token) {\n                //Make the token retrievable in other UI components.\n                registry.tokens[this.getReCaptchaId()] = token;\n\n                if (typeof registry._listeners[this.getReCaptchaId()] !== 'undefined') {\n                    registry._listeners[this.getReCaptchaId()](token);\n                }\n            },\n\n            /**\n             * Register this ReCaptcha.\n             *\n             * @param {Object} parentForm\n             * @param {String} widgetId\n             */\n            initParentForm: function (parentForm, widgetId) {\n                var self = this,\n                    trigger;\n\n                trigger = function () {\n                    self.reCaptchaCallback(grecaptcha.getResponse(widgetId));\n                };\n                registry._isInvisibleType[this.getReCaptchaId()] = false;\n\n                if (this.getIsInvisibleRecaptcha()) {\n                    trigger = function () {\n                        grecaptcha.execute(widgetId);\n                    };\n                    registry._isInvisibleType[this.getReCaptchaId()] = true;\n                }\n\n                if (this.autoTrigger) {\n                    //Validate ReCaptcha when initiated\n                    trigger();\n                    registry.triggers[this.getReCaptchaId()] = new Function();\n                } else {\n                    registry.triggers[this.getReCaptchaId()] = trigger;\n                }\n                this.tokenField = null;\n            }\n        });\n    }\n);\n","Magento_ReCaptchaWebapiUi/js/webapiReCaptchaRegistry.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         * recaptchaId: token map.\n         *\n         * Tokens for already verified recaptcha.\n         */\n        tokens: {},\n\n        /**\n         * recaptchaId: triggerFn map.\n         *\n         * Call a trigger to initiate a recaptcha verification.\n         */\n        triggers: {},\n\n        /**\n         * recaptchaId: callback map\n         */\n        _listeners: {},\n\n        /**\n         * recaptchaId: bool map\n         */\n        _isInvisibleType: {},\n\n        /**\n         * Add a listener to when the ReCaptcha finishes verification\n         * @param {String} id - ReCaptchaId\n         * @param {Function} func - Will be called back with the token\n         */\n        addListener: function (id, func) {\n            if (this.tokens.hasOwnProperty(id)) {\n                func(this.tokens[id]);\n            } else {\n                this._listeners[id] = func;\n            }\n        },\n\n        /**\n         * Remove a listener\n         *\n         * @param id\n         */\n        removeListener: function (id) {\n            this._listeners[id] = undefined;\n        }\n    };\n});\n","Magento_ReCaptchaWebapiUi/js/jquery-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n// jscs:disable requireDotNotation\n\ndefine([\n    'mage/utils/wrapper'\n], function (wrapper) {\n    'use strict';\n\n    return function (jQuery) {\n        jQuery.ajax = wrapper.wrapSuper(jQuery.ajax, function () {\n            //Moving ReCaptcha value from payload to the header for requests to web API\n            var settings,\n                payload;\n\n            if (arguments.length !== 0) {\n                settings = arguments.length === 1 ? arguments[0] : arguments[1];\n            }\n\n            if (settings && settings.hasOwnProperty('data')) {\n                //The request has a body, trying to parse JSON data\n                try {\n                    payload = JSON.parse(settings.data);\n                } catch (e) {\n                    //Not JSON\n                }\n            }\n\n            if (payload && payload.hasOwnProperty('xReCaptchaValue')) {\n                if (!settings.hasOwnProperty('headers')) {\n                    settings.headers = {};\n                }\n                settings.headers['X-ReCaptcha'] = payload.xReCaptchaValue;\n                delete payload['xReCaptchaValue'];\n                settings.data = JSON.stringify(payload);\n            }\n\n            return this._super.apply(this, arguments);\n        });\n\n        return jQuery;\n    };\n});\n","Magento_CheckoutAgreements/js/view/checkout-agreements.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko',\n    'jquery',\n    'uiComponent',\n    'Magento_CheckoutAgreements/js/model/agreements-modal'\n], function (ko, $, Component, agreementsModal) {\n    'use strict';\n\n    var checkoutConfig = window.checkoutConfig,\n        agreementManualMode = 1,\n        agreementsConfig = checkoutConfig ? checkoutConfig.checkoutAgreements : {};\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_CheckoutAgreements/checkout/checkout-agreements'\n        },\n        isVisible: agreementsConfig.isEnabled,\n        agreements: agreementsConfig.agreements,\n        modalTitle: ko.observable(null),\n        modalContent: ko.observable(null),\n        contentHeight: ko.observable(null),\n        modalWindow: null,\n\n        /**\n         * Checks if agreement required\n         *\n         * @param {Object} element\n         */\n        isAgreementRequired: function (element) {\n            return element.mode == agreementManualMode; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * Show agreement content in modal\n         *\n         * @param {Object} element\n         */\n        showContent: function (element) {\n            this.modalTitle(element.checkboxText);\n            this.modalContent(element.content);\n            this.contentHeight(element.contentHeight ? element.contentHeight : 'auto');\n            agreementsModal.showModal();\n        },\n\n        /**\n         * build a unique id for the term checkbox\n         *\n         * @param {Object} context - the ko context\n         * @param {Number} agreementId\n         */\n        getCheckboxId: function (context, agreementId) {\n            var paymentMethodName = '',\n                paymentMethodRenderer = context.$parents[1];\n\n            // corresponding payment method fetched from parent context\n            if (paymentMethodRenderer) {\n                // item looks like this: {title: \"Check / Money order\", method: \"checkmo\"}\n                paymentMethodName = paymentMethodRenderer.item ?\n                  paymentMethodRenderer.item.method : '';\n            }\n\n            return 'agreement_' + paymentMethodName + '_' + agreementId;\n        },\n\n        /**\n         * Init modal window for rendered element\n         *\n         * @param {Object} element\n         */\n        initModal: function (element) {\n            agreementsModal.createModal(element);\n        }\n    });\n});\n","Magento_CheckoutAgreements/js/view/agreement-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/payment/additional-validators',\n    'Magento_CheckoutAgreements/js/model/agreement-validator'\n], function (Component, additionalValidators, agreementValidator) {\n    'use strict';\n\n    additionalValidators.registerValidator(agreementValidator);\n\n    return Component.extend({});\n});\n","Magento_CheckoutAgreements/js/model/agreements-assigner.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    var agreementsConfig = window.checkoutConfig.checkoutAgreements;\n\n    /** Override default place order action and add agreement_ids to request */\n    return function (paymentData) {\n        var agreementForm,\n            agreementData,\n            agreementIds;\n\n        if (!agreementsConfig.isEnabled) {\n            return;\n        }\n\n        agreementForm = $('.payment-method._active div[data-role=checkout-agreements] input');\n        agreementData = agreementForm.serializeArray();\n        agreementIds = [];\n\n        agreementData.forEach(function (item) {\n            agreementIds.push(item.value);\n        });\n\n        if (paymentData['extension_attributes'] === undefined) {\n            paymentData['extension_attributes'] = {};\n        }\n\n        paymentData['extension_attributes']['agreement_ids'] = agreementIds;\n    };\n});\n","Magento_CheckoutAgreements/js/model/place-order-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/utils/wrapper',\n    'Magento_CheckoutAgreements/js/model/agreements-assigner'\n], function ($, wrapper, agreementsAssigner) {\n    'use strict';\n\n    return function (placeOrderAction) {\n\n        /** Override default place order action and add agreement_ids to request */\n        return wrapper.wrap(placeOrderAction, function (originalAction, paymentData, messageContainer) {\n            agreementsAssigner(paymentData);\n\n            return originalAction(paymentData, messageContainer);\n        });\n    };\n});\n","Magento_CheckoutAgreements/js/model/agreement-validator.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/validation'\n], function ($) {\n    'use strict';\n\n    var checkoutConfig = window.checkoutConfig,\n        agreementsConfig = checkoutConfig ? checkoutConfig.checkoutAgreements : {},\n        agreementsInputPath = '.payment-method._active div.checkout-agreements input';\n\n    return {\n        /**\n         * Validate checkout agreements\n         *\n         * @returns {Boolean}\n         */\n        validate: function (hideError) {\n            var isValid = true;\n\n            if (!agreementsConfig.isEnabled || $(agreementsInputPath).length === 0) {\n                return true;\n            }\n\n            $(agreementsInputPath).each(function (index, element) {\n                if (!$.validator.validateSingleElement(element, {\n                    errorElement: 'div',\n                    hideError: hideError || false\n                })) {\n                    isValid = false;\n                }\n            });\n\n            return isValid;\n        }\n    };\n});\n","Magento_CheckoutAgreements/js/model/agreements-modal.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Ui/js/modal/modal',\n    'mage/translate'\n], function ($, modal, $t) {\n    'use strict';\n\n    return {\n        modalWindow: null,\n\n        /**\n         * Create popUp window for provided element.\n         *\n         * @param {HTMLElement} element\n         */\n        createModal: function (element) {\n            var options;\n\n            this.modalWindow = element;\n            options = {\n                'type': 'popup',\n                'modalClass': 'agreements-modal',\n                'responsive': true,\n                'innerScroll': true,\n                'trigger': '.show-modal',\n                'buttons': [\n                    {\n                        text: $t('Close'),\n                        class: 'action secondary action-hide-popup',\n\n                        /** @inheritdoc */\n                        click: function () {\n                            this.closeModal();\n                        }\n                    }\n                ]\n            };\n            modal(options, $(this.modalWindow));\n        },\n\n        /** Show login popup window */\n        showModal: function () {\n            $(this.modalWindow).modal('openModal');\n        }\n    };\n});\n","Magento_CheckoutAgreements/js/model/set-payment-information-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/utils/wrapper',\n    'Magento_CheckoutAgreements/js/model/agreements-assigner'\n], function ($, wrapper, agreementsAssigner) {\n    'use strict';\n\n    return function (placeOrderAction) {\n\n        /** Override place-order-mixin for set-payment-information action as they differs only by method signature */\n        return wrapper.wrap(placeOrderAction, function (originalAction, messageContainer, paymentData) {\n            agreementsAssigner(paymentData);\n\n            return originalAction(messageContainer, paymentData);\n        });\n    };\n});\n"}
}});

Spamworldpro Mini