Your IP : 216.73.216.43


Current Path : /home/rtorresani/www/pub/static/frontend/Magento/forst-trento/it_IT/js/bundle/
Upload File :
Current File : //home/rtorresani/www/pub/static/frontend/Magento/forst-trento/it_IT/js/bundle/bundle3.js

require.config({"config": {
        "jsbuild":{"Magento_Ui/js/lib/core/element/links.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko',\n    'underscore',\n    'mageUtils',\n    'uiRegistry'\n], function (ko, _, utils, registry) {\n    'use strict';\n\n    /**\n     * Parse provided data.\n     *\n     * @param {String} placeholder\n     * @param {String} data\n     * @param {String} direction\n     * @returns {Boolean|Object}\n     */\n    function parseData(placeholder, data, direction) {\n        if (typeof data !== 'string') {\n            return false;\n        }\n\n        data = data.split(':');\n\n        if (!data[0]) {\n            return false;\n        }\n\n        if (!data[1]) {\n            data[1] = data[0];\n            data[0] = placeholder;\n        }\n\n        return {\n            target: data[0],\n            property: data[1],\n            direction: direction\n        };\n    }\n\n    /**\n     * Check if value not empty.\n     *\n     * @param {*} value\n     * @returns {Boolean}\n     */\n    function notEmpty(value) {\n        return typeof value !== 'undefined' && value != null;\n    }\n\n    /**\n     * Update value for linked component.\n     *\n     * @param {Object} data\n     * @param {Object} owner\n     * @param {Object} target\n     * @param {*} value\n     */\n    function updateValue(data, owner, target, value) {\n        var component = target.component,\n            property = target.property,\n            linked = data.linked;\n\n        if (data.mute) {\n            return;\n        }\n\n        if (linked) {\n            linked.mute = true;\n        }\n\n        if (owner.component !== target.component) {\n            value = data.inversionValue ? !utils.copy(value) : utils.copy(value);\n        }\n\n        component.set(property, value, owner);\n\n        if (property === 'disabled' && value) {\n            component.set('validate', value, owner);\n        }\n\n        if (linked) {\n            linked.mute = false;\n        }\n    }\n\n    /**\n     * Get value form owner component property.\n     *\n     * @param {Object} owner\n     * @returns {*}\n     */\n    function getValue(owner) {\n        var component = owner.component,\n            property = owner.property;\n\n        return component.get(property);\n    }\n\n    /**\n     * Format provided params to object.\n     *\n     * @param {String} ownerComponent\n     * @param {String} targetComponent\n     * @param {String} ownerProp\n     * @param {String} targetProp\n     * @param {String} direction\n     * @returns {Object}\n     */\n    function form(ownerComponent, targetComponent, ownerProp, targetProp, direction) {\n        var result,\n            tmp;\n\n        result = {\n            owner: {\n                component: ownerComponent,\n                property: ownerProp\n            },\n            target: {\n                component: targetComponent,\n                property: targetProp\n            }\n        };\n\n        if (direction === 'exports') {\n            tmp = result.owner;\n            result.owner = result.target;\n            result.target = tmp;\n        }\n\n        return result;\n    }\n\n    /**\n     * Set data to linked property.\n     *\n     * @param {Object} map\n     * @param {Object} data\n     */\n    function setLinked(map, data) {\n        var match;\n\n        if (!map) {\n            return;\n        }\n\n        match = _.findWhere(map, {\n            linked: false,\n            target: data.target,\n            property: data.property\n        });\n\n        if (match) {\n            match.linked = data;\n            data.linked = match;\n        }\n    }\n\n    /**\n     * Set data by direction.\n     *\n     * @param {Object} maps\n     * @param {String} property\n     * @param {Object} data\n     */\n    function setData(maps, property, data) {\n        var direction   = data.direction,\n            map         = maps[direction];\n\n        data.linked = false;\n\n        (map[property] = map[property] || []).push(data);\n\n        direction = direction === 'imports' ? 'exports' : 'imports';\n\n        setLinked(maps[direction][property], data);\n    }\n\n    /**\n     * Set links for components.\n     *\n     * @param {String} target\n     * @param {String} owner\n     * @param {Object} data\n     * @param {String} property\n     * @param {Boolean} immediate\n     */\n    function setLink(target, owner, data, property, immediate) {\n        var direction = data.direction,\n            formated = form(target, owner, data.property, property, direction),\n            callback,\n            value;\n\n        owner = formated.owner;\n        target = formated.target;\n\n        callback = updateValue.bind(null, data, owner, target);\n\n        owner.component.on(owner.property, callback, target.component.name);\n\n        if (immediate) {\n            value = getValue(owner);\n\n            if (notEmpty(value)) {\n                updateValue(data, owner, target, value);\n            }\n        }\n    }\n\n    /**\n     * Transfer data between components.\n     *\n     * @param {Object} owner\n     * @param {Object} data\n     */\n    function transfer(owner, data) {\n        var args = _.toArray(arguments);\n\n        if (data.target.substr(0, 1) === '!') {\n            data.target = data.target.substr(1);\n            data.inversionValue = true;\n        }\n\n        if (owner.name === data.target) {\n            args.unshift(owner);\n\n            setLink.apply(null, args);\n        } else {\n            registry.get(data.target, function (target) {\n                args.unshift(target);\n\n                setLink.apply(null, args);\n            });\n        }\n    }\n\n    return {\n        /**\n         * Assign listeners.\n         *\n         * @param {Object} listeners\n         * @returns {Object} Chainable\n         */\n        setListeners: function (listeners) {\n            var owner = this,\n                data;\n\n            _.each(listeners, function (callbacks, sources) {\n                sources = sources.split(' ');\n                callbacks = callbacks.split(' ');\n\n                sources.forEach(function (target) {\n                    callbacks.forEach(function (callback) {//eslint-disable-line max-nested-callbacks\n                        data = parseData(owner.name, target, 'imports');\n\n                        if (data) {\n                            setData(owner.maps, callback, data);\n                            transfer(owner, data, callback);\n                        }\n                    });\n                });\n            });\n\n            return this;\n        },\n\n        /**\n         * Set links in provided direction.\n         *\n         * @param {Object} links\n         * @param {String} direction\n         * @returns {Object} Chainable\n         */\n        setLinks: function (links, direction) {\n            var owner = this,\n                property,\n                data;\n\n            for (property in links) {\n                if (links.hasOwnProperty(property)) {\n                    data = parseData(owner.name, links[property], direction);\n\n                    if (data) {//eslint-disable-line max-depth\n                        setData(owner.maps, property, data);\n                        transfer(owner, data, property, true);\n                    }\n                }\n            }\n\n            return this;\n        }\n    };\n});\n","Magento_Ui/js/lib/validation/validator.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    './rules'\n], function (_, rulesList) {\n    'use strict';\n\n    /**\n     * Validates provided value be the specified rule.\n     *\n     * @param {String} id - Rule identifier.\n     * @param {*} value - Value to be checked.\n     * @param {*} [params]\n     * @param {*} additionalParams - additional validation params set by method caller\n     * @returns {Object}\n     */\n    function validate(id, value, params, additionalParams) {\n        var rule,\n            message,\n            valid,\n            result = {\n                rule: id,\n                passed: true,\n                message: ''\n            };\n\n        if (_.isObject(params)) {\n            message = params.message || '';\n        }\n\n        if (!rulesList[id]) {\n            return result;\n        }\n\n        rule    = rulesList[id];\n        message = message || rule.message;\n        valid   = rule.handler(value, params, additionalParams);\n\n        if (!valid) {\n            params = Array.isArray(params) ?\n                params :\n                [params];\n\n            if (typeof message === 'function') {\n                message = message.call(rule);\n            }\n\n            message = params.reduce(function (msg, param, idx) {\n                return msg.replace(new RegExp('\\\\{' + idx + '\\\\}', 'g'), param);\n            }, message);\n\n            result.passed = false;\n            result.message = message;\n        }\n\n        return result;\n    }\n\n    /**\n     * Validates provided value by a specified set of rules.\n     *\n     * @param {(String|Object)} rules - One or many validation rules.\n     * @param {*} value - Value to be checked.\n     * @param {*} additionalParams - additional validation params set by method caller\n     * @returns {Object}\n     */\n    function validator(rules, value, additionalParams) {\n        var result;\n\n        if (typeof rules === 'object') {\n            result = {\n                passed: true\n            };\n\n            _.every(rules, function (ruleParams, id) {\n                if (ruleParams.validate || ruleParams !== false || additionalParams) {\n                    result = validate(id, value, ruleParams, additionalParams);\n\n                    return result.passed;\n                }\n\n                return true;\n            });\n\n            return result;\n        }\n\n        return validate.apply(null, arguments);\n    }\n\n    /**\n     * Adds new validation rule.\n     *\n     * @param {String} id - Rule identifier.\n     * @param {Function} handler - Validation function.\n     * @param {String} message - Error message.\n     */\n    validator.addRule = function (id, handler, message) {\n        rulesList[id] = {\n            handler: handler,\n            message: message\n        };\n    };\n\n    /**\n     * Returns rule object found by provided identifier.\n     *\n     * @param {String} id - Rule identifier.\n     * @returns {Object}\n     */\n    validator.getRule = function (id) {\n        return rulesList[id];\n    };\n\n    return validator;\n});\n","Magento_Ui/js/lib/validation/rules.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    './utils',\n    'moment',\n    'tinycolor',\n    'jquery/validate',\n    'mage/translate'\n], function ($, _, utils, moment, tinycolor) {\n    'use strict';\n\n    /**\n     * validate credit card number using mod10\n     * @param {String} s\n     * @return {Boolean}\n     */\n    function validateCreditCard(s) {\n        // remove non-numerics\n        var v = '0123456789',\n            w = '',\n            i, j, k, m, c, a, x;\n\n        for (i = 0; i < s.length; i++) {\n            x = s.charAt(i);\n\n            if (v.indexOf(x, 0) !== -1) {\n                w += x;\n            }\n        }\n        // validate number\n        j = w.length / 2;\n        k = Math.floor(j);\n        m = Math.ceil(j) - k;\n        c = 0;\n\n        for (i = 0; i < k; i++) {\n            a = w.charAt(i * 2 + m) * 2;\n            c += a > 9 ? Math.floor(a / 10 + a % 10) : a;\n        }\n\n        for (i = 0; i < k + m; i++) {\n            c += w.charAt(i * 2 + 1 - m) * 1;\n        }\n\n        return c % 10 === 0;\n    }\n\n    /**\n     * Collection of validation rules including rules from additional-methods.js\n     * @type {Object}\n     */\n    return _.mapObject({\n        'min_text_length': [\n            function (value, params) {\n                return _.isUndefined(value) || value.length === 0 || value.length >= +params;\n            },\n            $.mage.__('Please enter more or equal than {0} symbols.')\n        ],\n        'max_text_length': [\n            function (value, params) {\n                return !_.isUndefined(value) && value.length <= +params;\n            },\n            $.mage.__('Please enter less or equal than {0} symbols.')\n        ],\n        'max-words': [\n            function (value, params) {\n                return utils.isEmpty(value) || utils.stripHtml(value).match(/\\b\\w+\\b/g).length < params;\n            },\n            $.mage.__('Please enter {0} words or less.')\n        ],\n        'min-words': [\n            function (value, params) {\n                return utils.isEmpty(value) || utils.stripHtml(value).match(/\\b\\w+\\b/g).length >= params;\n            },\n            $.mage.__('Please enter at least {0} words.')\n        ],\n        'range-words': [\n            function (value, params) {\n                var match = utils.stripHtml(value).match(/\\b\\w+\\b/g) || [];\n\n                return utils.isEmpty(value) || match.length >= params[0] &&\n                    match.length <= params[1];\n            },\n            $.mage.__('Please enter between {0} and {1} words.')\n        ],\n        'letters-with-basic-punc': [\n            function (value) {\n                return utils.isEmpty(value) || /^[a-z\\-.,()\\u0027\\u0022\\s]+$/i.test(value);\n            },\n            $.mage.__('Letters or punctuation only please')\n        ],\n        'alphanumeric': [\n            function (value) {\n                return utils.isEmpty(value) || /^\\w+$/i.test(value);\n            },\n            $.mage.__('Letters, numbers, spaces or underscores only please')\n        ],\n        'letters-only': [\n            function (value) {\n                return utils.isEmpty(value) || /^[a-z]+$/i.test(value);\n            },\n            $.mage.__('Letters only please')\n        ],\n        'no-whitespace': [\n            function (value) {\n                return utils.isEmpty(value) || /^\\S+$/i.test(value);\n            },\n            $.mage.__('No white space please')\n        ],\n        'no-marginal-whitespace': [\n            function (value) {\n                return !/^\\s+|\\s+$/i.test(value);\n            },\n            $.mage.__('No marginal white space please')\n        ],\n        'zip-range': [\n            function (value) {\n                return utils.isEmpty(value) || /^90[2-5]-\\d{2}-\\d{4}$/.test(value);\n            },\n            $.mage.__('Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx')\n        ],\n        'integer': [\n            function (value) {\n                return utils.isEmpty(value) || /^-?\\d+$/.test(value);\n            },\n            $.mage.__('A positive or negative non-decimal number please')\n        ],\n        'vinUS': [\n            function (value) {\n                if (utils.isEmpty(value)) {\n                    return true;\n                }\n\n                if (value.length !== 17) {\n                    return false;\n                }\n                var i, n, d, f, cd, cdv,//eslint-disable-line vars-on-top\n                    LL = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],//eslint-disable-line max-len\n                    VL = [1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9],\n                    FL = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2],\n                    rs = 0;\n\n                for (i = 0; i < 17; i++) {\n                    f = FL[i];\n                    d = value.slice(i, i + 1);\n\n                    if (i === 8) {\n                        cdv = d;\n                    }\n\n                    if (!isNaN(d)) {\n                        d *= f;\n                    } else {\n                        for (n = 0; n < LL.length; n++) {//eslint-disable-line max-depth\n                            if (d.toUpperCase() === LL[n]) {//eslint-disable-line max-depth\n                                d = VL[n];\n                                d *= f;\n\n                                if (isNaN(cdv) && n === 8) {//eslint-disable-line max-depth\n                                    cdv = LL[n];\n                                }\n                                break;\n                            }\n                        }\n                    }\n                    rs += d;\n                }\n                cd = rs % 11;\n\n                if (cd === 10) {\n                    cd = 'X';\n                }\n\n                if (cd === cdv) {\n                    return true;\n                }\n\n                return false;\n            },\n            $.mage.__('The specified vehicle identification number (VIN) is invalid.')\n        ],\n        'dateITA': [\n            function (value) {\n                var check = false,\n                    re = /^\\d{1,2}\\/\\d{1,2}\\/\\d{4}$/,\n                    adata, gg, mm, aaaa, xdata;\n\n                if (re.test(value)) {\n                    adata = value.split('/');\n                    gg = parseInt(adata[0], 10);\n                    mm = parseInt(adata[1], 10);\n                    aaaa = parseInt(adata[2], 10);\n                    xdata = new Date(aaaa, mm - 1, gg);\n\n                    if (xdata.getFullYear() === aaaa &&\n                        xdata.getMonth() === mm - 1 &&\n                        xdata.getDate() === gg\n                    ) {\n                        check = true;\n                    } else {\n                        check = false;\n                    }\n                } else {\n                    check = false;\n                }\n\n                return check;\n            },\n            $.mage.__('Please enter a correct date')\n        ],\n        'dateNL': [\n            function (value) {\n                return /^\\d\\d?[\\.\\/-]\\d\\d?[\\.\\/-]\\d\\d\\d?\\d?$/.test(value);\n            },\n            $.mage.__('Vul hier een geldige datum in.')\n        ],\n        'time': [\n            function (value) {\n                return utils.isEmpty(value) || /^([01]\\d|2[0-3])(:[0-5]\\d){0,2}$/.test(value);\n            },\n            $.mage.__('Please enter a valid time, between 00:00 and 23:59')\n        ],\n        'time12h': [\n            function (value) {\n                return utils.isEmpty(value) || /^((0?[1-9]|1[012])(:[0-5]\\d){0,2}(\\s[AP]M))$/i.test(value);\n            },\n            $.mage.__('Please enter a valid time, between 00:00 am and 12:00 pm')\n        ],\n        'phoneUS': [\n            function (value) {\n                value = value.replace(/\\s+/g, '');\n\n                return utils.isEmpty(value) || value.length > 9 &&\n                    value.match(/^(1-?)?(\\([2-9]\\d{2}\\)|[2-9]\\d{2})-?[2-9]\\d{2}-?\\d{4}$/);\n            },\n            $.mage.__('Please specify a valid phone number')\n        ],\n        'phoneUK': [\n            function (value) {\n                return utils.isEmpty(value) || value.length > 9 &&\n                    value.match(/^(\\(?(0|\\+44)[1-9]{1}\\d{1,4}?\\)?\\s?\\d{3,4}\\s?\\d{3,4})$/);\n            },\n            $.mage.__('Please specify a valid phone number')\n        ],\n        'mobileUK': [\n            function (value) {\n                return utils.isEmpty(value) || value.length > 9 && value.match(/^((0|\\+44)7\\d{3}\\s?\\d{6})$/);\n            },\n            $.mage.__('Please specify a valid mobile number')\n        ],\n        'stripped-min-length': [\n            function (value, param) {\n                return _.isUndefined(value) || value.length === 0 || utils.stripHtml(value).length >= param;\n            },\n            $.mage.__('Please enter at least {0} characters')\n        ],\n        'email2': [\n            function (value) {\n                return utils.isEmpty(value) || /^((([a-z]|\\d|[!#\\$%&\\u0027\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&\\u0027\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\u0022)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\u0022)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$/i.test(value);//eslint-disable-line max-len\n            },\n            $.validator.messages.email\n        ],\n        'url2': [\n            function (value) {\n                return utils.isEmpty(value) || /^(https?|ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(\\#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i.test(value);//eslint-disable-line max-len\n            },\n            $.validator.messages.url\n        ],\n        'credit-card-types': [\n            function (value, param) {\n                var validTypes;\n\n                if (utils.isEmpty(value)) {\n                    return true;\n                }\n\n                if (/[^0-9-]+/.test(value)) {\n                    return false;\n                }\n                value = value.replace(/\\D/g, '');\n                validTypes = 0x0000;\n\n                if (param.mastercard) {\n                    validTypes |= 0x0001;\n                }\n\n                if (param.visa) {\n                    validTypes |= 0x0002;\n                }\n\n                if (param.amex) {\n                    validTypes |= 0x0004;\n                }\n\n                if (param.dinersclub) {\n                    validTypes |= 0x0008;\n                }\n\n                if (param.enroute) {\n                    validTypes |= 0x0010;\n                }\n\n                if (param.discover) {\n                    validTypes |= 0x0020;\n                }\n\n                if (param.jcb) {\n                    validTypes |= 0x0040;\n                }\n\n                if (param.unknown) {\n                    validTypes |= 0x0080;\n                }\n\n                if (param.all) {\n                    validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;\n                }\n\n                if (validTypes & 0x0001 && /^(51|52|53|54|55)/.test(value)) { //mastercard\n                    return value.length === 16;\n                }\n\n                if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa\n                    return value.length === 16;\n                }\n\n                if (validTypes & 0x0004 && /^(34|37)/.test(value)) { //amex\n                    return value.length === 15;\n                }\n\n                if (validTypes & 0x0008 && /^(300|301|302|303|304|305|36|38)/.test(value)) { //dinersclub\n                    return value.length === 14;\n                }\n\n                if (validTypes & 0x0010 && /^(2014|2149)/.test(value)) { //enroute\n                    return value.length === 15;\n                }\n\n                if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover\n                    return value.length === 16;\n                }\n\n                if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb\n                    return value.length === 16;\n                }\n\n                if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb\n                    return value.length === 15;\n                }\n\n                if (validTypes & 0x0080) { //unknown\n                    return true;\n                }\n\n                return false;\n            },\n            $.mage.__('Please enter a valid credit card number.')\n        ],\n        'ipv4': [\n            function (value) {\n                return utils.isEmpty(value) || /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i.test(value);//eslint-disable-line max-len\n            },\n            $.mage.__('Please enter a valid IP v4 address.')\n        ],\n        'ipv6': [\n            function (value) {\n                return utils.isEmpty(value) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value);//eslint-disable-line max-len\n            },\n            $.mage.__('Please enter a valid IP v6 address.')\n        ],\n        'pattern': [\n            function (value, param) {\n                return utils.isEmpty(value) || new RegExp(param).test(value);\n            },\n            $.mage.__('Invalid format.')\n        ],\n        'validate-no-html-tags': [\n            function (value) {\n                return !/<(\\/)?\\w+/.test(value);\n            },\n            $.mage.__('HTML tags are not allowed.')\n        ],\n        'validate-select': [\n            function (value) {\n                return value !== 'none' && value != null && value.length !== 0;\n            },\n            $.mage.__('Please select an option.')\n        ],\n        'validate-no-empty': [\n            function (value) {\n                return !utils.isEmpty(value);\n            },\n            $.mage.__('Empty Value.')\n        ],\n        'validate-alphanum-with-spaces': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[a-zA-Z0-9 ]+$/.test(value);\n            },\n            $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or spaces only in this field.')\n        ],\n        'validate-data': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[A-Za-z]+[A-Za-z0-9_]+$/.test(value);\n            },\n            $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.')//eslint-disable-line max-len\n        ],\n        'validate-street': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) ||\n                    /^[ \\w]{3,}([A-Za-z]\\.)?([ \\w]*\\#\\d+)?(\\r\\n| )[ \\w]{3,}/.test(value);\n            },\n            $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9), spaces and \"#\" in this field.')\n        ],\n        'validate-phoneStrict': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^(\\()?\\d{3}(\\))?(-|\\s)?\\d{3}(-|\\s)\\d{4}$/.test(value);\n            },\n            $.mage.__('Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.')\n        ],\n        'validate-phoneLax': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) ||\n                    /^((\\d[\\-. ]?)?((\\(\\d{3}\\))|\\d{3}))?[\\-. ]?\\d{3}[\\-. ]?\\d{4}$/.test(value);\n            },\n            $.mage.__('Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.')\n        ],\n        'validate-fax': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^(\\()?\\d{3}(\\))?(-|\\s)?\\d{3}(-|\\s)\\d{4}$/.test(value);\n            },\n            $.mage.__('Please enter a valid fax number (Ex: 123-456-7890).')\n        ],\n        'validate-email': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*@([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*\\.(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]){2,})$/i.test(value);//eslint-disable-line max-len\n            },\n            $.mage.__('Please enter a valid email address (Ex: johndoe@domain.com).')\n        ],\n        'validate-emailSender': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[\\S ]+$/.test(value);\n            },\n            $.mage.__('Please enter a valid email address (Ex: johndoe@domain.com).')\n        ],\n        'validate-password': [\n            function (value) {\n                var pass;\n\n                if (value == null) {\n                    return false;\n                }\n\n                pass = value.trim();\n\n                if (!pass.length) {\n                    return true;\n                }\n\n                return !(pass.length > 0 && pass.length < 6);\n            },\n            $.mage.__('Please enter 6 or more characters. Leading and trailing spaces will be ignored.')\n        ],\n        'validate-admin-password': [\n            function (value) {\n                var pass;\n\n                if (value == null) {\n                    return false;\n                }\n\n                pass = value.trim();\n\n                if (pass.length === 0) {\n                    return true;\n                }\n\n                if (!/[a-z]/i.test(value) || !/[0-9]/.test(value)) {\n                    return false;\n                }\n\n                if (pass.length < 7) {\n                    return false;\n                }\n\n                return true;\n            },\n            $.mage.__('Please enter 7 or more characters, using both numeric and alphabetic.')\n        ],\n        'validate-customer-password': [\n            function (v, elm) {\n                var validator = this,\n                    counter = 0,\n                    passwordMinLength = $(elm).data('password-min-length'),\n                    passwordMinCharacterSets = $(elm).data('password-min-character-sets'),\n                    pass = v.trim(),\n                    result = pass.length >= passwordMinLength;\n\n                if (result === false) {\n                    validator.passwordErrorMessage = $.mage.__('Minimum length of this field must be equal or greater than %1 symbols. Leading and trailing spaces will be ignored.').replace('%1', passwordMinLength);//eslint-disable-line max-len\n\n                    return result;\n                }\n\n                if (pass.match(/\\d+/)) {\n                    counter++;\n                }\n\n                if (pass.match(/[a-z]+/)) {\n                    counter++;\n                }\n\n                if (pass.match(/[A-Z]+/)) {\n                    counter++;\n                }\n\n                if (pass.match(/[^a-zA-Z0-9]+/)) {\n                    counter++;\n                }\n\n                if (counter < passwordMinCharacterSets) {\n                    result = false;\n                    validator.passwordErrorMessage = $.mage.__('Minimum of different classes of characters in password is %1. Classes of characters: Lower Case, Upper Case, Digits, Special Characters.').replace('%1', passwordMinCharacterSets);//eslint-disable-line max-len\n                }\n\n                return result;\n            }, function () {\n                return this.passwordErrorMessage;\n            }\n        ],\n        'validate-url': [\n            function (value) {\n                if (utils.isEmptyNoTrim(value)) {\n                    return true;\n                }\n                value = (value || '').replace(/^\\s+/, '').replace(/\\s+$/, '');\n\n                return (/^(http|https|ftp):\\/\\/(([A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))(\\.[A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))*)(:(\\d+))?(\\/[A-Z0-9~](([A-Z0-9_~-]|\\.)*[A-Z0-9~]|))*\\/?(.*)?$/i).test(value);//eslint-disable-line max-len\n\n            },\n            $.mage.__('Please enter a valid URL. Protocol is required (http://, https:// or ftp://).')\n        ],\n        'validate-clean-url': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^(http|https|ftp):\\/\\/(([A-Z0-9][A-Z0-9_-]*)(\\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\\d+))?\\/?/i.test(value) || /^(www)((\\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\\d+))?\\/?/i.test(value);//eslint-disable-line max-len\n\n            },\n            $.mage.__('Please enter a valid URL. For example http://www.example.com or www.example.com.')\n        ],\n        'validate-xml-identifier': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[A-Z][A-Z0-9_\\/-]*$/i.test(value);\n\n            },\n            $.mage.__('Please enter a valid XML-identifier (Ex: something_1, block5, id-4).')\n        ],\n        'validate-ssn': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^\\d{3}-?\\d{2}-?\\d{4}$/.test(value);\n\n            },\n            $.mage.__('Please enter a valid social security number (Ex: 123-45-6789).')\n        ],\n        'validate-zip-us': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /(^\\d{5}$)|(^\\d{5}-\\d{4}$)/.test(value);\n\n            },\n            $.mage.__('Please enter a valid zip code (Ex: 90602 or 90602-1234).')\n        ],\n        'validate-date-au': [\n            function (value) {\n                var regex = /^(\\d{2})\\/(\\d{2})\\/(\\d{4})$/,\n                    d;\n\n                if (utils.isEmptyNoTrim(value)) {\n                    return true;\n                }\n\n                if (utils.isEmpty(value) || !regex.test(value)) {\n                    return false;\n                }\n                d = new Date(value.replace(regex, '$2/$1/$3'));\n\n                return parseInt(RegExp.$2, 10) === 1 + d.getMonth() &&\n                    parseInt(RegExp.$1, 10) === d.getDate() &&\n                    parseInt(RegExp.$3, 10) === d.getFullYear();\n\n            },\n            $.mage.__('Please use this date format: dd/mm/yyyy. For example 17/03/2006 for the 17th of March, 2006.')\n        ],\n        'validate-currency-dollar': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^\\$?\\-?([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}\\d*(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$/.test(value);//eslint-disable-line max-len\n\n            },\n            $.mage.__('Please enter a valid $ amount. For example $100.00.')\n        ],\n        'validate-not-negative-number': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || !isNaN(utils.parseNumber(value))\n                    && value >= 0 && (/^\\s*-?\\d+([,.]\\d+)*\\s*%?\\s*$/).test(value);\n\n            },\n            $.mage.__('Please enter a number 0 or greater, without comma in this field.')\n        ],\n        // validate-not-negative-number should be replaced in all places with this one and then removed\n        'validate-zero-or-greater': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || !isNaN(utils.parseNumber(value))\n                    && value >= 0 && (/^\\s*-?\\d+([,.]\\d+)*\\s*%?\\s*$/).test(value);\n            },\n            $.mage.__('Please enter a number 0 or greater, without comma in this field.')\n        ],\n        'validate-greater-than-zero': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || !isNaN(utils.parseNumber(value))\n                    && value > 0 && (/^\\s*-?\\d+([,.]\\d+)*\\s*%?\\s*$/).test(value);\n            },\n            $.mage.__('Please enter a number greater than 0, without comma in this field.')\n        ],\n        'validate-css-length': [\n            function (value) {\n                if (value !== '') {\n                    return (/^[0-9]*\\.*[0-9]+(px|pc|pt|ex|em|mm|cm|in|%)?$/).test(value);\n                }\n\n                return true;\n            },\n            $.mage.__('Please input a valid CSS-length (Ex: 100px, 77pt, 20em, .5ex or 50%).')\n        ],\n        'validate-number': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) ||\n                    !isNaN(utils.parseNumber(value)) &&\n                    /^\\s*-?\\d*(?:[.,|'|\\s]\\d+)*(?:[.,|'|\\s]\\d{2})?-?\\s*$/.test(value);\n            },\n            $.mage.__('Please enter a valid number in this field.')\n        ],\n        'validate-integer': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || !isNaN(utils.parseNumber(value)) && /^\\s*-?\\d*\\s*$/.test(value);\n            },\n            $.mage.__('Please enter a valid integer in this field.')\n        ],\n        'validate-number-range': [\n            function (value, param) {\n                var numValue, dataAttrRange, result, range, m;\n\n                if (utils.isEmptyNoTrim(value)) {\n                    return true;\n                }\n\n                numValue = utils.parseNumber(value);\n\n                if (isNaN(numValue)) {\n                    return false;\n                }\n\n                dataAttrRange = /^(-?[\\d.,]+)?-(-?[\\d.,]+)?$/;\n                result = true;\n                range = param;\n\n                if (range) {\n                    m = dataAttrRange.exec(range);\n\n                    if (m) {\n                        result = result && utils.isBetween(numValue, m[1], m[2]);\n                    }\n                }\n\n                return result;\n            },\n            $.mage.__('The value is not within the specified range.')\n        ],\n        'validate-positive-percent-decimal': [\n            function (value) {\n                var numValue;\n\n                if (utils.isEmptyNoTrim(value) || !/^\\s*-?\\d*(\\.\\d*)?\\s*$/.test(value)) {\n                    return false;\n                }\n\n                numValue = utils.parseNumber(value);\n\n                if (isNaN(numValue)) {\n                    return false;\n                }\n\n                return utils.isBetween(numValue, 0.01, 100);\n            },\n            $.mage.__('Please enter a valid percentage discount value greater than 0.')\n        ],\n        'validate-digits': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || !/[^\\d]/.test(value);\n            },\n            $.mage.__('Please enter a valid number in this field.')\n        ],\n        'validate-digits-range': [\n            function (value, param) {\n                var numValue, dataAttrRange, result, range, m;\n\n                if (utils.isEmptyNoTrim(value)) {\n                    return true;\n                }\n\n                numValue = utils.parseNumber(value);\n\n                if (isNaN(numValue)) {\n                    return false;\n                }\n\n                dataAttrRange = /^(-?\\d+)?-(-?\\d+)?$/;\n                result = true;\n                range = param;\n\n                if (range) {\n                    m = dataAttrRange.exec(range);\n\n                    if (m) {\n                        result = result && utils.isBetween(numValue, m[1], m[2]);\n                    }\n                }\n\n                return result;\n            },\n            $.mage.__('The value is not within the specified range.')\n        ],\n        'validate-range': [\n            function (value) {\n                var minValue, maxValue, ranges;\n\n                if (utils.isEmptyNoTrim(value)) {\n                    return true;\n                } else if ($.validator.methods['validate-digits'] && $.validator.methods['validate-digits'](value)) {\n                    minValue = maxValue = utils.parseNumber(value);\n                } else {\n                    ranges = /^(-?\\d+)?-(-?\\d+)?$/.exec(value);\n\n                    if (ranges) {\n                        minValue = utils.parseNumber(ranges[1]);\n                        maxValue = utils.parseNumber(ranges[2]);\n\n                        if (minValue > maxValue) {//eslint-disable-line max-depth\n                            return false;\n                        }\n                    } else {\n                        return false;\n                    }\n                }\n            },\n            $.mage.__('The value is not within the specified range.')\n        ],\n        'validate-alpha': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[a-zA-Z]+$/.test(value);\n            },\n            $.mage.__('Please use letters only (a-z or A-Z) in this field.')\n        ],\n        'validate-code': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[a-z]+[a-z0-9_]+$/.test(value);\n            },\n            $.mage.__('Please use only lowercase letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.')//eslint-disable-line max-len\n        ],\n        'validate-alphanum': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[a-zA-Z0-9]+$/.test(value);\n            },\n            $.mage.__('Please use only letters (a-z or A-Z) or numbers (0-9) in this field. No spaces or other characters are allowed.')//eslint-disable-line max-len\n        ],\n        'validate-not-number-first': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[^0-9-\\.].*$/.test(value.trim());\n            },\n            $.mage.__('First character must be letter.')\n        ],\n        'validate-date': [\n            function (value, params, additionalParams) {\n                var test = moment(value, additionalParams.dateFormat);\n\n                return utils.isEmptyNoTrim(value) || test.isValid();\n            },\n            $.mage.__('Please enter a valid date.')\n        ],\n        'validate-date-range': [\n            function (value, params) {\n                var fromDate = $('input[name*=\"' + params + '\"]').val();\n\n                return moment.utc(value).unix() >= moment.utc(fromDate).unix() || isNaN(moment.utc(value).unix());\n            },\n            $.mage.__('Make sure the To Date is later than or the same as the From Date.')\n        ],\n        'validate-identifier': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[a-z0-9][a-z0-9_\\/-]+(\\.[a-z0-9_-]+)?$/.test(value);\n            },\n            $.mage.__('Please enter a valid URL Key (Ex: \"example-page\", \"example-page.html\" or \"anotherlevel/example-page\").')//eslint-disable-line max-len\n        ],\n        'validate-trailing-hyphen': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^(?!-)(?!.*-$).+$/.test(value);\n            },\n            $.mage.__('Trailing hyphens are not allowed.')\n        ],\n        'validate-zip-international': [\n\n            /*function(v) {\n            // @TODO: Cleanup\n            return Validation.get('IsEmpty').test(v) || /(^[A-z0-9]{2,10}([\\s]{0,1}|[\\-]{0,1})[A-z0-9]{2,10}$)/.test(v);\n            }*/\n            function () {\n                return true;\n            },\n            $.mage.__('Please enter a valid zip code.')\n        ],\n        'validate-state': [\n            function (value) {\n                return value !== 0;\n            },\n            $.mage.__('Please select State/Province.')\n        ],\n        'less-than-equals-to': [\n            function (value, params) {\n                value = utils.parseNumber(value);\n\n                if (isNaN(parseFloat(params))) {\n                    params = $(params).val();\n                }\n\n                params = utils.parseNumber(params);\n\n                if (!isNaN(params) && !isNaN(value)) {\n                    this.lteToVal = params;\n\n                    return value <= params;\n                }\n\n                return true;\n            },\n            function () {\n                return $.mage.__('Please enter a value less than or equal to %s.').replace('%s', this.lteToVal);\n            }\n        ],\n        'greater-than-equals-to': [\n            function (value, params) {\n                value = utils.parseNumber(value);\n\n                if (isNaN(parseFloat(params))) {\n                    params = $(params).val();\n                }\n\n                params = utils.parseNumber(params);\n\n                if (!isNaN(params) && !isNaN(value)) {\n                    this.gteToVal = params;\n\n                    return value >= params;\n                }\n\n                return true;\n            },\n            function () {\n                return $.mage.__('Please enter a value greater than or equal to %s.').replace('%s', this.gteToVal);\n            }\n        ],\n        'validate-emails': [\n            function (value) {\n                var validRegexp, emails, i;\n\n                if (utils.isEmpty(value)) {\n                    return true;\n                }\n                validRegexp = /^[a-z0-9\\._-]{1,30}@([a-z0-9_-]{1,30}\\.){1,5}[a-z]{2,4}$/i;\n                emails = value.split(/[\\s\\n\\,]+/g);\n\n                for (i = 0; i < emails.length; i++) {\n                    if (!validRegexp.test(emails[i].strip())) {\n                        return false;\n                    }\n                }\n\n                return true;\n            },\n            $.mage.__('Please enter valid email addresses, separated by commas. For example, johndoe@domain.com, johnsmith@domain.com.')//eslint-disable-line max-len\n        ],\n        'validate-cc-number': [\n\n            /**\n             * Validate credit card number based on mod 10.\n             *\n             * @param {String} value - credit card number\n             * @return {Boolean}\n             */\n            function (value) {\n                if (value) {\n                    return validateCreditCard(value);\n                }\n\n                return true;\n            },\n            $.mage.__('Please enter a valid credit card number.')\n        ],\n        'validate-cc-ukss': [\n\n            /**\n             * Validate Switch/Solo/Maestro issue number and start date is filled.\n             *\n             * @param {String} value - input field value\n             * @return {*}\n             */\n            function (value) {\n                return value;\n            },\n            $.mage.__('Please enter issue number or start date for switch/solo card type.')\n        ],\n        'required-entry': [\n            function (value) {\n                return !utils.isEmpty(value);\n            },\n            $.mage.__('This is a required field.')\n        ],\n        'checked': [\n            function (value) {\n                return value;\n            },\n            $.mage.__('This is a required field.')\n        ],\n        'not-negative-amount': [\n            function (value) {\n                if (value.length) {\n                    return (/^\\s*\\d+([,.]\\d+)*\\s*%?\\s*$/).test(value);\n                }\n\n                return true;\n            },\n            $.mage.__('Please enter positive number in this field.')\n        ],\n        'validate-per-page-value-list': [\n            function (value) {\n                var isValid = true,\n                    values = value.split(','),\n                    i;\n\n                if (utils.isEmpty(value)) {\n                    return isValid;\n                }\n\n                for (i = 0; i < values.length; i++) {\n                    if (!/^[0-9]+$/.test(values[i])) {\n                        isValid = false;\n                    }\n                }\n\n                return isValid;\n            },\n            $.mage.__('Please enter a valid value, ex: 10,20,30')\n        ],\n        'validate-new-password': [\n            function (value) {\n                if ($.validator.methods['validate-password'] && !$.validator.methods['validate-password'](value)) {\n                    return false;\n                }\n\n                if (utils.isEmpty(value) && value !== '') {\n                    return false;\n                }\n\n                return true;\n            },\n            $.mage.__('Please enter 6 or more characters. Leading and trailing spaces will be ignored.')\n        ],\n        'validate-item-quantity': [\n            function (value, params) {\n                var validator = this,\n                    result = false,\n                    // obtain values for validation\n                    qty = utils.parseNumber(value),\n                    isMinAllowedValid = typeof params.minAllowed === 'undefined' ||\n                        qty >= utils.parseNumber(params.minAllowed),\n                    isMaxAllowedValid = typeof params.maxAllowed === 'undefined' ||\n                        qty <= utils.parseNumber(params.maxAllowed),\n                    isQtyIncrementsValid = typeof params.qtyIncrements === 'undefined' ||\n                        qty % utils.parseNumber(params.qtyIncrements) === 0;\n\n                result = qty > 0;\n\n                if (result === false) {\n                    validator.itemQtyErrorMessage = $.mage.__('Please enter a quantity greater than 0.');//eslint-disable-line max-len\n\n                    return result;\n                }\n\n                result = isMinAllowedValid;\n\n                if (result === false) {\n                    validator.itemQtyErrorMessage = $.mage.__('The fewest you may purchase is %1.').replace('%1', params.minAllowed);//eslint-disable-line max-len\n\n                    return result;\n                }\n\n                result = isMaxAllowedValid;\n\n                if (result === false) {\n                    validator.itemQtyErrorMessage = $.mage.__('The maximum you may purchase is %1.').replace('%1', params.maxAllowed);//eslint-disable-line max-len\n\n                    return result;\n                }\n\n                result = isQtyIncrementsValid;\n\n                if (result === false) {\n                    validator.itemQtyErrorMessage = $.mage.__('You can buy this product only in quantities of %1 at a time.').replace('%1', params.qtyIncrements);//eslint-disable-line max-len\n\n                    return result;\n                }\n\n                return result;\n            }, function () {\n                return this.itemQtyErrorMessage;\n            }\n        ],\n        'equalTo': [\n            function (value, param) {\n                return value === $(param).val();\n            },\n            $.validator.messages.equalTo\n        ],\n        'validate-file-type': [\n            function (name, types) {\n                var extension = name.split('.').pop().toLowerCase();\n\n                if (types && typeof types === 'string') {\n                    types = types.split(' ');\n                }\n\n                return !types || !types.length || ~types.indexOf(extension);\n            },\n            $.mage.__('We don\\'t recognize or support this file extension type.')\n        ],\n        'validate-max-size': [\n            function (size, maxSize) {\n                return maxSize === false || size < maxSize;\n            },\n            $.mage.__('File you are trying to upload exceeds maximum file size limit.')\n        ],\n        'validate-if-tag-script-exist': [\n            function (value) {\n                return !value || (/<script\\b[^>]*>([\\s\\S]*?)<\\/script>$/ig).test(value);\n            },\n            $.mage.__('Please use tag SCRIPT with SRC attribute or with proper content to include JavaScript to the document.')//eslint-disable-line max-len\n        ],\n        'date_range_min': [\n            function (value, minValue, params) {\n                return moment.utc(value, params.dateFormat).unix() >= minValue;\n            },\n            $.mage.__('The date is not within the specified range.')\n        ],\n        'date_range_max': [\n            function (value, maxValue, params) {\n                return moment.utc(value, params.dateFormat).unix() <= maxValue;\n            },\n            $.mage.__('The date is not within the specified range.')\n        ],\n        'validate-color': [\n            function (value) {\n                if (value === '') {\n                    return true;\n                }\n\n                return tinycolor(value).isValid();\n            },\n            $.mage.__('Wrong color format. Please specify color in HEX, RGBa, HSVa, HSLa or use color name.')\n        ],\n        'blacklist-url': [\n            function (value, param) {\n                return new RegExp(param).test(value);\n            },\n            $.mage.__('This link is not allowed.')\n        ],\n        'validate-dob': [\n            function (value, param, params) {\n                if (value === '') {\n                    return true;\n                }\n\n                return moment.utc(value, params.dateFormat).isSameOrBefore(moment.utc());\n            },\n            $.mage.__('The Date of Birth should not be greater than today.')\n        ],\n        'validate-no-utf8mb4-characters': [\n            function (value) {\n                var validator = this,\n                    message = $.mage.__('Please remove invalid characters: {0}.'),\n                    matches = value.match(/(?:[\\uD800-\\uDBFF][\\uDC00-\\uDFFF])/g),\n                    result = matches === null;\n\n                if (!result) {\n                    validator.charErrorMessage = message.replace('{0}', matches.join());\n                }\n\n                return result;\n            }, function () {\n                return this.charErrorMessage;\n            }\n        ]\n    }, function (data) {\n        return {\n            handler: data[0],\n            message: data[1]\n        };\n    });\n});\n","Magento_Ui/js/lib/validation/utils.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine(function () {\n    'use strict';\n\n    var utils = {\n        /**\n         * Check if string is empty with trim.\n         *\n         * @param {String} value\n         * @return {Boolean}\n         */\n        isEmpty: function (value) {\n            return value === '' || value == null || value.length === 0 || /^\\s+$/.test(value);\n        },\n\n        /**\n         * Check if string is empty no trim.\n         *\n         * @param {String} value\n         * @return {Boolean}\n         */\n        isEmptyNoTrim: function (value) {\n            return value === '' || value == null || value.length === 0;\n        },\n\n        /**\n         * Checks if {value} is between numbers {from} and {to}.\n         *\n         * @param {String} value\n         * @param {String} from\n         * @param {String} to\n         * @return {Boolean}\n         */\n        isBetween: function (value, from, to) {\n            return (from === null || from === '' || value >= utils.parseNumber(from)) &&\n                   (to === null || to === '' || value <= utils.parseNumber(to));\n        },\n\n        /**\n         * Parse price string.\n         *\n         * @param {String} value\n         * @return {Number}\n         */\n        parseNumber: function (value) {\n            var isDot, isComa;\n\n            if (typeof value !== 'string') {\n                return parseFloat(value);\n            }\n            isDot = value.indexOf('.');\n            isComa = value.indexOf(',');\n\n            if (isDot !== -1 && isComa !== -1) {\n                if (isComa > isDot) {\n                    value = value.replace('.', '').replace(',', '.');\n                } else {\n                    value = value.replace(',', '');\n                }\n            } else if (isComa !== -1) {\n                value = value.replace(',', '.');\n            }\n\n            return parseFloat(value);\n        },\n\n        /**\n         * Removes HTML tags and space characters, numbers and punctuation.\n         *\n         * @param {String} value -  Value being stripped.\n         * @return {String}\n         */\n        stripHtml: function (value) {\n            return value.replace(/<.[^<>]*?>/g, ' ').replace(/&nbsp;|&#160;/gi, ' ')\n                .replace(/[0-9.(),;:!?%#$'\"_+=\\/-]*/g, '');\n        }\n    };\n\n    return utils;\n});\n","Magento_Ui/js/modal/modalToggle.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'Magento_Ui/js/modal/modal'\n], function ($) {\n    'use strict';\n\n    return function (config, el) {\n        var widget,\n            content;\n\n        if (config.contentSelector) {\n            content = $(config.contentSelector);\n        } else if (config.content) {\n            content = $('<div></div>').html(config.content);\n        } else {\n            content = $('<div></div>');\n        }\n\n        widget = content.modal(config);\n\n        $(el).on(config.toggleEvent, function () {\n            var state = widget.data('mage-modal').options.isOpen;\n\n            if (state) {\n                widget.modal('closeModal');\n            } else {\n                widget.modal('openModal');\n            }\n\n            return false;\n        });\n\n        return widget;\n    };\n});\n","Magento_Ui/js/modal/modal-component.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_Ui/js/lib/view/utils/async',\n    'uiCollection',\n    'uiRegistry',\n    'underscore',\n    './modal'\n], function ($, Collection, registry, _) {\n    'use strict';\n\n    return Collection.extend({\n        defaults: {\n            template: 'ui/modal/modal-component',\n            title: '',\n            subTitle: '',\n            options: {\n                modalClass: '',\n                title: '',\n                subTitle: '',\n                buttons: [],\n                keyEventHandlers: {}\n            },\n            valid: true,\n            links: {\n                title: 'options.title',\n                subTitle: 'options.subTitle'\n            },\n            listens: {\n                state: 'onState',\n                title: 'setTitle',\n                'options.subTitle': 'setSubTitle'\n            },\n            modalClass: 'modal-component',\n            onCancel: 'closeModal'\n        },\n\n        /**\n         * Initializes component.\n         *\n         * @returns {Object} Chainable.\n         */\n        initialize: function () {\n            this._super();\n            _.bindAll(this,\n                'initModal',\n                'openModal',\n                'closeModal',\n                'toggleModal',\n                'setPrevValues',\n                'validate');\n            this.initializeContent();\n\n            return this;\n        },\n\n        /**\n         * Initializes modal configuration\n         *\n         * @returns {Object} Chainable.\n         */\n        initConfig: function () {\n            return this._super()\n                .initSelector()\n                .initModalEvents();\n        },\n\n        /**\n         * Configure modal selector\n         *\n         * @returns {Object} Chainable.\n         */\n        initSelector: function () {\n            var modalClass = this.name.replace(/\\./g, '_');\n\n            this.contentSelector = '.' + this.modalClass;\n            this.options.modalClass = this.options.modalClass + ' ' + modalClass;\n            this.rootSelector = '.' + modalClass;\n\n            return this;\n        },\n\n        /**\n         * Configure modal keyboard handlers\n         * and outer click\n         *\n         * @returns {Object} Chainable.\n         */\n        initModalEvents: function () {\n            this.options.keyEventHandlers.escapeKey = this.options.outerClickHandler = this[this.onCancel].bind(this);\n\n            return this;\n        },\n\n        /**\n         * Initialize modal's content components\n         */\n        initializeContent: function () {\n            $.async({\n                component: this.name\n            }, this.initModal);\n        },\n\n        /**\n         * Init toolbar section so other components will be able to place something in it\n         */\n        initToolbarSection: function () {\n            this.set('toolbarSection', this.modal.data('mage-modal').modal.find('header').get(0));\n        },\n\n        /**\n         * Initializes observable properties.\n         *\n         * @returns {Object} Chainable.\n         */\n        initObservable: function () {\n            this._super();\n            this.observe(['state', 'focused']);\n\n            return this;\n        },\n\n        /**\n         * Wrap content in a modal of certain type\n         *\n         * @param {HTMLElement} element\n         * @returns {Object} Chainable.\n         */\n        initModal: function (element) {\n            if (!this.modal) {\n                this.overrideModalButtonCallback();\n                this.options.modalCloseBtnHandler = this[this.onCancel].bind(this);\n                this.modal = $(element).modal(this.options);\n                this.initToolbarSection();\n\n                if (this.waitCbk) {\n                    this.waitCbk();\n                    this.waitCbk = null;\n                }\n            }\n\n            return this;\n        },\n\n        /**\n         * Open modal\n         */\n        openModal: function () {\n            if (this.modal) {\n                this.state(true);\n            } else {\n                this.waitCbk = this.openModal;\n            }\n        },\n\n        /**\n         * Close modal\n         */\n        closeModal: function () {\n            if (this.modal) {\n                this.state(false);\n            } else {\n                this.waitCbk = this.closeModal;\n            }\n        },\n\n        /**\n         * Toggle modal\n         */\n        toggleModal: function () {\n            if (this.modal) {\n                this.state(!this.state());\n            } else {\n                this.waitCbk = this.toggleModal;\n            }\n        },\n\n        /**\n         * Sets title for modal\n         *\n         * @param {String} title\n         */\n        setTitle: function (title) {\n            if (this.title !== title) {\n                this.title = title;\n            }\n\n            if (this.modal) {\n                this.modal.modal('setTitle', title);\n            }\n        },\n\n        /**\n         * Sets subTitle for modal\n         *\n         * @param {String} subTitle\n         */\n        setSubTitle: function (subTitle) {\n            if (this.subTitle !== subTitle) {\n                this.subTitle = subTitle;\n            }\n\n            if (this.modal) {\n                this.modal.modal('setSubTitle', subTitle);\n            }\n        },\n\n        /**\n         * Wrap content in a modal of certain type\n         *\n         * @param {Boolean} state\n         */\n        onState: function (state) {\n            if (state) {\n                this.modal.modal('openModal');\n                this.applyData();\n            } else {\n                this.modal.modal('closeModal');\n            }\n        },\n\n        /**\n         * Validate everything validatable in modal\n         */\n        validate: function (elem) {\n            if (typeof elem === 'undefined') {\n                return;\n            }\n\n            if (typeof elem.validate === 'function') {\n                this.valid &= elem.validate().valid;\n            } else if (elem.elems) {\n                elem.elems().forEach(this.validate, this);\n            }\n        },\n\n        /**\n         * Reset data from provider\n         */\n        resetData: function () {\n            this.elems().forEach(this.resetValue, this);\n        },\n\n        /**\n         * Update 'applied' property with data from modal content\n         */\n        applyData: function () {\n            var applied = {};\n\n            this.elems().forEach(this.gatherValues.bind(this, applied), this);\n            this.applied = applied;\n        },\n\n        /**\n         * Gather values from modal content\n         *\n         * @param {Array} applied\n         * @param {HTMLElement} elem\n         */\n        gatherValues: function (applied, elem) {\n            if (typeof elem.value === 'function') {\n                applied[elem.name] = elem.value();\n            } else if (elem.elems) {\n                elem.elems().forEach(this.gatherValues.bind(this, applied), this);\n            }\n        },\n\n        /**\n         * Set to previous values from modal content\n         *\n         * @param {HTMLElement} elem\n         */\n        setPrevValues: function (elem) {\n            if (typeof elem.value === 'function') {\n                this.modal.focus();\n                elem.value(this.applied[elem.name]);\n            } else if (elem.elems) {\n                elem.elems().forEach(this.setPrevValues, this);\n            }\n        },\n\n        /**\n         * Triggers some method in every modal child elem, if this method is defined\n         *\n         * @param {Object} action - action configuration,\n         * must contain actionName and targetName and\n         * can contain params\n         */\n        triggerAction: function (action) {\n            var targetName = action.targetName,\n                params = action.params || [],\n                actionName = action.actionName,\n                target;\n\n            target = registry.async(targetName);\n\n            if (target && typeof target === 'function' && actionName) {\n                params.unshift(actionName);\n                target.apply(target, params);\n            }\n        },\n\n        /**\n         * Override modal buttons callback placeholders with real callbacks\n         */\n        overrideModalButtonCallback: function () {\n            var buttons = this.options.buttons;\n\n            if (buttons && buttons.length) {\n                buttons.forEach(function (button) {\n                    button.click = this.getButtonClickHandler(button.actions);\n                }, this);\n            }\n        },\n\n        /**\n         * Generate button click handler based on button's 'actions' configuration\n         */\n        getButtonClickHandler: function (actionsConfig) {\n            var actions = actionsConfig.map(\n                function (actionConfig) {\n                    if (_.isObject(actionConfig)) {\n                        return this.triggerAction.bind(this, actionConfig);\n                    }\n\n                    return this[actionConfig] ? this[actionConfig].bind(this) : function () {};\n                }, this);\n\n            return function () {\n                actions.forEach(\n                    function (action) {\n                        action();\n                    }\n                );\n            };\n        },\n\n        /**\n         * Cancels changes in modal:\n         * returning elems values to the previous state,\n         * and close modal\n         */\n        actionCancel: function () {\n            this.elems().forEach(this.setPrevValues, this);\n            this.closeModal();\n        },\n\n        /**\n         * Accept changes in modal by not preventing them.\n         * Can be extended by exporting 'gatherValues' result somewhere\n         */\n        actionDone: function () {\n            this.valid = true;\n            this.elems().forEach(this.validate, this);\n\n            if (this.valid) {\n                this.closeModal();\n            }\n        }\n    });\n});\n","Magento_Ui/js/modal/confirm.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/translate',\n    'jquery-ui-modules/widget',\n    'Magento_Ui/js/modal/modal'\n], function ($, _, $t) {\n    'use strict';\n\n    $.widget('mage.confirm', $.mage.modal, {\n        options: {\n            modalClass: 'confirm',\n            title: '',\n            focus: '.action-accept',\n            actions: {\n\n                /**\n                 * Callback always - called on all actions.\n                 */\n                always: function () {},\n\n                /**\n                 * Callback confirm.\n                 */\n                confirm: function () {},\n\n                /**\n                 * Callback cancel.\n                 */\n                cancel: function () {}\n            },\n            buttons: [{\n                text: $t('Cancel'),\n                class: 'action-secondary action-dismiss',\n\n                /**\n                 * Click handler.\n                 */\n                click: function (event) {\n                    this.closeModal(event);\n                }\n            }, {\n                text: $t('OK'),\n                class: 'action-primary action-accept',\n\n                /**\n                 * Click handler.\n                 */\n                click: function (event) {\n                    this.closeModal(event, true);\n                }\n            }]\n        },\n\n        /**\n         * Create widget.\n         */\n        _create: function () {\n            this._super();\n            this.modal.find(this.options.modalCloseBtn).off().on('click', _.bind(this.closeModal, this));\n            this.openModal();\n        },\n\n        /**\n         * Remove modal window.\n         */\n        _remove: function () {\n            this.modal.remove();\n        },\n\n        /**\n         * Open modal window.\n         */\n        openModal: function () {\n            return this._super();\n        },\n\n        /**\n         * Close modal window.\n         */\n        closeModal: function (event, result) {\n            result = result || false;\n\n            if (result) {\n                this.options.actions.confirm(event);\n            } else {\n                this.options.actions.cancel(event);\n            }\n            this.options.actions.always(event);\n            this.element.on('confirmclosed', _.bind(this._remove, this));\n\n            return this._super();\n        }\n    });\n\n    return function (config) {\n        return $('<div></div>').html(config.content).confirm(config);\n    };\n});\n","Magento_Ui/js/modal/prompt.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    'text!ui/template/modal/modal-prompt-content.html',\n    'jquery-ui-modules/widget',\n    'Magento_Ui/js/modal/modal',\n    'mage/translate'\n], function ($, _, template, promptContentTmpl) {\n    'use strict';\n\n    $.widget('mage.prompt', $.mage.modal, {\n        options: {\n            modalClass: 'prompt',\n            promptContentTmpl: promptContentTmpl,\n            promptField: '[data-role=\"promptField\"]',\n            attributesForm: {},\n            attributesField: {},\n            value: '',\n            validation: false,\n            validationRules: [],\n            keyEventHandlers: {\n\n                /**\n                 * Enter key press handler,\n                 * submit result and close modal window\n                 * @param {Object} event - event\n                 */\n                enterKey: function (event) {\n                    if (this.options.isOpen && this.modal.find(document.activeElement).length ||\n                        this.options.isOpen && this.modal[0] === document.activeElement) {\n                        this.closeModal(true);\n                        event.preventDefault();\n                    }\n                },\n\n                /**\n                 * Tab key press handler,\n                 * set focus to elements\n                 */\n                tabKey: function () {\n                    if (document.activeElement === this.modal[0]) {\n                        this._setFocus('start');\n                    }\n                },\n\n                /**\n                 * Escape key press handler,\n                 * cancel and close modal window\n                 * @param {Object} event - event\n                 */\n                escapeKey: function (event) {\n                    if (this.options.isOpen && this.modal.find(document.activeElement).length ||\n                        this.options.isOpen && this.modal[0] === document.activeElement) {\n                        this.closeModal();\n                        event.preventDefault();\n                    }\n                }\n            },\n            actions: {\n\n                /**\n                 * Callback always - called on all actions.\n                 */\n                always: function () {},\n\n                /**\n                 * Callback confirm.\n                 */\n                confirm: function () {},\n\n                /**\n                 * Callback cancel.\n                 */\n                cancel: function () {}\n            },\n            buttons: [{\n                text: $.mage.__('Cancel'),\n                class: 'action-secondary action-dismiss',\n\n                /**\n                 * Click handler.\n                 */\n                click: function () {\n                    this.closeModal();\n                }\n            }, {\n                text: $.mage.__('OK'),\n                class: 'action-primary action-accept',\n\n                /**\n                 * Click handler.\n                 */\n                click: function () {\n                    this.closeModal(true);\n                }\n            }]\n        },\n\n        /**\n         * Create widget.\n         */\n        _create: function () {\n            this.options.focus = this.options.promptField;\n            this.options.validation = this.options.validation && this.options.validationRules.length;\n            this.options.outerClickHandler = this.options.outerClickHandler || _.bind(this.closeModal, this, false);\n            this._super();\n            this.modal.find(this.options.modalContent).append(this.getFormTemplate());\n            this.modal.find(this.options.modalCloseBtn).off().on('click',  _.bind(this.closeModal, this, false));\n\n            if (this.options.validation) {\n                this.setValidationClasses();\n            }\n\n            this.openModal();\n        },\n\n        /**\n         * Form template getter.\n         *\n         * @returns {Object} Form template.\n         */\n        getFormTemplate: function () {\n            var formTemplate,\n                formAttr = '',\n                inputAttr = '',\n                attributeName;\n\n            for (attributeName in this.options.attributesForm) {\n                if (this.options.attributesForm.hasOwnProperty(attributeName)) {\n                    formAttr = formAttr + ' ' + attributeName + '=\"' +\n                        this.options.attributesForm[attributeName] + '\"';\n                }\n            }\n\n            for (attributeName in this.options.attributesField) {\n                if (this.options.attributesField.hasOwnProperty(attributeName)) {\n                    inputAttr = inputAttr + ' ' + attributeName + '=\"' +\n                        this.options.attributesField[attributeName] + '\"';\n                }\n            }\n\n            formTemplate = $(template(this.options.promptContentTmpl, {\n                data: this.options,\n                formAttr: formAttr,\n                inputAttr: inputAttr\n            }));\n\n            return formTemplate;\n        },\n\n        /**\n         * Remove widget\n         */\n        _remove: function () {\n            this.modal.remove();\n        },\n\n        /**\n         * Validate prompt field\n         */\n        validate: function () {\n            return $.validator.validateSingleElement(this.options.promptField);\n        },\n\n        /**\n         * Add validation classes to prompt field\n         */\n        setValidationClasses: function () {\n            this.modal.find(this.options.promptField).attr('class', $.proxy(function (i, val) {\n                return val + ' ' + this.options.validationRules.join(' ');\n            }, this));\n        },\n\n        /**\n         * Open modal window\n         */\n        openModal: function () {\n            this._super();\n            this.modal.find(this.options.promptField).val(this.options.value);\n        },\n\n        /**\n         * Close modal window\n         */\n        closeModal: function (result) {\n            var value;\n\n            if (result) {\n                if (this.options.validation && !this.validate()) {\n                    return false;\n                }\n\n                value = this.modal.find(this.options.promptField).val();\n                this.options.actions.confirm.call(this, value);\n            } else {\n                this.options.actions.cancel.call(this, result);\n            }\n\n            this.options.actions.always();\n            this.element.on('promptclosed', _.bind(this._remove, this));\n\n            return this._super();\n        }\n    });\n\n    return function (config) {\n        return $('<div class=\"prompt-message\"></div>').html(config.content).prompt(config);\n    };\n});\n","Magento_Ui/js/modal/modal.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    'text!ui/template/modal/modal-popup.html',\n    'text!ui/template/modal/modal-slide.html',\n    'text!ui/template/modal/modal-custom.html',\n    'Magento_Ui/js/lib/key-codes',\n    'jquery-ui-modules/widget',\n    'jquery-ui-modules/core',\n    'mage/translate',\n    'jquery/z-index'\n], function ($, _, template, popupTpl, slideTpl, customTpl, keyCodes) {\n    'use strict';\n\n    /**\n     * Detect browser transition end event.\n     * @return {String|undefined} - transition event.\n     */\n    var transitionEvent = (function () {\n        var transition,\n            elementStyle = document.createElement('div').style,\n            transitions = {\n                'transition': 'transitionend',\n                'OTransition': 'oTransitionEnd',\n                'MozTransition': 'transitionend',\n                'WebkitTransition': 'webkitTransitionEnd'\n            };\n\n        for (transition in transitions) {\n            if (elementStyle[transition] !== undefined && transitions.hasOwnProperty(transition)) {\n                return transitions[transition];\n            }\n        }\n    })();\n\n    /**\n     * Modal Window Widget\n     */\n    $.widget('mage.modal', {\n        options: {\n            id: null,\n            type: 'popup',\n            title: '',\n            subTitle: '',\n            modalClass: '',\n            focus: '[data-role=\"closeBtn\"]',\n            autoOpen: false,\n            clickableOverlay: true,\n            popupTpl: popupTpl,\n            slideTpl: slideTpl,\n            customTpl: customTpl,\n            modalVisibleClass: '_show',\n            parentModalClass: '_has-modal',\n            innerScrollClass: '_inner-scroll',\n            responsive: false,\n            innerScroll: false,\n            modalTitle: '[data-role=\"title\"]',\n            modalSubTitle: '[data-role=\"subTitle\"]',\n            modalBlock: '[data-role=\"modal\"]',\n            modalCloseBtn: '[data-role=\"closeBtn\"]',\n            modalContent: '[data-role=\"content\"]',\n            modalAction: '[data-role=\"action\"]',\n            focusableScope: '[data-role=\"focusable-scope\"]',\n            focusableStart: '[data-role=\"focusable-start\"]',\n            focusableEnd: '[data-role=\"focusable-end\"]',\n            appendTo: 'body',\n            wrapperClass: 'modals-wrapper',\n            overlayClass: 'modals-overlay',\n            responsiveClass: 'modal-slide',\n            trigger: '',\n            modalLeftMargin: 45,\n            closeText: $.mage.__('Close'),\n            buttons: [{\n                text: $.mage.__('Ok'),\n                class: '',\n                attr: {},\n\n                /**\n                 * Default action on button click\n                 */\n                click: function (event) {\n                    this.closeModal(event);\n                }\n            }],\n            keyEventHandlers: {\n\n                /**\n                 * Tab key press handler,\n                 * set focus to elements\n                 */\n                tabKey: function () {\n                    if (document.activeElement === this.modal[0]) {\n                        this._setFocus('start');\n                    }\n                },\n\n                /**\n                 * Escape key press handler,\n                 * close modal window\n                 * @param {Object} event - event\n                 */\n                escapeKey: function (event) {\n                    if (this.options.isOpen && this.modal.find(document.activeElement).length ||\n                        this.options.isOpen && this.modal[0] === document.activeElement) {\n                        this.closeModal(event);\n                    }\n                }\n            }\n        },\n\n        /**\n         * Creates modal widget.\n         */\n        _create: function () {\n            _.bindAll(\n                this,\n                'keyEventSwitcher',\n                '_tabSwitcher',\n                'closeModal'\n            );\n\n            this.options.id = this.uuid;\n            this.options.transitionEvent = transitionEvent;\n            this._createWrapper();\n            this._renderModal();\n            this._createButtons();\n\n            if (this.options.trigger) {\n                $(document).on('click', this.options.trigger, _.bind(this.toggleModal, this));\n            }\n            this._on(this.modal.find(this.options.modalCloseBtn), {\n                'click': this.options.modalCloseBtnHandler ? this.options.modalCloseBtnHandler : this.closeModal\n            });\n            this._on(this.element, {\n                'openModal': this.openModal,\n                'closeModal': this.closeModal\n            });\n            this.options.autoOpen ? this.openModal() : false;\n        },\n\n        /**\n         * Returns element from modal node.\n         * @return {Object} - element.\n         */\n        _getElem: function (elem) {\n            return this.modal.find(elem);\n        },\n\n        /**\n         * Gets visible modal count.\n         * * @return {Number} - visible modal count.\n         */\n        _getVisibleCount: function () {\n            var modals = this.modalWrapper.find(this.options.modalBlock);\n\n            return modals.filter('.' + this.options.modalVisibleClass).length;\n        },\n\n        /**\n         * Gets count of visible modal by slide type.\n         * * @return {Number} - visible modal count.\n         */\n        _getVisibleSlideCount: function () {\n            var elems = this.modalWrapper.find('[data-type=\"slide\"]');\n\n            return elems.filter('.' + this.options.modalVisibleClass).length;\n        },\n\n        /**\n         * Listener key events.\n         * Call handler function if it exists\n         */\n        keyEventSwitcher: function (event) {\n            var key = keyCodes[event.keyCode];\n\n            if (this.options.keyEventHandlers.hasOwnProperty(key)) {\n                this.options.keyEventHandlers[key].apply(this, arguments);\n            }\n        },\n\n        /**\n         * Set title for modal.\n         *\n         * @param {String} title\n         */\n        setTitle: function (title) {\n            var $title = this.modal.find(this.options.modalTitle),\n                $subTitle = this.modal.find(this.options.modalSubTitle);\n\n            $title.text(title);\n            $title.append($subTitle);\n        },\n\n        /**\n         * Set sub title for modal.\n         *\n         * @param {String} subTitle\n         */\n        setSubTitle: function (subTitle) {\n            this.options.subTitle = subTitle;\n            this.modal.find(this.options.modalSubTitle).html(subTitle);\n        },\n\n        /**\n         * Toggle modal.\n         * * @return {Element} - current element.\n         */\n        toggleModal: function () {\n            if (this.options.isOpen === true) {\n                this.closeModal();\n            } else {\n                this.openModal();\n            }\n        },\n\n        /**\n         * Open modal.\n         * * @return {Element} - current element.\n         */\n        openModal: function () {\n            this.options.isOpen = true;\n            this.focussedElement = document.activeElement;\n            this._createOverlay();\n            this._setActive();\n            this._setKeyListener();\n            this.modal.one(this.options.transitionEvent, _.bind(this._setFocus, this, 'end', 'opened'));\n            this.modal.one(this.options.transitionEvent, _.bind(this._trigger, this, 'opened'));\n            this.modal.addClass(this.options.modalVisibleClass);\n\n            if (!this.options.transitionEvent) {\n                this._trigger('opened');\n            }\n\n            return this.element;\n        },\n\n        /**\n         * Set focus to element.\n         * @param {String} position - can be \"start\" and \"end\"\n         *      positions.\n         *      If position is \"end\" - sets focus to first\n         *      focusable element in modal window scope.\n         *      If position is \"start\" - sets focus to last\n         *      focusable element in modal window scope\n         *\n         *  @param {String} type - can be \"opened\" or false\n         *      If type is \"opened\" - looks to \"this.options.focus\"\n         *      property and sets focus\n         */\n        _setFocus: function (position, type) {\n            var focusableElements,\n                infelicity;\n\n            if (type === 'opened' && this.options.focus) {\n                this.modal.find($(this.options.focus)).trigger('focus');\n            } else if (type === 'opened' && !this.options.focus) {\n                this.modal.find(this.options.focusableScope).trigger('focus');\n            } else if (position === 'end') {\n                this.modal.find(this.options.modalCloseBtn).trigger('focus');\n            } else if (position === 'start') {\n                infelicity = 2; //Constant for find last focusable element\n                focusableElements = this.modal.find(':focusable');\n                focusableElements.eq(focusableElements.length - infelicity).trigger('focus');\n            }\n        },\n\n        /**\n         * Set events listener when modal is opened.\n         */\n        _setKeyListener: function () {\n            this.modal.find(this.options.focusableStart).on('focusin', this._tabSwitcher);\n            this.modal.find(this.options.focusableEnd).on('focusin', this._tabSwitcher);\n            this.modal.on('keydown', this.keyEventSwitcher);\n        },\n\n        /**\n         * Remove events listener when modal is closed.\n         */\n        _removeKeyListener: function () {\n            this.modal.find(this.options.focusableStart).off('focusin', this._tabSwitcher);\n            this.modal.find(this.options.focusableEnd).off('focusin', this._tabSwitcher);\n            this.modal.off('keydown', this.keyEventSwitcher);\n        },\n\n        /**\n         * Switcher for focus event.\n         * @param {Object} e - event\n         */\n        _tabSwitcher: function (e) {\n            var target = $(e.target);\n\n            if (target.is(this.options.focusableStart)) {\n                this._setFocus('start');\n            } else if (target.is(this.options.focusableEnd)) {\n                this._setFocus('end');\n            }\n        },\n\n        /**\n         * Close modal.\n         * * @return {Element} - current element.\n         */\n        closeModal: function () {\n            var that = this;\n\n            this._removeKeyListener();\n            this.options.isOpen = false;\n            this.modal.one(this.options.transitionEvent, function () {\n                that._close();\n            });\n            this.modal.removeClass(this.options.modalVisibleClass);\n\n            if (!this.options.transitionEvent) {\n                that._close();\n            }\n\n            return this.element;\n        },\n\n        /**\n         * Helper for closeModal function.\n         */\n        _close: function () {\n            var trigger = _.bind(this._trigger, this, 'closed', this.modal);\n\n            $(this.focussedElement).trigger('focus');\n            this._destroyOverlay();\n            this._unsetActive();\n            _.defer(trigger, this);\n        },\n\n        /**\n         * Set z-index and margin for modal and overlay.\n         */\n        _setActive: function () {\n            var zIndex = this.modal.zIndex(),\n                baseIndex = zIndex + this._getVisibleCount();\n\n            if (this.modal.data('active')) {\n                return;\n            }\n\n            this.modal.data('active', true);\n\n            this.overlay.zIndex(++baseIndex);\n            this.prevOverlayIndex = this.overlay.zIndex();\n            this.modal.zIndex(this.overlay.zIndex() + 1);\n\n            if (this._getVisibleSlideCount()) {\n                this.modal.css('marginLeft', this.options.modalLeftMargin * this._getVisibleSlideCount());\n            }\n        },\n\n        /**\n         * Unset styles for modal and set z-index for previous modal.\n         */\n        _unsetActive: function () {\n            this.modal.removeAttr('style');\n            this.modal.data('active', false);\n\n            if (this.overlay) {\n                this.overlay.zIndex(this.prevOverlayIndex - 1);\n            }\n        },\n\n        /**\n         * Creates wrapper to hold all modals.\n         */\n        _createWrapper: function () {\n            this.modalWrapper = $(this.options.appendTo).find('.' + this.options.wrapperClass);\n\n            if (!this.modalWrapper.length) {\n                this.modalWrapper = $('<div></div>')\n                    .addClass(this.options.wrapperClass)\n                    .appendTo(this.options.appendTo);\n            }\n        },\n\n        /**\n         * Compile template and append to wrapper.\n         */\n        _renderModal: function () {\n            $(template(\n                this.options[this.options.type + 'Tpl'],\n                {\n                    data: this.options\n                })).appendTo(this.modalWrapper);\n            this.modal = this.modalWrapper.find(this.options.modalBlock).last();\n            this.element.appendTo(this._getElem(this.options.modalContent));\n\n            if (this.element.is(':hidden')) {\n                this.element.show();\n            }\n        },\n\n        /**\n         * Creates buttons pane.\n         */\n        _createButtons: function () {\n            this.buttons = this._getElem(this.options.modalAction);\n            _.each(this.options.buttons, function (btn, key) {\n                var button = this.buttons[key];\n\n                if (btn.attr) {\n                    $(button).attr(btn.attr);\n                }\n\n                if (btn.class) {\n                    $(button).addClass(btn.class);\n                }\n\n                if (!btn.click) {\n                    btn.click = this.closeModal;\n                }\n                $(button).on('click', _.bind(btn.click, this));\n            }, this);\n        },\n\n        /**\n         * Creates overlay, append it to wrapper, set previous click event on overlay.\n         */\n        _createOverlay: function () {\n            var events,\n                outerClickHandler = this.options.outerClickHandler || this.closeModal;\n\n            this.overlay = $('.' + this.options.overlayClass);\n\n            if (!this.overlay.length) {\n                $(this.options.appendTo).addClass(this.options.parentModalClass);\n                this.overlay = $('<div></div>')\n                    .addClass(this.options.overlayClass)\n                    .appendTo(this.modalWrapper);\n            }\n            events = $._data(this.overlay.get(0), 'events');\n            events ? this.prevOverlayHandler = events.click[0].handler : false;\n            this.options.clickableOverlay ? this.overlay.off().on('click', outerClickHandler) : false;\n        },\n\n        /**\n         * Destroy overlay.\n         */\n        _destroyOverlay: function () {\n            if (this._getVisibleCount()) {\n                this.overlay.off().on('click', this.prevOverlayHandler);\n            } else {\n                $(this.options.appendTo).removeClass(this.options.parentModalClass);\n                this.overlay.remove();\n                this.overlay = null;\n            }\n        }\n    });\n\n    return $.mage.modal;\n});\n","Magento_Ui/js/modal/alert.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    'jquery-ui-modules/widget',\n    'Magento_Ui/js/modal/confirm',\n    'mage/translate'\n], function ($, _) {\n    'use strict';\n\n    $.widget('mage.alert', $.mage.confirm, {\n        options: {\n            modalClass: 'confirm',\n            title: $.mage.__('Attention'),\n            actions: {\n\n                /**\n                 * Callback always - called on all actions.\n                 */\n                always: function () {}\n            },\n            buttons: [{\n                text: $.mage.__('OK'),\n                class: 'action-primary action-accept',\n\n                /**\n                 * Click handler.\n                 */\n                click: function () {\n                    this.closeModal(true);\n                }\n            }]\n        },\n\n        /**\n         * Close modal window.\n         */\n        closeModal: function () {\n            this.options.actions.always();\n            this.element.on('alertclosed', _.bind(this._remove, this));\n\n            return this._super();\n        }\n    });\n\n    return function (config) {\n        return $('<div></div>').html(config.content).alert(config);\n    };\n});\n","Mageplaza_Smtp/js/action/send-address.js":"/**\n * Mageplaza\n *\n * NOTICE OF LICENSE\n *\n * This source file is subject to the Mageplaza.com license that is\n * available through the world-wide-web at this URL:\n * https://www.mageplaza.com/LICENSE.txt\n *\n * DISCLAIMER\n *\n * Do not edit or add to this file if you wish to upgrade this extension to newer\n * version in the future.\n *\n * @category    Mageplaza\n * @package     Mageplaza_Smtp\n * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)\n * @license     https://www.mageplaza.com/LICENSE.txt\n */\n\ndefine([\n    'mage/storage',\n    'Mageplaza_Smtp/js/model/resource-url-manager',\n    'Magento_Checkout/js/model/quote'\n], function (storage, resourceUrlManager, quote) {\n    'use strict';\n\n    return function (address, isOsc) {\n        return storage.post(\n            resourceUrlManager.getUrlForUpdateOrder(quote),\n            JSON.stringify({\n                address: address,\n                isOsc: isOsc\n            }),\n            false\n        );\n    };\n});\n","Mageplaza_Smtp/js/view/shipping-mixins.js":"/**\n * Mageplaza\n *\n * NOTICE OF LICENSE\n *\n * This source file is subject to the Mageplaza.com license that is\n * available through the world-wide-web at this URL:\n * https://www.mageplaza.com/LICENSE.txt\n *\n * DISCLAIMER\n *\n * Do not edit or add to this file if you wish to upgrade this extension to newer\n * version in the future.\n *\n * @category    Mageplaza\n * @package     Mageplaza_StoreLocator\n * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)\n * @license     https://www.mageplaza.com/LICENSE.txt\n */\n\ndefine(\n    [\n        'jquery',\n        'underscore',\n        'Magento_Ui/js/form/form',\n        'ko',\n        'Magento_Customer/js/model/customer',\n        'Magento_Customer/js/model/address-list',\n        'Magento_Checkout/js/model/address-converter',\n        'Magento_Checkout/js/model/quote',\n        'Magento_Checkout/js/action/create-shipping-address',\n        'Magento_Checkout/js/action/select-shipping-address',\n        'Magento_Checkout/js/model/shipping-rates-validator',\n        'Magento_Checkout/js/model/shipping-address/form-popup-state',\n        'Magento_Checkout/js/model/shipping-service',\n        'Magento_Checkout/js/action/select-shipping-method',\n        'Magento_Checkout/js/model/shipping-rate-registry',\n        'Magento_Checkout/js/action/set-shipping-information',\n        'Magento_Checkout/js/model/step-navigator',\n        'Magento_Ui/js/modal/modal',\n        'Magento_Checkout/js/model/checkout-data-resolver',\n        'Magento_Checkout/js/checkout-data',\n        'uiRegistry',\n        'mage/translate',\n        'Magento_Checkout/js/model/shipping-rate-service',\n        'Mageplaza_Smtp/js/model/address-on-change'\n    ],\n    function (\n        $,\n        _,\n        Component,\n        ko,\n        customer,\n        addressList,\n        addressConverter,\n        quote,\n        createShippingAddress,\n        selectShippingAddress,\n        shippingRatesValidator,\n        formPopUpState,\n        shippingService,\n        selectShippingMethodAction,\n        rateRegistry,\n        setShippingInformationAction,\n        stepNavigator,\n        modal,\n        checkoutDataResolver,\n        checkoutData,\n        registry,\n        $t,\n        shippingRateService,\n        shippingAddressOnChange\n    ) {\n        'use strict';\n\n        var mixin = {\n\n            initialize: function () {\n                var fieldsetName = 'checkout.steps.shipping-step.shippingAddress.shipping-address-fieldset';\n\n                this._super();\n\n                shippingAddressOnChange.initFields(fieldsetName);\n            }\n        };\n\n        return function (target) {\n            return target.extend(mixin);\n        };\n    }\n);\n","Mageplaza_Smtp/js/view/billing-address-mixins.js":"/**\n * Mageplaza\n *\n * NOTICE OF LICENSE\n *\n * This source file is subject to the Mageplaza.com license that is\n * available through the world-wide-web at this URL:\n * https://www.mageplaza.com/LICENSE.txt\n *\n * DISCLAIMER\n *\n * Do not edit or add to this file if you wish to upgrade this extension to newer\n * version in the future.\n *\n * @category    Mageplaza\n * @package     Mageplaza_StoreLocator\n * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)\n * @license     https://www.mageplaza.com/LICENSE.txt\n */\n\ndefine(\n    [\n        'jquery',\n        'ko',\n        'underscore',\n        'Magento_Ui/js/form/form',\n        'Magento_Customer/js/model/customer',\n        'Magento_Customer/js/model/address-list',\n        'Magento_Checkout/js/model/quote',\n        'Magento_Checkout/js/action/create-billing-address',\n        'Magento_Checkout/js/action/select-billing-address',\n        'Magento_Checkout/js/checkout-data',\n        'Magento_Checkout/js/model/checkout-data-resolver',\n        'Magento_Customer/js/customer-data',\n        'Magento_Checkout/js/action/set-billing-address',\n        'Magento_Ui/js/model/messageList',\n        'mage/translate',\n        'Magento_Checkout/js/model/billing-address-postcode-validator',\n        'Mageplaza_Smtp/js/model/address-on-change'\n    ],\n    function (\n        $,\n        ko,\n        _,\n        Component,\n        customer,\n        addressList,\n        quote,\n        createBillingAddress,\n        selectBillingAddress,\n        checkoutData,\n        checkoutDataResolver,\n        customerData,\n        setBillingAddressAction,\n        globalMessageList,\n        $t,\n        billingAddressPostcodeValidator,\n        billingAddressOnChange\n    ) {\n        'use strict';\n\n        var mixin = {\n            initialize: function () {\n                var fieldset;\n\n                this._super();\n\n                if (window.checkoutConfig.oscConfig) {\n                    fieldset = this.get('name') + '.billing-address-fieldset';\n                } else {\n                    fieldset = this.get('name') + '.form-fields';\n                }\n\n                billingAddressOnChange.initFields(fieldset);\n            },\n        };\n\n        return function (target) {\n            return target.extend(mixin);\n        };\n    }\n);\n","Mageplaza_Smtp/js/model/address-on-change.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    'mage/translate',\n    'uiRegistry',\n    'Magento_Checkout/js/model/quote',\n    'Mageplaza_Smtp/js/action/send-address'\n], function (\n    $,\n    ko,\n    $t,\n    uiRegistry,\n    quote,\n    sendAddress\n) {\n    'use strict';\n\n    var elements         = ['firstname', 'lastname', 'company', 'street', 'country_id', 'region_id', 'city', 'postcode', 'telephone'],\n        observedElements = [];\n\n    return {\n        validateAddressTimeout: 0,\n        validateDelay: 1000,\n\n        /**\n         * Perform postponed binding for fieldset elements\n         *\n         * @param {String} formPath\n         */\n        initFields: function (formPath) {\n            var self = this;\n\n            $.each(elements, function (index, field) {\n                uiRegistry.async(formPath + '.' + field)(self.smtpBindHandler.bind(self));\n            });\n        },\n\n        /**\n         * @param {Object} element\n         * @param {Number} delay\n         */\n        smtpBindHandler: function (element, delay) {\n            var self = this;\n\n            delay = typeof delay === 'undefined' ? self.validateDelay : delay;\n\n            if (element.component.indexOf('/group') !== -1) {\n                $.each(element.elems(), function (index, elem) {\n                    uiRegistry.async(elem.name)(function () {\n                        self.smtpBindHandler(elem);\n                    });\n                });\n            } else if (element && element.hasOwnProperty('value')) {\n                element.on('value', function () {\n                    clearTimeout(self.validateAddressTimeout);\n                    self.validateAddressTimeout = setTimeout(function () {\n                        sendAddress(JSON.stringify(self.collectObservedData()), self.isOsc());\n                    }, delay);\n                });\n\n                observedElements.push(element);\n            }\n        },\n        /**\n         * Collect observed fields data to object\n         *\n         * @returns {*}\n         */\n        collectObservedData: function () {\n            var observedValues = {};\n\n            $.each(observedElements, function (index, field) {\n                var value = field.value();\n\n                if ($.type(value) === 'undefined') {\n                    value = '';\n                }\n                observedValues[field.dataScope] = value;\n            });\n\n            return observedValues;\n        },\n        isOsc: function () {\n            return !!window.checkoutConfig.oscConfig;\n        }\n    };\n});\n","Mageplaza_Smtp/js/model/resource-url-manager.js":"/**\n * Mageplaza\n *\n * NOTICE OF LICENSE\n *\n * This source file is subject to the Mageplaza.com license that is\n * available through the world-wide-web at this URL:\n * https://www.mageplaza.com/LICENSE.txt\n *\n * DISCLAIMER\n *\n * Do not edit or add to this file if you wish to upgrade this extension to newer\n * version in the future.\n *\n * @category    Mageplaza\n * @package     Mageplaza_Smtp\n * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)\n * @license     https://www.mageplaza.com/LICENSE.txt\n */\n\ndefine(\n    [\n        'jquery',\n        'Magento_Checkout/js/model/resource-url-manager'\n    ],\n    function ($, resourceUrlManager) {\n        \"use strict\";\n\n        return $.extend({\n            /** Get url for send the address to update order */\n            getUrlForUpdateOrder: function (quote) {\n                var params = {cartId: quote.getQuoteId()};\n                var urls   = {\n                    'default': '/carts/:cartId/update-order'\n                };\n\n                return this.getUrl(urls, params);\n            }\n        }, resourceUrlManager);\n    }\n);\n","Magento_Swatches/js/swatch-renderer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'underscore',\n    'mage/template',\n    'mage/smart-keyboard-handler',\n    'mage/translate',\n    'priceUtils',\n    'jquery-ui-modules/widget',\n    'jquery/jquery.parsequery',\n    'mage/validation/validation'\n], function ($, _, mageTemplate, keyboardHandler, $t, priceUtils) {\n    'use strict';\n\n    /**\n     * Extend form validation to support swatch accessibility\n     */\n    $.widget('mage.validation', $.mage.validation, {\n        /**\n         * Handle form with swatches validation. Focus on first invalid swatch block.\n         *\n         * @param {jQuery.Event} event\n         * @param {Object} validation\n         */\n        listenFormValidateHandler: function (event, validation) {\n            var swatchWrapper, firstActive, swatches, swatch, successList, errorList, firstSwatch;\n\n            this._superApply(arguments);\n\n            swatchWrapper = '.swatch-attribute-options';\n            swatches = $(event.target).find(swatchWrapper);\n\n            if (!swatches.length) {\n                return;\n            }\n\n            swatch = '.swatch-attribute';\n            firstActive = $(validation.errorList[0].element || []);\n            successList = validation.successList;\n            errorList = validation.errorList;\n            firstSwatch = $(firstActive).parent(swatch).find(swatchWrapper);\n\n            keyboardHandler.focus(swatches);\n\n            $.each(successList, function (index, item) {\n                $(item).parent(swatch).find(swatchWrapper).attr('aria-invalid', false);\n            });\n\n            $.each(errorList, function (index, item) {\n                $(item.element).parent(swatch).find(swatchWrapper).attr('aria-invalid', true);\n            });\n\n            if (firstSwatch.length) {\n                $(firstSwatch).trigger('focus');\n            }\n        }\n    });\n\n    /**\n     * Render tooltips by attributes (only to up).\n     * Required element attributes:\n     *  - data-option-type (integer, 0-3)\n     *  - data-option-label (string)\n     *  - data-option-tooltip-thumb\n     *  - data-option-tooltip-value\n     *  - data-thumb-width\n     *  - data-thumb-height\n     */\n    $.widget('mage.SwatchRendererTooltip', {\n        options: {\n            delay: 200,                             //how much ms before tooltip to show\n            tooltipClass: 'swatch-option-tooltip'  //configurable, but remember about css\n        },\n\n        /**\n         * @private\n         */\n        _init: function () {\n            var $widget = this,\n                $this = this.element,\n                $element = $('.' + $widget.options.tooltipClass),\n                timer,\n                type = parseInt($this.data('option-type'), 10),\n                label = $this.data('option-label'),\n                thumb = $this.data('option-tooltip-thumb'),\n                value = $this.data('option-tooltip-value'),\n                width = $this.data('thumb-width'),\n                height = $this.data('thumb-height'),\n                $image,\n                $title,\n                $corner;\n\n            if (!$element.length) {\n                $element = $('<div class=\"' +\n                    $widget.options.tooltipClass +\n                    '\"><div class=\"image\"></div><div class=\"title\"></div><div class=\"corner\"></div></div>'\n                );\n                $('body').append($element);\n            }\n\n            $image = $element.find('.image');\n            $title = $element.find('.title');\n            $corner = $element.find('.corner');\n\n            $this.on('mouseenter', function () {\n                if (!$this.hasClass('disabled')) {\n                    timer = setTimeout(\n                        function () {\n                            var leftOpt = null,\n                                leftCorner = 0,\n                                left,\n                                $window;\n\n                            if (type === 2) {\n                                // Image\n                                $image.css({\n                                    'background': 'url(\"' + thumb + '\") no-repeat center', //Background case\n                                    'background-size': 'initial',\n                                    'width': width + 'px',\n                                    'height': height + 'px'\n                                });\n                                $image.show();\n                            } else if (type === 1) {\n                                // Color\n                                $image.css({\n                                    background: value\n                                });\n                                $image.show();\n                            } else if (type === 0 || type === 3) {\n                                // Default\n                                $image.hide();\n                            }\n\n                            $title.text(label);\n\n                            leftOpt = $this.offset().left;\n                            left = leftOpt + $this.width() / 2 - $element.width() / 2;\n                            $window = $(window);\n\n                            // the numbers (5 and 5) is magick constants for offset from left or right page\n                            if (left < 0) {\n                                left = 5;\n                            } else if (left + $element.width() > $window.width()) {\n                                left = $window.width() - $element.width() - 5;\n                            }\n\n                            // the numbers (6,  3 and 18) is magick constants for offset tooltip\n                            leftCorner = 0;\n\n                            if ($element.width() < $this.width()) {\n                                leftCorner = $element.width() / 2 - 3;\n                            } else {\n                                leftCorner = (leftOpt > left ? leftOpt - left : left - leftOpt) + $this.width() / 2 - 6;\n                            }\n\n                            $corner.css({\n                                left: leftCorner\n                            });\n                            $element.css({\n                                left: left,\n                                top: $this.offset().top - $element.height() - $corner.height() - 18\n                            }).show();\n                        },\n                        $widget.options.delay\n                    );\n                }\n            });\n\n            $this.on('mouseleave', function () {\n                $element.hide();\n                clearTimeout(timer);\n            });\n\n            $(document).on('tap', function () {\n                $element.hide();\n                clearTimeout(timer);\n            });\n\n            $this.on('tap', function (event) {\n                event.stopPropagation();\n            });\n        }\n    });\n\n    /**\n     * Render swatch controls with options and use tooltips.\n     * Required two json:\n     *  - jsonConfig (magento's option config)\n     *  - jsonSwatchConfig (swatch's option config)\n     *\n     *  Tuning:\n     *  - numberToShow (show \"more\" button if options are more)\n     *  - onlySwatches (hide selectboxes)\n     *  - moreButtonText (text for \"more\" button)\n     *  - selectorProduct (selector for product container)\n     *  - selectorProductPrice (selector for change price)\n     */\n    $.widget('mage.SwatchRenderer', {\n        options: {\n            classes: {\n                attributeClass: 'swatch-attribute',\n                attributeLabelClass: 'swatch-attribute-label',\n                attributeSelectedOptionLabelClass: 'swatch-attribute-selected-option',\n                attributeOptionsWrapper: 'swatch-attribute-options',\n                attributeInput: 'swatch-input',\n                optionClass: 'swatch-option',\n                selectClass: 'swatch-select',\n                moreButton: 'swatch-more',\n                loader: 'swatch-option-loading'\n            },\n            // option's json config\n            jsonConfig: {},\n\n            // swatch's json config\n            jsonSwatchConfig: {},\n\n            // selector of parental block of prices and swatches (need to know where to seek for price block)\n            selectorProduct: '.product-info-main',\n\n            // selector of price wrapper (need to know where set price)\n            selectorProductPrice: '[data-role=priceBox]',\n\n            //selector of product images gallery wrapper\n            mediaGallerySelector: '[data-gallery-role=gallery-placeholder]',\n\n            // selector of category product tile wrapper\n            selectorProductTile: '.product-item',\n\n            // number of controls to show (false or zero = show all)\n            numberToShow: false,\n\n            // show only swatch controls\n            onlySwatches: false,\n\n            // enable label for control\n            enableControlLabel: true,\n\n            // control label id\n            controlLabelId: '',\n\n            // text for more button\n            moreButtonText: $t('More'),\n\n            // Callback url for media\n            mediaCallback: '',\n\n            // Local media cache\n            mediaCache: {},\n\n            // Cache for BaseProduct images. Needed when option unset\n            mediaGalleryInitial: [{}],\n\n            // Use ajax to get image data\n            useAjax: false,\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\n            // whether swatches are rendered in product list or on product page\n            inProductList: false,\n\n            // sly-old-price block selector\n            slyOldPriceSelector: '.sly-old-price',\n\n            // tier prise selectors start\n            tierPriceTemplateSelector: '#tier-prices-template',\n            tierPriceBlockSelector: '[data-role=\"tier-price-block\"]',\n            tierPriceTemplate: '',\n            // tier prise selectors end\n\n            // A price label selector\n            normalPriceLabelSelector: '.product-info-main .normal-price .price-label',\n            qtyInfo: '#qty'\n        },\n\n        /**\n         * Get chosen product\n         *\n         * @returns int|null\n         */\n        getProduct: function () {\n            var products = this._CalcProducts();\n\n            return _.isArray(products) ? products[0] : null;\n        },\n\n        /**\n         * Get chosen product id\n         *\n         * @returns int|null\n         */\n        getProductId: function () {\n            var products = this._CalcProducts();\n\n            return _.isArray(products) && products.length === 1 ? products[0] : null;\n        },\n\n        /**\n         * @private\n         */\n        _init: function () {\n            // Don't render the same set of swatches twice\n            if ($(this.element).attr('data-rendered')) {\n                return;\n            }\n\n            $(this.element).attr('data-rendered', true);\n\n            if (_.isEmpty(this.options.jsonConfig.images)) {\n                this.options.useAjax = true;\n                // creates debounced variant of _LoadProductMedia()\n                // to use it in events handlers instead of _LoadProductMedia()\n                this._debouncedLoadProductMedia = _.debounce(this._LoadProductMedia.bind(this), 500);\n            }\n\n            this.options.tierPriceTemplate = $(this.options.tierPriceTemplateSelector).html();\n\n            if (this.options.jsonConfig !== '' && this.options.jsonSwatchConfig !== '') {\n                // store unsorted attributes\n                this.options.jsonConfig.mappedAttributes = _.clone(this.options.jsonConfig.attributes);\n                this._sortAttributes();\n                this._RenderControls();\n                this._setPreSelectedGallery();\n                $(this.element).trigger('swatch.initialized');\n            } else {\n                console.log('SwatchRenderer: No input data received');\n            }\n        },\n\n        /**\n         * @private\n         */\n        _sortAttributes: function () {\n            this.options.jsonConfig.attributes = _.sortBy(this.options.jsonConfig.attributes, function (attribute) {\n                return parseInt(attribute.position, 10);\n            });\n        },\n\n        /**\n         * @private\n         */\n        _create: function () {\n            var options = this.options,\n                gallery = $('[data-gallery-role=gallery-placeholder]', '.column.main'),\n                productData = this._determineProductData(),\n                $main = productData.isInProductView ?\n                    this.element.parents('.column.main') :\n                    this.element.parents('.product-item-info');\n\n            if (productData.isInProductView) {\n                gallery.data('gallery') ?\n                    this._onGalleryLoaded(gallery) :\n                    gallery.on('gallery:loaded', this._onGalleryLoaded.bind(this, gallery));\n            } else {\n                options.mediaGalleryInitial = [{\n                    'img': $main.find('.product-image-photo').attr('src')\n                }];\n            }\n\n            this.productForm = this.element.parents(this.options.selectorProductTile).find('form:first');\n            this.inProductList = this.productForm.length > 0;\n            $(this.options.qtyInfo).on('input', this._onQtyChanged.bind(this));\n        },\n\n        /**\n         * Determine product id and related data\n         *\n         * @returns {{productId: *, isInProductView: bool}}\n         * @private\n         */\n        _determineProductData: function () {\n            // Check if product is in a list of products.\n            var productId,\n                isInProductView = false;\n\n            productId = this.element.parents('.product-item-details')\n                    .find('.price-box.price-final_price').attr('data-product-id');\n\n            if (!productId) {\n                // Check individual product.\n                productId = $('[name=product]').val();\n                isInProductView = productId > 0;\n            }\n\n            return {\n                productId: productId,\n                isInProductView: isInProductView\n            };\n        },\n\n        /**\n         * Render controls\n         *\n         * @private\n         */\n        _RenderControls: function () {\n            var $widget = this,\n                container = this.element,\n                classes = this.options.classes,\n                chooseText = this.options.jsonConfig.chooseText,\n                showTooltip = this.options.showTooltip;\n\n            $widget.optionsMap = {};\n\n            $.each(this.options.jsonConfig.attributes, function () {\n                var item = this,\n                    controlLabelId = 'option-label-' + item.code + '-' + item.id,\n                    options = $widget._RenderSwatchOptions(item, controlLabelId),\n                    select = $widget._RenderSwatchSelect(item, chooseText),\n                    input = $widget._RenderFormInput(item),\n                    listLabel = '',\n                    label = '';\n\n                // Show only swatch controls\n                if ($widget.options.onlySwatches && !$widget.options.jsonSwatchConfig.hasOwnProperty(item.id)) {\n                    return;\n                }\n\n                if ($widget.options.enableControlLabel) {\n                    label +=\n                        '<span id=\"' + controlLabelId + '\" class=\"' + classes.attributeLabelClass + '\">' +\n                        $('<i></i>').text(item.label).html() +\n                        '</span>' +\n                        '<span class=\"' + classes.attributeSelectedOptionLabelClass + '\"></span>';\n                }\n\n                if ($widget.inProductList) {\n                    $widget.productForm.append(input);\n                    input = '';\n                    listLabel = 'aria-label=\"' + $('<i></i>').text(item.label).html() + '\"';\n                } else {\n                    listLabel = 'aria-labelledby=\"' + controlLabelId + '\"';\n                }\n\n                // Create new control\n                container.append(\n                    '<div class=\"' + classes.attributeClass + ' ' + item.code + '\" ' +\n                         'data-attribute-code=\"' + item.code + '\" ' +\n                         'data-attribute-id=\"' + item.id + '\">' +\n                        label +\n                        '<div aria-activedescendant=\"\" ' +\n                             'tabindex=\"0\" ' +\n                             'aria-invalid=\"false\" ' +\n                             'aria-required=\"true\" ' +\n                             'role=\"listbox\" ' + listLabel +\n                             'class=\"' + classes.attributeOptionsWrapper + ' clearfix\">' +\n                            options + select +\n                        '</div>' + input +\n                    '</div>'\n                );\n\n                $widget.optionsMap[item.id] = {};\n\n                // Aggregate options array to hash (key => value)\n                $.each(item.options, function () {\n                    if (this.products.length > 0) {\n                        $widget.optionsMap[item.id][this.id] = {\n                            price: parseInt(\n                                $widget.options.jsonConfig.optionPrices[this.products[0]].finalPrice.amount,\n                                10\n                            ),\n                            products: this.products\n                        };\n                    }\n                });\n            });\n\n            if (showTooltip === 1) {\n                // Connect Tooltip\n                container\n                    .find('[data-option-type=\"1\"], [data-option-type=\"2\"],' +\n                        ' [data-option-type=\"0\"], [data-option-type=\"3\"]')\n                    .SwatchRendererTooltip();\n            }\n\n            // Hide all elements below more button\n            $('.' + classes.moreButton).nextAll().hide();\n\n            // Handle events like click or change\n            $widget._EventListener();\n\n            // Rewind options\n            $widget._Rewind(container);\n\n            //Emulate click on all swatches from Request\n            $widget._EmulateSelected($.parseQuery());\n            $widget._EmulateSelected($widget._getSelectedAttributes());\n        },\n\n        disableSwatchForOutOfStockProducts: function () {\n            let $widget = this, container = this.element;\n\n            $.each(this.options.jsonConfig.attributes, function () {\n                let item = this;\n\n                if ($widget.options.jsonConfig.canDisplayShowOutOfStockStatus) {\n                    let salableProducts = $widget.options.jsonConfig.salable[item.id],\n                        swatchOptions = $(container).find(`[data-attribute-id='${item.id}']`).find('.swatch-option');\n\n                    swatchOptions.each(function (key, value) {\n                        let optionId = $(value).data('option-id');\n\n                        if (!salableProducts.hasOwnProperty(optionId)) {\n                            $(value).attr('disabled', true).addClass('disabled');\n                        }\n                    });\n                }\n            });\n        },\n\n        /**\n         * Render swatch options by part of config\n         *\n         * @param {Object} config\n         * @param {String} controlId\n         * @returns {String}\n         * @private\n         */\n        _RenderSwatchOptions: function (config, controlId) {\n            var optionConfig = this.options.jsonSwatchConfig[config.id],\n                optionClass = this.options.classes.optionClass,\n                sizeConfig = this.options.jsonSwatchImageSizeConfig,\n                moreLimit = parseInt(this.options.numberToShow, 10),\n                moreClass = this.options.classes.moreButton,\n                moreText = this.options.moreButtonText,\n                countAttributes = 0,\n                html = '';\n\n            if (!this.options.jsonSwatchConfig.hasOwnProperty(config.id)) {\n                return '';\n            }\n\n            $.each(config.options, function (index) {\n                var id,\n                    type,\n                    value,\n                    thumb,\n                    label,\n                    width,\n                    height,\n                    attr,\n                    swatchImageWidth,\n                    swatchImageHeight;\n\n                if (!optionConfig.hasOwnProperty(this.id)) {\n                    return '';\n                }\n\n                // Add more button\n                if (moreLimit === countAttributes++) {\n                    html += '<a href=\"#\" class=\"' + moreClass + '\"><span>' + moreText + '</span></a>';\n                }\n\n                id = this.id;\n                type = parseInt(optionConfig[id].type, 10);\n                value = optionConfig[id].hasOwnProperty('value') ?\n                    $('<i></i>').text(optionConfig[id].value).html() : '';\n                thumb = optionConfig[id].hasOwnProperty('thumb') ? optionConfig[id].thumb : '';\n                width = _.has(sizeConfig, 'swatchThumb') ? sizeConfig.swatchThumb.width : 110;\n                height = _.has(sizeConfig, 'swatchThumb') ? sizeConfig.swatchThumb.height : 90;\n                label = this.label ? $('<i></i>').text(this.label).html() : '';\n                attr =\n                    ' id=\"' + controlId + '-item-' + id + '\"' +\n                    ' index=\"' + index + '\"' +\n                    ' aria-checked=\"false\"' +\n                    ' aria-describedby=\"' + controlId + '\"' +\n                    ' tabindex=\"0\"' +\n                    ' data-option-type=\"' + type + '\"' +\n                    ' data-option-id=\"' + id + '\"' +\n                    ' data-option-label=\"' + label + '\"' +\n                    ' aria-label=\"' + label + '\"' +\n                    ' role=\"option\"' +\n                    ' data-thumb-width=\"' + width + '\"' +\n                    ' data-thumb-height=\"' + height + '\"';\n\n                attr += thumb !== '' ? ' data-option-tooltip-thumb=\"' + thumb + '\"' : '';\n                attr += value !== '' ? ' data-option-tooltip-value=\"' + value + '\"' : '';\n\n                swatchImageWidth = _.has(sizeConfig, 'swatchImage') ? sizeConfig.swatchImage.width : 30;\n                swatchImageHeight = _.has(sizeConfig, 'swatchImage') ? sizeConfig.swatchImage.height : 20;\n\n                if (!this.hasOwnProperty('products') || this.products.length <= 0) {\n                    attr += ' data-option-empty=\"true\"';\n                }\n\n                if (type === 0) {\n                    // Text\n                    html += '<div class=\"' + optionClass + ' text\" ' + attr + '>' + (value ? value : label) +\n                        '</div>';\n                } else if (type === 1) {\n                    // Color\n                    html += '<div class=\"' + optionClass + ' color\" ' + attr +\n                        ' style=\"background: ' + value +\n                        ' no-repeat center; background-size: initial;\">' + '' +\n                        '</div>';\n                } else if (type === 2) {\n                    // Image\n                    html += '<div class=\"' + optionClass + ' image\" ' + attr +\n                        ' style=\"background: url(' + value + ') no-repeat center; background-size: initial;width:' +\n                        swatchImageWidth + 'px; height:' + swatchImageHeight + 'px\">' + '' +\n                        '</div>';\n                } else if (type === 3) {\n                    // Clear\n                    html += '<div class=\"' + optionClass + '\" ' + attr + '></div>';\n                } else {\n                    // Default\n                    html += '<div class=\"' + optionClass + '\" ' + attr + '>' + label + '</div>';\n                }\n            });\n\n            return html;\n        },\n\n        /**\n         * Render select by part of config\n         *\n         * @param {Object} config\n         * @param {String} chooseText\n         * @returns {String}\n         * @private\n         */\n        _RenderSwatchSelect: function (config, chooseText) {\n            var html;\n\n            if (this.options.jsonSwatchConfig.hasOwnProperty(config.id)) {\n                return '';\n            }\n\n            html =\n                '<select class=\"' + this.options.classes.selectClass + ' ' + config.code + '\">' +\n                '<option value=\"0\" data-option-id=\"0\">' + chooseText + '</option>';\n\n            $.each(config.options, function () {\n                var label = this.label,\n                    attr = ' value=\"' + this.id + '\" data-option-id=\"' + this.id + '\"';\n\n                if (!this.hasOwnProperty('products') || this.products.length <= 0) {\n                    attr += ' data-option-empty=\"true\"';\n                }\n\n                html += '<option ' + attr + '>' + label + '</option>';\n            });\n\n            html += '</select>';\n\n            return html;\n        },\n\n        /**\n         * Input for submit form.\n         * This control shouldn't have \"type=hidden\", \"display: none\" for validation work :(\n         *\n         * @param {Object} config\n         * @private\n         */\n        _RenderFormInput: function (config) {\n            return '<input class=\"' + this.options.classes.attributeInput + ' super-attribute-select\" ' +\n                'name=\"super_attribute[' + config.id + ']\" ' +\n                'type=\"text\" ' +\n                'value=\"\" ' +\n                'data-selector=\"super_attribute[' + config.id + ']\" ' +\n                'data-validate=\"{required: true}\" ' +\n                'aria-required=\"true\" ' +\n                'aria-invalid=\"false\">';\n        },\n\n        /**\n         * Event listener\n         *\n         * @private\n         */\n        _EventListener: function () {\n            var $widget = this,\n                options = this.options.classes,\n                target;\n\n            $widget.element.on('click', '.' + options.optionClass, function () {\n                return $widget._OnClick($(this), $widget);\n            });\n\n            $widget.element.on('change', '.' + options.selectClass, function () {\n                return $widget._OnChange($(this), $widget);\n            });\n\n            $widget.element.on('click', '.' + options.moreButton, function (e) {\n                e.preventDefault();\n\n                return $widget._OnMoreClick($(this));\n            });\n\n            $widget.element.on('keydown', function (e) {\n                if (e.which === 13) {\n                    target = $(e.target);\n\n                    if (target.is('.' + options.optionClass)) {\n                        return $widget._OnClick(target, $widget);\n                    } else if (target.is('.' + options.selectClass)) {\n                        return $widget._OnChange(target, $widget);\n                    } else if (target.is('.' + options.moreButton)) {\n                        e.preventDefault();\n\n                        return $widget._OnMoreClick(target);\n                    }\n                }\n            });\n        },\n\n        /**\n         * Load media gallery using ajax or json config.\n         *\n         * @private\n         */\n        _loadMedia: function () {\n            var $main = this.inProductList ?\n                    this.element.parents('.product-item-info') :\n                    this.element.parents('.column.main'),\n                images;\n\n            if (this.options.useAjax) {\n                this._debouncedLoadProductMedia();\n            }  else {\n                images = this.options.jsonConfig.images[this.getProduct()];\n\n                if (!images) {\n                    images = this.options.mediaGalleryInitial;\n                }\n                this.updateBaseImage(this._sortImages(images), $main, !this.inProductList);\n            }\n        },\n\n        /**\n         * Sorting images array\n         *\n         * @private\n         */\n        _sortImages: function (images) {\n            return _.sortBy(images, function (image) {\n                return parseInt(image.position, 10);\n            });\n        },\n\n        /**\n         * Event for swatch options\n         *\n         * @param {Object} $this\n         * @param {Object} $widget\n         * @private\n         */\n        _OnClick: function ($this, $widget) {\n            var $parent = $this.parents('.' + $widget.options.classes.attributeClass),\n                $wrapper = $this.parents('.' + $widget.options.classes.attributeOptionsWrapper),\n                $label = $parent.find('.' + $widget.options.classes.attributeSelectedOptionLabelClass),\n                attributeId = $parent.data('attribute-id'),\n                $input = $parent.find('.' + $widget.options.classes.attributeInput),\n                checkAdditionalData = JSON.parse(this.options.jsonSwatchConfig[attributeId]['additional_data']),\n                $priceBox = $widget.element.parents($widget.options.selectorProduct)\n                    .find(this.options.selectorProductPrice);\n\n            if ($widget.inProductList) {\n                $input = $widget.productForm.find(\n                    '.' + $widget.options.classes.attributeInput + '[name=\"super_attribute[' + attributeId + ']\"]'\n                );\n            }\n\n            if ($this.hasClass('disabled')) {\n                return;\n            }\n\n            if ($this.hasClass('selected')) {\n                $parent.removeAttr('data-option-selected').find('.selected').removeClass('selected');\n                $input.val('');\n                $label.text('');\n                $this.attr('aria-checked', false);\n            } else {\n                $parent.attr('data-option-selected', $this.data('option-id')).find('.selected').removeClass('selected');\n                $label.text($this.data('option-label'));\n                $input.val($this.data('option-id'));\n                $input.attr('data-attr-name', this._getAttributeCodeById(attributeId));\n                $this.addClass('selected');\n                $widget._toggleCheckedAttributes($this, $wrapper);\n            }\n\n            $widget._Rebuild();\n\n            if ($priceBox.is(':data(mage-priceBox)')) {\n                $widget._UpdatePrice();\n            }\n\n            $(document).trigger('updateMsrpPriceBlock',\n                [\n                    this._getSelectedOptionPriceIndex(),\n                    $widget.options.jsonConfig.optionPrices,\n                    $priceBox\n                ]);\n\n            if (parseInt(checkAdditionalData['update_product_preview_image'], 10) === 1) {\n                $widget._loadMedia();\n            }\n\n            $input.trigger('change');\n        },\n\n        /**\n         * Get selected option price index\n         *\n         * @return {String|undefined}\n         * @private\n         */\n        _getSelectedOptionPriceIndex: function () {\n            var allowedProduct = this._getAllowedProductWithMinPrice(this._CalcProducts());\n\n            if (_.isEmpty(allowedProduct)) {\n                return undefined;\n            }\n\n            return allowedProduct;\n        },\n\n        /**\n         * Get human readable attribute code (eg. size, color) by it ID from configuration\n         *\n         * @param {Number} attributeId\n         * @returns {*}\n         * @private\n         */\n        _getAttributeCodeById: function (attributeId) {\n            var attribute = this.options.jsonConfig.mappedAttributes[attributeId];\n\n            return attribute ? attribute.code : attributeId;\n        },\n\n        /**\n         * Toggle accessibility attributes\n         *\n         * @param {Object} $this\n         * @param {Object} $wrapper\n         * @private\n         */\n        _toggleCheckedAttributes: function ($this, $wrapper) {\n            $wrapper.attr('aria-activedescendant', $this.attr('id'))\n                    .find('.' + this.options.classes.optionClass).attr('aria-checked', false);\n            $this.attr('aria-checked', true);\n        },\n\n        /**\n         * Event for select\n         *\n         * @param {Object} $this\n         * @param {Object} $widget\n         * @private\n         */\n        _OnChange: function ($this, $widget) {\n            var $parent = $this.parents('.' + $widget.options.classes.attributeClass),\n                attributeId = $parent.data('attribute-id'),\n                $input = $parent.find('.' + $widget.options.classes.attributeInput);\n\n            if ($widget.productForm.length > 0) {\n                $input = $widget.productForm.find(\n                    '.' + $widget.options.classes.attributeInput + '[name=\"super_attribute[' + attributeId + ']\"]'\n                );\n            }\n\n            if ($this.val() > 0) {\n                $parent.attr('data-option-selected', $this.val());\n                $input.val($this.val());\n            } else {\n                $parent.removeAttr('data-option-selected');\n                $input.val('');\n            }\n\n            $widget._Rebuild();\n            $widget._UpdatePrice();\n            $widget._loadMedia();\n            $input.trigger('change');\n        },\n\n        /**\n         * Event for more switcher\n         *\n         * @param {Object} $this\n         * @private\n         */\n        _OnMoreClick: function ($this) {\n            $this.nextAll().show();\n            $this.trigger('blur').remove();\n        },\n\n        /**\n         * Rewind options for controls\n         *\n         * @private\n         */\n        _Rewind: function (controls) {\n            controls.find('div[data-option-id], option[data-option-id]')\n                .removeClass('disabled')\n                .prop('disabled', false);\n            controls.find('div[data-option-empty], option[data-option-empty]')\n                .attr('disabled', true)\n                .addClass('disabled')\n                .attr('tabindex', '-1');\n            this.disableSwatchForOutOfStockProducts();\n        },\n\n        /**\n         * Rebuild container\n         *\n         * @private\n         */\n        _Rebuild: function () {\n            var $widget = this,\n                controls = $widget.element.find('.' + $widget.options.classes.attributeClass + '[data-attribute-id]'),\n                selected = controls.filter('[data-option-selected]');\n\n            // Enable all options\n            $widget._Rewind(controls);\n\n            // done if nothing selected\n            if (selected.length <= 0) {\n                return;\n            }\n\n            // Disable not available options\n            controls.each(function () {\n                var $this = $(this),\n                    id = $this.data('attribute-id'),\n                    products = $widget._CalcProducts(id);\n\n                if (selected.length === 1 && selected.first().data('attribute-id') === id) {\n                    return;\n                }\n\n                $this.find('[data-option-id]').each(function () {\n                    var $element = $(this),\n                        option = $element.data('option-id');\n\n                    if (!$widget.optionsMap.hasOwnProperty(id) || !$widget.optionsMap[id].hasOwnProperty(option) ||\n                        $element.hasClass('selected') ||\n                        $element.is(':selected')) {\n                        return;\n                    }\n\n                    if (_.intersection(products, $widget.optionsMap[id][option].products).length <= 0) {\n                        $element.attr('disabled', true).addClass('disabled');\n                    }\n                });\n            });\n        },\n\n        /**\n         * Get selected product list\n         *\n         * @returns {Array}\n         * @private\n         */\n        _CalcProducts: function ($skipAttributeId) {\n            var $widget = this,\n                selectedOptions = '.' + $widget.options.classes.attributeClass + '[data-option-selected]',\n                products = [];\n\n            // Generate intersection of products\n            $widget.element.find(selectedOptions).each(function () {\n                var id = $(this).data('attribute-id'),\n                    option = $(this).attr('data-option-selected');\n\n                if ($skipAttributeId !== undefined && $skipAttributeId === id) {\n                    return;\n                }\n\n                if (!$widget.optionsMap.hasOwnProperty(id) || !$widget.optionsMap[id].hasOwnProperty(option)) {\n                    return;\n                }\n\n                if (products.length === 0) {\n                    products = $widget.optionsMap[id][option].products;\n                } else {\n                    products = _.intersection(products, $widget.optionsMap[id][option].products);\n                }\n            });\n\n            return products;\n        },\n\n        /**\n         * Update total price\n         *\n         * @private\n         */\n        _UpdatePrice: function () {\n            var $widget = this,\n                $product = $widget.element.parents($widget.options.selectorProduct),\n                $productPrice = $product.find(this.options.selectorProductPrice),\n                result = $widget._getNewPrices(),\n                tierPriceHtml,\n                isShow;\n\n            $productPrice.trigger(\n                'updatePrice',\n                {\n                    'prices': $widget._getPrices(result, $productPrice.priceBox('option').prices)\n                }\n            );\n\n            isShow = typeof result != 'undefined' && result.oldPrice.amount !== result.finalPrice.amount;\n\n            $productPrice.find('span:first').toggleClass('special-price', isShow);\n\n            $product.find(this.options.slyOldPriceSelector)[isShow ? 'show' : 'hide']();\n\n            if (typeof result != 'undefined' && result.tierPrices && result.tierPrices.length) {\n                if (this.options.tierPriceTemplate) {\n                    tierPriceHtml = mageTemplate(\n                        this.options.tierPriceTemplate,\n                        {\n                            'tierPrices': result.tierPrices,\n                            '$t': $t,\n                            'currencyFormat': this.options.jsonConfig.currencyFormat,\n                            'priceUtils': priceUtils\n                        }\n                    );\n                    $(this.options.tierPriceBlockSelector).html(tierPriceHtml).show();\n                }\n            } else {\n                $(this.options.tierPriceBlockSelector).hide();\n            }\n\n            $(this.options.normalPriceLabelSelector).hide();\n\n            _.each($('.' + this.options.classes.attributeOptionsWrapper), function (attribute) {\n                if ($(attribute).find('.' + this.options.classes.optionClass + '.selected').length === 0) {\n                    if ($(attribute).find('.' + this.options.classes.selectClass).length > 0) {\n                        _.each($(attribute).find('.' + this.options.classes.selectClass), function (dropdown) {\n                            if ($(dropdown).val() === '0') {\n                                $(this.options.normalPriceLabelSelector).show();\n                            }\n                        }.bind(this));\n                    } else {\n                        $(this.options.normalPriceLabelSelector).show();\n                    }\n                }\n            }.bind(this));\n        },\n\n        /**\n         * Get new prices for selected options\n         *\n         * @returns {*}\n         * @private\n         */\n        _getNewPrices: function () {\n            var $widget = this,\n                newPrices = $widget.options.jsonConfig.prices,\n                allowedProduct = this._getAllowedProductWithMinPrice(this._CalcProducts());\n\n            if (!_.isEmpty(allowedProduct)) {\n                newPrices = this.options.jsonConfig.optionPrices[allowedProduct];\n            }\n\n            return newPrices;\n        },\n\n        /**\n         * Get prices\n         *\n         * @param {Object} newPrices\n         * @param {Object} displayPrices\n         * @returns {*}\n         * @private\n         */\n        _getPrices: function (newPrices, displayPrices) {\n            var $widget = this;\n\n            if (_.isEmpty(newPrices)) {\n                newPrices = $widget._getNewPrices();\n            }\n            _.each(displayPrices, function (price, code) {\n\n                if (newPrices[code]) {\n                    displayPrices[code].amount = newPrices[code].amount - displayPrices[code].amount;\n                }\n            });\n\n            return displayPrices;\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.jsonConfig.optionPrices,\n                product = {},\n                optionFinalPrice, optionMinPrice;\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         * Gets all product media and change current to the needed one\n         *\n         * @private\n         */\n        _LoadProductMedia: function () {\n            var $widget = this,\n                $this = $widget.element,\n                productData = this._determineProductData(),\n                mediaCallData,\n                mediaCacheKey,\n\n                /**\n                 * Processes product media data\n                 *\n                 * @param {Object} data\n                 * @returns void\n                 */\n                mediaSuccessCallback = function (data) {\n                    if (!(mediaCacheKey in $widget.options.mediaCache)) {\n                        $widget.options.mediaCache[mediaCacheKey] = data;\n                    }\n                    $widget._ProductMediaCallback($this, data, productData.isInProductView);\n                    setTimeout(function () {\n                        $widget._DisableProductMediaLoader($this);\n                    }, 300);\n                };\n\n            if (!$widget.options.mediaCallback) {\n                return;\n            }\n\n            mediaCallData = {\n                'product_id': this.getProduct()\n            };\n\n            mediaCacheKey = JSON.stringify(mediaCallData);\n\n            if (mediaCacheKey in $widget.options.mediaCache) {\n                $widget._XhrKiller();\n                $widget._EnableProductMediaLoader($this);\n                mediaSuccessCallback($widget.options.mediaCache[mediaCacheKey]);\n            } else {\n                mediaCallData.isAjax = true;\n                $widget._XhrKiller();\n                $widget._EnableProductMediaLoader($this);\n                $widget.xhr = $.ajax({\n                    url: $widget.options.mediaCallback,\n                    cache: true,\n                    type: 'GET',\n                    dataType: 'json',\n                    data: mediaCallData,\n                    success: mediaSuccessCallback\n                }).done(function () {\n                    $widget._XhrKiller();\n                });\n            }\n        },\n\n        /**\n         * Enable loader\n         *\n         * @param {Object} $this\n         * @private\n         */\n        _EnableProductMediaLoader: function ($this) {\n            var $widget = this;\n\n            if ($('body.catalog-product-view').length > 0) {\n                $this.parents('.column.main').find('.photo.image')\n                    .addClass($widget.options.classes.loader);\n            } else {\n                //Category View\n                $this.parents('.product-item-info').find('.product-image-photo')\n                    .addClass($widget.options.classes.loader);\n            }\n        },\n\n        /**\n         * Disable loader\n         *\n         * @param {Object} $this\n         * @private\n         */\n        _DisableProductMediaLoader: function ($this) {\n            var $widget = this;\n\n            if ($('body.catalog-product-view').length > 0) {\n                $this.parents('.column.main').find('.photo.image')\n                    .removeClass($widget.options.classes.loader);\n            } else {\n                //Category View\n                $this.parents('.product-item-info').find('.product-image-photo')\n                    .removeClass($widget.options.classes.loader);\n            }\n        },\n\n        /**\n         * Callback for product media\n         *\n         * @param {Object} $this\n         * @param {String} response\n         * @param {Boolean} isInProductView\n         * @private\n         */\n        _ProductMediaCallback: function ($this, response, isInProductView) {\n            var $main = isInProductView ? $this.parents('.column.main') : $this.parents('.product-item-info'),\n                $widget = this,\n                images = [],\n\n                /**\n                 * Check whether object supported or not\n                 *\n                 * @param {Object} e\n                 * @returns {*|Boolean}\n                 */\n                support = function (e) {\n                    return e.hasOwnProperty('large') && e.hasOwnProperty('medium') && e.hasOwnProperty('small');\n                };\n\n            if (_.size($widget) < 1 || !support(response)) {\n                this.updateBaseImage(this.options.mediaGalleryInitial, $main, isInProductView);\n\n                return;\n            }\n\n            images.push({\n                full: response.large,\n                img: response.medium,\n                thumb: response.small,\n                isMain: true\n            });\n\n            if (response.hasOwnProperty('gallery')) {\n                $.each(response.gallery, function () {\n                    if (!support(this) || response.large === this.large) {\n                        return;\n                    }\n                    images.push({\n                        full: this.large,\n                        img: this.medium,\n                        thumb: this.small\n                    });\n                });\n            }\n\n            this.updateBaseImage(images, $main, isInProductView);\n        },\n\n        /**\n         * Check if images to update are initial and set their type\n         * @param {Array} images\n         */\n        _setImageType: function (images) {\n\n            images.map(function (img) {\n                if (!img.type) {\n                    img.type = 'image';\n                }\n            });\n\n            return images;\n        },\n\n        /**\n         * Update [gallery-placeholder] or [product-image-photo]\n         * @param {Array} images\n         * @param {jQuery} context\n         * @param {Boolean} isInProductView\n         */\n        updateBaseImage: function (images, context, isInProductView) {\n            var justAnImage = images[0],\n                initialImages = this.options.mediaGalleryInitial,\n                imagesToUpdate,\n                gallery = context.find(this.options.mediaGallerySelector).data('gallery'),\n                isInitial;\n\n            if (isInProductView) {\n                if (_.isUndefined(gallery)) {\n                    context.find(this.options.mediaGallerySelector).on('gallery:loaded', function () {\n                        this.updateBaseImage(images, context, isInProductView);\n                    }.bind(this));\n\n                    return;\n                }\n\n                imagesToUpdate = images.length ? this._setImageType($.extend(true, [], images)) : [];\n                isInitial = _.isEqual(imagesToUpdate, initialImages);\n\n                if (this.options.gallerySwitchStrategy === 'prepend' && !isInitial) {\n                    imagesToUpdate = imagesToUpdate.concat(initialImages);\n                }\n\n                imagesToUpdate = this._setImageIndex(imagesToUpdate);\n\n                gallery.updateData(imagesToUpdate);\n                this._addFotoramaVideoEvents(isInitial);\n            } else if (justAnImage && justAnImage.img) {\n                context.find('.product-image-photo').attr('src', justAnImage.img);\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.getProduct(),\n                dataMergeStrategy: this.options.gallerySwitchStrategy\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         * Kill doubled AJAX requests\n         *\n         * @private\n         */\n        _XhrKiller: function () {\n            var $widget = this;\n\n            if ($widget.xhr !== undefined && $widget.xhr !== null) {\n                $widget.xhr.abort();\n                $widget.xhr = null;\n            }\n        },\n\n        /**\n         * Emulate mouse click on all swatches that should be selected\n         * @param {Object} [selectedAttributes]\n         * @private\n         */\n        _EmulateSelected: function (selectedAttributes) {\n            $.each(selectedAttributes, $.proxy(function (attributeCode, optionId) {\n                var elem = this.element.find('.' + this.options.classes.attributeClass +\n                    '[data-attribute-code=\"' + attributeCode + '\"] [data-option-id=\"' + optionId + '\"]'),\n                    parentInput = elem.parent();\n\n                if (elem.hasClass('selected')) {\n                    return;\n                }\n\n                if (parentInput.hasClass(this.options.classes.selectClass)) {\n                    parentInput.val(optionId);\n                    parentInput.trigger('change');\n                } else {\n                    elem.trigger('click');\n                }\n            }, this));\n        },\n\n        /**\n         * Emulate mouse click or selection change on all swatches that should be selected\n         * @param {Object} [selectedAttributes]\n         * @private\n         */\n        _EmulateSelectedByAttributeId: function (selectedAttributes) {\n            $.each(selectedAttributes, $.proxy(function (attributeId, optionId) {\n                var elem = this.element.find('.' + this.options.classes.attributeClass +\n                    '[data-attribute-id=\"' + attributeId + '\"] [data-option-id=\"' + optionId + '\"]'),\n                    parentInput = elem.parent();\n\n                if (elem.hasClass('selected')) {\n                    return;\n                }\n\n                if (parentInput.hasClass(this.options.classes.selectClass)) {\n                    parentInput.val(optionId);\n                    parentInput.trigger('change');\n                } else {\n                    elem.trigger('click');\n                }\n            }, this));\n        },\n\n        /**\n         * Get default options values settings with either URL query parameters\n         * @private\n         */\n        _getSelectedAttributes: function () {\n            var hashIndex = window.location.href.indexOf('#'),\n                selectedAttributes = {},\n                params;\n\n            if (hashIndex !== -1) {\n                params = $.parseQuery(window.location.href.substr(hashIndex + 1));\n\n                selectedAttributes = _.invert(_.mapObject(_.invert(params), function (attributeId) {\n                    var attribute = this.options.jsonConfig.mappedAttributes[attributeId];\n\n                    return attribute ? attribute.code : attributeId;\n                }.bind(this)));\n            }\n\n            return selectedAttributes;\n        },\n\n        /**\n         * Callback which fired after gallery gets initialized.\n         *\n         * @param {HTMLElement} element - DOM element associated with a gallery.\n         */\n        _onGalleryLoaded: function (element) {\n            var galleryObject = element.data('gallery');\n\n            this.options.mediaGalleryInitial = galleryObject.returnCurrentImages();\n        },\n\n        /**\n         * Sets mediaCache for cases when jsonConfig contains preSelectedGallery on layered navigation result pages\n         *\n         * @private\n         */\n        _setPreSelectedGallery: function () {\n            var mediaCallData;\n\n            if (this.options.jsonConfig.preSelectedGallery) {\n                mediaCallData = {\n                    'product_id': this.getProduct()\n                };\n\n                this.options.mediaCache[JSON.stringify(mediaCallData)] = this.options.jsonConfig.preSelectedGallery;\n            }\n        },\n\n        /**\n         * Callback for quantity change event.\n         */\n        _onQtyChanged: function () {\n            var $price = this.element.parents(this.options.selectorProduct)\n                .find(this.options.selectorProductPrice);\n\n            $price.trigger(\n                'updatePrice',\n                {\n                    'prices': this._getPrices(this._getNewPrices(), $price.priceBox('option').prices)\n                }\n            );\n        }\n    });\n\n    return $.mage.SwatchRenderer;\n});\n","Magento_Swatches/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            swatchSelector: '.swatch-opt'\n        },\n        swatchWidgetName = 'mage-SwatchRenderer',\n        widgetInitEvent = 'swatch.initialized',\n\n    /**\n    * Sets all configurable swatch attribute's selected values\n    */\n    updateSwatchOptions = function () {\n        var swatchWidget = $(selectors.swatchSelector).data(swatchWidgetName);\n\n        if (!swatchWidget || !swatchWidget._EmulateSelectedByAttributeId) {\n            return;\n        }\n        swatchWidget._EmulateSelectedByAttributeId(this.productOptions);\n    },\n    updater = new Updater(widgetInitEvent, updateSwatchOptions);\n\n    updater.listen();\n});\n","Magento_Swatches/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 swatch 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('[name*=\"super\"]').each(function (index, item) {\n            var $item = $(item),\n                attr;\n\n            if ($item.attr('data-attr-name')) {\n                attr = $item.attr('data-attr-name');\n            } else {\n                attr = $item.parent().attr('attribute-code');\n            }\n            data.redirectParameters.push(attr + '=' + $item.val());\n\n        });\n    });\n});\n","Mageplaza_Blog/js/postAction.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license that is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category    Mageplaza\r\n * @package     Mageplaza_Blog\r\n * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)\r\n * @license     https://www.mageplaza.com/LICENSE.txt\r\n */\r\ndefine([\r\n    'jquery',\r\n    \"mage/adminhtml/events\",\r\n    \"mage/adminhtml/wysiwyg/tiny_mce/setup\"\r\n], function ($) {\r\n    'use strict';\r\n\r\n    $.widget('mageplaza.mpBlogPostAction', {\r\n            options: {},\r\n            _create: function () {\r\n                var self = this;\r\n\r\n                $('button.mpblog-action-new').on('click', function () {\r\n                    self._AddNew();\r\n                });\r\n            },\r\n            _AddNew: function () {\r\n                var form      = $('#mp_blog_post_form'),\r\n                    formData  = new FormData(form[0]),\r\n                    htmlPopup = $('#mp-blog-new-post-popup'),\r\n                    url       = form.attr('action');\r\n\r\n                $.ajax({\r\n                    url: url,\r\n                    type: \"post\",\r\n                    data: formData,\r\n                    cache: false,\r\n                    contentType: false,\r\n                    processData: false,\r\n                    showLoader: true,\r\n                    success: function (result) {\r\n                        htmlPopup.data('mageModal').closeModal();\r\n                        if (result.status === 1) {\r\n                            setTimeout(function () {\r\n                                location.reload();\r\n                            }, 500);\r\n                        }\r\n                    }\r\n                });\r\n            }\r\n        }\r\n    );\r\n\r\n    return $.mageplaza.mpBlogPostAction;\r\n});\r\n","Mageplaza_Blog/js/comment.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license that is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category    Mageplaza\r\n * @package     Mageplaza_Blog\r\n * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)\r\n * @license     https://www.mageplaza.com/LICENSE.txt\r\n */\r\n\r\n\r\nrequire([\r\n    'jquery'\r\n], function ($) {\r\n    'use strict';\r\n\r\n    var cmtBox = $('.default-cmt__content__cmt-block__cmt-box__cmt-input'),\r\n        submitCmt = $('.default-cmt__content__cmt-block__cmt-box__cmt-btn__btn-submit'),\r\n        defaultCmt = $('ul.default-cmt__content__cmt-content:first'),\r\n        likeBtn = defaultCmt.find('.btn-like'),\r\n        replyBtn = defaultCmt.find('.btn-reply');\r\n\r\n    submitComment();\r\n    likeComment(likeBtn);\r\n    showReply(replyBtn);\r\n\r\n    $('li.default-cmt__content__cmt-content__cmt-row:first').css({'border-top': 'none'});\r\n    $('.default-cmt__cmt-login__btn-login').click(function () {\r\n        var socialPopup = $(\"[href$='social-login-popup']\");\r\n\r\n        if (socialPopup.length) {\r\n            socialPopup.first().trigger(\"click\");\r\n        } else {\r\n            window.location.href = loginUrl;\r\n        }\r\n    });\r\n\r\n    /**\r\n     * Check the guest name and email input is valid\r\n     *\r\n     * @returns {boolean}\r\n     */\r\n    function checkGuestFormValidate() {\r\n        if (isLogged == 'No') {\r\n            return $(\"#default-cmt__content__cmt-block__guest-form\").valid();\r\n        }\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * The comment submit button action\r\n     */\r\n    function submitComment() {\r\n        submitCmt.click(function () {\r\n            $(\".default-cmt__content__cmt-block__cmt-box\").find('.messages').hide();\r\n            if (checkGuestFormValidate()) {\r\n                var cmtText = cmtBox.val();\r\n\r\n                if (cmtText.trim().length) {\r\n                    $('.default-cmt_loading').show();\r\n                    $(this).prop('disabled', true);\r\n                    var ajaxRequest = ajaxCommentActions(cmtText, submitCmt);\r\n                    ajaxRequest.done(function () {\r\n                        cmtBox.val('');\r\n                        $('.default-cmt_loading').hide();\r\n                        $(this).prop('disabled', false);\r\n                    }.bind(this));\r\n                } else {\r\n                    $('.default-cmt__content__cmt-block__cmt-box__cmt-input').parent().append(messengerBox.cmt_warning);\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    //like action\r\n    function likeComment(btn) {\r\n        btn.each(function () {\r\n            var likeEl = $(this);\r\n\r\n            likeEl.click(function () {\r\n                var cmtId = $(this).attr('data-cmt-id'),\r\n                    cmtRowContainer = $(this).closest('.default-cmt__content__cmt-content__cmt-row');\r\n                if (isLogged === 'Yes') {\r\n                    var likeCount = $(this).find('span').text();\r\n                    if ($(this).attr('click') === '1') {\r\n                        if ($(this).hasClass('mpblog-liked')) {\r\n                            $(this).css('color', '#333333');\r\n                            likeCount--;\r\n                            $(this).find('span').text((likeCount === 0) ? \"\" : likeCount);\r\n                            $(this).removeClass('mpblog-liked')\r\n\r\n                        } else {\r\n                            likeCount++;\r\n                            $(this).find('span').text(likeCount);\r\n                            $(this).css('color', likedColor);\r\n                            $(this).addClass('mpblog-liked')\r\n                        }\r\n                        $.ajax({\r\n                            type: \"POST\",\r\n                            url: window.location.href,\r\n                            data: {cmtId: cmtId},\r\n                            success: function (response) {\r\n                                if (response.status === 'ok') {\r\n                                    $(likeEl).attr('click', '1');\r\n                                } else if (response.status === 'error' && response.hasOwnProperty(error)) {\r\n                                    defaultCmt.append(response.error);\r\n                                }\r\n                            }\r\n                        });\r\n                    }\r\n                    $(this).attr('click', '0');\r\n\r\n                } else {\r\n                    cmtRowContainer.append(messengerBox.login_warning);\r\n                    jQuery.fn.fadeOutAndRemove = function (speed) {\r\n                        $(this).fadeOut(speed, function () {\r\n                            $(this).remove();\r\n                        })\r\n                    };\r\n                    var removeNotification = function () {\r\n                        $('.message.error.message-error').fadeOutAndRemove('normal');\r\n                    };\r\n                    setTimeout(removeNotification, 3000);\r\n                }\r\n\r\n            });\r\n        });\r\n    }\r\n\r\n    //show reply\r\n    function showReply(btn) {\r\n        btn.each(function () {\r\n\r\n            $(this).click(function () {\r\n                var cmtId = (typeof $(this).closest('.default-cmt__content__cmt-content__cmt-row').parent().parent().attr('data-cmt-id') !== 'undefined') ? $(this).closest('.default-cmt__content__cmt-content__cmt-row').parent().parent().attr('data-cmt-id') : $(this).attr('data-cmt-id'),\r\n                    inputCmtID = $(this).attr('data-cmt-id'),\r\n                    cmtRowCmt = $(\"div\").find('#cmt-row');\r\n                var cmtRowContainer = $(this).closest('.default-cmt__content__cmt-content__cmt-row');\r\n                if ($(\"li.cmt-row-\" + cmtId).find(\"ul\").length) {\r\n                    var cmtRowContainer = $(\"#cmt-id-\" + cmtId + \" ul:last-child\");\r\n                }\r\n                var cmtRow = cmtRowContainer.find('.row__' + inputCmtID);\r\n                var cmtName = $(\".username__\" + inputCmtID).text();\r\n\r\n                if (isLogged === 'Yes') {\r\n                    if (cmtRowCmt.length) {\r\n                        cmtRowCmt.toggle();\r\n                        $(\"#cmt-row\").remove();\r\n                    }\r\n                    if (cmtRow.length) {\r\n                        cmtRow.toggle();\r\n                        $(\"#cmt-row\").remove();\r\n                    } else {\r\n                        cmtRowContainer.append('<div id=\"cmt-row\" class=\"cmt-row__reply-row row row__' + inputCmtID + ' col-md-12\">' +\r\n                            '<div class=\"reply-form__form-input form-group col-xs-8 col-md-6\">' +\r\n                            '<label for=\"reply_cmt' + inputCmtID + '\"></label>' +\r\n                            '<input type=\"text\" id=\"reply_cmt' + inputCmtID + '\" class=\"form-group__input form-control\" placeholder=\"Press enter to submit reply\" value=\"' + cmtName + ' \" autofocus onfocus=\"this.setSelectionRange(1000,1001);\"/>' +\r\n                            '</div>' +\r\n                            '</div>');\r\n                        var input = $('#reply_cmt' + inputCmtID);\r\n                        input.closest('.form-group').append(\r\n                            $('.default-cmt__content__cmt-block__cmt-box__cmt-btn .default-cmt_loading').clone()\r\n                        );\r\n                        input.focus();\r\n                        submitReply(input, cmtId, cmtRowContainer);\r\n                    }\r\n                } else {\r\n                    cmtRowContainer.append(messengerBox.login_warning);\r\n                    jQuery.fn.fadeOutAndRemove = function (speed) {\r\n                        $(this).fadeOut(speed, function () {\r\n                            $(this).remove();\r\n                        })\r\n                    };\r\n                    var removeNotification = function () {\r\n                        $('.message.error.message-error').fadeOutAndRemove('normal');\r\n                    };\r\n                    setTimeout(removeNotification, 3000);\r\n                }\r\n            });\r\n        });\r\n    }\r\n\r\n    //submit reply\r\n    function submitReply(input, replyId, parentComment) {\r\n        input.keypress(function (e) {\r\n            var text = input.val();\r\n            if (text !== '') {\r\n                if (e.keyCode === 13) {\r\n                    input.siblings('.default-cmt_loading').show();\r\n                    input.prop('disabled', true);\r\n                    var ajaxRequest = ajaxCommentActions(text, input, true, replyId, parentComment);\r\n                    ajaxRequest.done(function () {\r\n                        input.closest('.cmt-row__reply-row').hide();\r\n                        input.siblings('.default-cmt_loading').hide();\r\n                        input.prop('disabled', false);\r\n                        $(\"#cmt-row\").remove();\r\n                    });\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    //submit comment actions\r\n    function ajaxCommentActions(cmtText, inputEl, checkReply, cmtId, parentComment) {\r\n        var isReply = (typeof checkReply !== 'undefined') ? 1 : 0,\r\n            replyId = (typeof cmtId !== 'undefined') ? cmtId : 0,\r\n            displayReply = (typeof checkReply !== 'undefined');\r\n        var guestName = $('#default-cmt__content__cmt-block__guest-box__name-input').val();\r\n        var guestEmail = $('#default-cmt__content__cmt-block__guest-box__email-input').val();\r\n        return $.ajax({\r\n            type: 'POST',\r\n            url: window.location.href,\r\n            // async: false,\r\n            data: {cmt_text: cmtText, isReply: isReply, replyId: replyId, guestName: guestName, guestEmail: guestEmail},\r\n            success: function (response) {\r\n                switch (response.status) {\r\n                    case 'duplicated':\r\n                        $('.default-cmt__content__cmt-block__cmt-box__cmt-input').parent().append(messengerBox.exist_email_warning);\r\n                        break;\r\n                    case 3:\r\n                        $('.default-cmt__content__cmt-block').prepend(messengerBox.comment_approve);\r\n                        break;\r\n                    case 1:\r\n                        displayComment(response, displayReply);\r\n                        inputEl.val('');\r\n                        break;\r\n                    case 'error':\r\n                        if (checkReply !== 'undefined') {\r\n                            parentComment.append(response.error);\r\n                        } else {\r\n                            defaultCmt.append(response.error);\r\n                        }\r\n                        break;\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    // display comment\r\n    function displayComment(cmt, isReply) {\r\n        function htmlComment(text) {\r\n            var html = '';\r\n            var sub = text.split(\"\\n\");\r\n            for (var i = 0; i < sub.length; i++) {\r\n                html += '<p>' + sub[i] + '</p>';\r\n            }\r\n            return html;\r\n        }\r\n        var cmtRow = '<li style=\"width: 100%\" id=\"cmt-id-' + cmt.cmt_id + '\" class=\"default-cmt__content__cmt-content__cmt-row cmt-row-' + cmt.cmt_id + ' cmt-row col-m-12 '\r\n            + (isReply ? ('reply-row') : '') + '\" data-cmt-id=\"' + cmt.cmt_id + '\"' + (isReply ? ('data-reply-id=\"' + cmt.reply_cmt + '\"') : '')\r\n            + '> <div class=\"cmt-row__cmt-username\"> <span class=\"cmt-row__cmt-username username username__' + cmt.cmt_id + '\">' + cmt.user_cmt\r\n            + '</span> </div> <div class=\"cmt-row__cmt-content\"> <p>' + htmlComment(cmt.cmt_text)\r\n            + '</p> </div> <div class=\"cmt-row__cmt-interactions interactions\"> <div class=\"interactions__btn-actions\"> <a class=\"interactions__btn-actions action btn-like mpblog-like\" data-cmt-id=\"'\r\n            + cmt.cmt_id + '\" click=\"1\"><i class=\"fa fa-thumbs-up\" aria-hidden=\"true\" style=\"margin-right: 3px\"></i><span class=\"count-like__like-text\"></span></a> <a class=\"interactions__btn-actions action btn-reply\" data-cmt-id=\"'\r\n            + cmt.cmt_id + '\">' + reply + '</a>  </div> <div class=\"interactions__cmt-createdat\"> <span>' + cmt.created_at + '</span> </div> </div> </li>';\r\n\r\n        if (isReply) {\r\n            var replyCmtId = cmt.reply_cmt;\r\n            var replyCmt = defaultCmt.find('.default-cmt__content__cmt-content__cmt-row');\r\n\r\n            replyCmt.each(function () {\r\n                var cmtEl = $(this);\r\n                if (cmtEl.attr('data-cmt-id') === replyCmtId) {\r\n                    var replyList = cmtEl.find('ul.default-cmt__content__cmt-content:first');\r\n\r\n                    if (!replyList.length) {\r\n                        cmtRow = $('<ul class=\"default-cmt__content__cmt-content row\">' + cmtRow + '</ul>');\r\n                        cmtEl.append(cmtRow);\r\n\r\n                        likeComment(cmtRow.find('.btn-like'));\r\n                        showReply(cmtRow.find('.btn-reply'));\r\n                    } else {\r\n                        cmtRow = $(cmtRow);\r\n                        replyList.append(cmtRow);\r\n\r\n                        likeComment(cmtRow.find('.btn-like'));\r\n                        showReply(cmtRow.find('.btn-reply'));\r\n\r\n                    }\r\n\r\n                    return false;\r\n                }\r\n            });\r\n        } else {\r\n            cmtRow = $(cmtRow);\r\n            defaultCmt.append(cmtRow);\r\n\r\n            likeComment(cmtRow.find('.btn-like'));\r\n            showReply(cmtRow.find('.btn-reply'));\r\n        }\r\n    }\r\n});","Mageplaza_Blog/js/helpful-rate.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license that is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category    Mageplaza\r\n * @package     Mageplaza_Blog\r\n * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)\r\n * @license     https://www.mageplaza.com/LICENSE.txt\r\n */\r\ndefine([\r\n    'jquery'\r\n], function ($) {\r\n    'use strict';\r\n\r\n    $.widget('mageplaza.mpBlogHelpfulRate', {\r\n            options: {\r\n                url: '',\r\n                post_id: '',\r\n                mode: ''\r\n            },\r\n            _create: function () {\r\n                var post_id   = this.options.post_id,\r\n                    url       = this.options.url,\r\n                    self      = this,\r\n                    subPostId = {};\r\n\r\n                if (self.options.mode === 1) {\r\n                    $.ajax({\r\n                        url: url,\r\n                        type: \"post\",\r\n                        data: {\r\n                            post_id: post_id,\r\n                            action: '3',\r\n                            mode: self.options.mode\r\n                        },\r\n                        showLoader: false,\r\n                        success: function (response) {\r\n                            if (response.status === 0) {\r\n                                self.disableReview(response.action);\r\n                            }\r\n                        }\r\n                    });\r\n                } else if (JSON.parse(self.getCookie('mpblog_post_data'))) {\r\n                    subPostId = JSON.parse(self.getCookie('mpblog_post_data'));\r\n                    if (typeof subPostId[post_id] !== \"undefined\") {\r\n                        self.disableReview(subPostId[post_id].type);\r\n                    }\r\n                }\r\n\r\n                $('#mp-blog-review div').each(function () {\r\n                    var el = this;\r\n\r\n\r\n                    $(el).on('click', function () {\r\n                        var action         = 0,\r\n                            currentPostIds = {},\r\n                            likeId         = 0;\r\n\r\n                        if (JSON.parse(self.getCookie('mpblog_post_data'))) {\r\n                            currentPostIds = JSON.parse(self.getCookie('mpblog_post_data'));\r\n                        }\r\n\r\n                        if ($(this).hasClass('mp-blog-like')) {\r\n                            action = 1;\r\n                        }\r\n\r\n                        if (typeof currentPostIds[post_id] !== \"undefined\" && self.options.mode === 0) {\r\n                            likeId = currentPostIds[post_id].likeId;\r\n                            self.enableReview(currentPostIds[post_id].type);\r\n                            if (action === currentPostIds[post_id].type) {\r\n                                delete currentPostIds[post_id];\r\n                                document.cookie = 'mpblog_post_data = ' + JSON.stringify(currentPostIds);\r\n                            } else {\r\n                                currentPostIds[post_id].type = action;\r\n                                self.disableReview(action);\r\n                            }\r\n                        }\r\n                        $.ajax({\r\n                            url: url,\r\n                            type: \"post\",\r\n                            data: {\r\n                                post_id: post_id,\r\n                                action: action,\r\n                                mode: self.options.mode,\r\n                                likeId: likeId\r\n                            },\r\n                            showLoader: true,\r\n                            success: function (response) {\r\n                                var storedPostIds,\r\n                                    jsonStringIds;\r\n\r\n                                if (response['postLike']\r\n                                    && self.options.mode === 0 && typeof currentPostIds[post_id] === \"undefined\") {\r\n                                    storedPostIds   =\r\n                                        self.receiveCookiePostIds(post_id, action, response['postLike'], self);\r\n                                    jsonStringIds   = JSON.stringify(storedPostIds);\r\n                                    document.cookie = 'mpblog_post_data = ' + jsonStringIds;\r\n                                }\r\n\r\n                                if (response['status']) {\r\n                                    if (response[\"sumLike\"]) {\r\n                                        $('#mp-blog-review .mp-blog-like .mp-blog-view')\r\n                                        .text('(' + response[\"sumLike\"] + ')');\r\n                                    } else {\r\n                                        $('#mp-blog-review .mp-blog-like .mp-blog-view')\r\n                                        .text('');\r\n                                    }\r\n                                    if (response[\"sumDislike\"]) {\r\n                                        $('#mp-blog-review .mp-blog-dislike .mp-blog-view')\r\n                                        .text('(' + response[\"sumDislike\"] + ')');\r\n                                    } else {\r\n                                        $('#mp-blog-review .mp-blog-dislike .mp-blog-view')\r\n                                        .text('');\r\n                                    }\r\n                                }\r\n\r\n                                if (response['status']) {\r\n                                    self.enableAllReview();\r\n                                    if (response['postLike']) {\r\n                                        self.disableReview(action);\r\n                                    }\r\n                                }\r\n\r\n                                $('html, body').animate({\r\n                                    scrollTop: $('body').offset().top\r\n                                }, 500);\r\n                            }\r\n                        });\r\n\r\n                    });\r\n                });\r\n            },\r\n            disableReview: function (action) {\r\n                if ('' + action === '1') {\r\n                    $('.mp-blog-like').css('background-color', '#658259');\r\n\r\n                } else {\r\n                    $('.mp-blog-dislike').css('background-color', '#9a6464');\r\n                }\r\n            },\r\n            enableReview: function (action) {\r\n                if ('' + action === '1') {\r\n                    $('.mp-blog-like').css('background-color', '#6AA84F');\r\n\r\n                } else {\r\n                    $('.mp-blog-dislike').css('background-color', '#EC3A3C');\r\n                }\r\n            },\r\n            enableAllReview: function () {\r\n                $('.mp-blog-like').css('background-color', '#6AA84F');\r\n                $('.mp-blog-dislike').css('background-color', '#EC3A3C');\r\n\r\n            },\r\n            getCookie: function (name) {\r\n                var v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');\r\n\r\n                return v ? v[2] : null;\r\n            },\r\n            receiveCookiePostIds: function (postId, action, likeId, self) {\r\n                var postData        = {\r\n                        id: postId,\r\n                        type: action,\r\n                        likeId: likeId\r\n                    },\r\n                    receivedJsonStr = self.getCookie('mpblog_post_data'),\r\n                    postIds         = JSON.parse(receivedJsonStr);\r\n\r\n                if (postIds == null) {\r\n                    postIds = {};\r\n                }\r\n                if (typeof postIds[postId] !== \"undefined\") {\r\n\r\n                    return postIds;\r\n                }\r\n                postIds[postId] = postData;\r\n\r\n                return postIds;\r\n            }\r\n        }\r\n    );\r\n\r\n    return $.mageplaza.mpBlogHelpfulRate;\r\n});\r\n","Mageplaza_Blog/js/managePost.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license that is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category    Mageplaza\r\n * @package     Mageplaza_Blog\r\n * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)\r\n * @license     https://www.mageplaza.com/LICENSE.txt\r\n */\r\ndefine([\r\n    'jquery',\r\n    'mage/translate',\r\n    'underscore',\r\n    'Magento_Ui/js/modal/modal',\r\n    'uiRegistry',\r\n    'moment',\r\n    \"Mageplaza_Blog/js/get-editor\"\r\n], function ($, $t, _, modal, registry, moment, editor) {\r\n    'use strict';\r\n\r\n    $.widget('mageplaza.mpBlogManagePost', {\r\n            options: {\r\n                deleteUrl: '',\r\n                basePubUrl: '',\r\n                postDatas: {},\r\n                editorVersion: '',\r\n                magentoVersion: ''\r\n            },\r\n            _create: function () {\r\n                var self      = this,\r\n                    htmlPopup = $('#mp-blog-new-post-popup');\r\n\r\n                $('.mp-blog-new-post button').on('click', function () {\r\n                    self._AddNewPost(self, htmlPopup);\r\n                });\r\n\r\n                $('.mpblog-post-edit').on('click', function () {\r\n                    self._EditPost(self, this, htmlPopup);\r\n                });\r\n\r\n                $('.mpblog-post-duplicate').on('click', function () {\r\n                    self._DuplicatePost(self, this, htmlPopup);\r\n                });\r\n\r\n                $('.mpblog-post-delete').on('click', function () {\r\n                    self._DeletePost(self, this);\r\n                });\r\n            },\r\n            _AddNewPost: function (self, htmlPopup) {\r\n                var options = {\r\n                    'type': 'popup',\r\n                    'title': $t('Add New Post'),\r\n                    'responsive': true,\r\n                    'innerScroll': true,\r\n                    'buttons': []\r\n                };\r\n\r\n                self._resetForm('');\r\n                self._openPopup(options, htmlPopup, self);\r\n            },\r\n            _resetForm: function (postContent) {\r\n                var iframe = document.getElementById('post_content_ifr');\r\n\r\n                $('#mp_blog_post_form').trigger(\"reset\");\r\n                $('#short_description').empty();\r\n                $('#post_content').empty();\r\n                $('#post_id').removeAttr('value');\r\n\r\n                if (iframe){\r\n                    iframe.contentWindow.document.open();\r\n                    iframe.contentWindow.document.write(postContent);\r\n                    iframe.contentWindow.document.close();\r\n                }\r\n\r\n                $('.mp-field .mp-image-link').remove();\r\n                registry.get('customCategory').value('');\r\n                registry.get('customTag').value('');\r\n                registry.get('customTopic').value('');\r\n            },\r\n            _EditPost: function (self, click, htmlPopup) {\r\n                var postId   = $(click).parent().data('postid'),\r\n                    postData = self.options.postDatas[postId],\r\n                    pubUrl   = self.options.basePubUrl,\r\n                    options  = {\r\n                        'type': 'popup',\r\n                        'title': $t('Edit Post'),\r\n                        'responsive': true,\r\n                        'innerScroll': true,\r\n                        'buttons': []\r\n                    };\r\n\r\n                if (htmlPopup.find('#mp_blog_post_form [name=\"name\"]').length > 0) {\r\n                    self._resetForm(postData['post_content']);\r\n                }\r\n                self._openPopup(options, htmlPopup, self);\r\n                self._setPopupFormData(postData, pubUrl, htmlPopup);\r\n            },\r\n            _setPopupFormData: function(postData, pubUrl, htmlPopup){\r\n                _.each(postData, function (value, name) {\r\n                    var field = htmlPopup.find('#mp_blog_post_form [name=\"' + name + '\"]'),\r\n                        imageEL,\r\n                        deleteEL,\r\n                        date;\r\n\r\n                    if (field.is('[type=\"file\"]') && value) {\r\n                        imageEL = '<a class=\"mp-image-link\" href=\"' + pubUrl + 'mageplaza/blog/post/' + value\r\n                            + '\" onclick=\"imagePreview(\\'post_image_image\\'); return false;\" >' +\r\n                            '<img src=\"' + pubUrl + 'mageplaza/blog/post/' + value + '\" id=\"post_image_image\"' +\r\n                            ' title=\"' + value + '\" alt=\"' + value + '\" height=\"22\" width=\"22\"' +\r\n                            ' class=\"small-image-preview v-middle\">' +\r\n                            '</a>';\r\n                        field.parent().prepend(imageEL);\r\n                        deleteEL =  '<span class=\"delete-image\">'\r\n                            + '<input style=\"width: 8%\" type=\"checkbox\" name=\"image[delete]\"'\r\n                            + ' value=\"1\" class=\"checkbox\" id=\"post_image_delete\">'\r\n                            + '<label for=\"post_image_delete\"> Delete Image</label>'\r\n                            + '</span>';\r\n                        if (!field.parent().find('.delete-image').lenth) {\r\n                            field.parent().append(deleteEL);\r\n                        }\r\n                    } else if (field.is('[type=\"datetime-local\"]')) {\r\n                        date = moment(value).format(\"YYYY-MM-DDTkk:mm\");\r\n                        field.val(date);\r\n                    } else if (field.is('input') || field.is('select')) {\r\n                        field.val(value);\r\n                    } else if (field.is('textarea')) {\r\n                        field.html(value);\r\n                    }\r\n                    if (name === 'category_ids') {\r\n                        registry.get('customCategory').value(value);\r\n                    }\r\n                    if (name === 'tag_ids') {\r\n                        registry.get('customTag').value(value);\r\n                    }\r\n                    if (name === 'topic_ids') {\r\n                        registry.get('customTopic').value(value);\r\n                    }\r\n                });\r\n            },\r\n            _DuplicatePost: function (self, click, htmlPopup) {\r\n                var postId   = $(click).parent().data('postid'),\r\n                    postData = self.options.postDatas[postId],\r\n                    pubUrl   = self.options.basePubUrl,\r\n                    options  = {\r\n                        'type': 'popup',\r\n                        'title': $t('Duplicate Post'),\r\n                        'responsive': true,\r\n                        'innerScroll': true,\r\n                        'buttons': []\r\n                    };\r\n\r\n                if (htmlPopup.find('#mp_blog_post_form [name=\"name\"]').length > 0) {\r\n                    self._resetForm(postData['post_content']);\r\n                }\r\n                self._openPopup(options, htmlPopup, self);\r\n                self._setPopupFormData(postData, pubUrl, htmlPopup);\r\n                $('#post_id').removeAttr('value');\r\n                $('#image').parent().append('<input type=\"hidden\" name=\"image\" value=\"'+postData[\"image\"]+'\" />');\r\n            },\r\n            _DeletePost: function (self, widget) {\r\n                var url = self.options.deleteUrl,\r\n                    id = $(widget).parent().data('postid');\r\n\r\n                $.ajax({\r\n                    url: url,\r\n                    type: \"post\",\r\n                    data: {\r\n                        post_id: id\r\n                    },\r\n                    showLoader: true,\r\n                    success: function (result) {\r\n                        if (result['status'] === 1){\r\n                            $('.post-list-item[data-post-id=\"'+result['post_id']+'\"]').remove();\r\n                        }\r\n                    },\r\n                    complete: function () {\r\n\r\n                    }\r\n                });\r\n            },\r\n            _openPopup: function (options, htmlPopup, self) {\r\n                var popupModal,\r\n                    editorVersion = self.options.editorVersion,\r\n                    magentoVersion = self.options.magentoVersion;\r\n\r\n                popupModal = modal(options, htmlPopup);\r\n                popupModal.openModal();\r\n                $('#mp_blog_post_form').trigger('contentUpdated');\r\n\r\n                editor.config('post_content', editorVersion, magentoVersion);\r\n            }\r\n        }\r\n    );\r\n\r\n    return $.mageplaza.mpBlogManagePost;\r\n});\r\n","Mageplaza_Blog/js/get-editor.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license that is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category    Mageplaza\r\n * @package     Mageplaza_Blog\r\n * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)\r\n * @license     https://www.mageplaza.com/LICENSE.txt\r\n */\r\ndefine([\r\n    'jquery',\r\n    \"mage/adminhtml/events\",\r\n    \"mage/adminhtml/wysiwyg/tiny_mce/setup\"\r\n], function ($) {\r\n    'use strict';\r\n\r\n    return {\r\n        config: function (nameEL, versionEditor, versionMagento, width) {\r\n            var wysiwygcompany_description,\r\n                config = {},\r\n                editor;\r\n\r\n            if (typeof width === 'undefined') {\r\n                width = '99%';\r\n            }\r\n\r\n            if (versionMagento === \"2\") {\r\n                $.extend(config, {\r\n                    settings: {\r\n                        theme_advanced_buttons1: 'bold,italic,|,justifyleft,justifycenter,justifyright,|,' +\r\n                            'fontselect,fontsizeselect,|,forecolor,backcolor,|,link,unlink,image,|,' +\r\n                            'bullist,numlist,|,code',\r\n                        theme_advanced_buttons2: null,\r\n                        theme_advanced_buttons3: null,\r\n                        theme_advanced_buttons4: null\r\n                    }\r\n                });\r\n                editor = new tinyMceWysiwygSetup(\r\n                    nameEL,\r\n                    config\r\n                );\r\n                editor.turnOn();\r\n                $('#' + nameEL).addClass('wysiwyg-editor').data('wysiwygEditor', editor);\r\n            } else if (versionEditor === \"4\") {\r\n                wysiwygcompany_description = new wysiwygSetup(nameEL, {\r\n                    \"width\": width,\r\n                    \"height\": \"200px\",\r\n                    \"plugins\": [{\"name\": \"image\"}],\r\n                    \"tinymce4\": {\r\n                        \"toolbar\": \"formatselect | bold italic underline | alignleft aligncenter alignright |\" +\r\n                            \" bullist numlist | link table charmap\",\r\n                        \"plugins\": \"advlist autolink lists link charmap media noneditable\" +\r\n                            \" table contextmenu paste code help table\"\r\n                    }\r\n                });\r\n                wysiwygcompany_description.setup(\"exact\");\r\n            } else {\r\n                $.extend(config, {\r\n                    settings: {\r\n                        theme_advanced_buttons1: 'bold,italic,|,justifyleft,justifycenter,justifyright,|,' +\r\n                            'fontselect,fontsizeselect,|,forecolor,backcolor,|,link,unlink,image,|,' +\r\n                            'bullist,numlist,|,code',\r\n                        theme_advanced_buttons2: null,\r\n                        theme_advanced_buttons3: null,\r\n                        theme_advanced_buttons4: null\r\n                    },\r\n                    tinymce : {\r\n                        content_css : null\r\n                    }\r\n                });\r\n                editor = new wysiwygSetup(\r\n                    nameEL,\r\n                    config\r\n                );\r\n                editor.setup(\"exact\");\r\n                $('#' + nameEL).addClass('wysiwyg-editor').data('wysiwygEditor', editor);\r\n            }\r\n        }\r\n    };\r\n});","Mageplaza_Blog/js/categorytree.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license that is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category    Mageplaza\r\n * @package     Mageplaza_Blog\r\n * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)\r\n * @license     https://www.mageplaza.com/LICENSE.txt\r\n */\r\n\r\ndefine([\r\n        'jquery'\r\n    ], function ($) {\r\n    \"use strict\";\r\n\r\n        var parentCategory = $(\".mp-blog-expand-tree-2\");\r\n        var childCategory  = $(\".mp-blog-expand-tree-3\");\r\n\r\n        parentCategory.click(function () {\r\n            if ($(this).hasClass(\"mp-blog-expand-tree-2\")) {\r\n                $(this).parent().find(\".category-level3\").slideDown(\"fast\");\r\n                $(this).removeClass(\"mp-blog-expand-tree-2 fa fa-plus-square-o\")\r\n                .addClass(\"mp-blog-narrow-tree-2 fa fa-minus-square-o\");\r\n            } else {\r\n                $(this).parent().find(\".category-level4\").slideUp(\"fast\");\r\n                $(this).parent().find(\".category-level3\").slideUp(\"fast\");\r\n                $(this).removeClass(\"mp-blog-narrow-tree-2 fa fa-minus-square-o\")\r\n                .addClass(\"mp-blog-expand-tree-2 fa fa-plus-square-o\");\r\n                $(this).parent().find(\".mp-blog-narrow-tree-3\")\r\n                .removeClass(\"mp-blog-narrow-tree-3 fa fa-minus-square-o\")\r\n                .addClass(\"mp-blog-expand-tree-3 fa fa-plus-square-o\");\r\n            }\r\n\r\n        });\r\n\r\n        childCategory.click(function () {\r\n            if ($(this).hasClass(\"mp-blog-expand-tree-3\")) {\r\n                $(this).parent().find(\".category-level4\").slideDown(\"fast\");\r\n                $(this).removeClass(\"mp-blog-expand-tree-3 fa fa-plus-square-o\")\r\n                .addClass(\"mp-blog-narrow-tree-3 fa fa-minus-square-o\");\r\n            } else {\r\n                $(this).parent().find(\".category-level4\").slideUp(\"fast\");\r\n                $(this).removeClass(\"mp-blog-narrow-tree-3 fa fa-minus-square-o\")\r\n                .addClass(\"mp-blog-expand-tree-3 fa fa-plus-square-o\");\r\n            }\r\n        });\r\n    }\r\n);","fotorama/fotorama.js":"/*!\n * Fotorama 4.6.4 | http://fotorama.io/license/\n */\nfotoramaVersion = '4.6.4';\n(function (window, document, location, $, undefined) {\n    \"use strict\";\n    var _fotoramaClass = 'fotorama',\n        _fullscreenClass = 'fotorama__fullscreen',\n\n        wrapClass = _fotoramaClass + '__wrap',\n        wrapCss2Class = wrapClass + '--css2',\n        wrapCss3Class = wrapClass + '--css3',\n        wrapVideoClass = wrapClass + '--video',\n        wrapFadeClass = wrapClass + '--fade',\n        wrapSlideClass = wrapClass + '--slide',\n        wrapNoControlsClass = wrapClass + '--no-controls',\n        wrapNoShadowsClass = wrapClass + '--no-shadows',\n        wrapPanYClass = wrapClass + '--pan-y',\n        wrapRtlClass = wrapClass + '--rtl',\n        wrapOnlyActiveClass = wrapClass + '--only-active',\n        wrapNoCaptionsClass = wrapClass + '--no-captions',\n        wrapToggleArrowsClass = wrapClass + '--toggle-arrows',\n\n        stageClass = _fotoramaClass + '__stage',\n        stageFrameClass = stageClass + '__frame',\n        stageFrameVideoClass = stageFrameClass + '--video',\n        stageShaftClass = stageClass + '__shaft',\n\n        grabClass = _fotoramaClass + '__grab',\n        pointerClass = _fotoramaClass + '__pointer',\n\n        arrClass = _fotoramaClass + '__arr',\n        arrDisabledClass = arrClass + '--disabled',\n        arrPrevClass = arrClass + '--prev',\n        arrNextClass = arrClass + '--next',\n\n        navClass = _fotoramaClass + '__nav',\n        navWrapClass = navClass + '-wrap',\n        navShaftClass = navClass + '__shaft',\n        navShaftVerticalClass = navWrapClass + '--vertical',\n        navShaftListClass = navWrapClass + '--list',\n        navShafthorizontalClass = navWrapClass + '--horizontal',\n        navDotsClass = navClass + '--dots',\n        navThumbsClass = navClass + '--thumbs',\n        navFrameClass = navClass + '__frame',\n\n        fadeClass = _fotoramaClass + '__fade',\n        fadeFrontClass = fadeClass + '-front',\n        fadeRearClass = fadeClass + '-rear',\n\n        shadowClass = _fotoramaClass + '__shadow',\n        shadowsClass = shadowClass + 's',\n        shadowsLeftClass = shadowsClass + '--left',\n        shadowsRightClass = shadowsClass + '--right',\n        shadowsTopClass = shadowsClass + '--top',\n        shadowsBottomClass = shadowsClass + '--bottom',\n\n        activeClass = _fotoramaClass + '__active',\n        selectClass = _fotoramaClass + '__select',\n\n        hiddenClass = _fotoramaClass + '--hidden',\n\n        fullscreenClass = _fotoramaClass + '--fullscreen',\n        fullscreenIconClass = _fotoramaClass + '__fullscreen-icon',\n\n        errorClass = _fotoramaClass + '__error',\n        loadingClass = _fotoramaClass + '__loading',\n        loadedClass = _fotoramaClass + '__loaded',\n        loadedFullClass = loadedClass + '--full',\n        loadedImgClass = loadedClass + '--img',\n\n        grabbingClass = _fotoramaClass + '__grabbing',\n\n        imgClass = _fotoramaClass + '__img',\n        imgFullClass = imgClass + '--full',\n\n        thumbClass = _fotoramaClass + '__thumb',\n        thumbArrLeft = thumbClass + '__arr--left',\n        thumbArrRight = thumbClass + '__arr--right',\n        thumbBorderClass = thumbClass + '-border',\n\n        htmlClass = _fotoramaClass + '__html',\n\n        videoContainerClass = _fotoramaClass + '-video-container',\n        videoClass = _fotoramaClass + '__video',\n        videoPlayClass = videoClass + '-play',\n        videoCloseClass = videoClass + '-close',\n\n\n        horizontalImageClass = _fotoramaClass + '_horizontal_ratio',\n        verticalImageClass = _fotoramaClass + '_vertical_ratio',\n        fotoramaSpinnerClass = _fotoramaClass + '__spinner',\n        spinnerShowClass = fotoramaSpinnerClass + '--show';\n    var JQUERY_VERSION = $ && $.fn.jquery.split('.');\n\n    if (!JQUERY_VERSION\n        || JQUERY_VERSION[0] < 1\n        || (JQUERY_VERSION[0] == 1 && JQUERY_VERSION[1] < 8)) {\n        throw 'Fotorama requires jQuery 1.8 or later and will not run without it.';\n    }\n\n    var _ = {};\n    /* Modernizr 2.8.3 (Custom Build) | MIT & BSD\n     * Build: http://modernizr.com/download/#-csstransforms3d-csstransitions-touch-prefixed\n     */\n\n    var Modernizr = (function (window, document, undefined) {\n        var version = '2.8.3',\n            Modernizr = {},\n\n\n            docElement = document.documentElement,\n\n            mod = 'modernizr',\n            modElem = document.createElement(mod),\n            mStyle = modElem.style,\n            inputElem,\n\n\n            toString = {}.toString,\n\n            prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),\n\n\n            omPrefixes = 'Webkit Moz O ms',\n\n            cssomPrefixes = omPrefixes.split(' '),\n\n            domPrefixes = omPrefixes.toLowerCase().split(' '),\n\n\n            tests = {},\n            inputs = {},\n            attrs = {},\n\n            classes = [],\n\n            slice = classes.slice,\n\n            featureName,\n\n\n            injectElementWithStyles = function (rule, callback, nodes, testnames) {\n\n                var style, ret, node, docOverflow,\n                    div = document.createElement('div'),\n                    body = document.body,\n                    fakeBody = body || document.createElement('body');\n\n                if (parseInt(nodes, 10)) {\n                    while (nodes--) {\n                        node = document.createElement('div');\n                        node.id = testnames ? testnames[nodes] : mod + (nodes + 1);\n                        div.appendChild(node);\n                    }\n                }\n\n                style = ['&#173;', '<style id=\"s', mod, '\">', rule, '</style>'].join('');\n                div.id = mod;\n                (body ? div : fakeBody).innerHTML += style;\n                fakeBody.appendChild(div);\n                if (!body) {\n                    fakeBody.style.background = '';\n                    fakeBody.style.overflow = 'hidden';\n                    docOverflow = docElement.style.overflow;\n                    docElement.style.overflow = 'hidden';\n                    docElement.appendChild(fakeBody);\n                }\n\n                ret = callback(div, rule);\n                if (!body) {\n                    fakeBody.parentNode.removeChild(fakeBody);\n                    docElement.style.overflow = docOverflow;\n                } else {\n                    div.parentNode.removeChild(div);\n                }\n\n                return !!ret;\n\n            },\n            _hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;\n\n        if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) {\n            hasOwnProp = function (object, property) {\n                return _hasOwnProperty.call(object, property);\n            };\n        }\n        else {\n            hasOwnProp = function (object, property) {\n                return ((property in object) && is(object.constructor.prototype[property], 'undefined'));\n            };\n        }\n\n\n        if (!Function.prototype.bind) {\n            Function.prototype.bind = function bind(that) {\n\n                var target = this;\n\n                if (typeof target != \"function\") {\n                    throw new TypeError();\n                }\n\n                var args = slice.call(arguments, 1),\n                    bound = function () {\n\n                        if (this instanceof bound) {\n\n                            var F = function () {\n                            };\n                            F.prototype = target.prototype;\n                            var self = new F();\n\n                            var result = target.apply(\n                                self,\n                                args.concat(slice.call(arguments))\n                            );\n                            if (Object(result) === result) {\n                                return result;\n                            }\n                            return self;\n\n                        } else {\n\n                            return target.apply(\n                                that,\n                                args.concat(slice.call(arguments))\n                            );\n\n                        }\n\n                    };\n\n                return bound;\n            };\n        }\n\n        function setCss(str) {\n            mStyle.cssText = str;\n        }\n\n        function setCssAll(str1, str2) {\n            return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));\n        }\n\n        function is(obj, type) {\n            return typeof obj === type;\n        }\n\n        function contains(str, substr) {\n            return !!~('' + str).indexOf(substr);\n        }\n\n        function testProps(props, prefixed) {\n            for (var i in props) {\n                var prop = props[i];\n                if (!contains(prop, \"-\") && mStyle[prop] !== undefined) {\n                    return prefixed == 'pfx' ? prop : true;\n                }\n            }\n            return false;\n        }\n\n        function testDOMProps(props, obj, elem) {\n            for (var i in props) {\n                var item = obj[props[i]];\n                if (item !== undefined) {\n\n                    if (elem === false) return props[i];\n\n                    if (is(item, 'function')) {\n                        return item.bind(elem || obj);\n                    }\n\n                    return item;\n                }\n            }\n            return false;\n        }\n\n        function testPropsAll(prop, prefixed, elem) {\n\n            var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),\n                props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');\n\n            if (is(prefixed, \"string\") || is(prefixed, \"undefined\")) {\n                return testProps(props, prefixed);\n\n            } else {\n                props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');\n                return testDOMProps(props, prefixed, elem);\n            }\n        }\n\n        tests['touch'] = function () {\n            var bool;\n\n            if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {\n                bool = true;\n            } else {\n                injectElementWithStyles(['@media (', prefixes.join('touch-enabled),('), mod, ')', '{#modernizr{top:9px;position:absolute}}'].join(''), function (node) {\n                    bool = node.offsetTop === 9;\n                });\n            }\n\n            return bool;\n        };\n        tests['csstransforms3d'] = function () {\n\n            var ret = !!testPropsAll('perspective');\n\n            if (ret && 'webkitPerspective' in docElement.style) {\n\n                injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function (node, rule) {\n                    ret = node.offsetLeft === 9 && node.offsetHeight === 3;\n                });\n            }\n            return ret;\n        };\n\n\n        tests['csstransitions'] = function () {\n            return testPropsAll('transition');\n        };\n\n\n        for (var feature in tests) {\n            if (hasOwnProp(tests, feature)) {\n                featureName = feature.toLowerCase();\n                Modernizr[featureName] = tests[feature]();\n\n                classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);\n            }\n        }\n\n\n        Modernizr.addTest = function (feature, test) {\n            if (typeof feature == 'object') {\n                for (var key in feature) {\n                    if (hasOwnProp(feature, key)) {\n                        Modernizr.addTest(key, feature[key]);\n                    }\n                }\n            } else {\n\n                feature = feature.toLowerCase();\n\n                if (Modernizr[feature] !== undefined) {\n                    return Modernizr;\n                }\n\n                test = typeof test == 'function' ? test() : test;\n\n                if (typeof enableClasses !== \"undefined\" && enableClasses) {\n                    docElement.className += ' ' + (test ? '' : 'no-') + feature;\n                }\n                Modernizr[feature] = test;\n\n            }\n\n            return Modernizr;\n        };\n\n\n        setCss('');\n        modElem = inputElem = null;\n\n\n        Modernizr._version = version;\n\n        Modernizr._prefixes = prefixes;\n        Modernizr._domPrefixes = domPrefixes;\n        Modernizr._cssomPrefixes = cssomPrefixes;\n\n\n        Modernizr.testProp = function (prop) {\n            return testProps([prop]);\n        };\n\n        Modernizr.testAllProps = testPropsAll;\n        Modernizr.testStyles = injectElementWithStyles;\n        Modernizr.prefixed = function (prop, obj, elem) {\n            if (!obj) {\n                return testPropsAll(prop, 'pfx');\n            } else {\n                return testPropsAll(prop, obj, elem);\n            }\n        };\n        return Modernizr;\n    })(window, document);\n\n    var fullScreenApi = {\n            ok: false,\n            is: function () {\n                return false;\n            },\n            request: function () {\n            },\n            cancel: function () {\n            },\n            event: '',\n            prefix: ''\n        },\n        browserPrefixes = 'webkit moz o ms khtml'.split(' ');\n\n// check for native support\n    if (typeof document.cancelFullScreen != 'undefined') {\n        fullScreenApi.ok = true;\n    } else {\n        // check for fullscreen support by vendor prefix\n        for (var i = 0, il = browserPrefixes.length; i < il; i++) {\n            fullScreenApi.prefix = browserPrefixes[i];\n            if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined') {\n                fullScreenApi.ok = true;\n                break;\n            }\n        }\n    }\n\n// update methods to do something useful\n    if (fullScreenApi.ok) {\n        fullScreenApi.event = fullScreenApi.prefix + 'fullscreenchange';\n        fullScreenApi.is = function () {\n            switch (this.prefix) {\n                case '':\n                    return document.fullScreen;\n                case 'webkit':\n                    return document.webkitIsFullScreen;\n                default:\n                    return document[this.prefix + 'FullScreen'];\n            }\n        };\n        fullScreenApi.request = function (el) {\n            return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen']();\n        };\n        fullScreenApi.cancel = function (el) {\n            if (!this.is()) {\n                return false;\n            }\n            return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen']();\n        };\n    }\n    /* Bez v1.0.10-g5ae0136\n     * http://github.com/rdallasgray/bez\n     *\n     * A plugin to convert CSS3 cubic-bezier co-ordinates to jQuery-compatible easing functions\n     *\n     * With thanks to Nikolay Nemshilov for clarification on the cubic-bezier maths\n     * See http://st-on-it.blogspot.com/2011/05/calculating-cubic-bezier-function.html\n     *\n     * Copyright 2011 Robert Dallas Gray. All rights reserved.\n     * Provided under the FreeBSD license: https://github.com/rdallasgray/bez/blob/master/LICENSE.txt\n     */\n    function bez(coOrdArray) {\n        var encodedFuncName = \"bez_\" + $.makeArray(arguments).join(\"_\").replace(\".\", \"p\");\n        if (typeof $['easing'][encodedFuncName] !== \"function\") {\n            var polyBez = function (p1, p2) {\n                var A = [null, null],\n                    B = [null, null],\n                    C = [null, null],\n                    bezCoOrd = function (t, ax) {\n                        C[ax] = 3 * p1[ax];\n                        B[ax] = 3 * (p2[ax] - p1[ax]) - C[ax];\n                        A[ax] = 1 - C[ax] - B[ax];\n                        return t * (C[ax] + t * (B[ax] + t * A[ax]));\n                    },\n                    xDeriv = function (t) {\n                        return C[0] + t * (2 * B[0] + 3 * A[0] * t);\n                    },\n                    xForT = function (t) {\n                        var x = t, i = 0, z;\n                        while (++i < 14) {\n                            z = bezCoOrd(x, 0) - t;\n                            if (Math.abs(z) < 1e-3) break;\n                            x -= z / xDeriv(x);\n                        }\n                        return x;\n                    };\n                return function (t) {\n                    return bezCoOrd(xForT(t), 1);\n                }\n            };\n            $['easing'][encodedFuncName] = function (x, t, b, c, d) {\n                return c * polyBez([coOrdArray[0], coOrdArray[1]], [coOrdArray[2], coOrdArray[3]])(t / d) + b;\n            }\n        }\n        return encodedFuncName;\n    }\n\n    var $WINDOW = $(window),\n        $DOCUMENT = $(document),\n        $HTML,\n        $BODY,\n\n        QUIRKS_FORCE = location.hash.replace('#', '') === 'quirks',\n        TRANSFORMS3D = Modernizr.csstransforms3d,\n        CSS3 = TRANSFORMS3D && !QUIRKS_FORCE,\n        COMPAT = TRANSFORMS3D || document.compatMode === 'CSS1Compat',\n        FULLSCREEN = fullScreenApi.ok,\n\n        MOBILE = navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i),\n        SLOW = !CSS3 || MOBILE,\n\n        MS_POINTER = navigator.msPointerEnabled,\n\n        WHEEL = \"onwheel\" in document.createElement(\"div\") ? \"wheel\" : document.onmousewheel !== undefined ? \"mousewheel\" : \"DOMMouseScroll\",\n\n        TOUCH_TIMEOUT = 250,\n        TRANSITION_DURATION = 300,\n\n        SCROLL_LOCK_TIMEOUT = 1400,\n\n        AUTOPLAY_INTERVAL = 5000,\n        MARGIN = 2,\n        THUMB_SIZE = 64,\n\n        WIDTH = 500,\n        HEIGHT = 333,\n\n        STAGE_FRAME_KEY = '$stageFrame',\n        NAV_DOT_FRAME_KEY = '$navDotFrame',\n        NAV_THUMB_FRAME_KEY = '$navThumbFrame',\n\n        AUTO = 'auto',\n\n        BEZIER = bez([.1, 0, .25, 1]),\n\n        MAX_WIDTH = 1200,\n\n        /**\n         * Number of thumbnails in slide. Calculated only on setOptions and resize.\n         * @type {number}\n         */\n        thumbsPerSlide = 1,\n\n        OPTIONS = {\n\n            /**\n             * Set width for gallery.\n             * Default value - width of first image\n             * Number - set value in px\n             * String - set value in quotes\n             *\n             */\n            width: null,\n\n            /**\n             * Set min-width for gallery\n             *\n             */\n            minwidth: null,\n\n            /**\n             * Set max-width for gallery\n             *\n             */\n            maxwidth: '100%',\n\n            /**\n             * Set height for gallery\n             * Default value - height of first image\n             * Number - set value in px\n             * String - set value in quotes\n             *\n             */\n            height: null,\n\n            /**\n             * Set min-height for gallery\n             *\n             */\n            minheight: null,\n\n            /**\n             * Set max-height for gallery\n             *\n             */\n            maxheight: null,\n\n            /**\n             * Set proportion ratio for gallery depends of image\n             *\n             */\n            ratio: null, // '16/9' || 500/333 || 1.5\n\n            margin: MARGIN,\n\n            nav: 'dots', // 'thumbs' || false\n            navposition: 'bottom', // 'top'\n            navwidth: null,\n            thumbwidth: THUMB_SIZE,\n            thumbheight: THUMB_SIZE,\n            thumbmargin: MARGIN,\n            thumbborderwidth: MARGIN,\n\n            allowfullscreen: false, // true || 'native'\n\n            transition: 'slide', // 'crossfade' || 'dissolve'\n            clicktransition: null,\n            transitionduration: TRANSITION_DURATION,\n\n            captions: true,\n\n            startindex: 0,\n\n            loop: false,\n\n            autoplay: false,\n            stopautoplayontouch: true,\n\n            keyboard: false,\n\n            arrows: true,\n            click: true,\n            swipe: false,\n            trackpad: false,\n\n            shuffle: false,\n\n            direction: 'ltr', // 'rtl'\n\n            shadows: true,\n\n            showcaption: true,\n\n            /**\n             * Set type of thumbnail navigation\n             */\n            navdir: 'horizontal',\n\n            /**\n             * Set configuration to show or hide arrows in thumb navigation\n             */\n            navarrows: true,\n\n            /**\n             * Set type of navigation. Can be thumbs or slides\n             */\n            navtype: 'thumbs'\n\n        },\n\n        KEYBOARD_OPTIONS = {\n            left: true,\n            right: true,\n            down: true,\n            up: true,\n            space: false,\n            home: false,\n            end: false\n        };\n\n    function noop() {\n    }\n\n    function minMaxLimit(value, min, max) {\n        return Math.max(isNaN(min) ? -Infinity : min, Math.min(isNaN(max) ? Infinity : max, value));\n    }\n\n    function readTransform(css, dir) {\n        return css.match(/ma/) && css.match(/-?\\d+(?!d)/g)[css.match(/3d/) ?\n                (dir === 'vertical' ? 13 : 12) : (dir === 'vertical' ? 5 : 4)\n                ]\n    }\n\n    function readPosition($el, dir) {\n        if (CSS3) {\n            return +readTransform($el.css('transform'), dir);\n        } else {\n            return +$el.css(dir === 'vertical' ? 'top' : 'left').replace('px', '');\n        }\n    }\n\n    function getTranslate(pos, direction) {\n        var obj = {};\n\n        if (CSS3) {\n\n            switch (direction) {\n                case 'vertical':\n                    obj.transform = 'translate3d(0, ' + (pos) + 'px,0)';\n                    break;\n                case 'list':\n                    break;\n                default :\n                    obj.transform = 'translate3d(' + (pos) + 'px,0,0)';\n                    break;\n            }\n        } else {\n            direction === 'vertical' ?\n                obj.top = pos :\n                obj.left = pos;\n        }\n        return obj;\n    }\n\n    function getDuration(time) {\n        return {'transition-duration': time + 'ms'};\n    }\n\n    function unlessNaN(value, alternative) {\n        return isNaN(value) ? alternative : value;\n    }\n\n    function numberFromMeasure(value, measure) {\n        return unlessNaN(+String(value).replace(measure || 'px', ''));\n    }\n\n    function numberFromPercent(value) {\n        return /%$/.test(value) ? numberFromMeasure(value, '%') : undefined;\n    }\n\n    function numberFromWhatever(value, whole) {\n        return unlessNaN(numberFromPercent(value) / 100 * whole, numberFromMeasure(value));\n    }\n\n    function measureIsValid(value) {\n        return (!isNaN(numberFromMeasure(value)) || !isNaN(numberFromMeasure(value, '%'))) && value;\n    }\n\n    function getPosByIndex(index, side, margin, baseIndex) {\n\n        return (index - (baseIndex || 0)) * (side + (margin || 0));\n    }\n\n    function getIndexByPos(pos, side, margin, baseIndex) {\n        return -Math.round(pos / (side + (margin || 0)) - (baseIndex || 0));\n    }\n\n    function bindTransitionEnd($el) {\n        var elData = $el.data();\n\n        if (elData.tEnd) return;\n\n        var el = $el[0],\n            transitionEndEvent = {\n                WebkitTransition: 'webkitTransitionEnd',\n                MozTransition: 'transitionend',\n                OTransition: 'oTransitionEnd otransitionend',\n                msTransition: 'MSTransitionEnd',\n                transition: 'transitionend'\n            };\n        addEvent(el, transitionEndEvent[Modernizr.prefixed('transition')], function (e) {\n            elData.tProp && e.propertyName.match(elData.tProp) && elData.onEndFn();\n        });\n        elData.tEnd = true;\n    }\n\n    function afterTransition($el, property, fn, time) {\n        var ok,\n            elData = $el.data();\n\n        if (elData) {\n            elData.onEndFn = function () {\n                if (ok) return;\n                ok = true;\n                clearTimeout(elData.tT);\n                fn();\n            };\n            elData.tProp = property;\n\n            // Passive call, just in case of fail of native transition-end event\n            clearTimeout(elData.tT);\n            elData.tT = setTimeout(function () {\n                elData.onEndFn();\n            }, time * 1.5);\n\n            bindTransitionEnd($el);\n        }\n    }\n\n\n    function stop($el, pos/*, _001*/) {\n        var dir = $el.navdir || 'horizontal';\n        if ($el.length) {\n            var elData = $el.data();\n            if (CSS3) {\n                $el.css(getDuration(0));\n                elData.onEndFn = noop;\n                clearTimeout(elData.tT);\n            } else {\n                $el.stop();\n            }\n            var lockedPos = getNumber(pos, function () {\n                return readPosition($el, dir);\n            });\n\n            $el.css(getTranslate(lockedPos, dir/*, _001*/));//.width(); // `.width()` for reflow\n            return lockedPos;\n        }\n    }\n\n    function getNumber() {\n        var number;\n        for (var _i = 0, _l = arguments.length; _i < _l; _i++) {\n            number = _i ? arguments[_i]() : arguments[_i];\n            if (typeof number === 'number') {\n                break;\n            }\n        }\n\n        return number;\n    }\n\n    function edgeResistance(pos, edge) {\n        return Math.round(pos + ((edge - pos) / 1.5));\n    }\n\n    function getProtocol() {\n        getProtocol.p = getProtocol.p || (location.protocol === 'https:' ? 'https://' : 'http://');\n        return getProtocol.p;\n    }\n\n    function parseHref(href) {\n        var a = document.createElement('a');\n        a.href = href;\n        return a;\n    }\n\n    function findVideoId(href, forceVideo) {\n        if (typeof href !== 'string') return href;\n        href = parseHref(href);\n\n        var id,\n            type;\n\n        if (href.host.match(/youtube\\.com/) && href.search) {\n            //.log();\n            id = href.search.split('v=')[1];\n            if (id) {\n                var ampersandPosition = id.indexOf('&');\n                if (ampersandPosition !== -1) {\n                    id = id.substring(0, ampersandPosition);\n                }\n                type = 'youtube';\n            }\n        } else if (href.host.match(/youtube\\.com|youtu\\.be|youtube-nocookie.com/)) {\n            id = href.pathname.replace(/^\\/(embed\\/|v\\/)?/, '').replace(/\\/.*/, '');\n            type = 'youtube';\n        } else if (href.host.match(/vimeo\\.com/)) {\n            type = 'vimeo';\n            id = href.pathname.replace(/^\\/(video\\/)?/, '').replace(/\\/.*/, '');\n        }\n\n        if ((!id || !type) && forceVideo) {\n            id = href.href;\n            type = 'custom';\n        }\n\n        return id ? {id: id, type: type, s: href.search.replace(/^\\?/, ''), p: getProtocol()} : false;\n    }\n\n    function getVideoThumbs(dataFrame, data, fotorama) {\n        var img, thumb, video = dataFrame.video;\n        if (video.type === 'youtube') {\n            thumb = getProtocol() + 'img.youtube.com/vi/' + video.id + '/default.jpg';\n            img = thumb.replace(/\\/default.jpg$/, '/hqdefault.jpg');\n            dataFrame.thumbsReady = true;\n        } else if (video.type === 'vimeo') {\n            $.ajax({\n                url: getProtocol() + 'vimeo.com/api/oembed.json',\n                data: {\n                    url: 'https://vimeo.com/' + video.id\n                },\n                dataType: 'jsonp',\n                success: function (json) {\n                    dataFrame.thumbsReady = true;\n                    updateData(data, {\n                        img: json[0].thumbnail_url,\n                        thumb: json[0].thumbnail_url\n                    }, dataFrame.i, fotorama);\n                }\n            });\n        } else {\n            dataFrame.thumbsReady = true;\n        }\n\n        return {\n            img: img,\n            thumb: thumb\n        }\n    }\n\n    function updateData(data, _dataFrame, i, fotorama) {\n        for (var _i = 0, _l = data.length; _i < _l; _i++) {\n            var dataFrame = data[_i];\n\n            if (dataFrame.i === i && dataFrame.thumbsReady) {\n                var clear = {videoReady: true};\n                clear[STAGE_FRAME_KEY] = clear[NAV_THUMB_FRAME_KEY] = clear[NAV_DOT_FRAME_KEY] = false;\n\n                fotorama.splice(_i, 1, $.extend(\n                    {},\n                    dataFrame,\n                    clear,\n                    _dataFrame\n                ));\n\n                break;\n            }\n        }\n    }\n\n    function getDataFromHtml($el) {\n        var data = [];\n\n        function getDataFromImg($img, imgData, checkVideo) {\n            var $child = $img.children('img').eq(0),\n                _imgHref = $img.attr('href'),\n                _imgSrc = $img.attr('src'),\n                _thumbSrc = $child.attr('src'),\n                _video = imgData.video,\n                video = checkVideo ? findVideoId(_imgHref, _video === true) : false;\n\n            if (video) {\n                _imgHref = false;\n            } else {\n                video = _video;\n            }\n\n            getDimensions($img, $child, $.extend(imgData, {\n                video: video,\n                img: imgData.img || _imgHref || _imgSrc || _thumbSrc,\n                thumb: imgData.thumb || _thumbSrc || _imgSrc || _imgHref\n            }));\n        }\n\n        function getDimensions($img, $child, imgData) {\n            var separateThumbFLAG = imgData.thumb && imgData.img !== imgData.thumb,\n                width = numberFromMeasure(imgData.width || $img.attr('width')),\n                height = numberFromMeasure(imgData.height || $img.attr('height'));\n\n            $.extend(imgData, {\n                width: width,\n                height: height,\n                thumbratio: getRatio(imgData.thumbratio || (numberFromMeasure(imgData.thumbwidth || ($child && $child.attr('width')) || separateThumbFLAG || width) / numberFromMeasure(imgData.thumbheight || ($child && $child.attr('height')) || separateThumbFLAG || height)))\n            });\n        }\n\n        $el.children().each(function () {\n            var $this = $(this),\n                dataFrame = optionsToLowerCase($.extend($this.data(), {id: $this.attr('id')}));\n            if ($this.is('a, img')) {\n                getDataFromImg($this, dataFrame, true);\n            } else if (!$this.is(':empty')) {\n                getDimensions($this, null, $.extend(dataFrame, {\n                    html: this,\n                    _html: $this.html() // Because of IE\n                }));\n            } else return;\n\n            data.push(dataFrame);\n        });\n\n        return data;\n    }\n\n    function isHidden(el) {\n        return el.offsetWidth === 0 && el.offsetHeight === 0;\n    }\n\n    function isDetached(el) {\n        return !$.contains(document.documentElement, el);\n    }\n\n    function waitFor(test, fn, timeout, i) {\n        if (!waitFor.i) {\n            waitFor.i = 1;\n            waitFor.ii = [true];\n        }\n\n        i = i || waitFor.i;\n\n        if (typeof waitFor.ii[i] === 'undefined') {\n            waitFor.ii[i] = true;\n        }\n\n        if (test()) {\n            fn();\n        } else {\n            waitFor.ii[i] && setTimeout(function () {\n                waitFor.ii[i] && waitFor(test, fn, timeout, i);\n            }, timeout || 100);\n        }\n\n        return waitFor.i++;\n    }\n\n    waitFor.stop = function (i) {\n        waitFor.ii[i] = false;\n    };\n\n    function fit($el, measuresToFit) {\n        var elData = $el.data(),\n            measures = elData.measures;\n\n        if (measures && (!elData.l ||\n            elData.l.W !== measures.width ||\n            elData.l.H !== measures.height ||\n            elData.l.r !== measures.ratio ||\n            elData.l.w !== measuresToFit.w ||\n            elData.l.h !== measuresToFit.h)) {\n\n            var height = minMaxLimit(measuresToFit.h, 0, measures.height),\n                width = height * measures.ratio;\n\n            UTIL.setRatio($el, width, height);\n\n            elData.l = {\n                W: measures.width,\n                H: measures.height,\n                r: measures.ratio,\n                w: measuresToFit.w,\n                h: measuresToFit.h\n            };\n        }\n\n        return true;\n    }\n\n    function setStyle($el, style) {\n        var el = $el[0];\n        if (el.styleSheet) {\n            el.styleSheet.cssText = style;\n        } else {\n            $el.html(style);\n        }\n    }\n\n    function findShadowEdge(pos, min, max, dir) {\n        return min === max ? false :\n            dir === 'vertical' ?\n                (pos <= min ? 'top' : pos >= max ? 'bottom' : 'top bottom') :\n                (pos <= min ? 'left' : pos >= max ? 'right' : 'left right');\n    }\n\n    function smartClick($el, fn, _options) {\n        _options = _options || {};\n\n        $el.each(function () {\n            var $this = $(this),\n                thisData = $this.data(),\n                startEvent;\n\n            if (thisData.clickOn) return;\n\n            thisData.clickOn = true;\n\n            $.extend(touch($this, {\n                onStart: function (e) {\n                    startEvent = e;\n                    (_options.onStart || noop).call(this, e);\n                },\n                onMove: _options.onMove || noop,\n                onTouchEnd: _options.onTouchEnd || noop,\n                onEnd: function (result) {\n                    if (result.moved) return;\n                    fn.call(this, startEvent);\n                }\n            }), {noMove: true});\n        });\n    }\n\n    function div(classes, child) {\n        return '<div class=\"' + classes + '\">' + (child || '') + '</div>';\n    }\n\n\n    /**\n     * Function transforming into valid classname\n     * @param className - name of the class\n     * @returns {string} - dom format of class name\n     */\n    function cls(className) {\n        return \".\" + className;\n    }\n\n    /**\n     *\n     * @param {json-object} videoItem Parsed object from data.video item or href from link a in input dates\n     * @returns {string} DOM view of video iframe\n     */\n    function createVideoFrame(videoItem) {\n        var frame = '<iframe src=\"' + videoItem.p + videoItem.type + '.com/embed/' + videoItem.id + '\" frameborder=\"0\" allowfullscreen></iframe>';\n        return frame;\n    }\n\n// Fisher\u2013Yates Shuffle\n// http://bost.ocks.org/mike/shuffle/\n    function shuffle(array) {\n        // While there remain elements to shuffle\n        var l = array.length;\n        while (l) {\n            // Pick a remaining element\n            var i = Math.floor(Math.random() * l--);\n\n            // And swap it with the current element\n            var t = array[l];\n            array[l] = array[i];\n            array[i] = t;\n        }\n\n        return array;\n    }\n\n    function clone(array) {\n        return Object.prototype.toString.call(array) == '[object Array]'\n            && $.map(array, function (frame) {\n                return $.extend({}, frame);\n            });\n    }\n\n    function lockScroll($el, left, top) {\n        $el\n            .scrollLeft(left || 0)\n            .scrollTop(top || 0);\n    }\n\n    function optionsToLowerCase(options) {\n        if (options) {\n            var opts = {};\n            $.each(options, function (key, value) {\n                opts[key.toLowerCase()] = value;\n            });\n\n            return opts;\n        }\n    }\n\n    function getRatio(_ratio) {\n        if (!_ratio) return;\n        var ratio = +_ratio;\n        if (!isNaN(ratio)) {\n            return ratio;\n        } else {\n            ratio = _ratio.split('/');\n            return +ratio[0] / +ratio[1] || undefined;\n        }\n    }\n\n    function addEvent(el, e, fn, bool) {\n        if (!e) return;\n        el.addEventListener ? el.addEventListener(e, fn, !!bool) : el.attachEvent('on' + e, fn);\n    }\n\n    /**\n     *\n     * @param position guess position for navShaft\n     * @param restriction object contains min and max values for position\n     * @returns {*} filtered value of position\n     */\n    function validateRestrictions(position, restriction) {\n        if (position > restriction.max) {\n            position = restriction.max;\n        } else {\n            if (position < restriction.min) {\n                position = restriction.min;\n            }\n        }\n        return position;\n    }\n\n    function validateSlidePos(opt, navShaftTouchTail, guessIndex, offsetNav, $guessNavFrame, $navWrap, dir) {\n        var position,\n            size,\n            wrapSize;\n        if (dir === 'horizontal') {\n            size = opt.thumbwidth;\n            wrapSize = $navWrap.width();\n        } else {\n            size = opt.thumbheight;\n            wrapSize = $navWrap.height();\n        }\n        if ( (size + opt.margin) * (guessIndex + 1) >= (wrapSize - offsetNav) ) {\n            if (dir === 'horizontal') {\n                position = -$guessNavFrame.position().left;\n            } else {\n                position = -$guessNavFrame.position().top;\n            }\n        } else {\n            if ((size + opt.margin) * (guessIndex) <= Math.abs(offsetNav)) {\n                if (dir === 'horizontal') {\n                    position = -$guessNavFrame.position().left + wrapSize - (size + opt.margin);\n                } else {\n                    position = -$guessNavFrame.position().top + wrapSize - (size + opt.margin);\n                }\n            } else {\n                position = offsetNav;\n            }\n        }\n        position = validateRestrictions(position, navShaftTouchTail);\n\n        return position || 0;\n    }\n\n    function elIsDisabled(el) {\n        return !!el.getAttribute('disabled');\n    }\n\n    function disableAttr(FLAG, disable) {\n        if (disable) {\n            return {disabled: FLAG};\n        } else {\n            return {tabindex: FLAG * -1 + '', disabled: FLAG};\n\n        }\n    }\n\n    function addEnterUp(el, fn) {\n        addEvent(el, 'keyup', function (e) {\n            elIsDisabled(el) || e.keyCode == 13 && fn.call(el, e);\n        });\n    }\n\n    function addFocus(el, fn) {\n        addEvent(el, 'focus', el.onfocusin = function (e) {\n            fn.call(el, e);\n        }, true);\n    }\n\n    function stopEvent(e, stopPropagation) {\n        e.preventDefault ? e.preventDefault() : (e.returnValue = false);\n        stopPropagation && e.stopPropagation && e.stopPropagation();\n    }\n\n    function getDirectionSign(forward) {\n        return forward ? '>' : '<';\n    }\n\n    var UTIL = (function () {\n\n        function setRatioClass($el, wh, ht) {\n            var rateImg = wh / ht;\n\n            if (rateImg <= 1) {\n                $el.parent().removeClass(horizontalImageClass);\n                $el.parent().addClass(verticalImageClass);\n            } else {\n                $el.parent().removeClass(verticalImageClass);\n                $el.parent().addClass(horizontalImageClass);\n            }\n        }\n\n        /**\n         * Set specific attribute in thumbnail template\n         * @param $frame DOM item of specific thumbnail\n         * @param value Value which must be setted into specific attribute\n         * @param searchAttr Name of attribute where value must be included\n         */\n        function setThumbAttr($frame, value, searchAttr) {\n            var attr = searchAttr;\n\n            if (!$frame.attr(attr) && $frame.attr(attr) !== undefined) {\n                $frame.attr(attr, value);\n            }\n\n            if ($frame.find(\"[\" + attr + \"]\").length) {\n                $frame.find(\"[\" + attr + \"]\")\n                    .each(function () {\n                        $(this).attr(attr, value);\n                    });\n            }\n        }\n\n        /**\n         * Method describe behavior need to render caption on preview or not\n         * @param frameItem specific item from data\n         * @param isExpected {bool} if items with caption need render them or not\n         * @returns {boolean} if true then caption should be rendered\n         */\n        function isExpectedCaption(frameItem, isExpected, undefined) {\n            var expected = false,\n                frameExpected;\n\n            frameItem.showCaption === undefined || frameItem.showCaption === true ? frameExpected = true : frameExpected = false;\n\n            if (!isExpected) {\n                return false;\n            }\n\n            if (frameItem.caption && frameExpected) {\n                expected = true;\n            }\n\n            return expected;\n        }\n\n        return {\n            setRatio: setRatioClass,\n            setThumbAttr: setThumbAttr,\n            isExpectedCaption: isExpectedCaption\n        };\n\n    }(UTIL || {}, jQuery));\n\n    function slide($el, options) {\n        var elData = $el.data(),\n            elPos = Math.round(options.pos),\n            onEndFn = function () {\n                if (elData && elData.sliding) {\n                    elData.sliding = false;\n                }\n                (options.onEnd || noop)();\n            };\n\n        if (typeof options.overPos !== 'undefined' && options.overPos !== options.pos) {\n            elPos = options.overPos;\n        }\n\n        var translate = $.extend(getTranslate(elPos, options.direction), options.width && {width: options.width}, options.height && {height: options.height});\n        if (elData && elData.sliding) {\n            elData.sliding = true;\n        }\n\n        if (CSS3) {\n            $el.css($.extend(getDuration(options.time), translate));\n\n            if (options.time > 10) {\n                afterTransition($el, 'transform', onEndFn, options.time);\n            } else {\n                onEndFn();\n            }\n        } else {\n            $el.stop().animate(translate, options.time, BEZIER, onEndFn);\n        }\n    }\n\n    function fade($el1, $el2, $frames, options, fadeStack, chain) {\n        var chainedFLAG = typeof chain !== 'undefined';\n        if (!chainedFLAG) {\n            fadeStack.push(arguments);\n            Array.prototype.push.call(arguments, fadeStack.length);\n            if (fadeStack.length > 1) return;\n        }\n\n        $el1 = $el1 || $($el1);\n        $el2 = $el2 || $($el2);\n\n        var _$el1 = $el1[0],\n            _$el2 = $el2[0],\n            crossfadeFLAG = options.method === 'crossfade',\n            onEndFn = function () {\n                if (!onEndFn.done) {\n                    onEndFn.done = true;\n                    var args = (chainedFLAG || fadeStack.shift()) && fadeStack.shift();\n                    args && fade.apply(this, args);\n                    (options.onEnd || noop)(!!args);\n                }\n            },\n            time = options.time / (chain || 1);\n\n        $frames.removeClass(fadeRearClass + ' ' + fadeFrontClass);\n\n        $el1\n            .stop()\n            .addClass(fadeRearClass);\n        $el2\n            .stop()\n            .addClass(fadeFrontClass);\n\n        crossfadeFLAG && _$el2 && $el1.fadeTo(0, 0);\n\n        $el1.fadeTo(crossfadeFLAG ? time : 0, 1, crossfadeFLAG && onEndFn);\n        $el2.fadeTo(time, 0, onEndFn);\n\n        (_$el1 && crossfadeFLAG) || _$el2 || onEndFn();\n    }\n\n    var lastEvent,\n        moveEventType,\n        preventEvent,\n        preventEventTimeout,\n        dragDomEl;\n\n    function extendEvent(e) {\n        var touch = (e.touches || [])[0] || e;\n        e._x = touch.pageX || touch.originalEvent.pageX;\n        e._y = touch.clientY || touch.originalEvent.clientY;\n        e._now = $.now();\n    }\n\n    function touch($el, options) {\n        var el = $el[0],\n            tail = {},\n            touchEnabledFLAG,\n            startEvent,\n            $target,\n            controlTouch,\n            touchFLAG,\n            targetIsSelectFLAG,\n            targetIsLinkFlag,\n            isDisabledSwipe,\n            tolerance,\n            moved;\n\n        function onStart(e) {\n            $target = $(e.target);\n            tail.checked = targetIsSelectFLAG = targetIsLinkFlag = isDisabledSwipe = moved = false;\n\n            if (touchEnabledFLAG\n                || tail.flow\n                || (e.touches && e.touches.length > 1)\n                || e.which > 1\n                || (lastEvent && lastEvent.type !== e.type && preventEvent)\n                || (targetIsSelectFLAG = options.select && $target.is(options.select, el))) return targetIsSelectFLAG;\n\n            touchFLAG = e.type === 'touchstart';\n            targetIsLinkFlag = $target.is('a, a *', el);\n            isDisabledSwipe = $target.hasClass('disableSwipe');\n            controlTouch = tail.control;\n\n            tolerance = (tail.noMove || tail.noSwipe || controlTouch) ? 16 : !tail.snap ? 4 : 0;\n\n            extendEvent(e);\n\n            startEvent = lastEvent = e;\n            moveEventType = e.type.replace(/down|start/, 'move').replace(/Down/, 'Move');\n\n            (options.onStart || noop).call(el, e, {control: controlTouch, $target: $target});\n\n            touchEnabledFLAG = tail.flow = true;\n\n            if (!isDisabledSwipe && (!touchFLAG || tail.go)) stopEvent(e);\n        }\n\n        function onMove(e) {\n            if ((e.touches && e.touches.length > 1)\n                || (MS_POINTER && !e.isPrimary)\n                || moveEventType !== e.type\n                || !touchEnabledFLAG) {\n                touchEnabledFLAG && onEnd();\n                (options.onTouchEnd || noop)();\n                return;\n            }\n\n            isDisabledSwipe = $(e.target).hasClass('disableSwipe');\n\n            if (isDisabledSwipe) {\n                return;\n            }\n\n            extendEvent(e);\n\n            var xDiff = Math.abs(e._x - startEvent._x), // opt _x \u2192 _pageX\n                yDiff = Math.abs(e._y - startEvent._y),\n                xyDiff = xDiff - yDiff,\n                xWin = (tail.go || tail.x || xyDiff >= 0) && !tail.noSwipe,\n                yWin = xyDiff < 0;\n\n            if (touchFLAG && !tail.checked) {\n                if (touchEnabledFLAG = xWin) {\n                    stopEvent(e);\n                }\n            } else {\n                stopEvent(e);\n                if (movedEnough(xDiff,yDiff)) {\n                    (options.onMove || noop).call(el, e, {touch: touchFLAG});\n                }\n            }\n\n            if (!moved && movedEnough(xDiff, yDiff) && Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2)) > tolerance) {\n                moved = true;\n            }\n\n            tail.checked = tail.checked || xWin || yWin;\n        }\n\n        function movedEnough(xDiff, yDiff) {\n            return xDiff > yDiff && xDiff > 1.5;\n        }\n\n        function onEnd(e) {\n            (options.onTouchEnd || noop)();\n\n            var _touchEnabledFLAG = touchEnabledFLAG;\n            tail.control = touchEnabledFLAG = false;\n\n            if (_touchEnabledFLAG) {\n                tail.flow = false;\n            }\n\n            if (!_touchEnabledFLAG || (targetIsLinkFlag && !tail.checked)) return;\n\n            e && stopEvent(e);\n\n            preventEvent = true;\n            clearTimeout(preventEventTimeout);\n            preventEventTimeout = setTimeout(function () {\n                preventEvent = false;\n            }, 1000);\n\n            (options.onEnd || noop).call(el, {\n                moved: moved,\n                $target: $target,\n                control: controlTouch,\n                touch: touchFLAG,\n                startEvent: startEvent,\n                aborted: !e || e.type === 'MSPointerCancel'\n            });\n        }\n\n        function onOtherStart() {\n            if (tail.flow) return;\n            tail.flow = true;\n        }\n\n        function onOtherEnd() {\n            if (!tail.flow) return;\n            tail.flow = false;\n        }\n\n        if (MS_POINTER) {\n            addEvent(el, 'MSPointerDown', onStart);\n            addEvent(document, 'MSPointerMove', onMove);\n            addEvent(document, 'MSPointerCancel', onEnd);\n            addEvent(document, 'MSPointerUp', onEnd);\n        } else {\n            addEvent(el, 'touchstart', onStart);\n            addEvent(el, 'touchmove', onMove);\n            addEvent(el, 'touchend', onEnd);\n\n            addEvent(document, 'touchstart', onOtherStart, true);\n            addEvent(document, 'touchend', onOtherEnd);\n            addEvent(document, 'touchcancel', onOtherEnd);\n\n            $WINDOW.on('scroll', onOtherEnd);\n\n            $el.on('mousedown', onStart);\n            $DOCUMENT\n                .on('mousemove', onMove)\n                .on('mouseup', onEnd);\n        }\n        if (Modernizr.touch) {\n            dragDomEl = 'a';\n        } else {\n            dragDomEl = 'div';\n        }\n        $el.on('click', dragDomEl, function (e) {\n            tail.checked && stopEvent(e);\n        });\n\n        return tail;\n    }\n\n    function moveOnTouch($el, options) {\n        var el = $el[0],\n            elData = $el.data(),\n            tail = {},\n            startCoo,\n            coo,\n            startElPos,\n            moveElPos,\n            edge,\n            moveTrack,\n            startTime,\n            endTime,\n            min,\n            max,\n            snap,\n            dir,\n            slowFLAG,\n            controlFLAG,\n            moved,\n            tracked;\n\n        function startTracking(e, noStop) {\n            tracked = true;\n            startCoo = coo = (dir === 'vertical') ? e._y : e._x;\n            startTime = e._now;\n\n            moveTrack = [\n                [startTime, startCoo]\n            ];\n\n            startElPos = moveElPos = tail.noMove || noStop ? 0 : stop($el, (options.getPos || noop)()/*, options._001*/);\n\n            (options.onStart || noop).call(el, e);\n        }\n\n        function onStart(e, result) {\n            min = tail.min;\n            max = tail.max;\n            snap = tail.snap,\n                dir = tail.direction || 'horizontal',\n                $el.navdir = dir;\n\n            slowFLAG = e.altKey;\n            tracked = moved = false;\n\n            controlFLAG = result.control;\n\n            if (!controlFLAG && !elData.sliding) {\n                startTracking(e);\n            }\n        }\n\n        function onMove(e, result) {\n            if (!tail.noSwipe) {\n                if (!tracked) {\n                    startTracking(e);\n                }\n                coo = (dir === 'vertical') ? e._y : e._x;\n\n                moveTrack.push([e._now, coo]);\n\n                moveElPos = startElPos - (startCoo - coo);\n\n                edge = findShadowEdge(moveElPos, min, max, dir);\n\n                if (moveElPos <= min) {\n                    moveElPos = edgeResistance(moveElPos, min);\n                } else if (moveElPos >= max) {\n                    moveElPos = edgeResistance(moveElPos, max);\n                }\n\n                if (!tail.noMove) {\n                    $el.css(getTranslate(moveElPos, dir));\n                    if (!moved) {\n                        moved = true;\n                        // only for mouse\n                        result.touch || MS_POINTER || $el.addClass(grabbingClass);\n                    }\n\n                    (options.onMove || noop).call(el, e, {pos: moveElPos, edge: edge});\n                }\n            }\n        }\n\n        function onEnd(result) {\n            if (tail.noSwipe && result.moved) return;\n\n            if (!tracked) {\n                startTracking(result.startEvent, true);\n            }\n\n            result.touch || MS_POINTER || $el.removeClass(grabbingClass);\n\n            endTime = $.now();\n\n            var _backTimeIdeal = endTime - TOUCH_TIMEOUT,\n                _backTime,\n                _timeDiff,\n                _timeDiffLast,\n                backTime = null,\n                backCoo,\n                virtualPos,\n                limitPos,\n                newPos,\n                overPos,\n                time = TRANSITION_DURATION,\n                speed,\n                friction = options.friction;\n\n            for (var _i = moveTrack.length - 1; _i >= 0; _i--) {\n                _backTime = moveTrack[_i][0];\n                _timeDiff = Math.abs(_backTime - _backTimeIdeal);\n                if (backTime === null || _timeDiff < _timeDiffLast) {\n                    backTime = _backTime;\n                    backCoo = moveTrack[_i][1];\n                } else if (backTime === _backTimeIdeal || _timeDiff > _timeDiffLast) {\n                    break;\n                }\n                _timeDiffLast = _timeDiff;\n            }\n\n            newPos = minMaxLimit(moveElPos, min, max);\n\n            var cooDiff = backCoo - coo,\n                forwardFLAG = cooDiff >= 0,\n                timeDiff = endTime - backTime,\n                longTouchFLAG = timeDiff > TOUCH_TIMEOUT,\n                swipeFLAG = !longTouchFLAG && moveElPos !== startElPos && newPos === moveElPos;\n\n            if (snap) {\n                newPos = minMaxLimit(Math[swipeFLAG ? (forwardFLAG ? 'floor' : 'ceil') : 'round'](moveElPos / snap) * snap, min, max);\n                min = max = newPos;\n            }\n\n            if (swipeFLAG && (snap || newPos === moveElPos)) {\n                speed = -(cooDiff / timeDiff);\n                time *= minMaxLimit(Math.abs(speed), options.timeLow, options.timeHigh);\n                virtualPos = Math.round(moveElPos + speed * time / friction);\n\n                if (!snap) {\n                    newPos = virtualPos;\n                }\n\n                if (!forwardFLAG && virtualPos > max || forwardFLAG && virtualPos < min) {\n                    limitPos = forwardFLAG ? min : max;\n                    overPos = virtualPos - limitPos;\n                    if (!snap) {\n                        newPos = limitPos;\n                    }\n                    overPos = minMaxLimit(newPos + overPos * .03, limitPos - 50, limitPos + 50);\n                    time = Math.abs((moveElPos - overPos) / (speed / friction));\n                }\n            }\n\n            time *= slowFLAG ? 10 : 1;\n\n            (options.onEnd || noop).call(el, $.extend(result, {\n                moved: result.moved || longTouchFLAG && snap,\n                pos: moveElPos,\n                newPos: newPos,\n                overPos: overPos,\n                time: time,\n                dir: dir\n            }));\n        }\n\n        tail = $.extend(touch(options.$wrap, $.extend({}, options, {\n            onStart: onStart,\n            onMove: onMove,\n            onEnd: onEnd\n        })), tail);\n\n        return tail;\n    }\n\n    function wheel($el, options) {\n        var el = $el[0],\n            lockFLAG,\n            lastDirection,\n            lastNow,\n            tail = {\n                prevent: {}\n            };\n\n        addEvent(el, WHEEL, function (e) {\n            var yDelta = e.wheelDeltaY || -1 * e.deltaY || 0,\n                xDelta = e.wheelDeltaX || -1 * e.deltaX || 0,\n                xWin = Math.abs(xDelta) && !Math.abs(yDelta),\n                direction = getDirectionSign(xDelta < 0),\n                sameDirection = lastDirection === direction,\n                now = $.now(),\n                tooFast = now - lastNow < TOUCH_TIMEOUT;\n\n            lastDirection = direction;\n            lastNow = now;\n\n            if (!xWin || !tail.ok || tail.prevent[direction] && !lockFLAG) {\n                return;\n            } else {\n                stopEvent(e, true);\n                if (lockFLAG && sameDirection && tooFast) {\n                    return;\n                }\n            }\n\n            if (options.shift) {\n                lockFLAG = true;\n                clearTimeout(tail.t);\n                tail.t = setTimeout(function () {\n                    lockFLAG = false;\n                }, SCROLL_LOCK_TIMEOUT);\n            }\n\n            (options.onEnd || noop)(e, options.shift ? direction : xDelta);\n\n        });\n\n        return tail;\n    }\n\n    jQuery.Fotorama = function ($fotorama, opts) {\n        $HTML = $('html');\n        $BODY = $('body');\n\n        var that = this,\n            stamp = $.now(),\n            stampClass = _fotoramaClass + stamp,\n            fotorama = $fotorama[0],\n            data,\n            dataFrameCount = 1,\n            fotoramaData = $fotorama.data(),\n            size,\n\n            $style = $('<style></style>'),\n\n            $anchor = $(div(hiddenClass)),\n            $wrap = $fotorama.find(cls(wrapClass)),\n            $stage = $wrap.find(cls(stageClass)),\n            stage = $stage[0],\n\n            $stageShaft = $fotorama.find(cls(stageShaftClass)),\n            $stageFrame = $(),\n            $arrPrev = $fotorama.find(cls(arrPrevClass)),\n            $arrNext = $fotorama.find(cls(arrNextClass)),\n            $arrs = $fotorama.find(cls(arrClass)),\n            $navWrap = $fotorama.find(cls(navWrapClass)),\n            $nav = $navWrap.find(cls(navClass)),\n            $navShaft = $nav.find(cls(navShaftClass)),\n            $navFrame,\n            $navDotFrame = $(),\n            $navThumbFrame = $(),\n\n            stageShaftData = $stageShaft.data(),\n            navShaftData = $navShaft.data(),\n\n            $thumbBorder = $fotorama.find(cls(thumbBorderClass)),\n            $thumbArrLeft = $fotorama.find(cls(thumbArrLeft)),\n            $thumbArrRight = $fotorama.find(cls(thumbArrRight)),\n\n            $fullscreenIcon = $fotorama.find(cls(fullscreenIconClass)),\n            fullscreenIcon = $fullscreenIcon[0],\n            $videoPlay = $(div(videoPlayClass)),\n            $videoClose = $fotorama.find(cls(videoCloseClass)),\n            videoClose = $videoClose[0],\n\n            $spinner = $fotorama.find(cls(fotoramaSpinnerClass)),\n\n            $videoPlaying,\n\n            activeIndex = false,\n            activeFrame,\n            activeIndexes,\n            repositionIndex,\n            dirtyIndex,\n            lastActiveIndex,\n            prevIndex,\n            nextIndex,\n            nextAutoplayIndex,\n            startIndex,\n\n            o_loop,\n            o_nav,\n            o_navThumbs,\n            o_navTop,\n            o_allowFullScreen,\n            o_nativeFullScreen,\n            o_fade,\n            o_thumbSide,\n            o_thumbSide2,\n            o_transitionDuration,\n            o_transition,\n            o_shadows,\n            o_rtl,\n            o_keyboard,\n            lastOptions = {},\n\n            measures = {},\n            measuresSetFLAG,\n\n            stageShaftTouchTail = {},\n            stageWheelTail = {},\n            navShaftTouchTail = {},\n            navWheelTail = {},\n\n            scrollTop,\n            scrollLeft,\n\n            showedFLAG,\n            pausedAutoplayFLAG,\n            stoppedAutoplayFLAG,\n\n            toDeactivate = {},\n            toDetach = {},\n\n            measuresStash,\n\n            touchedFLAG,\n\n            hoverFLAG,\n\n            navFrameKey,\n            stageLeft = 0,\n\n            fadeStack = [];\n\n        $wrap[STAGE_FRAME_KEY] = $('<div class=\"' + stageFrameClass + '\"></div>');\n        $wrap[NAV_THUMB_FRAME_KEY] = $($.Fotorama.jst.thumb());\n        $wrap[NAV_DOT_FRAME_KEY] = $($.Fotorama.jst.dots());\n\n        toDeactivate[STAGE_FRAME_KEY] = [];\n        toDeactivate[NAV_THUMB_FRAME_KEY] = [];\n        toDeactivate[NAV_DOT_FRAME_KEY] = [];\n        toDetach[STAGE_FRAME_KEY] = {};\n\n        $wrap.addClass(CSS3 ? wrapCss3Class : wrapCss2Class);\n\n        fotoramaData.fotorama = this;\n\n        /**\n         * Search video items in incoming data and transform object for video layout.\n         *\n         */\n        function checkForVideo() {\n            $.each(data, function (i, dataFrame) {\n                if (!dataFrame.i) {\n                    dataFrame.i = dataFrameCount++;\n                    var video = findVideoId(dataFrame.video, true);\n                    if (video) {\n                        var thumbs = {};\n                        dataFrame.video = video;\n                        if (!dataFrame.img && !dataFrame.thumb) {\n                            thumbs = getVideoThumbs(dataFrame, data, that);\n                        } else {\n                            dataFrame.thumbsReady = true;\n                        }\n                        updateData(data, {img: thumbs.img, thumb: thumbs.thumb}, dataFrame.i, that);\n                    }\n                }\n            });\n        }\n\n        /**\n         * Checks if current media object is YouTube or Vimeo video stream\n         * @returns {boolean}\n         */\n        function isVideo() {\n            return $((that.activeFrame || {}).$stageFrame || {}).hasClass('fotorama-video-container');\n        }\n\n        function allowKey(key) {\n            return o_keyboard[key];\n        }\n\n        function setStagePosition() {\n            if ($stage !== undefined) {\n\n                if (opts.navdir == 'vertical') {\n                    var padding = opts.thumbwidth + opts.thumbmargin;\n\n                    $stage.css('left', padding);\n                    $arrNext.css('right', padding);\n                    $fullscreenIcon.css('right', padding);\n                    $wrap.css('width', $wrap.css('width') + padding);\n                    $stageShaft.css('max-width', $wrap.width() - padding);\n                } else {\n                    $stage.css('left', '');\n                    $arrNext.css('right', '');\n                    $fullscreenIcon.css('right', '');\n                    $wrap.css('width', $wrap.css('width') + padding);\n                    $stageShaft.css('max-width', '');\n                }\n            }\n        }\n\n        function bindGlobalEvents(FLAG) {\n            var keydownCommon = 'keydown.' + _fotoramaClass,\n                localStamp = _fotoramaClass + stamp,\n                keydownLocal = 'keydown.' + localStamp,\n                keyupLocal = 'keyup.' + localStamp,\n                resizeLocal = 'resize.' + localStamp + ' ' + 'orientationchange.' + localStamp,\n                showParams;\n\n            if (FLAG) {\n                $DOCUMENT\n                    .on(keydownLocal, function (e) {\n                        var catched,\n                            index;\n\n                        if ($videoPlaying && e.keyCode === 27) {\n                            catched = true;\n                            unloadVideo($videoPlaying, true, true);\n                        } else if (that.fullScreen || (opts.keyboard && !that.index)) {\n                            if (e.keyCode === 27) {\n                                catched = true;\n                                that.cancelFullScreen();\n                            } else if ((e.shiftKey && e.keyCode === 32 && allowKey('space')) || (!e.altKey && !e.metaKey && e.keyCode === 37 && allowKey('left')) || (e.keyCode === 38 && allowKey('up') && $(':focus').attr('data-gallery-role'))) {\n                                that.longPress.progress();\n                                index = '<';\n                            } else if ((e.keyCode === 32 && allowKey('space')) || (!e.altKey && !e.metaKey && e.keyCode === 39 && allowKey('right')) || (e.keyCode === 40 && allowKey('down') && $(':focus').attr('data-gallery-role'))) {\n                                that.longPress.progress();\n                                index = '>';\n                            } else if (e.keyCode === 36 && allowKey('home')) {\n                                that.longPress.progress();\n                                index = '<<';\n                            } else if (e.keyCode === 35 && allowKey('end')) {\n                                that.longPress.progress();\n                                index = '>>';\n                            }\n                        }\n\n                        (catched || index) && stopEvent(e);\n                        showParams = {index: index, slow: e.altKey, user: true};\n                        index && (that.longPress.inProgress ?\n                            that.showWhileLongPress(showParams) :\n                            that.show(showParams));\n                    });\n\n                if (FLAG) {\n                    $DOCUMENT\n                        .on(keyupLocal, function (e) {\n                            if (that.longPress.inProgress) {\n                                that.showEndLongPress({user: true});\n                            }\n                            that.longPress.reset();\n                        });\n                }\n\n                if (!that.index) {\n                    $DOCUMENT\n                        .off(keydownCommon)\n                        .on(keydownCommon, 'textarea, input, select', function (e) {\n                            !$BODY.hasClass(_fullscreenClass) && e.stopPropagation();\n                        });\n                }\n\n                $WINDOW.on(resizeLocal, that.resize);\n            } else {\n                $DOCUMENT.off(keydownLocal);\n                $WINDOW.off(resizeLocal);\n            }\n        }\n\n        function appendElements(FLAG) {\n            if (FLAG === appendElements.f) return;\n\n            if (FLAG) {\n                $fotorama\n                    .addClass(_fotoramaClass + ' ' + stampClass)\n                    .before($anchor)\n                    .before($style);\n                addInstance(that);\n            } else {\n                $anchor.detach();\n                $style.detach();\n                $fotorama\n                    .html(fotoramaData.urtext)\n                    .removeClass(stampClass);\n\n                hideInstance(that);\n            }\n\n            bindGlobalEvents(FLAG);\n            appendElements.f = FLAG;\n        }\n\n        /**\n         * Set and install data from incoming @param {JSON} options or takes data attr from data-\"name\"=... values.\n         */\n        function setData() {\n            data = that.data = data || clone(opts.data) || getDataFromHtml($fotorama);\n            size = that.size = data.length;\n\n            ready.ok && opts.shuffle && shuffle(data);\n\n            checkForVideo();\n\n            activeIndex = limitIndex(activeIndex);\n\n            size && appendElements(true);\n        }\n\n        function stageNoMove() {\n            var _noMove = size < 2 || $videoPlaying;\n            stageShaftTouchTail.noMove = _noMove || o_fade;\n            stageShaftTouchTail.noSwipe = _noMove || !opts.swipe;\n\n            !o_transition && $stageShaft.toggleClass(grabClass, !opts.click && !stageShaftTouchTail.noMove && !stageShaftTouchTail.noSwipe);\n            MS_POINTER && $wrap.toggleClass(wrapPanYClass, !stageShaftTouchTail.noSwipe);\n        }\n\n        function setAutoplayInterval(interval) {\n            if (interval === true) interval = '';\n            opts.autoplay = Math.max(+interval || AUTOPLAY_INTERVAL, o_transitionDuration * 1.5);\n        }\n\n        function updateThumbArrow(opt) {\n            if (opt.navarrows && opt.nav === 'thumbs') {\n                $thumbArrLeft.show();\n                $thumbArrRight.show();\n            } else {\n                $thumbArrLeft.hide();\n                $thumbArrRight.hide();\n            }\n\n        }\n\n        function getThumbsInSlide($el, opts) {\n            return Math.floor($wrap.width() / (opts.thumbwidth + opts.thumbmargin));\n        }\n\n        /**\n         * Options on the fly\n         * */\n        function setOptions() {\n            if (!opts.nav || opts.nav === 'dots') {\n                opts.navdir = 'horizontal'\n            }\n\n            that.options = opts = optionsToLowerCase(opts);\n            thumbsPerSlide = getThumbsInSlide($wrap, opts);\n\n            o_fade = (opts.transition === 'crossfade' || opts.transition === 'dissolve');\n\n            o_loop = opts.loop && (size > 2 || (o_fade && (!o_transition || o_transition !== 'slide')));\n\n            o_transitionDuration = +opts.transitionduration || TRANSITION_DURATION;\n\n            o_rtl = opts.direction === 'rtl';\n\n            o_keyboard = $.extend({}, opts.keyboard && KEYBOARD_OPTIONS, opts.keyboard);\n            updateThumbArrow(opts);\n            var classes = {add: [], remove: []};\n\n            function addOrRemoveClass(FLAG, value) {\n                classes[FLAG ? 'add' : 'remove'].push(value);\n            }\n\n            if (size > 1) {\n                o_nav = opts.nav;\n                o_navTop = opts.navposition === 'top';\n                classes.remove.push(selectClass);\n\n                $arrs.toggle(!!opts.arrows);\n            } else {\n                o_nav = false;\n                $arrs.hide();\n            }\n\n            arrsUpdate();\n            stageWheelUpdate();\n            thumbArrUpdate();\n            if (opts.autoplay) setAutoplayInterval(opts.autoplay);\n\n            o_thumbSide = numberFromMeasure(opts.thumbwidth) || THUMB_SIZE;\n            o_thumbSide2 = numberFromMeasure(opts.thumbheight) || THUMB_SIZE;\n\n            stageWheelTail.ok = navWheelTail.ok = opts.trackpad && !SLOW;\n\n            stageNoMove();\n\n            extendMeasures(opts, [measures]);\n\n            o_navThumbs = o_nav === 'thumbs';\n\n            if ($navWrap.filter(':hidden') && !!o_nav) {\n                $navWrap.show();\n            }\n            if (o_navThumbs) {\n                frameDraw(size, 'navThumb');\n\n                $navFrame = $navThumbFrame;\n                navFrameKey = NAV_THUMB_FRAME_KEY;\n\n                setStyle($style, $.Fotorama.jst.style({\n                    w: o_thumbSide,\n                    h: o_thumbSide2,\n                    b: opts.thumbborderwidth,\n                    m: opts.thumbmargin,\n                    s: stamp,\n                    q: !COMPAT\n                }));\n\n                $nav\n                    .addClass(navThumbsClass)\n                    .removeClass(navDotsClass);\n            } else if (o_nav === 'dots') {\n                frameDraw(size, 'navDot');\n\n                $navFrame = $navDotFrame;\n                navFrameKey = NAV_DOT_FRAME_KEY;\n\n                $nav\n                    .addClass(navDotsClass)\n                    .removeClass(navThumbsClass);\n            } else {\n                $navWrap.hide();\n                o_nav = false;\n                $nav.removeClass(navThumbsClass + ' ' + navDotsClass);\n            }\n\n            if (o_nav) {\n                if (o_navTop) {\n                    $navWrap.insertBefore($stage);\n                } else {\n                    $navWrap.insertAfter($stage);\n                }\n                frameAppend.nav = false;\n\n                frameAppend($navFrame, $navShaft, 'nav');\n            }\n\n            o_allowFullScreen = opts.allowfullscreen;\n\n            if (o_allowFullScreen) {\n                $fullscreenIcon.prependTo($stage);\n                o_nativeFullScreen = FULLSCREEN && o_allowFullScreen === 'native';\n            } else {\n                $fullscreenIcon.detach();\n                o_nativeFullScreen = false;\n            }\n\n            addOrRemoveClass(o_fade, wrapFadeClass);\n            addOrRemoveClass(!o_fade, wrapSlideClass);\n            addOrRemoveClass(!opts.captions, wrapNoCaptionsClass);\n            addOrRemoveClass(o_rtl, wrapRtlClass);\n            addOrRemoveClass(opts.arrows, wrapToggleArrowsClass);\n\n            o_shadows = opts.shadows && !SLOW;\n            addOrRemoveClass(!o_shadows, wrapNoShadowsClass);\n\n            $wrap\n                .addClass(classes.add.join(' '))\n                .removeClass(classes.remove.join(' '));\n\n            lastOptions = $.extend({}, opts);\n            setStagePosition();\n        }\n\n        function normalizeIndex(index) {\n            return index < 0 ? (size + (index % size)) % size : index >= size ? index % size : index;\n        }\n\n        function limitIndex(index) {\n            return minMaxLimit(index, 0, size - 1);\n        }\n\n        function edgeIndex(index) {\n            return o_loop ? normalizeIndex(index) : limitIndex(index);\n        }\n\n        function getPrevIndex(index) {\n            return index > 0 || o_loop ? index - 1 : false;\n        }\n\n        function getNextIndex(index) {\n            return index < size - 1 || o_loop ? index + 1 : false;\n        }\n\n        function setStageShaftMinmaxAndSnap() {\n            stageShaftTouchTail.min = o_loop ? -Infinity : -getPosByIndex(size - 1, measures.w, opts.margin, repositionIndex);\n            stageShaftTouchTail.max = o_loop ? Infinity : -getPosByIndex(0, measures.w, opts.margin, repositionIndex);\n            stageShaftTouchTail.snap = measures.w + opts.margin;\n        }\n\n        function setNavShaftMinMax() {\n\n            var isVerticalDir = (opts.navdir === 'vertical');\n            var param = isVerticalDir ? $navShaft.height() : $navShaft.width();\n            var mainParam = isVerticalDir ? measures.h : measures.nw;\n            navShaftTouchTail.min = Math.min(0, mainParam - param);\n            navShaftTouchTail.max = 0;\n            navShaftTouchTail.direction = opts.navdir;\n            $navShaft.toggleClass(grabClass, !(navShaftTouchTail.noMove = navShaftTouchTail.min === navShaftTouchTail.max));\n        }\n\n        function eachIndex(indexes, type, fn) {\n            if (typeof indexes === 'number') {\n                indexes = new Array(indexes);\n                var rangeFLAG = true;\n            }\n            return $.each(indexes, function (i, index) {\n                if (rangeFLAG) index = i;\n                if (typeof index === 'number') {\n                    var dataFrame = data[normalizeIndex(index)];\n\n                    if (dataFrame) {\n                        var key = '$' + type + 'Frame',\n                            $frame = dataFrame[key];\n\n                        fn.call(this, i, index, dataFrame, $frame, key, $frame && $frame.data());\n                    }\n                }\n            });\n        }\n\n        function setMeasures(width, height, ratio, index) {\n            if (!measuresSetFLAG || (measuresSetFLAG === '*' && index === startIndex)) {\n\n                width = measureIsValid(opts.width) || measureIsValid(width) || WIDTH;\n                height = measureIsValid(opts.height) || measureIsValid(height) || HEIGHT;\n                that.resize({\n                    width: width,\n                    ratio: opts.ratio || ratio || width / height\n                }, 0, index !== startIndex && '*');\n            }\n        }\n\n        function loadImg(indexes, type, specialMeasures, again) {\n\n            eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) {\n\n                if (!$frame) return;\n\n                var fullFLAG = that.fullScreen && !frameData.$full && type === 'stage';\n\n                if (frameData.$img && !again && !fullFLAG) return;\n\n                var img = new Image(),\n                    $img = $(img),\n                    imgData = $img.data();\n\n                frameData[fullFLAG ? '$full' : '$img'] = $img;\n\n                var srcKey = type === 'stage' ? (fullFLAG ? 'full' : 'img') : 'thumb',\n                    src = dataFrame[srcKey],\n                    dummy = fullFLAG ? dataFrame['img'] : dataFrame[type === 'stage' ? 'thumb' : 'img'];\n\n                if (type === 'navThumb') $frame = frameData.$wrap;\n\n                function triggerTriggerEvent(event) {\n                    var _index = normalizeIndex(index);\n                    triggerEvent(event, {\n                        index: _index,\n                        src: src,\n                        frame: data[_index]\n                    });\n                }\n\n                function error() {\n                    $img.remove();\n\n                    $.Fotorama.cache[src] = 'error';\n\n                    if ((!dataFrame.html || type !== 'stage') && dummy && dummy !== src) {\n                        dataFrame[srcKey] = src = dummy;\n                        frameData.$full = null;\n                        loadImg([index], type, specialMeasures, true);\n                    } else {\n                        if (src && !dataFrame.html && !fullFLAG) {\n                            $frame\n                                .trigger('f:error')\n                                .removeClass(loadingClass)\n                                .addClass(errorClass);\n\n                            triggerTriggerEvent('error');\n                        } else if (type === 'stage') {\n                            $frame\n                                .trigger('f:load')\n                                .removeClass(loadingClass + ' ' + errorClass)\n                                .addClass(loadedClass);\n\n                            triggerTriggerEvent('load');\n                            setMeasures();\n                        }\n\n                        frameData.state = 'error';\n\n                        if (size > 1 && data[index] === dataFrame && !dataFrame.html && !dataFrame.deleted && !dataFrame.video && !fullFLAG) {\n                            dataFrame.deleted = true;\n                            that.splice(index, 1);\n                        }\n                    }\n                }\n\n                function loaded() {\n                    $.Fotorama.measures[src] = imgData.measures = $.Fotorama.measures[src] || {\n                            width: img.width,\n                            height: img.height,\n                            ratio: img.width / img.height\n                        };\n\n                    setMeasures(imgData.measures.width, imgData.measures.height, imgData.measures.ratio, index);\n\n                    $img\n                        .off('load error')\n                        .addClass('' + (fullFLAG ? imgFullClass: imgClass))\n                        .attr('aria-hidden', 'false')\n                        .prependTo($frame);\n\n                    if ($frame.hasClass(stageFrameClass) && !$frame.hasClass(videoContainerClass)) {\n                        $frame.attr(\"href\", $img.attr(\"src\"));\n                    }\n\n                    fit($img, (\n                            $.isFunction(specialMeasures) ? specialMeasures() : specialMeasures) || measures);\n\n                    $.Fotorama.cache[src] = frameData.state = 'loaded';\n\n                    setTimeout(function () {\n                        $frame\n                            .trigger('f:load')\n                            .removeClass(loadingClass + ' ' + errorClass)\n                            .addClass(loadedClass + ' ' + (fullFLAG ? loadedFullClass : loadedImgClass));\n\n                        if (type === 'stage') {\n                            triggerTriggerEvent('load');\n                        } else if (dataFrame.thumbratio === AUTO || !dataFrame.thumbratio && opts.thumbratio === AUTO) {\n                            // danger! reflow for all thumbnails\n                            dataFrame.thumbratio = imgData.measures.ratio;\n                            reset();\n                        }\n                    }, 0);\n                }\n\n                if (!src) {\n                    error();\n                    return;\n                }\n\n                function waitAndLoad() {\n                    var _i = 10;\n                    waitFor(function () {\n                        return !touchedFLAG || !_i-- && !SLOW;\n                    }, function () {\n                        loaded();\n                    });\n                }\n\n                if (!$.Fotorama.cache[src]) {\n                    $.Fotorama.cache[src] = '*';\n\n                    $img\n                        .on('load', waitAndLoad)\n                        .on('error', error);\n                } else {\n                    (function justWait() {\n                        if ($.Fotorama.cache[src] === 'error') {\n                            error();\n                        } else if ($.Fotorama.cache[src] === 'loaded') {\n                            setTimeout(waitAndLoad, 0);\n                        } else {\n                            setTimeout(justWait, 100);\n                        }\n                    })();\n                }\n\n                frameData.state = '';\n                img.src = src;\n\n                if (frameData.data.caption) {\n                    img.alt = frameData.data.caption || \"\";\n                }\n\n                if (frameData.data.full) {\n                    $(img).data('original', frameData.data.full);\n                }\n\n                if (UTIL.isExpectedCaption(dataFrame, opts.showcaption)) {\n                    $(img).attr('aria-labelledby', dataFrame.labelledby);\n                }\n            });\n        }\n\n        function updateFotoramaState() {\n            var $frame = activeFrame[STAGE_FRAME_KEY];\n\n            if ($frame && !$frame.data().state) {\n                $spinner.addClass(spinnerShowClass);\n                $frame.on('f:load f:error', function () {\n                    $frame.off('f:load f:error');\n                    $spinner.removeClass(spinnerShowClass);\n                });\n            }\n        }\n\n        function addNavFrameEvents(frame) {\n            addEnterUp(frame, onNavFrameClick);\n            addFocus(frame, function () {\n\n                setTimeout(function () {\n                    lockScroll($nav);\n                }, 0);\n                slideNavShaft({time: o_transitionDuration, guessIndex: $(this).data().eq, minMax: navShaftTouchTail});\n            });\n        }\n\n        function frameDraw(indexes, type) {\n            eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) {\n                if ($frame) return;\n\n                $frame = dataFrame[key] = $wrap[key].clone();\n                frameData = $frame.data();\n                frameData.data = dataFrame;\n                var frame = $frame[0],\n                    labelledbyValue = \"labelledby\" + $.now();\n\n                if (type === 'stage') {\n\n                    if (dataFrame.html) {\n                        $('<div class=\"' + htmlClass + '\"></div>')\n                            .append(\n                            dataFrame._html ? $(dataFrame.html)\n                                .removeAttr('id')\n                                .html(dataFrame._html) // Because of IE\n                                : dataFrame.html\n                        )\n                            .appendTo($frame);\n                    }\n\n                    if (dataFrame.id) {\n                        labelledbyValue = dataFrame.id || labelledbyValue;\n                    }\n                    dataFrame.labelledby = labelledbyValue;\n\n                    if (UTIL.isExpectedCaption(dataFrame, opts.showcaption)) {\n                        $($.Fotorama.jst.frameCaption({\n                            caption: dataFrame.caption,\n                            labelledby: labelledbyValue\n                        })).appendTo($frame);\n                    }\n\n                    dataFrame.video && $frame\n                        .addClass(stageFrameVideoClass)\n                        .append($videoPlay.clone());\n\n                    // This solves tabbing problems\n                    addFocus(frame, function (e) {\n                        setTimeout(function () {\n                            lockScroll($stage);\n                        }, 0);\n                        clickToShow({index: frameData.eq, user: true}, e);\n                    });\n\n                    $stageFrame = $stageFrame.add($frame);\n                } else if (type === 'navDot') {\n                    addNavFrameEvents(frame);\n                    $navDotFrame = $navDotFrame.add($frame);\n                } else if (type === 'navThumb') {\n                    addNavFrameEvents(frame);\n                    frameData.$wrap = $frame.children(':first');\n\n                    $navThumbFrame = $navThumbFrame.add($frame);\n                    if (dataFrame.video) {\n                        frameData.$wrap.append($videoPlay.clone());\n                    }\n                }\n            });\n        }\n\n        function callFit($img, measuresToFit) {\n            return $img && $img.length && fit($img, measuresToFit);\n        }\n\n        function stageFramePosition(indexes) {\n            eachIndex(indexes, 'stage', function (i, index, dataFrame, $frame, key, frameData) {\n                if (!$frame) return;\n\n                var normalizedIndex = normalizeIndex(index);\n                frameData.eq = normalizedIndex;\n\n                toDetach[STAGE_FRAME_KEY][normalizedIndex] = $frame.css($.extend({left: o_fade ? 0 : getPosByIndex(index, measures.w, opts.margin, repositionIndex)}, o_fade && getDuration(0)));\n\n                if (isDetached($frame[0])) {\n                    $frame.appendTo($stageShaft);\n                    unloadVideo(dataFrame.$video);\n                }\n\n                callFit(frameData.$img, measures);\n                callFit(frameData.$full, measures);\n\n                if ($frame.hasClass(stageFrameClass) && !($frame.attr('aria-hidden') === \"false\" && $frame.hasClass(activeClass))) {\n                    $frame.attr('aria-hidden', 'true');\n                }\n            });\n        }\n\n        function thumbsDraw(pos, loadFLAG) {\n            var leftLimit,\n                rightLimit,\n                exceedLimit;\n\n\n            if (o_nav !== 'thumbs' || isNaN(pos)) return;\n\n            leftLimit = -pos;\n            rightLimit = -pos + measures.nw;\n\n            if (opts.navdir === 'vertical') {\n                pos = pos - opts.thumbheight;\n                rightLimit = -pos + measures.h;\n            }\n\n            $navThumbFrame.each(function () {\n                var $this = $(this),\n                    thisData = $this.data(),\n                    eq = thisData.eq,\n                    getSpecialMeasures = function () {\n                        return {\n                            h: o_thumbSide2,\n                            w: thisData.w\n                        }\n                    },\n                    specialMeasures = getSpecialMeasures(),\n                    exceedLimit = opts.navdir === 'vertical' ?\n                    thisData.t > rightLimit : thisData.l > rightLimit;\n                specialMeasures.w = thisData.w;\n\n                if ((opts.navdir !== 'vertical' && thisData.l + thisData.w < leftLimit)\n                    || exceedLimit\n                    || callFit(thisData.$img, specialMeasures)) return;\n\n                loadFLAG && loadImg([eq], 'navThumb', getSpecialMeasures);\n            });\n        }\n\n        function frameAppend($frames, $shaft, type) {\n            if (!frameAppend[type]) {\n\n                var thumbsFLAG = type === 'nav' && o_navThumbs,\n                    left = 0,\n                    top = 0;\n\n                $shaft.append(\n                    $frames\n                        .filter(function () {\n                            var actual,\n                                $this = $(this),\n                                frameData = $this.data();\n                            for (var _i = 0, _l = data.length; _i < _l; _i++) {\n                                if (frameData.data === data[_i]) {\n                                    actual = true;\n                                    frameData.eq = _i;\n                                    break;\n                                }\n                            }\n                            return actual || $this.remove() && false;\n                        })\n                        .sort(function (a, b) {\n                            return $(a).data().eq - $(b).data().eq;\n                        })\n                        .each(function () {\n                            var $this = $(this),\n                                frameData = $this.data();\n                            UTIL.setThumbAttr($this, frameData.data.caption, \"aria-label\");\n                        })\n                        .each(function () {\n\n                            if (!thumbsFLAG) return;\n\n                            var $this = $(this),\n                                frameData = $this.data(),\n                                thumbwidth = Math.round(o_thumbSide2 * frameData.data.thumbratio) || o_thumbSide,\n                                thumbheight = Math.round(o_thumbSide / frameData.data.thumbratio) || o_thumbSide2;\n                            frameData.t = top;\n                            frameData.h = thumbheight;\n                            frameData.l = left;\n                            frameData.w = thumbwidth;\n\n                            $this.css({width: thumbwidth});\n\n                            top += thumbheight + opts.thumbmargin;\n                            left += thumbwidth + opts.thumbmargin;\n                        })\n                );\n\n                frameAppend[type] = true;\n            }\n        }\n\n        function getDirection(x) {\n            return x - stageLeft > measures.w / 3;\n        }\n\n        function disableDirrection(i) {\n            return !o_loop && (!(activeIndex + i) || !(activeIndex - size + i)) && !$videoPlaying;\n        }\n\n        function arrsUpdate() {\n            var disablePrev = disableDirrection(0),\n                disableNext = disableDirrection(1);\n            $arrPrev\n                .toggleClass(arrDisabledClass, disablePrev)\n                .attr(disableAttr(disablePrev, false));\n            $arrNext\n                .toggleClass(arrDisabledClass, disableNext)\n                .attr(disableAttr(disableNext, false));\n        }\n\n        function thumbArrUpdate() {\n            var isLeftDisable = false,\n                isRightDisable = false;\n            if (opts.navtype === 'thumbs' && !opts.loop) {\n                (activeIndex == 0) ? isLeftDisable = true : isLeftDisable = false;\n                (activeIndex == opts.data.length - 1) ? isRightDisable = true : isRightDisable = false;\n            }\n            if (opts.navtype === 'slides') {\n                var pos = readPosition($navShaft, opts.navdir);\n                pos >= navShaftTouchTail.max ? isLeftDisable = true : isLeftDisable = false;\n                pos <= Math.round(navShaftTouchTail.min) ? isRightDisable = true : isRightDisable = false;\n            }\n            $thumbArrLeft\n                .toggleClass(arrDisabledClass, isLeftDisable)\n                .attr(disableAttr(isLeftDisable, true));\n            $thumbArrRight\n                .toggleClass(arrDisabledClass, isRightDisable)\n                .attr(disableAttr(isRightDisable, true));\n        }\n\n        function stageWheelUpdate() {\n            if (stageWheelTail.ok) {\n                stageWheelTail.prevent = {'<': disableDirrection(0), '>': disableDirrection(1)};\n            }\n        }\n\n        function getNavFrameBounds($navFrame) {\n            var navFrameData = $navFrame.data(),\n                left,\n                top,\n                width,\n                height;\n\n            if (o_navThumbs) {\n                left = navFrameData.l;\n                top = navFrameData.t;\n                width = navFrameData.w;\n                height = navFrameData.h;\n            } else {\n                left = $navFrame.position().left;\n                width = $navFrame.width();\n            }\n\n            var horizontalBounds = {\n                c: left + width / 2,\n                min: -left + opts.thumbmargin * 10,\n                max: -left + measures.w - width - opts.thumbmargin * 10\n            };\n\n            var verticalBounds = {\n                c: top + height / 2,\n                min: -top + opts.thumbmargin * 10,\n                max: -top + measures.h - height - opts.thumbmargin * 10\n            };\n\n            return opts.navdir === 'vertical' ? verticalBounds : horizontalBounds;\n        }\n\n        function slideThumbBorder(time) {\n            var navFrameData = activeFrame[navFrameKey].data();\n            slide($thumbBorder, {\n                time: time * 1.2,\n                pos: (opts.navdir === 'vertical' ? navFrameData.t : navFrameData.l),\n                width: navFrameData.w,\n                height: navFrameData.h,\n                direction: opts.navdir\n            });\n        }\n\n        function slideNavShaft(options) {\n            var $guessNavFrame = data[options.guessIndex][navFrameKey],\n                typeOfAnimation = opts.navtype;\n\n            var overflowFLAG,\n                time,\n                minMax,\n                boundTop,\n                boundLeft,\n                l,\n                pos,\n                x;\n\n            if ($guessNavFrame) {\n                if (typeOfAnimation === 'thumbs') {\n                    overflowFLAG = navShaftTouchTail.min !== navShaftTouchTail.max;\n                    minMax = options.minMax || overflowFLAG && getNavFrameBounds(activeFrame[navFrameKey]);\n                    boundTop = overflowFLAG && (options.keep && slideNavShaft.t ? slideNavShaft.l : minMaxLimit((options.coo || measures.nw / 2) - getNavFrameBounds($guessNavFrame).c, minMax.min, minMax.max));\n                    boundLeft = overflowFLAG && (options.keep && slideNavShaft.l ? slideNavShaft.l : minMaxLimit((options.coo || measures.nw / 2) - getNavFrameBounds($guessNavFrame).c, minMax.min, minMax.max));\n                    l = (opts.navdir === 'vertical' ? boundTop : boundLeft);\n                    pos = overflowFLAG && minMaxLimit(l, navShaftTouchTail.min, navShaftTouchTail.max) || 0;\n                    time = options.time * 1.1;\n                    slide($navShaft, {\n                        time: time,\n                        pos: pos,\n                        direction: opts.navdir,\n                        onEnd: function () {\n                            thumbsDraw(pos, true);\n                            thumbArrUpdate();\n                        }\n                    });\n\n                    setShadow($nav, findShadowEdge(pos, navShaftTouchTail.min, navShaftTouchTail.max, opts.navdir));\n                    slideNavShaft.l = l;\n                } else {\n                    x = readPosition($navShaft, opts.navdir);\n                    time = options.time * 1.11;\n\n                    pos = validateSlidePos(opts, navShaftTouchTail, options.guessIndex, x, $guessNavFrame, $navWrap, opts.navdir);\n\n                    slide($navShaft, {\n                        time: time,\n                        pos: pos,\n                        direction: opts.navdir,\n                        onEnd: function () {\n                            thumbsDraw(pos, true);\n                            thumbArrUpdate();\n                        }\n                    });\n                    setShadow($nav, findShadowEdge(pos, navShaftTouchTail.min, navShaftTouchTail.max, opts.navdir));\n                }\n            }\n        }\n\n        function navUpdate() {\n            deactivateFrames(navFrameKey);\n            toDeactivate[navFrameKey].push(activeFrame[navFrameKey].addClass(activeClass).attr('data-active', true));\n        }\n\n        function deactivateFrames(key) {\n            var _toDeactivate = toDeactivate[key];\n\n            while (_toDeactivate.length) {\n                _toDeactivate.shift().removeClass(activeClass).attr('data-active', false);\n            }\n        }\n\n        function detachFrames(key) {\n            var _toDetach = toDetach[key];\n\n            $.each(activeIndexes, function (i, index) {\n                delete _toDetach[normalizeIndex(index)];\n            });\n\n            $.each(_toDetach, function (index, $frame) {\n                delete _toDetach[index];\n                $frame.detach();\n            });\n        }\n\n        function stageShaftReposition(skipOnEnd) {\n\n            repositionIndex = dirtyIndex = activeIndex;\n\n            var $frame = activeFrame[STAGE_FRAME_KEY];\n\n            if ($frame) {\n                deactivateFrames(STAGE_FRAME_KEY);\n                toDeactivate[STAGE_FRAME_KEY].push($frame.addClass(activeClass).attr('data-active', true));\n\n                if ($frame.hasClass(stageFrameClass)) {\n                    $frame.attr('aria-hidden', 'false');\n                }\n\n                skipOnEnd || that.showStage.onEnd(true);\n                stop($stageShaft, 0, true);\n\n                detachFrames(STAGE_FRAME_KEY);\n                stageFramePosition(activeIndexes);\n                setStageShaftMinmaxAndSnap();\n                setNavShaftMinMax();\n                addEnterUp($stageShaft[0], function () {\n                    if (!$fotorama.hasClass(fullscreenClass)) {\n                        that.requestFullScreen();\n                        $fullscreenIcon.focus();\n                    }\n                });\n            }\n        }\n\n        function extendMeasures(options, measuresArray) {\n            if (!options) return;\n\n            $.each(measuresArray, function (i, measures) {\n                if (!measures) return;\n\n                $.extend(measures, {\n                    width: options.width || measures.width,\n                    height: options.height,\n                    minwidth: options.minwidth,\n                    maxwidth: options.maxwidth,\n                    minheight: options.minheight,\n                    maxheight: options.maxheight,\n                    ratio: getRatio(options.ratio)\n                })\n            });\n        }\n\n        function triggerEvent(event, extra) {\n            $fotorama.trigger(_fotoramaClass + ':' + event, [that, extra]);\n        }\n\n        function onTouchStart() {\n            clearTimeout(onTouchEnd.t);\n            touchedFLAG = 1;\n\n            if (opts.stopautoplayontouch) {\n                that.stopAutoplay();\n            } else {\n                pausedAutoplayFLAG = true;\n            }\n        }\n\n        function onTouchEnd() {\n            if (!touchedFLAG) return;\n            if (!opts.stopautoplayontouch) {\n                releaseAutoplay();\n                changeAutoplay();\n            }\n\n            onTouchEnd.t = setTimeout(function () {\n                touchedFLAG = 0;\n            }, TRANSITION_DURATION + TOUCH_TIMEOUT);\n        }\n\n        function releaseAutoplay() {\n            pausedAutoplayFLAG = !!($videoPlaying || stoppedAutoplayFLAG);\n        }\n\n        function changeAutoplay() {\n\n            clearTimeout(changeAutoplay.t);\n            waitFor.stop(changeAutoplay.w);\n\n            if (!opts.autoplay || pausedAutoplayFLAG) {\n                if (that.autoplay) {\n                    that.autoplay = false;\n                    triggerEvent('stopautoplay');\n                }\n\n                return;\n            }\n\n            if (!that.autoplay) {\n                that.autoplay = true;\n                triggerEvent('startautoplay');\n            }\n\n            var _activeIndex = activeIndex;\n\n\n            var frameData = activeFrame[STAGE_FRAME_KEY].data();\n            changeAutoplay.w = waitFor(function () {\n                return frameData.state || _activeIndex !== activeIndex;\n            }, function () {\n                changeAutoplay.t = setTimeout(function () {\n\n                    if (pausedAutoplayFLAG || _activeIndex !== activeIndex) return;\n\n                    var _nextAutoplayIndex = nextAutoplayIndex,\n                        nextFrameData = data[_nextAutoplayIndex][STAGE_FRAME_KEY].data();\n\n                    changeAutoplay.w = waitFor(function () {\n\n                        return nextFrameData.state || _nextAutoplayIndex !== nextAutoplayIndex;\n                    }, function () {\n                        if (pausedAutoplayFLAG || _nextAutoplayIndex !== nextAutoplayIndex) return;\n                        that.show(o_loop ? getDirectionSign(!o_rtl) : nextAutoplayIndex);\n                    });\n                }, opts.autoplay);\n            });\n\n        }\n\n        that.startAutoplay = function (interval) {\n            if (that.autoplay) return this;\n            pausedAutoplayFLAG = stoppedAutoplayFLAG = false;\n            setAutoplayInterval(interval || opts.autoplay);\n            changeAutoplay();\n\n            return this;\n        };\n\n        that.stopAutoplay = function () {\n            if (that.autoplay) {\n                pausedAutoplayFLAG = stoppedAutoplayFLAG = true;\n                changeAutoplay();\n            }\n            return this;\n        };\n\n        that.showSlide = function (slideDir) {\n            var currentPosition = readPosition($navShaft, opts.navdir),\n                pos,\n                time = 500 * 1.1,\n                size = opts.navdir === 'horizontal' ? opts.thumbwidth : opts.thumbheight,\n                onEnd = function () {\n                    thumbArrUpdate();\n                };\n            if (slideDir === 'next') {\n                pos = currentPosition - (size + opts.margin) * thumbsPerSlide;\n            }\n            if (slideDir === 'prev') {\n                pos = currentPosition + (size + opts.margin) * thumbsPerSlide;\n            }\n            pos = validateRestrictions(pos, navShaftTouchTail);\n            thumbsDraw(pos, true);\n            slide($navShaft, {\n                time: time,\n                pos: pos,\n                direction: opts.navdir,\n                onEnd: onEnd\n            });\n        };\n\n        that.showWhileLongPress = function (options) {\n            if (that.longPress.singlePressInProgress) {\n                return;\n            }\n\n            var index = calcActiveIndex(options);\n            calcGlobalIndexes(index);\n            var time = calcTime(options) / 50;\n            var _activeFrame = activeFrame;\n            that.activeFrame = activeFrame = data[activeIndex];\n            var silent = _activeFrame === activeFrame && !options.user;\n\n            that.showNav(silent, options, time);\n\n            return this;\n        };\n\n        that.showEndLongPress = function (options) {\n            if (that.longPress.singlePressInProgress) {\n                return;\n            }\n\n            var index = calcActiveIndex(options);\n            calcGlobalIndexes(index);\n            var time = calcTime(options) / 50;\n            var _activeFrame = activeFrame;\n            that.activeFrame = activeFrame = data[activeIndex];\n\n            var silent = _activeFrame === activeFrame && !options.user;\n\n            that.showStage(silent, options, time);\n\n            showedFLAG = typeof lastActiveIndex !== 'undefined' && lastActiveIndex !== activeIndex;\n            lastActiveIndex = activeIndex;\n            return this;\n        };\n\n        function calcActiveIndex (options) {\n            var index;\n\n            if (typeof options !== 'object') {\n                index = options;\n                options = {};\n            } else {\n                index = options.index;\n            }\n\n            index = index === '>' ? dirtyIndex + 1 : index === '<' ? dirtyIndex - 1 : index === '<<' ? 0 : index === '>>' ? size - 1 : index;\n            index = isNaN(index) ? undefined : index;\n            index = typeof index === 'undefined' ? activeIndex || 0 : index;\n\n            return index;\n        }\n\n        function calcGlobalIndexes (index) {\n            that.activeIndex = activeIndex = edgeIndex(index);\n            prevIndex = getPrevIndex(activeIndex);\n            nextIndex = getNextIndex(activeIndex);\n            nextAutoplayIndex = normalizeIndex(activeIndex + (o_rtl ? -1 : 1));\n            activeIndexes = [activeIndex, prevIndex, nextIndex];\n\n            dirtyIndex = o_loop ? index : activeIndex;\n        }\n\n        function calcTime (options) {\n            var diffIndex = Math.abs(lastActiveIndex - dirtyIndex),\n                time = getNumber(options.time, function () {\n                    return Math.min(o_transitionDuration * (1 + (diffIndex - 1) / 12), o_transitionDuration * 2);\n                });\n\n            if (options.slow) {\n                time *= 10;\n            }\n\n            return time;\n        }\n\n        that.showStage = function (silent, options, time, e) {\n            if (e !== undefined && e.target.tagName == 'IFRAME') {\n                return;\n            }\n            unloadVideo($videoPlaying, activeFrame.i !== data[normalizeIndex(repositionIndex)].i);\n            frameDraw(activeIndexes, 'stage');\n            stageFramePosition(SLOW ? [dirtyIndex] : [dirtyIndex, getPrevIndex(dirtyIndex), getNextIndex(dirtyIndex)]);\n            updateTouchTails('go', true);\n\n            silent || triggerEvent('show', {\n                user: options.user,\n                time: time\n            });\n\n            pausedAutoplayFLAG = true;\n\n            var overPos = options.overPos;\n            var onEnd = that.showStage.onEnd = function (skipReposition) {\n                if (onEnd.ok) return;\n                onEnd.ok = true;\n\n                skipReposition || stageShaftReposition(true);\n\n                if (!silent) {\n                    triggerEvent('showend', {\n                        user: options.user\n                    });\n                }\n\n                if (!skipReposition && o_transition && o_transition !== opts.transition) {\n                    that.setOptions({transition: o_transition});\n                    o_transition = false;\n                    return;\n                }\n\n                updateFotoramaState();\n                loadImg(activeIndexes, 'stage');\n\n                updateTouchTails('go', false);\n                stageWheelUpdate();\n\n                stageCursor();\n                releaseAutoplay();\n                changeAutoplay();\n\n                if (that.fullScreen) {\n                    activeFrame[STAGE_FRAME_KEY].find('.' + imgFullClass).attr('aria-hidden', false);\n                    activeFrame[STAGE_FRAME_KEY].find('.' + imgClass).attr('aria-hidden', true)\n                } else {\n                    activeFrame[STAGE_FRAME_KEY].find('.' + imgFullClass).attr('aria-hidden', true);\n                    activeFrame[STAGE_FRAME_KEY].find('.' + imgClass).attr('aria-hidden', false)\n                }\n            };\n\n            if (!o_fade) {\n                slide($stageShaft, {\n                    pos: -getPosByIndex(dirtyIndex, measures.w, opts.margin, repositionIndex),\n                    overPos: overPos,\n                    time: time,\n                    onEnd: onEnd\n                });\n            } else {\n                var $activeFrame = activeFrame[STAGE_FRAME_KEY],\n                    $prevActiveFrame = data[lastActiveIndex] && activeIndex !== lastActiveIndex ? data[lastActiveIndex][STAGE_FRAME_KEY] : null;\n\n                fade($activeFrame, $prevActiveFrame, $stageFrame, {\n                    time: time,\n                    method: opts.transition,\n                    onEnd: onEnd\n                }, fadeStack);\n            }\n\n            arrsUpdate();\n        };\n\n        that.showNav = function(silent, options, time){\n            thumbArrUpdate();\n            if (o_nav) {\n                navUpdate();\n\n                var guessIndex = limitIndex(activeIndex + minMaxLimit(dirtyIndex - lastActiveIndex, -1, 1));\n                slideNavShaft({\n                    time: time,\n                    coo: guessIndex !== activeIndex && options.coo,\n                    guessIndex: typeof options.coo !== 'undefined' ? guessIndex : activeIndex,\n                    keep: silent\n                });\n                if (o_navThumbs) slideThumbBorder(time);\n            }\n        };\n\n        that.show = function (options, e) {\n            that.longPress.singlePressInProgress = true;\n\n            var index = calcActiveIndex(options);\n            calcGlobalIndexes(index);\n            var time = calcTime(options);\n            var _activeFrame = activeFrame;\n            that.activeFrame = activeFrame = data[activeIndex];\n\n            var silent = _activeFrame === activeFrame && !options.user;\n\n            that.showStage(silent, options, time, e);\n            that.showNav(silent, options, time);\n\n            showedFLAG = typeof lastActiveIndex !== 'undefined' && lastActiveIndex !== activeIndex;\n            lastActiveIndex = activeIndex;\n            that.longPress.singlePressInProgress = false;\n\n            return this;\n        };\n\n        that.requestFullScreen = function () {\n            if (o_allowFullScreen && !that.fullScreen) {\n\n                //check that this is not video\n                if(isVideo()) {\n                    return;\n                }\n\n                scrollTop = $WINDOW.scrollTop();\n                scrollLeft = $WINDOW.scrollLeft();\n\n                lockScroll($WINDOW);\n\n                updateTouchTails('x', true);\n\n                measuresStash = $.extend({}, measures);\n\n                $fotorama\n                    .addClass(fullscreenClass)\n                    .appendTo($BODY.addClass(_fullscreenClass));\n\n                $HTML.addClass(_fullscreenClass);\n\n                unloadVideo($videoPlaying, true, true);\n\n                that.fullScreen = true;\n\n                if (o_nativeFullScreen) {\n                    fullScreenApi.request(fotorama);\n                }\n\n                loadImg(activeIndexes, 'stage');\n                updateFotoramaState();\n                triggerEvent('fullscreenenter');\n                that.resize();\n\n                if (!('ontouchstart' in window)) {\n                    $fullscreenIcon.focus();\n                }\n            }\n\n            return this;\n        };\n\n        function cancelFullScreen() {\n            if (that.fullScreen) {\n                that.fullScreen = false;\n\n                if (FULLSCREEN) {\n                    fullScreenApi.cancel(fotorama);\n                }\n\n                $BODY.removeClass(_fullscreenClass);\n                $HTML.removeClass(_fullscreenClass);\n\n                $fotorama\n                    .removeClass(fullscreenClass)\n                    .insertAfter($anchor);\n\n                measures = $.extend({}, measuresStash);\n\n                unloadVideo($videoPlaying, true, true);\n\n                updateTouchTails('x', false);\n\n                that.resize();\n                loadImg(activeIndexes, 'stage');\n\n                lockScroll($WINDOW, scrollLeft, scrollTop);\n\n                triggerEvent('fullscreenexit');\n            }\n        }\n\n        that.cancelFullScreen = function () {\n            if (o_nativeFullScreen && fullScreenApi.is()) {\n                fullScreenApi.cancel(document);\n            } else {\n                cancelFullScreen();\n            }\n\n            return this;\n        };\n\n        that.toggleFullScreen = function () {\n            return that[(that.fullScreen ? 'cancel' : 'request') + 'FullScreen']();\n        };\n\n        that.resize = function (options) {\n            if (!data) return this;\n\n            var time = arguments[1] || 0,\n                setFLAG = arguments[2];\n\n            thumbsPerSlide = getThumbsInSlide($wrap, opts);\n            extendMeasures(!that.fullScreen ? optionsToLowerCase(options) : {\n                width: $(window).width(),\n                maxwidth: null,\n                minwidth: null,\n                height: $(window).height(),\n                maxheight: null,\n                minheight: null\n            }, [measures, setFLAG || that.fullScreen || opts]);\n\n            var width = measures.width,\n                height = measures.height,\n                ratio = measures.ratio,\n                windowHeight = $WINDOW.height() - (o_nav ? $nav.height() : 0);\n\n            if (measureIsValid(width)) {\n                $wrap.css({width: ''});\n                $stage.css({width: ''});\n                $stageShaft.css({width: ''});\n                $nav.css({width: ''});\n                $wrap.css({minWidth: measures.minwidth || 0, maxWidth: measures.maxwidth || MAX_WIDTH});\n\n                if (o_nav === 'dots') {\n                    $navWrap.hide();\n                }\n                width = measures.W = measures.w = $wrap.width();\n                measures.nw = o_nav && numberFromWhatever(opts.navwidth, width) || width;\n\n                $stageShaft.css({width: measures.w, marginLeft: (measures.W - measures.w) / 2});\n\n                height = numberFromWhatever(height, windowHeight);\n\n                height = height || (ratio && width / ratio);\n\n                if (height) {\n                    width = Math.round(width);\n                    height = measures.h = Math.round(minMaxLimit(height, numberFromWhatever(measures.minheight, windowHeight), numberFromWhatever(measures.maxheight, windowHeight)));\n                    $stage.css({'width': width, 'height': height});\n\n                    if (opts.navdir === 'vertical' && !that.fullscreen) {\n                        $nav.width(opts.thumbwidth + opts.thumbmargin * 2);\n                    }\n\n                    if (opts.navdir === 'horizontal' && !that.fullscreen) {\n                        $nav.height(opts.thumbheight + opts.thumbmargin * 2);\n                    }\n\n                    if (o_nav === 'dots') {\n                        $nav.width(width)\n                            .height('auto');\n                        $navWrap.show();\n                    }\n\n                    if (opts.navdir === 'vertical' && that.fullScreen) {\n                        $stage.css('height', $WINDOW.height());\n                    }\n\n                    if (opts.navdir === 'horizontal' && that.fullScreen) {\n                        $stage.css('height', $WINDOW.height() - $nav.height());\n                    }\n\n                    if (o_nav) {\n                        switch (opts.navdir) {\n                            case 'vertical':\n                                $navWrap.removeClass(navShafthorizontalClass);\n                                $navWrap.removeClass(navShaftListClass);\n                                $navWrap.addClass(navShaftVerticalClass);\n                                $nav\n                                    .stop()\n                                    .animate({height: measures.h, width: opts.thumbwidth}, time);\n                                break;\n                            case 'list':\n                                $navWrap.removeClass(navShaftVerticalClass);\n                                $navWrap.removeClass(navShafthorizontalClass);\n                                $navWrap.addClass(navShaftListClass);\n                                break;\n                            default:\n                                $navWrap.removeClass(navShaftVerticalClass);\n                                $navWrap.removeClass(navShaftListClass);\n                                $navWrap.addClass(navShafthorizontalClass);\n                                $nav\n                                    .stop()\n                                    .animate({width: measures.nw}, time);\n                                break;\n                        }\n\n                        stageShaftReposition();\n                        slideNavShaft({guessIndex: activeIndex, time: time, keep: true});\n                        if (o_navThumbs && frameAppend.nav) slideThumbBorder(time);\n                    }\n\n                    measuresSetFLAG = setFLAG || true;\n\n                    ready.ok = true;\n                    ready();\n                }\n            }\n\n            stageLeft = $stage.offset().left;\n            setStagePosition();\n\n            return this;\n        };\n\n        that.setOptions = function (options) {\n            $.extend(opts, options);\n            reset();\n            return this;\n        };\n\n        that.shuffle = function () {\n            data && shuffle(data) && reset();\n            return this;\n        };\n\n        function setShadow($el, edge) {\n            if (o_shadows) {\n                $el.removeClass(shadowsLeftClass + ' ' + shadowsRightClass);\n                $el.removeClass(shadowsTopClass + ' ' + shadowsBottomClass);\n                edge && !$videoPlaying && $el.addClass(edge.replace(/^|\\s/g, ' ' + shadowsClass + '--'));\n            }\n        }\n\n        that.longPress = {\n            threshold: 1,\n            count: 0,\n            thumbSlideTime: 20,\n            progress: function(){\n                if (!this.inProgress) {\n                    this.count++;\n                    this.inProgress = this.count > this.threshold;\n                }\n            },\n            end: function(){\n                if(this.inProgress) {\n                    this.isEnded = true\n                }\n            },\n            reset: function(){\n                this.count = 0;\n                this.inProgress = false;\n                this.isEnded = false;\n            }\n        };\n\n        that.destroy = function () {\n            that.cancelFullScreen();\n            that.stopAutoplay();\n\n            data = that.data = null;\n\n            appendElements();\n\n            activeIndexes = [];\n            detachFrames(STAGE_FRAME_KEY);\n\n            reset.ok = false;\n\n            return this;\n        };\n\n        /**\n         *\n         * @returns {jQuery.Fotorama}\n         */\n        that.playVideo = function () {\n            var dataFrame = activeFrame,\n                video = dataFrame.video,\n                _activeIndex = activeIndex;\n\n            if (typeof video === 'object' && dataFrame.videoReady) {\n                o_nativeFullScreen && that.fullScreen && that.cancelFullScreen();\n\n                waitFor(function () {\n                    return !fullScreenApi.is() || _activeIndex !== activeIndex;\n                }, function () {\n                    if (_activeIndex === activeIndex) {\n                        dataFrame.$video = dataFrame.$video || $(div(videoClass)).append(createVideoFrame(video));\n                        dataFrame.$video.appendTo(dataFrame[STAGE_FRAME_KEY]);\n\n                        $wrap.addClass(wrapVideoClass);\n                        $videoPlaying = dataFrame.$video;\n\n                        stageNoMove();\n\n                        $arrs.blur();\n                        $fullscreenIcon.blur();\n\n                        triggerEvent('loadvideo');\n                    }\n                });\n            }\n\n            return this;\n        };\n\n        that.stopVideo = function () {\n            unloadVideo($videoPlaying, true, true);\n            return this;\n        };\n\n        that.spliceByIndex = function (index, newImgObj) {\n            newImgObj.i = index + 1;\n            newImgObj.img && $.ajax({\n                url: newImgObj.img,\n                type: 'HEAD',\n                success: function () {\n                    data.splice(index, 1, newImgObj);\n                    reset();\n                }\n            });\n        };\n\n        function unloadVideo($video, unloadActiveFLAG, releaseAutoplayFLAG) {\n            if (unloadActiveFLAG) {\n                $wrap.removeClass(wrapVideoClass);\n                $videoPlaying = false;\n\n                stageNoMove();\n            }\n\n            if ($video && $video !== $videoPlaying) {\n                $video.remove();\n                triggerEvent('unloadvideo');\n            }\n\n            if (releaseAutoplayFLAG) {\n                releaseAutoplay();\n                changeAutoplay();\n            }\n        }\n\n        function toggleControlsClass(FLAG) {\n            $wrap.toggleClass(wrapNoControlsClass, FLAG);\n        }\n\n        function stageCursor(e) {\n            if (stageShaftTouchTail.flow) return;\n\n            var x = e ? e.pageX : stageCursor.x,\n                pointerFLAG = x && !disableDirrection(getDirection(x)) && opts.click;\n\n            if (stageCursor.p !== pointerFLAG\n                && $stage.toggleClass(pointerClass, pointerFLAG)) {\n                stageCursor.p = pointerFLAG;\n                stageCursor.x = x;\n            }\n        }\n\n        $stage.on('mousemove', stageCursor);\n\n        function clickToShow(showOptions, e) {\n            clearTimeout(clickToShow.t);\n\n            if (opts.clicktransition && opts.clicktransition !== opts.transition) {\n                setTimeout(function () {\n                    var _o_transition = opts.transition;\n\n                    that.setOptions({transition: opts.clicktransition});\n\n                    // now safe to pass base transition to o_transition, so that.show will restor it\n                    o_transition = _o_transition;\n                    // this timeout is here to prevent jerking in some browsers\n                    clickToShow.t = setTimeout(function () {\n                        that.show(showOptions);\n                    }, 10);\n                }, 0);\n            } else {\n                that.show(showOptions, e);\n            }\n        }\n\n        function onStageTap(e, toggleControlsFLAG) {\n            var target = e.target,\n                $target = $(target);\n            if ($target.hasClass(videoPlayClass)) {\n                that.playVideo();\n            } else if (target === fullscreenIcon) {\n                that.toggleFullScreen();\n            } else if ($videoPlaying) {\n                target === videoClose && unloadVideo($videoPlaying, true, true);\n            } else if (!$fotorama.hasClass(fullscreenClass)) {\n                that.requestFullScreen();\n            }\n        }\n\n        function updateTouchTails(key, value) {\n            stageShaftTouchTail[key] = navShaftTouchTail[key] = value;\n        }\n\n        stageShaftTouchTail = moveOnTouch($stageShaft, {\n            onStart: onTouchStart,\n            onMove: function (e, result) {\n                setShadow($stage, result.edge);\n            },\n            onTouchEnd: onTouchEnd,\n            onEnd: function (result) {\n                var toggleControlsFLAG;\n\n                setShadow($stage);\n                toggleControlsFLAG = (MS_POINTER && !hoverFLAG || result.touch) &&\n                    opts.arrows;\n\n                if ((result.moved || (toggleControlsFLAG && result.pos !== result.newPos && !result.control)) && result.$target[0] !== $fullscreenIcon[0]) {\n                    var index = getIndexByPos(result.newPos, measures.w, opts.margin, repositionIndex);\n\n                    that.show({\n                        index: index,\n                        time: o_fade ? o_transitionDuration : result.time,\n                        overPos: result.overPos,\n                        user: true\n                    });\n                } else if (!result.aborted && !result.control) {\n                    onStageTap(result.startEvent, toggleControlsFLAG);\n                }\n            },\n            timeLow: 1,\n            timeHigh: 1,\n            friction: 2,\n            select: '.' + selectClass + ', .' + selectClass + ' *',\n            $wrap: $stage,\n            direction: 'horizontal'\n\n        });\n\n        navShaftTouchTail = moveOnTouch($navShaft, {\n            onStart: onTouchStart,\n            onMove: function (e, result) {\n                setShadow($nav, result.edge);\n            },\n            onTouchEnd: onTouchEnd,\n            onEnd: function (result) {\n\n                function onEnd() {\n                    slideNavShaft.l = result.newPos;\n                    releaseAutoplay();\n                    changeAutoplay();\n                    thumbsDraw(result.newPos, true);\n                    thumbArrUpdate();\n                }\n\n                if (!result.moved) {\n                    var target = result.$target.closest('.' + navFrameClass, $navShaft)[0];\n                    target && onNavFrameClick.call(target, result.startEvent);\n                } else if (result.pos !== result.newPos) {\n                    pausedAutoplayFLAG = true;\n                    slide($navShaft, {\n                        time: result.time,\n                        pos: result.newPos,\n                        overPos: result.overPos,\n                        direction: opts.navdir,\n                        onEnd: onEnd\n                    });\n                    thumbsDraw(result.newPos);\n                    o_shadows && setShadow($nav, findShadowEdge(result.newPos, navShaftTouchTail.min, navShaftTouchTail.max, result.dir));\n                } else {\n                    onEnd();\n                }\n            },\n            timeLow: .5,\n            timeHigh: 2,\n            friction: 5,\n            $wrap: $nav,\n            direction: opts.navdir\n        });\n\n        stageWheelTail = wheel($stage, {\n            shift: true,\n            onEnd: function (e, direction) {\n                onTouchStart();\n                onTouchEnd();\n                that.show({index: direction, slow: e.altKey})\n            }\n        });\n\n        navWheelTail = wheel($nav, {\n            onEnd: function (e, direction) {\n                onTouchStart();\n                onTouchEnd();\n                var newPos = stop($navShaft) + direction * .25;\n                $navShaft.css(getTranslate(minMaxLimit(newPos, navShaftTouchTail.min, navShaftTouchTail.max), opts.navdir));\n                o_shadows && setShadow($nav, findShadowEdge(newPos, navShaftTouchTail.min, navShaftTouchTail.max, opts.navdir));\n                navWheelTail.prevent = {'<': newPos >= navShaftTouchTail.max, '>': newPos <= navShaftTouchTail.min};\n                clearTimeout(navWheelTail.t);\n                navWheelTail.t = setTimeout(function () {\n                    slideNavShaft.l = newPos;\n                    thumbsDraw(newPos, true)\n                }, TOUCH_TIMEOUT);\n                thumbsDraw(newPos);\n            }\n        });\n\n        $wrap.hover(\n            function () {\n                setTimeout(function () {\n                    if (touchedFLAG) return;\n                    toggleControlsClass(!(hoverFLAG = true));\n                }, 0);\n            },\n            function () {\n                if (!hoverFLAG) return;\n                toggleControlsClass(!(hoverFLAG = false));\n            }\n        );\n\n        function onNavFrameClick(e) {\n            var index = $(this).data().eq;\n\n            if (opts.navtype === 'thumbs') {\n                clickToShow({index: index, slow: e.altKey, user: true, coo: e._x - $nav.offset().left});\n            } else {\n                clickToShow({index: index, slow: e.altKey, user: true});\n            }\n        }\n\n        function onArrClick(e) {\n            clickToShow({index: $arrs.index(this) ? '>' : '<', slow: e.altKey, user: true});\n        }\n\n        smartClick($arrs, function (e) {\n            stopEvent(e);\n            onArrClick.call(this, e);\n        }, {\n            onStart: function () {\n                onTouchStart();\n                stageShaftTouchTail.control = true;\n            },\n            onTouchEnd: onTouchEnd\n        });\n\n        smartClick($thumbArrLeft, function (e) {\n            stopEvent(e);\n            if (opts.navtype === 'thumbs') {\n\n                that.show('<');\n            } else {\n                that.showSlide('prev')\n            }\n        });\n\n        smartClick($thumbArrRight, function (e) {\n            stopEvent(e);\n            if (opts.navtype === 'thumbs') {\n                that.show('>');\n            } else {\n                that.showSlide('next')\n            }\n\n        });\n\n\n        function addFocusOnControls(el) {\n            addFocus(el, function () {\n                setTimeout(function () {\n                    lockScroll($stage);\n                }, 0);\n                toggleControlsClass(false);\n            });\n        }\n\n        $arrs.each(function () {\n            addEnterUp(this, function (e) {\n                onArrClick.call(this, e);\n            });\n            addFocusOnControls(this);\n        });\n\n        addEnterUp(fullscreenIcon, function () {\n            if ($fotorama.hasClass(fullscreenClass)) {\n                that.cancelFullScreen();\n                $stageShaft.focus();\n            } else {\n                that.requestFullScreen();\n                $fullscreenIcon.focus();\n            }\n\n        });\n        addFocusOnControls(fullscreenIcon);\n\n        function reset() {\n            setData();\n            setOptions();\n\n            if (!reset.i) {\n                reset.i = true;\n                // Only once\n                var _startindex = opts.startindex;\n                activeIndex = repositionIndex = dirtyIndex = lastActiveIndex = startIndex = edgeIndex(_startindex) || 0;\n                /*(o_rtl ? size - 1 : 0)*///;\n            }\n\n            if (size) {\n                if (changeToRtl()) return;\n\n                if ($videoPlaying) {\n                    unloadVideo($videoPlaying, true);\n                }\n\n                activeIndexes = [];\n\n                if (!isVideo()) {\n                    detachFrames(STAGE_FRAME_KEY);\n                }\n\n                reset.ok = true;\n\n                that.show({index: activeIndex, time: 0});\n                that.resize();\n            } else {\n                that.destroy();\n            }\n        }\n\n        function changeToRtl() {\n\n            if (!changeToRtl.f === o_rtl) {\n                changeToRtl.f = o_rtl;\n                activeIndex = size - 1 - activeIndex;\n                that.reverse();\n\n                return true;\n            }\n        }\n\n        $.each('load push pop shift unshift reverse sort splice'.split(' '), function (i, method) {\n            that[method] = function () {\n                data = data || [];\n                if (method !== 'load') {\n                    Array.prototype[method].apply(data, arguments);\n                } else if (arguments[0] && typeof arguments[0] === 'object' && arguments[0].length) {\n                    data = clone(arguments[0]);\n                }\n                reset();\n                return that;\n            }\n        });\n\n        function ready() {\n            if (ready.ok) {\n                ready.ok = false;\n                triggerEvent('ready');\n            }\n        }\n\n        reset();\n    };\n    $.fn.fotorama = function (opts) {\n        return this.each(function () {\n            var that = this,\n                $fotorama = $(this),\n                fotoramaData = $fotorama.data(),\n                fotorama = fotoramaData.fotorama;\n\n            if (!fotorama) {\n                waitFor(function () {\n                    return !isHidden(that);\n                }, function () {\n                    fotoramaData.urtext = $fotorama.html();\n                    new $.Fotorama($fotorama,\n                        $.extend(\n                            {},\n                            OPTIONS,\n                            window.fotoramaDefaults,\n                            opts,\n                            fotoramaData\n                        )\n                    );\n                });\n            } else {\n                fotorama.setOptions(opts, true);\n            }\n        });\n    };\n    $.Fotorama.instances = [];\n\n    function calculateIndexes() {\n        $.each($.Fotorama.instances, function (index, instance) {\n            instance.index = index;\n        });\n    }\n\n    function addInstance(instance) {\n        $.Fotorama.instances.push(instance);\n        calculateIndexes();\n    }\n\n    function hideInstance(instance) {\n        $.Fotorama.instances.splice(instance.index, 1);\n        calculateIndexes();\n    }\n\n    $.Fotorama.cache = {};\n    $.Fotorama.measures = {};\n    $ = $ || {};\n    $.Fotorama = $.Fotorama || {};\n    $.Fotorama.jst = $.Fotorama.jst || {};\n\n    $.Fotorama.jst.dots = function (v) {\n        var __t, __p = '', __e = _.escape;\n        __p += '<div class=\"fotorama__nav__frame fotorama__nav__frame--dot\" tabindex=\"0\" role=\"button\" data-gallery-role=\"nav-frame\" data-nav-type=\"thumb\" aria-label>\\r\\n    <div class=\"fotorama__dot\"></div>\\r\\n</div>';\n        return __p\n    };\n\n    $.Fotorama.jst.frameCaption = function (v) {\n        var __t, __p = '', __e = _.escape;\n        __p += '<div class=\"fotorama__caption\" aria-hidden=\"true\">\\r\\n    <div class=\"fotorama__caption__wrap\" id=\"' +\n            ((__t = ( v.labelledby )) == null ? '' : __t) +\n            '\">' +\n            ((__t = ( v.caption )) == null ? '' : __t) +\n            '</div>\\r\\n</div>\\r\\n';\n        return __p\n    };\n\n    $.Fotorama.jst.style = function (v) {\n        var __t, __p = '', __e = _.escape;\n        __p += '.fotorama' +\n            ((__t = ( v.s )) == null ? '' : __t) +\n            ' .fotorama__nav--thumbs .fotorama__nav__frame{\\r\\npadding:' +\n            ((__t = ( v.m )) == null ? '' : __t) +\n            'px;\\r\\nheight:' +\n            ((__t = ( v.h )) == null ? '' : __t) +\n            'px}\\r\\n.fotorama' +\n            ((__t = ( v.s )) == null ? '' : __t) +\n            ' .fotorama__thumb-border{\\r\\nheight:' +\n            ((__t = ( v.h )) == null ? '' : __t) +\n            'px;\\r\\nborder-width:' +\n            ((__t = ( v.b )) == null ? '' : __t) +\n            'px;\\r\\nmargin-top:' +\n            ((__t = ( v.m )) == null ? '' : __t) +\n            'px}';\n        return __p\n    };\n\n    $.Fotorama.jst.thumb = function (v) {\n        var __t, __p = '', __e = _.escape;\n        __p += '<div class=\"fotorama__nav__frame fotorama__nav__frame--thumb\" tabindex=\"0\" role=\"button\" data-gallery-role=\"nav-frame\" data-nav-type=\"thumb\" aria-label>\\r\\n    <div class=\"fotorama__thumb\">\\r\\n    </div>\\r\\n</div>';\n        return __p\n    };\n})(window, document, location, typeof jQuery !== 'undefined' && jQuery);\n","Magento_CardinalCommerce/js/cardinal-client.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'uiClass',\n    'Magento_CardinalCommerce/js/cardinal-factory',\n    'Magento_Checkout/js/model/quote',\n    'mage/translate'\n], function ($, Class, cardinalFactory, quote, $t) {\n    'use strict';\n\n    return {\n        /**\n         * Starts Cardinal Consumer Authentication\n         *\n         * @param {Object} cardData\n         * @return {jQuery.Deferred}\n         */\n        startAuthentication: function (cardData) {\n            var deferred = $.Deferred();\n\n            if (this.cardinalClient) {\n                this._startAuthentication(deferred, cardData);\n            } else {\n                cardinalFactory(this.getEnvironment())\n                    .done(function (client) {\n                        this.cardinalClient = client;\n                        this._startAuthentication(deferred, cardData);\n                    }.bind(this));\n            }\n\n            return deferred.promise();\n        },\n\n        /**\n         * Cardinal Consumer Authentication\n         *\n         * @param {jQuery.Deferred} deferred\n         * @param {Object} cardData\n         */\n        _startAuthentication: function (deferred, cardData) {\n            //this.cardinalClient.configure({ logging: { level: 'verbose' } });\n            this.cardinalClient.on('payments.validated', function (data, jwt) {\n                if (data.ErrorNumber !== 0) {\n                    deferred.reject(data.ErrorDescription);\n                } else if ($.inArray(data.ActionCode, ['FAILURE', 'ERROR']) !== -1) {\n                    deferred.reject($t('Authentication Failed. Please try again with another form of payment.'));\n                } else {\n                    deferred.resolve(jwt);\n                }\n                this.cardinalClient.off('payments.validated');\n            }.bind(this));\n\n            this.cardinalClient.on('payments.setupComplete', function () {\n                this.cardinalClient.start('cca', this.getRequestOrderObject(cardData));\n                this.cardinalClient.off('payments.setupComplete');\n            }.bind(this));\n\n            this.cardinalClient.setup('init', {\n                jwt: this.getRequestJWT()\n            });\n        },\n\n        /**\n         * Returns request order object.\n         *\n         * The request order object is structured object that is used to pass data\n         * to Cardinal that describes an order you'd like to process.\n         *\n         * If you pass a request object in both the JWT and the browser,\n         * Cardinal will merge the objects together where the browser overwrites\n         * the JWT object as it is considered the most recently captured data.\n         *\n         * @param {Object} cardData\n         * @returns {Object}\n         */\n        getRequestOrderObject: function (cardData) {\n            var totalAmount = quote.totals()['base_grand_total'],\n                currencyCode = quote.totals()['base_currency_code'],\n                billingAddress = quote.billingAddress(),\n                requestObject;\n\n            requestObject = {\n                OrderDetails: {\n                    Amount: totalAmount * 100,\n                    CurrencyCode: currencyCode\n                },\n                Consumer: {\n                    Account: {\n                        AccountNumber: cardData.accountNumber,\n                        ExpirationMonth: cardData.expMonth,\n                        ExpirationYear: cardData.expYear,\n                        CardCode: cardData.cardCode\n                    },\n                    BillingAddress: {\n                        FirstName: billingAddress.firstname,\n                        LastName: billingAddress.lastname,\n                        Address1: billingAddress.street[0],\n                        Address2: billingAddress.street[1],\n                        City: billingAddress.city,\n                        State: billingAddress.region,\n                        PostalCode: billingAddress.postcode,\n                        CountryCode: billingAddress.countryId,\n                        Phone1: billingAddress.telephone\n                    }\n                }\n            };\n\n            return requestObject;\n        },\n\n        /**\n         * Returns request JWT\n         * @returns {String}\n         */\n        getRequestJWT: function () {\n            return window.checkoutConfig.cardinal.requestJWT;\n        },\n\n        /**\n         * Returns type of environment\n         * @returns {String}\n         */\n        getEnvironment: function () {\n            return window.checkoutConfig.cardinal.environment;\n        }\n    };\n});\n","Magento_CardinalCommerce/js/cardinal-factory.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 (environment) {\n        var deferred = $.Deferred(),\n            dependency = 'cardinaljs';\n\n        if (environment === 'sandbox') {\n            dependency = 'cardinaljsSandbox';\n        }\n\n        require(\n            [dependency],\n            function (Cardinal) {\n                deferred.resolve(Cardinal);\n            },\n            deferred.reject\n        );\n\n        return deferred.promise();\n    };\n});\n","js-storage/storage-wrapper.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'js-storage/js.storage'\n], function ($, storage) {\n    'use strict';\n\n    if (window.cookieStorage) {\n        var cookiesConfig = window.cookiesConfig || {};\n\n        $.extend(window.cookieStorage, {\n            _secure: !!cookiesConfig.secure,\n            _samesite: cookiesConfig.samesite ? cookiesConfig.samesite : 'lax',\n\n            /**\n             * Set value under name\n             * @param {String} name\n             * @param {String} value\n             * @param {Object} [options]\n             */\n            setItem: function (name, value, options) {\n                var _default = {\n                    expires: this._expires,\n                    path: this._path,\n                    domain: this._domain,\n                    secure: this._secure,\n                    samesite: this._samesite\n                };\n\n                $.cookie(this._prefix + name, value, $.extend(_default, options || {}));\n            },\n\n            /**\n             * Set default options\n             * @param {Object} c\n             * @returns {storage}\n             */\n            setConf: function (c) {\n                if (c.path) {\n                    this._path = c.path;\n                }\n\n                if (c.domain) {\n                    this._domain = c.domain;\n                }\n\n                if (c.expires) {\n                    this._expires = c.expires;\n                }\n\n                if (typeof c.secure !== 'undefined') {\n                    this._secure = c.secure;\n                }\n\n                if (typeof c.samesite !== 'undefined') {\n                    this._samesite = c.samesite;\n                }\n\n                return this;\n            }\n        });\n    }\n\n    $.alwaysUseJsonInStorage = $.alwaysUseJsonInStorage || storage.alwaysUseJsonInStorage;\n    $.cookieStorage = $.cookieStorage || storage.cookieStorage;\n    $.initNamespaceStorage = $.initNamespaceStorage || storage.initNamespaceStorage;\n    $.localStorage = $.localStorage || storage.localStorage;\n    $.namespaceStorages = $.namespaceStorages || storage.namespaceStorages;\n    $.removeAllStorages = $.removeAllStorages || storage.removeAllStorages;\n    $.sessionStorage = $.sessionStorage || storage.sessionStorage;\n});\n","js-storage/js.storage.js":"/*\n * JS Storage Plugin\n *\n * Copyright (c) 2019 Julien Maurel\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/mit-license.php\n *\n * Project home:\n * https://github.com/julien-maurel/js-storage\n *\n * Version: 1.1.0\n */\n(function (factory) {\n    var registeredInModuleLoader = false;\n    if (typeof define === 'function' && define.amd) {\n        define(['jquery', 'jquery/jquery.cookie'], factory);\n        registeredInModuleLoader = true;\n    }\n    if (typeof exports === 'object') {\n        module.exports = factory();\n        registeredInModuleLoader = true;\n    }\n    if (!registeredInModuleLoader) {\n        var OldStorages = window.Storages;\n        var api = window.Storages = factory();\n        api.noConflict = function () {\n            window.Storages = OldStorages;\n            return api;\n        };\n    }\n}(function () {\n    // Variables used by utilities functions (like isPlainObject...)\n    var class2type = {};\n    var toString = class2type.toString;\n    var hasOwn = class2type.hasOwnProperty;\n    var fnToString = hasOwn.toString;\n    var ObjectFunctionString = fnToString.call(Object);\n    var getProto = Object.getPrototypeOf;\n    var apis = {};\n\n    // Prefix to use with cookie fallback\n    var cookie_local_prefix = \"ls_\";\n    var cookie_session_prefix = \"ss_\";\n\n    // Get items from a storage\n    function _get() {\n        var storage = this._type, l = arguments.length, s = window[storage], a = arguments, a0 = a[0], vi, ret, tmp, i, j;\n        if (l < 1) {\n            throw new Error('Minimum 1 argument must be given');\n        } else if (Array.isArray(a0)) {\n            // If second argument is an array, return an object with value of storage for each item in this array\n            ret = {};\n            for (i in a0) {\n                if (a0.hasOwnProperty(i)) {\n                    vi = a0[i];\n                    try {\n                        ret[vi] = JSON.parse(s.getItem(vi));\n                    } catch (e) {\n                        ret[vi] = s.getItem(vi);\n                    }\n                }\n            }\n            return ret;\n        } else if (l == 1) {\n            // If only 1 argument, return value directly\n            try {\n                return JSON.parse(s.getItem(a0));\n            } catch (e) {\n                return s.getItem(a0);\n            }\n        } else {\n            // If more than 1 argument, parse storage to retrieve final value to return it\n            // Get first level\n            try {\n                ret = JSON.parse(s.getItem(a0));\n                if (!ret) {\n                    throw new ReferenceError(a0 + ' is not defined in this storage');\n                }\n            } catch (e) {\n                throw new ReferenceError(a0 + ' is not defined in this storage');\n            }\n            // Parse next levels\n            for (i = 1; i < l - 1; i++) {\n                ret = ret[a[i]];\n                if (ret === undefined) {\n                    throw new ReferenceError([].slice.call(a, 0, i + 1).join('.') + ' is not defined in this storage');\n                }\n            }\n            // If last argument is an array, return an object with value for each item in this array\n            // Else return value normally\n            if (Array.isArray(a[i])) {\n                tmp = ret;\n                ret = {};\n                for (j in a[i]) {\n                    if (a[i].hasOwnProperty(j)) {\n                        ret[a[i][j]] = tmp[a[i][j]];\n                    }\n                }\n                return ret;\n            } else {\n                return ret[a[i]];\n            }\n        }\n    }\n\n    // Set items of a storage\n    function _set() {\n        var storage = this._type, l = arguments.length, s = window[storage], a = arguments, a0 = a[0], a1 = a[1], vi, to_store = isNaN(a1) ? {} : [], type, tmp, i;\n        if (l < 1 || !_isPlainObject(a0) && l < 2) {\n            throw new Error('Minimum 2 arguments must be given or first parameter must be an object');\n        } else if (_isPlainObject(a0)) {\n            // If first argument is an object, set values of storage for each property of this object\n            for (i in a0) {\n                if (a0.hasOwnProperty(i)) {\n                    vi = a0[i];\n                    if (!_isPlainObject(vi) && !this.alwaysUseJson) {\n                        s.setItem(i, vi);\n                    } else {\n                        s.setItem(i, JSON.stringify(vi));\n                    }\n                }\n            }\n            return a0;\n        } else if (l == 2) {\n            // If only 2 arguments, set value of storage directly\n            if (typeof a1 === 'object' || this.alwaysUseJson) {\n                s.setItem(a0, JSON.stringify(a1));\n            } else {\n                s.setItem(a0, a1);\n            }\n            return a1;\n        } else {\n            // If more than 3 arguments, parse storage to retrieve final node and set value\n            // Get first level\n            try {\n                tmp = s.getItem(a0);\n                if (tmp != null) {\n                    to_store = JSON.parse(tmp);\n                }\n            } catch (e) {\n            }\n            tmp = to_store;\n            // Parse next levels and set value\n            for (i = 1; i < l - 2; i++) {\n                vi = a[i];\n                type = isNaN(a[i + 1]) ? \"object\" : \"array\";\n                if (!tmp[vi] || type == \"object\" && !_isPlainObject(tmp[vi]) || type == \"array\" && !Array.isArray(tmp[vi])) {\n                    if (type == \"array\") tmp[vi] = [];\n                    else tmp[vi] = {};\n                }\n                tmp = tmp[vi];\n            }\n            tmp[a[i]] = a[i + 1];\n            s.setItem(a0, JSON.stringify(to_store));\n            return to_store;\n        }\n    }\n\n    // Remove items from a storage\n    function _remove() {\n        var storage = this._type, l = arguments.length, s = window[storage], a = arguments, a0 = a[0], to_store, tmp, i, j;\n        if (l < 1) {\n            throw new Error('Minimum 1 argument must be given');\n        } else if (Array.isArray(a0)) {\n            // If first argument is an array, remove values from storage for each item of this array\n            for (i in a0) {\n                if (a0.hasOwnProperty(i)) {\n                    s.removeItem(a0[i]);\n                }\n            }\n            return true;\n        } else if (l == 1) {\n            // If only 2 arguments, remove value from storage directly\n            s.removeItem(a0);\n            return true;\n        } else {\n            // If more than 2 arguments, parse storage to retrieve final node and remove value\n            // Get first level\n            try {\n                to_store = tmp = JSON.parse(s.getItem(a0));\n            } catch (e) {\n                throw new ReferenceError(a0 + ' is not defined in this storage');\n            }\n            // Parse next levels and remove value\n            for (i = 1; i < l - 1; i++) {\n                tmp = tmp[a[i]];\n                if (tmp === undefined) {\n                    throw new ReferenceError([].slice.call(a, 1, i).join('.') + ' is not defined in this storage');\n                }\n            }\n            // If last argument is an array,remove value for each item in this array\n            // Else remove value normally\n            if (Array.isArray(a[i])) {\n                for (j in a[i]) {\n                    if (a[i].hasOwnProperty(j)) {\n                        delete tmp[a[i][j]];\n                    }\n                }\n            } else {\n                delete tmp[a[i]];\n            }\n            s.setItem(a0, JSON.stringify(to_store));\n            return true;\n        }\n    }\n\n    // Remove all items from a storage\n    function _removeAll(reinit_ns) {\n        var keys = _keys.call(this), i;\n        for (i in keys) {\n            if (keys.hasOwnProperty(i)) {\n                _remove.call(this, keys[i]);\n            }\n        }\n        // Reinitialize all namespace storages\n        if (reinit_ns) {\n            for (i in apis.namespaceStorages) {\n                if (apis.namespaceStorages.hasOwnProperty(i)) {\n                    _createNamespace(i);\n                }\n            }\n        }\n    }\n\n    // Check if items of a storage are empty\n    function _isEmpty() {\n        var l = arguments.length, a = arguments, a0 = a[0], i;\n        if (l == 0) {\n            // If no argument, test if storage is empty\n            return (_keys.call(this).length == 0);\n        } else if (Array.isArray(a0)) {\n            // If first argument is an array, test each item of this array and return true only if all items are empty\n            for (i = 0; i < a0.length; i++) {\n                if (!_isEmpty.call(this, a0[i])) {\n                    return false;\n                }\n            }\n            return true;\n        } else {\n            // If at least 1 argument, try to get value and test it\n            try {\n                var v = _get.apply(this, arguments);\n                // Convert result to an object (if last argument is an array, _get return already an object) and test each item\n                if (!Array.isArray(a[l - 1])) {\n                    v = {'totest': v};\n                }\n                for (i in v) {\n                    if (v.hasOwnProperty(i) && !(\n                        (_isPlainObject(v[i]) && _isEmptyObject(v[i])) ||\n                        (Array.isArray(v[i]) && !v[i].length) ||\n                        (typeof v[i] !== 'boolean' && !v[i])\n                    )) {\n                        return false;\n                    }\n                }\n                return true;\n            } catch (e) {\n                return true;\n            }\n        }\n    }\n\n    // Check if items of a storage exist\n    function _isSet() {\n        var l = arguments.length, a = arguments, a0 = a[0], i;\n        if (l < 1) {\n            throw new Error('Minimum 1 argument must be given');\n        }\n        if (Array.isArray(a0)) {\n            // If first argument is an array, test each item of this array and return true only if all items exist\n            for (i = 0; i < a0.length; i++) {\n                if (!_isSet.call(this, a0[i])) {\n                    return false;\n                }\n            }\n            return true;\n        } else {\n            // For other case, try to get value and test it\n            try {\n                var v = _get.apply(this, arguments);\n                // Convert result to an object (if last argument is an array, _get return already an object) and test each item\n                if (!Array.isArray(a[l - 1])) {\n                    v = {'totest': v};\n                }\n                for (i in v) {\n                    if (v.hasOwnProperty(i) && !(v[i] !== undefined && v[i] !== null)) {\n                        return false;\n                    }\n                }\n                return true;\n            } catch (e) {\n                return false;\n            }\n        }\n    }\n\n    // Get keys of a storage or of an item of the storage\n    function _keys() {\n        var storage = this._type, l = arguments.length, s = window[storage], keys = [], o = {};\n        // If at least 1 argument, get value from storage to retrieve keys\n        // Else, use storage to retrieve keys\n        if (l > 0) {\n            o = _get.apply(this, arguments);\n        } else {\n            o = s;\n        }\n        if (o && o._cookie) {\n            // If storage is a cookie, use js-cookie to retrieve keys\n            var cookies = Cookies.get();\n            for (var key in cookies) {\n                if (cookies.hasOwnProperty(key) && key != '') {\n                    keys.push(key.replace(o._prefix, ''));\n                }\n            }\n        } else {\n            for (var i in o) {\n                if (o.hasOwnProperty(i)) {\n                    keys.push(i);\n                }\n            }\n        }\n        return keys;\n    }\n\n    // Create new namespace storage\n    function _createNamespace(name) {\n        if (!name || typeof name != \"string\") {\n            throw new Error('First parameter must be a string');\n        }\n        if (storage_available) {\n            if (!window.localStorage.getItem(name)) {\n                window.localStorage.setItem(name, '{}');\n            }\n            if (!window.sessionStorage.getItem(name)) {\n                window.sessionStorage.setItem(name, '{}');\n            }\n        } else {\n            if (!window.localCookieStorage.getItem(name)) {\n                window.localCookieStorage.setItem(name, '{}');\n            }\n            if (!window.sessionCookieStorage.getItem(name)) {\n                window.sessionCookieStorage.setItem(name, '{}');\n            }\n        }\n        var ns = {\n            localStorage: _extend({}, apis.localStorage, {_ns: name}),\n            sessionStorage: _extend({}, apis.sessionStorage, {_ns: name})\n        };\n        if (cookies_available) {\n            if (!window.cookieStorage.getItem(name)) {\n                window.cookieStorage.setItem(name, '{}');\n            }\n            ns.cookieStorage = _extend({}, apis.cookieStorage, {_ns: name});\n        }\n        apis.namespaceStorages[name] = ns;\n        return ns;\n    }\n\n    // Test if storage is natively available on browser\n    function _testStorage(name) {\n        var foo = 'jsapi';\n        try {\n            if (!window[name]) {\n                return false;\n            }\n            window[name].setItem(foo, foo);\n            window[name].removeItem(foo);\n            return true;\n        } catch (e) {\n            return false;\n        }\n    }\n\n    // Test if a variable is a plain object (from jQuery)\n    function _isPlainObject(obj) {\n        var proto, Ctor;\n\n        // Detect obvious negatives\n        // Use toString instead of jQuery.type to catch host objects\n        if (!obj || toString.call(obj) !== \"[object Object]\") {\n            return false;\n        }\n\n        proto = getProto(obj);\n\n        // Objects with no prototype (e.g., `Object.create( null )`) are plain\n        if (!proto) {\n            return true;\n        }\n\n        // Objects with prototype are plain iff they were constructed by a global Object function\n        Ctor = hasOwn.call(proto, \"constructor\") && proto.constructor;\n        return typeof Ctor === \"function\" && fnToString.call(Ctor) === ObjectFunctionString;\n    }\n\n    // Test if a variable is an empty object (from jQuery)\n    function _isEmptyObject(obj) {\n        var name;\n\n        for (name in obj) {\n            return false;\n        }\n        return true;\n    }\n\n    // Merge objects\n    function _extend() {\n        var i = 1;\n        var result = arguments[0];\n        for (; i < arguments.length; i++) {\n            var attributes = arguments[i];\n            for (var key in attributes) {\n                if (attributes.hasOwnProperty(key)) {\n                    result[key] = attributes[key];\n                }\n            }\n        }\n        return result;\n    }\n\n    // Check if storages are natively available on browser and check is js-cookie is present\n    var storage_available = _testStorage('localStorage');\n    var cookies_available = typeof Cookies !== 'undefined';\n\n    // Namespace object\n    var storage = {\n        _type: '',\n        _ns: '',\n        _callMethod: function (f, a) {\n            a = Array.prototype.slice.call(a);\n            var p = [], a0 = a[0];\n            if (this._ns) {\n                p.push(this._ns);\n            }\n            if (typeof a0 === 'string' && a0.indexOf('.') !== -1) {\n                a.shift();\n                [].unshift.apply(a, a0.split('.'));\n            }\n            [].push.apply(p, a);\n            return f.apply(this, p);\n        },\n        // Define if plugin always use JSON to store values (even to store simple values like string, int...) or not\n        alwaysUseJson: false,\n        // Get items. If no parameters and storage have a namespace, return all namespace\n        get: function () {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_get, arguments);\n        },\n        // Set items\n        set: function () {\n            var l = arguments.length, a = arguments, a0 = a[0];\n            if (l < 1 || !_isPlainObject(a0) && l < 2) {\n                throw new Error('Minimum 2 arguments must be given or first parameter must be an object');\n            }\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            // If first argument is an object and storage is a namespace storage, set values individually\n            if (_isPlainObject(a0) && this._ns) {\n                for (var i in a0) {\n                    if (a0.hasOwnProperty(i)) {\n                        this._callMethod(_set, [i, a0[i]]);\n                    }\n                }\n                return a0;\n            } else {\n                var r = this._callMethod(_set, a);\n                if (this._ns) {\n                    return r[a0.split('.')[0]];\n                } else {\n                    return r;\n                }\n            }\n        },\n        // Delete items\n        remove: function () {\n            if (arguments.length < 1) {\n                throw new Error('Minimum 1 argument must be given');\n            }\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_remove, arguments);\n        },\n        // Delete all items\n        removeAll: function (reinit_ns) {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            if (this._ns) {\n                this._callMethod(_set, [{}]);\n                return true;\n            } else {\n                return this._callMethod(_removeAll, [reinit_ns]);\n            }\n        },\n        // Items empty\n        isEmpty: function () {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_isEmpty, arguments);\n        },\n        // Items exists\n        isSet: function () {\n            if (arguments.length < 1) {\n                throw new Error('Minimum 1 argument must be given');\n            }\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_isSet, arguments);\n        },\n        // Get keys of items\n        keys: function () {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_keys, arguments);\n        }\n    };\n\n    // Use js-cookie for compatibility with old browsers and give access to cookieStorage\n    if (cookies_available) {\n        // sessionStorage is valid for one window/tab. To simulate that with cookie, we set a name for the window and use it for the name of the cookie\n        if (!window.name) {\n            window.name = Math.floor(Math.random() * 100000000);\n        }\n        var cookie_storage = {\n            _cookie: true,\n            _prefix: '',\n            _expires: null,\n            _path: null,\n            _domain: null,\n            _secure: false,\n            setItem: function (n, v) {\n                Cookies.set(this._prefix + n, v, {expires: this._expires, path: this._path, domain: this._domain, secure: this._secure});\n            },\n            getItem: function (n) {\n                return Cookies.get(this._prefix + n);\n            },\n            removeItem: function (n) {\n                return Cookies.remove(this._prefix + n, {path: this._path});\n            },\n            clear: function () {\n                var cookies = Cookies.get();\n                for (var key in cookies) {\n                    if (cookies.hasOwnProperty(key) && key != '') {\n                        if (!this._prefix && key.indexOf(cookie_local_prefix) === -1 && key.indexOf(cookie_session_prefix) === -1 || this._prefix && key.indexOf(this._prefix) === 0) {\n                            Cookies.remove(key);\n                        }\n                    }\n                }\n            },\n            setExpires: function (e) {\n                this._expires = e;\n                return this;\n            },\n            setPath: function (p) {\n                this._path = p;\n                return this;\n            },\n            setDomain: function (d) {\n                this._domain = d;\n                return this;\n            },\n            setSecure: function (s) {\n                this._secure = s;\n                return this;\n            },\n            setConf: function (c) {\n                if (c.path) {\n                    this._path = c.path;\n                }\n                if (c.domain) {\n                    this._domain = c.domain;\n                }\n                if (c.secure) {\n                    this._secure = c.secure;\n                }\n                if (c.expires) {\n                    this._expires = c.expires;\n                }\n                return this;\n            },\n            setDefaultConf: function () {\n                this._path = this._domain = this._expires = null;\n                this._secure = false;\n            }\n        };\n        if (!storage_available) {\n            window.localCookieStorage = _extend({}, cookie_storage, {\n                _prefix: cookie_local_prefix,\n                _expires: 365 * 10,\n                _secure: true\n            });\n            window.sessionCookieStorage = _extend({}, cookie_storage, {\n                _prefix: cookie_session_prefix + window.name + '_',\n                _secure: true\n            });\n        }\n        window.cookieStorage = _extend({}, cookie_storage);\n        // cookieStorage API\n        apis.cookieStorage = _extend({}, storage, {\n            _type: 'cookieStorage',\n            setExpires: function (e) {\n                window.cookieStorage.setExpires(e);\n                return this;\n            },\n            setPath: function (p) {\n                window.cookieStorage.setPath(p);\n                return this;\n            },\n            setDomain: function (d) {\n                window.cookieStorage.setDomain(d);\n                return this;\n            },\n            setSecure: function (s) {\n                window.cookieStorage.setSecure(s);\n                return this;\n            },\n            setConf: function (c) {\n                window.cookieStorage.setConf(c);\n                return this;\n            },\n            setDefaultConf: function () {\n                window.cookieStorage.setDefaultConf();\n                return this;\n            }\n        });\n    }\n\n    // Get a new API on a namespace\n    apis.initNamespaceStorage = function (ns) {\n        return _createNamespace(ns);\n    };\n    if (storage_available) {\n        // localStorage API\n        apis.localStorage = _extend({}, storage, {_type: 'localStorage'});\n        // sessionStorage API\n        apis.sessionStorage = _extend({}, storage, {_type: 'sessionStorage'});\n    } else {\n        // localStorage API\n        apis.localStorage = _extend({}, storage, {_type: 'localCookieStorage'});\n        // sessionStorage API\n        apis.sessionStorage = _extend({}, storage, {_type: 'sessionCookieStorage'});\n    }\n    // List of all namespace storage\n    apis.namespaceStorages = {};\n    // Remove all items in all storages\n    apis.removeAllStorages = function (reinit_ns) {\n        apis.localStorage.removeAll(reinit_ns);\n        apis.sessionStorage.removeAll(reinit_ns);\n        if (apis.cookieStorage) {\n            apis.cookieStorage.removeAll(reinit_ns);\n        }\n        if (!reinit_ns) {\n            apis.namespaceStorages = {};\n        }\n    };\n    // About alwaysUseJson\n    // By default, all values are string on html storages and the plugin don't use json to store simple values (strings, int, float...)\n    // So by default, if you do storage.setItem('test',2), value in storage will be \"2\", not 2\n    // If you set this property to true, all values set with the plugin will be stored as json to have typed values in any cases\n    apis.alwaysUseJsonInStorage = function (value) {\n        storage.alwaysUseJson = value;\n        apis.localStorage.alwaysUseJson = value;\n        apis.sessionStorage.alwaysUseJson = value;\n        if (apis.cookieStorage) {\n            apis.cookieStorage.alwaysUseJson = value;\n        }\n    };\n\n    return apis;\n}));\n","Magento_Security/js/escaper.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * A loose JavaScript version of Magento\\Framework\\Escaper\n *\n * Due to differences in how XML/HTML is processed in PHP vs JS there are a couple of minor differences in behavior\n * from the PHP counterpart.\n *\n * The first difference is that the default invocation of escapeHtml without allowedTags will double-escape existing\n * entities as the intention of such an invocation is that the input isn't supposed to contain any HTML.\n *\n * The second difference is that escapeHtml will not escape quotes. Since the input is actually being processed by the\n * DOM there is no chance of quotes being mixed with HTML syntax. And, since escapeHtml is not\n * intended to be used with raw injection into a HTML attribute, this is acceptable.\n *\n * @api\n */\ndefine([], function () {\n    'use strict';\n\n    return {\n        neverAllowedElements: ['script', 'img', 'embed', 'iframe', 'video', 'source', 'object', 'audio'],\n        generallyAllowedAttributes: ['id', 'class', 'href', 'title', 'style'],\n        forbiddenAttributesByElement: {\n            a: ['style']\n        },\n\n        /**\n         * Escape a string for safe injection into HTML\n         *\n         * @param {String} data\n         * @param {Array|null} allowedTags\n         * @returns {String}\n         */\n        escapeHtml: function (data, allowedTags) {\n            var domParser = new DOMParser(),\n                fragment = domParser.parseFromString('<div></div>', 'text/html');\n\n            fragment = fragment.body.childNodes[0];\n            allowedTags = typeof allowedTags === 'object' && allowedTags.length ? allowedTags : null;\n\n            if (allowedTags) {\n                fragment.innerHTML = data || '';\n                allowedTags = this._filterProhibitedTags(allowedTags);\n\n                this._removeComments(fragment);\n                this._removeNotAllowedElements(fragment, allowedTags);\n                this._removeNotAllowedAttributes(fragment);\n\n                return fragment.innerHTML;\n            }\n\n            fragment.textContent = data || '';\n\n            return fragment.innerHTML;\n        },\n\n        /**\n         * Remove the always forbidden tags from a list of provided tags\n         *\n         * @param {Array} tags\n         * @returns {Array}\n         * @private\n         */\n        _filterProhibitedTags: function (tags) {\n            return tags.filter(function (n) {\n                return this.neverAllowedElements.indexOf(n) === -1;\n            }.bind(this));\n        },\n\n        /**\n         * Remove comment nodes from the given node\n         *\n         * @param {Node} node\n         * @private\n         */\n        _removeComments: function (node) {\n            var treeWalker = node.ownerDocument.createTreeWalker(\n                    node,\n                    NodeFilter.SHOW_COMMENT,\n                    function () {\n                        return NodeFilter.FILTER_ACCEPT;\n                    },\n                    false\n                ),\n                nodesToRemove = [];\n\n            while (treeWalker.nextNode()) {\n                nodesToRemove.push(treeWalker.currentNode);\n            }\n\n            nodesToRemove.forEach(function (nodeToRemove) {\n                nodeToRemove.parentNode.removeChild(nodeToRemove);\n            });\n        },\n\n        /**\n         * Strip the given node of all disallowed tags while permitting any nested text nodes\n         *\n         * @param {Node} node\n         * @param {Array|null} allowedTags\n         * @private\n         */\n        _removeNotAllowedElements: function (node, allowedTags) {\n            var treeWalker = node.ownerDocument.createTreeWalker(\n                    node,\n                    NodeFilter.SHOW_ELEMENT,\n                    function (currentNode) {\n                        return allowedTags.indexOf(currentNode.nodeName.toLowerCase()) === -1 ?\n                            NodeFilter.FILTER_ACCEPT\n                            // SKIP instead of REJECT because REJECT also rejects child nodes\n                            : NodeFilter.FILTER_SKIP;\n                    },\n                false\n                ),\n                nodesToRemove = [];\n\n            while (treeWalker.nextNode()) {\n                if (allowedTags.indexOf(treeWalker.currentNode.nodeName.toLowerCase()) === -1) {\n                    nodesToRemove.push(treeWalker.currentNode);\n                }\n            }\n\n            nodesToRemove.forEach(function (nodeToRemove) {\n                nodeToRemove.parentNode.replaceChild(\n                    node.ownerDocument.createTextNode(nodeToRemove.textContent),\n                    nodeToRemove\n                );\n            });\n        },\n\n        /**\n         * Remove any invalid attributes from the given node\n         *\n         * @param {Node} node\n         * @private\n         */\n        _removeNotAllowedAttributes: function (node) {\n            var treeWalker = node.ownerDocument.createTreeWalker(\n                    node,\n                    NodeFilter.SHOW_ELEMENT,\n                    function () {\n                        return NodeFilter.FILTER_ACCEPT;\n                    },\n                false\n                ),\n                i,\n                attribute,\n                nodeName,\n                attributesToRemove = [];\n\n            while (treeWalker.nextNode()) {\n                for (i = 0; i < treeWalker.currentNode.attributes.length; i++) {\n                    attribute = treeWalker.currentNode.attributes[i];\n                    nodeName = treeWalker.currentNode.nodeName.toLowerCase();\n\n                    if (this.generallyAllowedAttributes.indexOf(attribute.name) === -1  || // eslint-disable-line max-depth,max-len\n                        this._checkHrefValue(attribute) ||\n                        this.forbiddenAttributesByElement[nodeName] &&\n                        this.forbiddenAttributesByElement[nodeName].indexOf(attribute.name) !== -1\n                    ) {\n                        attributesToRemove.push(attribute);\n                    }\n                }\n            }\n\n            attributesToRemove.forEach(function (attributeToRemove) {\n                attributeToRemove.ownerElement.removeAttribute(attributeToRemove.name);\n            });\n        },\n\n        /**\n         * Check that attribute contains script content\n         *\n         * @param {Object} attribute\n         * @private\n         */\n        _checkHrefValue: function (attribute) {\n            return attribute.nodeName === 'href' && attribute.nodeValue.startsWith('javascript');\n        }\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/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/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/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/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","Amasty_Conditions/js/action/recollect-totals.js":"define([\n    'jquery',\n    'mage/utils/wrapper',\n    'underscore',\n    'Amasty_Conditions/js/model/resource-url-manager',\n    'Magento_Checkout/js/model/quote',\n    'mage/storage',\n    'Magento_Checkout/js/model/totals',\n    'Magento_Checkout/js/model/error-processor',\n    'Magento_Customer/js/customer-data',\n    'uiRegistry',\n    'Amasty_Conditions/js/model/subscriber'\n], function ($, wrapper, _, resourceUrlManager, quote, storage, totalsService, errorProcessor, customerData, registry, subscriber) {\n    'use strict';\n\n    var ajax,\n        sendTimeout,\n        sendingPayload;\n\n    return function (force) {\n        var serviceUrl,\n            payload,\n            address,\n            paymentMethod,\n            requiredFields = ['countryId', 'region', 'regionId', 'postcode', 'city'],\n            newAddress = quote.shippingAddress() ? quote.shippingAddress() : quote.billingAddress(),\n            city;\n\n        serviceUrl = resourceUrlManager.getUrlForTotalsEstimationForNewAddress(quote);\n        address = _.pick(newAddress, requiredFields);\n        paymentMethod = quote.paymentMethod() ? quote.paymentMethod().method : null;\n        \n        city = '';\n        if (quote.isVirtual() && quote.billingAddress()) {\n            city = quote.billingAddress().city;\n        } else if (quote.shippingAddress()) {\n            city = quote.shippingAddress().city;\n        }\n        \n        address.extension_attributes = {\n            advanced_conditions: {\n                custom_attributes: quote.shippingAddress() ? quote.shippingAddress().custom_attributes : [],\n                payment_method: paymentMethod,\n                city: city,\n                shipping_address_line: quote.shippingAddress() ? quote.shippingAddress().street : null,\n                billing_address_country: quote.billingAddress() ? quote.billingAddress().countryId : null,\n                currency: totalsService.totals() ? totalsService.totals().quote_currency_code : null\n            }\n        };\n\n        payload = {\n            addressInformation: {\n                address: address\n            }\n        };\n\n        if (quote.shippingMethod() && quote.shippingMethod()['method_code']) {\n            payload.addressInformation['shipping_method_code'] = quote.shippingMethod()['method_code'];\n            payload.addressInformation['shipping_carrier_code'] = quote.shippingMethod()['carrier_code'];\n        }\n\n        if (!_.isEqual(sendingPayload, payload) || force === true) {\n            sendingPayload = payload;\n            clearTimeout(sendTimeout);\n            //delay for avoid multi request\n            sendTimeout = setTimeout(function(){\n                clearTimeout(sendTimeout);\n                if (subscriber.isLoading() === true) {\n                    ajax.abort();\n                } else {\n                    // Start loader for totals block\n                    totalsService.isLoading(true);\n                    subscriber.isLoading(true);\n                }\n\n                ajax = storage.post(\n                    serviceUrl,\n                    JSON.stringify(payload),\n                    false\n                ).done(function (result) {\n                    quote.setTotals(result);\n                    // Stop loader for totals block\n                    totalsService.isLoading(false);\n                    subscriber.isLoading(false);\n                }).fail(function (response) {\n                    if (response.responseText || response.status) {\n                        errorProcessor.process(response);\n                    }\n                });\n            }, 200);\n        }\n    };\n});","Amasty_Conditions/js/model/subscriber.js":"define([\n    'ko'\n    ], function (ko) {\n        return {\n            isLoading: ko.observable(false)\n        }\n    }\n);","Amasty_Conditions/js/model/resource-url-manager.js":"define([\n    'Magento_Checkout/js/model/resource-url-manager'\n], function (resourceUrlManager) {\n    'use strict';\n\n    return {\n        /**\n         * Making url for total estimation request.\n         *\n         * @param {Object} quote - Quote model.\n         * @returns {String} Result url.\n         */\n        getUrlForTotalsEstimationForNewAddress: function (quote) {\n            if (window.checkoutConfig.isNegotiableQuote) {\n                var params = {\n                        quoteId: quote.getQuoteId()\n                    },\n                    urls = {\n                        'negotiable': '/negotiable-carts/:quoteId/totals-information/?isNegotiableQuote=true'\n                    };\n\n                return resourceUrlManager.getUrl(urls, params);\n            }\n\n            return resourceUrlManager.getUrlForTotalsEstimationForNewAddress(quote);\n        },\n    };\n});\n","Amasty_Conditions/js/model/shipping-rates-validation-rules-mixin.js":"define([\n    'jquery',\n    'mage/utils/wrapper',\n    'uiRegistry'\n], function ($, wrapper) {\n    \"use strict\";\n\n    return function (shippingRatesValidationRules) {\n        shippingRatesValidationRules.getObservableFields = wrapper.wrap(shippingRatesValidationRules.getObservableFields,\n            function (originalAction) {\n                var fields = originalAction();\n                fields.push('street');\n                fields.push('city');\n                fields.push('region_id');\n\n                return fields;\n            }\n        );\n\n        return shippingRatesValidationRules;\n    };\n});\n","Amasty_Conditions/js/model/conditions-subscribe.js":"define([\n    'jquery',\n    'underscore',\n    'uiComponent',\n    'Magento_Checkout/js/model/quote',\n    'Amasty_Conditions/js/action/recollect-totals',\n    'Amasty_Conditions/js/model/subscriber',\n    'Magento_Checkout/js/model/shipping-service',\n    'Magento_Checkout/js/model/shipping-rate-processor/new-address',\n    'Magento_Checkout/js/model/totals',\n    'Magento_SalesRule/js/view/payment/discount',\n    'rjsResolver'\n], function ($, _, Component, quote, recollect, subscriber, shippingService, shippingProcessor, totals, discount, resolver) {\n    'use strict';\n\n    return Component.extend({\n        previousShippingMethodData: {},\n        previousItemsData: [],\n        billingAddressCountry: null,\n        city: null,\n        street: null,\n        isPageLoaded: false,\n        initialize: function () {\n            this._insertPolyfills();\n            this._super();\n\n            resolver(function() {\n                this.isPageLoaded = true;\n\n                totals.getItems().subscribe(this.storeOldItems, this, \"beforeChange\");\n                totals.getItems().subscribe(this.recollectOnItems, this);\n            }.bind(this));\n\n            discount().isApplied.subscribe(function () {\n                recollect(true);\n            });\n\n            quote.shippingAddress.subscribe(function (newShippingAddress) {\n                // while page is loading do not recollect, should be recollected after shipping rates\n                // for avoid extra requests to server\n                if (this.isPageLoaded && this._isNeededRecollectShipping(newShippingAddress, this.city, this.street)) {\n                    this.city = newShippingAddress.city;\n                    this.street = newShippingAddress.street;\n                    if (newShippingAddress) {\n                        recollect();\n                    }\n                }\n            }.bind(this));\n\n            quote.billingAddress.subscribe(function (newBillAddress) {\n                if (this._isNeededRecollectBilling(\n                    newBillAddress,\n                    this.billingAddressCountry,\n                    this.billingAddressCity\n                )) {\n                    this.billingAddressCountry = newBillAddress.countryId;\n                    this.billingAddressCity = newBillAddress.city;\n                    if (!this._isVirtualQuote()\n                        && (quote.shippingAddress() && newBillAddress.countryId !== quote.shippingAddress().countryId)\n                    ) {\n                        shippingProcessor.getRates(quote.shippingAddress());\n                    }\n                    recollect();\n                }\n            }.bind(this));\n\n            //for invalid shipping address update\n            shippingService.getShippingRates().subscribe(function (rates) {\n                if (!this._isVirtualQuote()) {\n                    recollect();\n                }\n            }.bind(this));\n\n            quote.paymentMethod.subscribe(function (newMethodData) {\n                recollect();\n            }, this);\n\n            quote.shippingMethod.subscribe(this.storeOldMethod, this, \"beforeChange\");\n            quote.shippingMethod.subscribe(this.recollectOnShippingMethod, this);\n\n            return this;\n        },\n\n        /**\n         * Store before change shipping method, because sometimes shipping methods updates always (not by change)\n         *\n         * @param {Object} oldMethod\n         */\n        storeOldMethod: function (oldMethod) {\n            this.previousShippingMethodData = oldMethod;\n        },\n\n        recollectOnShippingMethod: function (newMethodData) {\n            if (!_.isEqual(this.previousShippingMethodData, newMethodData)) {\n                recollect();\n            }\n        },\n\n        /**\n         * Store before change cart items\n         *\n         * @param {Array} oldItems\n         * @since 1.3.13\n         */\n        storeOldItems: function (oldItems) {\n            this.previousItemsData = this._prepareArrayForCompare(oldItems);\n        },\n\n        /**\n         * Recollect totals on cart items update\n         *\n         * @param {Array} newItems\n         * @since 1.3.13 improve compatibility with modules which allow update cart items on checkout page\n         *        and ajax update cart items\n         */\n        recollectOnItems: function (newItems) {\n            if (!_.isEqual(this.previousItemsData, this._prepareArrayForCompare(newItems))) {\n                // totals should be already collected, trigger subscribers\n                // for more stability but less performance can be replaced with recollect(true);\n                subscriber.isLoading.valueHasMutated();\n            }\n        },\n\n        /**\n         * Remove all not simple types from array items\n         *\n         * @param {Array} data\n         * @returns {Array}\n         * @private\n         * @since 1.3.13\n         */\n        _prepareArrayForCompare: function (data) {\n            var result = [],\n                itemData = {};\n\n            _.each(data, function(item) {\n                itemData = _.pick(item, function (value) {\n                    return !_.isObject(value);\n                });\n                result.push(itemData);\n            }.bind(this));\n\n            return result;\n        },\n\n        _isVirtualQuote: function () {\n            return quote.isVirtual()\n                || window.checkoutConfig.activeCarriers && window.checkoutConfig.activeCarriers.length === 0;\n        },\n\n        _isNeededRecollectShipping: function (newShippingAddress, city, street) {\n            return !this._isVirtualQuote()\n                && (\n                    newShippingAddress\n                    && (newShippingAddress.city || newShippingAddress.street)\n                    && (newShippingAddress.city != city || !_.isEqual(newShippingAddress.street, street)));\n        },\n\n        _isNeededRecollectBilling: function (newBillAddress, billingAddressCountry, billingAddressCity) {\n            var isNeedRecollectByCountry = newBillAddress\n                    && newBillAddress.countryId\n                    && newBillAddress.countryId !== billingAddressCountry,\n                isNeedRecollectByCity = newBillAddress\n                    && newBillAddress.city\n                    && newBillAddress.city !== billingAddressCity;\n\n            return this.isPageLoaded && (isNeedRecollectByCountry || isNeedRecollectByCity);\n        },\n\n        _insertPolyfills: function () {\n            if (typeof Object.assign != 'function') {\n                // Must be writable: true, enumerable: false, configurable: true\n                Object.defineProperty(Object, \"assign\", {\n                    value: function assign(target, varArgs) { // .length of function is 2\n                        'use strict';\n                        if (target == null) { // TypeError if undefined or null\n                            throw new TypeError('Cannot convert undefined or null to object');\n                        }\n\n                        var to = Object(target);\n\n                        for (var index = 1; index < arguments.length; index++) {\n                            var nextSource = arguments[index];\n\n                            if (nextSource != null) { // Skip over if undefined or null\n                                for (var nextKey in nextSource) {\n                                    // Avoid bugs when hasOwnProperty is shadowed\n                                    if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n                                        to[nextKey] = nextSource[nextKey];\n                                    }\n                                }\n                            }\n                        }\n                        return to;\n                    },\n                    writable: true,\n                    configurable: true\n                });\n            }\n        }\n    });\n});\n","Magento_LoginAsCustomerAssistance/js/opt-in.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            this.elements['assistance_allowed'].value =\n                this.elements['assistance_allowed_checkbox'].checked ?\n                    config.allowAccess : config.denyAccess;\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_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_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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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_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/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/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/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","Mageplaza_Core/js/bootstrap.min.js":"/*!\r\n * Bootstrap v3.3.6 (http://getbootstrap.com)\r\n * Copyright 2011-2015 Twitter, Inc.\r\n * Licensed under the MIT license\r\n */\r\nif(\"undefined\"==typeof jQuery)throw new Error(\"Bootstrap's JavaScript requires jQuery\");+function(a){\"use strict\";var b=a.fn.jquery.split(\" \")[0].split(\".\");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error(\"Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3\")}(jQuery),+function(a){\"use strict\";function b(){var a=document.createElement(\"bootstrap\"),b={WebkitTransition:\"webkitTransitionEnd\",MozTransition:\"transitionend\",OTransition:\"oTransitionEnd otransitionend\",transition:\"transitionend\"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(\"bsTransitionEnd\",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var c=a(this),e=c.data(\"bs.alert\");e||c.data(\"bs.alert\",e=new d(this)),\"string\"==typeof b&&e[b].call(c)})}var c='[data-dismiss=\"alert\"]',d=function(b){a(b).on(\"click\",c,this.close)};d.VERSION=\"3.3.6\",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger(\"closed.bs.alert\").remove()}var e=a(this),f=e.attr(\"data-target\");f||(f=e.attr(\"href\"),f=f&&f.replace(/.*(?=#[^\\s]*$)/,\"\"));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(\".alert\")),g.trigger(b=a.Event(\"close.bs.alert\")),b.isDefaultPrevented()||(g.removeClass(\"in\"),a.support.transition&&g.hasClass(\"fade\")?g.one(\"bsTransitionEnd\",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on(\"click.bs.alert.data-api\",c,d.prototype.close)}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.button\"),f=\"object\"==typeof b&&b;e||d.data(\"bs.button\",e=new c(this,f)),\"toggle\"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION=\"3.3.6\",c.DEFAULTS={loadingText:\"loading...\"},c.prototype.setState=function(b){var c=\"disabled\",d=this.$element,e=d.is(\"input\")?\"val\":\"html\",f=d.data();b+=\"Text\",null==f.resetText&&d.data(\"resetText\",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),\"loadingText\"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle=\"buttons\"]');if(b.length){var c=this.$element.find(\"input\");\"radio\"==c.prop(\"type\")?(c.prop(\"checked\")&&(a=!1),b.find(\".active\").removeClass(\"active\"),this.$element.addClass(\"active\")):\"checkbox\"==c.prop(\"type\")&&(c.prop(\"checked\")!==this.$element.hasClass(\"active\")&&(a=!1),this.$element.toggleClass(\"active\")),c.prop(\"checked\",this.$element.hasClass(\"active\")),a&&c.trigger(\"change\")}else this.$element.attr(\"aria-pressed\",!this.$element.hasClass(\"active\")),this.$element.toggleClass(\"active\")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on(\"click.bs.button.data-api\",'[data-toggle^=\"button\"]',function(c){var d=a(c.target);d.hasClass(\"btn\")||(d=d.closest(\".btn\")),b.call(d,\"toggle\"),a(c.target).is('input[type=\"radio\"]')||a(c.target).is('input[type=\"checkbox\"]')||c.preventDefault()}).on(\"focus.bs.button.data-api blur.bs.button.data-api\",'[data-toggle^=\"button\"]',function(b){a(b.target).closest(\".btn\").toggleClass(\"focus\",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.carousel\"),f=a.extend({},c.DEFAULTS,d.data(),\"object\"==typeof b&&b),g=\"string\"==typeof b?b:f.slide;e||d.data(\"bs.carousel\",e=new c(this,f)),\"number\"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(\".carousel-indicators\"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on(\"keydown.bs.carousel\",a.proxy(this.keydown,this)),\"hover\"==this.options.pause&&!(\"ontouchstart\"in document.documentElement)&&this.$element.on(\"mouseenter.bs.carousel\",a.proxy(this.pause,this)).on(\"mouseleave.bs.carousel\",a.proxy(this.cycle,this))};c.VERSION=\"3.3.6\",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:\"hover\",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(\".item\"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d=\"prev\"==a&&0===c||\"next\"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e=\"prev\"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(\".item.active\"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one(\"slid.bs.carousel\",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?\"next\":\"prev\",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(\".next, .prev\").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide(\"next\")},c.prototype.prev=function(){return this.sliding?void 0:this.slide(\"prev\")},c.prototype.slide=function(b,d){var e=this.$element.find(\".item.active\"),f=d||this.getItemForDirection(b,e),g=this.interval,h=\"next\"==b?\"left\":\"right\",i=this;if(f.hasClass(\"active\"))return this.sliding=!1;var j=f[0],k=a.Event(\"slide.bs.carousel\",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(\".active\").removeClass(\"active\");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass(\"active\")}var m=a.Event(\"slid.bs.carousel\",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass(\"slide\")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one(\"bsTransitionEnd\",function(){f.removeClass([b,h].join(\" \")).addClass(\"active\"),e.removeClass([\"active\",h].join(\" \")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass(\"active\"),f.addClass(\"active\"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr(\"data-target\")||(d=e.attr(\"href\"))&&d.replace(/.*(?=#[^\\s]+$)/,\"\"));if(f.hasClass(\"carousel\")){var g=a.extend({},f.data(),e.data()),h=e.attr(\"data-slide-to\");h&&(g.interval=!1),b.call(f,g),h&&f.data(\"bs.carousel\").to(h),c.preventDefault()}};a(document).on(\"click.bs.carousel.data-api\",\"[data-slide]\",e).on(\"click.bs.carousel.data-api\",\"[data-slide-to]\",e),a(window).on(\"load\",function(){a('[data-ride=\"carousel\"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){\"use strict\";function b(b){var c,d=b.attr(\"data-target\")||(c=b.attr(\"href\"))&&c.replace(/.*(?=#[^\\s]+$)/,\"\");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data(\"bs.collapse\"),f=a.extend({},d.DEFAULTS,c.data(),\"object\"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data(\"bs.collapse\",e=new d(this,f)),\"string\"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle=\"collapse\"][href=\"#'+b.id+'\"],[data-toggle=\"collapse\"][data-target=\"#'+b.id+'\"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION=\"3.3.6\",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass(\"width\");return a?\"width\":\"height\"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass(\"in\")){var b,e=this.$parent&&this.$parent.children(\".panel\").children(\".in, .collapsing\");if(!(e&&e.length&&(b=e.data(\"bs.collapse\"),b&&b.transitioning))){var f=a.Event(\"show.bs.collapse\");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,\"hide\"),b||e.data(\"bs.collapse\",null));var g=this.dimension();this.$element.removeClass(\"collapse\").addClass(\"collapsing\")[g](0).attr(\"aria-expanded\",!0),this.$trigger.removeClass(\"collapsed\").attr(\"aria-expanded\",!0),this.transitioning=1;var h=function(){this.$element.removeClass(\"collapsing\").addClass(\"collapse in\")[g](\"\"),this.transitioning=0,this.$element.trigger(\"shown.bs.collapse\")};if(!a.support.transition)return h.call(this);var i=a.camelCase([\"scroll\",g].join(\"-\"));this.$element.one(\"bsTransitionEnd\",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass(\"in\")){var b=a.Event(\"hide.bs.collapse\");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass(\"collapsing\").removeClass(\"collapse in\").attr(\"aria-expanded\",!1),this.$trigger.addClass(\"collapsed\").attr(\"aria-expanded\",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass(\"collapsing\").addClass(\"collapse\").trigger(\"hidden.bs.collapse\")};return a.support.transition?void this.$element[c](0).one(\"bsTransitionEnd\",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass(\"in\")?\"hide\":\"show\"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle=\"collapse\"][data-parent=\"'+this.options.parent+'\"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass(\"in\");a.attr(\"aria-expanded\",c),b.toggleClass(\"collapsed\",!c).attr(\"aria-expanded\",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on(\"click.bs.collapse.data-api\",'[data-toggle=\"collapse\"]',function(d){var e=a(this);e.attr(\"data-target\")||d.preventDefault();var f=b(e),g=f.data(\"bs.collapse\"),h=g?\"toggle\":e.data();c.call(f,h)})}(jQuery),+function(a){\"use strict\";function b(b){var c=b.attr(\"data-target\");c||(c=b.attr(\"href\"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\\s]*$)/,\"\"));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass(\"open\")&&(c&&\"click\"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event(\"hide.bs.dropdown\",f)),c.isDefaultPrevented()||(d.attr(\"aria-expanded\",\"false\"),e.removeClass(\"open\").trigger(a.Event(\"hidden.bs.dropdown\",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data(\"bs.dropdown\");d||c.data(\"bs.dropdown\",d=new g(this)),\"string\"==typeof b&&d[b].call(c)})}var e=\".dropdown-backdrop\",f='[data-toggle=\"dropdown\"]',g=function(b){a(b).on(\"click.bs.dropdown\",this.toggle)};g.VERSION=\"3.3.6\",g.prototype.toggle=function(d){var e=a(this);if(!e.is(\".disabled, :disabled\")){var f=b(e),g=f.hasClass(\"open\");if(c(),!g){\"ontouchstart\"in document.documentElement&&!f.closest(\".navbar-nav\").length&&a(document.createElement(\"div\")).addClass(\"dropdown-backdrop\").insertAfter(a(this)).on(\"click\",c);var h={relatedTarget:this};if(f.trigger(d=a.Event(\"show.bs.dropdown\",h)),d.isDefaultPrevented())return;e.trigger(\"focus\").attr(\"aria-expanded\",\"true\"),f.toggleClass(\"open\").trigger(a.Event(\"shown.bs.dropdown\",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(\".disabled, :disabled\")){var e=b(d),g=e.hasClass(\"open\");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger(\"focus\"),d.trigger(\"click\");var h=\" li:not(.disabled):visible a\",i=e.find(\".dropdown-menu\"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger(\"focus\")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on(\"click.bs.dropdown.data-api\",c).on(\"click.bs.dropdown.data-api\",\".dropdown form\",function(a){a.stopPropagation()}).on(\"click.bs.dropdown.data-api\",f,g.prototype.toggle).on(\"keydown.bs.dropdown.data-api\",f,g.prototype.keydown).on(\"keydown.bs.dropdown.data-api\",\".dropdown-menu\",g.prototype.keydown)}(jQuery),+function(a){\"use strict\";function b(b,d){return this.each(function(){var e=a(this),f=e.data(\"bs.modal\"),g=a.extend({},c.DEFAULTS,e.data(),\"object\"==typeof b&&b);f||e.data(\"bs.modal\",f=new c(this,g)),\"string\"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(\".modal-dialog\"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(\".modal-content\").load(this.options.remote,a.proxy(function(){this.$element.trigger(\"loaded.bs.modal\")},this))};c.VERSION=\"3.3.6\",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event(\"show.bs.modal\",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass(\"modal-open\"),this.escape(),this.resize(),this.$element.on(\"click.dismiss.bs.modal\",'[data-dismiss=\"modal\"]',a.proxy(this.hide,this)),this.$dialog.on(\"mousedown.dismiss.bs.modal\",function(){d.$element.one(\"mouseup.dismiss.bs.modal\",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass(\"fade\");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass(\"in\"),d.enforceFocus();var f=a.Event(\"shown.bs.modal\",{relatedTarget:b});e?d.$dialog.one(\"bsTransitionEnd\",function(){d.$element.trigger(\"focus\").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger(\"focus\").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event(\"hide.bs.modal\"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off(\"focusin.bs.modal\"),this.$element.removeClass(\"in\").off(\"click.dismiss.bs.modal\").off(\"mouseup.dismiss.bs.modal\"),this.$dialog.off(\"mousedown.dismiss.bs.modal\"),a.support.transition&&this.$element.hasClass(\"fade\")?this.$element.one(\"bsTransitionEnd\",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off(\"focusin.bs.modal\").on(\"focusin.bs.modal\",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger(\"focus\")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on(\"keydown.dismiss.bs.modal\",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off(\"keydown.dismiss.bs.modal\")},c.prototype.resize=function(){this.isShown?a(window).on(\"resize.bs.modal\",a.proxy(this.handleUpdate,this)):a(window).off(\"resize.bs.modal\")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass(\"modal-open\"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger(\"hidden.bs.modal\")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass(\"fade\")?\"fade\":\"\";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement(\"div\")).addClass(\"modal-backdrop \"+e).appendTo(this.$body),this.$element.on(\"click.dismiss.bs.modal\",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&(\"static\"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass(\"in\"),!b)return;f?this.$backdrop.one(\"bsTransitionEnd\",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass(\"in\");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass(\"fade\")?this.$backdrop.one(\"bsTransitionEnd\",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:\"\",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:\"\"})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:\"\",paddingRight:\"\"})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css(\"padding-right\")||0,10);this.originalBodyPad=document.body.style.paddingRight||\"\",this.bodyIsOverflowing&&this.$body.css(\"padding-right\",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css(\"padding-right\",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement(\"div\");a.className=\"modal-scrollbar-measure\",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on(\"click.bs.modal.data-api\",'[data-toggle=\"modal\"]',function(c){var d=a(this),e=d.attr(\"href\"),f=a(d.attr(\"data-target\")||e&&e.replace(/.*(?=#[^\\s]+$)/,\"\")),g=f.data(\"bs.modal\")?\"toggle\":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is(\"a\")&&c.preventDefault(),f.one(\"show.bs.modal\",function(a){a.isDefaultPrevented()||f.one(\"hidden.bs.modal\",function(){d.is(\":visible\")&&d.trigger(\"focus\")})}),b.call(f,g,this)})}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.tooltip\"),f=\"object\"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data(\"bs.tooltip\",e=new c(this,f)),\"string\"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init(\"tooltip\",a,b)};c.VERSION=\"3.3.6\",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:\"top\",selector:!1,template:'<div class=\"tooltip\" role=\"tooltip\"><div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div></div>',trigger:\"hover focus\",title:\"\",delay:0,html:!1,container:!1,viewport:{selector:\"body\",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error(\"`selector` option must be specified when initializing \"+this.type+\" on the window.document object!\");for(var e=this.options.trigger.split(\" \"),f=e.length;f--;){var g=e[f];if(\"click\"==g)this.$element.on(\"click.\"+this.type,this.options.selector,a.proxy(this.toggle,this));else if(\"manual\"!=g){var h=\"hover\"==g?\"mouseenter\":\"focusin\",i=\"hover\"==g?\"mouseleave\":\"focusout\";this.$element.on(h+\".\"+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+\".\"+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:\"manual\",selector:\"\"}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&\"number\"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data(\"bs.\"+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data(\"bs.\"+this.type,c)),b instanceof a.Event&&(c.inState[\"focusin\"==b.type?\"focus\":\"hover\"]=!0),c.tip().hasClass(\"in\")||\"in\"==c.hoverState?void(c.hoverState=\"in\"):(clearTimeout(c.timeout),c.hoverState=\"in\",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){\"in\"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data(\"bs.\"+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data(\"bs.\"+this.type,c)),b instanceof a.Event&&(c.inState[\"focusout\"==b.type?\"focus\":\"hover\"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState=\"out\",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){\"out\"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event(\"show.bs.\"+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr(\"id\",g),this.$element.attr(\"aria-describedby\",g),this.options.animation&&f.addClass(\"fade\");var h=\"function\"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\\s?auto?\\s?/i,j=i.test(h);j&&(h=h.replace(i,\"\")||\"top\"),f.detach().css({top:0,left:0,display:\"block\"}).addClass(h).data(\"bs.\"+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger(\"inserted.bs.\"+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h=\"bottom\"==h&&k.bottom+m>o.bottom?\"top\":\"top\"==h&&k.top-m<o.top?\"bottom\":\"right\"==h&&k.right+l>o.width?\"left\":\"left\"==h&&k.left-l<o.left?\"right\":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger(\"shown.bs.\"+e.type),e.hoverState=null,\"out\"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass(\"fade\")?f.one(\"bsTransitionEnd\",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css(\"margin-top\"),10),h=parseInt(d.css(\"margin-left\"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass(\"in\");var i=d[0].offsetWidth,j=d[0].offsetHeight;\"top\"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?\"offsetWidth\":\"offsetHeight\";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?\"left\":\"top\",50*(1-a/b)+\"%\").css(c?\"top\":\"left\",\"\")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(\".tooltip-inner\")[this.options.html?\"html\":\"text\"](b),a.removeClass(\"fade in top bottom left right\")},c.prototype.hide=function(b){function d(){\"in\"!=e.hoverState&&f.detach(),e.$element.removeAttr(\"aria-describedby\").trigger(\"hidden.bs.\"+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event(\"hide.bs.\"+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass(\"in\"),a.support.transition&&f.hasClass(\"fade\")?f.one(\"bsTransitionEnd\",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr(\"title\")||\"string\"!=typeof a.attr(\"data-original-title\"))&&a.attr(\"data-original-title\",a.attr(\"title\")||\"\").attr(\"title\",\"\")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d=\"BODY\"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return\"bottom\"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:\"top\"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:\"left\"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr(\"data-original-title\")||(\"function\"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+\" `template` option must consist of exactly 1 top-level element!\");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(\".tooltip-arrow\")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data(\"bs.\"+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data(\"bs.\"+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass(\"in\")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off(\".\"+a.type).removeData(\"bs.\"+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.popover\"),f=\"object\"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data(\"bs.popover\",e=new c(this,f)),\"string\"==typeof b&&e[b]())})}var c=function(a,b){this.init(\"popover\",a,b)};if(!a.fn.tooltip)throw new Error(\"Popover requires tooltip.js\");c.VERSION=\"3.3.6\",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:\"right\",trigger:\"click\",content:\"\",template:'<div class=\"popover\" role=\"tooltip\"><div class=\"arrow\"></div><h3 class=\"popover-title\"></h3><div class=\"popover-content\"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(\".popover-title\")[this.options.html?\"html\":\"text\"](b),a.find(\".popover-content\").children().detach().end()[this.options.html?\"string\"==typeof c?\"html\":\"append\":\"text\"](c),a.removeClass(\"fade top bottom left right in\"),a.find(\".popover-title\").html()||a.find(\".popover-title\").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr(\"data-content\")||(\"function\"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(\".arrow\")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){\"use strict\";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||\"\")+\" .nav li > a\",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on(\"scroll.bs.scrollspy\",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data(\"bs.scrollspy\"),f=\"object\"==typeof c&&c;e||d.data(\"bs.scrollspy\",e=new b(this,f)),\"string\"==typeof c&&e[c]()})}b.VERSION=\"3.3.6\",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c=\"offset\",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c=\"position\",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data(\"target\")||b.attr(\"href\"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(\":visible\")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target=\"'+b+'\"],'+this.selector+'[href=\"'+b+'\"]',d=a(c).parents(\"li\").addClass(\"active\");\r\n    d.parent(\".dropdown-menu\").length&&(d=d.closest(\"li.dropdown\").addClass(\"active\")),d.trigger(\"activate.bs.scrollspy\")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,\".active\").removeClass(\"active\")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on(\"load.bs.scrollspy.data-api\",function(){a('[data-spy=\"scroll\"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.tab\");e||d.data(\"bs.tab\",e=new c(this)),\"string\"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION=\"3.3.6\",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest(\"ul:not(.dropdown-menu)\"),d=b.data(\"target\");if(d||(d=b.attr(\"href\"),d=d&&d.replace(/.*(?=#[^\\s]*$)/,\"\")),!b.parent(\"li\").hasClass(\"active\")){var e=c.find(\".active:last a\"),f=a.Event(\"hide.bs.tab\",{relatedTarget:b[0]}),g=a.Event(\"show.bs.tab\",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest(\"li\"),c),this.activate(h,h.parent(),function(){e.trigger({type:\"hidden.bs.tab\",relatedTarget:b[0]}),b.trigger({type:\"shown.bs.tab\",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass(\"active\").find(\"> .dropdown-menu > .active\").removeClass(\"active\").end().find('[data-toggle=\"tab\"]').attr(\"aria-expanded\",!1),b.addClass(\"active\").find('[data-toggle=\"tab\"]').attr(\"aria-expanded\",!0),h?(b[0].offsetWidth,b.addClass(\"in\")):b.removeClass(\"fade\"),b.parent(\".dropdown-menu\").length&&b.closest(\"li.dropdown\").addClass(\"active\").end().find('[data-toggle=\"tab\"]').attr(\"aria-expanded\",!0),e&&e()}var g=d.find(\"> .active\"),h=e&&a.support.transition&&(g.length&&g.hasClass(\"fade\")||!!d.find(\"> .fade\").length);g.length&&h?g.one(\"bsTransitionEnd\",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass(\"in\")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),\"show\")};a(document).on(\"click.bs.tab.data-api\",'[data-toggle=\"tab\"]',e).on(\"click.bs.tab.data-api\",'[data-toggle=\"pill\"]',e)}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.affix\"),f=\"object\"==typeof b&&b;e||d.data(\"bs.affix\",e=new c(this,f)),\"string\"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on(\"scroll.bs.affix.data-api\",a.proxy(this.checkPosition,this)).on(\"click.bs.affix.data-api\",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION=\"3.3.6\",c.RESET=\"affix affix-top affix-bottom\",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&\"top\"==this.affixed)return c>e?\"top\":!1;if(\"bottom\"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:\"bottom\":a-d>=e+g?!1:\"bottom\";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?\"top\":null!=d&&i+j>=a-d?\"bottom\":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass(\"affix\");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(\":visible\")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());\"object\"!=typeof d&&(f=e=d),\"function\"==typeof e&&(e=d.top(this.$element)),\"function\"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css(\"top\",\"\");var i=\"affix\"+(h?\"-\"+h:\"\"),j=a.Event(i+\".bs.affix\");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin=\"bottom\"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace(\"affix\",\"affixed\")+\".bs.affix\")}\"bottom\"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on(\"load\",function(){a('[data-spy=\"affix\"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);","Mageplaza_Core/js/jquery.ui.touch-punch.min.js":"/*!\r\n * jQuery UI Touch Punch 0.2.3\r\n *\r\n * Copyright 2011\u20132014, Dave Furfero\r\n * Dual licensed under the MIT or GPL Version 2 licenses.\r\n *\r\n * Depends:\r\n *  jquery.ui.widget.js\r\n *  jquery.ui.mouse.js\r\n */\r\n!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent(\"MouseEvents\");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch=\"ontouchend\"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,\"mouseover\"),f(a,\"mousemove\"),f(a,\"mousedown\"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,\"mousemove\"))},b._touchEnd=function(a){e&&(f(a,\"mouseup\"),f(a,\"mouseout\"),this._touchMoved||f(a,\"click\"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,\"_touchStart\"),touchmove:a.proxy(b,\"_touchMove\"),touchend:a.proxy(b,\"_touchEnd\")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,\"_touchStart\"),touchmove:a.proxy(b,\"_touchMove\"),touchend:a.proxy(b,\"_touchEnd\")}),d.call(b)}}}(jQuery);\r\n","Mageplaza_Core/js/ion.rangeSlider.min.js":"// Ion.RangeSlider | version 2.1.6 | https://github.com/IonDen/ion.rangeSlider\r\n;(function(f){\"function\"===typeof define&&define.amd?define([\"jquery\"],function(p){return f(p,document,window,navigator)}):\"object\"===typeof exports?f(require(\"jquery\"),document,window,navigator):f(jQuery,document,window,navigator)})(function(f,p,h,t,q){var u=0,m=function(){var a=t.userAgent,b=/msie\\s\\d+/i;return 0<a.search(b)&&(a=b.exec(a).toString(),a=a.split(\" \")[1],9>a)?(f(\"html\").addClass(\"lt-ie9\"),!0):!1}();Function.prototype.bind||(Function.prototype.bind=function(a){var b=this,d=[].slice;if(\"function\"!=\r\n    typeof b)throw new TypeError;var c=d.call(arguments,1),e=function(){if(this instanceof e){var g=function(){};g.prototype=b.prototype;var g=new g,l=b.apply(g,c.concat(d.call(arguments)));return Object(l)===l?l:g}return b.apply(a,c.concat(d.call(arguments)))};return e});Array.prototype.indexOf||(Array.prototype.indexOf=function(a,b){var d;if(null==this)throw new TypeError('\"this\" is null or not defined');var c=Object(this),e=c.length>>>0;if(0===e)return-1;d=+b||0;Infinity===Math.abs(d)&&(d=0);if(d>=\r\n    e)return-1;for(d=Math.max(0<=d?d:e-Math.abs(d),0);d<e;){if(d in c&&c[d]===a)return d;d++}return-1});var r=function(a,b,d){this.VERSION=\"2.1.6\";this.input=a;this.plugin_count=d;this.old_to=this.old_from=this.update_tm=this.calc_count=this.current_plugin=0;this.raf_id=this.old_min_interval=null;this.is_update=this.is_key=this.no_diapason=this.force_redraw=this.dragging=!1;this.is_start=this.is_first_update=!0;this.is_click=this.is_resize=this.is_active=this.is_finish=!1;b=b||{};this.$cache={win:f(h),\r\n    body:f(p.body),input:f(a),cont:null,rs:null,min:null,max:null,from:null,to:null,single:null,bar:null,line:null,s_single:null,s_from:null,s_to:null,shad_single:null,shad_from:null,shad_to:null,edge:null,grid:null,grid_labels:[]};this.coords={x_gap:0,x_pointer:0,w_rs:0,w_rs_old:0,w_handle:0,p_gap:0,p_gap_left:0,p_gap_right:0,p_step:0,p_pointer:0,p_handle:0,p_single_fake:0,p_single_real:0,p_from_fake:0,p_from_real:0,p_to_fake:0,p_to_real:0,p_bar_x:0,p_bar_w:0,grid_gap:0,big_num:0,big:[],big_w:[],big_p:[],\r\n    big_x:[]};this.labels={w_min:0,w_max:0,w_from:0,w_to:0,w_single:0,p_min:0,p_max:0,p_from_fake:0,p_from_left:0,p_to_fake:0,p_to_left:0,p_single_fake:0,p_single_left:0};var c=this.$cache.input;a=c.prop(\"value\");var e;d={type:\"single\",min:10,max:100,from:null,to:null,step:1,min_interval:0,max_interval:0,drag_interval:!1,values:[],p_values:[],from_fixed:!1,from_min:null,from_max:null,from_shadow:!1,to_fixed:!1,to_min:null,to_max:null,to_shadow:!1,prettify_enabled:!0,prettify_separator:\" \",prettify:null,\r\n    force_edges:!1,keyboard:!1,keyboard_step:5,grid:!1,grid_margin:!0,grid_num:4,grid_snap:!1,hide_min_max:!1,hide_from_to:!1,prefix:\"\",postfix:\"\",max_postfix:\"\",decorate_both:!0,values_separator:\" \\u2014 \",input_values_separator:\";\",disable:!1,onStart:null,onChange:null,onFinish:null,onUpdate:null};\"INPUT\"!==c[0].nodeName&&console&&console.warn&&console.warn(\"Base element should be <input>!\",c[0]);c={type:c.data(\"type\"),min:c.data(\"min\"),max:c.data(\"max\"),from:c.data(\"from\"),to:c.data(\"to\"),step:c.data(\"step\"),\r\n    min_interval:c.data(\"minInterval\"),max_interval:c.data(\"maxInterval\"),drag_interval:c.data(\"dragInterval\"),values:c.data(\"values\"),from_fixed:c.data(\"fromFixed\"),from_min:c.data(\"fromMin\"),from_max:c.data(\"fromMax\"),from_shadow:c.data(\"fromShadow\"),to_fixed:c.data(\"toFixed\"),to_min:c.data(\"toMin\"),to_max:c.data(\"toMax\"),to_shadow:c.data(\"toShadow\"),prettify_enabled:c.data(\"prettifyEnabled\"),prettify_separator:c.data(\"prettifySeparator\"),force_edges:c.data(\"forceEdges\"),keyboard:c.data(\"keyboard\"),\r\n    keyboard_step:c.data(\"keyboardStep\"),grid:c.data(\"grid\"),grid_margin:c.data(\"gridMargin\"),grid_num:c.data(\"gridNum\"),grid_snap:c.data(\"gridSnap\"),hide_min_max:c.data(\"hideMinMax\"),hide_from_to:c.data(\"hideFromTo\"),prefix:c.data(\"prefix\"),postfix:c.data(\"postfix\"),max_postfix:c.data(\"maxPostfix\"),decorate_both:c.data(\"decorateBoth\"),values_separator:c.data(\"valuesSeparator\"),input_values_separator:c.data(\"inputValuesSeparator\"),disable:c.data(\"disable\")};c.values=c.values&&c.values.split(\",\");for(e in c)c.hasOwnProperty(e)&&\r\n(c[e]!==q&&\"\"!==c[e]||delete c[e]);a!==q&&\"\"!==a&&(a=a.split(c.input_values_separator||b.input_values_separator||\";\"),a[0]&&a[0]==+a[0]&&(a[0]=+a[0]),a[1]&&a[1]==+a[1]&&(a[1]=+a[1]),b&&b.values&&b.values.length?(d.from=a[0]&&b.values.indexOf(a[0]),d.to=a[1]&&b.values.indexOf(a[1])):(d.from=a[0]&&+a[0],d.to=a[1]&&+a[1]));f.extend(d,b);f.extend(d,c);this.options=d;this.update_check={};this.validate();this.result={input:this.$cache.input,slider:null,min:this.options.min,max:this.options.max,from:this.options.from,\r\n    from_percent:0,from_value:null,to:this.options.to,to_percent:0,to_value:null};this.init()};r.prototype={init:function(a){this.no_diapason=!1;this.coords.p_step=this.convertToPercent(this.options.step,!0);this.target=\"base\";this.toggleInput();this.append();this.setMinMax();a?(this.force_redraw=!0,this.calc(!0),this.callOnUpdate()):(this.force_redraw=!0,this.calc(!0),this.callOnStart());this.updateScene()},append:function(){this.$cache.input.before('<span class=\"irs js-irs-'+this.plugin_count+'\"></span>');\r\n        this.$cache.input.prop(\"readonly\",!0);this.$cache.cont=this.$cache.input.prev();this.result.slider=this.$cache.cont;this.$cache.cont.html('<span class=\"irs\"><span class=\"irs-line\" tabindex=\"-1\"><span class=\"irs-line-left\"></span><span class=\"irs-line-mid\"></span><span class=\"irs-line-right\"></span></span><span class=\"irs-min\">0</span><span class=\"irs-max\">1</span><span class=\"irs-from\">0</span><span class=\"irs-to\">0</span><span class=\"irs-single\">0</span></span><span class=\"irs-grid\"></span><span class=\"irs-bar\"></span>');\r\n        this.$cache.rs=this.$cache.cont.find(\".irs\");this.$cache.min=this.$cache.cont.find(\".irs-min\");this.$cache.max=this.$cache.cont.find(\".irs-max\");this.$cache.from=this.$cache.cont.find(\".irs-from\");this.$cache.to=this.$cache.cont.find(\".irs-to\");this.$cache.single=this.$cache.cont.find(\".irs-single\");this.$cache.bar=this.$cache.cont.find(\".irs-bar\");this.$cache.line=this.$cache.cont.find(\".irs-line\");this.$cache.grid=this.$cache.cont.find(\".irs-grid\");\"single\"===this.options.type?(this.$cache.cont.append('<span class=\"irs-bar-edge\"></span><span class=\"irs-shadow shadow-single\"></span><span class=\"irs-slider single\"></span>'),\r\n            this.$cache.edge=this.$cache.cont.find(\".irs-bar-edge\"),this.$cache.s_single=this.$cache.cont.find(\".single\"),this.$cache.from[0].style.visibility=\"hidden\",this.$cache.to[0].style.visibility=\"hidden\",this.$cache.shad_single=this.$cache.cont.find(\".shadow-single\")):(this.$cache.cont.append('<span class=\"irs-shadow shadow-from\"></span><span class=\"irs-shadow shadow-to\"></span><span class=\"irs-slider from\"></span><span class=\"irs-slider to\"></span>'),this.$cache.s_from=this.$cache.cont.find(\".from\"),\r\n            this.$cache.s_to=this.$cache.cont.find(\".to\"),this.$cache.shad_from=this.$cache.cont.find(\".shadow-from\"),this.$cache.shad_to=this.$cache.cont.find(\".shadow-to\"),this.setTopHandler());this.options.hide_from_to&&(this.$cache.from[0].style.display=\"none\",this.$cache.to[0].style.display=\"none\",this.$cache.single[0].style.display=\"none\");this.appendGrid();this.options.disable?(this.appendDisableMask(),this.$cache.input[0].disabled=!0):(this.$cache.cont.removeClass(\"irs-disabled\"),this.$cache.input[0].disabled=\r\n            !1,this.bindEvents());this.options.drag_interval&&(this.$cache.bar[0].style.cursor=\"ew-resize\")},setTopHandler:function(){var a=this.options.max,b=this.options.to;this.options.from>this.options.min&&b===a?this.$cache.s_from.addClass(\"type_last\"):b<a&&this.$cache.s_to.addClass(\"type_last\")},changeLevel:function(a){switch(a){case \"single\":this.coords.p_gap=this.toFixed(this.coords.p_pointer-this.coords.p_single_fake);break;case \"from\":this.coords.p_gap=this.toFixed(this.coords.p_pointer-this.coords.p_from_fake);\r\n        this.$cache.s_from.addClass(\"state_hover\");this.$cache.s_from.addClass(\"type_last\");this.$cache.s_to.removeClass(\"type_last\");break;case \"to\":this.coords.p_gap=this.toFixed(this.coords.p_pointer-this.coords.p_to_fake);this.$cache.s_to.addClass(\"state_hover\");this.$cache.s_to.addClass(\"type_last\");this.$cache.s_from.removeClass(\"type_last\");break;case \"both\":this.coords.p_gap_left=this.toFixed(this.coords.p_pointer-this.coords.p_from_fake),this.coords.p_gap_right=this.toFixed(this.coords.p_to_fake-\r\n        this.coords.p_pointer),this.$cache.s_to.removeClass(\"type_last\"),this.$cache.s_from.removeClass(\"type_last\")}},appendDisableMask:function(){this.$cache.cont.append('<span class=\"irs-disable-mask\"></span>');this.$cache.cont.addClass(\"irs-disabled\")},remove:function(){this.$cache.cont.remove();this.$cache.cont=null;this.$cache.line.off(\"keydown.irs_\"+this.plugin_count);this.$cache.body.off(\"touchmove.irs_\"+this.plugin_count);this.$cache.body.off(\"mousemove.irs_\"+this.plugin_count);this.$cache.win.off(\"touchend.irs_\"+\r\n        this.plugin_count);this.$cache.win.off(\"mouseup.irs_\"+this.plugin_count);m&&(this.$cache.body.off(\"mouseup.irs_\"+this.plugin_count),this.$cache.body.off(\"mouseleave.irs_\"+this.plugin_count));this.$cache.grid_labels=[];this.coords.big=[];this.coords.big_w=[];this.coords.big_p=[];this.coords.big_x=[];cancelAnimationFrame(this.raf_id)},bindEvents:function(){if(!this.no_diapason){this.$cache.body.on(\"touchmove.irs_\"+this.plugin_count,this.pointerMove.bind(this));this.$cache.body.on(\"mousemove.irs_\"+this.plugin_count,\r\n        this.pointerMove.bind(this));this.$cache.win.on(\"touchend.irs_\"+this.plugin_count,this.pointerUp.bind(this));this.$cache.win.on(\"mouseup.irs_\"+this.plugin_count,this.pointerUp.bind(this));this.$cache.line.on(\"touchstart.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\"));this.$cache.line.on(\"mousedown.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\"));this.options.drag_interval&&\"double\"===this.options.type?(this.$cache.bar.on(\"touchstart.irs_\"+this.plugin_count,this.pointerDown.bind(this,\r\n        \"both\")),this.$cache.bar.on(\"mousedown.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"both\"))):(this.$cache.bar.on(\"touchstart.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")),this.$cache.bar.on(\"mousedown.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")));\"single\"===this.options.type?(this.$cache.single.on(\"touchstart.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"single\")),this.$cache.s_single.on(\"touchstart.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"single\")),\r\n        this.$cache.shad_single.on(\"touchstart.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")),this.$cache.single.on(\"mousedown.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"single\")),this.$cache.s_single.on(\"mousedown.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"single\")),this.$cache.edge.on(\"mousedown.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")),this.$cache.shad_single.on(\"mousedown.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\"))):(this.$cache.single.on(\"touchstart.irs_\"+\r\n        this.plugin_count,this.pointerDown.bind(this,null)),this.$cache.single.on(\"mousedown.irs_\"+this.plugin_count,this.pointerDown.bind(this,null)),this.$cache.from.on(\"touchstart.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"from\")),this.$cache.s_from.on(\"touchstart.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"from\")),this.$cache.to.on(\"touchstart.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"to\")),this.$cache.s_to.on(\"touchstart.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"to\")),\r\n        this.$cache.shad_from.on(\"touchstart.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")),this.$cache.shad_to.on(\"touchstart.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")),this.$cache.from.on(\"mousedown.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"from\")),this.$cache.s_from.on(\"mousedown.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"from\")),this.$cache.to.on(\"mousedown.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"to\")),this.$cache.s_to.on(\"mousedown.irs_\"+\r\n        this.plugin_count,this.pointerDown.bind(this,\"to\")),this.$cache.shad_from.on(\"mousedown.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")),this.$cache.shad_to.on(\"mousedown.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")));if(this.options.keyboard)this.$cache.line.on(\"keydown.irs_\"+this.plugin_count,this.key.bind(this,\"keyboard\"));m&&(this.$cache.body.on(\"mouseup.irs_\"+this.plugin_count,this.pointerUp.bind(this)),this.$cache.body.on(\"mouseleave.irs_\"+this.plugin_count,this.pointerUp.bind(this)))}},\r\n    pointerMove:function(a){this.dragging&&(this.coords.x_pointer=(a.pageX||a.originalEvent.touches&&a.originalEvent.touches[0].pageX)-this.coords.x_gap,this.calc())},pointerUp:function(a){this.current_plugin===this.plugin_count&&this.is_active&&(this.is_active=!1,this.$cache.cont.find(\".state_hover\").removeClass(\"state_hover\"),this.force_redraw=!0,m&&f(\"*\").prop(\"unselectable\",!1),this.updateScene(),this.restoreOriginalMinInterval(),(f.contains(this.$cache.cont[0],a.target)||this.dragging)&&this.callOnFinish(),\r\n        this.dragging=!1)},pointerDown:function(a,b){b.preventDefault();var d=b.pageX||b.originalEvent.touches&&b.originalEvent.touches[0].pageX;2!==b.button&&(\"both\"===a&&this.setTempMinInterval(),a||(a=this.target||\"from\"),this.current_plugin=this.plugin_count,this.target=a,this.dragging=this.is_active=!0,this.coords.x_gap=this.$cache.rs.offset().left,this.coords.x_pointer=d-this.coords.x_gap,this.calcPointerPercent(),this.changeLevel(a),m&&f(\"*\").prop(\"unselectable\",!0),this.$cache.line.trigger(\"focus\"),\r\n        this.updateScene())},pointerClick:function(a,b){b.preventDefault();var d=b.pageX||b.originalEvent.touches&&b.originalEvent.touches[0].pageX;2!==b.button&&(this.current_plugin=this.plugin_count,this.target=a,this.is_click=!0,this.coords.x_gap=this.$cache.rs.offset().left,this.coords.x_pointer=+(d-this.coords.x_gap).toFixed(),this.force_redraw=!0,this.calc(),this.$cache.line.trigger(\"focus\"))},key:function(a,b){if(!(this.current_plugin!==this.plugin_count||b.altKey||b.ctrlKey||b.shiftKey||b.metaKey)){switch(b.which){case 83:case 65:case 40:case 37:b.preventDefault();\r\n        this.moveByKey(!1);break;case 87:case 68:case 38:case 39:b.preventDefault(),this.moveByKey(!0)}return!0}},moveByKey:function(a){var b=this.coords.p_pointer,b=a?b+this.options.keyboard_step:b-this.options.keyboard_step;this.coords.x_pointer=this.toFixed(this.coords.w_rs/100*b);this.is_key=!0;this.calc()},setMinMax:function(){this.options&&(this.options.hide_min_max?(this.$cache.min[0].style.display=\"none\",this.$cache.max[0].style.display=\"none\"):(this.options.values.length?(this.$cache.min.html(this.decorate(this.options.p_values[this.options.min])),\r\n        this.$cache.max.html(this.decorate(this.options.p_values[this.options.max]))):(this.$cache.min.html(this.decorate(this._prettify(this.options.min),this.options.min)),this.$cache.max.html(this.decorate(this._prettify(this.options.max),this.options.max))),this.labels.w_min=this.$cache.min.outerWidth(!1),this.labels.w_max=this.$cache.max.outerWidth(!1)))},setTempMinInterval:function(){var a=this.result.to-this.result.from;null===this.old_min_interval&&(this.old_min_interval=this.options.min_interval);\r\n        this.options.min_interval=a},restoreOriginalMinInterval:function(){null!==this.old_min_interval&&(this.options.min_interval=this.old_min_interval,this.old_min_interval=null)},calc:function(a){if(this.options){this.calc_count++;if(10===this.calc_count||a)this.calc_count=0,this.coords.w_rs=this.$cache.rs.outerWidth(!1),this.calcHandlePercent();if(this.coords.w_rs){this.calcPointerPercent();a=this.getHandleX();\"both\"===this.target&&(this.coords.p_gap=0,a=this.getHandleX());\"click\"===this.target&&(this.coords.p_gap=\r\n        this.coords.p_handle/2,a=this.getHandleX(),this.target=this.options.drag_interval?\"both_one\":this.chooseHandle(a));switch(this.target){case \"base\":var b=(this.options.max-this.options.min)/100;a=(this.result.from-this.options.min)/b;b=(this.result.to-this.options.min)/b;this.coords.p_single_real=this.toFixed(a);this.coords.p_from_real=this.toFixed(a);this.coords.p_to_real=this.toFixed(b);this.coords.p_single_real=this.checkDiapason(this.coords.p_single_real,this.options.from_min,this.options.from_max);\r\n        this.coords.p_from_real=this.checkDiapason(this.coords.p_from_real,this.options.from_min,this.options.from_max);this.coords.p_to_real=this.checkDiapason(this.coords.p_to_real,this.options.to_min,this.options.to_max);this.coords.p_single_fake=this.convertToFakePercent(this.coords.p_single_real);this.coords.p_from_fake=this.convertToFakePercent(this.coords.p_from_real);this.coords.p_to_fake=this.convertToFakePercent(this.coords.p_to_real);this.target=null;break;case \"single\":if(this.options.from_fixed)break;\r\n        this.coords.p_single_real=this.convertToRealPercent(a);this.coords.p_single_real=this.calcWithStep(this.coords.p_single_real);this.coords.p_single_real=this.checkDiapason(this.coords.p_single_real,this.options.from_min,this.options.from_max);this.coords.p_single_fake=this.convertToFakePercent(this.coords.p_single_real);break;case \"from\":if(this.options.from_fixed)break;this.coords.p_from_real=this.convertToRealPercent(a);this.coords.p_from_real=this.calcWithStep(this.coords.p_from_real);this.coords.p_from_real>\r\n    this.coords.p_to_real&&(this.coords.p_from_real=this.coords.p_to_real);this.coords.p_from_real=this.checkDiapason(this.coords.p_from_real,this.options.from_min,this.options.from_max);this.coords.p_from_real=this.checkMinInterval(this.coords.p_from_real,this.coords.p_to_real,\"from\");this.coords.p_from_real=this.checkMaxInterval(this.coords.p_from_real,this.coords.p_to_real,\"from\");this.coords.p_from_fake=this.convertToFakePercent(this.coords.p_from_real);break;case \"to\":if(this.options.to_fixed)break;\r\n        this.coords.p_to_real=this.convertToRealPercent(a);this.coords.p_to_real=this.calcWithStep(this.coords.p_to_real);this.coords.p_to_real<this.coords.p_from_real&&(this.coords.p_to_real=this.coords.p_from_real);this.coords.p_to_real=this.checkDiapason(this.coords.p_to_real,this.options.to_min,this.options.to_max);this.coords.p_to_real=this.checkMinInterval(this.coords.p_to_real,this.coords.p_from_real,\"to\");this.coords.p_to_real=this.checkMaxInterval(this.coords.p_to_real,this.coords.p_from_real,\"to\");\r\n        this.coords.p_to_fake=this.convertToFakePercent(this.coords.p_to_real);break;case \"both\":if(this.options.from_fixed||this.options.to_fixed)break;a=this.toFixed(a+.001*this.coords.p_handle);this.coords.p_from_real=this.convertToRealPercent(a)-this.coords.p_gap_left;this.coords.p_from_real=this.calcWithStep(this.coords.p_from_real);this.coords.p_from_real=this.checkDiapason(this.coords.p_from_real,this.options.from_min,this.options.from_max);this.coords.p_from_real=this.checkMinInterval(this.coords.p_from_real,\r\n        this.coords.p_to_real,\"from\");this.coords.p_from_fake=this.convertToFakePercent(this.coords.p_from_real);this.coords.p_to_real=this.convertToRealPercent(a)+this.coords.p_gap_right;this.coords.p_to_real=this.calcWithStep(this.coords.p_to_real);this.coords.p_to_real=this.checkDiapason(this.coords.p_to_real,this.options.to_min,this.options.to_max);this.coords.p_to_real=this.checkMinInterval(this.coords.p_to_real,this.coords.p_from_real,\"to\");this.coords.p_to_fake=this.convertToFakePercent(this.coords.p_to_real);\r\n        break;case \"both_one\":if(!this.options.from_fixed&&!this.options.to_fixed){var d=this.convertToRealPercent(a);a=this.result.to_percent-this.result.from_percent;var c=a/2,b=d-c,d=d+c;0>b&&(b=0,d=b+a);100<d&&(d=100,b=d-a);this.coords.p_from_real=this.calcWithStep(b);this.coords.p_from_real=this.checkDiapason(this.coords.p_from_real,this.options.from_min,this.options.from_max);this.coords.p_from_fake=this.convertToFakePercent(this.coords.p_from_real);this.coords.p_to_real=this.calcWithStep(d);this.coords.p_to_real=\r\n        this.checkDiapason(this.coords.p_to_real,this.options.to_min,this.options.to_max);this.coords.p_to_fake=this.convertToFakePercent(this.coords.p_to_real)}}\"single\"===this.options.type?(this.coords.p_bar_x=this.coords.p_handle/2,this.coords.p_bar_w=this.coords.p_single_fake,this.result.from_percent=this.coords.p_single_real,this.result.from=this.convertToValue(this.coords.p_single_real),this.options.values.length&&(this.result.from_value=this.options.values[this.result.from])):(this.coords.p_bar_x=\r\n        this.toFixed(this.coords.p_from_fake+this.coords.p_handle/2),this.coords.p_bar_w=this.toFixed(this.coords.p_to_fake-this.coords.p_from_fake),this.result.from_percent=this.coords.p_from_real,this.result.from=this.convertToValue(this.coords.p_from_real),this.result.to_percent=this.coords.p_to_real,this.result.to=this.convertToValue(this.coords.p_to_real),this.options.values.length&&(this.result.from_value=this.options.values[this.result.from],this.result.to_value=this.options.values[this.result.to]));\r\n        this.calcMinMax();this.calcLabels()}}},calcPointerPercent:function(){this.coords.w_rs?(0>this.coords.x_pointer||isNaN(this.coords.x_pointer)?this.coords.x_pointer=0:this.coords.x_pointer>this.coords.w_rs&&(this.coords.x_pointer=this.coords.w_rs),this.coords.p_pointer=this.toFixed(this.coords.x_pointer/this.coords.w_rs*100)):this.coords.p_pointer=0},convertToRealPercent:function(a){return a/(100-this.coords.p_handle)*100},convertToFakePercent:function(a){return a/100*(100-this.coords.p_handle)},getHandleX:function(){var a=\r\n        100-this.coords.p_handle,b=this.toFixed(this.coords.p_pointer-this.coords.p_gap);0>b?b=0:b>a&&(b=a);return b},calcHandlePercent:function(){this.coords.w_handle=\"single\"===this.options.type?this.$cache.s_single.outerWidth(!1):this.$cache.s_from.outerWidth(!1);this.coords.p_handle=this.toFixed(this.coords.w_handle/this.coords.w_rs*100)},chooseHandle:function(a){return\"single\"===this.options.type?\"single\":a>=this.coords.p_from_real+(this.coords.p_to_real-this.coords.p_from_real)/2?this.options.to_fixed?\r\n        \"from\":\"to\":this.options.from_fixed?\"to\":\"from\"},calcMinMax:function(){this.coords.w_rs&&(this.labels.p_min=this.labels.w_min/this.coords.w_rs*100,this.labels.p_max=this.labels.w_max/this.coords.w_rs*100)},calcLabels:function(){this.coords.w_rs&&!this.options.hide_from_to&&(\"single\"===this.options.type?(this.labels.w_single=this.$cache.single.outerWidth(!1),this.labels.p_single_fake=this.labels.w_single/this.coords.w_rs*100,this.labels.p_single_left=this.coords.p_single_fake+this.coords.p_handle/\r\n        2-this.labels.p_single_fake/2):(this.labels.w_from=this.$cache.from.outerWidth(!1),this.labels.p_from_fake=this.labels.w_from/this.coords.w_rs*100,this.labels.p_from_left=this.coords.p_from_fake+this.coords.p_handle/2-this.labels.p_from_fake/2,this.labels.p_from_left=this.toFixed(this.labels.p_from_left),this.labels.p_from_left=this.checkEdges(this.labels.p_from_left,this.labels.p_from_fake),this.labels.w_to=this.$cache.to.outerWidth(!1),this.labels.p_to_fake=this.labels.w_to/this.coords.w_rs*100,\r\n        this.labels.p_to_left=this.coords.p_to_fake+this.coords.p_handle/2-this.labels.p_to_fake/2,this.labels.p_to_left=this.toFixed(this.labels.p_to_left),this.labels.p_to_left=this.checkEdges(this.labels.p_to_left,this.labels.p_to_fake),this.labels.w_single=this.$cache.single.outerWidth(!1),this.labels.p_single_fake=this.labels.w_single/this.coords.w_rs*100,this.labels.p_single_left=(this.labels.p_from_left+this.labels.p_to_left+this.labels.p_to_fake)/2-this.labels.p_single_fake/2,this.labels.p_single_left=\r\n        this.toFixed(this.labels.p_single_left)),this.labels.p_single_left=this.checkEdges(this.labels.p_single_left,this.labels.p_single_fake))},updateScene:function(){this.raf_id&&(cancelAnimationFrame(this.raf_id),this.raf_id=null);clearTimeout(this.update_tm);this.update_tm=null;this.options&&(this.drawHandles(),this.is_active?this.raf_id=requestAnimationFrame(this.updateScene.bind(this)):this.update_tm=setTimeout(this.updateScene.bind(this),300))},drawHandles:function(){this.coords.w_rs=this.$cache.rs.outerWidth(!1);\r\n        if(this.coords.w_rs){this.coords.w_rs!==this.coords.w_rs_old&&(this.target=\"base\",this.is_resize=!0);if(this.coords.w_rs!==this.coords.w_rs_old||this.force_redraw)this.setMinMax(),this.calc(!0),this.drawLabels(),this.options.grid&&(this.calcGridMargin(),this.calcGridLabels()),this.force_redraw=!0,this.coords.w_rs_old=this.coords.w_rs,this.drawShadow();if(this.coords.w_rs&&(this.dragging||this.force_redraw||this.is_key)){if(this.old_from!==this.result.from||this.old_to!==this.result.to||this.force_redraw||\r\n            this.is_key){this.drawLabels();this.$cache.bar[0].style.left=this.coords.p_bar_x+\"%\";this.$cache.bar[0].style.width=this.coords.p_bar_w+\"%\";if(\"single\"===this.options.type)this.$cache.s_single[0].style.left=this.coords.p_single_fake+\"%\";else{this.$cache.s_from[0].style.left=this.coords.p_from_fake+\"%\";this.$cache.s_to[0].style.left=this.coords.p_to_fake+\"%\";if(this.old_from!==this.result.from||this.force_redraw)this.$cache.from[0].style.left=this.labels.p_from_left+\"%\";if(this.old_to!==this.result.to||\r\n            this.force_redraw)this.$cache.to[0].style.left=this.labels.p_to_left+\"%\"}this.$cache.single[0].style.left=this.labels.p_single_left+\"%\";this.writeToInput();this.old_from===this.result.from&&this.old_to===this.result.to||this.is_start||(this.$cache.input.trigger(\"change\"),this.$cache.input.trigger(\"input\"));this.old_from=this.result.from;this.old_to=this.result.to;this.is_resize||this.is_update||this.is_start||this.is_finish||this.callOnChange();if(this.is_key||this.is_click||this.is_first_update)this.is_first_update=\r\n            this.is_click=this.is_key=!1,this.callOnFinish();this.is_finish=this.is_resize=this.is_update=!1}this.force_redraw=this.is_click=this.is_key=this.is_start=!1}}},drawLabels:function(){if(this.options){var a=this.options.values.length,b=this.options.p_values,d;if(!this.options.hide_from_to)if(\"single\"===this.options.type)a=a?this.decorate(b[this.result.from]):this.decorate(this._prettify(this.result.from),this.result.from),this.$cache.single.html(a),this.calcLabels(),this.$cache.min[0].style.visibility=\r\n        this.labels.p_single_left<this.labels.p_min+1?\"hidden\":\"visible\",this.$cache.max[0].style.visibility=this.labels.p_single_left+this.labels.p_single_fake>100-this.labels.p_max-1?\"hidden\":\"visible\";else{a?(this.options.decorate_both?(a=this.decorate(b[this.result.from]),a+=this.options.values_separator,a+=this.decorate(b[this.result.to])):a=this.decorate(b[this.result.from]+this.options.values_separator+b[this.result.to]),d=this.decorate(b[this.result.from]),b=this.decorate(b[this.result.to])):(this.options.decorate_both?\r\n        (a=this.decorate(this._prettify(this.result.from),this.result.from),a+=this.options.values_separator,a+=this.decorate(this._prettify(this.result.to),this.result.to)):a=this.decorate(this._prettify(this.result.from)+this.options.values_separator+this._prettify(this.result.to),this.result.to),d=this.decorate(this._prettify(this.result.from),this.result.from),b=this.decorate(this._prettify(this.result.to),this.result.to));this.$cache.single.html(a);this.$cache.from.html(d);this.$cache.to.html(b);this.calcLabels();\r\n        b=Math.min(this.labels.p_single_left,this.labels.p_from_left);a=this.labels.p_single_left+this.labels.p_single_fake;d=this.labels.p_to_left+this.labels.p_to_fake;var c=Math.max(a,d);this.labels.p_from_left+this.labels.p_from_fake>=this.labels.p_to_left?(this.$cache.from[0].style.visibility=\"hidden\",this.$cache.to[0].style.visibility=\"hidden\",this.$cache.single[0].style.visibility=\"visible\",this.result.from===this.result.to?(\"from\"===this.target?this.$cache.from[0].style.visibility=\"visible\":\"to\"===\r\n        this.target?this.$cache.to[0].style.visibility=\"visible\":this.target||(this.$cache.from[0].style.visibility=\"visible\"),this.$cache.single[0].style.visibility=\"hidden\",c=d):(this.$cache.from[0].style.visibility=\"hidden\",this.$cache.to[0].style.visibility=\"hidden\",this.$cache.single[0].style.visibility=\"visible\",c=Math.max(a,d))):(this.$cache.from[0].style.visibility=\"visible\",this.$cache.to[0].style.visibility=\"visible\",this.$cache.single[0].style.visibility=\"hidden\");this.$cache.min[0].style.visibility=\r\n            b<this.labels.p_min+1?\"hidden\":\"visible\";this.$cache.max[0].style.visibility=c>100-this.labels.p_max-1?\"hidden\":\"visible\"}}},drawShadow:function(){var a=this.options,b=this.$cache,d=\"number\"===typeof a.from_min&&!isNaN(a.from_min),c=\"number\"===typeof a.from_max&&!isNaN(a.from_max),e=\"number\"===typeof a.to_min&&!isNaN(a.to_min),g=\"number\"===typeof a.to_max&&!isNaN(a.to_max);\"single\"===a.type?a.from_shadow&&(d||c)?(d=this.convertToPercent(d?a.from_min:a.min),c=this.convertToPercent(c?a.from_max:a.max)-\r\n        d,d=this.toFixed(d-this.coords.p_handle/100*d),c=this.toFixed(c-this.coords.p_handle/100*c),d+=this.coords.p_handle/2,b.shad_single[0].style.display=\"block\",b.shad_single[0].style.left=d+\"%\",b.shad_single[0].style.width=c+\"%\"):b.shad_single[0].style.display=\"none\":(a.from_shadow&&(d||c)?(d=this.convertToPercent(d?a.from_min:a.min),c=this.convertToPercent(c?a.from_max:a.max)-d,d=this.toFixed(d-this.coords.p_handle/100*d),c=this.toFixed(c-this.coords.p_handle/100*c),d+=this.coords.p_handle/2,b.shad_from[0].style.display=\r\n        \"block\",b.shad_from[0].style.left=d+\"%\",b.shad_from[0].style.width=c+\"%\"):b.shad_from[0].style.display=\"none\",a.to_shadow&&(e||g)?(e=this.convertToPercent(e?a.to_min:a.min),a=this.convertToPercent(g?a.to_max:a.max)-e,e=this.toFixed(e-this.coords.p_handle/100*e),a=this.toFixed(a-this.coords.p_handle/100*a),e+=this.coords.p_handle/2,b.shad_to[0].style.display=\"block\",b.shad_to[0].style.left=e+\"%\",b.shad_to[0].style.width=a+\"%\"):b.shad_to[0].style.display=\"none\")},writeToInput:function(){\"single\"===\r\n    this.options.type?(this.options.values.length?this.$cache.input.prop(\"value\",this.result.from_value):this.$cache.input.prop(\"value\",this.result.from),this.$cache.input.data(\"from\",this.result.from)):(this.options.values.length?this.$cache.input.prop(\"value\",this.result.from_value+this.options.input_values_separator+this.result.to_value):this.$cache.input.prop(\"value\",this.result.from+this.options.input_values_separator+this.result.to),this.$cache.input.data(\"from\",this.result.from),this.$cache.input.data(\"to\",\r\n        this.result.to))},callOnStart:function(){this.writeToInput();if(this.options.onStart&&\"function\"===typeof this.options.onStart)this.options.onStart(this.result)},callOnChange:function(){this.writeToInput();if(this.options.onChange&&\"function\"===typeof this.options.onChange)this.options.onChange(this.result)},callOnFinish:function(){this.writeToInput();if(this.options.onFinish&&\"function\"===typeof this.options.onFinish)this.options.onFinish(this.result)},callOnUpdate:function(){this.writeToInput();\r\n        if(this.options.onUpdate&&\"function\"===typeof this.options.onUpdate)this.options.onUpdate(this.result)},toggleInput:function(){this.$cache.input.toggleClass(\"irs-hidden-input\")},convertToPercent:function(a,b){var d=this.options.max-this.options.min;return d?this.toFixed((b?a:a-this.options.min)/(d/100)):(this.no_diapason=!0,0)},convertToValue:function(a){var b=this.options.min,d=this.options.max,c=b.toString().split(\".\")[1],e=d.toString().split(\".\")[1],g,l,f=0,k=0;if(0===a)return this.options.min;\r\n        if(100===a)return this.options.max;c&&(f=g=c.length);e&&(f=l=e.length);g&&l&&(f=g>=l?g:l);0>b&&(k=Math.abs(b),b=+(b+k).toFixed(f),d=+(d+k).toFixed(f));a=(d-b)/100*a+b;(b=this.options.step.toString().split(\".\")[1])?a=+a.toFixed(b.length):(a/=this.options.step,a*=this.options.step,a=+a.toFixed(0));k&&(a-=k);k=b?+a.toFixed(b.length):this.toFixed(a);k<this.options.min?k=this.options.min:k>this.options.max&&(k=this.options.max);return k},calcWithStep:function(a){var b=Math.round(a/this.coords.p_step)*\r\n        this.coords.p_step;100<b&&(b=100);100===a&&(b=100);return this.toFixed(b)},checkMinInterval:function(a,b,d){var c=this.options;if(!c.min_interval)return a;a=this.convertToValue(a);b=this.convertToValue(b);\"from\"===d?b-a<c.min_interval&&(a=b-c.min_interval):a-b<c.min_interval&&(a=b+c.min_interval);return this.convertToPercent(a)},checkMaxInterval:function(a,b,d){var c=this.options;if(!c.max_interval)return a;a=this.convertToValue(a);b=this.convertToValue(b);\"from\"===d?b-a>c.max_interval&&(a=b-c.max_interval):\r\n        a-b>c.max_interval&&(a=b+c.max_interval);return this.convertToPercent(a)},checkDiapason:function(a,b,d){a=this.convertToValue(a);var c=this.options;\"number\"!==typeof b&&(b=c.min);\"number\"!==typeof d&&(d=c.max);a<b&&(a=b);a>d&&(a=d);return this.convertToPercent(a)},toFixed:function(a){a=a.toFixed(20);return+a},_prettify:function(a){return this.options.prettify_enabled?this.options.prettify&&\"function\"===typeof this.options.prettify?this.options.prettify(a):this.prettify(a):a},prettify:function(a){return a.toString().replace(/(\\d{1,3}(?=(?:\\d\\d\\d)+(?!\\d)))/g,\r\n        \"$1\"+this.options.prettify_separator)},checkEdges:function(a,b){if(!this.options.force_edges)return this.toFixed(a);0>a?a=0:a>100-b&&(a=100-b);return this.toFixed(a)},validate:function(){var a=this.options,b=this.result,d=a.values,c=d.length,e,g;\"string\"===typeof a.min&&(a.min=+a.min);\"string\"===typeof a.max&&(a.max=+a.max);\"string\"===typeof a.from&&(a.from=+a.from);\"string\"===typeof a.to&&(a.to=+a.to);\"string\"===typeof a.step&&(a.step=+a.step);\"string\"===typeof a.from_min&&(a.from_min=+a.from_min);\r\n        \"string\"===typeof a.from_max&&(a.from_max=+a.from_max);\"string\"===typeof a.to_min&&(a.to_min=+a.to_min);\"string\"===typeof a.to_max&&(a.to_max=+a.to_max);\"string\"===typeof a.keyboard_step&&(a.keyboard_step=+a.keyboard_step);\"string\"===typeof a.grid_num&&(a.grid_num=+a.grid_num);a.max<a.min&&(a.max=a.min);if(c)for(a.p_values=[],a.min=0,a.max=c-1,a.step=1,a.grid_num=a.max,a.grid_snap=!0,g=0;g<c;g++)e=+d[g],isNaN(e)?e=d[g]:(d[g]=e,e=this._prettify(e)),a.p_values.push(e);if(\"number\"!==typeof a.from||isNaN(a.from))a.from=\r\n            a.min;if(\"number\"!==typeof a.to||isNaN(a.to))a.to=a.max;\"single\"===a.type?(a.from<a.min&&(a.from=a.min),a.from>a.max&&(a.from=a.max)):(a.from<a.min&&(a.from=a.min),a.from>a.max&&(a.from=a.max),a.to<a.min&&(a.to=a.min),a.to>a.max&&(a.to=a.max),this.update_check.from&&(this.update_check.from!==a.from&&a.from>a.to&&(a.from=a.to),this.update_check.to!==a.to&&a.to<a.from&&(a.to=a.from)),a.from>a.to&&(a.from=a.to),a.to<a.from&&(a.to=a.from));if(\"number\"!==typeof a.step||isNaN(a.step)||!a.step||0>a.step)a.step=\r\n            1;if(\"number\"!==typeof a.keyboard_step||isNaN(a.keyboard_step)||!a.keyboard_step||0>a.keyboard_step)a.keyboard_step=5;\"number\"===typeof a.from_min&&a.from<a.from_min&&(a.from=a.from_min);\"number\"===typeof a.from_max&&a.from>a.from_max&&(a.from=a.from_max);\"number\"===typeof a.to_min&&a.to<a.to_min&&(a.to=a.to_min);\"number\"===typeof a.to_max&&a.from>a.to_max&&(a.to=a.to_max);if(b){b.min!==a.min&&(b.min=a.min);b.max!==a.max&&(b.max=a.max);if(b.from<b.min||b.from>b.max)b.from=a.from;if(b.to<b.min||b.to>\r\n            b.max)b.to=a.to}if(\"number\"!==typeof a.min_interval||isNaN(a.min_interval)||!a.min_interval||0>a.min_interval)a.min_interval=0;if(\"number\"!==typeof a.max_interval||isNaN(a.max_interval)||!a.max_interval||0>a.max_interval)a.max_interval=0;a.min_interval&&a.min_interval>a.max-a.min&&(a.min_interval=a.max-a.min);a.max_interval&&a.max_interval>a.max-a.min&&(a.max_interval=a.max-a.min)},decorate:function(a,b){var d=\"\",c=this.options;c.prefix&&(d+=c.prefix);d+=a;c.max_postfix&&(c.values.length&&a===c.p_values[c.max]?\r\n        (d+=c.max_postfix,c.postfix&&(d+=\" \")):b===c.max&&(d+=c.max_postfix,c.postfix&&(d+=\" \")));c.postfix&&(d+=c.postfix);return d},updateFrom:function(){this.result.from=this.options.from;this.result.from_percent=this.convertToPercent(this.result.from);this.options.values&&(this.result.from_value=this.options.values[this.result.from])},updateTo:function(){this.result.to=this.options.to;this.result.to_percent=this.convertToPercent(this.result.to);this.options.values&&(this.result.to_value=this.options.values[this.result.to])},\r\n    updateResult:function(){this.result.min=this.options.min;this.result.max=this.options.max;this.updateFrom();this.updateTo()},appendGrid:function(){if(this.options.grid){var a=this.options,b,d;b=a.max-a.min;var c=a.grid_num,e,g,f=4,h,k,m,n=\"\";this.calcGridMargin();a.grid_snap?(c=b/a.step,e=this.toFixed(a.step/(b/100))):e=this.toFixed(100/c);4<c&&(f=3);7<c&&(f=2);14<c&&(f=1);28<c&&(f=0);for(b=0;b<c+1;b++){h=f;g=this.toFixed(e*b);100<g&&(g=100,h-=2,0>h&&(h=0));this.coords.big[b]=g;k=(g-e*(b-1))/(h+1);\r\n        for(d=1;d<=h&&0!==g;d++)m=this.toFixed(g-k*d),n+='<span class=\"irs-grid-pol small\" style=\"left: '+m+'%\"></span>';n+='<span class=\"irs-grid-pol\" style=\"left: '+g+'%\"></span>';d=this.convertToValue(g);d=a.values.length?a.p_values[d]:this._prettify(d);n+='<span class=\"irs-grid-text js-grid-text-'+b+'\" style=\"left: '+g+'%\">'+d+\"</span>\"}this.coords.big_num=Math.ceil(c+1);this.$cache.cont.addClass(\"irs-with-grid\");this.$cache.grid.html(n);this.cacheGridLabels()}},cacheGridLabels:function(){var a,b,d=this.coords.big_num;\r\n        for(b=0;b<d;b++)a=this.$cache.grid.find(\".js-grid-text-\"+b),this.$cache.grid_labels.push(a);this.calcGridLabels()},calcGridLabels:function(){var a,b;b=[];var d=[],c=this.coords.big_num;for(a=0;a<c;a++)this.coords.big_w[a]=this.$cache.grid_labels[a].outerWidth(!1),this.coords.big_p[a]=this.toFixed(this.coords.big_w[a]/this.coords.w_rs*100),this.coords.big_x[a]=this.toFixed(this.coords.big_p[a]/2),b[a]=this.toFixed(this.coords.big[a]-this.coords.big_x[a]),d[a]=this.toFixed(b[a]+this.coords.big_p[a]);\r\n        this.options.force_edges&&(b[0]<-this.coords.grid_gap&&(b[0]=-this.coords.grid_gap,d[0]=this.toFixed(b[0]+this.coords.big_p[0]),this.coords.big_x[0]=this.coords.grid_gap),d[c-1]>100+this.coords.grid_gap&&(d[c-1]=100+this.coords.grid_gap,b[c-1]=this.toFixed(d[c-1]-this.coords.big_p[c-1]),this.coords.big_x[c-1]=this.toFixed(this.coords.big_p[c-1]-this.coords.grid_gap)));this.calcGridCollision(2,b,d);this.calcGridCollision(4,b,d);for(a=0;a<c;a++)b=this.$cache.grid_labels[a][0],this.coords.big_x[a]!==\r\n        Number.POSITIVE_INFINITY&&(b.style.marginLeft=-this.coords.big_x[a]+\"%\")},calcGridCollision:function(a,b,d){var c,e,g,f=this.coords.big_num;for(c=0;c<f;c+=a){e=c+a/2;if(e>=f)break;g=this.$cache.grid_labels[e][0];g.style.visibility=d[c]<=b[e]?\"visible\":\"hidden\"}},calcGridMargin:function(){this.options.grid_margin&&(this.coords.w_rs=this.$cache.rs.outerWidth(!1),this.coords.w_rs&&(this.coords.w_handle=\"single\"===this.options.type?this.$cache.s_single.outerWidth(!1):this.$cache.s_from.outerWidth(!1),\r\n        this.coords.p_handle=this.toFixed(this.coords.w_handle/this.coords.w_rs*100),this.coords.grid_gap=this.toFixed(this.coords.p_handle/2-.1),this.$cache.grid[0].style.width=this.toFixed(100-this.coords.p_handle)+\"%\",this.$cache.grid[0].style.left=this.coords.grid_gap+\"%\"))},update:function(a){this.input&&(this.is_update=!0,this.options.from=this.result.from,this.options.to=this.result.to,this.update_check.from=this.result.from,this.update_check.to=this.result.to,this.options=f.extend(this.options,a),\r\n        this.validate(),this.updateResult(a),this.toggleInput(),this.remove(),this.init(!0))},reset:function(){this.input&&(this.updateResult(),this.update())},destroy:function(){this.input&&(this.toggleInput(),this.$cache.input.prop(\"readonly\",!1),f.data(this.input,\"ionRangeSlider\",null),this.remove(),this.options=this.input=null)}};f.fn.ionRangeSlider=function(a){return this.each(function(){f.data(this,\"ionRangeSlider\")||f.data(this,\"ionRangeSlider\",new r(this,a,u++))})};(function(){for(var a=0,b=[\"ms\",\r\n    \"moz\",\"webkit\",\"o\"],d=0;d<b.length&&!h.requestAnimationFrame;++d)h.requestAnimationFrame=h[b[d]+\"RequestAnimationFrame\"],h.cancelAnimationFrame=h[b[d]+\"CancelAnimationFrame\"]||h[b[d]+\"CancelRequestAnimationFrame\"];h.requestAnimationFrame||(h.requestAnimationFrame=function(b,d){var c=(new Date).getTime(),e=Math.max(0,16-(c-a)),f=h.setTimeout(function(){b(c+e)},e);a=c+e;return f});h.cancelAnimationFrame||(h.cancelAnimationFrame=function(a){clearTimeout(a)})})()});\r\n","Mageplaza_Core/js/jquery.magnific-popup.min.js":"// Magnific Popup v1.1.0 by Dmitry Semenov\r\n// http://bit.ly/magnific-popup#build=inline+image+ajax+iframe+gallery+retina+imagezoom\r\n(function(a){typeof define==\"function\"&&define.amd?define([\"jquery\"],a):typeof exports==\"object\"?a(require(\"jquery\")):a(window.jQuery||window.Zepto)})(function(a){var b=\"Close\",c=\"BeforeClose\",d=\"AfterClose\",e=\"BeforeAppend\",f=\"MarkupParse\",g=\"Open\",h=\"Change\",i=\"mfp\",j=\".\"+i,k=\"mfp-ready\",l=\"mfp-removing\",m=\"mfp-prevent-close\",n,o=function(){},p=!!window.jQuery,q,r=a(window),s,t,u,v,w=function(a,b){n.ev.on(i+a+j,b)},x=function(b,c,d,e){var f=document.createElement(\"div\");return f.className=\"mfp-\"+b,d&&(f.innerHTML=d),e?c&&c.appendChild(f):(f=a(f),c&&f.appendTo(c)),f},y=function(b,c){n.ev.triggerHandler(i+b,c),n.st.callbacks&&(b=b.charAt(0).toLowerCase()+b.slice(1),n.st.callbacks[b]&&n.st.callbacks[b].apply(n,a.isArray(c)?c:[c]))},z=function(b){if(b!==v||!n.currTemplate.closeBtn)n.currTemplate.closeBtn=a(n.st.closeMarkup.replace(\"%title%\",n.st.tClose)),v=b;return n.currTemplate.closeBtn},A=function(){a.magnificPopup.instance||(n=new o,n.init(),a.magnificPopup.instance=n)},B=function(){var a=document.createElement(\"p\").style,b=[\"ms\",\"O\",\"Moz\",\"Webkit\"];if(a.transition!==undefined)return!0;while(b.length)if(b.pop()+\"Transition\"in a)return!0;return!1};o.prototype={constructor:o,init:function(){var b=navigator.appVersion;n.isLowIE=n.isIE8=document.all&&!document.addEventListener,n.isAndroid=/android/gi.test(b),n.isIOS=/iphone|ipad|ipod/gi.test(b),n.supportsTransition=B(),n.probablyMobile=n.isAndroid||n.isIOS||/(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent),s=a(document),n.popupsCache={}},open:function(b){var c;if(b.isObj===!1){n.items=b.items.toArray(),n.index=0;var d=b.items,e;for(c=0;c<d.length;c++){e=d[c],e.parsed&&(e=e.el[0]);if(e===b.el[0]){n.index=c;break}}}else n.items=a.isArray(b.items)?b.items:[b.items],n.index=b.index||0;if(n.isOpen){n.updateItemHTML();return}n.types=[],u=\"\",b.mainEl&&b.mainEl.length?n.ev=b.mainEl.eq(0):n.ev=s,b.key?(n.popupsCache[b.key]||(n.popupsCache[b.key]={}),n.currTemplate=n.popupsCache[b.key]):n.currTemplate={},n.st=a.extend(!0,{},a.magnificPopup.defaults,b),n.fixedContentPos=n.st.fixedContentPos===\"auto\"?!n.probablyMobile:n.st.fixedContentPos,n.st.modal&&(n.st.closeOnContentClick=!1,n.st.closeOnBgClick=!1,n.st.showCloseBtn=!1,n.st.enableEscapeKey=!1),n.bgOverlay||(n.bgOverlay=x(\"bg\").on(\"click\"+j,function(){n.close()}),n.wrap=x(\"wrap\").attr(\"tabindex\",-1).on(\"click\"+j,function(a){n._checkIfClose(a.target)&&n.close()}),n.container=x(\"container\",n.wrap)),n.contentContainer=x(\"content\"),n.st.preloader&&(n.preloader=x(\"preloader\",n.container,n.st.tLoading));var h=a.magnificPopup.modules;for(c=0;c<h.length;c++){var i=h[c];i=i.charAt(0).toUpperCase()+i.slice(1),n[\"init\"+i].call(n)}y(\"BeforeOpen\"),n.st.showCloseBtn&&(n.st.closeBtnInside?(w(f,function(a,b,c,d){c.close_replaceWith=z(d.type)}),u+=\" mfp-close-btn-in\"):n.wrap.append(z())),n.st.alignTop&&(u+=\" mfp-align-top\"),n.fixedContentPos?n.wrap.css({overflow:n.st.overflowY,overflowX:\"hidden\",overflowY:n.st.overflowY}):n.wrap.css({top:r.scrollTop(),position:\"absolute\"}),(n.st.fixedBgPos===!1||n.st.fixedBgPos===\"auto\"&&!n.fixedContentPos)&&n.bgOverlay.css({height:s.height(),position:\"absolute\"}),n.st.enableEscapeKey&&s.on(\"keyup\"+j,function(a){a.keyCode===27&&n.close()}),r.on(\"resize\"+j,function(){n.updateSize()}),n.st.closeOnContentClick||(u+=\" mfp-auto-cursor\"),u&&n.wrap.addClass(u);var l=n.wH=r.height(),m={};if(n.fixedContentPos&&n._hasScrollBar(l)){var o=n._getScrollbarSize();o&&(m.marginRight=o)}n.fixedContentPos&&(n.isIE7?a(\"body, html\").css(\"overflow\",\"hidden\"):m.overflow=\"hidden\");var p=n.st.mainClass;return n.isIE7&&(p+=\" mfp-ie7\"),p&&n._addClassToMFP(p),n.updateItemHTML(),y(\"BuildControls\"),a(\"html\").css(m),n.bgOverlay.add(n.wrap).prependTo(n.st.prependTo||a(document.body)),n._lastFocusedEl=document.activeElement,setTimeout(function(){n.content?(n._addClassToMFP(k),n._setFocus()):n.bgOverlay.addClass(k),s.on(\"focusin\"+j,n._onFocusIn)},16),n.isOpen=!0,n.updateSize(l),y(g),b},close:function(){if(!n.isOpen)return;y(c),n.isOpen=!1,n.st.removalDelay&&!n.isLowIE&&n.supportsTransition?(n._addClassToMFP(l),setTimeout(function(){n._close()},n.st.removalDelay)):n._close()},_close:function(){y(b);var c=l+\" \"+k+\" \";n.bgOverlay.detach(),n.wrap.detach(),n.container.empty(),n.st.mainClass&&(c+=n.st.mainClass+\" \"),n._removeClassFromMFP(c);if(n.fixedContentPos){var e={marginRight:\"\"};n.isIE7?a(\"body, html\").css(\"overflow\",\"\"):e.overflow=\"\",a(\"html\").css(e)}s.off(\"keyup\"+j+\" focusin\"+j),n.ev.off(j),n.wrap.attr(\"class\",\"mfp-wrap\").removeAttr(\"style\"),n.bgOverlay.attr(\"class\",\"mfp-bg\"),n.container.attr(\"class\",\"mfp-container\"),n.st.showCloseBtn&&(!n.st.closeBtnInside||n.currTemplate[n.currItem.type]===!0)&&n.currTemplate.closeBtn&&n.currTemplate.closeBtn.detach(),n.st.autoFocusLast&&n._lastFocusedEl&&a(n._lastFocusedEl).focus(),n.currItem=null,n.content=null,n.currTemplate=null,n.prevHeight=0,y(d)},updateSize:function(a){if(n.isIOS){var b=document.documentElement.clientWidth/window.innerWidth,c=window.innerHeight*b;n.wrap.css(\"height\",c),n.wH=c}else n.wH=a||r.height();n.fixedContentPos||n.wrap.css(\"height\",n.wH),y(\"Resize\")},updateItemHTML:function(){var b=n.items[n.index];n.contentContainer.detach(),n.content&&n.content.detach(),b.parsed||(b=n.parseEl(n.index));var c=b.type;y(\"BeforeChange\",[n.currItem?n.currItem.type:\"\",c]),n.currItem=b;if(!n.currTemplate[c]){var d=n.st[c]?n.st[c].markup:!1;y(\"FirstMarkupParse\",d),d?n.currTemplate[c]=a(d):n.currTemplate[c]=!0}t&&t!==b.type&&n.container.removeClass(\"mfp-\"+t+\"-holder\");var e=n[\"get\"+c.charAt(0).toUpperCase()+c.slice(1)](b,n.currTemplate[c]);n.appendContent(e,c),b.preloaded=!0,y(h,b),t=b.type,n.container.prepend(n.contentContainer),y(\"AfterChange\")},appendContent:function(a,b){n.content=a,a?n.st.showCloseBtn&&n.st.closeBtnInside&&n.currTemplate[b]===!0?n.content.find(\".mfp-close\").length||n.content.append(z()):n.content=a:n.content=\"\",y(e),n.container.addClass(\"mfp-\"+b+\"-holder\"),n.contentContainer.append(n.content)},parseEl:function(b){var c=n.items[b],d;c.tagName?c={el:a(c)}:(d=c.type,c={data:c,src:c.src});if(c.el){var e=n.types;for(var f=0;f<e.length;f++)if(c.el.hasClass(\"mfp-\"+e[f])){d=e[f];break}c.src=c.el.attr(\"data-mfp-src\"),c.src||(c.src=c.el.attr(\"href\"))}return c.type=d||n.st.type||\"inline\",c.index=b,c.parsed=!0,n.items[b]=c,y(\"ElementParse\",c),n.items[b]},addGroup:function(a,b){var c=function(c){c.mfpEl=this,n._openClick(c,a,b)};b||(b={});var d=\"click.magnificPopup\";b.mainEl=a,b.items?(b.isObj=!0,a.off(d).on(d,c)):(b.isObj=!1,b.delegate?a.off(d).on(d,b.delegate,c):(b.items=a,a.off(d).on(d,c)))},_openClick:function(b,c,d){var e=d.midClick!==undefined?d.midClick:a.magnificPopup.defaults.midClick;if(!e&&(b.which===2||b.ctrlKey||b.metaKey||b.altKey||b.shiftKey))return;var f=d.disableOn!==undefined?d.disableOn:a.magnificPopup.defaults.disableOn;if(f)if(a.isFunction(f)){if(!f.call(n))return!0}else if(r.width()<f)return!0;b.type&&(b.preventDefault(),n.isOpen&&b.stopPropagation()),d.el=a(b.mfpEl),d.delegate&&(d.items=c.find(d.delegate)),n.open(d)},updateStatus:function(a,b){if(n.preloader){q!==a&&n.container.removeClass(\"mfp-s-\"+q),!b&&a===\"loading\"&&(b=n.st.tLoading);var c={status:a,text:b};y(\"UpdateStatus\",c),a=c.status,b=c.text,n.preloader.html(b),n.preloader.find(\"a\").on(\"click\",function(a){a.stopImmediatePropagation()}),n.container.addClass(\"mfp-s-\"+a),q=a}},_checkIfClose:function(b){if(a(b).hasClass(m))return;var c=n.st.closeOnContentClick,d=n.st.closeOnBgClick;if(c&&d)return!0;if(!n.content||a(b).hasClass(\"mfp-close\")||n.preloader&&b===n.preloader[0])return!0;if(b!==n.content[0]&&!a.contains(n.content[0],b)){if(d&&a.contains(document,b))return!0}else if(c)return!0;return!1},_addClassToMFP:function(a){n.bgOverlay.addClass(a),n.wrap.addClass(a)},_removeClassFromMFP:function(a){this.bgOverlay.removeClass(a),n.wrap.removeClass(a)},_hasScrollBar:function(a){return(n.isIE7?s.height():document.body.scrollHeight)>(a||r.height())},_setFocus:function(){(n.st.focus?n.content.find(n.st.focus).eq(0):n.wrap).focus()},_onFocusIn:function(b){if(b.target!==n.wrap[0]&&!a.contains(n.wrap[0],b.target))return n._setFocus(),!1},_parseMarkup:function(b,c,d){var e;d.data&&(c=a.extend(d.data,c)),y(f,[b,c,d]),a.each(c,function(c,d){if(d===undefined||d===!1)return!0;e=c.split(\"_\");if(e.length>1){var f=b.find(j+\"-\"+e[0]);if(f.length>0){var g=e[1];g===\"replaceWith\"?f[0]!==d[0]&&f.replaceWith(d):g===\"img\"?f.is(\"img\")?f.attr(\"src\",d):f.replaceWith(a(\"<img>\").attr(\"src\",d).attr(\"class\",f.attr(\"class\"))):f.attr(e[1],d)}}else b.find(j+\"-\"+c).html(d)})},_getScrollbarSize:function(){if(n.scrollbarSize===undefined){var a=document.createElement(\"div\");a.style.cssText=\"width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;\",document.body.appendChild(a),n.scrollbarSize=a.offsetWidth-a.clientWidth,document.body.removeChild(a)}return n.scrollbarSize}},a.magnificPopup={instance:null,proto:o.prototype,modules:[],open:function(b,c){return A(),b?b=a.extend(!0,{},b):b={},b.isObj=!0,b.index=c||0,this.instance.open(b)},close:function(){return a.magnificPopup.instance&&a.magnificPopup.instance.close()},registerModule:function(b,c){c.options&&(a.magnificPopup.defaults[b]=c.options),a.extend(this.proto,c.proto),this.modules.push(b)},defaults:{disableOn:0,key:null,midClick:!1,mainClass:\"\",preloader:!0,focus:\"\",closeOnContentClick:!1,closeOnBgClick:!0,closeBtnInside:!0,showCloseBtn:!0,enableEscapeKey:!0,modal:!1,alignTop:!1,removalDelay:0,prependTo:null,fixedContentPos:\"auto\",fixedBgPos:\"auto\",overflowY:\"auto\",closeMarkup:'<button title=\"%title%\" type=\"button\" class=\"mfp-close\">&#215;</button>',tClose:\"Close (Esc)\",tLoading:\"Loading...\",autoFocusLast:!0}},a.fn.magnificPopup=function(b){A();var c=a(this);if(typeof b==\"string\")if(b===\"open\"){var d,e=p?c.data(\"magnificPopup\"):c[0].magnificPopup,f=parseInt(arguments[1],10)||0;e.items?d=e.items[f]:(d=c,e.delegate&&(d=d.find(e.delegate)),d=d.eq(f)),n._openClick({mfpEl:d},c,e)}else n.isOpen&&n[b].apply(n,Array.prototype.slice.call(arguments,1));else b=a.extend(!0,{},b),p?c.data(\"magnificPopup\",b):c[0].magnificPopup=b,n.addGroup(c,b);return c};var C=\"inline\",D,E,F,G=function(){F&&(E.after(F.addClass(D)).detach(),F=null)};a.magnificPopup.registerModule(C,{options:{hiddenClass:\"hide\",markup:\"\",tNotFound:\"Content not found\"},proto:{initInline:function(){n.types.push(C),w(b+\".\"+C,function(){G()})},getInline:function(b,c){G();if(b.src){var d=n.st.inline,e=a(b.src);if(e.length){var f=e[0].parentNode;f&&f.tagName&&(E||(D=d.hiddenClass,E=x(D),D=\"mfp-\"+D),F=e.after(E).detach().removeClass(D)),n.updateStatus(\"ready\")}else n.updateStatus(\"error\",d.tNotFound),e=a(\"<div>\");return b.inlineElement=e,e}return n.updateStatus(\"ready\"),n._parseMarkup(c,{},b),c}}});var H=\"ajax\",I,J=function(){I&&a(document.body).removeClass(I)},K=function(){J(),n.req&&n.req.abort()};a.magnificPopup.registerModule(H,{options:{settings:null,cursor:\"mfp-ajax-cur\",tError:'<a href=\"%url%\">The content</a> could not be loaded.'},proto:{initAjax:function(){n.types.push(H),I=n.st.ajax.cursor,w(b+\".\"+H,K),w(\"BeforeChange.\"+H,K)},getAjax:function(b){I&&a(document.body).addClass(I),n.updateStatus(\"loading\");var c=a.extend({url:b.src,success:function(c,d,e){var f={data:c,xhr:e};y(\"ParseAjax\",f),n.appendContent(a(f.data),H),b.finished=!0,J(),n._setFocus(),setTimeout(function(){n.wrap.addClass(k)},16),n.updateStatus(\"ready\"),y(\"AjaxContentAdded\")},error:function(){J(),b.finished=b.loadError=!0,n.updateStatus(\"error\",n.st.ajax.tError.replace(\"%url%\",b.src))}},n.st.ajax.settings);return n.req=a.ajax(c),\"\"}}});var L,M=function(b){if(b.data&&b.data.title!==undefined)return b.data.title;var c=n.st.image.titleSrc;if(c){if(a.isFunction(c))return c.call(n,b);if(b.el)return b.el.attr(c)||\"\"}return\"\"};a.magnificPopup.registerModule(\"image\",{options:{markup:'<div class=\"mfp-figure\"><div class=\"mfp-close\"></div><figure><div class=\"mfp-img\"></div><figcaption><div class=\"mfp-bottom-bar\"><div class=\"mfp-title\"></div><div class=\"mfp-counter\"></div></div></figcaption></figure></div>',cursor:\"mfp-zoom-out-cur\",titleSrc:\"title\",verticalFit:!0,tError:'<a href=\"%url%\">The image</a> could not be loaded.'},proto:{initImage:function(){var c=n.st.image,d=\".image\";n.types.push(\"image\"),w(g+d,function(){n.currItem.type===\"image\"&&c.cursor&&a(document.body).addClass(c.cursor)}),w(b+d,function(){c.cursor&&a(document.body).removeClass(c.cursor),r.off(\"resize\"+j)}),w(\"Resize\"+d,n.resizeImage),n.isLowIE&&w(\"AfterChange\",n.resizeImage)},resizeImage:function(){var a=n.currItem;if(!a||!a.img)return;if(n.st.image.verticalFit){var b=0;n.isLowIE&&(b=parseInt(a.img.css(\"padding-top\"),10)+parseInt(a.img.css(\"padding-bottom\"),10)),a.img.css(\"max-height\",n.wH-b)}},_onImageHasSize:function(a){a.img&&(a.hasSize=!0,L&&clearInterval(L),a.isCheckingImgSize=!1,y(\"ImageHasSize\",a),a.imgHidden&&(n.content&&n.content.removeClass(\"mfp-loading\"),a.imgHidden=!1))},findImageSize:function(a){var b=0,c=a.img[0],d=function(e){L&&clearInterval(L),L=setInterval(function(){if(c.naturalWidth>0){n._onImageHasSize(a);return}b>200&&clearInterval(L),b++,b===3?d(10):b===40?d(50):b===100&&d(500)},e)};d(1)},getImage:function(b,c){var d=0,e=function(){b&&(b.img[0].complete?(b.img.off(\".mfploader\"),b===n.currItem&&(n._onImageHasSize(b),n.updateStatus(\"ready\")),b.hasSize=!0,b.loaded=!0,y(\"ImageLoadComplete\")):(d++,d<200?setTimeout(e,100):f()))},f=function(){b&&(b.img.off(\".mfploader\"),b===n.currItem&&(n._onImageHasSize(b),n.updateStatus(\"error\",g.tError.replace(\"%url%\",b.src))),b.hasSize=!0,b.loaded=!0,b.loadError=!0)},g=n.st.image,h=c.find(\".mfp-img\");if(h.length){var i=document.createElement(\"img\");i.className=\"mfp-img\",b.el&&b.el.find(\"img\").length&&(i.alt=b.el.find(\"img\").attr(\"alt\")),b.img=a(i).on(\"load.mfploader\",e).on(\"error.mfploader\",f),i.src=b.src,h.is(\"img\")&&(b.img=b.img.clone()),i=b.img[0],i.naturalWidth>0?b.hasSize=!0:i.width||(b.hasSize=!1)}return n._parseMarkup(c,{title:M(b),img_replaceWith:b.img},b),n.resizeImage(),b.hasSize?(L&&clearInterval(L),b.loadError?(c.addClass(\"mfp-loading\"),n.updateStatus(\"error\",g.tError.replace(\"%url%\",b.src))):(c.removeClass(\"mfp-loading\"),n.updateStatus(\"ready\")),c):(n.updateStatus(\"loading\"),b.loading=!0,b.hasSize||(b.imgHidden=!0,c.addClass(\"mfp-loading\"),n.findImageSize(b)),c)}}});var N,O=function(){return N===undefined&&(N=document.createElement(\"p\").style.MozTransform!==undefined),N};a.magnificPopup.registerModule(\"zoom\",{options:{enabled:!1,easing:\"ease-in-out\",duration:300,opener:function(a){return a.is(\"img\")?a:a.find(\"img\")}},proto:{initZoom:function(){var a=n.st.zoom,d=\".zoom\",e;if(!a.enabled||!n.supportsTransition)return;var f=a.duration,g=function(b){var c=b.clone().removeAttr(\"style\").removeAttr(\"class\").addClass(\"mfp-animated-image\"),d=\"all \"+a.duration/1e3+\"s \"+a.easing,e={position:\"fixed\",zIndex:9999,left:0,top:0,\"-webkit-backface-visibility\":\"hidden\"},f=\"transition\";return e[\"-webkit-\"+f]=e[\"-moz-\"+f]=e[\"-o-\"+f]=e[f]=d,c.css(e),c},h=function(){n.content.css(\"visibility\",\"visible\")},i,j;w(\"BuildControls\"+d,function(){if(n._allowZoom()){clearTimeout(i),n.content.css(\"visibility\",\"hidden\"),e=n._getItemToZoom();if(!e){h();return}j=g(e),j.css(n._getOffset()),n.wrap.append(j),i=setTimeout(function(){j.css(n._getOffset(!0)),i=setTimeout(function(){h(),setTimeout(function(){j.remove(),e=j=null,y(\"ZoomAnimationEnded\")},16)},f)},16)}}),w(c+d,function(){if(n._allowZoom()){clearTimeout(i),n.st.removalDelay=f;if(!e){e=n._getItemToZoom();if(!e)return;j=g(e)}j.css(n._getOffset(!0)),n.wrap.append(j),n.content.css(\"visibility\",\"hidden\"),setTimeout(function(){j.css(n._getOffset())},16)}}),w(b+d,function(){n._allowZoom()&&(h(),j&&j.remove(),e=null)})},_allowZoom:function(){return n.currItem.type===\"image\"},_getItemToZoom:function(){return n.currItem.hasSize?n.currItem.img:!1},_getOffset:function(b){var c;b?c=n.currItem.img:c=n.st.zoom.opener(n.currItem.el||n.currItem);var d=c.offset(),e=parseInt(c.css(\"padding-top\"),10),f=parseInt(c.css(\"padding-bottom\"),10);d.top-=a(window).scrollTop()-e;var g={width:c.width(),height:(p?c.innerHeight():c[0].offsetHeight)-f-e};return O()?g[\"-moz-transform\"]=g.transform=\"translate(\"+d.left+\"px,\"+d.top+\"px)\":(g.left=d.left,g.top=d.top),g}}});var P=\"iframe\",Q=\"//about:blank\",R=function(a){if(n.currTemplate[P]){var b=n.currTemplate[P].find(\"iframe\");b.length&&(a||(b[0].src=Q),n.isIE8&&b.css(\"display\",a?\"block\":\"none\"))}};a.magnificPopup.registerModule(P,{options:{markup:'<div class=\"mfp-iframe-scaler\"><div class=\"mfp-close\"></div><iframe class=\"mfp-iframe\" src=\"//about:blank\" frameborder=\"0\" allowfullscreen></iframe></div>',srcAction:\"iframe_src\",patterns:{youtube:{index:\"youtube.com\",id:\"v=\",src:\"//www.youtube.com/embed/%id%?autoplay=1\"},vimeo:{index:\"vimeo.com/\",id:\"/\",src:\"//player.vimeo.com/video/%id%?autoplay=1\"},gmaps:{index:\"//maps.google.\",src:\"%id%&output=embed\"}}},proto:{initIframe:function(){n.types.push(P),w(\"BeforeChange\",function(a,b,c){b!==c&&(b===P?R():c===P&&R(!0))}),w(b+\".\"+P,function(){R()})},getIframe:function(b,c){var d=b.src,e=n.st.iframe;a.each(e.patterns,function(){if(d.indexOf(this.index)>-1)return this.id&&(typeof this.id==\"string\"?d=d.substr(d.lastIndexOf(this.id)+this.id.length,d.length):d=this.id.call(this,d)),d=this.src.replace(\"%id%\",d),!1});var f={};return e.srcAction&&(f[e.srcAction]=d),n._parseMarkup(c,f,b),n.updateStatus(\"ready\"),c}}});var S=function(a){var b=n.items.length;return a>b-1?a-b:a<0?b+a:a},T=function(a,b,c){return a.replace(/%curr%/gi,b+1).replace(/%total%/gi,c)};a.magnificPopup.registerModule(\"gallery\",{options:{enabled:!1,arrowMarkup:'<button title=\"%title%\" type=\"button\" class=\"mfp-arrow mfp-arrow-%dir%\"></button>',preload:[0,2],navigateByImgClick:!0,arrows:!0,tPrev:\"Previous (Left arrow key)\",tNext:\"Next (Right arrow key)\",tCounter:\"%curr% of %total%\"},proto:{initGallery:function(){var c=n.st.gallery,d=\".mfp-gallery\";n.direction=!0;if(!c||!c.enabled)return!1;u+=\" mfp-gallery\",w(g+d,function(){c.navigateByImgClick&&n.wrap.on(\"click\"+d,\".mfp-img\",function(){if(n.items.length>1)return n.next(),!1}),s.on(\"keydown\"+d,function(a){a.keyCode===37?n.prev():a.keyCode===39&&n.next()})}),w(\"UpdateStatus\"+d,function(a,b){b.text&&(b.text=T(b.text,n.currItem.index,n.items.length))}),w(f+d,function(a,b,d,e){var f=n.items.length;d.counter=f>1?T(c.tCounter,e.index,f):\"\"}),w(\"BuildControls\"+d,function(){if(n.items.length>1&&c.arrows&&!n.arrowLeft){var b=c.arrowMarkup,d=n.arrowLeft=a(b.replace(/%title%/gi,c.tPrev).replace(/%dir%/gi,\"left\")).addClass(m),e=n.arrowRight=a(b.replace(/%title%/gi,c.tNext).replace(/%dir%/gi,\"right\")).addClass(m);d.click(function(){n.prev()}),e.click(function(){n.next()}),n.container.append(d.add(e))}}),w(h+d,function(){n._preloadTimeout&&clearTimeout(n._preloadTimeout),n._preloadTimeout=setTimeout(function(){n.preloadNearbyImages(),n._preloadTimeout=null},16)}),w(b+d,function(){s.off(d),n.wrap.off(\"click\"+d),n.arrowRight=n.arrowLeft=null})},next:function(){n.direction=!0,n.index=S(n.index+1),n.updateItemHTML()},prev:function(){n.direction=!1,n.index=S(n.index-1),n.updateItemHTML()},goTo:function(a){n.direction=a>=n.index,n.index=a,n.updateItemHTML()},preloadNearbyImages:function(){var a=n.st.gallery.preload,b=Math.min(a[0],n.items.length),c=Math.min(a[1],n.items.length),d;for(d=1;d<=(n.direction?c:b);d++)n._preloadItem(n.index+d);for(d=1;d<=(n.direction?b:c);d++)n._preloadItem(n.index-d)},_preloadItem:function(b){b=S(b);if(n.items[b].preloaded)return;var c=n.items[b];c.parsed||(c=n.parseEl(b)),y(\"LazyLoad\",c),c.type===\"image\"&&(c.img=a('<img class=\"mfp-img\" />').on(\"load.mfploader\",function(){c.hasSize=!0}).on(\"error.mfploader\",function(){c.hasSize=!0,c.loadError=!0,y(\"LazyLoadError\",c)}).attr(\"src\",c.src)),c.preloaded=!0}}});var U=\"retina\";a.magnificPopup.registerModule(U,{options:{replaceSrc:function(a){return a.src.replace(/\\.\\w+$/,function(a){return\"@2x\"+a})},ratio:1},proto:{initRetina:function(){if(window.devicePixelRatio>1){var a=n.st.retina,b=a.ratio;b=isNaN(b)?b():b,b>1&&(w(\"ImageHasSize.\"+U,function(a,c){c.img.css({\"max-width\":c.img[0].naturalWidth/b,width:\"100%\"})}),w(\"ElementParse.\"+U,function(c,d){d.src=a.replaceSrc(d,b)}))}}}}),A()})","Mageplaza_Core/js/jquery.autocomplete.min.js":"/**\r\n *  Ajax Autocomplete for jQuery, version 1.3.0\r\n *  (c) 2017 Tomas Kirda\r\n *\r\n *  Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.\r\n *  For details, see the web site: https://github.com/devbridge/jQuery-Autocomplete\r\n */\r\n!function(a){\"use strict\";\"function\"==typeof define&&define.amd?define([\"jquery\"],a):a(\"object\"==typeof exports&&\"function\"==typeof require?require(\"jquery\"):jQuery)}(function(a){\"use strict\";function b(c,d){var e=a.noop,f=this,g={ajaxSettings:{},autoSelectFirst:!1,appendTo:document.body,serviceUrl:null,lookup:null,onSelect:null,width:\"auto\",minChars:1,maxHeight:300,deferRequestBy:0,params:{},formatResult:b.formatResult,formatGroup:b.formatGroup,delimiter:null,zIndex:9999,type:\"GET\",noCache:!1,onSearchStart:e,onSearchComplete:e,onSearchError:e,preserveInput:!1,containerClass:\"autocomplete-suggestions\",tabDisabled:!1,dataType:\"text\",currentRequest:null,triggerSelectOnValidInput:!0,preventBadQueries:!0,lookupFilter:function(a,b,c){return-1!==a.value.toLowerCase().indexOf(c)},paramName:\"query\",transformResult:function(b){return\"string\"==typeof b?a.parseJSON(b):b},showNoSuggestionNotice:!1,noSuggestionNotice:\"No results\",orientation:\"bottom\",forceFixPosition:!1};f.element=c,f.el=a(c),f.suggestions=[],f.badQueries=[],f.selectedIndex=-1,f.currentValue=f.element.value,f.intervalId=0,f.cachedResponse={},f.onChangeInterval=null,f.onChange=null,f.isLocal=!1,f.suggestionsContainer=null,f.noSuggestionsContainer=null,f.options=a.extend({},g,d),f.classes={selected:\"autocomplete-selected\",suggestion:\"autocomplete-suggestion\"},f.hint=null,f.hintValue=\"\",f.selection=null,f.initialize(),f.setOptions(d)}var c=function(){return{escapeRegExChars:function(a){return a.replace(/[|\\\\{}()[\\]^$+*?.]/g,\"\\\\$&\")},createNode:function(a){var b=document.createElement(\"div\");return b.className=a,b.style.position=\"absolute\",b.style.display=\"none\",b}}}(),d={ESC:27,TAB:9,RETURN:13,LEFT:37,UP:38,RIGHT:39,DOWN:40};b.utils=c,a.Autocomplete=b,b.formatResult=function(a,b){if(!b)return a.value;var d=\"(\"+c.escapeRegExChars(b)+\")\";return a.value.replace(new RegExp(d,\"gi\"),\"<strong>$1</strong>\").replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/\"/g,\"&quot;\").replace(/&lt;(\\/?strong)&gt;/g,\"<$1>\")},b.formatGroup=function(a,b){return'<div class=\"autocomplete-group\"><strong>'+b+\"</strong></div>\"},b.prototype={killerFn:null,initialize:function(){var c,d=this,e=\".\"+d.classes.suggestion,f=d.classes.selected,g=d.options;d.element.setAttribute(\"autocomplete\",\"off\"),d.killerFn=function(b){a(b.target).closest(\".\"+d.options.containerClass).length||(d.killSuggestions(),d.disableKillerFn())},d.noSuggestionsContainer=a('<div class=\"autocomplete-no-suggestion\"></div>').html(this.options.noSuggestionNotice).get(0),d.suggestionsContainer=b.utils.createNode(g.containerClass),c=a(d.suggestionsContainer),c.appendTo(g.appendTo),\"auto\"!==g.width&&c.css(\"width\",g.width),c.on(\"mouseover.autocomplete\",e,function(){d.activate(a(this).data(\"index\"))}),c.on(\"mouseout.autocomplete\",function(){d.selectedIndex=-1,c.children(\".\"+f).removeClass(f)}),c.on(\"click.autocomplete\",e,function(){return d.select(a(this).data(\"index\")),!1}),d.fixPositionCapture=function(){d.visible&&d.fixPosition()},a(window).on(\"resize.autocomplete\",d.fixPositionCapture),d.el.on(\"keydown.autocomplete\",function(a){d.onKeyPress(a)}),d.el.on(\"keyup.autocomplete\",function(a){d.onKeyUp(a)}),d.el.on(\"blur.autocomplete\",function(){d.onBlur()}),d.el.on(\"focus.autocomplete\",function(){d.onFocus()}),d.el.on(\"change.autocomplete\",function(a){d.onKeyUp(a)}),d.el.on(\"input.autocomplete\",function(a){d.onKeyUp(a)})},onFocus:function(){var a=this;a.fixPosition(),a.el.val().length>=a.options.minChars&&a.onValueChange()},onBlur:function(){this.enableKillerFn()},abortAjax:function(){var a=this;a.currentRequest&&(a.currentRequest.abort(),a.currentRequest=null)},setOptions:function(b){var c=this,d=c.options;a.extend(d,b),c.isLocal=a.isArray(d.lookup),c.isLocal&&(d.lookup=c.verifySuggestionsFormat(d.lookup)),d.orientation=c.validateOrientation(d.orientation,\"bottom\"),a(c.suggestionsContainer).css({\"max-height\":d.maxHeight+\"px\",width:d.width+\"px\",\"z-index\":d.zIndex})},clearCache:function(){this.cachedResponse={},this.badQueries=[]},clear:function(){this.clearCache(),this.currentValue=\"\",this.suggestions=[]},disable:function(){var a=this;a.disabled=!0,clearInterval(a.onChangeInterval),a.abortAjax()},enable:function(){this.disabled=!1},fixPosition:function(){var b=this,c=a(b.suggestionsContainer),d=c.parent().get(0);if(d===document.body||b.options.forceFixPosition){var e=b.options.orientation,f=c.outerHeight(),g=b.el.outerHeight(),h=b.el.offset(),i={top:h.top,left:h.left};if(\"auto\"===e){var j=a(window).height(),k=a(window).scrollTop(),l=-k+h.top-f,m=k+j-(h.top+g+f);e=Math.max(l,m)===l?\"top\":\"bottom\"}if(\"top\"===e?i.top+=-f:i.top+=g,d!==document.body){var n,o=c.css(\"opacity\");b.visible||c.css(\"opacity\",0).show(),n=c.offsetParent().offset(),i.top-=n.top,i.left-=n.left,b.visible||c.css(\"opacity\",o).hide()}\"auto\"===b.options.width&&(i.width=b.el.outerWidth()+\"px\"),c.css(i)}},enableKillerFn:function(){var b=this;a(document).on(\"click.autocomplete\",b.killerFn)},disableKillerFn:function(){var b=this;a(document).off(\"click.autocomplete\",b.killerFn)},killSuggestions:function(){var a=this;a.stopKillSuggestions(),a.intervalId=window.setInterval(function(){a.visible&&(a.options.preserveInput||a.el.val(a.currentValue),a.hide()),a.stopKillSuggestions()},50)},stopKillSuggestions:function(){window.clearInterval(this.intervalId)},isCursorAtEnd:function(){var a,b=this,c=b.el.val().length,d=b.element.selectionStart;return\"number\"==typeof d?d===c:document.selection?(a=document.selection.createRange(),a.moveStart(\"character\",-c),c===a.text.length):!0},onKeyPress:function(a){var b=this;if(!b.disabled&&!b.visible&&a.which===d.DOWN&&b.currentValue)return void b.suggest();if(!b.disabled&&b.visible){switch(a.which){case d.ESC:b.el.val(b.currentValue),b.hide();break;case d.RIGHT:if(b.hint&&b.options.onHint&&b.isCursorAtEnd()){b.selectHint();break}return;case d.TAB:if(b.hint&&b.options.onHint)return void b.selectHint();if(-1===b.selectedIndex)return void b.hide();if(b.select(b.selectedIndex),b.options.tabDisabled===!1)return;break;case d.RETURN:if(-1===b.selectedIndex)return void b.hide();b.select(b.selectedIndex);break;case d.UP:b.moveUp();break;case d.DOWN:b.moveDown();break;default:return}a.stopImmediatePropagation(),a.preventDefault()}},onKeyUp:function(a){var b=this;if(!b.disabled){switch(a.which){case d.UP:case d.DOWN:return}clearInterval(b.onChangeInterval),b.currentValue!==b.el.val()&&(b.findBestHint(),b.options.deferRequestBy>0?b.onChangeInterval=setInterval(function(){b.onValueChange()},b.options.deferRequestBy):b.onValueChange())}},onValueChange:function(){var b=this,c=b.options,d=b.el.val(),e=b.getQuery(d);return b.selection&&b.currentValue!==e&&(b.selection=null,(c.onInvalidateSelection||a.noop).call(b.element)),clearInterval(b.onChangeInterval),b.currentValue=d,b.selectedIndex=-1,c.triggerSelectOnValidInput&&b.isExactMatch(e)?void b.select(0):void(e.length<c.minChars?b.hide():b.getSuggestions(e))},isExactMatch:function(a){var b=this.suggestions;return 1===b.length&&b[0].value.toLowerCase()===a.toLowerCase()},getQuery:function(b){var c,d=this.options.delimiter;return d?(c=b.split(d),a.trim(c[c.length-1])):b},getSuggestionsLocal:function(b){var c,d=this,e=d.options,f=b.toLowerCase(),g=e.lookupFilter,h=parseInt(e.lookupLimit,10);return c={suggestions:a.grep(e.lookup,function(a){return g(a,b,f)})},h&&c.suggestions.length>h&&(c.suggestions=c.suggestions.slice(0,h)),c},getSuggestions:function(b){var c,d,e,f,g=this,h=g.options,i=h.serviceUrl;if(h.params[h.paramName]=b,d=h.ignoreParams?null:h.params,h.onSearchStart.call(g.element,h.params)!==!1){if(a.isFunction(h.lookup))return void h.lookup(b,function(a){g.suggestions=a.suggestions,g.suggest(),h.onSearchComplete.call(g.element,b,a.suggestions)});g.isLocal?c=g.getSuggestionsLocal(b):(a.isFunction(i)&&(i=i.call(g.element,b)),e=i+\"?\"+a.param(d||{}),c=g.cachedResponse[e]),c&&a.isArray(c.suggestions)?(g.suggestions=c.suggestions,g.suggest(),h.onSearchComplete.call(g.element,b,c.suggestions)):g.isBadQuery(b)?h.onSearchComplete.call(g.element,b,[]):(g.abortAjax(),f={url:i,data:d,type:h.type,dataType:h.dataType},a.extend(f,h.ajaxSettings),g.currentRequest=a.ajax(f).done(function(a){var c;g.currentRequest=null,c=h.transformResult(a,b),g.processResponse(c,b,e),h.onSearchComplete.call(g.element,b,c.suggestions)}).fail(function(a,c,d){h.onSearchError.call(g.element,b,a,c,d)}))}},isBadQuery:function(a){if(!this.options.preventBadQueries)return!1;for(var b=this.badQueries,c=b.length;c--;)if(0===a.indexOf(b[c]))return!0;return!1},hide:function(){var b=this,c=a(b.suggestionsContainer);a.isFunction(b.options.onHide)&&b.visible&&b.options.onHide.call(b.element,c),b.visible=!1,b.selectedIndex=-1,clearInterval(b.onChangeInterval),a(b.suggestionsContainer).hide(),b.signalHint(null)},suggest:function(){if(!this.suggestions.length)return void(this.options.showNoSuggestionNotice?this.noSuggestions():this.hide());var b,c=this,d=c.options,e=d.groupBy,f=d.formatResult,g=c.getQuery(c.currentValue),h=c.classes.suggestion,i=c.classes.selected,j=a(c.suggestionsContainer),k=a(c.noSuggestionsContainer),l=d.beforeRender,m=\"\",n=function(a,c){var f=a.data[e];return b===f?\"\":(b=f,d.formatGroup(a,b))};return d.triggerSelectOnValidInput&&c.isExactMatch(g)?void c.select(0):(a.each(c.suggestions,function(a,b){e&&(m+=n(b,g,a)),m+='<div class=\"'+h+'\" data-index=\"'+a+'\">'+f(b,g,a)+\"</div>\"}),this.adjustContainerWidth(),k.detach(),j.html(m),a.isFunction(l)&&l.call(c.element,j,c.suggestions),c.fixPosition(),j.show(),d.autoSelectFirst&&(c.selectedIndex=0,j.scrollTop(0),j.children(\".\"+h).first().addClass(i)),c.visible=!0,void c.findBestHint())},noSuggestions:function(){var b=this,c=a(b.suggestionsContainer),d=a(b.noSuggestionsContainer);this.adjustContainerWidth(),d.detach(),c.empty(),c.append(d),b.fixPosition(),c.show(),b.visible=!0},adjustContainerWidth:function(){var b,c=this,d=c.options,e=a(c.suggestionsContainer);\"auto\"===d.width?(b=c.el.outerWidth(),e.css(\"width\",b>0?b:300)):\"flex\"===d.width&&e.css(\"width\",\"\")},findBestHint:function(){var b=this,c=b.el.val().toLowerCase(),d=null;c&&(a.each(b.suggestions,function(a,b){var e=0===b.value.toLowerCase().indexOf(c);return e&&(d=b),!e}),b.signalHint(d))},signalHint:function(b){var c=\"\",d=this;b&&(c=d.currentValue+b.value.substr(d.currentValue.length)),d.hintValue!==c&&(d.hintValue=c,d.hint=b,(this.options.onHint||a.noop)(c))},verifySuggestionsFormat:function(b){return b.length&&\"string\"==typeof b[0]?a.map(b,function(a){return{value:a,data:null}}):b},validateOrientation:function(b,c){return b=a.trim(b||\"\").toLowerCase(),-1===a.inArray(b,[\"auto\",\"bottom\",\"top\"])&&(b=c),b},processResponse:function(a,b,c){var d=this,e=d.options;a.suggestions=d.verifySuggestionsFormat(a.suggestions),e.noCache||(d.cachedResponse[c]=a,e.preventBadQueries&&!a.suggestions.length&&d.badQueries.push(b)),b===d.getQuery(d.currentValue)&&(d.suggestions=a.suggestions,d.suggest())},activate:function(b){var c,d=this,e=d.classes.selected,f=a(d.suggestionsContainer),g=f.find(\".\"+d.classes.suggestion);return f.find(\".\"+e).removeClass(e),d.selectedIndex=b,-1!==d.selectedIndex&&g.length>d.selectedIndex?(c=g.get(d.selectedIndex),a(c).addClass(e),c):null},selectHint:function(){var b=this,c=a.inArray(b.hint,b.suggestions);b.select(c)},select:function(a){var b=this;b.hide(),b.onSelect(a),b.disableKillerFn()},moveUp:function(){var b=this;if(-1!==b.selectedIndex)return 0===b.selectedIndex?(a(b.suggestionsContainer).children().first().removeClass(b.classes.selected),b.selectedIndex=-1,b.el.val(b.currentValue),void b.findBestHint()):void b.adjustScroll(b.selectedIndex-1)},moveDown:function(){var a=this;a.selectedIndex!==a.suggestions.length-1&&a.adjustScroll(a.selectedIndex+1)},adjustScroll:function(b){var c=this,d=c.activate(b);if(d){var e,f,g,h=a(d).outerHeight();e=d.offsetTop,f=a(c.suggestionsContainer).scrollTop(),g=f+c.options.maxHeight-h,f>e?a(c.suggestionsContainer).scrollTop(e):e>g&&a(c.suggestionsContainer).scrollTop(e-c.options.maxHeight+h),c.options.preserveInput||c.el.val(c.getValue(c.suggestions[b].value)),c.signalHint(null)}},onSelect:function(b){var c=this,d=c.options.onSelect,e=c.suggestions[b];c.currentValue=c.getValue(e.value),c.currentValue===c.el.val()||c.options.preserveInput||c.el.val(c.currentValue),c.signalHint(null),c.suggestions=[],c.selection=e,a.isFunction(d)&&d.call(c.element,e)},getValue:function(a){var b,c,d=this,e=d.options.delimiter;return e?(b=d.currentValue,c=b.split(e),1===c.length?a:b.substr(0,b.length-c[c.length-1].length)+a):a},dispose:function(){var b=this;b.el.off(\".autocomplete\").removeData(\"autocomplete\"),b.disableKillerFn(),a(window).off(\"resize.autocomplete\",b.fixPositionCapture),a(b.suggestionsContainer).remove()}},a.fn.autocomplete=a.fn.devbridgeAutocomplete=function(c,d){var e=\"autocomplete\";return arguments.length?this.each(function(){var f=a(this),g=f.data(e);\"string\"==typeof c?g&&\"function\"==typeof g[c]&&g[c](d):(g&&g.dispose&&g.dispose(),g=new b(this,c),f.data(e,g))}):this.first().data(e)}});","Mageplaza_Core/js/owl.carousel.min.js":"/**\r\n * Owl Carousel v2.3.4\r\n * Copyright 2013-2018 David Deutsch\r\n * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE\r\n */\r\n!function(a,b,c,d){function e(b,c){this.settings=null,this.options=a.extend({},e.Defaults,c),this.$element=a(b),this._handlers={},this._plugins={},this._supress={},this._current=null,this._speed=null,this._coordinates=[],this._breakpoint=null,this._width=null,this._items=[],this._clones=[],this._mergers=[],this._widths=[],this._invalidated={},this._pipe=[],this._drag={time:null,target:null,pointer:null,stage:{start:null,current:null},direction:null},this._states={current:{},tags:{initializing:[\"busy\"],animating:[\"busy\"],dragging:[\"interacting\"]}},a.each([\"onResize\",\"onThrottledResize\"],a.proxy(function(b,c){this._handlers[c]=a.proxy(this[c],this)},this)),a.each(e.Plugins,a.proxy(function(a,b){this._plugins[a.charAt(0).toLowerCase()+a.slice(1)]=new b(this)},this)),a.each(e.Workers,a.proxy(function(b,c){this._pipe.push({filter:c.filter,run:a.proxy(c.run,this)})},this)),this.setup(),this.initialize()}e.Defaults={items:3,loop:!1,center:!1,rewind:!1,checkVisibility:!0,mouseDrag:!0,touchDrag:!0,pullDrag:!0,freeDrag:!1,margin:0,stagePadding:0,merge:!1,mergeFit:!0,autoWidth:!1,startPosition:0,rtl:!1,smartSpeed:250,fluidSpeed:!1,dragEndSpeed:!1,responsive:{},responsiveRefreshRate:200,responsiveBaseElement:b,fallbackEasing:\"swing\",slideTransition:\"\",info:!1,nestedItemSelector:!1,itemElement:\"div\",stageElement:\"div\",refreshClass:\"owl-refresh\",loadedClass:\"owl-loaded\",loadingClass:\"owl-loading\",rtlClass:\"owl-rtl\",responsiveClass:\"owl-responsive\",dragClass:\"owl-drag\",itemClass:\"owl-item\",stageClass:\"owl-stage\",stageOuterClass:\"owl-stage-outer\",grabClass:\"owl-grab\"},e.Width={Default:\"default\",Inner:\"inner\",Outer:\"outer\"},e.Type={Event:\"event\",State:\"state\"},e.Plugins={},e.Workers=[{filter:[\"width\",\"settings\"],run:function(){this._width=this.$element.width()}},{filter:[\"width\",\"items\",\"settings\"],run:function(a){a.current=this._items&&this._items[this.relative(this._current)]}},{filter:[\"items\",\"settings\"],run:function(){this.$stage.children(\".cloned\").remove()}},{filter:[\"width\",\"items\",\"settings\"],run:function(a){var b=this.settings.margin||\"\",c=!this.settings.autoWidth,d=this.settings.rtl,e={width:\"auto\",\"margin-left\":d?b:\"\",\"margin-right\":d?\"\":b};!c&&this.$stage.children().css(e),a.css=e}},{filter:[\"width\",\"items\",\"settings\"],run:function(a){var b=(this.width()/this.settings.items).toFixed(3)-this.settings.margin,c=null,d=this._items.length,e=!this.settings.autoWidth,f=[];for(a.items={merge:!1,width:b};d--;)c=this._mergers[d],c=this.settings.mergeFit&&Math.min(c,this.settings.items)||c,a.items.merge=c>1||a.items.merge,f[d]=e?b*c:this._items[d].width();this._widths=f}},{filter:[\"items\",\"settings\"],run:function(){var b=[],c=this._items,d=this.settings,e=Math.max(2*d.items,4),f=2*Math.ceil(c.length/2),g=d.loop&&c.length?d.rewind?e:Math.max(e,f):0,h=\"\",i=\"\";for(g/=2;g>0;)b.push(this.normalize(b.length/2,!0)),h+=c[b[b.length-1]][0].outerHTML,b.push(this.normalize(c.length-1-(b.length-1)/2,!0)),i=c[b[b.length-1]][0].outerHTML+i,g-=1;this._clones=b,a(h).addClass(\"cloned\").appendTo(this.$stage),a(i).addClass(\"cloned\").prependTo(this.$stage)}},{filter:[\"width\",\"items\",\"settings\"],run:function(){for(var a=this.settings.rtl?1:-1,b=this._clones.length+this._items.length,c=-1,d=0,e=0,f=[];++c<b;)d=f[c-1]||0,e=this._widths[this.relative(c)]+this.settings.margin,f.push(d+e*a);this._coordinates=f}},{filter:[\"width\",\"items\",\"settings\"],run:function(){var a=this.settings.stagePadding,b=this._coordinates,c={width:Math.ceil(Math.abs(b[b.length-1]))+2*a,\"padding-left\":a||\"\",\"padding-right\":a||\"\"};this.$stage.css(c)}},{filter:[\"width\",\"items\",\"settings\"],run:function(a){var b=this._coordinates.length,c=!this.settings.autoWidth,d=this.$stage.children();if(c&&a.items.merge)for(;b--;)a.css.width=this._widths[this.relative(b)],d.eq(b).css(a.css);else c&&(a.css.width=a.items.width,d.css(a.css))}},{filter:[\"items\"],run:function(){this._coordinates.length<1&&this.$stage.removeAttr(\"style\")}},{filter:[\"width\",\"items\",\"settings\"],run:function(a){a.current=a.current?this.$stage.children().index(a.current):0,a.current=Math.max(this.minimum(),Math.min(this.maximum(),a.current)),this.reset(a.current)}},{filter:[\"position\"],run:function(){this.animate(this.coordinates(this._current))}},{filter:[\"width\",\"position\",\"items\",\"settings\"],run:function(){var a,b,c,d,e=this.settings.rtl?1:-1,f=2*this.settings.stagePadding,g=this.coordinates(this.current())+f,h=g+this.width()*e,i=[];for(c=0,d=this._coordinates.length;c<d;c++)a=this._coordinates[c-1]||0,b=Math.abs(this._coordinates[c])+f*e,(this.op(a,\"<=\",g)&&this.op(a,\">\",h)||this.op(b,\"<\",g)&&this.op(b,\">\",h))&&i.push(c);this.$stage.children(\".active\").removeClass(\"active\"),this.$stage.children(\":eq(\"+i.join(\"), :eq(\")+\")\").addClass(\"active\"),this.$stage.children(\".center\").removeClass(\"center\"),this.settings.center&&this.$stage.children().eq(this.current()).addClass(\"center\")}}],e.prototype.initializeStage=function(){this.$stage=this.$element.find(\".\"+this.settings.stageClass),this.$stage.length||(this.$element.addClass(this.options.loadingClass),this.$stage=a(\"<\"+this.settings.stageElement+\">\",{class:this.settings.stageClass}).wrap(a(\"<div/>\",{class:this.settings.stageOuterClass})),this.$element.append(this.$stage.parent()))},e.prototype.initializeItems=function(){var b=this.$element.find(\".owl-item\");if(b.length)return this._items=b.get().map(function(b){return a(b)}),this._mergers=this._items.map(function(){return 1}),void this.refresh();this.replace(this.$element.children().not(this.$stage.parent())),this.isVisible()?this.refresh():this.invalidate(\"width\"),this.$element.removeClass(this.options.loadingClass).addClass(this.options.loadedClass)},e.prototype.initialize=function(){if(this.enter(\"initializing\"),this.trigger(\"initialize\"),this.$element.toggleClass(this.settings.rtlClass,this.settings.rtl),this.settings.autoWidth&&!this.is(\"pre-loading\")){var a,b,c;a=this.$element.find(\"img\"),b=this.settings.nestedItemSelector?\".\"+this.settings.nestedItemSelector:d,c=this.$element.children(b).width(),a.length&&c<=0&&this.preloadAutoWidthImages(a)}this.initializeStage(),this.initializeItems(),this.registerEventHandlers(),this.leave(\"initializing\"),this.trigger(\"initialized\")},e.prototype.isVisible=function(){return!this.settings.checkVisibility||this.$element.is(\":visible\")},e.prototype.setup=function(){var b=this.viewport(),c=this.options.responsive,d=-1,e=null;c?(a.each(c,function(a){a<=b&&a>d&&(d=Number(a))}),e=a.extend({},this.options,c[d]),\"function\"==typeof e.stagePadding&&(e.stagePadding=e.stagePadding()),delete e.responsive,e.responsiveClass&&this.$element.attr(\"class\",this.$element.attr(\"class\").replace(new RegExp(\"(\"+this.options.responsiveClass+\"-)\\\\S+\\\\s\",\"g\"),\"$1\"+d))):e=a.extend({},this.options),this.trigger(\"change\",{property:{name:\"settings\",value:e}}),this._breakpoint=d,this.settings=e,this.invalidate(\"settings\"),this.trigger(\"changed\",{property:{name:\"settings\",value:this.settings}})},e.prototype.optionsLogic=function(){this.settings.autoWidth&&(this.settings.stagePadding=!1,this.settings.merge=!1)},e.prototype.prepare=function(b){var c=this.trigger(\"prepare\",{content:b});return c.data||(c.data=a(\"<\"+this.settings.itemElement+\"/>\").addClass(this.options.itemClass).append(b)),this.trigger(\"prepared\",{content:c.data}),c.data},e.prototype.update=function(){for(var b=0,c=this._pipe.length,d=a.proxy(function(a){return this[a]},this._invalidated),e={};b<c;)(this._invalidated.all||a.grep(this._pipe[b].filter,d).length>0)&&this._pipe[b].run(e),b++;this._invalidated={},!this.is(\"valid\")&&this.enter(\"valid\")},e.prototype.width=function(a){switch(a=a||e.Width.Default){case e.Width.Inner:case e.Width.Outer:return this._width;default:return this._width-2*this.settings.stagePadding+this.settings.margin}},e.prototype.refresh=function(){this.enter(\"refreshing\"),this.trigger(\"refresh\"),this.setup(),this.optionsLogic(),this.$element.addClass(this.options.refreshClass),this.update(),this.$element.removeClass(this.options.refreshClass),this.leave(\"refreshing\"),this.trigger(\"refreshed\")},e.prototype.onThrottledResize=function(){b.clearTimeout(this.resizeTimer),this.resizeTimer=b.setTimeout(this._handlers.onResize,this.settings.responsiveRefreshRate)},e.prototype.onResize=function(){return!!this._items.length&&(this._width!==this.$element.width()&&(!!this.isVisible()&&(this.enter(\"resizing\"),this.trigger(\"resize\").isDefaultPrevented()?(this.leave(\"resizing\"),!1):(this.invalidate(\"width\"),this.refresh(),this.leave(\"resizing\"),void this.trigger(\"resized\")))))},e.prototype.registerEventHandlers=function(){a.support.transition&&this.$stage.on(a.support.transition.end+\".owl.core\",a.proxy(this.onTransitionEnd,this)),!1!==this.settings.responsive&&this.on(b,\"resize\",this._handlers.onThrottledResize),this.settings.mouseDrag&&(this.$element.addClass(this.options.dragClass),this.$stage.on(\"mousedown.owl.core\",a.proxy(this.onDragStart,this)),this.$stage.on(\"dragstart.owl.core selectstart.owl.core\",function(){return!1})),this.settings.touchDrag&&(this.$stage.on(\"touchstart.owl.core\",a.proxy(this.onDragStart,this)),this.$stage.on(\"touchcancel.owl.core\",a.proxy(this.onDragEnd,this)))},e.prototype.onDragStart=function(b){var d=null;3!==b.which&&(a.support.transform?(d=this.$stage.css(\"transform\").replace(/.*\\(|\\)| /g,\"\").split(\",\"),d={x:d[16===d.length?12:4],y:d[16===d.length?13:5]}):(d=this.$stage.position(),d={x:this.settings.rtl?d.left+this.$stage.width()-this.width()+this.settings.margin:d.left,y:d.top}),this.is(\"animating\")&&(a.support.transform?this.animate(d.x):this.$stage.stop(),this.invalidate(\"position\")),this.$element.toggleClass(this.options.grabClass,\"mousedown\"===b.type),this.speed(0),this._drag.time=(new Date).getTime(),this._drag.target=a(b.target),this._drag.stage.start=d,this._drag.stage.current=d,this._drag.pointer=this.pointer(b),a(c).on(\"mouseup.owl.core touchend.owl.core\",a.proxy(this.onDragEnd,this)),a(c).one(\"mousemove.owl.core touchmove.owl.core\",a.proxy(function(b){var d=this.difference(this._drag.pointer,this.pointer(b));a(c).on(\"mousemove.owl.core touchmove.owl.core\",a.proxy(this.onDragMove,this)),Math.abs(d.x)<Math.abs(d.y)&&this.is(\"valid\")||(b.preventDefault(),this.enter(\"dragging\"),this.trigger(\"drag\"))},this)))},e.prototype.onDragMove=function(a){var b=null,c=null,d=null,e=this.difference(this._drag.pointer,this.pointer(a)),f=this.difference(this._drag.stage.start,e);this.is(\"dragging\")&&(a.preventDefault(),this.settings.loop?(b=this.coordinates(this.minimum()),c=this.coordinates(this.maximum()+1)-b,f.x=((f.x-b)%c+c)%c+b):(b=this.settings.rtl?this.coordinates(this.maximum()):this.coordinates(this.minimum()),c=this.settings.rtl?this.coordinates(this.minimum()):this.coordinates(this.maximum()),d=this.settings.pullDrag?-1*e.x/5:0,f.x=Math.max(Math.min(f.x,b+d),c+d)),this._drag.stage.current=f,this.animate(f.x))},e.prototype.onDragEnd=function(b){var d=this.difference(this._drag.pointer,this.pointer(b)),e=this._drag.stage.current,f=d.x>0^this.settings.rtl?\"left\":\"right\";a(c).off(\".owl.core\"),this.$element.removeClass(this.options.grabClass),(0!==d.x&&this.is(\"dragging\")||!this.is(\"valid\"))&&(this.speed(this.settings.dragEndSpeed||this.settings.smartSpeed),this.current(this.closest(e.x,0!==d.x?f:this._drag.direction)),this.invalidate(\"position\"),this.update(),this._drag.direction=f,(Math.abs(d.x)>3||(new Date).getTime()-this._drag.time>300)&&this._drag.target.one(\"click.owl.core\",function(){return!1})),this.is(\"dragging\")&&(this.leave(\"dragging\"),this.trigger(\"dragged\"))},e.prototype.closest=function(b,c){var e=-1,f=30,g=this.width(),h=this.coordinates();return this.settings.freeDrag||a.each(h,a.proxy(function(a,i){return\"left\"===c&&b>i-f&&b<i+f?e=a:\"right\"===c&&b>i-g-f&&b<i-g+f?e=a+1:this.op(b,\"<\",i)&&this.op(b,\">\",h[a+1]!==d?h[a+1]:i-g)&&(e=\"left\"===c?a+1:a),-1===e},this)),this.settings.loop||(this.op(b,\">\",h[this.minimum()])?e=b=this.minimum():this.op(b,\"<\",h[this.maximum()])&&(e=b=this.maximum())),e},e.prototype.animate=function(b){var c=this.speed()>0;this.is(\"animating\")&&this.onTransitionEnd(),c&&(this.enter(\"animating\"),this.trigger(\"translate\")),a.support.transform3d&&a.support.transition?this.$stage.css({transform:\"translate3d(\"+b+\"px,0px,0px)\",transition:this.speed()/1e3+\"s\"+(this.settings.slideTransition?\" \"+this.settings.slideTransition:\"\")}):c?this.$stage.animate({left:b+\"px\"},this.speed(),this.settings.fallbackEasing,a.proxy(this.onTransitionEnd,this)):this.$stage.css({left:b+\"px\"})},e.prototype.is=function(a){return this._states.current[a]&&this._states.current[a]>0},e.prototype.current=function(a){if(a===d)return this._current;if(0===this._items.length)return d;if(a=this.normalize(a),this._current!==a){var b=this.trigger(\"change\",{property:{name:\"position\",value:a}});b.data!==d&&(a=this.normalize(b.data)),this._current=a,this.invalidate(\"position\"),this.trigger(\"changed\",{property:{name:\"position\",value:this._current}})}return this._current},e.prototype.invalidate=function(b){return\"string\"===a.type(b)&&(this._invalidated[b]=!0,this.is(\"valid\")&&this.leave(\"valid\")),a.map(this._invalidated,function(a,b){return b})},e.prototype.reset=function(a){(a=this.normalize(a))!==d&&(this._speed=0,this._current=a,this.suppress([\"translate\",\"translated\"]),this.animate(this.coordinates(a)),this.release([\"translate\",\"translated\"]))},e.prototype.normalize=function(a,b){var c=this._items.length,e=b?0:this._clones.length;return!this.isNumeric(a)||c<1?a=d:(a<0||a>=c+e)&&(a=((a-e/2)%c+c)%c+e/2),a},e.prototype.relative=function(a){return a-=this._clones.length/2,this.normalize(a,!0)},e.prototype.maximum=function(a){var b,c,d,e=this.settings,f=this._coordinates.length;if(e.loop)f=this._clones.length/2+this._items.length-1;else if(e.autoWidth||e.merge){if(b=this._items.length)for(c=this._items[--b].width(),d=this.$element.width();b--&&!((c+=this._items[b].width()+this.settings.margin)>d););f=b+1}else f=e.center?this._items.length-1:this._items.length-e.items;return a&&(f-=this._clones.length/2),Math.max(f,0)},e.prototype.minimum=function(a){return a?0:this._clones.length/2},e.prototype.items=function(a){return a===d?this._items.slice():(a=this.normalize(a,!0),this._items[a])},e.prototype.mergers=function(a){return a===d?this._mergers.slice():(a=this.normalize(a,!0),this._mergers[a])},e.prototype.clones=function(b){var c=this._clones.length/2,e=c+this._items.length,f=function(a){return a%2==0?e+a/2:c-(a+1)/2};return b===d?a.map(this._clones,function(a,b){return f(b)}):a.map(this._clones,function(a,c){return a===b?f(c):null})},e.prototype.speed=function(a){return a!==d&&(this._speed=a),this._speed},e.prototype.coordinates=function(b){var c,e=1,f=b-1;return b===d?a.map(this._coordinates,a.proxy(function(a,b){return this.coordinates(b)},this)):(this.settings.center?(this.settings.rtl&&(e=-1,f=b+1),c=this._coordinates[b],c+=(this.width()-c+(this._coordinates[f]||0))/2*e):c=this._coordinates[f]||0,c=Math.ceil(c))},e.prototype.duration=function(a,b,c){return 0===c?0:Math.min(Math.max(Math.abs(b-a),1),6)*Math.abs(c||this.settings.smartSpeed)},e.prototype.to=function(a,b){var c=this.current(),d=null,e=a-this.relative(c),f=(e>0)-(e<0),g=this._items.length,h=this.minimum(),i=this.maximum();this.settings.loop?(!this.settings.rewind&&Math.abs(e)>g/2&&(e+=-1*f*g),a=c+e,(d=((a-h)%g+g)%g+h)!==a&&d-e<=i&&d-e>0&&(c=d-e,a=d,this.reset(c))):this.settings.rewind?(i+=1,a=(a%i+i)%i):a=Math.max(h,Math.min(i,a)),this.speed(this.duration(c,a,b)),this.current(a),this.isVisible()&&this.update()},e.prototype.next=function(a){a=a||!1,this.to(this.relative(this.current())+1,a)},e.prototype.prev=function(a){a=a||!1,this.to(this.relative(this.current())-1,a)},e.prototype.onTransitionEnd=function(a){if(a!==d&&(a.stopPropagation(),(a.target||a.srcElement||a.originalTarget)!==this.$stage.get(0)))return!1;this.leave(\"animating\"),this.trigger(\"translated\")},e.prototype.viewport=function(){var d;return this.options.responsiveBaseElement!==b?d=a(this.options.responsiveBaseElement).width():b.innerWidth?d=b.innerWidth:c.documentElement&&c.documentElement.clientWidth?d=c.documentElement.clientWidth:console.warn(\"Can not detect viewport width.\"),d},e.prototype.replace=function(b){this.$stage.empty(),this._items=[],b&&(b=b instanceof jQuery?b:a(b)),this.settings.nestedItemSelector&&(b=b.find(\".\"+this.settings.nestedItemSelector)),b.filter(function(){return 1===this.nodeType}).each(a.proxy(function(a,b){b=this.prepare(b),this.$stage.append(b),this._items.push(b),this._mergers.push(1*b.find(\"[data-merge]\").addBack(\"[data-merge]\").attr(\"data-merge\")||1)},this)),this.reset(this.isNumeric(this.settings.startPosition)?this.settings.startPosition:0),this.invalidate(\"items\")},e.prototype.add=function(b,c){var e=this.relative(this._current);c=c===d?this._items.length:this.normalize(c,!0),b=b instanceof jQuery?b:a(b),this.trigger(\"add\",{content:b,position:c}),b=this.prepare(b),0===this._items.length||c===this._items.length?(0===this._items.length&&this.$stage.append(b),0!==this._items.length&&this._items[c-1].after(b),this._items.push(b),this._mergers.push(1*b.find(\"[data-merge]\").addBack(\"[data-merge]\").attr(\"data-merge\")||1)):(this._items[c].before(b),this._items.splice(c,0,b),this._mergers.splice(c,0,1*b.find(\"[data-merge]\").addBack(\"[data-merge]\").attr(\"data-merge\")||1)),this._items[e]&&this.reset(this._items[e].index()),this.invalidate(\"items\"),this.trigger(\"added\",{content:b,position:c})},e.prototype.remove=function(a){(a=this.normalize(a,!0))!==d&&(this.trigger(\"remove\",{content:this._items[a],position:a}),this._items[a].remove(),this._items.splice(a,1),this._mergers.splice(a,1),this.invalidate(\"items\"),this.trigger(\"removed\",{content:null,position:a}))},e.prototype.preloadAutoWidthImages=function(b){b.each(a.proxy(function(b,c){this.enter(\"pre-loading\"),c=a(c),a(new Image).one(\"load\",a.proxy(function(a){c.attr(\"src\",a.target.src),c.css(\"opacity\",1),this.leave(\"pre-loading\"),!this.is(\"pre-loading\")&&!this.is(\"initializing\")&&this.refresh()},this)).attr(\"src\",c.attr(\"src\")||c.attr(\"data-src\")||c.attr(\"data-src-retina\"))},this))},e.prototype.destroy=function(){this.$element.off(\".owl.core\"),this.$stage.off(\".owl.core\"),a(c).off(\".owl.core\"),!1!==this.settings.responsive&&(b.clearTimeout(this.resizeTimer),this.off(b,\"resize\",this._handlers.onThrottledResize));for(var d in this._plugins)this._plugins[d].destroy();this.$stage.children(\".cloned\").remove(),this.$stage.unwrap(),this.$stage.children().contents().unwrap(),this.$stage.children().unwrap(),this.$stage.remove(),this.$element.removeClass(this.options.refreshClass).removeClass(this.options.loadingClass).removeClass(this.options.loadedClass).removeClass(this.options.rtlClass).removeClass(this.options.dragClass).removeClass(this.options.grabClass).attr(\"class\",this.$element.attr(\"class\").replace(new RegExp(this.options.responsiveClass+\"-\\\\S+\\\\s\",\"g\"),\"\")).removeData(\"owl.carousel\")},e.prototype.op=function(a,b,c){var d=this.settings.rtl;switch(b){case\"<\":return d?a>c:a<c;case\">\":return d?a<c:a>c;case\">=\":return d?a<=c:a>=c;case\"<=\":return d?a>=c:a<=c}},e.prototype.on=function(a,b,c,d){a.addEventListener?a.addEventListener(b,c,d):a.attachEvent&&a.attachEvent(\"on\"+b,c)},e.prototype.off=function(a,b,c,d){a.removeEventListener?a.removeEventListener(b,c,d):a.detachEvent&&a.detachEvent(\"on\"+b,c)},e.prototype.trigger=function(b,c,d,f,g){var h={item:{count:this._items.length,index:this.current()}},i=a.camelCase(a.grep([\"on\",b,d],function(a){return a}).join(\"-\").toLowerCase()),j=a.Event([b,\"owl\",d||\"carousel\"].join(\".\").toLowerCase(),a.extend({relatedTarget:this},h,c));return this._supress[b]||(a.each(this._plugins,function(a,b){b.onTrigger&&b.onTrigger(j)}),this.register({type:e.Type.Event,name:b}),this.$element.trigger(j),this.settings&&\"function\"==typeof this.settings[i]&&this.settings[i].call(this,j)),j},e.prototype.enter=function(b){a.each([b].concat(this._states.tags[b]||[]),a.proxy(function(a,b){this._states.current[b]===d&&(this._states.current[b]=0),this._states.current[b]++},this))},e.prototype.leave=function(b){a.each([b].concat(this._states.tags[b]||[]),a.proxy(function(a,b){this._states.current[b]--},this))},e.prototype.register=function(b){if(b.type===e.Type.Event){if(a.event.special[b.name]||(a.event.special[b.name]={}),!a.event.special[b.name].owl){var c=a.event.special[b.name]._default;a.event.special[b.name]._default=function(a){return!c||!c.apply||a.namespace&&-1!==a.namespace.indexOf(\"owl\")?a.namespace&&a.namespace.indexOf(\"owl\")>-1:c.apply(this,arguments)},a.event.special[b.name].owl=!0}}else b.type===e.Type.State&&(this._states.tags[b.name]?this._states.tags[b.name]=this._states.tags[b.name].concat(b.tags):this._states.tags[b.name]=b.tags,this._states.tags[b.name]=a.grep(this._states.tags[b.name],a.proxy(function(c,d){return a.inArray(c,this._states.tags[b.name])===d},this)))},e.prototype.suppress=function(b){a.each(b,a.proxy(function(a,b){this._supress[b]=!0},this))},e.prototype.release=function(b){a.each(b,a.proxy(function(a,b){delete this._supress[b]},this))},e.prototype.pointer=function(a){var c={x:null,y:null};return a=a.originalEvent||a||b.event,a=a.touches&&a.touches.length?a.touches[0]:a.changedTouches&&a.changedTouches.length?a.changedTouches[0]:a,a.pageX?(c.x=a.pageX,c.y=a.pageY):(c.x=a.clientX,c.y=a.clientY),c},e.prototype.isNumeric=function(a){return!isNaN(parseFloat(a))},e.prototype.difference=function(a,b){return{x:a.x-b.x,y:a.y-b.y}},a.fn.owlCarousel=function(b){var c=Array.prototype.slice.call(arguments,1);return this.each(function(){var d=a(this),f=d.data(\"owl.carousel\");f||(f=new e(this,\"object\"==typeof b&&b),d.data(\"owl.carousel\",f),a.each([\"next\",\"prev\",\"to\",\"destroy\",\"refresh\",\"replace\",\"add\",\"remove\"],function(b,c){f.register({type:e.Type.Event,name:c}),f.$element.on(c+\".owl.carousel.core\",a.proxy(function(a){a.namespace&&a.relatedTarget!==this&&(this.suppress([c]),f[c].apply(this,[].slice.call(arguments,1)),this.release([c]))},f))})),\"string\"==typeof b&&\"_\"!==b.charAt(0)&&f[b].apply(f,c)})},a.fn.owlCarousel.Constructor=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){var e=function(b){this._core=b,this._interval=null,this._visible=null,this._handlers={\"initialized.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.settings.autoRefresh&&this.watch()},this)},this._core.options=a.extend({},e.Defaults,this._core.options),this._core.$element.on(this._handlers)};e.Defaults={autoRefresh:!0,autoRefreshInterval:500},e.prototype.watch=function(){this._interval||(this._visible=this._core.isVisible(),this._interval=b.setInterval(a.proxy(this.refresh,this),this._core.settings.autoRefreshInterval))},e.prototype.refresh=function(){this._core.isVisible()!==this._visible&&(this._visible=!this._visible,this._core.$element.toggleClass(\"owl-hidden\",!this._visible),this._visible&&this._core.invalidate(\"width\")&&this._core.refresh())},e.prototype.destroy=function(){var a,c;b.clearInterval(this._interval);for(a in this._handlers)this._core.$element.off(a,this._handlers[a]);for(c in Object.getOwnPropertyNames(this))\"function\"!=typeof this[c]&&(this[c]=null)},a.fn.owlCarousel.Constructor.Plugins.AutoRefresh=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){var e=function(b){this._core=b,this._loaded=[],this._handlers={\"initialized.owl.carousel change.owl.carousel resized.owl.carousel\":a.proxy(function(b){if(b.namespace&&this._core.settings&&this._core.settings.lazyLoad&&(b.property&&\"position\"==b.property.name||\"initialized\"==b.type)){var c=this._core.settings,e=c.center&&Math.ceil(c.items/2)||c.items,f=c.center&&-1*e||0,g=(b.property&&b.property.value!==d?b.property.value:this._core.current())+f,h=this._core.clones().length,i=a.proxy(function(a,b){this.load(b)},this);for(c.lazyLoadEager>0&&(e+=c.lazyLoadEager,c.loop&&(g-=c.lazyLoadEager,e++));f++<e;)this.load(h/2+this._core.relative(g)),h&&a.each(this._core.clones(this._core.relative(g)),i),g++}},this)},this._core.options=a.extend({},e.Defaults,this._core.options),this._core.$element.on(this._handlers)};e.Defaults={lazyLoad:!1,lazyLoadEager:0},e.prototype.load=function(c){var d=this._core.$stage.children().eq(c),e=d&&d.find(\".owl-lazy\");!e||a.inArray(d.get(0),this._loaded)>-1||(e.each(a.proxy(function(c,d){var e,f=a(d),g=b.devicePixelRatio>1&&f.attr(\"data-src-retina\")||f.attr(\"data-src\")||f.attr(\"data-srcset\");this._core.trigger(\"load\",{element:f,url:g},\"lazy\"),f.is(\"img\")?f.one(\"load.owl.lazy\",a.proxy(function(){f.css(\"opacity\",1),this._core.trigger(\"loaded\",{element:f,url:g},\"lazy\")},this)).attr(\"src\",g):f.is(\"source\")?f.one(\"load.owl.lazy\",a.proxy(function(){this._core.trigger(\"loaded\",{element:f,url:g},\"lazy\")},this)).attr(\"srcset\",g):(e=new Image,e.onload=a.proxy(function(){f.css({\"background-image\":'url(\"'+g+'\")',opacity:\"1\"}),this._core.trigger(\"loaded\",{element:f,url:g},\"lazy\")},this),e.src=g)},this)),this._loaded.push(d.get(0)))},e.prototype.destroy=function(){var a,b;for(a in this.handlers)this._core.$element.off(a,this.handlers[a]);for(b in Object.getOwnPropertyNames(this))\"function\"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.Lazy=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){var e=function(c){this._core=c,this._previousHeight=null,this._handlers={\"initialized.owl.carousel refreshed.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.settings.autoHeight&&this.update()},this),\"changed.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.settings.autoHeight&&\"position\"===a.property.name&&this.update()},this),\"loaded.owl.lazy\":a.proxy(function(a){a.namespace&&this._core.settings.autoHeight&&a.element.closest(\".\"+this._core.settings.itemClass).index()===this._core.current()&&this.update()},this)},this._core.options=a.extend({},e.Defaults,this._core.options),this._core.$element.on(this._handlers),this._intervalId=null;var d=this;a(b).on(\"load\",function(){d._core.settings.autoHeight&&d.update()}),a(b).resize(function(){d._core.settings.autoHeight&&(null!=d._intervalId&&clearTimeout(d._intervalId),d._intervalId=setTimeout(function(){d.update()},250))})};e.Defaults={autoHeight:!1,autoHeightClass:\"owl-height\"},e.prototype.update=function(){var b=this._core._current,c=b+this._core.settings.items,d=this._core.settings.lazyLoad,e=this._core.$stage.children().toArray().slice(b,c),f=[],g=0;a.each(e,function(b,c){f.push(a(c).height())}),g=Math.max.apply(null,f),g<=1&&d&&this._previousHeight&&(g=this._previousHeight),this._previousHeight=g,this._core.$stage.parent().height(g).addClass(this._core.settings.autoHeightClass)},e.prototype.destroy=function(){var a,b;for(a in this._handlers)this._core.$element.off(a,this._handlers[a]);for(b in Object.getOwnPropertyNames(this))\"function\"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.AutoHeight=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){var e=function(b){this._core=b,this._videos={},this._playing=null,this._handlers={\"initialized.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.register({type:\"state\",name:\"playing\",tags:[\"interacting\"]})},this),\"resize.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.settings.video&&this.isInFullScreen()&&a.preventDefault()},this),\"refreshed.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.is(\"resizing\")&&this._core.$stage.find(\".cloned .owl-video-frame\").remove()},this),\"changed.owl.carousel\":a.proxy(function(a){a.namespace&&\"position\"===a.property.name&&this._playing&&this.stop()},this),\"prepared.owl.carousel\":a.proxy(function(b){if(b.namespace){var c=a(b.content).find(\".owl-video\");c.length&&(c.css(\"display\",\"none\"),this.fetch(c,a(b.content)))}},this)},this._core.options=a.extend({},e.Defaults,this._core.options),this._core.$element.on(this._handlers),this._core.$element.on(\"click.owl.video\",\".owl-video-play-icon\",a.proxy(function(a){this.play(a)},this))};e.Defaults={video:!1,videoHeight:!1,videoWidth:!1},e.prototype.fetch=function(a,b){var c=function(){return a.attr(\"data-vimeo-id\")?\"vimeo\":a.attr(\"data-vzaar-id\")?\"vzaar\":\"youtube\"}(),d=a.attr(\"data-vimeo-id\")||a.attr(\"data-youtube-id\")||a.attr(\"data-vzaar-id\"),e=a.attr(\"data-width\")||this._core.settings.videoWidth,f=a.attr(\"data-height\")||this._core.settings.videoHeight,g=a.attr(\"href\");if(!g)throw new Error(\"Missing video URL.\");if(d=g.match(/(http:|https:|)\\/\\/(player.|www.|app.)?(vimeo\\.com|youtu(be\\.com|\\.be|be\\.googleapis\\.com|be\\-nocookie\\.com)|vzaar\\.com)\\/(video\\/|videos\\/|embed\\/|channels\\/.+\\/|groups\\/.+\\/|watch\\?v=|v\\/)?([A-Za-z0-9._%-]*)(\\&\\S+)?/),d[3].indexOf(\"youtu\")>-1)c=\"youtube\";else if(d[3].indexOf(\"vimeo\")>-1)c=\"vimeo\";else{if(!(d[3].indexOf(\"vzaar\")>-1))throw new Error(\"Video URL not supported.\");c=\"vzaar\"}d=d[6],this._videos[g]={type:c,id:d,width:e,height:f},b.attr(\"data-video\",g),this.thumbnail(a,this._videos[g])},e.prototype.thumbnail=function(b,c){var d,e,f,g=c.width&&c.height?\"width:\"+c.width+\"px;height:\"+c.height+\"px;\":\"\",h=b.find(\"img\"),i=\"src\",j=\"\",k=this._core.settings,l=function(c){e='<div class=\"owl-video-play-icon\"></div>',d=k.lazyLoad?a(\"<div/>\",{class:\"owl-video-tn \"+j,srcType:c}):a(\"<div/>\",{class:\"owl-video-tn\",style:\"opacity:1;background-image:url(\"+c+\")\"}),b.after(d),b.after(e)};if(b.wrap(a(\"<div/>\",{class:\"owl-video-wrapper\",style:g})),this._core.settings.lazyLoad&&(i=\"data-src\",j=\"owl-lazy\"),h.length)return l(h.attr(i)),h.remove(),!1;\"youtube\"===c.type?(f=\"//img.youtube.com/vi/\"+c.id+\"/hqdefault.jpg\",l(f)):\"vimeo\"===c.type?a.ajax({type:\"GET\",url:\"//vimeo.com/api/v2/video/\"+c.id+\".json\",jsonp:\"callback\",dataType:\"jsonp\",success:function(a){f=a[0].thumbnail_large,l(f)}}):\"vzaar\"===c.type&&a.ajax({type:\"GET\",url:\"//vzaar.com/api/videos/\"+c.id+\".json\",jsonp:\"callback\",dataType:\"jsonp\",success:function(a){f=a.framegrab_url,l(f)}})},e.prototype.stop=function(){this._core.trigger(\"stop\",null,\"video\"),this._playing.find(\".owl-video-frame\").remove(),this._playing.removeClass(\"owl-video-playing\"),this._playing=null,this._core.leave(\"playing\"),this._core.trigger(\"stopped\",null,\"video\")},e.prototype.play=function(b){var c,d=a(b.target),e=d.closest(\".\"+this._core.settings.itemClass),f=this._videos[e.attr(\"data-video\")],g=f.width||\"100%\",h=f.height||this._core.$stage.height();this._playing||(this._core.enter(\"playing\"),this._core.trigger(\"play\",null,\"video\"),e=this._core.items(this._core.relative(e.index())),this._core.reset(e.index()),c=a('<iframe frameborder=\"0\" allowfullscreen mozallowfullscreen webkitAllowFullScreen ></iframe>'),c.attr(\"height\",h),c.attr(\"width\",g),\"youtube\"===f.type?c.attr(\"src\",\"//www.youtube.com/embed/\"+f.id+\"?autoplay=1&rel=0&v=\"+f.id):\"vimeo\"===f.type?c.attr(\"src\",\"//player.vimeo.com/video/\"+f.id+\"?autoplay=1\"):\"vzaar\"===f.type&&c.attr(\"src\",\"//view.vzaar.com/\"+f.id+\"/player?autoplay=true\"),a(c).wrap('<div class=\"owl-video-frame\" />').insertAfter(e.find(\".owl-video\")),this._playing=e.addClass(\"owl-video-playing\"))},e.prototype.isInFullScreen=function(){var b=c.fullscreenElement||c.mozFullScreenElement||c.webkitFullscreenElement;return b&&a(b).parent().hasClass(\"owl-video-frame\")},e.prototype.destroy=function(){var a,b;this._core.$element.off(\"click.owl.video\");for(a in this._handlers)this._core.$element.off(a,this._handlers[a]);for(b in Object.getOwnPropertyNames(this))\"function\"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.Video=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){var e=function(b){this.core=b,this.core.options=a.extend({},e.Defaults,this.core.options),this.swapping=!0,this.previous=d,this.next=d,this.handlers={\"change.owl.carousel\":a.proxy(function(a){a.namespace&&\"position\"==a.property.name&&(this.previous=this.core.current(),this.next=a.property.value)},this),\"drag.owl.carousel dragged.owl.carousel translated.owl.carousel\":a.proxy(function(a){a.namespace&&(this.swapping=\"translated\"==a.type)},this),\"translate.owl.carousel\":a.proxy(function(a){a.namespace&&this.swapping&&(this.core.options.animateOut||this.core.options.animateIn)&&this.swap()},this)},this.core.$element.on(this.handlers)};e.Defaults={animateOut:!1,\r\nanimateIn:!1},e.prototype.swap=function(){if(1===this.core.settings.items&&a.support.animation&&a.support.transition){this.core.speed(0);var b,c=a.proxy(this.clear,this),d=this.core.$stage.children().eq(this.previous),e=this.core.$stage.children().eq(this.next),f=this.core.settings.animateIn,g=this.core.settings.animateOut;this.core.current()!==this.previous&&(g&&(b=this.core.coordinates(this.previous)-this.core.coordinates(this.next),d.one(a.support.animation.end,c).css({left:b+\"px\"}).addClass(\"animated owl-animated-out\").addClass(g)),f&&e.one(a.support.animation.end,c).addClass(\"animated owl-animated-in\").addClass(f))}},e.prototype.clear=function(b){a(b.target).css({left:\"\"}).removeClass(\"animated owl-animated-out owl-animated-in\").removeClass(this.core.settings.animateIn).removeClass(this.core.settings.animateOut),this.core.onTransitionEnd()},e.prototype.destroy=function(){var a,b;for(a in this.handlers)this.core.$element.off(a,this.handlers[a]);for(b in Object.getOwnPropertyNames(this))\"function\"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.Animate=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){var e=function(b){this._core=b,this._call=null,this._time=0,this._timeout=0,this._paused=!0,this._handlers={\"changed.owl.carousel\":a.proxy(function(a){a.namespace&&\"settings\"===a.property.name?this._core.settings.autoplay?this.play():this.stop():a.namespace&&\"position\"===a.property.name&&this._paused&&(this._time=0)},this),\"initialized.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.settings.autoplay&&this.play()},this),\"play.owl.autoplay\":a.proxy(function(a,b,c){a.namespace&&this.play(b,c)},this),\"stop.owl.autoplay\":a.proxy(function(a){a.namespace&&this.stop()},this),\"mouseover.owl.autoplay\":a.proxy(function(){this._core.settings.autoplayHoverPause&&this._core.is(\"rotating\")&&this.pause()},this),\"mouseleave.owl.autoplay\":a.proxy(function(){this._core.settings.autoplayHoverPause&&this._core.is(\"rotating\")&&this.play()},this),\"touchstart.owl.core\":a.proxy(function(){this._core.settings.autoplayHoverPause&&this._core.is(\"rotating\")&&this.pause()},this),\"touchend.owl.core\":a.proxy(function(){this._core.settings.autoplayHoverPause&&this.play()},this)},this._core.$element.on(this._handlers),this._core.options=a.extend({},e.Defaults,this._core.options)};e.Defaults={autoplay:!1,autoplayTimeout:5e3,autoplayHoverPause:!1,autoplaySpeed:!1},e.prototype._next=function(d){this._call=b.setTimeout(a.proxy(this._next,this,d),this._timeout*(Math.round(this.read()/this._timeout)+1)-this.read()),this._core.is(\"interacting\")||c.hidden||this._core.next(d||this._core.settings.autoplaySpeed)},e.prototype.read=function(){return(new Date).getTime()-this._time},e.prototype.play=function(c,d){var e;this._core.is(\"rotating\")||this._core.enter(\"rotating\"),c=c||this._core.settings.autoplayTimeout,e=Math.min(this._time%(this._timeout||c),c),this._paused?(this._time=this.read(),this._paused=!1):b.clearTimeout(this._call),this._time+=this.read()%c-e,this._timeout=c,this._call=b.setTimeout(a.proxy(this._next,this,d),c-e)},e.prototype.stop=function(){this._core.is(\"rotating\")&&(this._time=0,this._paused=!0,b.clearTimeout(this._call),this._core.leave(\"rotating\"))},e.prototype.pause=function(){this._core.is(\"rotating\")&&!this._paused&&(this._time=this.read(),this._paused=!0,b.clearTimeout(this._call))},e.prototype.destroy=function(){var a,b;this.stop();for(a in this._handlers)this._core.$element.off(a,this._handlers[a]);for(b in Object.getOwnPropertyNames(this))\"function\"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.autoplay=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){\"use strict\";var e=function(b){this._core=b,this._initialized=!1,this._pages=[],this._controls={},this._templates=[],this.$element=this._core.$element,this._overrides={next:this._core.next,prev:this._core.prev,to:this._core.to},this._handlers={\"prepared.owl.carousel\":a.proxy(function(b){b.namespace&&this._core.settings.dotsData&&this._templates.push('<div class=\"'+this._core.settings.dotClass+'\">'+a(b.content).find(\"[data-dot]\").addBack(\"[data-dot]\").attr(\"data-dot\")+\"</div>\")},this),\"added.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.settings.dotsData&&this._templates.splice(a.position,0,this._templates.pop())},this),\"remove.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.settings.dotsData&&this._templates.splice(a.position,1)},this),\"changed.owl.carousel\":a.proxy(function(a){a.namespace&&\"position\"==a.property.name&&this.draw()},this),\"initialized.owl.carousel\":a.proxy(function(a){a.namespace&&!this._initialized&&(this._core.trigger(\"initialize\",null,\"navigation\"),this.initialize(),this.update(),this.draw(),this._initialized=!0,this._core.trigger(\"initialized\",null,\"navigation\"))},this),\"refreshed.owl.carousel\":a.proxy(function(a){a.namespace&&this._initialized&&(this._core.trigger(\"refresh\",null,\"navigation\"),this.update(),this.draw(),this._core.trigger(\"refreshed\",null,\"navigation\"))},this)},this._core.options=a.extend({},e.Defaults,this._core.options),this.$element.on(this._handlers)};e.Defaults={nav:!1,navText:['<span aria-label=\"Previous\">&#x2039;</span>','<span aria-label=\"Next\">&#x203a;</span>'],navSpeed:!1,navElement:'button type=\"button\" role=\"presentation\"',navContainer:!1,navContainerClass:\"owl-nav\",navClass:[\"owl-prev\",\"owl-next\"],slideBy:1,dotClass:\"owl-dot\",dotsClass:\"owl-dots\",dots:!0,dotsEach:!1,dotsData:!1,dotsSpeed:!1,dotsContainer:!1},e.prototype.initialize=function(){var b,c=this._core.settings;this._controls.$relative=(c.navContainer?a(c.navContainer):a(\"<div>\").addClass(c.navContainerClass).appendTo(this.$element)).addClass(\"disabled\"),this._controls.$previous=a(\"<\"+c.navElement+\">\").addClass(c.navClass[0]).html(c.navText[0]).prependTo(this._controls.$relative).on(\"click\",a.proxy(function(a){this.prev(c.navSpeed)},this)),this._controls.$next=a(\"<\"+c.navElement+\">\").addClass(c.navClass[1]).html(c.navText[1]).appendTo(this._controls.$relative).on(\"click\",a.proxy(function(a){this.next(c.navSpeed)},this)),c.dotsData||(this._templates=[a('<button role=\"button\">').addClass(c.dotClass).append(a(\"<span>\")).prop(\"outerHTML\")]),this._controls.$absolute=(c.dotsContainer?a(c.dotsContainer):a(\"<div>\").addClass(c.dotsClass).appendTo(this.$element)).addClass(\"disabled\"),this._controls.$absolute.on(\"click\",\"button\",a.proxy(function(b){var d=a(b.target).parent().is(this._controls.$absolute)?a(b.target).index():a(b.target).parent().index();b.preventDefault(),this.to(d,c.dotsSpeed)},this));for(b in this._overrides)this._core[b]=a.proxy(this[b],this)},e.prototype.destroy=function(){var a,b,c,d,e;e=this._core.settings;for(a in this._handlers)this.$element.off(a,this._handlers[a]);for(b in this._controls)\"$relative\"===b&&e.navContainer?this._controls[b].html(\"\"):this._controls[b].remove();for(d in this.overides)this._core[d]=this._overrides[d];for(c in Object.getOwnPropertyNames(this))\"function\"!=typeof this[c]&&(this[c]=null)},e.prototype.update=function(){var a,b,c,d=this._core.clones().length/2,e=d+this._core.items().length,f=this._core.maximum(!0),g=this._core.settings,h=g.center||g.autoWidth||g.dotsData?1:g.dotsEach||g.items;if(\"page\"!==g.slideBy&&(g.slideBy=Math.min(g.slideBy,g.items)),g.dots||\"page\"==g.slideBy)for(this._pages=[],a=d,b=0,c=0;a<e;a++){if(b>=h||0===b){if(this._pages.push({start:Math.min(f,a-d),end:a-d+h-1}),Math.min(f,a-d)===f)break;b=0,++c}b+=this._core.mergers(this._core.relative(a))}},e.prototype.draw=function(){var b,c=this._core.settings,d=this._core.items().length<=c.items,e=this._core.relative(this._core.current()),f=c.loop||c.rewind;this._controls.$relative.toggleClass(\"disabled\",!c.nav||d),c.nav&&(this._controls.$previous.toggleClass(\"disabled\",!f&&e<=this._core.minimum(!0)),this._controls.$next.toggleClass(\"disabled\",!f&&e>=this._core.maximum(!0))),this._controls.$absolute.toggleClass(\"disabled\",!c.dots||d),c.dots&&(b=this._pages.length-this._controls.$absolute.children().length,c.dotsData&&0!==b?this._controls.$absolute.html(this._templates.join(\"\")):b>0?this._controls.$absolute.append(new Array(b+1).join(this._templates[0])):b<0&&this._controls.$absolute.children().slice(b).remove(),this._controls.$absolute.find(\".active\").removeClass(\"active\"),this._controls.$absolute.children().eq(a.inArray(this.current(),this._pages)).addClass(\"active\"))},e.prototype.onTrigger=function(b){var c=this._core.settings;b.page={index:a.inArray(this.current(),this._pages),count:this._pages.length,size:c&&(c.center||c.autoWidth||c.dotsData?1:c.dotsEach||c.items)}},e.prototype.current=function(){var b=this._core.relative(this._core.current());return a.grep(this._pages,a.proxy(function(a,c){return a.start<=b&&a.end>=b},this)).pop()},e.prototype.getPosition=function(b){var c,d,e=this._core.settings;return\"page\"==e.slideBy?(c=a.inArray(this.current(),this._pages),d=this._pages.length,b?++c:--c,c=this._pages[(c%d+d)%d].start):(c=this._core.relative(this._core.current()),d=this._core.items().length,b?c+=e.slideBy:c-=e.slideBy),c},e.prototype.next=function(b){a.proxy(this._overrides.to,this._core)(this.getPosition(!0),b)},e.prototype.prev=function(b){a.proxy(this._overrides.to,this._core)(this.getPosition(!1),b)},e.prototype.to=function(b,c,d){var e;!d&&this._pages.length?(e=this._pages.length,a.proxy(this._overrides.to,this._core)(this._pages[(b%e+e)%e].start,c)):a.proxy(this._overrides.to,this._core)(b,c)},a.fn.owlCarousel.Constructor.Plugins.Navigation=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){\"use strict\";var e=function(c){this._core=c,this._hashes={},this.$element=this._core.$element,this._handlers={\"initialized.owl.carousel\":a.proxy(function(c){c.namespace&&\"URLHash\"===this._core.settings.startPosition&&a(b).trigger(\"hashchange.owl.navigation\")},this),\"prepared.owl.carousel\":a.proxy(function(b){if(b.namespace){var c=a(b.content).find(\"[data-hash]\").addBack(\"[data-hash]\").attr(\"data-hash\");if(!c)return;this._hashes[c]=b.content}},this),\"changed.owl.carousel\":a.proxy(function(c){if(c.namespace&&\"position\"===c.property.name){var d=this._core.items(this._core.relative(this._core.current())),e=a.map(this._hashes,function(a,b){return a===d?b:null}).join();if(!e||b.location.hash.slice(1)===e)return;b.location.hash=e}},this)},this._core.options=a.extend({},e.Defaults,this._core.options),this.$element.on(this._handlers),a(b).on(\"hashchange.owl.navigation\",a.proxy(function(a){var c=b.location.hash.substring(1),e=this._core.$stage.children(),f=this._hashes[c]&&e.index(this._hashes[c]);f!==d&&f!==this._core.current()&&this._core.to(this._core.relative(f),!1,!0)},this))};e.Defaults={URLhashListener:!1},e.prototype.destroy=function(){var c,d;a(b).off(\"hashchange.owl.navigation\");for(c in this._handlers)this._core.$element.off(c,this._handlers[c]);for(d in Object.getOwnPropertyNames(this))\"function\"!=typeof this[d]&&(this[d]=null)},a.fn.owlCarousel.Constructor.Plugins.Hash=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){function e(b,c){var e=!1,f=b.charAt(0).toUpperCase()+b.slice(1);return a.each((b+\" \"+h.join(f+\" \")+f).split(\" \"),function(a,b){if(g[b]!==d)return e=!c||b,!1}),e}function f(a){return e(a,!0)}var g=a(\"<support>\").get(0).style,h=\"Webkit Moz O ms\".split(\" \"),i={transition:{end:{WebkitTransition:\"webkitTransitionEnd\",MozTransition:\"transitionend\",OTransition:\"oTransitionEnd\",transition:\"transitionend\"}},animation:{end:{WebkitAnimation:\"webkitAnimationEnd\",MozAnimation:\"animationend\",OAnimation:\"oAnimationEnd\",animation:\"animationend\"}}},j={csstransforms:function(){return!!e(\"transform\")},csstransforms3d:function(){return!!e(\"perspective\")},csstransitions:function(){return!!e(\"transition\")},cssanimations:function(){return!!e(\"animation\")}};j.csstransitions()&&(a.support.transition=new String(f(\"transition\")),a.support.transition.end=i.transition.end[a.support.transition]),j.cssanimations()&&(a.support.animation=new String(f(\"animation\")),a.support.animation.end=i.animation.end[a.support.animation]),j.csstransforms()&&(a.support.transform=new String(f(\"transform\")),a.support.transform3d=j.csstransforms3d())}(window.Zepto||window.jQuery,window,document);","Magento_Catalog/product/view/validation.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    'mage/validation/validation'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.validation', $.mage.validation, {\n        options: {\n            radioCheckboxClosest: 'ul, ol',\n\n            /**\n             * @param {*} error\n             * @param {HTMLElement} element\n             */\n            errorPlacement: function (error, element) {\n                var messageBox,\n                    dataValidate;\n\n                if ($(element).hasClass('datetime-picker')) {\n                    element = $(element).parent();\n\n                    if (element.parent().find('.mage-error').length) {\n                        return;\n                    }\n                }\n\n                if (element.attr('data-errors-message-box')) {\n                    messageBox = $(element.attr('data-errors-message-box'));\n                    messageBox.html(error);\n\n                    return;\n                }\n\n                dataValidate = element.attr('data-validate');\n\n                if (dataValidate && dataValidate.indexOf('validate-one-checkbox-required-by-name') > 0) {\n                    error.appendTo('#links-advice-container');\n                } else if (element.is(':radio, :checkbox')) {\n                    element.closest(this.radioCheckboxClosest).after(error);\n                } else {\n                    element.after(error);\n                }\n            },\n\n            /**\n             * @param {HTMLElement} element\n             * @param {String} errorClass\n             */\n            highlight: function (element, errorClass) {\n                var dataValidate = $(element).attr('data-validate');\n\n                if (dataValidate && dataValidate.indexOf('validate-required-datetime') > 0) {\n                    $(element).parent().find('.datetime-picker').each(function () {\n                        $(this).removeClass(errorClass);\n\n                        if ($(this).val().length === 0) {\n                            $(this).addClass(errorClass);\n                        }\n                    });\n                } else if ($(element).is(':radio, :checkbox')) {\n                    $(element).closest(this.radioCheckboxClosest).addClass(errorClass);\n                } else {\n                    $(element).addClass(errorClass);\n                }\n            },\n\n            /**\n             * @param {HTMLElement} element\n             * @param {String} errorClass\n             */\n            unhighlight: function (element, errorClass) {\n                var dataValidate = $(element).attr('data-validate');\n\n                if (dataValidate && dataValidate.indexOf('validate-required-datetime') > 0) {\n                    $(element).parent().find('.datetime-picker').removeClass(errorClass);\n                } else if ($(element).is(':radio, :checkbox')) {\n                    $(element).closest(this.radioCheckboxClosest).removeClass(errorClass);\n                } else {\n                    $(element).removeClass(errorClass);\n                }\n            }\n        }\n    });\n\n    return $.mage.validation;\n});\n","Magento_Catalog/js/price-box.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'Magento_Catalog/js/price-utils',\n    'underscore',\n    'mage/template',\n    'jquery-ui-modules/widget'\n], function ($, utils, _, mageTemplate) {\n    'use strict';\n\n    var globalOptions = {\n        productId: null,\n        priceConfig: null,\n        prices: {},\n        priceTemplate: '<span class=\"price\"><%- data.formatted %></span>'\n    };\n\n    $.widget('mage.priceBox', {\n        options: globalOptions,\n        qtyInfo: '#qty',\n\n        /**\n         * Widget initialisation.\n         * Every time when option changed prices also can be changed. So\n         * changed options.prices -> changed cached prices -> recalculation -> redraw price box\n         */\n        _init: function initPriceBox() {\n            var box = this.element;\n\n            box.trigger('updatePrice');\n            this.cache.displayPrices = utils.deepClone(this.options.prices);\n        },\n\n        /**\n         * Widget creating.\n         */\n        _create: function createPriceBox() {\n            var box = this.element;\n\n            this.cache = {};\n            this._setDefaultsFromPriceConfig();\n            this._setDefaultsFromDataSet();\n\n            box.on('reloadPrice', this.reloadPrice.bind(this));\n            box.on('updatePrice', this.onUpdatePrice.bind(this));\n            $(this.qtyInfo).on('input', this.updateProductTierPrice.bind(this));\n            box.trigger('price-box-initialized');\n        },\n\n        /**\n         * Call on event updatePrice. Proxy to updatePrice method.\n         * @param {Event} event\n         * @param {Object} prices\n         */\n        onUpdatePrice: function onUpdatePrice(event, prices) {\n            return this.updatePrice(prices);\n        },\n\n        /**\n         * Updates price via new (or additional values).\n         * It expects object like this:\n         * -----\n         *   \"option-hash\":\n         *      \"price-code\":\n         *         \"amount\": 999.99999,\n         *         ...\n         * -----\n         * Empty option-hash object or empty price-code object treats as zero amount.\n         * @param {Object} newPrices\n         */\n        updatePrice: function updatePrice(newPrices) {\n            var prices = this.cache.displayPrices,\n                additionalPrice = {},\n                pricesCode = [],\n                priceValue, origin, finalPrice;\n\n            this.cache.additionalPriceObject = this.cache.additionalPriceObject || {};\n\n            if (newPrices) {\n                $.extend(this.cache.additionalPriceObject, newPrices);\n            }\n\n            if (!_.isEmpty(additionalPrice)) {\n                pricesCode = _.keys(additionalPrice);\n            } else if (!_.isEmpty(prices)) {\n                pricesCode = _.keys(prices);\n            }\n\n            _.each(this.cache.additionalPriceObject, function (additional) {\n                if (additional && !_.isEmpty(additional)) {\n                    pricesCode = _.keys(additional);\n                }\n                _.each(pricesCode, function (priceCode) {\n                    priceValue = additional[priceCode] || {};\n                    priceValue.amount = +priceValue.amount || 0;\n                    priceValue.adjustments = priceValue.adjustments || {};\n\n                    additionalPrice[priceCode] = additionalPrice[priceCode] || {\n                        'amount': 0,\n                        'adjustments': {}\n                    };\n                    additionalPrice[priceCode].amount =  0 + (additionalPrice[priceCode].amount || 0) +\n                        priceValue.amount;\n                    _.each(priceValue.adjustments, function (adValue, adCode) {\n                        additionalPrice[priceCode].adjustments[adCode] = 0 +\n                            (additionalPrice[priceCode].adjustments[adCode] || 0) + adValue;\n                    });\n                });\n            });\n\n            if (_.isEmpty(additionalPrice)) {\n                this.cache.displayPrices = utils.deepClone(this.options.prices);\n            } else {\n                _.each(additionalPrice, function (option, priceCode) {\n                    origin = this.options.prices[priceCode] || {};\n                    finalPrice = prices[priceCode] || {};\n                    option.amount = option.amount || 0;\n                    origin.amount = origin.amount || 0;\n                    origin.adjustments = origin.adjustments || {};\n                    finalPrice.adjustments = finalPrice.adjustments || {};\n\n                    finalPrice.amount = 0 + origin.amount + option.amount;\n                    _.each(option.adjustments, function (pa, paCode) {\n                        finalPrice.adjustments[paCode] = 0 + (origin.adjustments[paCode] || 0) + pa;\n                    });\n                }, this);\n            }\n\n            this.element.trigger('priceUpdated', this.cache.displayPrices);\n            this.element.trigger('reloadPrice');\n        },\n\n        /*eslint-disable no-extra-parens*/\n        /**\n         * Render price unit block.\n         */\n        reloadPrice: function reDrawPrices() {\n            var priceFormat = (this.options.priceConfig && this.options.priceConfig.priceFormat) || {},\n                priceTemplate = mageTemplate(this.options.priceTemplate);\n\n            _.each(this.cache.displayPrices, function (price, priceCode) {\n                price.final = _.reduce(price.adjustments, function (memo, amount) {\n                    return memo + amount;\n                }, price.amount);\n\n                price.formatted = utils.formatPriceLocale(price.final, priceFormat);\n\n                $('[data-price-type=\"' + priceCode + '\"]', this.element).html(priceTemplate({\n                    data: price\n                }));\n            }, this);\n        },\n\n        /*eslint-enable no-extra-parens*/\n        /**\n         * Overwrites initial (default) prices object.\n         * @param {Object} prices\n         */\n        setDefault: function setDefaultPrices(prices) {\n            this.cache.displayPrices = utils.deepClone(prices);\n            this.options.prices = utils.deepClone(prices);\n        },\n\n        /**\n         * Custom behavior on getting options:\n         * now widget able to deep merge of accepted configuration.\n         * @param  {Object} options\n         * @return {mage.priceBox}\n         */\n        _setOptions: function setOptions(options) {\n            $.extend(true, this.options, options);\n\n            if ('disabled' in options) {\n                this._setOption('disabled', options.disabled);\n            }\n\n            return this;\n        },\n\n        /**\n         * setDefaultsFromDataSet\n         */\n        _setDefaultsFromDataSet: function _setDefaultsFromDataSet() {\n            var box = this.element,\n                priceHolders = $('[data-price-type]', box),\n                prices = this.options.prices;\n\n            this.options.productId = box.data('productId');\n\n            if (_.isEmpty(prices)) {\n                priceHolders.each(function (index, element) {\n                    var type = $(element).data('priceType'),\n                        amount = parseFloat($(element).data('priceAmount'));\n\n                    if (type && !_.isNaN(amount)) {\n                        prices[type] = {\n                            amount: amount\n                        };\n                    }\n                });\n            }\n        },\n\n        /**\n         * setDefaultsFromPriceConfig\n         */\n        _setDefaultsFromPriceConfig: function _setDefaultsFromPriceConfig() {\n            var config = this.options.priceConfig;\n\n            if (config && config.prices) {\n                this.options.prices = config.prices;\n            }\n        },\n\n        /**\n         * Updates product final and base price according to tier prices\n         */\n        updateProductTierPrice: function updateProductTierPrice() {\n            var originalPrice,\n                prices = {'prices': {}};\n\n            if (this.options.prices.finalPrice) {\n                originalPrice = this.options.prices.finalPrice.amount;\n                prices.prices.finalPrice = {'amount': this.getPrice('price') - originalPrice};\n            }\n\n            if (this.options.prices.basePrice) {\n                originalPrice = this.options.prices.basePrice.amount;\n                prices.prices.basePrice = {'amount': this.getPrice('basePrice') - originalPrice};\n            }\n\n            this.updatePrice(prices);\n        },\n\n        /**\n         * Returns price.\n         *\n         * @param {String} priceKey\n         * @returns {Number}\n         */\n        getPrice: function (priceKey) {\n            var productQty = $(this.qtyInfo).val(),\n                result,\n                tierPriceItem,\n                i;\n\n            for (i = 0; i < this.options.priceConfig.tierPrices.length; i++) {\n                tierPriceItem = this.options.priceConfig.tierPrices[i];\n                if (productQty >= tierPriceItem.qty && tierPriceItem[priceKey]) {\n                    result = tierPriceItem[priceKey];\n                }\n            }\n\n            return result;\n        }\n    });\n\n    return $.mage.priceBox;\n});\n","Magento_Catalog/js/price-option-file.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.priceOptionFile', {\n        options: {\n            fileName: '',\n            fileNamed: '',\n            fieldNameAction: '',\n            changeFileSelector: '',\n            deleteFileSelector: ''\n        },\n\n        /**\n         * Creates instance of widget\n         * @private\n         */\n        _create: function () {\n            this.fileDeleteFlag = this.fileChangeFlag = false;\n            this.inputField = this.element.find('input[name=' + this.options.fileName + ']')[0];\n            this.inputFieldAction = this.element.find('input[name=' + this.options.fieldNameAction + ']')[0];\n            this.fileNameSpan = this.element.parent('dd').find('.' + this.options.fileNamed);\n\n            $(this.options.changeFileSelector).on('click', $.proxy(function () {\n                this._toggleFileChange();\n            }, this));\n            $(this.options.deleteFileSelector).on('click', $.proxy(function () {\n                this._toggleFileDelete();\n            }, this));\n        },\n\n        /**\n         * Toggles whether the current file is being changed or not. If the file is being deleted\n         * then the option to change the file is disabled.\n         * @private\n         */\n        _toggleFileChange: function () {\n            this.element.toggle();\n            this.fileChangeFlag = !this.fileChangeFlag;\n\n            if (!this.fileDeleteFlag) {\n                $(this.inputFieldAction).attr('value', this.fileChangeFlag ? 'save_new' : 'save_old');\n                this.inputField.disabled = !this.fileChangeFlag;\n            }\n        },\n\n        /**\n         * Toggles whether the file is to be deleted. When the file is being deleted, the name of\n         * the file is decorated with strike-through text and the option to change the file is\n         * disabled.\n         * @private\n         */\n        _toggleFileDelete: function () {\n            this.fileDeleteFlag = $(this.options.deleteFileSelector + ':checked').val();\n            $(this.inputFieldAction).attr('value',\n                this.fileDeleteFlag ? '' : this.fileChangeFlag ? 'save_new' : 'save_old');\n            this.inputField.disabled = this.fileDeleteFlag || !this.fileChangeFlag;\n            this.fileNameSpan.css('text-decoration', this.fileDeleteFlag ? 'line-through' : 'none');\n        }\n    });\n\n    return $.mage.priceOptionFile;\n});\n","Magento_Catalog/js/validate-product.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'mage/mage',\n    'Magento_Catalog/product/view/validation',\n    'catalogAddToCart'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.productValidate', {\n        options: {\n            bindSubmit: false,\n            radioCheckboxClosest: '.nested',\n            addToCartButtonSelector: '.action.tocart'\n        },\n\n        /**\n         * Uses Magento's validation widget for the form object.\n         * @private\n         */\n        _create: function () {\n            var bindSubmit = this.options.bindSubmit;\n\n            this.element.validation({\n                radioCheckboxClosest: this.options.radioCheckboxClosest,\n\n                /**\n                 * Uses catalogAddToCart widget as submit handler.\n                 * @param {Object} form\n                 * @returns {Boolean}\n                 */\n                submitHandler: function (form) {\n                    var jqForm = $(form).catalogAddToCart({\n                        bindSubmit: bindSubmit\n                    });\n\n                    jqForm.catalogAddToCart('submitForm', jqForm);\n\n                    return false;\n                }\n            });\n            $(this.options.addToCartButtonSelector).attr('disabled', false);\n        }\n    });\n\n    return $.mage.productValidate;\n});\n","Magento_Catalog/js/price-option-date.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'priceUtils',\n    'priceOptions',\n    'jquery-ui-modules/widget'\n], function ($, utils) {\n    'use strict';\n\n    var globalOptions = {\n            fromSelector: 'form',\n            dropdownsSelector: '[data-role=calendar-dropdown]'\n        },\n        optionHandler = {};\n\n    optionHandler.optionHandlers = {};\n\n    /**\n     * Custom handler for Date-with-Dropdowns option type.\n     * @param  {jQuery} siblings\n     * @return {Function} function that return object { optionHash : optionAdditionalPrice }\n     */\n    function onCalendarDropdownChange(siblings) {\n        return function (element, optionConfig) {\n            var changes = {},\n                optionId = utils.findOptionId(element),\n                overhead = optionConfig[optionId].prices,\n                isNeedToUpdate = true,\n                optionHash = 'price-option-calendar-' + optionId;\n\n            siblings.each(function (index, el) {\n                isNeedToUpdate = isNeedToUpdate && !!$(el).val();\n            });\n\n            overhead = isNeedToUpdate ? overhead : {};\n            changes[optionHash] = overhead;\n\n            return changes;\n        };\n    }\n\n    /**\n     * Returns number of days for special month and year\n     * @param  {Number} month\n     * @param  {Number} year\n     * @return {Number}\n     */\n    function getDaysInMonth(month, year) {\n        return new Date(year, month, 0).getDate();\n    }\n\n    /**\n     * Adjusts the number of days in the day option element based on which month or year\n     * is selected (changed). Adjusts the days to 28, 29, 30, or 31 typically.\n     * @param {jQuery} dropdowns\n     */\n    function onDateChange(dropdowns) {\n        var daysNodes,\n            curMonth, curYear, expectedDays,\n            options, needed,\n            month = dropdowns.filter('[data-calendar-role=month]'),\n            year = dropdowns.filter('[data-calendar-role=year]');\n\n        if (month.length && year.length) {\n            daysNodes = dropdowns.filter('[data-calendar-role=day]').find('option');\n\n            curMonth = month.val() || '01';\n            curYear = year.val() || '2000';\n            expectedDays = getDaysInMonth(curMonth, curYear);\n\n            if (daysNodes.length - 1 > expectedDays) { // remove unnecessary option nodes\n                daysNodes.each(function (i, e) {\n                    if (e.value > expectedDays) {\n                        $(e).remove();\n                    }\n                });\n            } else if (daysNodes.length - 1 < expectedDays) { // add missing option nodes\n                options = [];\n                needed = expectedDays - daysNodes.length + 1;\n\n                while (needed--) { //eslint-disable-line max-depth\n                    options.push(\n                        '<option value=\"' + (expectedDays - needed) + '\">' + (expectedDays - needed) + '</option>'\n                    );\n                }\n                $(options.join('')).insertAfter(daysNodes.last());\n            }\n        }\n    }\n\n    $.widget('mage.priceOptionDate', {\n        options: globalOptions,\n\n        /**\n         * Function-initializer of priceOptionDate widget\n         * @private\n         */\n        _create: function initOptionDate() {\n            var field = this.element,\n                form = field.closest(this.options.fromSelector),\n                dropdowns = $(this.options.dropdownsSelector, field),\n                dateOptionId;\n\n            if (dropdowns.length) {\n                dateOptionId = this.options.dropdownsSelector + dropdowns.attr('name');\n\n                optionHandler.optionHandlers[dateOptionId] = onCalendarDropdownChange(dropdowns);\n\n                form.priceOptions(optionHandler);\n\n                dropdowns.data('role', dateOptionId);\n                dropdowns.on('change', onDateChange.bind(this, dropdowns));\n            }\n        }\n    });\n\n    return $.mage.priceOptionDate;\n});\n","Magento_Catalog/js/upsell-products.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.upsellProducts', {\n        options: {\n            elementsSelector: '.item.product'\n        },\n\n        /**\n         * Bind events to the appropriate handlers.\n         * @private\n         */\n        _create: function () {\n            if (this.element.data('shuffle')) {\n                this._shuffle(this.element.find(this.options.elementsSelector));\n            }\n            this._showUpsellProducts(\n                this.element.find(this.options.elementsSelector),\n                this.element.data('limit'),\n                this.element.data('shuffle-weighted')\n            );\n        },\n\n        /* jscs:disable */\n        /* eslint-disable */\n        /**\n         * Show upsell products according to limit. Shuffle if needed.\n         * @param {*} elements\n         * @param {Number} limit\n         * @param {Boolean} weightedRandom\n         * @private\n         */\n        _showUpsellProducts: function (elements, limit, weightedRandom) {\n            var index, weights = [], random = [], weight = 2, shown = 0, $element, currentGroup, prevGroup;\n\n            if (limit === 0) {\n                limit = elements.length;\n            }\n\n            if (weightedRandom && limit > 0 && limit < elements.length) {\n                for (index = 0; index < limit; index++) {\n                    $element = $(elements[index]);\n                    if ($element.data('shuffle-group') !== '') {\n                        break;\n                    }\n                    $element.show();\n                    shown++;\n                }\n                limit -= shown;\n                for (index = elements.length - 1; index >= 0; index--) {\n                    $element = $(elements[index]);\n                    currentGroup = $element.data('shuffle-group');\n                    if (currentGroup !== '') {\n                        weights.push([index, Math.log(weight)]);\n                        if (typeof prevGroup !== 'undefined' && prevGroup !== currentGroup) {\n                            weight += 2;\n                        }\n                        prevGroup = currentGroup;\n                    }\n                }\n\n                if (weights.length === 0) {\n                    return;\n                }\n\n                for (index = 0; index < weights.length; index++) {\n                    random.push([weights[index][0], Math.pow(Math.random(), 1 / weights[index][1])]);\n                }\n\n                random.sort(function(a, b) {\n                    a = a[1];\n                    b = b[1];\n                    return a < b ? 1 : (a > b ? -1 : 0);\n                });\n                index = 0;\n                while (limit) {\n                    $(elements[random[index][0]]).show();\n                    limit--;\n                    index++\n                }\n                return;\n            }\n\n            for (index = 0; index < limit; index++) {\n                $(elements[index]).show();\n            }\n        },\n\n        /* jscs:disable */\n        /* eslint-disable */\n        /**\n         * Shuffle an array\n         * @param elements\n         * @returns {*}\n         */\n        _shuffle: function shuffle(elements){ //v1.0\n            var parent, child, lastSibling;\n            if (elements.length) {\n                parent = $(elements[0]).parent();\n            }\n            while (elements.length) {\n                child = elements.splice(Math.floor(Math.random() *  elements.length), 1)[0];\n                lastSibling = parent.find('[data-shuffle-group=\"' + $(child).data('shuffle-group') + '\"]').last();\n                lastSibling.after(child);\n            }\n        }\n\n        /* jscs:disable */\n        /* eslint:disable */\n    });\n\n    return $.mage.upsellProducts;\n});\n","Magento_Catalog/js/gallery.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.gallery', {\n        options: {\n            minWidth: 300, // Minimum width of the gallery image.\n            widthOffset: 90, // Offset added to the width of the gallery image.\n            heightOffset: 210, // Offset added to the height of the gallery image.\n            closeWindow: 'div.buttons-set a[role=\"close-window\"]' // Selector for closing the gallery popup window.\n        },\n\n        /**\n         * Bind click handler for closing the popup window and resize the popup based on the image size.\n         * @private\n         */\n        _create: function () {\n            $(this.options.closeWindow).on('click', function () {\n                window.close();\n            });\n            this._resizeWindow();\n        },\n\n        /**\n         * Resize the gallery image popup window based on the image's dimensions.\n         * @private\n         */\n        _resizeWindow: function () {\n            var img = this.element,\n                width = img.width() < this.options.minWidth ? this.options.minWidth : img.width();\n\n            window.resizeTo(width + this.options.widthOffset, img.height() + this.options.heightOffset);\n        }\n    });\n\n    return $.mage.gallery;\n});\n","Magento_Catalog/js/related-products.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    'mage/translate'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.relatedProducts', {\n        options: {\n            relatedCheckbox: '.related-checkbox', // Class name for a related product's input checkbox.\n            relatedProductsCheckFlag: false, // Related products checkboxes are initially unchecked.\n            relatedProductsField: '#related-products-field', // Hidden input field that stores related products.\n            selectAllMessage: $.mage.__('select all'),\n            unselectAllMessage: $.mage.__('unselect all'),\n            selectAllLink: '[data-role=\"select-all\"]',\n            elementsSelector: '.item.product'\n        },\n\n        /**\n         * Bind events to the appropriate handlers.\n         * @private\n         */\n        _create: function () {\n            $(this.options.selectAllLink, this.element).on('click', $.proxy(this._selectAllRelated, this));\n            $(this.options.relatedCheckbox, this.element).on('click', $.proxy(this._addRelatedToProduct, this));\n\n            if (this.element.data('shuffle')) {\n                this._shuffle(this.element.find(this.options.elementsSelector));\n            }\n            this._showRelatedProducts(\n                this.element.find(this.options.elementsSelector),\n                this.element.data('limit'),\n                this.element.data('shuffle-weighted')\n            );\n        },\n\n        /**\n         * This method either checks all checkboxes for a product's set of related products (select all)\n         * or unchecks them (unselect all).\n         * @private\n         * @param {jQuery.Event} e - Click event on either the \"select all\" link or the \"unselect all\" link.\n         * @return {Boolean} - Prevent default event action and event propagation.\n         */\n        _selectAllRelated: function (e) {\n            var innerHTML = this.options.relatedProductsCheckFlag ?\n                this.options.selectAllMessage : this.options.unselectAllMessage;\n\n            $(e.target).html(innerHTML);\n            $(this.options.relatedCheckbox + ':visible').attr(\n                'checked',\n                this.options.relatedProductsCheckFlag = !this.options.relatedProductsCheckFlag\n            );\n            this._addRelatedToProduct();\n\n            return false;\n        },\n\n        /**\n         * This method iterates through each checkbox for all related products and collects only those products\n         * whose checkbox has been checked. The selected related products are stored in a hidden input field.\n         * @private\n         */\n        _addRelatedToProduct: function () {\n            $(this.options.relatedProductsField).val(\n                $(this.options.relatedCheckbox + ':checked').map(function () {\n                    return this.value;\n                }).get().join(',')\n            );\n        },\n\n        /* jscs:disable */\n        /* eslint-disable */\n        /**\n         * Show related products according to limit. Shuffle if needed.\n         * @param {*} elements\n         * @param {*} limit\n         * @param weightedRandom\n         * @private\n         */\n        _showRelatedProducts: function (elements, limit, weightedRandom) {\n            var index, weights = [], random = [], weight = 2, shown = 0, $element, currentGroup, prevGroup;\n\n            if (limit === 0) {\n                limit = elements.length;\n            }\n\n            if (weightedRandom && limit > 0 && limit < elements.length) {\n                for (index = 0; index < limit; index++) {\n                    $element = $(elements[index]);\n                    if ($element.data('shuffle-group') !== '') {\n                        break;\n                    }\n                    $element.show();\n                    shown++;\n                }\n                limit -= shown;\n                for (index = elements.length - 1; index >= 0; index--) {\n                    $element = $(elements[index]);\n                    currentGroup = $element.data('shuffle-group');\n                    if (currentGroup !== '') {\n                        weights.push([index, Math.log(weight)]);\n                        if (typeof prevGroup !== 'undefined' && prevGroup !== currentGroup) {\n                            weight += 2;\n                        }\n                        prevGroup = currentGroup;\n                    }\n                }\n\n                if (weights.length === 0) {\n                    return;\n                }\n\n                for (index = 0; index < weights.length; index++) {\n                    random.push([weights[index][0], Math.pow(Math.random(), 1 / weights[index][1])]);\n                }\n\n                random.sort(function(a, b) {\n                    a = a[1];\n                    b = b[1];\n                    return a < b ? 1 : (a > b ? -1 : 0);\n                });\n                index = 0;\n                while (limit) {\n                    $(elements[random[index][0]]).show();\n                    limit--;\n                    index++\n                }\n                return;\n            }\n\n            for (index = 0; index < limit; index++) {\n                $(elements[index]).show();\n            }\n        },\n\n        /* jscs:disable */\n        /* eslint-disable */\n        /**\n         * Shuffle an array\n         * @param {Array} elements\n         * @returns {*}\n         */\n        _shuffle: function shuffle(elements) {\n            var parent, child, lastSibling;\n            if (elements.length) {\n                parent = $(elements[0]).parent();\n            }\n            while (elements.length) {\n                child = elements.splice(Math.floor(Math.random() *  elements.length), 1)[0];\n                lastSibling = parent.find('[data-shuffle-group=\"' + $(child).data('shuffle-group') + '\"]').last();\n                lastSibling.after(child);\n            }\n        }\n\n        /* jscs:disable */\n        /* eslint:disable */\n    });\n\n    return $.mage.relatedProducts;\n});\n","Magento_Catalog/js/list.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.compareList', {\n\n        /** @inheritdoc */\n        _create: function () {\n            var elem = this.element,\n                products = $('thead td', elem),\n                headings;\n\n            if (products.length > this.options.productsInRow) {\n                headings = $('<table></table>')\n                    .addClass('comparison headings data table')\n                    .insertBefore(elem.closest('.container'));\n\n                elem.addClass('scroll');\n\n                $('th', elem).each(function () {\n                    var th = $(this),\n                        thCopy = th.clone();\n\n                    th.animate({\n                        top: '+=0'\n                    }, 50, function () {\n                        var height = th.height();\n\n                        thCopy.css('height', height)\n                            .appendTo(headings)\n                            .wrap('<tr></tr>');\n                    });\n                });\n            }\n\n            $(this.options.windowPrintSelector).on('click', function (e) {\n                e.preventDefault();\n                window.print();\n            });\n        }\n    });\n\n    return $.mage.compareList;\n});\n","Magento_Catalog/js/catalog-add-to-cart.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/translate',\n    'underscore',\n    'Magento_Catalog/js/product/view/product-ids-resolver',\n    'Magento_Catalog/js/product/view/product-info-resolver',\n    'jquery-ui-modules/widget'\n], function ($, $t, _, idsResolver, productInfoResolver) {\n    'use strict';\n\n    $.widget('mage.catalogAddToCart', {\n        options: {\n            processStart: null,\n            processStop: null,\n            bindSubmit: true,\n            minicartSelector: '[data-block=\"minicart\"]',\n            messagesSelector: '[data-placeholder=\"messages\"]',\n            productStatusSelector: '.stock.available',\n            addToCartButtonSelector: '.action.tocart',\n            addToCartButtonDisabledClass: 'disabled',\n            addToCartButtonTextWhileAdding: '',\n            addToCartButtonTextAdded: '',\n            addToCartButtonTextDefault: '',\n            productInfoResolver: productInfoResolver\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            if (this.options.bindSubmit) {\n                this._bindSubmit();\n            }\n            $(this.options.addToCartButtonSelector).prop('disabled', false);\n        },\n\n        /**\n         * @private\n         */\n        _bindSubmit: function () {\n            var self = this;\n\n            if (this.element.data('catalog-addtocart-initialized')) {\n                return;\n            }\n\n            this.element.data('catalog-addtocart-initialized', 1);\n            this.element.on('submit', function (e) {\n                e.preventDefault();\n                self.submitForm($(this));\n            });\n        },\n\n        /**\n         * @private\n         */\n        _redirect: function (url) {\n            var urlParts, locationParts, forceReload;\n\n            urlParts = url.split('#');\n            locationParts = window.location.href.split('#');\n            forceReload = urlParts[0] === locationParts[0];\n\n            window.location.assign(url);\n\n            if (forceReload) {\n                window.location.reload();\n            }\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isLoaderEnabled: function () {\n            return this.options.processStart && this.options.processStop;\n        },\n\n        /**\n         * Handler for the form 'submit' event\n         *\n         * @param {jQuery} form\n         */\n        submitForm: function (form) {\n            this.ajaxSubmit(form);\n        },\n\n        /**\n         * @param {jQuery} form\n         */\n        ajaxSubmit: function (form) {\n            var self = this,\n                productIds = idsResolver(form),\n                productInfo = self.options.productInfoResolver(form),\n                formData;\n\n            $(self.options.minicartSelector).trigger('contentLoading');\n            self.disableAddToCartButton(form);\n            formData = new FormData(form[0]);\n\n            $.ajax({\n                url: form.prop('action'),\n                data: formData,\n                type: 'post',\n                dataType: 'json',\n                cache: false,\n                contentType: false,\n                processData: false,\n\n                /** @inheritdoc */\n                beforeSend: function () {\n                    if (self.isLoaderEnabled()) {\n                        $('body').trigger(self.options.processStart);\n                    }\n                },\n\n                /** @inheritdoc */\n                success: function (res) {\n                    var eventData, parameters;\n\n                    $(document).trigger('ajax:addToCart', {\n                        'sku': form.data().productSku,\n                        'productIds': productIds,\n                        'productInfo': productInfo,\n                        'form': form,\n                        'response': res\n                    });\n\n                    if (self.isLoaderEnabled()) {\n                        $('body').trigger(self.options.processStop);\n                    }\n\n                    if (res.backUrl) {\n                        eventData = {\n                            'form': form,\n                            'redirectParameters': []\n                        };\n                        // trigger global event, so other modules will be able add parameters to redirect url\n                        $('body').trigger('catalogCategoryAddToCartRedirect', eventData);\n\n                        if (eventData.redirectParameters.length > 0 &&\n                            window.location.href.split(/[?#]/)[0] === res.backUrl\n                        ) {\n                            parameters = res.backUrl.split('#');\n                            parameters.push(eventData.redirectParameters.join('&'));\n                            res.backUrl = parameters.join('#');\n                        }\n\n                        self._redirect(res.backUrl);\n\n                        return;\n                    }\n\n                    if (res.messages) {\n                        $(self.options.messagesSelector).html(res.messages);\n                    }\n\n                    if (res.minicart) {\n                        $(self.options.minicartSelector).replaceWith(res.minicart);\n                        $(self.options.minicartSelector).trigger('contentUpdated');\n                    }\n\n                    if (res.product && res.product.statusText) {\n                        $(self.options.productStatusSelector)\n                            .removeClass('available')\n                            .addClass('unavailable')\n                            .find('span')\n                            .html(res.product.statusText);\n                    }\n                    self.enableAddToCartButton(form);\n                },\n\n                /** @inheritdoc */\n                error: function (res) {\n                    $(document).trigger('ajax:addToCart:error', {\n                        'sku': form.data().productSku,\n                        'productIds': productIds,\n                        'productInfo': productInfo,\n                        'form': form,\n                        'response': res\n                    });\n                },\n\n                /** @inheritdoc */\n                complete: function (res) {\n                    if (res.state() === 'rejected') {\n                        location.reload();\n                    }\n                }\n            });\n        },\n\n        /**\n         * @param {String} form\n         */\n        disableAddToCartButton: function (form) {\n            var addToCartButtonTextWhileAdding = this.options.addToCartButtonTextWhileAdding || $t('Adding...'),\n                addToCartButton = $(form).find(this.options.addToCartButtonSelector);\n\n            addToCartButton.addClass(this.options.addToCartButtonDisabledClass);\n            addToCartButton.find('span').text(addToCartButtonTextWhileAdding);\n            addToCartButton.prop('title', addToCartButtonTextWhileAdding);\n        },\n\n        /**\n         * @param {String} form\n         */\n        enableAddToCartButton: function (form) {\n            var addToCartButtonTextAdded = this.options.addToCartButtonTextAdded || $t('Added'),\n                self = this,\n                addToCartButton = $(form).find(this.options.addToCartButtonSelector);\n\n            addToCartButton.find('span').text(addToCartButtonTextAdded);\n            addToCartButton.prop('title', addToCartButtonTextAdded);\n\n            setTimeout(function () {\n                var addToCartButtonTextDefault = self.options.addToCartButtonTextDefault || $t('Add to Cart');\n\n                addToCartButton.removeClass(self.options.addToCartButtonDisabledClass);\n                addToCartButton.find('span').text(addToCartButtonTextDefault);\n                addToCartButton.prop('title', addToCartButtonTextDefault);\n            }, 1000);\n        }\n    });\n\n    return $.mage.catalogAddToCart;\n});\n","Magento_Catalog/js/storage-manager.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'uiElement',\n    'mageUtils',\n    'Magento_Catalog/js/product/storage/storage-service',\n    'Magento_Customer/js/section-config',\n    'jquery'\n], function (_, Element, utils, storage, sectionConfig, $) {\n    'use strict';\n\n    /**\n     * Flush events, that are clones of the same customer data sections\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 && window.localStorage) {\n                _.each(sections, function (section) {\n                    window.localStorage.removeItem(section);\n                });\n            }\n        }\n    });\n\n    return Element.extend({\n        defaults: {\n            defaultNamespace: {\n                lifetime: 1000\n            },\n            storagesConfiguration: {\n                'recently_viewed_product': {\n                    namespace: 'recently_viewed_product',\n                    className: 'IdsStorage',\n                    lifetime: '${ $.defaultNamespace.lifetime }',\n                    requestConfig: {\n                        typeId: '${ $.storagesConfiguration.recently_viewed_product.namespace }'\n                    },\n                    savePrevious: {\n                        namespace: '${ $.storagesConfiguration.recently_viewed_product.namespace }' + '_previous',\n                        className: '${ $.storagesConfiguration.recently_viewed_product.className }'\n                    },\n                    allowToSendRequest: 0\n                },\n                'recently_compared_product': {\n                    namespace: 'recently_compared_product',\n                    className: 'IdsStorageCompare',\n                    provider: 'compare-products',\n                    lifetime: '${ $.defaultNamespace.lifetime }',\n                    requestConfig: {\n                        typeId: '${ $.storagesConfiguration.recently_compared_product.namespace }'\n                    },\n                    savePrevious: {\n                        namespace: '${ $.storagesConfiguration.recently_compared_product.namespace }' + '_previous',\n                        className: '${ $.storagesConfiguration.recently_compared_product.className }'\n                    },\n                    allowToSendRequest: 0\n                },\n                'product_data_storage': {\n                    namespace: 'product_data_storage',\n                    className: 'DataStorage',\n                    allowToSendRequest: 0,\n                    updateRequestConfig: {\n                        url: '',\n                        method: 'GET',\n                        dataType: 'json'\n                    }\n                }\n            },\n            requestConfig: {\n                method: 'POST',\n                dataType: 'json',\n                ajaxSaveType: 'default',\n                ignoreProcessEvents: true\n            },\n            requestSent: 0\n        },\n\n        /**\n         * Initializes provider component.\n         *\n         * @returns {Object} Chainable.\n         */\n        initialize: function () {\n            this._super()\n                .prepareStoragesConfig()\n                .initStorages()\n                .initStartData()\n                .initUpdateStorageDataListener();\n\n            return this;\n        },\n\n        /**\n         * Initializes storages.\n         *\n         * @returns {Object} Chainable.\n         */\n        initStorages: function () {\n            _.each(this.storagesNamespace, function (name) {\n                this[name] = storage.createStorage(this.storagesConfiguration[name]);\n\n                if (this.storagesConfiguration[name].savePrevious) {\n                    this[name].previous = storage.createStorage(this.storagesConfiguration[name].savePrevious);\n                }\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Initializes start data.\n         *\n         * @returns {Object} Chainable.\n         */\n        initStartData: function () {\n            _.each(this.storagesNamespace, function (name) {\n                this.updateDataHandler(name, this[name].get());\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Prepare storages congfig.\n         *\n         * @returns {Object} Chainable.\n         */\n        prepareStoragesConfig: function () {\n            this.storagesNamespace = _.keys(this.storagesConfiguration);\n\n            _.each(this.storagesNamespace, function (name) {\n                this.storagesConfiguration[name].requestConfig = _.extend(\n                    utils.copy(this.requestConfig),\n                    this.storagesConfiguration[name].requestConfig\n                );\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Prepare date in UTC format (in GMT), and calculate unix timestamp based in seconds\n         *\n         * @returns {Number}\n         * @private\n         */\n        getUtcTime: function () {\n            return new Date().getTime() / 1000;\n        },\n\n        /**\n         * Initializes listeners to storages \"data\" property.\n         */\n        initUpdateStorageDataListener: function () {\n            _.each(this.storagesNamespace, function (name) {\n                if (this[name].data) {\n                    this[name].data.subscribe(this.updateDataHandler.bind(this, name));\n                }\n            }.bind(this));\n        },\n\n        /**\n         * Handlers for storages \"data\" property\n         */\n        updateDataHandler: function (name, data) {\n            var previousData = this[name].previous ? this[name].previous.get() : false;\n\n            if (!_.isEmpty(previousData) &&\n                !_.isEmpty(data) &&\n                !utils.compare(data, previousData).equal) {\n                this[name].set(data);\n                this[name].previous.set(data);\n                this.sendRequest(name, data);\n            } else if (\n                _.isEmpty(previousData) &&\n                !_.isEmpty(data)\n            ) {\n                this[name].set(data);\n                this.sendRequest(name, data);\n            }\n        },\n\n        /**\n         * Gets last updated time\n         *\n         * @param {String} name - storage name\n         */\n        getLastUpdate: function (name) {\n            return window.localStorage.getItem(this[name].namespace + '_last_update');\n        },\n\n        /**\n         * Sets last updated time\n         *\n         * @param {String} name - storage name\n         */\n        setLastUpdate: function (name) {\n            window.localStorage.setItem(this[name].namespace + '_last_update', this.getUtcTime());\n        },\n\n        /**\n         * Request handler\n         *\n         * @param {String} name - storage name\n         */\n        requestHandler: function (name) {\n            this.setLastUpdate(name);\n            this.requestSent = 1;\n        },\n\n        /**\n         * Sends request to server to gets data\n         *\n         * @param {String} name - storage name\n         * @param {Object} data - ids\n         */\n        sendRequest: function (name, data) {\n            var params  = utils.copy(this.storagesConfiguration[name].requestConfig),\n                url = params.syncUrl,\n                typeId = params.typeId;\n\n            if (this.requestSent || !~~this.storagesConfiguration[name].allowToSendRequest) {\n                return;\n            }\n\n            delete params.typeId;\n            delete params.url;\n            this.requestSent = 1;\n\n            return utils.ajaxSubmit({\n                url: url,\n                data: {\n                    ids: data,\n                    'type_id': typeId\n                }\n            }, params).done(this.requestHandler.bind(this, name));\n        }\n    });\n});\n","Magento_Catalog/js/price-options.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'underscore',\n    'mage/template',\n    'priceUtils',\n    'priceBox',\n    'jquery-ui-modules/widget'\n], function ($, _, mageTemplate, utils) {\n    'use strict';\n\n    var globalOptions = {\n        productId: null,\n        priceHolderSelector: '.price-box', //data-role=\"priceBox\"\n        optionsSelector: '.product-custom-option',\n        optionConfig: {},\n        optionHandlers: {},\n        optionTemplate: '<%= data.label %>' +\n        '<% if (data.finalPrice.value > 0) { %>' +\n        ' +<%- data.finalPrice.formatted %>' +\n        '<% } else if (data.finalPrice.value < 0) { %>' +\n        ' <%- data.finalPrice.formatted %>' +\n        '<% } %>',\n        controlContainer: 'dd'\n    };\n\n    /**\n     * Custom option preprocessor\n     * @param  {jQuery} element\n     * @param  {Object} optionsConfig - part of config\n     * @return {Object}\n     */\n    function defaultGetOptionValue(element, optionsConfig) {\n        var changes = {},\n            optionValue = element.val(),\n            optionId = utils.findOptionId(element[0]),\n            optionName = element.prop('name'),\n            optionType = element.prop('type'),\n            optionConfig = optionsConfig[optionId],\n            optionHash = optionName;\n\n        switch (optionType) {\n            case 'text':\n            case 'textarea':\n                changes[optionHash] = optionValue ? optionConfig.prices : {};\n                break;\n\n            case 'radio':\n                if (element.is(':checked')) {\n                    changes[optionHash] = optionConfig[optionValue] && optionConfig[optionValue].prices || {};\n                }\n                break;\n\n            case 'select-one':\n                changes[optionHash] = optionConfig[optionValue] && optionConfig[optionValue].prices || {};\n                break;\n\n            case 'select-multiple':\n                _.each(optionConfig, function (row, optionValueCode) {\n                    optionHash = optionName + '##' + optionValueCode;\n                    changes[optionHash] = _.contains(optionValue, optionValueCode) ? row.prices : {};\n                });\n                break;\n\n            case 'checkbox':\n                optionHash = optionName + '##' + optionValue;\n                changes[optionHash] = element.is(':checked') ? optionConfig[optionValue].prices : {};\n                break;\n\n            case 'file':\n                // Checking for 'disable' property equal to checking DOMNode with id*=\"change-\"\n                changes[optionHash] = optionValue || element.prop('disabled') ? optionConfig.prices : {};\n                break;\n        }\n\n        return changes;\n    }\n\n    $.widget('mage.priceOptions', {\n        options: globalOptions,\n\n        /**\n         * @private\n         */\n        _init: function initPriceBundle() {\n            $(this.options.optionsSelector, this.element).trigger('change');\n        },\n\n        /**\n         * Widget creating method.\n         * Triggered once.\n         * @private\n         */\n        _create: function createPriceOptions() {\n            var form = this.element,\n                options = $(this.options.optionsSelector, form),\n                priceBox = $(this.options.priceHolderSelector, $(this.options.optionsSelector).element);\n\n            if (priceBox.data('magePriceBox') &&\n                priceBox.priceBox('option') &&\n                priceBox.priceBox('option').priceConfig\n            ) {\n                if (priceBox.priceBox('option').priceConfig.optionTemplate) {\n                    this._setOption('optionTemplate', priceBox.priceBox('option').priceConfig.optionTemplate);\n                }\n                this._setOption('priceFormat', priceBox.priceBox('option').priceConfig.priceFormat);\n            }\n\n            this._applyOptionNodeFix(options);\n\n            options.on('change', this._onOptionChanged.bind(this));\n        },\n\n        /**\n         * Custom option change-event handler\n         * @param {Event} event\n         * @private\n         */\n        _onOptionChanged: function onOptionChanged(event) {\n            var changes,\n                option = $(event.target),\n                handler = this.options.optionHandlers[option.data('role')];\n\n            option.data('optionContainer', option.closest(this.options.controlContainer));\n\n            if (handler && handler instanceof Function) {\n                changes = handler(option, this.options.optionConfig, this);\n            } else {\n                changes = defaultGetOptionValue(option, this.options.optionConfig);\n            }\n            $(this.options.priceHolderSelector).trigger('updatePrice', changes);\n        },\n\n        /**\n         * Helper to fix issue with option nodes:\n         *  - you can't place any html in option ->\n         *    so you can't style it via CSS\n         * @param {jQuery} options\n         * @private\n         */\n        _applyOptionNodeFix: function applyOptionNodeFix(options) {\n            var config = this.options,\n                format = config.priceFormat,\n                template = config.optionTemplate;\n\n            template = mageTemplate(template);\n            options.filter('select').each(function (index, element) {\n                var $element = $(element),\n                    optionId = utils.findOptionId($element),\n                    optionConfig = config.optionConfig && config.optionConfig[optionId];\n\n                $element.find('option').each(function (idx, option) {\n                    var $option,\n                        optionValue,\n                        toTemplate,\n                        prices;\n\n                    $option = $(option);\n                    optionValue = $option.val();\n\n                    if (!optionValue && optionValue !== 0) {\n                        return;\n                    }\n\n                    toTemplate = {\n                        data: {\n                            label: optionConfig[optionValue] && optionConfig[optionValue].name\n                        }\n                    };\n                    prices = optionConfig[optionValue] ? optionConfig[optionValue].prices : null;\n\n                    if (prices) {\n                        _.each(prices, function (price, type) {\n                            var value = +price.amount;\n\n                            value += _.reduce(price.adjustments, function (sum, x) { //eslint-disable-line\n                                return sum + x;\n                            }, 0);\n                            toTemplate.data[type] = {\n                                value: value,\n                                formatted: utils.formatPriceLocale(value, format)\n                            };\n                        });\n\n                        $option.text(template(toTemplate));\n                    }\n                });\n            });\n        },\n\n        /**\n         * Custom behavior on getting options:\n         * now widget able to deep merge accepted configuration with instance options.\n         * @param  {Object}  options\n         * @return {$.Widget}\n         * @private\n         */\n        _setOptions: function setOptions(options) {\n            $.extend(true, this.options, options);\n            this._super(options);\n\n            return this;\n        }\n    });\n\n    return $.mage.priceOptions;\n});\n","Magento_Catalog/js/price-utils.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], function ($, _) {\n    'use strict';\n\n    var globalPriceFormat = {\n        requiredPrecision: 2,\n        integerRequired: 1,\n        decimalSymbol: ',',\n        groupSymbol: ',',\n        groupLength: ','\n    };\n\n    /**\n     * Repeats {string} {times} times\n     * @param  {String} string\n     * @param  {Number} times\n     * @return {String}\n     */\n    function stringPad(string, times) {\n        return new Array(times + 1).join(string);\n    }\n\n    /**\n     * Format the price with the compliance to the specified locale\n     *\n     * @param {Number} amount\n     * @param {Object} format\n     * @param  {Boolean} isShowSign\n     */\n    function formatPriceLocale(amount, format, isShowSign)\n    {\n        var s = '',\n            precision, pattern, locale, r;\n\n        format = _.extend(globalPriceFormat, format);\n        precision = isNaN(format.requiredPrecision = Math.abs(format.requiredPrecision)) ? 2 : format.requiredPrecision;\n        pattern = format.pattern || '%s';\n        locale = window.LOCALE || 'en-US';\n        if (isShowSign === undefined || isShowSign === true) {\n            s = amount < 0 ? '-' : isShowSign ? '+' : '';\n        } else if (isShowSign === false) {\n            s = '';\n        }\n        pattern = pattern.indexOf('{sign}') < 0 ? s + pattern : pattern.replace('{sign}', s);\n        amount = Number(Math.round(Math.abs(+amount || 0) + 'e+' + precision) + ('e-' + precision));\n        r = amount.toLocaleString(locale, {minimumFractionDigits: precision});\n\n        return pattern.replace('%s', r).replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '');\n    }\n\n    /**\n     * Formatter for price amount\n     * @param  {Number}  amount\n     * @param  {Object}  format\n     * @param  {Boolean} isShowSign\n     * @return {String}              Formatted value\n     * @deprecated\n     */\n    function formatPrice(amount, format, isShowSign) {\n        var s = '',\n            precision, integerRequired, decimalSymbol, groupSymbol, groupLength, pattern, i, pad, j, re, r, am;\n\n        format = _.extend(globalPriceFormat, format);\n\n        // copied from price-option.js | Could be refactored with varien/js.js\n\n        precision = isNaN(format.requiredPrecision = Math.abs(format.requiredPrecision)) ? 2 : format.requiredPrecision;\n        integerRequired = isNaN(format.integerRequired = Math.abs(format.integerRequired)) ? 1 : format.integerRequired;\n        decimalSymbol = format.decimalSymbol === undefined ? ',' : format.decimalSymbol;\n        groupSymbol = format.groupSymbol === undefined ? '.' : format.groupSymbol;\n        groupLength = format.groupLength === undefined ? 3 : format.groupLength;\n        pattern = format.pattern || '%s';\n\n        if (isShowSign === undefined || isShowSign === true) {\n            s = amount < 0 ? '-' : isShowSign ? '+' : '';\n        } else if (isShowSign === false) {\n            s = '';\n        }\n        pattern = pattern.indexOf('{sign}') < 0 ? s + pattern : pattern.replace('{sign}', s);\n\n        // we're avoiding the usage of to fixed, and using round instead with the e representation to address\n        // numbers like 1.005 = 1.01. Using ToFixed to only provide trailing zeroes in case we have a whole number\n        i = parseInt(\n                amount = Number(Math.round(Math.abs(+amount || 0) + 'e+' + precision) + ('e-' + precision)),\n                10\n            ) + '';\n        pad = i.length < integerRequired ? integerRequired - i.length : 0;\n\n        i = stringPad('0', pad) + i;\n\n        j = i.length > groupLength ? i.length % groupLength : 0;\n        re = new RegExp('(\\\\d{' + groupLength + '})(?=\\\\d)', 'g');\n\n        // replace(/-/, 0) is only for fixing Safari bug which appears\n        // when Math.abs(0).toFixed() executed on '0' number.\n        // Result is '0.-0' :(\n\n        am = Number(Math.round(Math.abs(amount - i) + 'e+' + precision) + ('e-' + precision));\n        r = (j ? i.substr(0, j) + groupSymbol : '') +\n            i.substr(j).replace(re, '$1' + groupSymbol) +\n            (precision ? decimalSymbol + am.toFixed(precision).replace(/-/, 0).slice(2) : '');\n\n        return pattern.replace('%s', r).replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '');\n    }\n\n    /**\n     * Deep clone of Object. Doesn't support functions\n     * @param {Object} obj\n     * @return {Object}\n     */\n    function objectDeepClone(obj) {\n        return JSON.parse(JSON.stringify(obj));\n    }\n\n    /**\n     * Helper to find ID in name attribute\n     * @param   {jQuery} element\n     * @returns {undefined|String}\n     */\n    function findOptionId(element) {\n        var re, id, name;\n\n        if (!element) {\n            return id;\n        }\n        name = $(element).attr('name');\n\n        if (name.indexOf('[') !== -1) {\n            re = /\\[([^\\]]+)?\\]/;\n        } else {\n            re = /_([^\\]]+)?_/; // just to support file-type-option\n        }\n        id = re.exec(name) && re.exec(name)[1];\n\n        if (id) {\n            return id;\n        }\n    }\n\n    return {\n        formatPriceLocale: formatPriceLocale,\n        formatPrice: formatPrice,\n        deepClone: objectDeepClone,\n        strPad: stringPad,\n        findOptionId: findOptionId\n    };\n});\n","Magento_Catalog/js/product/uenc-processor.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([], function () {\n        'use strict';\n\n        /**\n         * Check data to JSON.\n         *\n         * @returns {Boolean}\n         */\n        function _isJSON(data) {\n            try {\n                JSON.parse(data);\n            } catch (e) {\n                return false;\n            }\n\n            return true;\n        }\n\n        /**\n         * Processes data.\n         *\n         * @param {Object} data\n         * @param {String} placeholder\n         * @param {String} uenc\n         *\n         * @returns {String}\n         */\n        function _stringProcessor(data, placeholder, uenc) {\n            if (data && ~data.indexOf(placeholder)) {\n                return data.replace(placeholder, uenc);\n            }\n\n            return data;\n        }\n\n        /**\n         * Processes data.\n         *\n         * @param {Object} data\n         * @param {String} placeholder\n         * @param {String} uenc\n         *\n         * @returns {String}\n         */\n        function _objectProcessor(data, placeholder, uenc) {\n            data = JSON.parse(data);\n\n            if (data.hasOwnProperty('action')) {\n                data.action = _stringProcessor(data.action, placeholder, uenc);\n            }\n\n            if (data.hasOwnProperty('data') && data.data.hasOwnProperty('uenc')) {\n                data.data.uenc = uenc;\n            }\n\n            return JSON.stringify(data);\n        }\n\n        /**\n         * Processes data.\n         *\n         * @param {Object} data\n         * @param {String} placeholder\n         *\n         * @returns {String}\n         */\n        return function (data, placeholder) {\n            var uenc = btoa(window.location.href).replace('+/=', '-_,');\n\n            placeholder = placeholder || encodeURI('%uenc%');\n\n            return _isJSON(data) ?\n                _objectProcessor(data, placeholder, uenc) :\n                _stringProcessor(data, placeholder, uenc);\n\n        };\n    }\n);\n","Magento_Catalog/js/product/provider-compared.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    './provider',\n    'Magento_Catalog/js/product/storage/storage-service',\n    'Magento_Customer/js/customer-data'\n], function (_, Provider, storage, customerData) {\n    'use strict';\n\n    return Provider.extend({\n\n        /**\n         * Ids update handler\n         *\n         * @param {Object} data\n         */\n        idsHandler: function (data) {\n            this.productStorage.setIds(this.data.currency, this.data.store, this.dataFilter(data));\n        },\n\n        /**\n         * Filters data by provider\n         *\n         * @param {Object} data\n         *\n         * @returns {Object}\n         */\n        dataFilter: function (data) {\n            var providerData = this.idsStorage.prepareData(customerData.get(this.identifiersConfig.provider)().items),\n                result = {},\n                productCurrentScope,\n                scopeId;\n\n            if (typeof this.data.productCurrentScope !== 'undefined' && window.checkout && window.checkout.baseUrl) {\n                productCurrentScope = this.data.productCurrentScope;\n                scopeId = productCurrentScope === 'store' ? window.checkout.storeId :\n                    productCurrentScope === 'group' ? window.checkout.storeGroupId :\n                        window.checkout.websiteId;\n                _.each(data, function (value, key) {\n                    if (!providerData[productCurrentScope + '-' + scopeId + '-' + key]) {\n                        result[key] = value;\n                    }\n                });\n            } else {\n                _.each(data, function (value, key) {\n                    if (!providerData[key]) {\n                        result[key] = value;\n                    }\n                });\n            }\n\n            return result;\n        },\n\n        /**\n         * Filters data from product storage by ids\n         *\n         * @param {Object} data\n         *\n         * @returns {Object}\n         */\n        filterData: function (data) {\n            var result = {},\n                i = 0,\n                ids = _.keys(this.dataFilter(this.ids())),\n                length = ids.length;\n\n            for (i; i < length; i++) {\n                if (ids[i] && data[ids[i]]) {\n                    result[ids[i]] = data[ids[i]];\n                }\n            }\n\n            return result;\n        }\n    });\n});\n","Magento_Catalog/js/product/addtocompare-button.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\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 (Column, uencProcessor, columnStatusValidator) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            label: ''\n        },\n\n        /**\n         * Prepare Data-Post data that will be used in data-mage-init\n         *\n         * @param {Object} row\n         * @returns {Array}\n         */\n        getDataPost: function (row) {\n            return uencProcessor(row['add_to_compare_button'].url ||\n                    row['add_to_compare_button']['post_data']);\n        },\n\n        /**\n         * Depends on this option, \"Add to compare\" button can be shown or hide. Depends on  backend configuration\n         *\n         * @returns {Boolean}\n         */\n        isAllowed: function () {\n            return columnStatusValidator.isValid(this.source(), 'add_to_compare', '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_Catalog/js/product/breadcrumbs.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Theme/js/model/breadcrumb-list'\n], function ($, breadcrumbList) {\n    'use strict';\n\n    return function (widget) {\n\n        $.widget('mage.breadcrumbs', widget, {\n            options: {\n                categoryUrlSuffix: '',\n                useCategoryPathInUrl: false,\n                product: '',\n                categoryItemSelector: '.category-item',\n                menuContainer: '[data-action=\"navigation\"] > ul'\n            },\n\n            /** @inheritdoc */\n            _render: function () {\n                this._appendCatalogCrumbs();\n                this._super();\n            },\n\n            /**\n             * Append category and product crumbs.\n             *\n             * @private\n             */\n            _appendCatalogCrumbs: function () {\n                var categoryCrumbs = this._resolveCategoryCrumbs();\n\n                categoryCrumbs.forEach(function (crumbInfo) {\n                    breadcrumbList.push(crumbInfo);\n                });\n\n                if (this.options.product) {\n                    breadcrumbList.push(this._getProductCrumb());\n                }\n            },\n\n            /**\n             * Resolve categories crumbs.\n             *\n             * @return Array\n             * @private\n             */\n            _resolveCategoryCrumbs: function () {\n                var menuItem = this._resolveCategoryMenuItem(),\n                    categoryCrumbs = [];\n\n                if (menuItem !== null && menuItem.length) {\n                    categoryCrumbs.unshift(this._getCategoryCrumb(menuItem));\n\n                    while ((menuItem = this._getParentMenuItem(menuItem)) !== null) {\n                        categoryCrumbs.unshift(this._getCategoryCrumb(menuItem));\n                    }\n                }\n\n                return categoryCrumbs;\n            },\n\n            /**\n             * Returns crumb data.\n             *\n             * @param {Object} menuItem\n             * @return {Object}\n             * @private\n             */\n            _getCategoryCrumb: function (menuItem) {\n                return {\n                    'name': 'category',\n                    'label': menuItem.text(),\n                    'link': menuItem.attr('href'),\n                    'title': ''\n                };\n            },\n\n            /**\n             * Returns product crumb.\n             *\n             * @return {Object}\n             * @private\n             */\n            _getProductCrumb: function () {\n                return {\n                    'name': 'product',\n                    'label': this.options.product,\n                    'link': '',\n                    'title': ''\n                };\n            },\n\n            /**\n             * Find parent menu item for current.\n             *\n             * @param {Object} menuItem\n             * @return {Object|null}\n             * @private\n             */\n            _getParentMenuItem: function (menuItem) {\n                var classes,\n                    classNav,\n                    parentClass,\n                    parentMenuItem = null;\n\n                if (!menuItem) {\n                    return null;\n                }\n\n                classes = menuItem.parent().attr('class');\n                classNav = classes.match(/(nav\\-)[0-9]+(\\-[0-9]+)+/gi);\n\n                if (classNav) {\n                    classNav = classNav[0];\n                    parentClass = classNav.substr(0, classNav.lastIndexOf('-'));\n\n                    if (parentClass.lastIndexOf('-') !== -1) {\n                        parentMenuItem = $(this.options.menuContainer).find('.' + parentClass + ' > a');\n                        parentMenuItem = parentMenuItem.length ? parentMenuItem : null;\n                    }\n                }\n\n                return parentMenuItem;\n            },\n\n            /**\n             * Returns category menu item.\n             *\n             * Tries to resolve category from url or from referrer as fallback and\n             * find menu item from navigation menu by category url.\n             *\n             * @return {Object|null}\n             * @private\n             */\n            _resolveCategoryMenuItem: function () {\n                var categoryUrl = this._resolveCategoryUrl(),\n                    menu = $(this.options.menuContainer),\n                    categoryMenuItem = null;\n\n                if (categoryUrl && menu.length) {\n                    categoryMenuItem = menu.find(\n                        this.options.categoryItemSelector +\n                        ' > a[href=\"' + categoryUrl + '\"]'\n                    );\n                }\n\n                return categoryMenuItem;\n            },\n\n            /**\n             * Returns category url.\n             *\n             * @return {String}\n             * @private\n             */\n            _resolveCategoryUrl: function () {\n                var categoryUrl;\n\n                if (this.options.useCategoryPathInUrl) {\n                    // In case category path is used in product url - resolve category url from current url.\n                    categoryUrl = window.location.href.split('?')[0];\n                    categoryUrl = categoryUrl.substring(0, categoryUrl.lastIndexOf('/')) +\n                        this.options.categoryUrlSuffix;\n                } else {\n                    // In other case - try to resolve it from referrer (without parameters).\n                    categoryUrl = document.referrer;\n\n                    if (categoryUrl.indexOf('?') > 0) {\n                        categoryUrl = categoryUrl.substr(0, categoryUrl.indexOf('?'));\n                    }\n                }\n\n                return categoryUrl;\n            }\n        });\n\n        return $.mage.breadcrumbs;\n    };\n});\n","Magento_Catalog/js/product/provider.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'jquery',\n    'mageUtils',\n    'uiElement',\n    'Magento_Catalog/js/product/storage/storage-service',\n    'Magento_Customer/js/customer-data',\n    'Magento_Catalog/js/product/view/product-ids-resolver'\n], function (_, $, utils, Element, storage, customerData, productResolver) {\n    'use strict';\n\n    return Element.extend({\n        defaults: {\n            identifiersConfig: {\n                namespace: ''\n            },\n            productStorageConfig: {\n                namespace: 'product_data_storage',\n                customerDataProvider: 'product_data_storage',\n                updateRequestConfig: {\n                    url: '',\n                    method: 'GET',\n                    dataType: 'json'\n                },\n                className: 'DataStorage'\n            },\n            ids: {},\n            listens: {\n                ids: 'idsHandler'\n            }\n        },\n\n        /**\n         * Initializes provider component.\n         *\n         * @returns {Provider} Chainable.\n         */\n        initialize: function () {\n            this._super()\n                .initIdsStorage();\n\n            return this;\n        },\n\n        /**\n         * Calls 'initObservable' of parent\n         *\n         * @returns {Object} Chainable.\n         */\n        initObservable: function () {\n            this._super();\n            this.observe('ids');\n\n            return this;\n        },\n\n        /**\n         * Initializes ids storage.\n         *\n         * @returns {Provider} Chainable.\n         */\n        initIdsStorage: function () {\n            storage.onStorageInit(this.identifiersConfig.namespace, this.idsStorageHandler.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Initializes ids storage handler.\n         *\n         * @param {Object} idsStorage\n         */\n        idsStorageHandler: function (idsStorage) {\n            this.idsStorage = idsStorage;\n            this.productStorage = storage.createStorage(this.productStorageConfig);\n            this.productStorage.data.subscribe(this.dataCollectionHandler.bind(this));\n\n            if (~~this.idsStorage.allowToSendRequest) {\n                customerData.reload([idsStorage.namespace]).done(this._resolveDataByIds.bind(this));\n            } else {\n                this._resolveDataByIds();\n            }\n        },\n\n        /**\n         * Callback, which load by ids from ids-storage product data\n         *\n         * @private\n         */\n        _resolveDataByIds: function () {\n            if (!window.checkout || !window.checkout.baseUrl) {\n                // We need data that the minicart provdes to determine storeId/websiteId\n                return;\n            }\n\n            this.initIdsListener();\n            this.idsMerger(\n                this.idsStorage.get(),\n                this.prepareDataFromCustomerData(customerData.get(this.identifiersConfig.namespace)())\n            );\n\n            if (!_.isEmpty(this.productStorage.data())) {\n                this.dataCollectionHandler(this.productStorage.data());\n            } else {\n                this.productStorage.setIds(this.data.currency, this.data.store, this.ids());\n            }\n        },\n\n        /**\n         * Init ids storage listener.\n         */\n        initIdsListener: function () {\n            customerData.get(this.identifiersConfig.namespace).subscribe(function (data) {\n                this.idsMerger(this.prepareDataFromCustomerData(data));\n            }.bind(this));\n            this.idsStorage.data.subscribe(this.idsMerger.bind(this));\n        },\n\n        /**\n         * Prepare data from customerData.\n         *\n         * @param {Object} data\n         *\n         * @returns {Object}\n         */\n        prepareDataFromCustomerData: function (data) {\n            data = data.items ? data.items : data;\n\n            return data;\n        },\n\n        /**\n         * Filter ids by their lifetime in order to show only hot ids :)\n         *\n         * @param {Object} ids\n         * @returns {Array}\n         */\n        filterIds: function (ids) {\n            var _ids = {},\n                currentTime = new Date().getTime() / 1000,\n                currentProductIds = productResolver($('#product_addtocart_form')),\n                productCurrentScope = this.data.productCurrentScope,\n                scopeId = productCurrentScope === 'store' ? window.checkout.storeId :\n                productCurrentScope === 'group' ? window.checkout.storeGroupId :\n                    window.checkout.websiteId;\n\n            _.each(ids, function (id, key) {\n                if (\n                    currentTime - ids[key]['added_at'] < ~~this.idsStorage.lifetime &&\n                    !_.contains(currentProductIds, ids[key]['product_id']) &&\n                    (!id.hasOwnProperty('scope_id') || ids[key]['scope_id'] === scopeId)\n                ) {\n                    _ids[id['product_id']] = id;\n\n                }\n            }, this);\n\n            return _ids;\n        },\n\n        /**\n         * Merges id from storage and customer data\n         *\n         * @param {Object} data\n         * @param {Object} optionalData\n         */\n        idsMerger: function (data, optionalData) {\n            if (data && optionalData) {\n                data = _.extend(data, optionalData);\n            }\n\n            if (!_.isEmpty(data)) {\n                this.ids(\n                    this.filterIds(_.extend(this.ids(), data))\n                );\n            }\n        },\n\n        /**\n         * Ids update handler\n         *\n         * @param {Object} data\n         */\n        idsHandler: function (data) {\n            this.productStorage.setIds(this.data.currency, this.data.store, data);\n        },\n\n        /**\n         * Process data\n         *\n         * @param {Object} data\n         */\n        processData: function (data) {\n            var curData = utils.copy(this.data),\n                ids = this.ids();\n\n            delete data['data_id'];\n            data = _.values(data);\n\n            _.each(data, function (record, index) {\n                record._rowIndex = index;\n                record['added_at'] = ids[record.id]['added_at'];\n            }, this);\n\n            curData.items = data;\n            this.set('data', curData);\n        },\n\n        /**\n         * Product storage data handler\n         *\n         * @param {Object} data\n         */\n        dataCollectionHandler: function (data) {\n            data = this.filterData(data);\n            this.processData(data);\n        },\n\n        /**\n         * Filters data from product storage by ids\n         *\n         * @param {Object} data\n         *\n         * @returns {Object}\n         */\n        filterData: function (data) {\n            var result = {},\n                i = 0,\n                ids = _.keys(this.ids()),\n                length = ids.length;\n\n            for (i; i < length; i++) {\n                if (ids[i] && data[ids[i]]) {\n                    result[ids[i]] = data[ids[i]];\n                }\n            }\n\n            return result;\n        }\n    });\n});\n","Magento_Catalog/js/product/name.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/list/column-status-validator',\n    'escaper'\n], function (Column, columnStatusValidator, escaper) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            allowedTags: ['div', 'span', 'b', 'strong', 'i', 'em', 'u', 'a']\n        },\n\n        /**\n         * Depends on this option, product name can be shown or hide. Depends on  backend configuration\n         *\n         * @returns {Boolean}\n         */\n        isAllowed: function () {\n            return columnStatusValidator.isValid(this.source(), 'name', 'show_attributes');\n        },\n\n        /**\n         * Name column.\n         *\n         * @param {String} label\n         * @returns {String}\n         */\n        getNameUnsanitizedHtml: function (label) {\n            return escaper.escapeHtml(label, this.allowedTags);\n        }\n    });\n});\n","Magento_Catalog/js/product/addtocart-button.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\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         * Prepare data, that will be inserted as data-mage-init attribute into button. With help of this attribute\n         * Add To * buttons can understand post data and urls\n         *\n         * @param {Object} row\n         * @returns {String}\n         */\n        getDataMageInit: function (row) {\n            return '{\"redirectUrl\": { \"url\" : \"'  + uencProcessor(row['add_to_cart_button'].url) + '\"}}';\n        },\n\n        /**\n         * Prepare Data-Post data that will be used in data-mage-init\n         *\n         * @param {Object} row\n         * @return {String}\n         */\n        getDataPost: function (row) {\n            return uencProcessor(row['add_to_cart_button']['post_data']);\n        },\n\n        /**\n         * Check if product has required options.\n         *\n         * @param {Object} row\n         * @return {Boolean}\n         */\n        hasRequiredOptions: function (row) {\n            return row['add_to_cart_button']['required_options'];\n        },\n\n        /**\n         * Depends on this option, \"Add to cart\" button can be shown or hide\n         *\n         * @param {Object} row\n         * @returns {Boolean}\n         */\n        isSalable: function (row) {\n            return row['is_salable'];\n        },\n\n        /**\n         * Depends on this option, stock status text can be \"In stock\" or \"Out Of Stock\"\n         *\n         * @param {Object} row\n         * @returns {Boolean}\n         */\n        isAvailable: function (row) {\n            return row['is_available'];\n        },\n\n        /**\n         * Depends on this option, \"Add to cart\" button can be shown or hide. Depends on  backend configuration\n         *\n         * @returns {Boolean}\n         */\n        isAllowed: function () {\n            return columnStatusValidator.isValid(this.source(), 'add_to_cart', '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_Catalog/js/product/learn-more.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'Magento_Ui/js/grid/columns/column',\n    'Magento_Catalog/js/product/list/column-status-validator'\n], function (Column, columnStatusValidator) {\n    'use strict';\n\n    return Column.extend({\n        /**\n         * Depends on this option, \"Learn More\" link can be shown or hide. Depends on  backend configuration\n         *\n         * @returns {Boolean}\n         */\n        isAllowed: function () {\n            return columnStatusValidator.isValid(this.source(), 'learn_more', 'show_attributes');\n        }\n    });\n});\n","Magento_Catalog/js/product/query-builder.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n        'underscore'\n    ], function (_) {\n        'use strict';\n\n        return {\n\n            /**\n             * Build query to get id\n             *\n             * @param {Object} data\n             */\n            buildQuery: function (data) {\n                var filters = [];\n\n                _.each(data, function (value, key) {\n                    filters.push({\n                        field: key,\n                        value: value,\n                        'condition_type': 'in'\n                    });\n                });\n\n                return {\n                    searchCriteria: {\n                        filterGroups: [\n                            {\n                                filters: filters\n                            }\n                        ]\n                    }\n                };\n            }\n        };\n    }\n);\n","Magento_Catalog/js/product/remaining-characters.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/translate',\n    'jquery-ui-modules/widget'\n], function ($, $t) {\n    'use strict';\n\n    $.widget('mage.remainingCharacters', {\n        options: {\n            remainingText: $t('remaining'),\n            tooManyText: $t('too many'),\n            errorClass: 'mage-error',\n            noDisplayClass: 'no-display'\n        },\n\n        /**\n         * Initializes custom option component\n         *\n         * @private\n         */\n        _create: function () {\n            this.note = $(this.options.noteSelector);\n            this.counter = $(this.options.counterSelector);\n\n            this.updateCharacterCount();\n            this.element.on('change keyup paste', this.updateCharacterCount.bind(this));\n        },\n\n        /**\n         * Updates counter message\n         */\n        updateCharacterCount: function () {\n            var length = this.element.val().length,\n                diff = this.options.maxLength - length;\n\n            this.counter.text(this._formatMessage(diff));\n            this.counter.toggleClass(this.options.noDisplayClass, length === 0);\n            this.note.toggleClass(this.options.errorClass, diff < 0);\n        },\n\n        /**\n         * Format remaining characters message\n         *\n         * @param {int} diff\n         * @returns {String}\n         * @private\n         */\n        _formatMessage: function (diff) {\n            var count = Math.abs(diff),\n                qualifier = diff < 0 ? this.options.tooManyText : this.options.remainingText;\n\n            return '(' + count + ' ' + qualifier + ')';\n        }\n    });\n\n    return $.mage.remainingCharacters;\n});\n","Magento_Catalog/js/product/view/product-ids.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko'\n], function (ko) {\n    'use strict';\n\n    return ko.observableArray([]);\n});\n","Magento_Catalog/js/product/view/product-ids-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-ids'\n], function (_, productIds) {\n    'use strict';\n\n    /**\n     * Returns id's of products in form.\n     *\n     * @param {jQuery} $form\n     * @return {Array}\n     */\n    return function ($form) {\n        var idSet = productIds(),\n            product = _.findWhere($form.serializeArray(), {\n            name: 'product'\n        });\n\n        if (!_.isUndefined(product)) {\n            idSet.push(product.value);\n        }\n\n        return _.uniq(idSet);\n    };\n});\n","Magento_Catalog/js/product/view/product-info.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko'\n], function (ko) {\n    'use strict';\n\n    return ko.observableArray([]);\n});\n","Magento_Catalog/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 products in form.\n     *\n     * @param {jQuery} $form\n     * @return {Array}\n     */\n    return function ($form) {\n        var product = _.findWhere($form.serializeArray(), {\n                name: 'product'\n            });\n\n        if (!_.isUndefined(product)) {\n            productInfo().push(\n                {\n                    'id': product.value\n                }\n            );\n        }\n\n        return _.uniq(productInfo(), function (item) {\n            return item.id;\n        });\n    };\n});\n\n","Magento_Catalog/js/product/view/provider.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'uiElement',\n    'Magento_Catalog/js/product/storage/storage-service'\n], function (_, Element, storage) {\n    'use strict';\n\n    return Element.extend({\n        defaults: {\n            identifiersConfig: {\n                namespace: 'recently_viewed_product'\n            },\n            productStorageConfig: {\n                namespace: 'product_data_storage',\n                updateRequestConfig: {\n                    method: 'GET',\n                    dataType: 'json'\n                },\n                className: 'DataStorage'\n            }\n        },\n\n        /**\n         * Initializes\n         *\n         * @returns {Object} Chainable.\n         */\n        initialize: function () {\n            this._super();\n\n            if (window.checkout && window.checkout.baseUrl) {\n                this.initIdsStorage();\n            }\n\n            this.initDataStorage();\n\n            return this;\n        },\n\n        /**\n         * Init ids storage\n         *\n         * @returns {Object} Chainable.\n         */\n        initIdsStorage: function () {\n            storage.onStorageInit(this.identifiersConfig.namespace, this.idsStorageHandler.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Init data storage\n         *\n         * @returns {Object} Chainable.\n         */\n        initDataStorage: function () {\n            storage.onStorageInit(this.productStorageConfig.namespace, this.dataStorageHandler.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Init data storage handler\n         *\n         * @param {Object} dataStorage - storage instance\n         */\n        dataStorageHandler: function (dataStorage) {\n            this.productStorage = dataStorage;\n            this.productStorage.add(this.data.items);\n        },\n\n        /**\n         * Init ids storage handler\n         *\n         * @param {Object} idsStorage - storage instance\n         */\n        idsStorageHandler: function (idsStorage) {\n            this.idsStorage = idsStorage;\n            this.idsStorage.add(this.getIdentifiers());\n        },\n\n        /**\n         * Gets ids from items\n         *\n         * @returns {Object}\n         */\n        getIdentifiers: function () {\n            var result = {},\n                productCurrentScope = this.data.productCurrentScope,\n                scopeId = productCurrentScope === 'store' ? window.checkout.storeId :\n                    productCurrentScope === 'group' ? window.checkout.storeGroupId :\n                        window.checkout.websiteId;\n\n            _.each(this.data.items, function (item, key) {\n                result[productCurrentScope + '-' + scopeId + '-' + key] = {\n                    'added_at': new Date().getTime() / 1000,\n                    'product_id': key,\n                    'scope_id': scopeId\n                };\n            }, this);\n\n            return result;\n        }\n    });\n});\n","Magento_Catalog/js/product/storage/data-storage.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'underscore',\n    'ko',\n    'mageUtils',\n    'Magento_Catalog/js/product/query-builder',\n    'Magento_Customer/js/customer-data',\n    'jquery/jquery-storageapi'\n], function ($, _, ko, utils, queryBuilder, customerData) {\n    'use strict';\n\n    /**\n     * Process data from API request\n     *\n     * @param {Object} data\n     * @returns {Object}\n     */\n    function getParsedDataFromServer(data) {\n        var result = {};\n\n        _.each(data.items, function (item) {\n                if (item.id) {\n                    result[item.id] = item;\n                }\n            }\n        );\n\n        return {\n            items: result\n        };\n    }\n\n    /**\n     * Set data to localStorage with support check.\n     *\n     * @param {String} namespace\n     * @param {Object} data\n     */\n    function setLocalStorageItem(namespace, data) {\n        try {\n            window.localStorage.setItem(namespace, JSON.stringify(data));\n        } catch (e) {\n            console.warn('localStorage is unavailable - skipping local caching of product data');\n            console.error(e);\n        }\n    }\n\n    return {\n\n        /**\n         * Class name\n         */\n        name: 'DataStorage',\n        request: {},\n        customerDataProvider: 'product_data_storage',\n\n        /**\n         * Initialize class\n         *\n         * @return Chainable.\n         */\n        initialize: function () {\n            if (!this.data) {\n                this.data = ko.observable({});\n            }\n\n            this.initLocalStorage()\n                .initCustomerDataReloadListener()\n                .cachesDataFromLocalStorage()\n                .initDataListener()\n                .initProvideStorage()\n                .initProviderListener();\n\n            return this;\n        },\n\n        /**\n         * Initialize listener to customer data reload\n         *\n         * @return Chainable.\n         */\n        initCustomerDataReloadListener: function () {\n            $(document).on('customer-data-invalidate', this._flushProductStorage.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Flush product storage\n         *\n         * @private\n         * @return void\n         */\n        _flushProductStorage: function (event, sections) {\n            if (_.isEmpty(sections) || _.contains(sections, 'product_data_storage')) {\n                this.localStorage.removeAll();\n            }\n        },\n\n        /**\n         * Initialize listener to data property\n         *\n         * @return Chainable.\n         */\n        initDataListener: function () {\n            this.data.subscribe(this.dataHandler.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Initialize provider storage\n         *\n         * @return Chainable.\n         */\n        initProvideStorage: function () {\n            this.providerHandler(customerData.get(this.customerDataProvider)());\n\n            return this;\n        },\n\n        /**\n         * Handler to update \"data\" property.\n         * Sets data to localStorage\n         *\n         * @param {Object} data\n         */\n        dataHandler: function (data) {\n            if (_.isEmpty(data)) {\n                this.localStorage.removeAll();\n            } else {\n                setLocalStorageItem(this.namespace, data);\n            }\n        },\n\n        /**\n         * Handler to update data in provider.\n         *\n         * @param {Object} data\n         */\n        providerHandler: function (data) {\n            var currentData = utils.copy(this.data()),\n                ids = _.keys(data.items);\n\n            if (data.items && ids.length) {\n                //we can extend only items\n                data = data.items;\n                this.data(_.extend(data, currentData));\n            }\n        },\n\n        /**\n         * Sets data ids\n         *\n         * @param {String} currency\n         * @param {String} store\n         * @param {Object} ids\n         */\n        setIds: function (currency, store, ids) {\n            if (!this.hasInCache(currency, store, ids)) {\n                this.loadDataFromServer(currency, store, ids);\n            } else {\n                this.data.valueHasMutated();\n            }\n        },\n\n        /**\n         * Gets data from \"data\" property by identifiers\n         *\n         * @param {String} currency\n         * @param {String} store\n         * @param {Object} productIdentifiers\n         *\n         * @return {Object} data.\n         */\n        getDataByIdentifiers: function (currency, store, productIdentifiers) {\n            var data = {},\n                dataCollection = this.data(),\n                id;\n\n            for (id in productIdentifiers) {\n                if (productIdentifiers.hasOwnProperty(id)) {\n                    data[id] = dataCollection[id];\n                }\n            }\n\n            return data;\n        },\n\n        /**\n         * Checks has cached data or not\n         *\n         * @param {String} currency\n         * @param {String} store\n         * @param {Object} ids\n         *\n         * @return {Boolean}\n         */\n        hasInCache: function (currency, store, ids) {\n            var data = this.data(),\n                id;\n\n            for (id in ids) {\n                if (!data.hasOwnProperty(id) ||\n                    data[id]['currency_code'] !== currency ||\n                    ~~data[id]['store_id'] !== ~~store\n                ) {\n                    return false;\n                }\n            }\n\n            return true;\n        },\n\n        /**\n         * Load data from server by ids\n         *\n         * @param {String} currency\n         * @param {String} store\n         * @param {Object} ids\n         *\n         * @return void\n         */\n        loadDataFromServer: function (currency, store, ids) {\n            var idsArray = _.keys(ids),\n                prepareAjaxParams = {\n                    'entity_id': idsArray.join(',')\n                };\n\n            if (this.request.sent && this.hasIdsInSentRequest(ids)) {\n                return;\n            }\n\n            this.request = {\n                sent: true,\n                data: ids\n            };\n\n            this.updateRequestConfig.data = queryBuilder.buildQuery(prepareAjaxParams);\n            this.updateRequestConfig.data['store_id'] = store;\n            this.updateRequestConfig.data['currency_code'] = currency;\n            $.ajax(this.updateRequestConfig).done(function (data) {\n                this.request = {};\n                this.providerHandler(getParsedDataFromServer(data));\n            }.bind(this));\n        },\n\n        /**\n         * Each product page consist product cache data,\n         * this function prepare those data to appropriate view, and save it\n         *\n         * @param {Object} data\n         */\n        addDataFromPageCache: function (data) {\n            this.providerHandler(getParsedDataFromServer(data));\n        },\n\n        /**\n         * @param {Object} ids\n         * @returns {Boolean}\n         */\n        hasIdsInSentRequest: function (ids) {\n            var sentDataIds,\n                currentDataIds;\n\n            if (this.request.data) {\n                sentDataIds = _.keys(this.request.data);\n                currentDataIds = _.keys(ids);\n\n                _.each(currentDataIds, function (id) {\n                    if (_.lastIndexOf(sentDataIds, id) === -1) {\n                        return false;\n                    }\n                });\n\n                return true;\n            }\n\n            return false;\n        },\n\n        /**\n         * Initialize provider listener\n         *\n         * @return Chainable.\n         */\n        initProviderListener: function () {\n            customerData.get(this.customerDataProvider).subscribe(this.providerHandler.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Caches data from local storage to local scope\n         *\n         * @return Chainable.\n         */\n        cachesDataFromLocalStorage: function () {\n            this.data(this.getDataFromLocalStorage());\n\n            return this;\n        },\n\n        /**\n         * Gets data from local storage by current namespace\n         *\n         * @return {Object}.\n         */\n        getDataFromLocalStorage: function () {\n            return this.localStorage.get();\n        },\n\n        /**\n         * Initialize localStorage\n         *\n         * @return Chainable.\n         */\n        initLocalStorage: function () {\n            this.localStorage = $.initNamespaceStorage(this.namespace).localStorage;\n\n            return this;\n        }\n    };\n});\n","Magento_Catalog/js/product/storage/ids-storage.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'underscore',\n    'ko',\n    'mageUtils',\n    'jquery/jquery-storageapi'\n], function ($, _, ko, utils) {\n    'use strict';\n\n    /**\n     * Set data to localStorage with support check.\n     *\n     * @param {String} namespace\n     * @param {Object} data\n     */\n    function setLocalStorageItem(namespace, data) {\n        try {\n            window.localStorage.setItem(namespace, JSON.stringify(data));\n        } catch (e) {\n            console.warn('localStorage is unavailable - skipping local caching of product data');\n            console.error(e);\n        }\n    }\n\n    return {\n\n        /**\n         * Class name\n         */\n        name: 'IdsStorage',\n\n        /**\n         * Initializes class\n         *\n         * @return Chainable.\n         */\n        initialize: function () {\n            if (!this.data) {\n                this.data = ko.observable({});\n            }\n\n            this.initCustomerDataReloadListener()\n                .initLocalStorage()\n                .cachesDataFromLocalStorage()\n                .initDataListener();\n\n            return this;\n        },\n\n        /**\n         * Gets data from local storage by current namespace\n         *\n         * @return {Object}.\n         */\n        getDataFromLocalStorage: function () {\n            return this.localStorage.get();\n        },\n\n        /**\n         * Caches data from local storage to local scope\n         *\n         * @return Chainable.\n         */\n        cachesDataFromLocalStorage: function () {\n            this.data(this.getDataFromLocalStorage());\n\n            return this;\n        },\n\n        /**\n         * Initialize localStorage\n         *\n         * @return Chainable.\n         */\n        initLocalStorage: function () {\n            this.localStorage = $.initNamespaceStorage(this.namespace).localStorage;\n\n            return this;\n        },\n\n        /**\n         * Initializes listener to \"data\" property\n         */\n        initDataListener: function () {\n            this.data.subscribe(this.internalDataHandler.bind(this));\n        },\n\n        /**\n         * Initialize listener to customer data reload\n         *\n         * @return Chainable.\n         */\n        initCustomerDataReloadListener: function () {\n            $(document).on('customer-data-reload', function (event, sections) {\n                if ((_.isEmpty(sections) || _.contains(sections, this.namespace)) && ~~this.allowToSendRequest) {\n                    this.localStorage.removeAll();\n                    this.data();\n                }\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Initializes handler to \"data\" property update\n         */\n        internalDataHandler: function (data) {\n            setLocalStorageItem(this.namespace, data);\n        },\n\n        /**\n         * Initializes handler to storage update\n         */\n        externalDataHandler: function (data) {\n            data = data.items ? data.items : data;\n\n            this.set(_.extend(utils.copy(this.data()), data));\n        }\n    };\n});\n\n","Magento_Catalog/js/product/storage/ids-storage-compare.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'ko',\n    'mageUtils',\n    'Magento_Customer/js/customer-data',\n    'Magento_Catalog/js/product/storage/ids-storage'\n], function (_, ko, utils, customerData, idsStorage) {\n    'use strict';\n\n    return _.extend(utils.copy(idsStorage), {\n\n        /**\n         * Class name\n         */\n        name: 'IdsStorageCompare',\n\n        /**\n         * Initializes class\n         *\n         * @return Chainable.\n         */\n        initialize: function () {\n            if (!this.data) {\n                this.data = ko.observable({});\n            }\n\n            if (this.provider && window.checkout && window.checkout.baseUrl) {\n                this.providerDataHandler(customerData.get(this.provider)());\n                this.initProviderListener();\n            }\n\n            this.initLocalStorage()\n                .cachesDataFromLocalStorage()\n                .initDataListener();\n\n            return this;\n        },\n\n        /**\n         * Initializes listener for external data provider\n         */\n        initProviderListener: function () {\n            customerData.get(this.provider).subscribe(this.providerDataHandler.bind(this));\n        },\n\n        /**\n         * Initializes handler for external data provider update\n         *\n         * @param {Object} data\n         */\n        providerDataHandler: function (data) {\n            data = data.items || data;\n            data = this.prepareData(data);\n\n            this.add(data);\n        },\n\n        /**\n         * Prepares data to correct interface\n         *\n         * @param {Object} data\n         *\n         * @returns {Object} data\n         */\n        prepareData: function (data) {\n            var result = {},\n                scopeId;\n\n            _.each(data, function (item) {\n                if (typeof item.productScope !== 'undefined') {\n                    scopeId = item.productScope === 'store' ? window.checkout.storeId :\n                        item.productScope === 'group' ? window.checkout.storeGroupId :\n                            window.checkout.websiteId;\n\n                    result[item.productScope + '-' + scopeId + '-' + item.id] = {\n                        'added_at': new Date().getTime() / 1000,\n                        'product_id': item.id,\n                        'scope_id': scopeId\n                    };\n                } else {\n                    result[item.id] = {\n                        'added_at': new Date().getTime() / 1000,\n                        'product_id': item.id\n                    };\n                }\n            });\n\n            return result;\n        }\n    });\n});\n","Magento_Catalog/js/product/storage/storage-service.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'underscore',\n    'mageUtils',\n    'mage/translate',\n    'Magento_Catalog/js/product/storage/ids-storage',\n    'Magento_Catalog/js/product/storage/data-storage',\n    'Magento_Catalog/js/product/storage/ids-storage-compare'\n], function ($, _, utils, $t, IdsStorage, DataStore, IdsStorageCompare) {\n    'use strict';\n\n    return (function () {\n\n        var /**\n             * {Object} storages - list of storages\n             */\n            storages = {},\n\n            /**\n             * {Object} classes - list of classes\n             */\n            classes = {},\n\n            /**\n             * {Object} prototype - methods that will be added to all storage classes to prototype property.\n             */\n            prototype = {\n\n                /**\n                 * Sets data to storage\n                 *\n                 * @param {*} data\n                 */\n                set: function (data) {\n                    if (!utils.compare(data, this.data()).equal) {\n                        this.data(data);\n                    }\n                },\n\n                /**\n                 * Adds some data to current storage data\n                 *\n                 * @param {*} data\n                 */\n                add: function (data) {\n                    if (!_.isEmpty(data)) {\n                        this.data(_.extend(utils.copy(this.data()), data));\n                    }\n                },\n\n                /**\n                 * Gets current storage data\n                 *\n                 * @returns {*} data\n                 */\n                get: function () {\n                    return this.data();\n                }\n            },\n\n            /**\n             * Required properties to storage\n             */\n            storagesInterface =  {\n                data: 'function',\n                initialize: 'function',\n                namespace: 'string'\n            },\n\n            /**\n             * Private service methods\n             */\n            _private = {\n\n                /**\n                 * Overrides class method and add ability use _super to call parent method\n                 *\n                 * @param {Object} extensionMethods\n                 * @param {Object} originInstance\n                 */\n                overrideClassMethods: function (extensionMethods, originInstance) {\n                    var methodsName = _.keys(extensionMethods),\n                        i = 0,\n                        length = methodsName.length;\n\n                    for (i; i < length; i++) {\n                        if (_.isFunction(originInstance[methodsName[i]])) {\n                            originInstance[methodsName[i]] = extensionMethods[methodsName[i]];\n                        }\n                    }\n\n                    return originInstance;\n                },\n\n                /**\n                 * Checks is storage implement interface\n                 *\n                 * @param {Object} classInstance\n                 *\n                 * @returns {Boolean}\n                 */\n                isImplementInterface: function (classInstance) {\n                    _.each(storagesInterface, function (key, value) {\n                        if (typeof classInstance[key] !== value) {\n                            return false;\n                        }\n                    });\n\n                    return true;\n                }\n            },\n\n            /**\n             * Subscribers list\n             */\n            subsctibers = {};\n\n        (function () {\n            /**\n             * @param {Object} config\n             * @return void\n             */\n            classes[IdsStorage.name] = function (config) {\n                _.extend(this, IdsStorage, config);\n            };\n\n            /**\n             * @param {Object} config\n             * @return void\n             */\n            classes[IdsStorageCompare.name] = function (config) {\n                _.extend(this, IdsStorageCompare, config);\n            };\n\n            /**\n             * @param {Object} config\n             * @return void\n             */\n            classes[DataStore.name] = function (config) {\n                _.extend(this, DataStore, config);\n            };\n\n            _.each(classes, function (classItem) {\n                classItem.prototype = prototype;\n            });\n        })();\n\n        return {\n\n            /**\n             * Creates new storage or returns if storage with declared namespace exist\n             *\n             * @param {Object} config - storage config\n             * @throws {Error}\n             * @returns {Object} storage instance\n             */\n            createStorage: function (config) {\n                var instance,\n                    initialized;\n\n                if (storages[config.namespace]) {\n                    return storages[config.namespace];\n                }\n\n                instance = new classes[config.className](config);\n\n                if (_private.isImplementInterface(instance)) {\n                    initialized = storages[config.namespace] = instance.initialize();\n                    this.processSubscribers(initialized, config);\n\n                    return initialized;\n                }\n\n                throw new Error('Class ' + config.className + $t('does not implement Storage Interface'));\n            },\n\n            /**\n             * Process subscribers\n             *\n             * Differentiate subscribers by their namespaces: recently_viewed or recently_compared\n             * and process callbacks. Callbacks can be add through onStorageInit function\n             *\n             * @param {Object} initialized\n             * @param {Object} config\n             * @return void\n             */\n            processSubscribers: function (initialized, config) {\n                if (subsctibers[config.namespace]) {\n                    _.each(subsctibers[config.namespace], function (callback) {\n                        callback(initialized);\n                    });\n\n                    delete subsctibers[config.namespace];\n                }\n            },\n\n            /**\n             * Listens storage creating by namespace\n             *\n             * @param {String} namespace\n             * @param {Function} callback\n             * @return void\n             */\n            onStorageInit: function (namespace, callback) {\n                if (storages[namespace]) {\n                    callback(storages[namespace]);\n                } else {\n                    subsctibers[namespace] ?\n                        subsctibers[namespace].push(callback) :\n                        subsctibers[namespace] = [callback];\n                }\n            },\n\n            /**\n             * Gets storage by namespace\n             *\n             * @param {String} namespace\n             *\n             * @returns {Object} storage insance\n             */\n            getStorage: function (namespace) {\n                return storages[namespace];\n            }\n        };\n    })();\n});\n\n","Magento_Catalog/js/product/list/listing.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko',\n    'underscore',\n    'Magento_Ui/js/grid/listing'\n], function (ko, _, Listing) {\n    'use strict';\n\n    return Listing.extend({\n        defaults: {\n            additionalClasses: '',\n            filteredRows: {},\n            limit: 5,\n            listens: {\n                elems: 'filterRowsFromCache',\n                '${ $.provider }:data.items': 'filterRowsFromServer'\n            }\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n            this.filteredRows = ko.observable();\n            this.initProductsLimit();\n            this.hideLoader();\n        },\n\n        /**\n         * Initialize product limit\n         * Product limit can be configured through Ui component.\n         * Product limit are present in widget form\n         *\n         * @returns {exports}\n         */\n        initProductsLimit: function () {\n            if (this.source['page_size']) {\n                this.limit = this.source['page_size'];\n            }\n\n            return this;\n        },\n\n        /**\n         * Initializes observable properties.\n         *\n         * @returns {Listing} Chainable.\n         */\n        initObservable: function () {\n            this._super()\n                .track({\n                    rows: []\n                });\n\n            return this;\n        },\n\n        /**\n         * Sort and filter rows, that are already in magento storage cache\n         *\n         * @return void\n         */\n        filterRowsFromCache: function () {\n            this._filterRows(this.rows);\n        },\n\n        /**\n         * Sort and filter rows, that are come from backend\n         *\n         * @param {Object} rows\n         */\n        filterRowsFromServer: function (rows) {\n            this._filterRows(rows);\n        },\n\n        /**\n         * Filter rows by limit and sort them\n         *\n         * @param {Array} rows\n         * @private\n         */\n        _filterRows: function (rows) {\n            this.filteredRows(_.sortBy(rows, 'added_at').reverse().slice(0, this.limit));\n        },\n\n        /**\n         * Can retrieve product url\n         *\n         * @param {Object} row\n         * @returns {String}\n         */\n        getUrl: function (row) {\n            return row.url;\n        },\n\n        /**\n         * Get product attribute by code.\n         *\n         * @param {String} code\n         * @return {Object}\n         */\n        getComponentByCode: function (code) {\n            var elems = this.elems() ? this.elems() : ko.getObservable(this, 'elems'),\n                component;\n\n            component = _.filter(elems, function (elem) {\n                return elem.index === code;\n            }, this).pop();\n\n            return component;\n        }\n    });\n});\n","Magento_Catalog/js/product/list/column-status-validator.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore'\n], function (_) {\n    'use strict';\n\n    return _.extend({\n        /**\n         * Check whether we can show column depends on server settings or not\n         *\n         * @param {Object} source\n         * @param {String} attributeCode\n         * @param {String} type\n         * @returns {Boolean}\n         */\n        isValid: function (source, attributeCode, type) {\n            var attributes;\n\n            if (!source[type]) {\n                return false;\n            }\n\n            attributes = source[type].split(',');\n\n            return _.contains(attributes, attributeCode);\n        }\n    });\n});\n","Magento_Catalog/js/product/list/toolbar.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     * ProductListToolbarForm Widget - this widget is setting cookie and submitting form according to toolbar controls\n     */\n    $.widget('mage.productListToolbarForm', {\n\n        options: {\n            modeControl: '[data-role=\"mode-switcher\"]',\n            directionControl: '[data-role=\"direction-switcher\"]',\n            orderControl: '[data-role=\"sorter\"]',\n            limitControl: '[data-role=\"limiter\"]',\n            mode: 'product_list_mode',\n            direction: 'product_list_dir',\n            order: 'product_list_order',\n            limit: 'product_list_limit',\n            page: 'p',\n            modeDefault: 'grid',\n            directionDefault: 'asc',\n            orderDefault: 'position',\n            limitDefault: '9',\n            url: '',\n            formKey: '',\n            post: false\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            this._bind(\n                $(this.options.modeControl, this.element),\n                this.options.mode,\n                this.options.modeDefault\n            );\n            this._bind(\n                $(this.options.directionControl, this.element),\n                this.options.direction,\n                this.options.directionDefault\n            );\n            this._bind(\n                $(this.options.orderControl, this.element),\n                this.options.order,\n                this.options.orderDefault\n            );\n            this._bind(\n                $(this.options.limitControl, this.element),\n                this.options.limit,\n                this.options.limitDefault\n            );\n        },\n\n        /** @inheritdoc */\n        _bind: function (element, paramName, defaultValue) {\n            if (element.is('select')) {\n                element.on('change', {\n                    paramName: paramName,\n                    'default': defaultValue\n                }, $.proxy(this._processSelect, this));\n            } else {\n                element.on('click', {\n                    paramName: paramName,\n                    'default': defaultValue\n                }, $.proxy(this._processLink, this));\n            }\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _processLink: function (event) {\n            event.preventDefault();\n            this.changeUrl(\n                event.data.paramName,\n                $(event.currentTarget).data('value'),\n                event.data.default\n            );\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _processSelect: function (event) {\n            this.changeUrl(\n                event.data.paramName,\n                event.currentTarget.options[event.currentTarget.selectedIndex].value,\n                event.data.default\n            );\n        },\n\n        /**\n         * @private\n         */\n        getUrlParams: function () {\n            var decode = window.decodeURIComponent,\n                urlPaths = this.options.url.split('?'),\n                urlParams = urlPaths[1] ? urlPaths[1].split('&') : [],\n                params = {},\n                parameters, i;\n\n            for (i = 0; i < urlParams.length; i++) {\n                parameters = urlParams[i].split('=');\n                params[decode(parameters[0])] = parameters[1] !== undefined ?\n                    decode(parameters[1].replace(/\\+/g, '%20')) :\n                    '';\n            }\n\n            return params;\n        },\n\n        /**\n         * @returns {String}\n         * @private\n         */\n        getCurrentLimit: function () {\n            return this.getUrlParams()[this.options.limit] || this.options.limitDefault;\n        },\n\n        /**\n         * @returns {String}\n         * @private\n         */\n        getCurrentPage: function () {\n            return this.getUrlParams()[this.options.page] || 1;\n        },\n\n        /**\n         * @param {String} paramName\n         * @param {*} paramValue\n         * @param {*} defaultValue\n         */\n        changeUrl: function (paramName, paramValue, defaultValue) {\n            var urlPaths = this.options.url.split('?'),\n                baseUrl = urlPaths[0],\n                paramData = this.getUrlParams(),\n                currentPage = this.getCurrentPage(),\n                form, params, key, input, formKey, newPage;\n\n            if (currentPage > 1 && paramName === this.options.mode) {\n                delete paramData[this.options.page];\n            }\n\n            if (currentPage > 1 && paramName === this.options.limit) {\n                newPage = Math.floor(this.getCurrentLimit() * (currentPage - 1) / paramValue) + 1;\n\n                if (newPage > 1) {\n                    paramData[this.options.page] = newPage;\n                } else {\n                    delete paramData[this.options.page];\n                }\n            }\n\n            paramData[paramName] = paramValue;\n\n            if (this.options.post) {\n                form = document.createElement('form');\n                params = [this.options.mode, this.options.direction, this.options.order, this.options.limit];\n\n                for (key in paramData) {\n                    if (params.indexOf(key) !== -1) { //eslint-disable-line max-depth\n                        input = document.createElement('input');\n                        input.name = key;\n                        input.value = paramData[key];\n                        form.appendChild(input);\n                        delete paramData[key];\n                    }\n                }\n                formKey = document.createElement('input');\n                formKey.name = 'form_key';\n                formKey.value = this.options.formKey;\n                form.appendChild(formKey);\n\n                paramData = $.param(paramData);\n                baseUrl += paramData.length ? '?' + paramData : '';\n\n                form.action = baseUrl;\n                form.method = 'POST';\n                document.body.appendChild(form);\n                form.submit();\n            } else {\n                if (paramValue == defaultValue) { //eslint-disable-line eqeqeq\n                    delete paramData[paramName];\n                }\n\n                paramData = $.param(paramData);\n                location.href = baseUrl + (paramData.length ? '?' + paramData : '');\n            }\n        }\n    });\n\n    return $.mage.productListToolbarForm;\n});\n","Magento_Catalog/js/product/list/columns/price-box.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    'underscore',\n    'uiRegistry',\n    'mageUtils',\n    'uiCollection',\n    'Magento_Catalog/js/product/list/column-status-validator',\n    'uiLayout'\n], function (ko, _, registry, utils, Collection, columnStatusValidator, layout) {\n    'use strict';\n\n    return Collection.extend({\n        defaults: {\n            label: '',\n            hasSpecialPrice: false,\n            showMinimalPrice: false,\n            useLinkForAsLowAs: false,\n            visible: true,\n            headerTmpl: 'ui/grid/columns/text',\n            bodyTmpl: 'Magento_Catalog/product/price/price_box',\n            disableAction: false,\n            controlVisibility: true,\n            sortable: false,\n            sorting: false,\n            draggable: true,\n            fieldClass: {},\n            renders: {\n                default: {}\n            },\n            ignoreTmpls: {\n                fieldAction: true\n            },\n            statefull: {\n                visible: true,\n                sorting: true\n            },\n            imports: {\n                exportSorting: 'sorting'\n            },\n            listens: {\n                elems: ''\n            },\n            modules: {\n                source: '${ $.provider }'\n            },\n            pricesInit: {}\n        },\n\n        /**\n         * Sort prices api\n         *\n         * @returns {exports}\n         */\n        sort: function () {\n            return this;\n        },\n\n        /**\n         * Check whether is allowed to render price or not\n         *\n         * @returns {*}\n         */\n        isAllowed: function () {\n            return columnStatusValidator.isValid(this.source(), 'price', 'show_attributes');\n        },\n\n        /**\n         * Retrieve array of prices, that should be rendered for specific product\n         *\n         * @param {Array} row\n         * @return {Array}\n         */\n        getPrices: function (row) {\n            var elems = this.elems() ? this.elems() : ko.getObservable(this, 'elems'),\n                result;\n\n            //we cant take type of product from row\n            this.initPrices(row);\n            result = _.filter(elems, function (elem) {\n                return elem.productType === row.type;\n            });\n\n            return result;\n        },\n\n        /**\n         * Recursive Merging of objects\n         *\n         * @param {Array} target\n         * @param {Array} source\n         * @returns {Array}\n         * @private\n         */\n        _deepObjectExtend: function (target, source) {\n            var _target = utils.copy(target);\n\n            _.each(source, function (value, key) {\n                if (_.keys(value).length && typeof _target[key] !== 'undefined') {\n                    _target[key] = this._deepObjectExtend(_target[key], value);\n                } else {\n                    _target[key] = value;\n                }\n            }, this);\n\n            return _target;\n        },\n\n        /**\n         * Init price type box, in cases when product type has custom component or bodyTmpl\n         *\n         * @param {String} productType\n         * @private\n         */\n        _initPriceWithCustomMetaData: function (productType) {\n            var price = this._deepObjectExtend(\n                this.renders.prices['default'],\n                this.renders.prices[productType]\n            );\n\n            price.name = productType + '.default';\n            price.parent = this.name;\n            price.source = this.source;\n            price.productType = productType;\n            layout([price]);\n        },\n\n        /**\n         * Init Prices by product type and add them to layout\n         *\n         * @param {Array} _priceData\n         * @param {String} productType\n         * @private\n         */\n        _initPricesForProductType: function (_priceData, productType) {\n            var prices = [];\n\n            this._setPriceNamesToPrices(_priceData, productType);\n            _.sortBy(_priceData, this._comparePrices);\n\n            _.each(_priceData, function (priceData) {\n                if (!priceData.component) {\n                    return;\n                }\n\n                priceData.parent = this.name;\n                priceData.provider = this.provider;\n                priceData.productType = productType;\n                priceData = utils.template(priceData, this);\n                prices.push(priceData);\n            }, this);\n\n            layout(prices);\n        },\n\n        /**\n         * Init dynamic price components\n         *\n         * @param {Array} row\n         * @returns {void}\n         */\n        initPrices: function (row) {\n            var _priceData = [],\n                productType = row.type,\n                defaultPrice = this.renders.prices['default'];\n\n            if (this.pricesInit[productType]) {\n                return true;\n            }\n\n            this.pricesInit[productType] = true;\n\n            if (this.renders.prices[productType] && this._needToApplyCustomTemplate(this.renders.prices[productType])) {\n                return this._initPriceWithCustomMetaData(productType);\n            }\n\n            if (this.renders.prices[productType] && this.renders.prices[productType].children) {\n                _priceData = this._deepObjectExtend(defaultPrice.children, this.renders.prices[productType].children);\n            } else {\n                _priceData = defaultPrice.children;\n            }\n\n            return this._initPricesForProductType(_priceData, productType);\n        },\n\n        /**\n         * Set name to all price components\n         *\n         * @param {Array} prices\n         * @param {String} productType\n         * @private\n         */\n        _setPriceNamesToPrices: function (prices, productType) {\n            _.each(prices, function (price, name) {\n                price.priceType = name;\n                price.name = name + '.' + productType;\n            });\n\n            return prices;\n        },\n\n        /**\n         * Sort callback to compare prices by sort order\n         *\n         * @param {Number} firstPrice\n         * @param {Number} secondPrice\n         * @returns {Number}\n         * @private\n         */\n        _comparePrices: function (firstPrice, secondPrice) {\n            if (firstPrice.sortOrder < secondPrice.sortOrder) {\n                return -1;\n            }\n\n            if (firstPrice.sortOrder > secondPrice.sortOrder) {\n                return 1;\n            }\n\n            return 0;\n        },\n\n        /**\n         * Check whether metadata of product type prices was changed, and we should\n         * to apply custom template or custom component\n         *\n         * @param {Array} productData\n         * @returns {*}\n         * @private\n         */\n        _needToApplyCustomTemplate: function (productData) {\n            return productData.bodyTmpl || productData.component;\n        },\n\n        /**\n         * Returns path to the columns' body template.\n         *\n         * @returns {String}\n         */\n        getBody: function () {\n            return this.bodyTmpl;\n        },\n\n        /**\n         * Get price label.\n         *\n         * @returns {String}\n         */\n        getLabel: function () {\n            return this.label;\n        }\n    });\n});\n","Magento_Catalog/js/product/list/columns/final-price.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'uiRegistry',\n    'mageUtils',\n    'uiCollection'\n], function (_, registry, utils, Collection) {\n    'use strict';\n\n    return Collection.extend({\n        defaults: {\n            label: false,\n            headerTmpl: 'ui/grid/columns/text',\n            showMinimalPrice: false,\n            showMaximumPrice: false,\n            useLinkForAsLowAs: false,\n            bodyTmpl: 'Magento_Catalog/product/final_price',\n            priceWrapperCssClasses: '',\n            priceWrapperAttr: {}\n        },\n\n        /**\n         * Get product final price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} final price html\n         */\n        getPrice: function (row) {\n            return row['price_info']['formatted_prices']['final_price'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getPrice.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} final price html\n         */\n        getPriceUnsanitizedHtml: function (row) {\n            return this.getPrice(row);\n        },\n\n        /**\n         * Get product regular price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} regular price html\n         */\n        getRegularPrice: function (row) {\n            return row['price_info']['formatted_prices']['regular_price'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getRegularPrice.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} regular price html\n         */\n        getRegularPriceUnsanitizedHtml: function (row) {\n            return this.getRegularPrice(row);\n        },\n\n        /**\n         * Check if product has a price range.\n         *\n         * @param {Object} row\n         * @return {Boolean}\n         */\n        hasPriceRange: function (row) {\n            return row['price_info']['max_regular_price'] !== row['price_info']['min_regular_price'];\n        },\n\n        /**\n         * Check if product has special price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} special price html\n         */\n        hasSpecialPrice: function (row) {\n            return row['price_info']['regular_price'] > row['price_info']['final_price'];\n        },\n\n        /**\n         * Check if product has minimal price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} minimal price html\n         */\n        isMinimalPrice: function (row) {\n            return row['price_info']['minimal_price'] < row['price_info']['final_price'];\n        },\n\n        /**\n         * Get product minimal price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} minimal price html\n         */\n        getMinimalPrice: function (row) {\n            return row['price_info']['formatted_prices']['minimal_price'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getMinimalPrice.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} minimal price html\n         */\n        getMinimalPriceUnsanitizedHtml: function (row) {\n            return this.getMinimalPrice(row);\n        },\n\n        /**\n         * Check if product is salable.\n         *\n         * @param {Object} row\n         * @return {Boolean}\n         */\n        isSalable: function (row) {\n            return row['is_salable'];\n        },\n\n        /**\n         * Get product maximum price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} maximum price html\n         */\n        getMaxPrice: function (row) {\n            return row['price_info']['formatted_prices']['max_price'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getMaxPrice.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} maximum price html\n         */\n        getMaxPriceUnsanitizedHtml: function (row) {\n            return this.getMaxPrice(row);\n        },\n\n        /**\n         * Get product maximum regular price in case of price range and special price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} maximum regular price html\n         */\n        getMaxRegularPrice: function (row) {\n            return row['price_info']['formatted_prices']['max_regular_price'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getMaxRegularPrice.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} maximum regular price html\n         */\n        getMaxRegularPriceUnsanitizedHtml: function (row) {\n            return this.getMaxRegularPrice(row);\n        },\n\n        /**\n         * Get product minimal regular price in case of price range and special price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} minimal regular price html\n         */\n        getMinRegularPrice: function (row) {\n            return row['price_info']['formatted_prices']['min_regular_price'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getMinRegularPrice.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} minimal regular price html\n         */\n        getMinRegularPriceUnsanitizedHtml: function (row) {\n            return this.getMinRegularPrice(row);\n        },\n\n        /**\n         * Get adjustments names and return as string.\n         *\n         * @return {String} adjustments classes\n         */\n        getAdjustmentCssClasses: function () {\n            return _.pluck(this.getAdjustments(), 'index').join(' ');\n        },\n\n        /**\n         * Get product minimal price as number.\n         *\n         * @param {Object} row\n         * @return {Number} minimal price amount\n         */\n        getMinimalPriceAmount: function (row) {\n            return row['price_info']['minimal_price'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getMinimalPriceAmount\n         *\n         * @param {Object} row\n         * @return {Number} minimal price amount\n         */\n        getMinimalPriceAmountUnsanitizedHtml: function (row) {\n            return this.getMinimalPriceAmount(row);\n        },\n\n        /**\n         * Get product minimal regular price as number in case of special price.\n         *\n         * @param {Object} row\n         * @return {Number} minimal regular price amount\n         */\n        getMinimalRegularPriceAmount: function (row) {\n            return row['price_info']['min_regular_price'];\n        },\n\n        /**\n         * Get product maximum price as number.\n         *\n         * @param {Object} row\n         * @return {Number} maximum price amount\n         */\n        getMaximumPriceAmount: function (row) {\n            return row['price_info']['max_price'];\n        },\n\n        /**\n         * Get product maximum regular price as number in case of special price.\n         *\n         * @param {Object} row\n         * @return {Number} maximum regular price amount\n         */\n        getMaximumRegularPriceAmount: function (row) {\n            return row['price_info']['max_regular_price'];\n        },\n\n        /**\n         * Check if minimal regular price exist for product.\n         *\n         * @param {Object} row\n         * @return {Boolean}\n         */\n        showMinRegularPrice: function (row) {\n            return this.getMinimalPriceAmount(row) < this.getMinimalRegularPriceAmount(row);\n        },\n\n        /**\n         * Check if maximum regular price exist for product.\n         *\n         * @param {Object} row\n         * @return {Boolean}\n         */\n        showMaxRegularPrice: function (row) {\n            return this.getMaximumPriceAmount(row) < this.getMaximumRegularPriceAmount(row);\n        },\n\n        /**\n         * Get path to the columns' body template.\n         *\n         * @returns {String}\n         */\n        getBody: function () {\n            return this.bodyTmpl;\n        },\n\n        /**\n         * Get all price adjustments.\n         *\n         * @returns {Object}\n         */\n        getAdjustments: function () {\n            var adjustments = this.elems();\n\n            _.each(adjustments, function (adjustment) {\n                adjustment.setPriceType(this.priceType);\n                adjustment.source = this.source;\n            }, this);\n\n            return adjustments;\n        }\n    });\n});\n","Magento_Catalog/js/product/list/columns/pricetype-box.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    'underscore',\n    'uiCollection'\n], function (ko, _, Collection) {\n    'use strict';\n\n    return Collection.extend({\n        /**\n         * Find from all price ui components, price with specific code, init source on it and set priceType\n         *\n         * @param {String} code\n         * @returns {*|T}\n         */\n        getPriceByCode: function (code) {\n            var elems = this.elems() ? this.elems() : ko.getObservable(this, 'elems'),\n                price;\n\n            price = _.filter(elems, function (elem) {\n                return elem.index.split('.').shift() === code;\n            }, this).pop();\n\n            price.source = this.source();\n            price.priceType = code;\n\n            return price;\n        },\n\n        /**\n         * Retrieve body template\n         *\n         * @returns {String}\n         */\n        getBody: function () {\n            return this.bodyTmpl;\n        },\n\n        /**\n         * Check whether price has price range, depends on different options, that can be choose\n         *\n         * @param {Object} row\n         * @returns {Boolean}\n         */\n        hasPriceRange: function (row) {\n            return row['price_info']['max_regular_price'] !== row['price_info']['min_regular_price'];\n        }\n    });\n});\n","Magento_Catalog/js/product/list/columns/image.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'Magento_Ui/js/grid/columns/column',\n    'Magento_Catalog/js/product/list/column-status-validator'\n], function (_, Element, columnStatusValidator) {\n    'use strict';\n\n    return Element.extend({\n        defaults: {\n            bodyTmpl: 'Magento_Catalog/product/list/columns/image',\n            imageCode: 'default',\n            image: {}\n        },\n\n        /**\n         * Find image by code in scope of images\n         *\n         * @param {Object} images\n         * @returns {*|T}\n         */\n        getImage: function (images) {\n            return _.filter(images, function (image) {\n                return this.imageCode === image.code;\n            }, this).pop();\n        },\n\n        /**\n         * Get image path.\n         *\n         * @param {Object} row\n         * @return {String}\n         */\n        getImageUrl: function (row) {\n            return this.getImage(row.images).url;\n        },\n\n        /**\n         * Get image box width.\n         *\n         * @param {Object} row\n         * @return {Number}\n         */\n        getWidth: function (row) {\n            return this.getImage(row.images).width;\n        },\n\n        /**\n         * Get image box height.\n         *\n         * @param {Object} row\n         * @return {Number}\n         */\n        getHeight: function (row) {\n            return this.getImage(row.images).height;\n        },\n\n        /**\n         * Get resized image width.\n         *\n         * @param {Object} row\n         * @return {Number}\n         */\n        getResizedImageWidth: function (row) {\n            return this.getImage(row.images)['resized_width'];\n        },\n\n        /**\n         * Get resized image height.\n         *\n         * @param {Object} row\n         * @return {Number}\n         */\n        getResizedImageHeight: function (row) {\n            return this.getImage(row.images)['resized_height'];\n        },\n\n        /**\n         * Get image alt text.\n         *\n         * @param {Object} row\n         * @return {String}\n         */\n        getLabel: function (row) {\n            if (!this.imageExists(row)) {\n                return this._super();\n            }\n\n            return this.getImage(row.images).label;\n        },\n\n        /**\n         * Check if image exist.\n         *\n         * @param {Object} row\n         * @return {Boolean}\n         */\n        imageExists: function (row) {\n            return this.getImage(row.images) !== 'undefined';\n        },\n\n        /**\n         * Check if component must be shown.\n         *\n         * @return {Boolean}\n         */\n        isAllowed: function () {\n            return columnStatusValidator.isValid(this.source(), 'image', 'show_attributes');\n        }\n    });\n});\n","Magento_Catalog/js/view/compare-products.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    'jquery',\n    'underscore',\n    'mage/mage',\n    'mage/decorate'\n], function (Component, customerData, $, _) {\n    'use strict';\n\n    var sidebarInitialized = false,\n        compareProductsReloaded = false;\n\n    /**\n     * Initialize sidebar\n     */\n    function initSidebar() {\n        if (sidebarInitialized) {\n            return;\n        }\n\n        sidebarInitialized = true;\n        $('[data-role=compare-products-sidebar]').decorate('list', true);\n    }\n\n    return Component.extend({\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n            this.compareProducts = customerData.get('compare-products');\n            if (!compareProductsReloaded\n                && !_.isEmpty(this.compareProducts())\n                //Expired section names are reloaded on page load\n                && _.indexOf(customerData.getExpiredSectionNames(), 'compare-products') === -1\n                && window.checkout\n                && window.checkout.websiteId\n                && window.checkout.websiteId !== this.compareProducts().websiteId\n            ) {\n                //set count to 0 to prevent \"compared products\" blocks and count to show with wrong count and items\n                this.compareProducts().count = 0;\n                customerData.reload(['compare-products'], false);\n                compareProductsReloaded = true;\n            }\n            initSidebar();\n        }\n    });\n});\n","Magento_Catalog/js/view/image.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent'\n], function (Component) {\n    'use strict';\n\n    return Component.extend({\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n\n            this.template = window.checkout.imageTemplate || this.template;\n        }\n    });\n});\n","requirejs/domReady.js":"/**\n * @license RequireJS domReady 2.0.1 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.\n * Available via the MIT or new BSD license.\n * see: http://github.com/requirejs/domReady for details\n */\n/*jslint */\n/*global require: false, define: false, requirejs: false,\n  window: false, clearInterval: false, document: false,\n  self: false, setInterval: false */\n\n\ndefine(function () {\n    'use strict';\n\n    var isTop, testDiv, scrollIntervalId,\n        isBrowser = typeof window !== \"undefined\" && window.document,\n        isPageLoaded = !isBrowser,\n        doc = isBrowser ? document : null,\n        readyCalls = [];\n\n    function runCallbacks(callbacks) {\n        var i;\n        for (i = 0; i < callbacks.length; i += 1) {\n            callbacks[i](doc);\n        }\n    }\n\n    function callReady() {\n        var callbacks = readyCalls;\n\n        if (isPageLoaded) {\n            //Call the DOM ready callbacks\n            if (callbacks.length) {\n                readyCalls = [];\n                runCallbacks(callbacks);\n            }\n        }\n    }\n\n    /**\n     * Sets the page as loaded.\n     */\n    function pageLoaded() {\n        if (!isPageLoaded) {\n            isPageLoaded = true;\n            if (scrollIntervalId) {\n                clearInterval(scrollIntervalId);\n            }\n\n            callReady();\n        }\n    }\n\n    if (isBrowser) {\n        if (document.addEventListener) {\n            //Standards. Hooray! Assumption here that if standards based,\n            //it knows about DOMContentLoaded.\n            document.addEventListener(\"DOMContentLoaded\", pageLoaded, false);\n            window.addEventListener(\"load\", pageLoaded, false);\n        } else if (window.attachEvent) {\n            window.attachEvent(\"onload\", pageLoaded);\n\n            testDiv = document.createElement('div');\n            try {\n                isTop = window.frameElement === null;\n            } catch (e) {}\n\n            //DOMContentLoaded approximation that uses a doScroll, as found by\n            //Diego Perini: http://javascript.nwbox.com/IEContentLoaded/,\n            //but modified by other contributors, including jdalton\n            if (testDiv.doScroll && isTop && window.external) {\n                scrollIntervalId = setInterval(function () {\n                    try {\n                        testDiv.doScroll();\n                        pageLoaded();\n                    } catch (e) {}\n                }, 30);\n            }\n        }\n\n        //Check if document is no longer loading, and if so, just trigger page load\n        //listeners. Latest webkit browsers also use \"interactive\", and\n        //will fire the onDOMContentLoaded before \"interactive\" but not after\n        //entering \"interactive\" or \"complete\". More details:\n        //http://dev.w3.org/html5/spec/the-end.html#the-end\n        //http://stackoverflow.com/questions/3665561/document-readystate-of-interactive-vs-ondomcontentloaded\n        //Hmm, this is more complicated on further use, see \"firing too early\"\n        //bug: https://github.com/requirejs/domReady/issues/1\n        //so removing the || document.readyState === \"interactive\" test.\n        //There is still a window.onload binding that should get fired if\n        //DOMContentLoaded is missed.\n        if (document.readyState !== \"loading\") {\n            // Handle it asynchronously to allow scripts the opportunity to delay ready\n            setTimeout(pageLoaded);\n        }\n    }\n\n    /** START OF PUBLIC API **/\n\n    /**\n     * Registers a callback for DOM ready. If DOM is already ready, the\n     * callback is called immediately.\n     * @param {Function} callback\n     */\n    function domReady(callback) {\n        if (isPageLoaded) {\n            callback(doc);\n        } else {\n            readyCalls.push(callback);\n        }\n        return domReady;\n    }\n\n    domReady.version = '2.0.1';\n\n    /**\n     * Loader Plugin API method\n     */\n    domReady.load = function (name, req, onLoad, config) {\n        if (config.isBuild) {\n            onLoad(null);\n        } else {\n            domReady(onLoad);\n        }\n    };\n\n    /** END OF PUBLIC API **/\n\n    return domReady;\n});\n","Magento_OfflinePayments/js/view/payment/offline-payments.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n    'uiComponent',\n    'Magento_Checkout/js/model/payment/renderer-list'\n], function (Component, rendererList) {\n    'use strict';\n\n    rendererList.push(\n        {\n            type: 'checkmo',\n            component: 'Magento_OfflinePayments/js/view/payment/method-renderer/checkmo-method'\n        },\n        {\n            type: 'banktransfer',\n            component: 'Magento_OfflinePayments/js/view/payment/method-renderer/banktransfer-method'\n        },\n        {\n            type: 'cashondelivery',\n            component: 'Magento_OfflinePayments/js/view/payment/method-renderer/cashondelivery-method'\n        },\n        {\n            type: 'purchaseorder',\n            component: 'Magento_OfflinePayments/js/view/payment/method-renderer/purchaseorder-method'\n        }\n    );\n\n    /** Add view logic here if needed */\n    return Component.extend({});\n});\n","Magento_OfflinePayments/js/view/payment/method-renderer/checkmo-method.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n    'Magento_Checkout/js/view/payment/default'\n], function (Component) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_OfflinePayments/payment/checkmo'\n        },\n\n        /**\n         * Returns send check to info.\n         *\n         * @return {*}\n         */\n        getMailingAddress: function () {\n            return window.checkoutConfig.payment.checkmo.mailingAddress;\n        },\n\n        /**\n         * Returns payable to info.\n         *\n         * @return {*}\n         */\n        getPayableTo: function () {\n            return window.checkoutConfig.payment.checkmo.payableTo;\n        }\n    });\n});\n","Magento_OfflinePayments/js/view/payment/method-renderer/purchaseorder-method.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n    'Magento_Checkout/js/view/payment/default',\n    'jquery',\n    'mage/validation'\n], function (Component, $) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_OfflinePayments/payment/purchaseorder-form',\n            purchaseOrderNumber: ''\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super()\n                .observe('purchaseOrderNumber');\n\n            return this;\n        },\n\n        /**\n         * @return {Object}\n         */\n        getData: function () {\n            return {\n                method: this.item.method,\n                'po_number': this.purchaseOrderNumber(),\n                'additional_data': null\n            };\n        },\n\n        /**\n         * @return {jQuery}\n         */\n        validate: function () {\n            var form = 'form[data-role=purchaseorder-form]';\n\n            return $(form).validation() && $(form).validation('isValid');\n        }\n    });\n});\n","Magento_OfflinePayments/js/view/payment/method-renderer/banktransfer-method.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n    'ko',\n    'Magento_Checkout/js/view/payment/default'\n], function (ko, Component) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_OfflinePayments/payment/banktransfer'\n        },\n\n        /**\n         * Get value of instruction field.\n         * @returns {String}\n         */\n        getInstructions: function () {\n            return window.checkoutConfig.payment.instructions[this.item.method];\n        }\n    });\n});\n","Magento_OfflinePayments/js/view/payment/method-renderer/cashondelivery-method.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n    'Magento_Checkout/js/view/payment/default'\n], function (Component) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_OfflinePayments/payment/cashondelivery'\n        },\n\n        /**\n         * Returns payment method instructions.\n         *\n         * @return {*}\n         */\n        getInstructions: function () {\n            return window.checkoutConfig.payment.instructions[this.item.method];\n        }\n    });\n});\n","Magento_Weee/js/tax-toggle.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    /**\n     * @param {Object} config\n     * @param {jQuery.Event} e\n     */\n    function onToggle(config, e) {\n        var elem = $(e.currentTarget),\n            expandedClassName = config.expandedClassName || 'cart-tax-total-expanded';\n\n        elem.toggleClass(expandedClassName);\n\n        $(config.itemTaxId).toggle();\n    }\n\n    return function (data, el) {\n        $(el).on('click', onToggle.bind(null, data));\n    };\n});\n","Magento_Weee/js/price/adjustment.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'Magento_Ui/js/grid/columns/column'\n], function (Element) {\n    'use strict';\n\n    return Element.extend({\n        defaults: {\n            bodyTmpl: 'Magento_Weee/price/adjustment',\n            dataSource: '${ $.parentName }.provider',\n            //Weee configuration constants can be configured from backend\n            inclFptWithDesc: 1,//show FPT and description\n            inclFpt: 0, //show FPT attribute\n            exclFpt: 2, //do not show FPT\n            bothFptPrices: 3 //show price without FPT and with FPT and with description\n        },\n\n        /**\n         * Get Weee attributes.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} Weee html\n         */\n        getWeeeAttributes: function (row) {\n            return row['price_info']['extension_attributes']['weee_attributes'];\n        },\n\n        /**\n         * Get Weee without Tax attributes.\n         *\n         * @param {Object} taxAmount\n         * @return {HTMLElement} Weee html\n         */\n        getWeeeTaxWithoutTax: function (taxAmount) {\n            return taxAmount['amount_excl_tax'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getWeeeTaxWithoutTax.\n         *\n         * @param {Object} taxAmount\n         * @return {HTMLElement} Weee html\n         */\n        getWeeeTaxWithoutTaxUnsanitizedHtml: function (taxAmount) {\n            return this.getWeeeTaxWithoutTax(taxAmount);\n        },\n\n        /**\n         * Get Weee with Tax attributes.\n         *\n         * @param {Object} taxAmount\n         * @return {HTMLElement} Weee html\n         */\n        getWeeeTaxWithTax: function (taxAmount) {\n            return taxAmount['tax_amount_incl_tax'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getWeeeTaxWithTax.\n         *\n         * @param {Object} taxAmount\n         * @return {HTMLElement} Weee html\n         */\n        getWeeeTaxWithTaxUnsanitizedHtml: function (taxAmount) {\n            return this.getWeeeTaxWithTax(taxAmount);\n        },\n\n        /**\n         * Get Weee Tax name.\n         *\n         * @param {String} taxAmount\n         * @return {String} Weee name\n         */\n        getWeeTaxAttributeName: function (taxAmount) {\n            return taxAmount['attribute_code'];\n        },\n\n        /**\n         * Set price type.\n         *\n         * @param {String} priceType\n         * @return {Object}\n         */\n        setPriceType: function (priceType) {\n            this.taxPriceType = priceType;\n\n            return this;\n        },\n\n        /**\n         * Check if Weee Tax must be shown.\n         *\n         * @param {Object} row\n         * @return {Boolean}\n         */\n        isShown: function (row) {\n            return row['price_info']['extension_attributes']['weee_attributes'].length;\n        },\n\n        /**\n         * Get Weee final price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} Weee final price html\n         */\n        getWeeeAdjustment: function (row) {\n            return row['price_info']['extension_attributes']['weee_adjustment'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getWeeeAdjustment.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} Weee final price html\n         */\n        getWeeeAdjustmentUnsanitizedHtml: function (row) {\n            return this.getWeeeAdjustment(row);\n        },\n\n        /**\n         * Return whether display setting is to display price including FPT only.\n         *\n         * @return {Boolean}\n         */\n        displayPriceInclFpt: function () {\n            return +this.source.data.displayWeee === this.inclFpt;\n        },\n\n        /**\n         * Return whether display setting is to display\n         * price including FPT and FPT description.\n         *\n         * @return {Boolean}\n         */\n        displayPriceInclFptDescr: function () {\n            return +this.source.data.displayWeee === this.inclFptWithDesc;\n        },\n\n        /**\n         * Return whether display setting is to display price\n         * excluding FPT but including FPT description and final price.\n         *\n         * @return {Boolean}\n         */\n        displayPriceExclFptDescr: function () {\n            return +this.source.data.displayWeee === this.exclFpt;\n        },\n\n        /**\n         * Return whether display setting is to display price excluding FPT.\n         *\n         * @return {Boolean}\n         */\n        displayPriceExclFpt: function () {\n            return +this.source.data.displayWeee === this.bothFptPrices;\n        },\n\n        /**\n         * Return whether display setting is to display price excluding tax.\n         *\n         * @return {Boolean}\n         */\n        displayPriceExclTax: function () {\n            return +this.source.data.displayTaxes === this.inclFptWithDesc;\n        },\n\n        /**\n         * Return whether display setting is to display price including tax.\n         *\n         * @return {Boolean}\n         */\n        displayPriceInclTax: function () {\n            return +this.source.data.displayTaxes === this.exclFpt;\n        },\n\n        /**\n         * Return whether display setting is to display\n         * both price including tax and price excluding tax.\n         *\n         * @return {Boolean}\n         */\n        displayBothPricesTax: function () {\n            return +this.source.data.displayTaxes === this.bothFptPrices;\n        }\n    });\n});\n","Magento_Weee/js/view/cart/totals/weee.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Weee/js/view/checkout/summary/weee'\n], function (Component) {\n    'use strict';\n\n    return Component.extend({\n\n        /**\n         * @override\n         */\n        isFullMode: function () {\n            return true;\n        }\n    });\n});\n","Magento_Weee/js/view/checkout/summary/weee.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Checkout/js/view/summary/abstract-total',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Checkout/js/model/totals',\n    'Magento_Catalog/js/price-utils'\n], function (Component, quote, totals) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_Weee/checkout/summary/weee'\n        },\n        isIncludedInSubtotal: window.checkoutConfig.isIncludedInSubtotal,\n        totals: totals.totals,\n\n        /**\n         * @returns {Number}\n         */\n        getWeeeTaxSegment: function () {\n            var weee = totals.getSegment('weee_tax') || totals.getSegment('weee');\n\n            if (weee !== null && weee.hasOwnProperty('value')) {\n                return weee.value;\n            }\n\n            return 0;\n        },\n\n        /**\n         * Get weee value\n         * @returns {String}\n         */\n        getValue: function () {\n            return this.getFormattedPrice(this.getWeeeTaxSegment());\n        },\n\n        /**\n         * Weee display flag\n         * @returns {Boolean}\n         */\n        isDisplayed: function () {\n            return this.isFullMode() && this.getWeeeTaxSegment() > 0;\n        }\n    });\n});\n","Magento_Weee/js/view/checkout/summary/item/price/row_excl_tax.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Weee/js/view/checkout/summary/item/price/weee'\n], function (weee) {\n    'use strict';\n\n    return weee.extend({\n        defaults: {\n            template: 'Magento_Weee/checkout/summary/item/price/row_excl_tax'\n        },\n\n        /**\n         * @param {Object} item\n         * @return {Number}\n         */\n        getFinalRowDisplayPriceExclTax: function (item) {\n            var rowTotalExclTax = parseFloat(item['row_total']);\n\n            if (!window.checkoutConfig.getIncludeWeeeFlag) {\n                rowTotalExclTax += parseFloat(item['qty']) *\n                    parseFloat(item['weee_tax_applied_amount']);\n            }\n\n            return rowTotalExclTax;\n        },\n\n        /**\n         * @param {Object} item\n         * @return {Number}\n         */\n        getRowDisplayPriceExclTax: function (item) {\n            var rowTotalExclTax = parseFloat(item['row_total']);\n\n            if (window.checkoutConfig.getIncludeWeeeFlag) {\n                rowTotalExclTax += this.getRowWeeeTaxExclTax(item);\n            }\n\n            return rowTotalExclTax;\n        },\n\n        /**\n         * @param {Object} item\n         * @return {Number}\n         */\n        getRowWeeeTaxExclTax: function (item) {\n            var totalWeeeTaxExclTaxApplied = 0,\n                weeeTaxAppliedAmounts;\n\n            if (item['weee_tax_applied']) {\n                weeeTaxAppliedAmounts = JSON.parse(item['weee_tax_applied']);\n                weeeTaxAppliedAmounts.forEach(function (weeeTaxAppliedAmount) {\n                    totalWeeeTaxExclTaxApplied += parseFloat(Math.max(weeeTaxAppliedAmount['row_amount'], 0));\n                });\n            }\n\n            return totalWeeeTaxExclTaxApplied;\n        }\n\n    });\n});\n","Magento_Weee/js/view/checkout/summary/item/price/weee.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Checkout/js/view/summary/abstract-total',\n    'Magento_Checkout/js/model/quote'\n], function (Component) {\n    'use strict';\n\n    return Component.extend({\n        /**\n         * @param {Object} item\n         * @return {Boolean}\n         */\n        isDisplayPriceWithWeeeDetails: function (item) {\n            if (!parseFloat(item['weee_tax_applied_amount']) || parseFloat(item['weee_tax_applied_amount'] <= 0)) {\n                return false;\n            }\n\n            return window.checkoutConfig.isDisplayPriceWithWeeeDetails;\n        },\n\n        /**\n         * @param {Object} item\n         * @return {Boolean}\n         */\n        isDisplayFinalPrice: function (item) {\n            if (!parseFloat(item['weee_tax_applied_amount'])) {\n                return false;\n            }\n\n            return window.checkoutConfig.isDisplayFinalPrice;\n        },\n\n        /**\n         * @param {Object} item\n         * @return {Array}\n         */\n        getWeeeTaxApplied: function (item) {\n            if (item['weee_tax_applied']) {\n                return JSON.parse(item['weee_tax_applied']);\n            }\n\n            return [];\n        }\n    });\n});\n","Magento_Weee/js/view/checkout/summary/item/price/row_incl_tax.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Weee/js/view/checkout/summary/item/price/weee'\n], function (weee) {\n    'use strict';\n\n    return weee.extend({\n        defaults: {\n            template: 'Magento_Weee/checkout/summary/item/price/row_incl_tax',\n            displayArea: 'row_incl_tax'\n        },\n\n        /**\n         * @param {Object} item\n         * @return {Number}\n         */\n        getFinalRowDisplayPriceInclTax: function (item) {\n            var rowTotalInclTax = parseFloat(item['row_total_incl_tax']);\n\n            if (!window.checkoutConfig.getIncludeWeeeFlag) {\n                rowTotalInclTax += this.getRowWeeeTaxInclTax(item);\n            }\n\n            return rowTotalInclTax;\n        },\n\n        /**\n         * @param {Object} item\n         * @return {Number}\n         */\n        getRowDisplayPriceInclTax: function (item) {\n            var rowTotalInclTax = parseFloat(item['row_total_incl_tax']);\n\n            if (window.checkoutConfig.getIncludeWeeeFlag) {\n                rowTotalInclTax += this.getRowWeeeTaxInclTax(item);\n            }\n\n            return rowTotalInclTax;\n        },\n\n        /**\n         * @param {Object}item\n         * @return {Number}\n         */\n        getRowWeeeTaxInclTax: function (item) {\n            var totalWeeeTaxInclTaxApplied = 0,\n                weeeTaxAppliedAmounts;\n\n            if (item['weee_tax_applied']) {\n                weeeTaxAppliedAmounts = JSON.parse(item['weee_tax_applied']);\n                weeeTaxAppliedAmounts.forEach(function (weeeTaxAppliedAmount) {\n                    totalWeeeTaxInclTaxApplied += parseFloat(Math.max(weeeTaxAppliedAmount['row_amount_incl_tax'], 0));\n                });\n            }\n\n            return totalWeeeTaxInclTaxApplied;\n        }\n\n    });\n});\n","Magento_ReCaptchaPaypal/js/reCaptchaPaypal.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(\n    [\n        'Magento_ReCaptchaFrontendUi/js/reCaptcha',\n        'jquery'\n    ],\n    function (Component, $) {\n        'use strict';\n\n        return Component.extend({\n\n            /**\n             * Recaptcha callback\n             * @param {String} token\n             */\n            reCaptchaCallback: function (token) {\n                this.tokenField.value = token;\n                this.$parentForm.trigger('captcha:endExecute');\n            },\n\n            /**\n             * Initialize parent form.\n             *\n             * @param {Object} parentForm\n             * @param {String} widgetId\n             */\n            initParentForm: function (parentForm, widgetId) {\n                var me = this;\n\n                parentForm.on('captcha:startExecute', function (event) {\n                    if (!me.tokenField.value && me.getIsInvisibleRecaptcha()) {\n                        // eslint-disable-next-line no-undef\n                        grecaptcha.execute(widgetId);\n                        event.preventDefault(event);\n                        event.stopImmediatePropagation();\n                    } else {\n                        me.$parentForm.trigger('captcha:endExecute');\n                    }\n                });\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            }\n        });\n    }\n);\n","Magento_ReCaptchaPaypal/js/payflowpro-method-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'Magento_Checkout/js/model/payment/additional-validators'\n], function ($, additionalValidators) {\n    'use strict';\n\n    return function (originalComponent) {\n        return originalComponent.extend({\n            /**\n             * Initializes reCaptcha\n             */\n            placeOrder: function () {\n                var original = this._super.bind(this),\n                    // jscs:disable requireCamelCaseOrUpperCaseIdentifiers\n                    isEnabledForPaypal = window.checkoutConfig.recaptcha_paypal,\n                    // jscs:enable requireCamelCaseOrUpperCaseIdentifiers\n                    paymentFormSelector = $('#co-payment-form'),\n                    startEvent = 'captcha:startExecute',\n                    endEvent = 'captcha:endExecute';\n\n                if (!this.validateHandler() || !additionalValidators.validate() || !isEnabledForPaypal) {\n                    return original();\n                }\n\n                paymentFormSelector.off(endEvent).on(endEvent, function () {\n                    original();\n                    paymentFormSelector.off(endEvent);\n                });\n\n                paymentFormSelector.trigger(startEvent);\n            }\n        });\n    };\n});\n","Magento_SendFriend/requirejs-config.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\nvar config = {\n    map: {\n        '*': {\n            'Magento_SendFriend/back-event': 'Magento_SendFriend/js/back-event'\n        }\n    }\n};\n","Magento_SendFriend/js/back-event.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('click', function () {\n            history.back();\n\n            return false;\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/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/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","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","Torresani_Consent/js/view/shipping-mixin.js":"define([\n    'jquery',\n    'underscore',\n    'Magento_Ui/js/form/form',\n    'ko',\n    'Magento_Customer/js/model/customer',\n    'Magento_Customer/js/model/address-list',\n    'Magento_Checkout/js/model/address-converter',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Checkout/js/action/create-shipping-address',\n    'Magento_Checkout/js/action/select-shipping-address',\n    'Magento_Checkout/js/model/shipping-rates-validator',\n    'Magento_Checkout/js/model/shipping-address/form-popup-state',\n    'Magento_Checkout/js/model/shipping-service',\n    'Magento_Checkout/js/action/select-shipping-method',\n    'Magento_Checkout/js/model/shipping-rate-registry',\n    'Magento_Checkout/js/action/set-shipping-information',\n    'Magento_Checkout/js/model/step-navigator',\n    'Magento_Ui/js/modal/modal',\n    'Magento_Checkout/js/model/checkout-data-resolver',\n    'Magento_Checkout/js/checkout-data',\n    'uiRegistry',\n    'mage/translate',\n    'Magento_Checkout/js/model/shipping-rate-service'\n], function (\n    $,\n    _,\n    Component,\n    ko,\n    customer,\n    addressList,\n    addressConverter,\n    quote,\n    createShippingAddress,\n    selectShippingAddress,\n    shippingRatesValidator,\n    formPopUpState,\n    shippingService,\n    selectShippingMethodAction,\n    rateRegistry,\n    setShippingInformationAction,\n    stepNavigator,\n    modal,\n    checkoutDataResolver,\n    checkoutData,\n    registry,\n    $t\n) {\n    'use strict';\n\n    var mixin = {\n        defaults: {\n            template: 'Torresani_Consent/shipping'\n        }\n    };\n\n    function showPrivacyCheckout() {\n        jQuery('div[name=\"shippingAddress.privacy\"] label > span').html('Ho letto e compreso l\u2019<a href=\"/informativa-privacy\" target=\"_blank\">informativa privacy</a> in merito al trattamento dei miei dati personali.');\n        jQuery('div[name=\"shippingAddress.terms\"] label > span').html('Accetto i <a href=\"/condizioni-generali-di-vendita\" target=\"_blank\">termini e le condizioni generali di vendita</a>.');\n        jQuery('div[name=\"shippingAddress.consent1\"] label > span').html('Acconsento a ricevere newsletter e comunicazioni commerciali sui nostri prodotti, servizi, attivit\u00e0 (punto 2 delle finalit\u00e0 indicate in <a href=\"/informativa-privacy\" target=\"_blank\">informativa privacy</a>');\n        jQuery('div[name=\"shippingAddress.consent2\"] label > span').html('Acconsento al trattamento dei miei dati per la profilazione finalizzata a ricevere comunicazioni, proposte commerciali, suggerimenti di acquisto in linea con i miei interessi (punto 3 delle finalit\u00e0 indicate in <a href=\"/informativa-privacy\" target=\"_blank\">informativa privacy</a>).');\n        jQuery('div[name=\"shippingAddress.consent3\"] label > span').html('Acconsento al trattamento dei miei dati per partecipare alle ricerche di mercato eseguite e/o commissionate dal Titolare (punto 5 delle finalit\u00e0 indicate in <a href=\"/informativa-privacy\" target=\"_blank\">informativa privacy</a>).');\n    }\n\n    return function (target) {\n        jQuery(document).ready(function() {\n            setTimeout(() => { showPrivacyCheckout(); }, 1000);\n            setTimeout(() => { showPrivacyCheckout(); }, 3000);\n            setTimeout(() => { showPrivacyCheckout(); }, 5000);\n        });\n        jQuery('body').on(\"click\", \"#shipping-method-buttons-container button.continue\", function(e){\n            var valid = true;\n            jQuery('.custom-checkout-form-mandatory .checkbox').each(function() {\n                if (!this.checked) {\n                    this.parentNode.classList.add(\"_error\");\n                    valid = false;\n                }\n            });\n            if (!valid) {\n                e.stopPropagation();\n            }\n            return valid;\n        });\n        return target.extend(mixin);\n    };\n});\n","Torresani_Consent/js/view/custom-checkout-form.js":"/*global define*/\ndefine([\n    'Magento_Ui/js/form/form'\n], function(Component) {\n    'use strict';\n    return Component.extend({\n        initialize: function () {\n            this._super();\n            return this;\n        },\n\n        /**\n         * Form submit handler\n         *\n         * This method can have any name.\n         */\n        onSubmit: function() {\n            this.source.set('params.invalid', false);\n            this.source.trigger('customCheckoutForm.data.validate');\n\n            // verify that form data is valid\n            if (!this.source.get('params.invalid')) {\n                // data is retrieved from data provider by value of the customScope property\n                var formData = this.source.get('customCheckoutForm');\n                // do something with form data\n //               console.dir(formData);\n            }\n        }\n    });\n});\n","jquery/jquery.metadata.js":"/*\n * Metadata - jQuery plugin for parsing metadata from elements\n *\n * Copyright (c) 2006 John Resig, Yehuda Katz, J\u00ef\u00bf\u00bd\u00c3\u00b6rn Zaefferer, Paul McLanahan\n *\n * Dual licensed under the MIT and GPL licenses:\n *   http://www.opensource.org/licenses/mit-license.php\n *   http://www.gnu.org/licenses/gpl.html\n *\n * Revision: $Id: jquery.metadata.js 3640 2007-10-11 18:34:38Z pmclanahan $\n *\n */\n\n/**\n * Sets the type of metadata to use. Metadata is encoded in JSON, and each property\n * in the JSON will become a property of the element itself.\n *\n * There are four supported types of metadata storage:\n *\n *   attr:  Inside an attribute. The name parameter indicates *which* attribute.\n *\n *   class: Inside the class attribute, wrapped in curly braces: { }\n *\n *   elem:  Inside a child element (e.g. a script tag). The\n *          name parameter indicates *which* element.\n *   html5: Values are stored in data-* attributes.\n *\n * The metadata for an element is loaded the first time the element is accessed via jQuery.\n *\n * As a result, you can define the metadata type, use $(expr) to load the metadata into the elements\n * matched by expr, then redefine the metadata type and run another $(expr) for other elements.\n *\n * @name $.metadata.setType\n *\n * @example <p id=\"one\" class=\"some_class {item_id: 1, item_label: 'Label'}\">This is a p</p>\n * @before $.metadata.setType(\"class\")\n * @after $(\"#one\").metadata().item_id == 1; $(\"#one\").metadata().item_label == \"Label\"\n * @desc Reads metadata from the class attribute\n *\n * @example <p id=\"one\" class=\"some_class\" data=\"{item_id: 1, item_label: 'Label'}\">This is a p</p>\n * @before $.metadata.setType(\"attr\", \"data\")\n * @after $(\"#one\").metadata().item_id == 1; $(\"#one\").metadata().item_label == \"Label\"\n * @desc Reads metadata from a \"data\" attribute\n *\n * @example <p id=\"one\" class=\"some_class\"><script>{item_id: 1, item_label: 'Label'}</script>This is a p</p>\n * @before $.metadata.setType(\"elem\", \"script\")\n * @after $(\"#one\").metadata().item_id == 1; $(\"#one\").metadata().item_label == \"Label\"\n * @desc Reads metadata from a nested script element\n *\n * @example <p id=\"one\" class=\"some_class\" data-item_id=\"1\" data-item_label=\"Label\">This is a p</p>\n * @before $.metadata.setType(\"html5\")\n * @after $(\"#one\").metadata().item_id == 1; $(\"#one\").metadata().item_label == \"Label\"\n * @desc Reads metadata from a series of data-* attributes\n *\n * @param String type The encoding type\n * @param String name The name of the attribute to be used to get metadata (optional)\n * @cat Plugins/Metadata\n * @descr Sets the type of encoding to be used when loading metadata for the first time\n * @type undefined\n * @see metadata()\n */\n(function (factory) {\n    if (typeof define === 'function' && define.amd) {\n        define([\"jquery\"], factory);\n    } else {\n        factory(jQuery);\n    }\n}(function ($) {\n\n\n    $.extend({\n        metadata : {\n            defaults : {\n                type: 'class',\n                name: 'metadata',\n                cre: /({.*})/,\n                single: 'metadata',\n                meta:'validate'\n            },\n            setType: function( type, name ){\n                this.defaults.type = type;\n                this.defaults.name = name;\n            },\n            get: function( elem, opts ){\n                var settings = $.extend({},this.defaults,opts);\n                // check for empty string in single property\n                if (!settings.single.length) {\n                    settings.single = 'metadata';\n                }\n                if (!settings.meta.length) {\n                    settings.meta = 'validate';\n                }\n\n                var data = $.data(elem, settings.single);\n                // returned cached data if it already exists\n                if ( data ) return data;\n\n                data = \"{}\";\n\n                var getData = function(data) {\n                    if(typeof data != \"string\") return data;\n\n                    if( data.indexOf('{') < 0 ) {\n                        data = eval(\"(\" + data + \")\");\n                    }\n                }\n\n                var getObject = function(data) {\n                    if(typeof data != \"string\") return data;\n\n                    data = eval(\"(\" + data + \")\");\n                    return data;\n                }\n\n                if ( settings.type == \"html5\" ) {\n                    var object = {};\n                    $( elem.attributes ).each(function() {\n                        var name = this.nodeName;\n                        if (name.indexOf('data-' + settings.meta) === 0) {\n                            name = name.replace(/^data-/, '');\n                        }\n                        else {\n                            return true;\n                        }\n                        object[name] = getObject(this.value);\n                    });\n                } else {\n                    if ( settings.type == \"class\" ) {\n                        var m = settings.cre.exec( elem.className );\n                        if ( m )\n                            data = m[1];\n                    } else if ( settings.type == \"elem\" ) {\n                        if( !elem.getElementsByTagName ) return;\n                        var e = elem.getElementsByTagName(settings.name);\n                        if ( e.length )\n                            data = $.trim(e[0].innerHTML);\n                    } else if ( elem.getAttribute != undefined ) {\n                        var attr = elem.getAttribute( settings.name );\n                        if ( attr )\n                            data = attr;\n                    }\n                    object = getObject(data.indexOf(\"{\") < 0 ? \"{\" + data + \"}\" : data);\n                }\n\n                $.data( elem, settings.single, object );\n                return object;\n            }\n        }\n    });\n\n    /**\n     * Returns the metadata object for the first member of the jQuery object.\n     *\n     * @name metadata\n     * @descr Returns element's metadata object\n     * @param Object opts An object contianing settings to override the defaults\n     * @type jQuery\n     * @cat Plugins/Metadata\n     */\n    $.fn.metadata = function( opts ){\n        return $.metadata.get( this[0], opts );\n    };\n\n}));","jquery/jquery-ui-timepicker-addon.js":"/*! jQuery Timepicker Addon - v1.6.3 - 2016-04-20\n* http://trentrichardson.com/examples/timepicker\n* Copyright (c) 2016 Trent Richardson; Licensed MIT */\n(function (factory) {\n    if (typeof define === 'function' && define.amd) {\n        define(['jquery', 'jquery/ui'], factory);\n    } else {\n        factory(jQuery);\n    }\n}(function ($) {\n\n    /*\n    * Lets not redefine timepicker, Prevent \"Uncaught RangeError: Maximum call stack size exceeded\"\n    */\n    $.ui.timepicker = $.ui.timepicker || {};\n    if ($.ui.timepicker.version) {\n        return;\n    }\n\n    /*\n    * Extend jQueryUI, get it started with our version number\n    */\n    $.extend($.ui, {\n        timepicker: {\n            version: \"1.6.3\"\n        }\n    });\n\n    /*\n    * Timepicker manager.\n    * Use the singleton instance of this class, $.timepicker, to interact with the time picker.\n    * Settings for (groups of) time pickers are maintained in an instance object,\n    * allowing multiple different settings on the same page.\n    */\n    var Timepicker = function () {\n        this.regional = []; // Available regional settings, indexed by language code\n        this.regional[''] = { // Default regional settings\n            currentText: 'Now',\n            closeText: 'Done',\n            amNames: ['AM', 'A'],\n            pmNames: ['PM', 'P'],\n            timeFormat: 'HH:mm',\n            timeSuffix: '',\n            timeOnlyTitle: 'Choose Time',\n            timeText: 'Time',\n            hourText: 'Hour',\n            minuteText: 'Minute',\n            secondText: 'Second',\n            millisecText: 'Millisecond',\n            microsecText: 'Microsecond',\n            timezoneText: 'Time Zone',\n            isRTL: false\n        };\n        this._defaults = { // Global defaults for all the datetime picker instances\n            showButtonPanel: true,\n            timeOnly: false,\n            timeOnlyShowDate: false,\n            showHour: null,\n            showMinute: null,\n            showSecond: null,\n            showMillisec: null,\n            showMicrosec: null,\n            showTimezone: null,\n            showTime: true,\n            stepHour: 1,\n            stepMinute: 1,\n            stepSecond: 1,\n            stepMillisec: 1,\n            stepMicrosec: 1,\n            hour: 0,\n            minute: 0,\n            second: 0,\n            millisec: 0,\n            microsec: 0,\n            timezone: null,\n            hourMin: 0,\n            minuteMin: 0,\n            secondMin: 0,\n            millisecMin: 0,\n            microsecMin: 0,\n            hourMax: 23,\n            minuteMax: 59,\n            secondMax: 59,\n            millisecMax: 999,\n            microsecMax: 999,\n            minDateTime: null,\n            maxDateTime: null,\n            maxTime: null,\n            minTime: null,\n            onSelect: null,\n            hourGrid: 0,\n            minuteGrid: 0,\n            secondGrid: 0,\n            millisecGrid: 0,\n            microsecGrid: 0,\n            alwaysSetTime: true,\n            separator: ' ',\n            altFieldTimeOnly: true,\n            altTimeFormat: null,\n            altSeparator: null,\n            altTimeSuffix: null,\n            altRedirectFocus: true,\n            pickerTimeFormat: null,\n            pickerTimeSuffix: null,\n            showTimepicker: true,\n            timezoneList: null,\n            addSliderAccess: false,\n            sliderAccessArgs: null,\n            controlType: 'slider',\n            oneLine: false,\n            defaultValue: null,\n            parse: 'strict',\n            afterInject: null\n        };\n        $.extend(this._defaults, this.regional['']);\n    };\n\n    $.extend(Timepicker.prototype, {\n        $input: null,\n        $altInput: null,\n        $timeObj: null,\n        inst: null,\n        hour_slider: null,\n        minute_slider: null,\n        second_slider: null,\n        millisec_slider: null,\n        microsec_slider: null,\n        timezone_select: null,\n        maxTime: null,\n        minTime: null,\n        hour: 0,\n        minute: 0,\n        second: 0,\n        millisec: 0,\n        microsec: 0,\n        timezone: null,\n        hourMinOriginal: null,\n        minuteMinOriginal: null,\n        secondMinOriginal: null,\n        millisecMinOriginal: null,\n        microsecMinOriginal: null,\n        hourMaxOriginal: null,\n        minuteMaxOriginal: null,\n        secondMaxOriginal: null,\n        millisecMaxOriginal: null,\n        microsecMaxOriginal: null,\n        ampm: '',\n        formattedDate: '',\n        formattedTime: '',\n        formattedDateTime: '',\n        timezoneList: null,\n        units: ['hour', 'minute', 'second', 'millisec', 'microsec'],\n        support: {},\n        control: null,\n\n        /*\n        * Override the default settings for all instances of the time picker.\n        * @param  {Object} settings  object - the new settings to use as defaults (anonymous object)\n        * @return {Object} the manager object\n        */\n        setDefaults: function (settings) {\n            extendRemove(this._defaults, settings || {});\n            return this;\n        },\n\n        /*\n        * Create a new Timepicker instance\n        */\n        _newInst: function ($input, opts) {\n            var tp_inst = new Timepicker(),\n                inlineSettings = {},\n                fns = {},\n                overrides, i;\n\n            for (var attrName in this._defaults) {\n                if (this._defaults.hasOwnProperty(attrName)) {\n                    var attrValue = $input.attr('time:' + attrName);\n                    if (attrValue) {\n                        try {\n                            inlineSettings[attrName] = eval(attrValue);\n                        } catch (err) {\n                            inlineSettings[attrName] = attrValue;\n                        }\n                    }\n                }\n            }\n\n            overrides = {\n                beforeShow: function (input, dp_inst) {\n                    if ($.isFunction(tp_inst._defaults.evnts.beforeShow)) {\n                        return tp_inst._defaults.evnts.beforeShow.call($input[0], input, dp_inst, tp_inst);\n                    }\n                },\n                onChangeMonthYear: function (year, month, dp_inst) {\n                    // Update the time as well : this prevents the time from disappearing from the $input field.\n                    // tp_inst._updateDateTime(dp_inst);\n                    if ($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)) {\n                        tp_inst._defaults.evnts.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst);\n                    }\n                },\n                onClose: function (dateText, dp_inst) {\n                    if (tp_inst.timeDefined === true && $input.val() !== '') {\n                        tp_inst._updateDateTime(dp_inst);\n                    }\n                    if ($.isFunction(tp_inst._defaults.evnts.onClose)) {\n                        tp_inst._defaults.evnts.onClose.call($input[0], dateText, dp_inst, tp_inst);\n                    }\n                }\n            };\n            for (i in overrides) {\n                if (overrides.hasOwnProperty(i)) {\n                    fns[i] = opts[i] || this._defaults[i] || null;\n                }\n            }\n\n            tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, opts, overrides, {\n                evnts: fns,\n                timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');\n            });\n            tp_inst.amNames = $.map(tp_inst._defaults.amNames, function (val) {\n                return val.toUpperCase();\n            });\n            tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function (val) {\n                return val.toUpperCase();\n            });\n\n            // detect which units are supported\n            tp_inst.support = detectSupport(\n                tp_inst._defaults.timeFormat +\n                (tp_inst._defaults.pickerTimeFormat ? tp_inst._defaults.pickerTimeFormat : '') +\n                (tp_inst._defaults.altTimeFormat ? tp_inst._defaults.altTimeFormat : ''));\n\n            // controlType is string - key to our this._controls\n            if (typeof(tp_inst._defaults.controlType) === 'string') {\n                if (tp_inst._defaults.controlType === 'slider' && typeof($.ui.slider) === 'undefined') {\n                    tp_inst._defaults.controlType = 'select';\n                }\n                tp_inst.control = tp_inst._controls[tp_inst._defaults.controlType];\n            }\n            // controlType is an object and must implement create, options, value methods\n            else {\n                tp_inst.control = tp_inst._defaults.controlType;\n            }\n\n            // prep the timezone options\n            var timezoneList = [-720, -660, -600, -570, -540, -480, -420, -360, -300, -270, -240, -210, -180, -120, -60,\n                0, 60, 120, 180, 210, 240, 270, 300, 330, 345, 360, 390, 420, 480, 525, 540, 570, 600, 630, 660, 690, 720, 765, 780, 840];\n            if (tp_inst._defaults.timezoneList !== null) {\n                timezoneList = tp_inst._defaults.timezoneList;\n            }\n            var tzl = timezoneList.length, tzi = 0, tzv = null;\n            if (tzl > 0 && typeof timezoneList[0] !== 'object') {\n                for (; tzi < tzl; tzi++) {\n                    tzv = timezoneList[tzi];\n                    timezoneList[tzi] = { value: tzv, label: $.timepicker.timezoneOffsetString(tzv, tp_inst.support.iso8601) };\n                }\n            }\n            tp_inst._defaults.timezoneList = timezoneList;\n\n            // set the default units\n            tp_inst.timezone = tp_inst._defaults.timezone !== null ? $.timepicker.timezoneOffsetNumber(tp_inst._defaults.timezone) :\n                ((new Date()).getTimezoneOffset() * -1);\n            tp_inst.hour = tp_inst._defaults.hour < tp_inst._defaults.hourMin ? tp_inst._defaults.hourMin :\n                tp_inst._defaults.hour > tp_inst._defaults.hourMax ? tp_inst._defaults.hourMax : tp_inst._defaults.hour;\n            tp_inst.minute = tp_inst._defaults.minute < tp_inst._defaults.minuteMin ? tp_inst._defaults.minuteMin :\n                tp_inst._defaults.minute > tp_inst._defaults.minuteMax ? tp_inst._defaults.minuteMax : tp_inst._defaults.minute;\n            tp_inst.second = tp_inst._defaults.second < tp_inst._defaults.secondMin ? tp_inst._defaults.secondMin :\n                tp_inst._defaults.second > tp_inst._defaults.secondMax ? tp_inst._defaults.secondMax : tp_inst._defaults.second;\n            tp_inst.millisec = tp_inst._defaults.millisec < tp_inst._defaults.millisecMin ? tp_inst._defaults.millisecMin :\n                tp_inst._defaults.millisec > tp_inst._defaults.millisecMax ? tp_inst._defaults.millisecMax : tp_inst._defaults.millisec;\n            tp_inst.microsec = tp_inst._defaults.microsec < tp_inst._defaults.microsecMin ? tp_inst._defaults.microsecMin :\n                tp_inst._defaults.microsec > tp_inst._defaults.microsecMax ? tp_inst._defaults.microsecMax : tp_inst._defaults.microsec;\n            tp_inst.ampm = '';\n            tp_inst.$input = $input;\n\n            if (tp_inst._defaults.altField) {\n                tp_inst.$altInput = $(tp_inst._defaults.altField);\n                if (tp_inst._defaults.altRedirectFocus === true) {\n                    tp_inst.$altInput.css({\n                        cursor: 'pointer'\n                    }).focus(function () {\n                        $input.trigger(\"focus\");\n                    });\n                }\n            }\n\n            if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) {\n                tp_inst._defaults.minDate = new Date();\n            }\n            if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) {\n                tp_inst._defaults.maxDate = new Date();\n            }\n\n            // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime..\n            if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) {\n                tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime());\n            }\n            if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) {\n                tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime());\n            }\n            if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) {\n                tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime());\n            }\n            if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) {\n                tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime());\n            }\n            tp_inst.$input.bind('focus', function () {\n                tp_inst._onFocus();\n            });\n\n            return tp_inst;\n        },\n\n        /*\n        * add our sliders to the calendar\n        */\n        _addTimePicker: function (dp_inst) {\n            var currDT = $.trim((this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val());\n\n            this.timeDefined = this._parseTime(currDT);\n            this._limitMinMaxDateTime(dp_inst, false);\n            this._injectTimePicker();\n            this._afterInject();\n        },\n\n        /*\n        * parse the time string from input value or _setTime\n        */\n        _parseTime: function (timeString, withDate) {\n            if (!this.inst) {\n                this.inst = $.datepicker._getInst(this.$input[0]);\n            }\n\n            if (withDate || !this._defaults.timeOnly) {\n                var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');\n                try {\n                    var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults);\n                    if (!parseRes.timeObj) {\n                        return false;\n                    }\n                    $.extend(this, parseRes.timeObj);\n                } catch (err) {\n                    $.timepicker.log(\"Error parsing the date/time string: \" + err +\n                        \"\\ndate/time string = \" + timeString +\n                        \"\\ntimeFormat = \" + this._defaults.timeFormat +\n                        \"\\ndateFormat = \" + dp_dateFormat);\n                    return false;\n                }\n                return true;\n            } else {\n                var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults);\n                if (!timeObj) {\n                    return false;\n                }\n                $.extend(this, timeObj);\n                return true;\n            }\n        },\n\n        /*\n        * Handle callback option after injecting timepicker\n        */\n        _afterInject: function() {\n            var o = this.inst.settings;\n            if ($.isFunction(o.afterInject)) {\n                o.afterInject.call(this);\n            }\n        },\n\n        /*\n        * generate and inject html for timepicker into ui datepicker\n        */\n        _injectTimePicker: function () {\n            var $dp = this.inst.dpDiv,\n                o = this.inst.settings,\n                tp_inst = this,\n                litem = '',\n                uitem = '',\n                show = null,\n                max = {},\n                gridSize = {},\n                size = null,\n                i = 0,\n                l = 0;\n\n            // Prevent displaying twice\n            if ($dp.find(\"div.ui-timepicker-div\").length === 0 && o.showTimepicker) {\n                var noDisplay = ' ui_tpicker_unit_hide',\n                    html = '<div class=\"ui-timepicker-div' + (o.isRTL ? ' ui-timepicker-rtl' : '') + (o.oneLine && o.controlType === 'select' ? ' ui-timepicker-oneLine' : '') + '\"><dl>' + '<dt class=\"ui_tpicker_time_label' + ((o.showTime) ? '' : noDisplay) + '\">' + o.timeText + '</dt>' +\n                        '<dd class=\"ui_tpicker_time '+ ((o.showTime) ? '' : noDisplay) + '\"><input class=\"ui_tpicker_time_input\" ' + (o.timeInput ? '' : 'disabled') + '/></dd>';\n\n                // Create the markup\n                for (i = 0, l = this.units.length; i < l; i++) {\n                    litem = this.units[i];\n                    uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);\n                    show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];\n\n                    // Added by Peter Medeiros:\n                    // - Figure out what the hour/minute/second max should be based on the step values.\n                    // - Example: if stepMinute is 15, then minMax is 45.\n                    max[litem] = parseInt((o[litem + 'Max'] - ((o[litem + 'Max'] - o[litem + 'Min']) % o['step' + uitem])), 10);\n                    gridSize[litem] = 0;\n\n                    html += '<dt class=\"ui_tpicker_' + litem + '_label' + (show ? '' : noDisplay) + '\">' + o[litem + 'Text'] + '</dt>' +\n                        '<dd class=\"ui_tpicker_' + litem + (show ? '' : noDisplay) + '\"><div class=\"ui_tpicker_' + litem + '_slider' + (show ? '' : noDisplay) + '\"></div>';\n\n                    if (show && o[litem + 'Grid'] > 0) {\n                        html += '<div style=\"padding-left: 1px\"><table class=\"ui-tpicker-grid-label\"><tr>';\n\n                        if (litem === 'hour') {\n                            for (var h = o[litem + 'Min']; h <= max[litem]; h += parseInt(o[litem + 'Grid'], 10)) {\n                                gridSize[litem]++;\n                                var tmph = $.datepicker.formatTime(this.support.ampm ? 'hht' : 'HH', {hour: h}, o);\n                                html += '<td data-for=\"' + litem + '\">' + tmph + '</td>';\n                            }\n                        }\n                        else {\n                            for (var m = o[litem + 'Min']; m <= max[litem]; m += parseInt(o[litem + 'Grid'], 10)) {\n                                gridSize[litem]++;\n                                html += '<td data-for=\"' + litem + '\">' + ((m < 10) ? '0' : '') + m + '</td>';\n                            }\n                        }\n\n                        html += '</tr></table></div>';\n                    }\n                    html += '</dd>';\n                }\n\n                // Timezone\n                var showTz = o.showTimezone !== null ? o.showTimezone : this.support.timezone;\n                html += '<dt class=\"ui_tpicker_timezone_label' + (showTz ? '' : noDisplay) + '\">' + o.timezoneText + '</dt>';\n                html += '<dd class=\"ui_tpicker_timezone' + (showTz ? '' : noDisplay) + '\"></dd>';\n\n                // Create the elements from string\n                html += '</dl></div>';\n                var $tp = $(html);\n\n                // if we only want time picker...\n                if (o.timeOnly === true) {\n                    $tp.prepend('<div class=\"ui-widget-header ui-helper-clearfix ui-corner-all\">' + '<div class=\"ui-datepicker-title\">' + o.timeOnlyTitle + '</div>' + '</div>');\n                    $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide();\n                }\n\n                // add sliders, adjust grids, add events\n                for (i = 0, l = tp_inst.units.length; i < l; i++) {\n                    litem = tp_inst.units[i];\n                    uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);\n                    show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];\n\n                    // add the slider\n                    tp_inst[litem + '_slider'] = tp_inst.control.create(tp_inst, $tp.find('.ui_tpicker_' + litem + '_slider'), litem, tp_inst[litem], o[litem + 'Min'], max[litem], o['step' + uitem]);\n\n                    // adjust the grid and add click event\n                    if (show && o[litem + 'Grid'] > 0) {\n                        size = 100 * gridSize[litem] * o[litem + 'Grid'] / (max[litem] - o[litem + 'Min']);\n                        $tp.find('.ui_tpicker_' + litem + ' table').css({\n                            width: size + \"%\",\n                            marginLeft: o.isRTL ? '0' : ((size / (-2 * gridSize[litem])) + \"%\"),\n                            marginRight: o.isRTL ? ((size / (-2 * gridSize[litem])) + \"%\") : '0',\n                            borderCollapse: 'collapse'\n                        }).find(\"td\").click(function (e) {\n                            var $t = $(this),\n                                h = $t.html(),\n                                n = parseInt(h.replace(/[^0-9]/g), 10),\n                                ap = h.replace(/[^apm]/ig),\n                                f = $t.data('for'); // loses scope, so we use data-for\n\n                            if (f === 'hour') {\n                                if (ap.indexOf('p') !== -1 && n < 12) {\n                                    n += 12;\n                                }\n                                else {\n                                    if (ap.indexOf('a') !== -1 && n === 12) {\n                                        n = 0;\n                                    }\n                                }\n                            }\n\n                            tp_inst.control.value(tp_inst, tp_inst[f + '_slider'], litem, n);\n\n                            tp_inst._onTimeChange();\n                            tp_inst._onSelectHandler();\n                        }).css({\n                            cursor: 'pointer',\n                            width: (100 / gridSize[litem]) + '%',\n                            textAlign: 'center',\n                            overflow: 'hidden'\n                        });\n                    } // end if grid > 0\n                } // end for loop\n\n                // Add timezone options\n                this.timezone_select = $tp.find('.ui_tpicker_timezone').append('<select></select>').find(\"select\");\n                $.fn.append.apply(this.timezone_select,\n                    $.map(o.timezoneList, function (val, idx) {\n                        return $(\"<option />\").val(typeof val === \"object\" ? val.value : val).text(typeof val === \"object\" ? val.label : val);\n                    }));\n                if (typeof(this.timezone) !== \"undefined\" && this.timezone !== null && this.timezone !== \"\") {\n                    var local_timezone = (new Date(this.inst.selectedYear, this.inst.selectedMonth, this.inst.selectedDay, 12)).getTimezoneOffset() * -1;\n                    if (local_timezone === this.timezone) {\n                        selectLocalTimezone(tp_inst);\n                    } else {\n                        this.timezone_select.val(this.timezone);\n                    }\n                } else {\n                    if (typeof(this.hour) !== \"undefined\" && this.hour !== null && this.hour !== \"\") {\n                        this.timezone_select.val(o.timezone);\n                    } else {\n                        selectLocalTimezone(tp_inst);\n                    }\n                }\n                this.timezone_select.change(function () {\n                    tp_inst._onTimeChange();\n                    tp_inst._onSelectHandler();\n                    tp_inst._afterInject();\n                });\n                // End timezone options\n\n                // inject timepicker into datepicker\n                var $buttonPanel = $dp.find('.ui-datepicker-buttonpane');\n                if ($buttonPanel.length) {\n                    $buttonPanel.before($tp);\n                } else {\n                    $dp.append($tp);\n                }\n\n                this.$timeObj = $tp.find('.ui_tpicker_time_input');\n                this.$timeObj.change(function () {\n                    var timeFormat = tp_inst.inst.settings.timeFormat;\n                    var parsedTime = $.datepicker.parseTime(timeFormat, this.value);\n                    var update = new Date();\n                    if (parsedTime) {\n                        update.setHours(parsedTime.hour);\n                        update.setMinutes(parsedTime.minute);\n                        update.setSeconds(parsedTime.second);\n                        $.datepicker._setTime(tp_inst.inst, update);\n                    } else {\n                        this.value = tp_inst.formattedTime;\n                        this.blur();\n                    }\n                });\n\n                if (this.inst !== null) {\n                    var timeDefined = this.timeDefined;\n                    this._onTimeChange();\n                    this.timeDefined = timeDefined;\n                }\n\n                // slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/\n                if (this._defaults.addSliderAccess) {\n                    var sliderAccessArgs = this._defaults.sliderAccessArgs,\n                        rtl = this._defaults.isRTL;\n                    sliderAccessArgs.isRTL = rtl;\n\n                    setTimeout(function () { // fix for inline mode\n                        if ($tp.find('.ui-slider-access').length === 0) {\n                            $tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs);\n\n                            // fix any grids since sliders are shorter\n                            var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true);\n                            if (sliderAccessWidth) {\n                                $tp.find('table:visible').each(function () {\n                                    var $g = $(this),\n                                        oldWidth = $g.outerWidth(),\n                                        oldMarginLeft = $g.css(rtl ? 'marginRight' : 'marginLeft').toString().replace('%', ''),\n                                        newWidth = oldWidth - sliderAccessWidth,\n                                        newMarginLeft = ((oldMarginLeft * newWidth) / oldWidth) + '%',\n                                        css = { width: newWidth, marginRight: 0, marginLeft: 0 };\n                                    css[rtl ? 'marginRight' : 'marginLeft'] = newMarginLeft;\n                                    $g.css(css);\n                                });\n                            }\n                        }\n                    }, 10);\n                }\n                // end slideAccess integration\n\n                tp_inst._limitMinMaxDateTime(this.inst, true);\n            }\n        },\n\n        /*\n        * This function tries to limit the ability to go outside the\n        * min/max date range\n        */\n        _limitMinMaxDateTime: function (dp_inst, adjustSliders) {\n            var o = this._defaults,\n                dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay);\n\n            if (!this._defaults.showTimepicker) {\n                return;\n            } // No time so nothing to check here\n\n            if ($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date) {\n                var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'),\n                    minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0);\n\n                if (this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null || this.microsecMinOriginal === null) {\n                    this.hourMinOriginal = o.hourMin;\n                    this.minuteMinOriginal = o.minuteMin;\n                    this.secondMinOriginal = o.secondMin;\n                    this.millisecMinOriginal = o.millisecMin;\n                    this.microsecMinOriginal = o.microsecMin;\n                }\n\n                if (dp_inst.settings.timeOnly || minDateTimeDate.getTime() === dp_date.getTime()) {\n                    this._defaults.hourMin = minDateTime.getHours();\n                    if (this.hour <= this._defaults.hourMin) {\n                        this.hour = this._defaults.hourMin;\n                        this._defaults.minuteMin = minDateTime.getMinutes();\n                        if (this.minute <= this._defaults.minuteMin) {\n                            this.minute = this._defaults.minuteMin;\n                            this._defaults.secondMin = minDateTime.getSeconds();\n                            if (this.second <= this._defaults.secondMin) {\n                                this.second = this._defaults.secondMin;\n                                this._defaults.millisecMin = minDateTime.getMilliseconds();\n                                if (this.millisec <= this._defaults.millisecMin) {\n                                    this.millisec = this._defaults.millisecMin;\n                                    this._defaults.microsecMin = minDateTime.getMicroseconds();\n                                } else {\n                                    if (this.microsec < this._defaults.microsecMin) {\n                                        this.microsec = this._defaults.microsecMin;\n                                    }\n                                    this._defaults.microsecMin = this.microsecMinOriginal;\n                                }\n                            } else {\n                                this._defaults.millisecMin = this.millisecMinOriginal;\n                                this._defaults.microsecMin = this.microsecMinOriginal;\n                            }\n                        } else {\n                            this._defaults.secondMin = this.secondMinOriginal;\n                            this._defaults.millisecMin = this.millisecMinOriginal;\n                            this._defaults.microsecMin = this.microsecMinOriginal;\n                        }\n                    } else {\n                        this._defaults.minuteMin = this.minuteMinOriginal;\n                        this._defaults.secondMin = this.secondMinOriginal;\n                        this._defaults.millisecMin = this.millisecMinOriginal;\n                        this._defaults.microsecMin = this.microsecMinOriginal;\n                    }\n                } else {\n                    this._defaults.hourMin = this.hourMinOriginal;\n                    this._defaults.minuteMin = this.minuteMinOriginal;\n                    this._defaults.secondMin = this.secondMinOriginal;\n                    this._defaults.millisecMin = this.millisecMinOriginal;\n                    this._defaults.microsecMin = this.microsecMinOriginal;\n                }\n            }\n\n            if ($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date) {\n                var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'),\n                    maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0);\n\n                if (this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null || this.millisecMaxOriginal === null) {\n                    this.hourMaxOriginal = o.hourMax;\n                    this.minuteMaxOriginal = o.minuteMax;\n                    this.secondMaxOriginal = o.secondMax;\n                    this.millisecMaxOriginal = o.millisecMax;\n                    this.microsecMaxOriginal = o.microsecMax;\n                }\n\n                if (dp_inst.settings.timeOnly || maxDateTimeDate.getTime() === dp_date.getTime()) {\n                    this._defaults.hourMax = maxDateTime.getHours();\n                    if (this.hour >= this._defaults.hourMax) {\n                        this.hour = this._defaults.hourMax;\n                        this._defaults.minuteMax = maxDateTime.getMinutes();\n                        if (this.minute >= this._defaults.minuteMax) {\n                            this.minute = this._defaults.minuteMax;\n                            this._defaults.secondMax = maxDateTime.getSeconds();\n                            if (this.second >= this._defaults.secondMax) {\n                                this.second = this._defaults.secondMax;\n                                this._defaults.millisecMax = maxDateTime.getMilliseconds();\n                                if (this.millisec >= this._defaults.millisecMax) {\n                                    this.millisec = this._defaults.millisecMax;\n                                    this._defaults.microsecMax = maxDateTime.getMicroseconds();\n                                } else {\n                                    if (this.microsec > this._defaults.microsecMax) {\n                                        this.microsec = this._defaults.microsecMax;\n                                    }\n                                    this._defaults.microsecMax = this.microsecMaxOriginal;\n                                }\n                            } else {\n                                this._defaults.millisecMax = this.millisecMaxOriginal;\n                                this._defaults.microsecMax = this.microsecMaxOriginal;\n                            }\n                        } else {\n                            this._defaults.secondMax = this.secondMaxOriginal;\n                            this._defaults.millisecMax = this.millisecMaxOriginal;\n                            this._defaults.microsecMax = this.microsecMaxOriginal;\n                        }\n                    } else {\n                        this._defaults.minuteMax = this.minuteMaxOriginal;\n                        this._defaults.secondMax = this.secondMaxOriginal;\n                        this._defaults.millisecMax = this.millisecMaxOriginal;\n                        this._defaults.microsecMax = this.microsecMaxOriginal;\n                    }\n                } else {\n                    this._defaults.hourMax = this.hourMaxOriginal;\n                    this._defaults.minuteMax = this.minuteMaxOriginal;\n                    this._defaults.secondMax = this.secondMaxOriginal;\n                    this._defaults.millisecMax = this.millisecMaxOriginal;\n                    this._defaults.microsecMax = this.microsecMaxOriginal;\n                }\n            }\n\n            if (dp_inst.settings.minTime!==null) {\n                var tempMinTime=new Date(\"01/01/1970 \" + dp_inst.settings.minTime);\n                if (this.hour<tempMinTime.getHours()) {\n                    this.hour=this._defaults.hourMin=tempMinTime.getHours();\n                    this.minute=this._defaults.minuteMin=tempMinTime.getMinutes();\n                } else if (this.hour===tempMinTime.getHours() && this.minute<tempMinTime.getMinutes()) {\n                    this.minute=this._defaults.minuteMin=tempMinTime.getMinutes();\n                } else {\n                    if (this._defaults.hourMin<tempMinTime.getHours()) {\n                        this._defaults.hourMin=tempMinTime.getHours();\n                        this._defaults.minuteMin=tempMinTime.getMinutes();\n                    } else if (this._defaults.hourMin===tempMinTime.getHours()===this.hour && this._defaults.minuteMin<tempMinTime.getMinutes()) {\n                        this._defaults.minuteMin=tempMinTime.getMinutes();\n                    } else {\n                        this._defaults.minuteMin=0;\n                    }\n                }\n            }\n\n            if (dp_inst.settings.maxTime!==null) {\n                var tempMaxTime=new Date(\"01/01/1970 \" + dp_inst.settings.maxTime);\n                if (this.hour>tempMaxTime.getHours()) {\n                    this.hour=this._defaults.hourMax=tempMaxTime.getHours();\n                    this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes();\n                } else if (this.hour===tempMaxTime.getHours() && this.minute>tempMaxTime.getMinutes()) {\n                    this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes();\n                } else {\n                    if (this._defaults.hourMax>tempMaxTime.getHours()) {\n                        this._defaults.hourMax=tempMaxTime.getHours();\n                        this._defaults.minuteMax=tempMaxTime.getMinutes();\n                    } else if (this._defaults.hourMax===tempMaxTime.getHours()===this.hour && this._defaults.minuteMax>tempMaxTime.getMinutes()) {\n                        this._defaults.minuteMax=tempMaxTime.getMinutes();\n                    } else {\n                        this._defaults.minuteMax=59;\n                    }\n                }\n            }\n\n            if (adjustSliders !== undefined && adjustSliders === true) {\n                var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)), 10),\n                    minMax = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)), 10),\n                    secMax = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)), 10),\n                    millisecMax = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)), 10),\n                    microsecMax = parseInt((this._defaults.microsecMax - ((this._defaults.microsecMax - this._defaults.microsecMin) % this._defaults.stepMicrosec)), 10);\n\n                if (this.hour_slider) {\n                    this.control.options(this, this.hour_slider, 'hour', { min: this._defaults.hourMin, max: hourMax, step: this._defaults.stepHour });\n                    this.control.value(this, this.hour_slider, 'hour', this.hour - (this.hour % this._defaults.stepHour));\n                }\n                if (this.minute_slider) {\n                    this.control.options(this, this.minute_slider, 'minute', { min: this._defaults.minuteMin, max: minMax, step: this._defaults.stepMinute });\n                    this.control.value(this, this.minute_slider, 'minute', this.minute - (this.minute % this._defaults.stepMinute));\n                }\n                if (this.second_slider) {\n                    this.control.options(this, this.second_slider, 'second', { min: this._defaults.secondMin, max: secMax, step: this._defaults.stepSecond });\n                    this.control.value(this, this.second_slider, 'second', this.second - (this.second % this._defaults.stepSecond));\n                }\n                if (this.millisec_slider) {\n                    this.control.options(this, this.millisec_slider, 'millisec', { min: this._defaults.millisecMin, max: millisecMax, step: this._defaults.stepMillisec });\n                    this.control.value(this, this.millisec_slider, 'millisec', this.millisec - (this.millisec % this._defaults.stepMillisec));\n                }\n                if (this.microsec_slider) {\n                    this.control.options(this, this.microsec_slider, 'microsec', { min: this._defaults.microsecMin, max: microsecMax, step: this._defaults.stepMicrosec });\n                    this.control.value(this, this.microsec_slider, 'microsec', this.microsec - (this.microsec % this._defaults.stepMicrosec));\n                }\n            }\n\n        },\n\n        /*\n        * when a slider moves, set the internal time...\n        * on time change is also called when the time is updated in the text field\n        */\n        _onTimeChange: function () {\n            if (!this._defaults.showTimepicker) {\n                return;\n            }\n            var hour = (this.hour_slider) ? this.control.value(this, this.hour_slider, 'hour') : false,\n                minute = (this.minute_slider) ? this.control.value(this, this.minute_slider, 'minute') : false,\n                second = (this.second_slider) ? this.control.value(this, this.second_slider, 'second') : false,\n                millisec = (this.millisec_slider) ? this.control.value(this, this.millisec_slider, 'millisec') : false,\n                microsec = (this.microsec_slider) ? this.control.value(this, this.microsec_slider, 'microsec') : false,\n                timezone = (this.timezone_select) ? this.timezone_select.val() : false,\n                o = this._defaults,\n                pickerTimeFormat = o.pickerTimeFormat || o.timeFormat,\n                pickerTimeSuffix = o.pickerTimeSuffix || o.timeSuffix;\n\n            if (typeof(hour) === 'object') {\n                hour = false;\n            }\n            if (typeof(minute) === 'object') {\n                minute = false;\n            }\n            if (typeof(second) === 'object') {\n                second = false;\n            }\n            if (typeof(millisec) === 'object') {\n                millisec = false;\n            }\n            if (typeof(microsec) === 'object') {\n                microsec = false;\n            }\n            if (typeof(timezone) === 'object') {\n                timezone = false;\n            }\n\n            if (hour !== false) {\n                hour = parseInt(hour, 10);\n            }\n            if (minute !== false) {\n                minute = parseInt(minute, 10);\n            }\n            if (second !== false) {\n                second = parseInt(second, 10);\n            }\n            if (millisec !== false) {\n                millisec = parseInt(millisec, 10);\n            }\n            if (microsec !== false) {\n                microsec = parseInt(microsec, 10);\n            }\n            if (timezone !== false) {\n                timezone = timezone.toString();\n            }\n\n            var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0];\n\n            // If the update was done in the input field, the input field should not be updated.\n            // If the update was done using the sliders, update the input field.\n            var hasChanged = (\n                hour !== parseInt(this.hour,10) || // sliders should all be numeric\n                minute !== parseInt(this.minute,10) ||\n                second !== parseInt(this.second,10) ||\n                millisec !== parseInt(this.millisec,10) ||\n                microsec !== parseInt(this.microsec,10) ||\n                (this.ampm.length > 0 && (hour < 12) !== ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1)) ||\n                (this.timezone !== null && timezone !== this.timezone.toString()) // could be numeric or \"EST\" format, so use toString()\n            );\n\n            if (hasChanged) {\n\n                if (hour !== false) {\n                    this.hour = hour;\n                }\n                if (minute !== false) {\n                    this.minute = minute;\n                }\n                if (second !== false) {\n                    this.second = second;\n                }\n                if (millisec !== false) {\n                    this.millisec = millisec;\n                }\n                if (microsec !== false) {\n                    this.microsec = microsec;\n                }\n                if (timezone !== false) {\n                    this.timezone = timezone;\n                }\n\n                if (!this.inst) {\n                    this.inst = $.datepicker._getInst(this.$input[0]);\n                }\n\n                this._limitMinMaxDateTime(this.inst, true);\n            }\n            if (this.support.ampm) {\n                this.ampm = ampm;\n            }\n\n            // Updates the time within the timepicker\n            this.formattedTime = $.datepicker.formatTime(o.timeFormat, this, o);\n            if (this.$timeObj) {\n                if (pickerTimeFormat === o.timeFormat) {\n                    this.$timeObj.val(this.formattedTime + pickerTimeSuffix);\n                }\n                else {\n                    this.$timeObj.val($.datepicker.formatTime(pickerTimeFormat, this, o) + pickerTimeSuffix);\n                }\n                if (this.$timeObj[0].setSelectionRange) {\n                    var sPos = this.$timeObj[0].selectionStart;\n                    var ePos = this.$timeObj[0].selectionEnd;\n                    this.$timeObj[0].setSelectionRange(sPos, ePos);\n                }\n            }\n\n            this.timeDefined = true;\n            if (hasChanged) {\n                this._updateDateTime();\n                //this.$input.focus(); // may automatically open the picker on setDate\n            }\n        },\n\n        /*\n        * call custom onSelect.\n        * bind to sliders slidestop, and grid click.\n        */\n        _onSelectHandler: function () {\n            var onSelect = this._defaults.onSelect || this.inst.settings.onSelect;\n            var inputEl = this.$input ? this.$input[0] : null;\n            if (onSelect && inputEl) {\n                onSelect.apply(inputEl, [this.formattedDateTime, this]);\n            }\n        },\n\n        /*\n        * update our input with the new date time..\n        */\n        _updateDateTime: function (dp_inst) {\n            dp_inst = this.inst || dp_inst;\n            var dtTmp = (dp_inst.currentYear > 0?\n                new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay) :\n                new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),\n                dt = $.datepicker._daylightSavingAdjust(dtTmp),\n                //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),\n                //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay)),\n                dateFmt = $.datepicker._get(dp_inst, 'dateFormat'),\n                formatCfg = $.datepicker._getFormatConfig(dp_inst),\n                timeAvailable = dt !== null && this.timeDefined;\n            this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg);\n            var formattedDateTime = this.formattedDate;\n\n            // if a slider was changed but datepicker doesn't have a value yet, set it\n            if (dp_inst.lastVal === \"\") {\n                dp_inst.currentYear = dp_inst.selectedYear;\n                dp_inst.currentMonth = dp_inst.selectedMonth;\n                dp_inst.currentDay = dp_inst.selectedDay;\n            }\n\n            /*\n            * remove following lines to force every changes in date picker to change the input value\n            * Bug descriptions: when an input field has a default value, and click on the field to pop up the date picker.\n            * If the user manually empty the value in the input field, the date picker will never change selected value.\n            */\n            //if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) {\n            //\treturn;\n            //}\n\n            if (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === false) {\n                formattedDateTime = this.formattedTime;\n            } else if ((this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) || (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === true)) {\n                formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix;\n            }\n\n            this.formattedDateTime = formattedDateTime;\n\n            if (!this._defaults.showTimepicker) {\n                this.$input.val(this.formattedDate);\n            } else if (this.$altInput && this._defaults.timeOnly === false && this._defaults.altFieldTimeOnly === true) {\n                this.$altInput.val(this.formattedTime);\n                this.$input.val(this.formattedDate);\n            } else if (this.$altInput) {\n                this.$input.val(formattedDateTime);\n                var altFormattedDateTime = '',\n                    altSeparator = this._defaults.altSeparator !== null ? this._defaults.altSeparator : this._defaults.separator,\n                    altTimeSuffix = this._defaults.altTimeSuffix !== null ? this._defaults.altTimeSuffix : this._defaults.timeSuffix;\n\n                if (!this._defaults.timeOnly) {\n                    if (this._defaults.altFormat) {\n                        altFormattedDateTime = $.datepicker.formatDate(this._defaults.altFormat, (dt === null ? new Date() : dt), formatCfg);\n                    }\n                    else {\n                        altFormattedDateTime = this.formattedDate;\n                    }\n\n                    if (altFormattedDateTime) {\n                        altFormattedDateTime += altSeparator;\n                    }\n                }\n\n                if (this._defaults.altTimeFormat !== null) {\n                    altFormattedDateTime += $.datepicker.formatTime(this._defaults.altTimeFormat, this, this._defaults) + altTimeSuffix;\n                }\n                else {\n                    altFormattedDateTime += this.formattedTime + altTimeSuffix;\n                }\n                this.$altInput.val(altFormattedDateTime);\n            } else {\n                this.$input.val(formattedDateTime);\n            }\n\n            this.$input.trigger(\"change\");\n        },\n\n        _onFocus: function () {\n            if (!this.$input.val() && this._defaults.defaultValue) {\n                this.$input.val(this._defaults.defaultValue);\n                var inst = $.datepicker._getInst(this.$input.get(0)),\n                    tp_inst = $.datepicker._get(inst, 'timepicker');\n                if (tp_inst) {\n                    if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {\n                        try {\n                            $.datepicker._updateDatepicker(inst);\n                        } catch (err) {\n                            $.timepicker.log(err);\n                        }\n                    }\n                }\n            }\n        },\n\n        /*\n        * Small abstraction to control types\n        * We can add more, just be sure to follow the pattern: create, options, value\n        */\n        _controls: {\n            // slider methods\n            slider: {\n                create: function (tp_inst, obj, unit, val, min, max, step) {\n                    var rtl = tp_inst._defaults.isRTL; // if rtl go -60->0 instead of 0->60\n                    return obj.prop('slide', null).slider({\n                        orientation: \"horizontal\",\n                        value: rtl ? val * -1 : val,\n                        min: rtl ? max * -1 : min,\n                        max: rtl ? min * -1 : max,\n                        step: step,\n                        slide: function (event, ui) {\n                            tp_inst.control.value(tp_inst, $(this), unit, rtl ? ui.value * -1 : ui.value);\n                            tp_inst._onTimeChange();\n                        },\n                        stop: function (event, ui) {\n                            tp_inst._onSelectHandler();\n                        }\n                    });\n                },\n                options: function (tp_inst, obj, unit, opts, val) {\n                    if (tp_inst._defaults.isRTL) {\n                        if (typeof(opts) === 'string') {\n                            if (opts === 'min' || opts === 'max') {\n                                if (val !== undefined) {\n                                    return obj.slider(opts, val * -1);\n                                }\n                                return Math.abs(obj.slider(opts));\n                            }\n                            return obj.slider(opts);\n                        }\n                        var min = opts.min,\n                            max = opts.max;\n                        opts.min = opts.max = null;\n                        if (min !== undefined) {\n                            opts.max = min * -1;\n                        }\n                        if (max !== undefined) {\n                            opts.min = max * -1;\n                        }\n                        return obj.slider(opts);\n                    }\n                    if (typeof(opts) === 'string' && val !== undefined) {\n                        return obj.slider(opts, val);\n                    }\n                    return obj.slider(opts);\n                },\n                value: function (tp_inst, obj, unit, val) {\n                    if (tp_inst._defaults.isRTL) {\n                        if (val !== undefined) {\n                            return obj.slider('value', val * -1);\n                        }\n                        return Math.abs(obj.slider('value'));\n                    }\n                    if (val !== undefined) {\n                        return obj.slider('value', val);\n                    }\n                    return obj.slider('value');\n                }\n            },\n            // select methods\n            select: {\n                create: function (tp_inst, obj, unit, val, min, max, step) {\n                    var sel = '<select class=\"ui-timepicker-select ui-state-default ui-corner-all\" data-unit=\"' + unit + '\" data-min=\"' + min + '\" data-max=\"' + max + '\" data-step=\"' + step + '\">',\n                        format = tp_inst._defaults.pickerTimeFormat || tp_inst._defaults.timeFormat;\n\n                    for (var i = min; i <= max; i += step) {\n                        sel += '<option value=\"' + i + '\"' + (i === val ? ' selected' : '') + '>';\n                        if (unit === 'hour') {\n                            sel += $.datepicker.formatTime($.trim(format.replace(/[^ht ]/ig, '')), {hour: i}, tp_inst._defaults);\n                        }\n                        else if (unit === 'millisec' || unit === 'microsec' || i >= 10) { sel += i; }\n                        else {sel += '0' + i.toString(); }\n                        sel += '</option>';\n                    }\n                    sel += '</select>';\n\n                    obj.children('select').remove();\n\n                    $(sel).appendTo(obj).change(function (e) {\n                        tp_inst._onTimeChange();\n                        tp_inst._onSelectHandler();\n                        tp_inst._afterInject();\n                    });\n\n                    return obj;\n                },\n                options: function (tp_inst, obj, unit, opts, val) {\n                    var o = {},\n                        $t = obj.children('select');\n                    if (typeof(opts) === 'string') {\n                        if (val === undefined) {\n                            return $t.data(opts);\n                        }\n                        o[opts] = val;\n                    }\n                    else { o = opts; }\n                    return tp_inst.control.create(tp_inst, obj, $t.data('unit'), $t.val(), o.min>=0 ? o.min : $t.data('min'), o.max || $t.data('max'), o.step || $t.data('step'));\n                },\n                value: function (tp_inst, obj, unit, val) {\n                    var $t = obj.children('select');\n                    if (val !== undefined) {\n                        return $t.val(val);\n                    }\n                    return $t.val();\n                }\n            }\n        } // end _controls\n\n    });\n\n    $.fn.extend({\n        /*\n        * shorthand just to use timepicker.\n        */\n        timepicker: function (o) {\n            o = o || {};\n            var tmp_args = Array.prototype.slice.call(arguments);\n\n            if (typeof o === 'object') {\n                tmp_args[0] = $.extend(o, {\n                    timeOnly: true\n                });\n            }\n\n            return $(this).each(function () {\n                $.fn.datetimepicker.apply($(this), tmp_args);\n            });\n        },\n\n        /*\n        * extend timepicker to datepicker\n        */\n        datetimepicker: function (o) {\n            o = o || {};\n            var tmp_args = arguments;\n\n            if (typeof(o) === 'string') {\n                if (o === 'getDate'  || (o === 'option' && tmp_args.length === 2 && typeof (tmp_args[1]) === 'string')) {\n                    return $.fn.datepicker.apply($(this[0]), tmp_args);\n                } else {\n                    return this.each(function () {\n                        var $t = $(this);\n                        $t.datepicker.apply($t, tmp_args);\n                    });\n                }\n            } else {\n                return this.each(function () {\n                    var $t = $(this);\n                    $t.datepicker($.timepicker._newInst($t, o)._defaults);\n                });\n            }\n        }\n    });\n\n    /*\n    * Public Utility to parse date and time\n    */\n    $.datepicker.parseDateTime = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {\n        var parseRes = parseDateTimeInternal(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings);\n        if (parseRes.timeObj) {\n            var t = parseRes.timeObj;\n            parseRes.date.setHours(t.hour, t.minute, t.second, t.millisec);\n            parseRes.date.setMicroseconds(t.microsec);\n        }\n\n        return parseRes.date;\n    };\n\n    /*\n    * Public utility to parse time\n    */\n    $.datepicker.parseTime = function (timeFormat, timeString, options) {\n        var o = extendRemove(extendRemove({}, $.timepicker._defaults), options || {}),\n            iso8601 = (timeFormat.replace(/\\'.*?\\'/g, '').indexOf('Z') !== -1);\n\n        // Strict parse requires the timeString to match the timeFormat exactly\n        var strictParse = function (f, s, o) {\n\n            // pattern for standard and localized AM/PM markers\n            var getPatternAmpm = function (amNames, pmNames) {\n                var markers = [];\n                if (amNames) {\n                    $.merge(markers, amNames);\n                }\n                if (pmNames) {\n                    $.merge(markers, pmNames);\n                }\n                markers = $.map(markers, function (val) {\n                    return val.replace(/[.*+?|()\\[\\]{}\\\\]/g, '\\\\$&');\n                });\n                return '(' + markers.join('|') + ')?';\n            };\n\n            // figure out position of time elements.. cause js cant do named captures\n            var getFormatPositions = function (timeFormat) {\n                var finds = timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|c{1}|t{1,2}|z|'.*?')/g),\n                    orders = {\n                        h: -1,\n                        m: -1,\n                        s: -1,\n                        l: -1,\n                        c: -1,\n                        t: -1,\n                        z: -1\n                    };\n\n                if (finds) {\n                    for (var i = 0; i < finds.length; i++) {\n                        if (orders[finds[i].toString().charAt(0)] === -1) {\n                            orders[finds[i].toString().charAt(0)] = i + 1;\n                        }\n                    }\n                }\n                return orders;\n            };\n\n            var regstr = '^' + f.toString()\n                    .replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {\n                        var ml = match.length;\n                        switch (match.charAt(0).toLowerCase()) {\n                            case 'h':\n                                return ml === 1 ? '(\\\\d?\\\\d)' : '(\\\\d{' + ml + '})';\n                            case 'm':\n                                return ml === 1 ? '(\\\\d?\\\\d)' : '(\\\\d{' + ml + '})';\n                            case 's':\n                                return ml === 1 ? '(\\\\d?\\\\d)' : '(\\\\d{' + ml + '})';\n                            case 'l':\n                                return '(\\\\d?\\\\d?\\\\d)';\n                            case 'c':\n                                return '(\\\\d?\\\\d?\\\\d)';\n                            case 'z':\n                                return '(z|[-+]\\\\d\\\\d:?\\\\d\\\\d|\\\\S+)?';\n                            case 't':\n                                return getPatternAmpm(o.amNames, o.pmNames);\n                            default:    // literal escaped in quotes\n                                return '(' + match.replace(/\\'/g, \"\").replace(/(\\.|\\$|\\^|\\\\|\\/|\\(|\\)|\\[|\\]|\\?|\\+|\\*)/g, function (m) { return \"\\\\\" + m; }) + ')?';\n                        }\n                    })\n                    .replace(/\\s/g, '\\\\s?') +\n                o.timeSuffix + '$',\n                order = getFormatPositions(f),\n                ampm = '',\n                treg;\n\n            treg = s.match(new RegExp(regstr, 'i'));\n\n            var resTime = {\n                hour: 0,\n                minute: 0,\n                second: 0,\n                millisec: 0,\n                microsec: 0\n            };\n\n            if (treg) {\n                if (order.t !== -1) {\n                    if (treg[order.t] === undefined || treg[order.t].length === 0) {\n                        ampm = '';\n                        resTime.ampm = '';\n                    } else {\n                        ampm = $.inArray(treg[order.t].toUpperCase(), $.map(o.amNames, function (x,i) { return x.toUpperCase(); })) !== -1 ? 'AM' : 'PM';\n                        resTime.ampm = o[ampm === 'AM' ? 'amNames' : 'pmNames'][0];\n                    }\n                }\n\n                if (order.h !== -1) {\n                    if (ampm === 'AM' && treg[order.h] === '12') {\n                        resTime.hour = 0; // 12am = 0 hour\n                    } else {\n                        if (ampm === 'PM' && treg[order.h] !== '12') {\n                            resTime.hour = parseInt(treg[order.h], 10) + 12; // 12pm = 12 hour, any other pm = hour + 12\n                        } else {\n                            resTime.hour = Number(treg[order.h]);\n                        }\n                    }\n                }\n\n                if (order.m !== -1) {\n                    resTime.minute = Number(treg[order.m]);\n                }\n                if (order.s !== -1) {\n                    resTime.second = Number(treg[order.s]);\n                }\n                if (order.l !== -1) {\n                    resTime.millisec = Number(treg[order.l]);\n                }\n                if (order.c !== -1) {\n                    resTime.microsec = Number(treg[order.c]);\n                }\n                if (order.z !== -1 && treg[order.z] !== undefined) {\n                    resTime.timezone = $.timepicker.timezoneOffsetNumber(treg[order.z]);\n                }\n\n\n                return resTime;\n            }\n            return false;\n        };// end strictParse\n\n        // First try JS Date, if that fails, use strictParse\n        var looseParse = function (f, s, o) {\n            try {\n                var d = new Date('2012-01-01 ' + s);\n                if (isNaN(d.getTime())) {\n                    d = new Date('2012-01-01T' + s);\n                    if (isNaN(d.getTime())) {\n                        d = new Date('01/01/2012 ' + s);\n                        if (isNaN(d.getTime())) {\n                            throw \"Unable to parse time with native Date: \" + s;\n                        }\n                    }\n                }\n\n                return {\n                    hour: d.getHours(),\n                    minute: d.getMinutes(),\n                    second: d.getSeconds(),\n                    millisec: d.getMilliseconds(),\n                    microsec: d.getMicroseconds(),\n                    timezone: d.getTimezoneOffset() * -1\n                };\n            }\n            catch (err) {\n                try {\n                    return strictParse(f, s, o);\n                }\n                catch (err2) {\n                    $.timepicker.log(\"Unable to parse \\ntimeString: \" + s + \"\\ntimeFormat: \" + f);\n                }\n            }\n            return false;\n        }; // end looseParse\n\n        if (typeof o.parse === \"function\") {\n            return o.parse(timeFormat, timeString, o);\n        }\n        if (o.parse === 'loose') {\n            return looseParse(timeFormat, timeString, o);\n        }\n        return strictParse(timeFormat, timeString, o);\n    };\n\n    /**\n     * Public utility to format the time\n     * @param {string} format format of the time\n     * @param {Object} time Object not a Date for timezones\n     * @param {Object} [options] essentially the regional[].. amNames, pmNames, ampm\n     * @returns {string} the formatted time\n     */\n    $.datepicker.formatTime = function (format, time, options) {\n        options = options || {};\n        options = $.extend({}, $.timepicker._defaults, options);\n        time = $.extend({\n            hour: 0,\n            minute: 0,\n            second: 0,\n            millisec: 0,\n            microsec: 0,\n            timezone: null\n        }, time);\n\n        var tmptime = format,\n            ampmName = options.amNames[0],\n            hour = parseInt(time.hour, 10);\n\n        if (hour > 11) {\n            ampmName = options.pmNames[0];\n        }\n\n        tmptime = tmptime.replace(/(?:HH?|hh?|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {\n            switch (match) {\n                case 'HH':\n                    return ('0' + hour).slice(-2);\n                case 'H':\n                    return hour;\n                case 'hh':\n                    return ('0' + convert24to12(hour)).slice(-2);\n                case 'h':\n                    return convert24to12(hour);\n                case 'mm':\n                    return ('0' + time.minute).slice(-2);\n                case 'm':\n                    return time.minute;\n                case 'ss':\n                    return ('0' + time.second).slice(-2);\n                case 's':\n                    return time.second;\n                case 'l':\n                    return ('00' + time.millisec).slice(-3);\n                case 'c':\n                    return ('00' + time.microsec).slice(-3);\n                case 'z':\n                    return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, false);\n                case 'Z':\n                    return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, true);\n                case 'T':\n                    return ampmName.charAt(0).toUpperCase();\n                case 'TT':\n                    return ampmName.toUpperCase();\n                case 't':\n                    return ampmName.charAt(0).toLowerCase();\n                case 'tt':\n                    return ampmName.toLowerCase();\n                default:\n                    return match.replace(/'/g, \"\");\n            }\n        });\n\n        return tmptime;\n    };\n\n    /*\n    * the bad hack :/ override datepicker so it doesn't close on select\n    // inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378\n    */\n    $.datepicker._base_selectDate = $.datepicker._selectDate;\n    $.datepicker._selectDate = function (id, dateStr) {\n        var inst = this._getInst($(id)[0]),\n            tp_inst = this._get(inst, 'timepicker'),\n            was_inline;\n\n        if (tp_inst && inst.settings.showTimepicker) {\n            tp_inst._limitMinMaxDateTime(inst, true);\n            was_inline = inst.inline;\n            inst.inline = inst.stay_open = true;\n            //This way the onSelect handler called from calendarpicker get the full dateTime\n            this._base_selectDate(id, dateStr);\n            inst.inline = was_inline;\n            inst.stay_open = false;\n            this._notifyChange(inst);\n            this._updateDatepicker(inst);\n        } else {\n            this._base_selectDate(id, dateStr);\n        }\n    };\n\n    /*\n    * second bad hack :/ override datepicker so it triggers an event when changing the input field\n    * and does not redraw the datepicker on every selectDate event\n    */\n    $.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker;\n    $.datepicker._updateDatepicker = function (inst) {\n\n        // don't popup the datepicker if there is another instance already opened\n        var input = inst.input[0];\n        if ($.datepicker._curInst && $.datepicker._curInst !== inst && $.datepicker._datepickerShowing && $.datepicker._lastInput !== input) {\n            return;\n        }\n\n        if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) {\n\n            this._base_updateDatepicker(inst);\n\n            // Reload the time control when changing something in the input text field.\n            var tp_inst = this._get(inst, 'timepicker');\n            if (tp_inst) {\n                tp_inst._addTimePicker(inst);\n            }\n        }\n    };\n\n    /*\n    * third bad hack :/ override datepicker so it allows spaces and colon in the input field\n    */\n    $.datepicker._base_doKeyPress = $.datepicker._doKeyPress;\n    $.datepicker._doKeyPress = function (event) {\n        var inst = $.datepicker._getInst(event.target),\n            tp_inst = $.datepicker._get(inst, 'timepicker');\n\n        if (tp_inst) {\n            if ($.datepicker._get(inst, 'constrainInput')) {\n                var ampm = tp_inst.support.ampm,\n                    tz = tp_inst._defaults.showTimezone !== null ? tp_inst._defaults.showTimezone : tp_inst.support.timezone,\n                    dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')),\n                    datetimeChars = tp_inst._defaults.timeFormat.toString()\n                            .replace(/[hms]/g, '')\n                            .replace(/TT/g, ampm ? 'APM' : '')\n                            .replace(/Tt/g, ampm ? 'AaPpMm' : '')\n                            .replace(/tT/g, ampm ? 'AaPpMm' : '')\n                            .replace(/T/g, ampm ? 'AP' : '')\n                            .replace(/tt/g, ampm ? 'apm' : '')\n                            .replace(/t/g, ampm ? 'ap' : '') +\n                        \" \" + tp_inst._defaults.separator +\n                        tp_inst._defaults.timeSuffix +\n                        (tz ? tp_inst._defaults.timezoneList.join('') : '') +\n                        (tp_inst._defaults.amNames.join('')) + (tp_inst._defaults.pmNames.join('')) +\n                        dateChars,\n                    chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode);\n                return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1);\n            }\n        }\n\n        return $.datepicker._base_doKeyPress(event);\n    };\n\n    /*\n    * Fourth bad hack :/ override _updateAlternate function used in inline mode to init altField\n    * Update any alternate field to synchronise with the main field.\n    */\n    $.datepicker._base_updateAlternate = $.datepicker._updateAlternate;\n    $.datepicker._updateAlternate = function (inst) {\n        var tp_inst = this._get(inst, 'timepicker');\n        if (tp_inst) {\n            var altField = tp_inst._defaults.altField;\n            if (altField) { // update alternate field too\n                var altFormat = tp_inst._defaults.altFormat || tp_inst._defaults.dateFormat,\n                    date = this._getDate(inst),\n                    formatCfg = $.datepicker._getFormatConfig(inst),\n                    altFormattedDateTime = '',\n                    altSeparator = tp_inst._defaults.altSeparator ? tp_inst._defaults.altSeparator : tp_inst._defaults.separator,\n                    altTimeSuffix = tp_inst._defaults.altTimeSuffix ? tp_inst._defaults.altTimeSuffix : tp_inst._defaults.timeSuffix,\n                    altTimeFormat = tp_inst._defaults.altTimeFormat !== null ? tp_inst._defaults.altTimeFormat : tp_inst._defaults.timeFormat;\n\n                altFormattedDateTime += $.datepicker.formatTime(altTimeFormat, tp_inst, tp_inst._defaults) + altTimeSuffix;\n                if (!tp_inst._defaults.timeOnly && !tp_inst._defaults.altFieldTimeOnly && date !== null) {\n                    if (tp_inst._defaults.altFormat) {\n                        altFormattedDateTime = $.datepicker.formatDate(tp_inst._defaults.altFormat, date, formatCfg) + altSeparator + altFormattedDateTime;\n                    }\n                    else {\n                        altFormattedDateTime = tp_inst.formattedDate + altSeparator + altFormattedDateTime;\n                    }\n                }\n                $(altField).val( inst.input.val() ? altFormattedDateTime : \"\");\n            }\n        }\n        else {\n            $.datepicker._base_updateAlternate(inst);\n        }\n    };\n\n    /*\n    * Override key up event to sync manual input changes.\n    */\n    $.datepicker._base_doKeyUp = $.datepicker._doKeyUp;\n    $.datepicker._doKeyUp = function (event) {\n        var inst = $.datepicker._getInst(event.target),\n            tp_inst = $.datepicker._get(inst, 'timepicker');\n\n        if (tp_inst) {\n            if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {\n                try {\n                    $.datepicker._updateDatepicker(inst);\n                } catch (err) {\n                    $.timepicker.log(err);\n                }\n            }\n        }\n\n        return $.datepicker._base_doKeyUp(event);\n    };\n\n    /*\n    * override \"Today\" button to also grab the time and set it to input field.\n    */\n    $.datepicker._base_gotoToday = $.datepicker._gotoToday;\n    $.datepicker._gotoToday = function (id) {\n        var inst = this._getInst($(id)[0]);\n        this._base_gotoToday(id);\n        var tp_inst = this._get(inst, 'timepicker');\n        if (!tp_inst) {\n            return;\n        }\n\n        var tzoffset = $.timepicker.timezoneOffsetNumber(tp_inst.timezone);\n        var now = new Date();\n        now.setMinutes(now.getMinutes() + now.getTimezoneOffset() + parseInt(tzoffset, 10));\n        this._setTime(inst, now);\n        this._setDate(inst, now);\n        tp_inst._onSelectHandler();\n    };\n\n    /*\n    * Disable & enable the Time in the datetimepicker\n    */\n    $.datepicker._disableTimepickerDatepicker = function (target) {\n        var inst = this._getInst(target);\n        if (!inst) {\n            return;\n        }\n\n        var tp_inst = this._get(inst, 'timepicker');\n        $(target).datepicker('getDate'); // Init selected[Year|Month|Day]\n        if (tp_inst) {\n            inst.settings.showTimepicker = false;\n            tp_inst._defaults.showTimepicker = false;\n            tp_inst._updateDateTime(inst);\n        }\n    };\n\n    $.datepicker._enableTimepickerDatepicker = function (target) {\n        var inst = this._getInst(target);\n        if (!inst) {\n            return;\n        }\n\n        var tp_inst = this._get(inst, 'timepicker');\n        $(target).datepicker('getDate'); // Init selected[Year|Month|Day]\n        if (tp_inst) {\n            inst.settings.showTimepicker = true;\n            tp_inst._defaults.showTimepicker = true;\n            tp_inst._addTimePicker(inst); // Could be disabled on page load\n            tp_inst._updateDateTime(inst);\n        }\n    };\n\n    /*\n    * Create our own set time function\n    */\n    $.datepicker._setTime = function (inst, date) {\n        var tp_inst = this._get(inst, 'timepicker');\n        if (tp_inst) {\n            var defaults = tp_inst._defaults;\n\n            // calling _setTime with no date sets time to defaults\n            tp_inst.hour = date ? date.getHours() : defaults.hour;\n            tp_inst.minute = date ? date.getMinutes() : defaults.minute;\n            tp_inst.second = date ? date.getSeconds() : defaults.second;\n            tp_inst.millisec = date ? date.getMilliseconds() : defaults.millisec;\n            tp_inst.microsec = date ? date.getMicroseconds() : defaults.microsec;\n\n            //check if within min/max times..\n            tp_inst._limitMinMaxDateTime(inst, true);\n\n            tp_inst._onTimeChange();\n            tp_inst._updateDateTime(inst);\n        }\n    };\n\n    /*\n    * Create new public method to set only time, callable as $().datepicker('setTime', date)\n    */\n    $.datepicker._setTimeDatepicker = function (target, date, withDate) {\n        var inst = this._getInst(target);\n        if (!inst) {\n            return;\n        }\n\n        var tp_inst = this._get(inst, 'timepicker');\n\n        if (tp_inst) {\n            this._setDateFromField(inst);\n            var tp_date;\n            if (date) {\n                if (typeof date === \"string\") {\n                    tp_inst._parseTime(date, withDate);\n                    tp_date = new Date();\n                    tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);\n                    tp_date.setMicroseconds(tp_inst.microsec);\n                } else {\n                    tp_date = new Date(date.getTime());\n                    tp_date.setMicroseconds(date.getMicroseconds());\n                }\n                if (tp_date.toString() === 'Invalid Date') {\n                    tp_date = undefined;\n                }\n                this._setTime(inst, tp_date);\n            }\n        }\n\n    };\n\n    /*\n    * override setDate() to allow setting time too within Date object\n    */\n    $.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker;\n    $.datepicker._setDateDatepicker = function (target, _date) {\n        var inst = this._getInst(target);\n        var date = _date;\n        if (!inst) {\n            return;\n        }\n\n        if (typeof(_date) === 'string') {\n            date = new Date(_date);\n            if (!date.getTime()) {\n                this._base_setDateDatepicker.apply(this, arguments);\n                date = $(target).datepicker('getDate');\n            }\n        }\n\n        var tp_inst = this._get(inst, 'timepicker');\n        var tp_date;\n        if (date instanceof Date) {\n            tp_date = new Date(date.getTime());\n            tp_date.setMicroseconds(date.getMicroseconds());\n        } else {\n            tp_date = date;\n        }\n\n        // This is important if you are using the timezone option, javascript's Date\n        // object will only return the timezone offset for the current locale, so we\n        // adjust it accordingly.  If not using timezone option this won't matter..\n        // If a timezone is different in tp, keep the timezone as is\n        if (tp_inst && tp_date) {\n            // look out for DST if tz wasn't specified\n            if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {\n                tp_inst.timezone = tp_date.getTimezoneOffset() * -1;\n            }\n            date = $.timepicker.timezoneAdjust(date, $.timepicker.timezoneOffsetString(-date.getTimezoneOffset()), tp_inst.timezone);\n            tp_date = $.timepicker.timezoneAdjust(tp_date, $.timepicker.timezoneOffsetString(-tp_date.getTimezoneOffset()), tp_inst.timezone);\n        }\n\n        this._updateDatepicker(inst);\n        this._base_setDateDatepicker.apply(this, arguments);\n        this._setTimeDatepicker(target, tp_date, true);\n    };\n\n    /*\n    * override getDate() to allow getting time too within Date object\n    */\n    $.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker;\n    $.datepicker._getDateDatepicker = function (target, noDefault) {\n        var inst = this._getInst(target);\n        if (!inst) {\n            return;\n        }\n\n        var tp_inst = this._get(inst, 'timepicker');\n\n        if (tp_inst) {\n            // if it hasn't yet been defined, grab from field\n            if (inst.lastVal === undefined) {\n                this._setDateFromField(inst, noDefault);\n            }\n\n            var date = this._getDate(inst);\n\n            var currDT = null;\n\n            if (tp_inst.$altInput && tp_inst._defaults.altFieldTimeOnly) {\n                currDT = tp_inst.$input.val() + ' ' + tp_inst.$altInput.val();\n            }\n            else if (tp_inst.$input.get(0).tagName !== 'INPUT' && tp_inst.$altInput) {\n                /**\n                 * in case the datetimepicker has been applied to a non-input tag for inline UI,\n                 * and the user has not configured the plugin to display only time in altInput,\n                 * pick current date time from the altInput (and hope for the best, for now, until \"ER1\" is applied)\n                 *\n                 * @todo ER1. Since altInput can have a totally difference format, convert it to standard format by reading input format from \"altFormat\" and \"altTimeFormat\" option values\n                 */\n                currDT = tp_inst.$altInput.val();\n            }\n            else {\n                currDT = tp_inst.$input.val();\n            }\n\n            if (date && tp_inst._parseTime(currDT, !inst.settings.timeOnly)) {\n                date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);\n                date.setMicroseconds(tp_inst.microsec);\n\n                // This is important if you are using the timezone option, javascript's Date\n                // object will only return the timezone offset for the current locale, so we\n                // adjust it accordingly.  If not using timezone option this won't matter..\n                if (tp_inst.timezone != null) {\n                    // look out for DST if tz wasn't specified\n                    if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {\n                        tp_inst.timezone = date.getTimezoneOffset() * -1;\n                    }\n                    date = $.timepicker.timezoneAdjust(date, tp_inst.timezone, $.timepicker.timezoneOffsetString(-date.getTimezoneOffset()));\n                }\n            }\n            return date;\n        }\n        return this._base_getDateDatepicker(target, noDefault);\n    };\n\n    /*\n    * override parseDate() because UI 1.8.14 throws an error about \"Extra characters\"\n    * An option in datapicker to ignore extra format characters would be nicer.\n    */\n    $.datepicker._base_parseDate = $.datepicker.parseDate;\n    $.datepicker.parseDate = function (format, value, settings) {\n        var date;\n        try {\n            date = this._base_parseDate(format, value, settings);\n        } catch (err) {\n            // Hack!  The error message ends with a colon, a space, and\n            // the \"extra\" characters.  We rely on that instead of\n            // attempting to perfectly reproduce the parsing algorithm.\n            if (err.indexOf(\":\") >= 0) {\n                date = this._base_parseDate(format, value.substring(0, value.length - (err.length - err.indexOf(':') - 2)), settings);\n                $.timepicker.log(\"Error parsing the date string: \" + err + \"\\ndate string = \" + value + \"\\ndate format = \" + format);\n            } else {\n                throw err;\n            }\n        }\n        return date;\n    };\n\n    /*\n    * override formatDate to set date with time to the input\n    */\n    $.datepicker._base_formatDate = $.datepicker._formatDate;\n    $.datepicker._formatDate = function (inst, day, month, year) {\n        var tp_inst = this._get(inst, 'timepicker');\n        if (tp_inst) {\n            tp_inst._updateDateTime(inst);\n            return tp_inst.$input.val();\n        }\n        return this._base_formatDate(inst);\n    };\n\n    /*\n    * override options setter to add time to maxDate(Time) and minDate(Time). MaxDate\n    */\n    $.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker;\n    $.datepicker._optionDatepicker = function (target, name, value) {\n        var inst = this._getInst(target),\n            name_clone;\n        if (!inst) {\n            return null;\n        }\n\n        var tp_inst = this._get(inst, 'timepicker');\n        if (tp_inst) {\n            var min = null,\n                max = null,\n                onselect = null,\n                overrides = tp_inst._defaults.evnts,\n                fns = {},\n                prop,\n                ret,\n                oldVal,\n                $target;\n            if (typeof name === 'string') { // if min/max was set with the string\n                if (name === 'minDate' || name === 'minDateTime') {\n                    min = value;\n                } else if (name === 'maxDate' || name === 'maxDateTime') {\n                    max = value;\n                } else if (name === 'onSelect') {\n                    onselect = value;\n                } else if (overrides.hasOwnProperty(name)) {\n                    if (typeof (value) === 'undefined') {\n                        return overrides[name];\n                    }\n                    fns[name] = value;\n                    name_clone = {}; //empty results in exiting function after overrides updated\n                }\n            } else if (typeof name === 'object') { //if min/max was set with the JSON\n                if (name.minDate) {\n                    min = name.minDate;\n                } else if (name.minDateTime) {\n                    min = name.minDateTime;\n                } else if (name.maxDate) {\n                    max = name.maxDate;\n                } else if (name.maxDateTime) {\n                    max = name.maxDateTime;\n                }\n                for (prop in overrides) {\n                    if (overrides.hasOwnProperty(prop) && name[prop]) {\n                        fns[prop] = name[prop];\n                    }\n                }\n            }\n            for (prop in fns) {\n                if (fns.hasOwnProperty(prop)) {\n                    overrides[prop] = fns[prop];\n                    if (!name_clone) { name_clone = $.extend({}, name); }\n                    delete name_clone[prop];\n                }\n            }\n            if (name_clone && isEmptyObject(name_clone)) { return; }\n            if (min) { //if min was set\n                if (min === 0) {\n                    min = new Date();\n                } else {\n                    min = new Date(min);\n                }\n                tp_inst._defaults.minDate = min;\n                tp_inst._defaults.minDateTime = min;\n            } else if (max) { //if max was set\n                if (max === 0) {\n                    max = new Date();\n                } else {\n                    max = new Date(max);\n                }\n                tp_inst._defaults.maxDate = max;\n                tp_inst._defaults.maxDateTime = max;\n            } else if (onselect) {\n                tp_inst._defaults.onSelect = onselect;\n            }\n\n            // Datepicker will override our date when we call _base_optionDatepicker when\n            // calling minDate/maxDate, so we will first grab the value, call\n            // _base_optionDatepicker, then set our value back.\n            if(min || max){\n                $target = $(target);\n                oldVal = $target.datetimepicker('getDate');\n                ret = this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);\n                $target.datetimepicker('setDate', oldVal);\n                return ret;\n            }\n        }\n        if (value === undefined) {\n            return this._base_optionDatepicker.call($.datepicker, target, name);\n        }\n        return this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);\n    };\n\n    /*\n    * jQuery isEmptyObject does not check hasOwnProperty - if someone has added to the object prototype,\n    * it will return false for all objects\n    */\n    var isEmptyObject = function (obj) {\n        var prop;\n        for (prop in obj) {\n            if (obj.hasOwnProperty(prop)) {\n                return false;\n            }\n        }\n        return true;\n    };\n\n    /*\n    * jQuery extend now ignores nulls!\n    */\n    var extendRemove = function (target, props) {\n        $.extend(target, props);\n        for (var name in props) {\n            if (props[name] === null || props[name] === undefined) {\n                target[name] = props[name];\n            }\n        }\n        return target;\n    };\n\n    /*\n    * Determine by the time format which units are supported\n    * Returns an object of booleans for each unit\n    */\n    var detectSupport = function (timeFormat) {\n        var tf = timeFormat.replace(/'.*?'/g, '').toLowerCase(), // removes literals\n            isIn = function (f, t) { // does the format contain the token?\n                return f.indexOf(t) !== -1 ? true : false;\n            };\n        return {\n            hour: isIn(tf, 'h'),\n            minute: isIn(tf, 'm'),\n            second: isIn(tf, 's'),\n            millisec: isIn(tf, 'l'),\n            microsec: isIn(tf, 'c'),\n            timezone: isIn(tf, 'z'),\n            ampm: isIn(tf, 't') && isIn(timeFormat, 'h'),\n            iso8601: isIn(timeFormat, 'Z')\n        };\n    };\n\n    /*\n    * Converts 24 hour format into 12 hour\n    * Returns 12 hour without leading 0\n    */\n    var convert24to12 = function (hour) {\n        hour %= 12;\n\n        if (hour === 0) {\n            hour = 12;\n        }\n\n        return String(hour);\n    };\n\n    var computeEffectiveSetting = function (settings, property) {\n        return settings && settings[property] ? settings[property] : $.timepicker._defaults[property];\n    };\n\n    /*\n    * Splits datetime string into date and time substrings.\n    * Throws exception when date can't be parsed\n    * Returns {dateString: dateString, timeString: timeString}\n    */\n    var splitDateTime = function (dateTimeString, timeSettings) {\n        // The idea is to get the number separator occurrences in datetime and the time format requested (since time has\n        // fewer unknowns, mostly numbers and am/pm). We will use the time pattern to split.\n        var separator = computeEffectiveSetting(timeSettings, 'separator'),\n            format = computeEffectiveSetting(timeSettings, 'timeFormat'),\n            timeParts = format.split(separator), // how many occurrences of separator may be in our format?\n            timePartsLen = timeParts.length,\n            allParts = dateTimeString.split(separator),\n            allPartsLen = allParts.length;\n\n        if (allPartsLen > 1) {\n            return {\n                dateString: allParts.splice(0, allPartsLen - timePartsLen).join(separator),\n                timeString: allParts.splice(0, timePartsLen).join(separator)\n            };\n        }\n\n        return {\n            dateString: dateTimeString,\n            timeString: ''\n        };\n    };\n\n    /*\n    * Internal function to parse datetime interval\n    * Returns: {date: Date, timeObj: Object}, where\n    *   date - parsed date without time (type Date)\n    *   timeObj = {hour: , minute: , second: , millisec: , microsec: } - parsed time. Optional\n    */\n    var parseDateTimeInternal = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {\n        var date,\n            parts,\n            parsedTime;\n\n        parts = splitDateTime(dateTimeString, timeSettings);\n        date = $.datepicker._base_parseDate(dateFormat, parts.dateString, dateSettings);\n\n        if (parts.timeString === '') {\n            return {\n                date: date\n            };\n        }\n\n        parsedTime = $.datepicker.parseTime(timeFormat, parts.timeString, timeSettings);\n\n        if (!parsedTime) {\n            throw 'Wrong time format';\n        }\n\n        return {\n            date: date,\n            timeObj: parsedTime\n        };\n    };\n\n    /*\n    * Internal function to set timezone_select to the local timezone\n    */\n    var selectLocalTimezone = function (tp_inst, date) {\n        if (tp_inst && tp_inst.timezone_select) {\n            var now = date || new Date();\n            tp_inst.timezone_select.val(-now.getTimezoneOffset());\n        }\n    };\n\n    /*\n    * Create a Singleton Instance\n    */\n    $.timepicker = new Timepicker();\n\n    /**\n     * Get the timezone offset as string from a date object (eg '+0530' for UTC+5.5)\n     * @param {number} tzMinutes if not a number, less than -720 (-1200), or greater than 840 (+1400) this value is returned\n     * @param {boolean} iso8601 if true formats in accordance to iso8601 \"+12:45\"\n     * @return {string}\n     */\n    $.timepicker.timezoneOffsetString = function (tzMinutes, iso8601) {\n        if (isNaN(tzMinutes) || tzMinutes > 840 || tzMinutes < -720) {\n            return tzMinutes;\n        }\n\n        var off = tzMinutes,\n            minutes = off % 60,\n            hours = (off - minutes) / 60,\n            iso = iso8601 ? ':' : '',\n            tz = (off >= 0 ? '+' : '-') + ('0' + Math.abs(hours)).slice(-2) + iso + ('0' + Math.abs(minutes)).slice(-2);\n\n        if (tz === '+00:00') {\n            return 'Z';\n        }\n        return tz;\n    };\n\n    /**\n     * Get the number in minutes that represents a timezone string\n     * @param  {string} tzString formatted like \"+0500\", \"-1245\", \"Z\"\n     * @return {number} the offset minutes or the original string if it doesn't match expectations\n     */\n    $.timepicker.timezoneOffsetNumber = function (tzString) {\n        var normalized = tzString.toString().replace(':', ''); // excuse any iso8601, end up with \"+1245\"\n\n        if (normalized.toUpperCase() === 'Z') { // if iso8601 with Z, its 0 minute offset\n            return 0;\n        }\n\n        if (!/^(\\-|\\+)\\d{4}$/.test(normalized)) { // possibly a user defined tz, so just give it back\n            return parseInt(tzString, 10);\n        }\n\n        return ((normalized.substr(0, 1) === '-' ? -1 : 1) * // plus or minus\n            ((parseInt(normalized.substr(1, 2), 10) * 60) + // hours (converted to minutes)\n                parseInt(normalized.substr(3, 2), 10))); // minutes\n    };\n\n    /**\n     * No way to set timezone in js Date, so we must adjust the minutes to compensate. (think setDate, getDate)\n     * @param  {Date} date\n     * @param  {string} fromTimezone formatted like \"+0500\", \"-1245\"\n     * @param  {string} toTimezone formatted like \"+0500\", \"-1245\"\n     * @return {Date}\n     */\n    $.timepicker.timezoneAdjust = function (date, fromTimezone, toTimezone) {\n        var fromTz = $.timepicker.timezoneOffsetNumber(fromTimezone);\n        var toTz = $.timepicker.timezoneOffsetNumber(toTimezone);\n        if (!isNaN(toTz)) {\n            date.setMinutes(date.getMinutes() + (-fromTz) - (-toTz));\n        }\n        return date;\n    };\n\n    /**\n     * Calls `timepicker()` on the `startTime` and `endTime` elements, and configures them to\n     * enforce date range limits.\n     * n.b. The input value must be correctly formatted (reformatting is not supported)\n     * @param  {Element} startTime\n     * @param  {Element} endTime\n     * @param  {Object} options Options for the timepicker() call\n     * @return {jQuery}\n     */\n    $.timepicker.timeRange = function (startTime, endTime, options) {\n        return $.timepicker.handleRange('timepicker', startTime, endTime, options);\n    };\n\n    /**\n     * Calls `datetimepicker` on the `startTime` and `endTime` elements, and configures them to\n     * enforce date range limits.\n     * @param  {Element} startTime\n     * @param  {Element} endTime\n     * @param  {Object} options Options for the `timepicker()` call. Also supports `reformat`,\n     *   a boolean value that can be used to reformat the input values to the `dateFormat`.\n     * @param  {string} method Can be used to specify the type of picker to be added\n     * @return {jQuery}\n     */\n    $.timepicker.datetimeRange = function (startTime, endTime, options) {\n        $.timepicker.handleRange('datetimepicker', startTime, endTime, options);\n    };\n\n    /**\n     * Calls `datepicker` on the `startTime` and `endTime` elements, and configures them to\n     * enforce date range limits.\n     * @param  {Element} startTime\n     * @param  {Element} endTime\n     * @param  {Object} options Options for the `timepicker()` call. Also supports `reformat`,\n     *   a boolean value that can be used to reformat the input values to the `dateFormat`.\n     * @return {jQuery}\n     */\n    $.timepicker.dateRange = function (startTime, endTime, options) {\n        $.timepicker.handleRange('datepicker', startTime, endTime, options);\n    };\n\n    /**\n     * Calls `method` on the `startTime` and `endTime` elements, and configures them to\n     * enforce date range limits.\n     * @param  {string} method Can be used to specify the type of picker to be added\n     * @param  {Element} startTime\n     * @param  {Element} endTime\n     * @param  {Object} options Options for the `timepicker()` call. Also supports `reformat`,\n     *   a boolean value that can be used to reformat the input values to the `dateFormat`.\n     * @return {jQuery}\n     */\n    $.timepicker.handleRange = function (method, startTime, endTime, options) {\n        options = $.extend({}, {\n            minInterval: 0, // min allowed interval in milliseconds\n            maxInterval: 0, // max allowed interval in milliseconds\n            start: {},      // options for start picker\n            end: {}         // options for end picker\n        }, options);\n\n        // for the mean time this fixes an issue with calling getDate with timepicker()\n        var timeOnly = false;\n        if(method === 'timepicker'){\n            timeOnly = true;\n            method = 'datetimepicker';\n        }\n\n        function checkDates(changed, other) {\n            var startdt = startTime[method]('getDate'),\n                enddt = endTime[method]('getDate'),\n                changeddt = changed[method]('getDate');\n\n            if (startdt !== null) {\n                var minDate = new Date(startdt.getTime()),\n                    maxDate = new Date(startdt.getTime());\n\n                minDate.setMilliseconds(minDate.getMilliseconds() + options.minInterval);\n                maxDate.setMilliseconds(maxDate.getMilliseconds() + options.maxInterval);\n\n                if (options.minInterval > 0 && minDate > enddt) { // minInterval check\n                    endTime[method]('setDate', minDate);\n                }\n                else if (options.maxInterval > 0 && maxDate < enddt) { // max interval check\n                    endTime[method]('setDate', maxDate);\n                }\n                else if (startdt > enddt) {\n                    other[method]('setDate', changeddt);\n                }\n            }\n        }\n\n        function selected(changed, other, option) {\n            if (!changed.val()) {\n                return;\n            }\n            var date = changed[method].call(changed, 'getDate');\n            if (date !== null && options.minInterval > 0) {\n                if (option === 'minDate') {\n                    date.setMilliseconds(date.getMilliseconds() + options.minInterval);\n                }\n                if (option === 'maxDate') {\n                    date.setMilliseconds(date.getMilliseconds() - options.minInterval);\n                }\n            }\n\n            if (date.getTime) {\n                other[method].call(other, 'option', option, date);\n            }\n        }\n\n        $.fn[method].call(startTime, $.extend({\n            timeOnly: timeOnly,\n            onClose: function (dateText, inst) {\n                checkDates($(this), endTime);\n            },\n            onSelect: function (selectedDateTime) {\n                selected($(this), endTime, 'minDate');\n            }\n        }, options, options.start));\n        $.fn[method].call(endTime, $.extend({\n            timeOnly: timeOnly,\n            onClose: function (dateText, inst) {\n                checkDates($(this), startTime);\n            },\n            onSelect: function (selectedDateTime) {\n                selected($(this), startTime, 'maxDate');\n            }\n        }, options, options.end));\n\n        checkDates(startTime, endTime);\n\n        selected(startTime, endTime, 'minDate');\n        selected(endTime, startTime, 'maxDate');\n\n        return $([startTime.get(0), endTime.get(0)]);\n    };\n\n    /**\n     * Log error or data to the console during error or debugging\n     * @param  {Object} err pass any type object to log to the console during error or debugging\n     * @return {void}\n     */\n    $.timepicker.log = function () {\n        // Older IE (9, maybe 10) throw error on accessing `window.console.log.apply`, so check first.\n        if (window.console && window.console.log && window.console.log.apply) {\n            window.console.log.apply(window.console, Array.prototype.slice.call(arguments));\n        }\n    };\n\n    /*\n     * Add util object to allow access to private methods for testability.\n     */\n    $.timepicker._util = {\n        _extendRemove: extendRemove,\n        _isEmptyObject: isEmptyObject,\n        _convert24to12: convert24to12,\n        _detectSupport: detectSupport,\n        _selectLocalTimezone: selectLocalTimezone,\n        _computeEffectiveSetting: computeEffectiveSetting,\n        _splitDateTime: splitDateTime,\n        _parseDateTimeInternal: parseDateTimeInternal\n    };\n\n    /*\n    * Microsecond support\n    */\n    if (!Date.prototype.getMicroseconds) {\n        Date.prototype.microseconds = 0;\n        Date.prototype.getMicroseconds = function () { return this.microseconds; };\n        Date.prototype.setMicroseconds = function (m) {\n            this.setMilliseconds(this.getMilliseconds() + Math.floor(m / 1000));\n            this.microseconds = m % 1000;\n            return this;\n        };\n    }\n\n    /*\n    * Keep up with the version\n    */\n    $.timepicker.version = \"1.6.3\";\n\n}));\n","jquery/z-index.js":"/*!\n * zIndex plugin from jQuery UI Core - v1.10.4\n * http://jqueryui.com\n *\n * Copyright 2014 jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/category/ui-core/\n */\ndefine([\n    'jquery'\n], function ($, undefined) {\n\n// plugins\n    $.fn.extend({\n        zIndex: function (zIndex) {\n            if (zIndex !== undefined) {\n                return this.css(\"zIndex\", zIndex);\n            }\n\n            if (this.length) {\n                var elem = $(this[0]), position, value;\n                while (elem.length && elem[0] !== document) {\n                    // Ignore z-index if position is set to a value where z-index is ignored by the browser\n                    // This makes behavior of this function consistent across browsers\n                    // WebKit always returns auto if the element is positioned\n                    position = elem.css(\"position\");\n                    if (position === \"absolute\" || position === \"relative\" || position === \"fixed\") {\n                        // IE returns 0 when zIndex is not specified\n                        // other browsers return a string\n                        // we ignore the case of nested elements with an explicit value of 0\n                        // <div style=\"z-index: -10;\"><div style=\"z-index: 0;\"></div></div>\n                        value = parseInt(elem.css(\"zIndex\"), 10);\n                        if (!isNaN(value) && value !== 0) {\n                            return value;\n                        }\n                    }\n                    elem = elem.parent();\n                }\n            }\n\n            return 0;\n        }\n    });\n});\n","jquery/jquery.tabs.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    \"jquery\",\n    \"jquery/bootstrap/tab\",\n    \"jquery/bootstrap/collapse\",\n], function () {\n\n});\n"}
}});