cdn-7.com Open in urlscan Pro
2606:4700::6812:f87  Public Scan

URL: https://cdn-7.com/media/js/188719d1fc05a630f9afc55580deae02.js?v=109508030
Submission Tags: falconsandbox
Submission: On February 24 via api from US — Scanned from DE

Form analysis 0 forms found in the DOM

Text Content

(function () {
    var msg = 'Hello inspector, we are hiring! https://team.emma-sleep.com/team/technology-and-software-engineering';
    var chromeFirefox=new RegExp('chrome|firefox','i');if(chromeFirefox.test(navigator.userAgent)){console.log('%c ' + msg,'color: #1e2b5a; font-weight: bold');}else{console.log(msg);}
})();

class cartMini {
    constructor(){
        if(
            $j('body').hasClass('checkout-onepage-success') ||
            $j('body').hasClass('customer-account-logoutsuccess') ||
            $j('body').hasClass('customer-account-index') ||
            $j('body').hasClass('checkout-klarna-success') ||
            window.location.hash === '#empty_cart'
        ) {
            registry('cart_qty', null, false);
        }
        this.updateQty();


        $j('#checkout-cart-summary, #shopping-cart-table').on('click','.cart__product-remove',function(event) {
            event.preventDefault();
            cartMini.prototype.removeItem(event.currentTarget)
        });
    }

    getStepLoader(currentStep){

        if(currentStep == 'shipping_method'){
            return 'shipping-method';
        }

        return currentStep;

    }

    removeItem(el){

        var url = jQuery(el).attr('delete-url');
        var formKeyElement = $j('input[name=form_key]');
        var form_key = false;

        if(formKeyElement.length > 0){

            this.showCheckoutLoader();
            jQuery(el).addClass('disabled');
            jQuery(el).find('.cart__product-remove--loader').removeClass('is-hidden');

            form_key = formKeyElement[0].value;
            $j.ajax({
                type: 'POST',
                dataType: 'json',
                data: {
                    form_key: form_key
                },
                url: url
            }).done(function(result){
                registry('cart_qty', result.qty, false);
                location.reload();
            });

        }else{
            console.log('missing form key');
        }

    }

    updateQty(){

        if(registry('cart_qty')) {
            var qty = registry('cart_qty');
            var container = $j('#mini-cart-qty')
            if(container){
                container.html(qty);
                if(qty > 0 )
                {
                    container.removeClass('is-hidden');
                }
            }
        }
    }

    submit(form){

        this.showCheckoutLoader();
        form.submit();

    }

    showCheckoutLoader(){
        if(typeof checkout !== 'undefined'){
            var loader = jQuery("#"+this.getStepLoader(checkout.currentStep) + '-please-wait');
            if(loader){
                loader.show();
            }
        }
    }
};
var stripeTokens = {};

var initStripe = function(apiKey, securityMethod, callback)
{
    if (typeof callback == "undefined")
        callback = function() {};

    stripe.securityMethod = securityMethod;
    stripe.apiKey = apiKey;
    stripe.onStripeInitCallback = callback;

    if (stripe.securityMethod == 1)
        stripe.loadStripeJsV2(stripe.onLoadStripeJsV2);

    // We always load v3 so that we use Payment Intents
    stripe.loadStripeJsV3(stripe.onLoadStripeJsV3);

    // Disable server side card validation when Stripe.js is enabled
    if (typeof AdminOrder != 'undefined' && AdminOrder.prototype.loadArea && typeof AdminOrder.prototype._loadArea == 'undefined')
    {
        AdminOrder.prototype._loadArea = AdminOrder.prototype.loadArea;
        AdminOrder.prototype.loadArea = function(area, indicator, params)
        {
            if (typeof area == "object" && area.indexOf('card_validation') >= 0)
                area = area.splice(area.indexOf('card_validation'), 0);

            if (area.length > 0)
                this._loadArea(area, indicator, params);
        };
    }

    // Integrate Stripe.js with various One Step Checkout modules
    initOSCModules();
    stripe.onWindowLoaded(initOSCModules); // Run it again after the page has loaded in case we missed an ajax based OSC module

    // Integrate Stripe.js with the multi-shipping payment form
    stripe.onWindowLoaded(initMultiShippingForm);

    // Errors at the checkout review step should send the customer back to the payment section
    stripe.initReviewStepErrors();
    stripe.onWindowLoaded(stripe.initReviewStepErrors); // For OSC modules

    // Integrate Stripe.js with the admin area
    stripe.onWindowLoaded(initAdmin); // Needed when refreshing the browser
    initAdmin(); // Needed when the payment method is loaded through an ajax call after adding the shipping address
};

var stripe = {
    version: '1.1.9',

    // Properties
    billingInfo: null,
    multiShippingFormInitialized: false,
    oscInitialized: false,
    applePayButton: null,
    applePaySuccess: false,
    applePayResponse: null,
    securityMethod: 0,
    card: null,
    paymentFormValidator: null,
    stripeJsV2: null,
    stripeJsV3: null,
    apiKey: null,
    sourceId: null,
    iconsContainer: null,
    paymentIntent: null,
    paymentIntents: [],
    isAdmin: false,
    PRAPIEvent: null,
    isDynamicCustomerAuthenticationInitialized: false,
    isAlertProxyInitialized: false,
    is3DSecureOpen: false,
    onStripeInitCallback: function() {},

    // Methods
    placeOrder: function() {}, // Will be overwritten dynamically
    shouldLoadStripeJsV2: function()
    {
        return (stripe.securityMethod == 1 || (stripe.securityMethod == 2 && stripe.isApplePayEnabled()));
    },
    loadStripeJsV2: function(callback)
    {
        if (!stripe.shouldLoadStripeJsV2())
            return callback();

        var script = document.getElementsByTagName('script')[0];
        var stripeJsV2 = document.createElement('script');
        stripeJsV2.src = "https://js.stripe.com/v2/";
        stripeJsV2.onload = function()
        {
            stripe.onLoadStripeJsV2();
            callback();
        };
        stripeJsV2.onerror = function(evt) {
            console.warn("Stripe.js v2 could not be loaded");
            console.error(evt);
            callback();
        };
        script.parentNode.insertBefore(stripeJsV2, script);
    },
    loadStripeJsV3: function(callback)
    {
        var script = document.getElementsByTagName('script')[0];
        var stripeJsV3 = document.createElement('script');
        stripeJsV3.src = "https://js.stripe.com/v3/";
        stripeJsV3.onload = function()
        {
            stripe.onLoadStripeJsV3();
            if (typeof callback === 'function') {
                callback();
            }
        };
        stripeJsV3.onerror = function(evt) {
            console.warn("Stripe.js v3 could not be loaded");
            console.error(evt);
        };
        // Do this on the next cycle so that stripe.onLoadStripeJsV2() finishes first
        script.parentNode.insertBefore(stripeJsV3, script);
    },
    onLoadStripeJsV2: function()
    {
        if (!stripe.stripeJsV2)
        {
            Stripe.setPublishableKey(stripe.apiKey);
            stripe.stripeJsV2 = Stripe;
        }
    },
    onLoadStripeJsV3: function()
    {
        if (!stripe.stripeJsV3)
        {
            var params = {
                betas: ['payment_intent_beta_3']
            };
            stripe.stripeJsV3 = Stripe(stripe.apiKey, params);
        }

        stripe.initLoadedStripeJsV3();
    },
    initLoadedStripeJsV3: function()
    {
        stripe.initStripeElements();
        stripe.onWindowLoaded(stripe.initStripeElements);

        stripe.initPaymentRequestButton();
        stripe.onWindowLoaded(stripe.initPaymentRequestButton);

        stripe.onStripeInitCallback();
    },
    onWindowLoaded: function(callback)
    {
        if (window.attachEvent)
            window.attachEvent("onload", callback); // IE
        else
            window.addEventListener("load", callback); // Other browsers
    },
    initReviewStepErrors: function()
    {
        if (typeof Review == 'undefined' || typeof Review.prototype.nextStep == 'undefined')
            return;

        Review.prototype._nextStep = Review.prototype.nextStep;

        var nextStep = Review.prototype.nextStep;
        Review.prototype.nextStep = function(transport)
        {
            if (stripe.oscInitialized)
                return this._nextStep(transport);

            if (transport) {
                var response = transport.responseJSON || transport.responseText.evalJSON(true) || {};

                if (response.redirect) {
                    this.isSuccess = true;
                    location.href = encodeURI(response.redirect);
                    return;
                }
                if (response.success) {
                    this.isSuccess = true;
                    location.href = encodeURI(this.successUrl);
                }
                else{
                    var msg = response.error_messages;
                    if (Object.isArray(msg)) {
                        msg = msg.join("\n").stripTags().toString();
                    }
                    if (msg) {
                        stripe.displayReviewStepError(msg);
                    }
                }

                if (response.update_section) {
                    $('checkout-'+response.update_section.name+'-load').update(response.update_section.html);
                }

                if (response.goto_section) {
                    checkout.gotoSection(response.goto_section, true);
                }
            }
        };
        if (typeof review != 'undefined')
        {
            review.nextStep = Review.prototype.nextStep;
            review._nextStep = Review.prototype._nextStep;
        }
    },
    displayReviewStepError: function(msg)
    {
        if (msg.indexOf("reusable source you provided is consumed") >= 0)
        {
            alert("Your card was declined");
            stripe.displayCardError("Your card was declined", true);
            deleteStripeToken();
        }
        else if (msg.indexOf("card was declined") >= 0)
        {
            alert(msg);
            stripe.displayCardError(msg, true);
            deleteStripeToken();
        }
        else
            alert(msg);
    },
    validatePaymentForm: function(callback)
    {
        if (!this.paymentFormValidator)
            this.paymentFormValidator = new Validation('payment_form_stripe_payments');

        if (!this.paymentFormValidator.form)
            this.paymentFormValidator = new Validation('new-card');

        if (!this.paymentFormValidator.form)
            return true;

        this.paymentFormValidator.reset();

        result = this.paymentFormValidator.validate();

        // The Magento validator will try to pass over injected Stripe Elements, so to exclude those,
        // check if any of the form elements have a validation-failed class
        if (!result)
        {
            var failedElements = Form.getElements('payment_form_stripe_payments').findAll(function(elm){
                return $(elm).hasClassName('validation-failed');
            });
            if (failedElements.length === 0)
                return true;
        }

        return result;
    },
    placeAdminOrder: function(e)
    {
        var radioButton = document.getElementById('p_method_stripe_payments');
        if (radioButton && !radioButton.checked)
            return order.submit();

        createStripeToken(function(err)
        {
            if (err)
                alert(err);
            else
                order.submit();
        });
    },
    addAVSFieldsTo: function(cardDetails)
    {
        var owner = stripe.getSourceOwner();
        cardDetails.name = owner.name;
        cardDetails.address_line1 = owner.address.line1;
        cardDetails.address_line2 = owner.address.line2;
        cardDetails.address_zip = owner.address.postal_code;
        cardDetails.address_city = owner.address.city;
        cardDetails.address_state = owner.address.state;
        cardDetails.address_country = owner.address.country;
        return cardDetails;
    },
    getSourceOwner: function()
    {
        // Format is
        var owner = {
            name: null,
            email: null,
            phone: null,
            address: {
                city: null,
                country: null,
                line1: null,
                line2: null,
                postal_code: null,
                state: null
            }
        };

        // If there is an address select dropdown, don't read the address from the input fields in case
        // the customer changes the address from the dropdown. Dropdown value changes do not update the
        // plain input fields
        if (!document.getElementById('billing-address-select'))
        {
            // Scenario 1: We are in the admin area creating an order for a guest who has no saved address yet
            var line1 = document.getElementById('order-billing_address_street0');
            var postcode = document.getElementById('order-billing_address_postcode');
            var email = document.getElementById('order-billing_address_email');

            // Scenario 2: Checkout page with an OSC module and a guest customer
            if (!line1)
                line1 = document.getElementById('billing:street1');

            if (!postcode)
                postcode = document.getElementById('billing:postcode');

            if (!email)
                email = document.getElementById('billing:email');

            if (line1)
                owner.address.line1 = line1.value;

            if (postcode)
                owner.address.postal_code = postcode.value;

            if (email)
                owner.email = email.value;

            // New fields
            if (document.getElementById('billing:firstname'))
                owner.name = document.getElementById('billing:firstname').value + ' ' + document.getElementById('billing:lastname').value;

            if (document.getElementById('billing:telephone'))
                owner.phone = document.getElementById('billing:telephone').value;

            if (document.getElementById('billing:city'))
                owner.address.city = document.getElementById('billing:city').value;

            if (document.getElementById('billing:country_id'))
                owner.address.country = document.getElementById('billing:country_id').value;

            if (document.getElementById('billing:street2'))
                owner.address.line2 = document.getElementById('billing:street2').value;

            if (document.getElementById('billing:region'))
                owner.address.state = document.getElementById('billing:region').value;
        }

        // Scenario 3: Checkout or admin area and a registered customer already has a pre-loaded billing address
        if (stripe.billingInfo !== null)
        {
            if (owner.email === null && stripe.billingInfo.email !== null)
                owner.email = stripe.billingInfo.email;

            if (owner.address.line1 === null && stripe.billingInfo.line1 !== null)
                owner.address.line1 = stripe.billingInfo.line1;

            if (owner.address.postal_code === null && stripe.billingInfo.postcode !== null)
                owner.address.postal_code = stripe.billingInfo.postcode;

            // New fields
            if (owner.name === null && stripe.billingInfo.name !== null)
                owner.name = stripe.billingInfo.name;

            if (owner.phone === null && stripe.billingInfo.phone !== null)
                owner.phone = stripe.billingInfo.phone;

            if (owner.address.city === null && stripe.billingInfo.city !== null)
                owner.address.city = stripe.billingInfo.city;

            if (owner.address.country === null && stripe.billingInfo.country !== null)
                owner.address.country = stripe.billingInfo.country;

            if (owner.address.line2 === null && stripe.billingInfo.line2 !== null)
                owner.address.line2 = stripe.billingInfo.line2;

            if (owner.address.state === null && stripe.billingInfo.state !== null)
                owner.address.state = stripe.billingInfo.state;
        }

        if (!owner.phone)
            delete owner.phone;

        return owner;
    },
    displayCardError: function(message, inline)
    {
        // Some OSC modules have the Place Order button away from the payment form
        if (stripe.oscInitialized && typeof inline == 'undefined')
        {
            alert(message);
            return;
        }

        // When we use a saved card, display the message as an alert
        var newCardRadio = document.getElementById('new_card');
        if (newCardRadio && !newCardRadio.checked)
        {
            alert(message);
            return;
        }

        var box = $('stripe-payments-card-errors');

        if (box)
        {
            try
            {
                checkout.gotoSection("payment");
            }
            catch (e) {}

            box.update(message);
            box.addClassName('populated');
        }
        else
            alert(message);
    },
    clearCardErrors: function()
    {
        var box = $('stripe-payments-card-errors');

        if (box)
        {
            box.update("");
            box.removeClassName('populated');
        }
    },
    isApplePayEnabled: function()
    {
        // Some OSC modules will refuse to reload the payment method when the billing address is changed for a customer.
        // We can't use Apple Pay without a billing address
        if (typeof paramsApplePay == "undefined" || !paramsApplePay)
            return false;

        return true;
    },
    hasNoCountryCode: function()
    {
        return (typeof paramsApplePay.country == "undefined" || !paramsApplePay.country || paramsApplePay.country.length === 0);
    },
    getCountryElement: function()
    {
        var element = document.getElementById('billing:country_id');

        if (!element)
            element = document.getElementById('billing_country_id');

        if (!element)
        {
            var selects = document.getElementsByName('billing[country_id]');
            if (selects.length > 0)
                element = selects[0];
        }

        return element;
    },
    getCountryCode: function()
    {
        var element = stripe.getCountryElement();

        if (!element)
            return null;

        if (element.value && element.value.length > 0)
            return element.value;

        return null;
    },
    initResetButton: function()
    {
        var resetButton = document.getElementById('apple-pay-reset');
        resetButton.addEventListener('click', resetApplePayToken);
        resetButton.disabled = false;
    },
    getStripeElementsStyle: function()
    {
        // Custom styling can be passed to options when creating an Element.
        return {
            base: {
                // Add your base input styles here. For example:
                fontSize: '16px',
                lineHeight: '24px'
                // iconColor: '#c4f0ff',
                // color: '#31325F'
        //         fontWeight: 300,
        //         fontFamily: '"Helvetica Neue", Helvetica, sans-serif',

        //         '::placeholder': {
        //             color: '#CFD7E0'
        //         }
            }
        };
    },
    getStripeElementCardNumberOptions: function()
    {
        return {
            // iconStyle: 'solid',
            // hideIcon: false,
            style: stripe.getStripeElementsStyle()
        };
    },
    getStripeElementCardExpiryOptions: function()
    {
        return {
            style: stripe.getStripeElementsStyle()
        };
    },
    getStripeElementCardCvcOptions: function()
    {
        return {
            style: stripe.getStripeElementsStyle()
        };
    },
    getStripeElementsOptions: function()
    {
        return {
            locale: 'auto'
        };
    },
    initStripeElements: function()
    {
        if (stripe.securityMethod != 2)
            return;

        if (document.getElementById('stripe-payments-card-number') === null)
            return;

        var elements = stripe.stripeJsV3.elements(stripe.getStripeElementsOptions());

        var cardNumber = stripe.card = elements.create('cardNumber', stripe.getStripeElementCardNumberOptions());
        cardNumber.mount('#stripe-payments-card-number');
        cardNumber.addEventListener('change', stripe.stripeElementsOnChange);

        var cardExpiry = elements.create('cardExpiry', stripe.getStripeElementCardExpiryOptions());
        cardExpiry.mount('#stripe-payments-card-expiry');
        cardExpiry.addEventListener('change', stripe.stripeElementsOnChange);

        var cardCvc = elements.create('cardCvc', stripe.getStripeElementCardCvcOptions());
        cardCvc.mount('#stripe-payments-card-cvc');
        cardCvc.addEventListener('change', stripe.stripeElementsOnChange);
    },
    stripeElementsOnChange: function(event)
    {
        if (typeof event.brand != 'undefined')
            stripe.onCardNumberChanged(event.brand);

        if (event.error)
            stripe.displayCardError(event.error.message, true);
        else
            stripe.clearCardErrors();
    },
    onCardNumberChanged: function(cardType)
    {
        stripe.onCardNumberChangedFade(cardType);
        stripe.onCardNumberChangedSwapIcon(cardType);
    },
    resetIconsFade: function()
    {
        stripe.iconsContainer.className = 'input-box';
        var children = stripe.iconsContainer.getElementsByTagName('img');
        for (var i = 0; i < children.length; i++)
            children[i].className = '';
    },
    onCardNumberChangedFade: function(cardType)
    {
        if (!stripe.iconsContainer)
            stripe.iconsContainer = document.getElementById('stripe-payments-accepted-cards');

        if (!stripe.iconsContainer)
            return;

        stripe.resetIconsFade();

        if (!cardType || cardType == "unknown") return;

        var img = document.getElementById('stripe_payments_' + cardType + '_type');
        if (!img) return;

        img.className = 'active';
        stripe.iconsContainer.className = 'input-box stripe-payments-detected';
    },
    cardBrandToPfClass: {
        'visa': 'pf-visa',
        'mastercard': 'pf-mastercard',
        'amex': 'pf-american-express',
        'discover': 'pf-discover',
        'diners': 'pf-diners',
        'jcb': 'pf-jcb',
        'unknown': 'pf-credit-card',
    },
    onCardNumberChangedSwapIcon: function(cardType)
    {
        var brandIconElement = document.getElementById('stripe-payments-brand-icon');
        var pfClass = 'pf-credit-card';
        if (cardType in stripe.cardBrandToPfClass)
            pfClass = stripe.cardBrandToPfClass[cardType];

        for (var i = brandIconElement.classList.length - 1; i >= 0; i--)
            brandIconElement.classList.remove(brandIconElement.classList[i]);

        brandIconElement.classList.add('pf');
        brandIconElement.classList.add(pfClass);
    },
    initPaymentRequestButton: function()
    {
        if (!stripe.isApplePayEnabled())
            return;

        if (stripe.hasNoCountryCode())
            paramsApplePay.country = stripe.getCountryCode();

        if (stripe.hasNoCountryCode())
            return;

        var paymentRequest;
        try
        {
            paymentRequest = stripe.stripeJsV3.paymentRequest(paramsApplePay);
            var elements = stripe.stripeJsV3.elements();
            var prButton = elements.create('paymentRequestButton', {
                paymentRequest: paymentRequest,
            });
        }
        catch (e)
        {
            console.warn(e.message);
            return;
        }

        // Check the availability of the Payment Request API first.
        paymentRequest.canMakePayment().then(function(result)
        {
            if (result)
            {
                if (!document.getElementById('payment-request-button'))
                    return;

                prButton.mount('#payment-request-button');
                $('payment_form_stripe_payments').addClassName('payment-request-api-supported');
                if ($('co-payment-form'))
                    $('co-payment-form').addClassName('payment-request-api-supported');
                stripe.initResetButton();
            }
        });

        paymentRequest.on('paymentmethod', function(result)
        {
            try
            {
                stripe.PRAPIEvent = result;
                setStripeToken(result.paymentMethod.id + ':' + result.paymentMethod.card.brand + ':' + result.paymentMethod.card.last4);
                setApplePayToken(result.paymentMethod);
                stripe.closePaysheet('success');
            }
            catch (e)
            {
                stripe.closePaysheet('fail');
                console.error(e);
            }
        });
    },
    isPaymentMethodSelected: function()
    {
        if (typeof payment != 'undefined' && typeof payment.currentMethod != 'undefined' && payment.currentMethod.length > 0)
            return (payment.currentMethod == 'stripe_payments');
        else
        {
            var radioButton = document.getElementById('p_method_stripe_payments');
            if (!radioButton || !radioButton.checked)
                return false;

            return true;
        }
    },
    selectMandate: function()
    {
        document.getElementById('stripe_payments_sepa_iban').classList.remove("required-entry");
    },
    selectNewIBAN: function()
    {
        document.getElementById('new_mandate').checked = 1;
        document.getElementById('stripe_payments_sepa_iban').classList.add("required-entry");
    },
    setLoadWaiting: function(section)
    {
        // Check if defined first in case of an OSC module rewriting the whole thing
        if (typeof checkout != 'undefined' && checkout && checkout.setLoadWaiting)
        {
            try
            {
                // OSC modules may also cause crashes if they have stripped away the html elements
                checkout.setLoadWaiting(section);
            }
            catch (e) {}
        }
        else
            stripe.toggleAdminSave(section);
    },
    // Triggered when the user clicks a saved card radio button
    useCard: function()
    {
        var token = stripe.getSelectedSavedCard();

        // User wants to use a new card
        if (token == null)
        {
            enablePaymentFormValidation();
            deleteStripeToken();
            stripe.sourceId = null;
        }
        // User wants to use a saved card
        else
        {
            disablePaymentFormValidation();
            setStripeToken(token);
            stripe.sourceId = stripe.cleanToken(token);
        }
    },
    getSelectedSavedCard: function()
    {
        var elements = document.getElementsByName("payment[cc_saved]");
        if (elements.length == 0)
            return null;
        var selected = null;
        for (var i = 0; i < elements.length; i++)
            if (elements[i].checked)
                selected = elements[i];
        if (!selected)
            return null;
        if (selected.value == 'new_card')
            return null;
        return selected.value;
    },
    // Converts tokens in the form "src_1E8UX32WmagXEVq4SpUlSuoa:Visa:4242" into src_1E8UX32WmagXEVq4SpUlSuoa
    cleanToken: function(token)
    {
        if (token.indexOf(":") >= 0)
            return token.substring(0, token.indexOf(":"));
        return token;
    },
    shouldSaveCard: function()
    {
        var saveCardInput = document.getElementById('stripe_payments_cc_save');
        if (!saveCardInput)
            return false;
        return saveCardInput.checked;
    },
    getPaymentIntent: function(callback)
    {
        new Ajax.Request(
            MAGENTO_BASE_URL + 'stripe_payments/api/get_payment_intent', {
                method: 'post',
                onComplete: function (response)
                {
                    try
                    {
                        callback(null, response.responseJSON.paymentIntent);
                    }
                    catch (e)
                    {
                        callback("Could not retrieve payment details, please contact us for help");
                        console.error(response);
                    }
                }
            }
        );
    },
    handleCardPayment: function(done)
    {
        try
        {
            stripe.closePaysheet('success');

            stripe.stripeJsV3.handleCardPayment(stripe.paymentIntent).then(function(result)
            {
                if (result.error)
                    return done(result.error.message);

                return done();
            });
        }
        catch (e)
        {
            done(e.message);
        }
    },
    handleCardAction: function(done)
    {
        try
        {
            stripe.closePaysheet('success');

            stripe.stripeJsV3.handleCardAction(stripe.paymentIntent).then(function(result)
            {
                if (result.error)
                    return done(result.error.message);

                return done();
            });
        }
        catch (e)
        {
            done(e.message);
        }
    },
    processNextAuthentication: function(done)
    {
        if (stripe.paymentIntents.length > 0)
        {
            stripe.paymentIntent = stripe.paymentIntents.pop();
            stripe.authenticateCustomer(function(err)
            {
                if (err)
                    done(err);
                else
                    stripe.processNextAuthentication(done);
            });
        }
        else
        {
            stripe.paymentIntent = null;
            return done();
        }
    },
    authenticateCustomer: function(done)
    {
        try
        {
            stripe.stripeJsV3.retrievePaymentIntent(stripe.paymentIntent).then(function(result)
            {
                if (result.error)
                    return done(result.error);

                if (result.paymentIntent.status == "requires_action"
                    || result.paymentIntent.status == "requires_source_action")
                {
                    if (result.paymentIntent.confirmation_method == "manual")
                        return stripe.handleCardAction(done);
                    else
                        return stripe.handleCardPayment(done);
                }

                return done();
            });
        }
        catch (e)
        {
            done(e.message);
        }
    },
    isNextAction3DSecureRedirect: function(result)
    {
        if (!result)
            return false;

        if (typeof result.paymentIntent == 'undefined' || !result.paymentIntent)
            return false;

        if (typeof result.paymentIntent.next_action == 'undefined' || !result.paymentIntent.next_action)
            return false;

        if (typeof result.paymentIntent.next_action.use_stripe_sdk == 'undefined' || !result.paymentIntent.next_action.use_stripe_sdk)
            return false;

        if (typeof result.paymentIntent.next_action.use_stripe_sdk.type == 'undefined' || !result.paymentIntent.next_action.use_stripe_sdk.type)
            return false;

        return (result.paymentIntent.next_action.use_stripe_sdk.type == 'three_d_secure_redirect');
    },
    paymentIntentCanBeConfirmed: function()
    {
        // If stripe.sourceId exists, it means that we are using a saved card source, which is not going to be a 3DS card
        // (because those are hidden from the admin saved cards section)
        return !stripe.sourceId;
    },
    maskError: function(err)
    {
        var errLowercase = err.toLowerCase();
        var pos1 = errLowercase.indexOf("Invalid API key provided".toLowerCase());
        var pos2 = errLowercase.indexOf("No API key provided".toLowerCase());
        if (pos1 === 0 || pos2 === 0)
            return 'Invalid Stripe API key provided.';

        return err;
    },
    closePaysheet: function(withResult)
    {
        try
        {
            if (!stripe.PRAPIEvent)
                return;

            stripe.PRAPIEvent.complete(withResult);
        }
        catch (e)
        {
            // Will get here if we already closed it
        }
    },
    isApplePayInsideForm: function()
    {
        return stripe.applePayLocation == 2;
    },
    triggerCustomerAuthentication: function()
    {
        if (stripe.is3DSecureOpen)
            return;

        stripe.agreeToTerms();
        stripe.is3DSecureOpen = true;
        stripe.authenticateCustomer(function(err)
        {
            stripe.is3DSecureOpen = false;

            if (err)
                return stripe.displayCardError(err);

            stripe.placeOrder();
        });
    },
    agreeToTerms: function()
    {
        // Some OSC modules such as LotusBreath and Idev OSC reload the page when customer authentication is required
        // causing the terms and agreements checkboxes to lose their value. We re-agree here so that we can resubmit the form.
        var agreements = $$(".checkout-agreements input[type=checkbox]");
        for (var i = 0; i < agreements.length; i++)
            agreements[i].checked = true;
    },
    parseErrorMessage: function(msg)
    {
        stripe.paymentIntent = null;

        if (msg == "Authentication Required")
            return true;

        // Case of subscriptions
        if (msg.indexOf("Authentication Required: ") === 0)
        {
            stripe.paymentIntent = msg.substring("Authentication Required: ".length);
            return true;
        }
        // FME QuickCheckout prefers to inform us that this is a core exception...
        else if (msg.indexOf("Core Exception: Authentication Required: ") === 0)
        {
            stripe.paymentIntent = msg.substring("Core Exception: Authentication Required: ".length);
            return true;
        }

        return false;
    },
    isAuthenticationRequired: function(msgs)
    {
        if (typeof msgs == "undefined")
            return false;

        if (typeof msgs[0] == "string")
        {
            var multipleMsgs = msgs[0].split(/\n/);
            if (multipleMsgs.length > 0)
            {
                for (var i = 0; i < multipleMsgs.length; i++)
                    if (stripe.parseErrorMessage(multipleMsgs[i]))
                        return true;
            }
        }

        return false;
    },
    initAlertProxy: function(authenticationMethod)
    {
        if (stripe.isAlertProxyInitialized)
            return;

        stripe.isAlertProxyInitialized = true;

        (function(proxied)
        {
            window.alert = function()
            {
                if (stripe.isAuthenticationRequired(arguments))
                {
                    authenticationMethod();
                }
                else
                    return proxied.apply(this, arguments);
            };
        })
        (window.alert);
    },
    searchForAuthenticationRequiredError: function(authenticationMethod)
    {
        // Some OSC modules will not alert the error, they will instead redirect to the same page and add the error in a DOM element.
        // Here we handle those cases
        var errors = $$('.onestepcheckout-error')
            .concat($$('.error-msg li'))
            .concat($$('.error-msg span'))
            .concat($$('.opc-message-container'))
            .concat($$('#saveOder-error'));

        for (var i = 0; i < errors.length; i++)
        {
            if (!errors[i])
                continue;

            if (stripe.parseErrorMessage(errors[i].innerText))
            {
                errors.each(Element.hide);
                $$('ul.messages').each(Element.hide);
                authenticationMethod();
                break;
            }
        }
    },
    toggleAdminSave: function(disable)
    {
        if (typeof disableElements != 'undefined' && typeof enableElements != 'undefined')
        {
            if (disable)
                disableElements('save');
            else
                enableElements('save');
        }
    },
    ach:
    {
        token: null,
        verificationError: 'Could not verify bank account details!',

        getParams: function()
        {
            var routingNumber = $('stripe-ach-routing_number').value;
            var accountNumber = $('stripe-ach-account_number').value;
            var accountHolderName = $('stripe-ach-account_holder_name').value;
            var accountHolderType = $('stripe-ach-account_holder_type').value;
            var country = $('stripe-ach-country').value;
            var currency = $('stripe-ach-currency').value;

            if (routingNumber.length === 0 ||
                accountNumber.length === 0 ||
                accountHolderName.length === 0 ||
                accountHolderType.length === 0)
            {
                stripe.ach.verificationError = 'Please enter your account details';
                return false;
            }

            if (country.length === 0 ||
                currency.length === 0)
            {
                stripe.ach.verificationError = 'Your country or currency could not be determined';
                return false;
            }

            return {
              country: country,
              currency: currency,
              routing_number: routingNumber,
              account_number: accountNumber,
              account_holder_name: accountHolderName,
              account_holder_type: accountHolderType,
            };
        },
        generateToken: function()
        {
            var params = stripe.ach.getParams();

            if (!params)
                return;

            if (params.routing_number.length < 9)
                return;

            if (params.account_number.length < 4)
                return;

            if (!stripe.stripeJsV3)
            {
                stripe.ach.verificationError = 'Could not verify bank details because the Stripe.js v3 security method has not been enabled';
                return;
            }

            stripe.ach.hideErrors();

            stripe.stripeJsV3.createToken('bank_account', params).then(function(result)
            {
                if (result.token)
                    stripe.ach.setToken(result.token.id, result.token.bank_account);
                else
                {
                    if (result.error)
                        stripe.ach.verificationError = result.error.message;
                    else
                        stripe.ach.verificationError = 'Your bank account details could not be used to verify your account';

                    stripe.ach.showErrors();
                }
            });
        },
        validateForm: function(value)
        {
            stripe.ach.generateToken();

            if (stripe.ach.token)
                return true;

            stripe.ach.showErrors();

            return false;
        },
        resetToken: function()
        {
            stripe.ach.token = null;
            $('stripe-ach-token').value = "";

            stripe.ach.hideSuccessMessage();
            stripe.ach.hideErrors();
            stripe.ach.generateToken();
        },
        setToken: function(token, bank_account)
        {
            stripe.ach.token = token;
            $('stripe-ach-token').value = token;

            stripe.ach.showSuccessMessage();
            stripe.ach.hideErrors();
        },
        setVerificationError: function()
        {
            setTimeout(function(){
                var el = $('advice-stripe-payments-ach-generate-token-stripe-ach-token');
                if (el)
                    el.innerText = stripe.ach.verificationError;
            }, 10);
        },
        hideErrors: function()
        {
            $('ach-bank-account-details').removeClassName("showVerificationError");
            stripe.ach.verificationError = 'Could not verify bank account details!';
            stripe.ach.setVerificationError();
        },
        showErrors: function()
        {
            $('ach-bank-account-details').addClassName("showVerificationError");
            stripe.ach.setVerificationError();
        },
        hideSuccessMessage: function()
        {
            $('stripe-ach-account-verified').style.display = "none";
        },
        showSuccessMessage: function()
        {
            $('stripe-ach-account-verified').style.display = "block";
        }
    }
};

var initAdmin = function()
{
    var btn = document.getElementById('order-totals');
    if (btn) btn = btn.getElementsByTagName('button');
    if (btn && btn[0]) btn = btn[0];
    if (btn) btn.onclick = stripe.placeAdminOrder;

    var topBtns = document.getElementsByClassName('save');
    for (var i = 0; i < topBtns.length; i++)
    {
        topBtns[i].onclick = stripe.placeAdminOrder;
    }
};

var setApplePayToken = function(token)
{
    if (!stripe.isApplePayEnabled())
        return;

    var radio = document.querySelector('input[name="payment[cc_saved]"]:checked');
    if (!radio || (radio && radio.value == 'new_card'))
        disablePaymentFormValidation();

    if ($('new_card'))
        $('new_card').removeClassName('validate-one-required-by-name');

    $('apple-pay-result-brand').update(token.card.brand);
    $('apple-pay-result-last4').update(token.card.last4);
    $('payment_form_stripe_payments').addClassName('apple-pay-success');

    if (!stripe.isApplePayInsideForm() && $('co-payment-form'))
        $('co-payment-form').addClassName('apple-pay-success');

    $('apple-pay-result-brand').className = "type " + token.card.brand;
    stripe.applePaySuccess = true;
    stripe.applePayToken = token;
    stripe.sourceId = token.id;

    // Ensure that a payment method is selected if Apple Pay is used outside the payment form
    var el = document.getElementById("p_method_stripe_payments");
    if (el) el.checked = true;
};

var resetApplePayToken = function()
{
    if (!stripe.isApplePayEnabled())
        return;

    var radio = document.querySelector('input[name="payment[cc_saved]"]:checked');
    if (!radio || (radio && radio.value == 'new_card'))
        enablePaymentFormValidation();

    if ($('new_card'))
        $('new_card').addClassName('validate-one-required-by-name');

    $('payment_form_stripe_payments').removeClassName('apple-pay-success');

    if (!stripe.isApplePayInsideForm() && $('co-payment-form'))
        $('co-payment-form').removeClassName('apple-pay-success');

    if ($('apple-pay-result-brand'))
    {
        $('apple-pay-result-brand').update();
        $('apple-pay-result-last4').update();
        $('apple-pay-result-brand').className = "";
    }
    deleteStripeToken();
    stripe.applePaySuccess = false;
    stripe.applePayToken = null;
};

var getCardDetails = function()
{
    // Validate the card
    var cardName = document.getElementById('stripe_payments_cc_owner');
    var cardNumber = document.getElementById('stripe_payments_cc_number');
    var cardCvc = document.getElementById('stripe_payments_cc_cid');
    var cardExpMonth = document.getElementById('stripe_payments_expiration');
    var cardExpYear = document.getElementById('stripe_payments_expiration_yr');

    var isValid = cardName && cardName.value && cardNumber && cardNumber.value && cardCvc && cardCvc.value && cardExpMonth && cardExpMonth.value && cardExpYear && cardExpYear.value;

    if (!isValid) return null;

    var cardDetails = {
        name: cardName.value,
        number: cardNumber.value,
        cvc: cardCvc.value,
        exp_month: cardExpMonth.value,
        exp_year: cardExpYear.value
    };

    cardDetails = stripe.addAVSFieldsTo(cardDetails);

    return cardDetails;
};

var createStripeToken = function(callback)
{
    stripe.clearCardErrors();

    // Card validation, displays the error at the payment form section
    if (!stripe.validatePaymentForm())
        return;

    // Terms and Agreements validation, shows as an alert
    var terms = $$('#checkout-agreements input[type=checkbox]');

    stripe.setLoadWaiting('review');
    var done = function(err)
    {
        stripe.setLoadWaiting(false);

        if (err)
        {
            resetApplePayToken();
            err = stripe.maskError(err);
        }

        return callback(err);
    };

    if (stripe.applePaySuccess)
    {
        return done();
    }

    // First check if the "Use new card" radio is selected, return if not
    var cardDetails, newCardRadio = document.getElementById('new_card');
    if (newCardRadio && !newCardRadio.checked)
    {
        if (stripe.sourceId)
            setStripeToken(stripe.sourceId);
        else
            return done("No card specified");

        return done(); // We are using a saved card token for the payment
    }

    try
    {
        var data = {
            billing_details: stripe.getSourceOwner()
        };

        stripe.stripeJsV3.createPaymentMethod('card', stripe.card, data).then(function(result)
        {
            if (result.error)
                return done(result.error.message);

            var cardKey = result.paymentMethod.id;
            var token = result.paymentMethod.id + ':' + result.paymentMethod.card.brand + ':' + result.paymentMethod.card.last4;
            stripeTokens[cardKey] = token;
            setStripeToken(token);

            return done();
        });
    }
    catch (e)
    {
        return done(e.message);
    }
};

function setStripeToken(token)
{
    try
    {
        var input, inputs = document.getElementsByClassName('stripejs-token');
        if (inputs && inputs[0]) input = inputs[0];
        else input = document.createElement("input");
        input.setAttribute("type", "hidden");
        input.setAttribute("name", "payment[cc_stripejs_token]");
        input.setAttribute("class", 'stripejs-token');
        input.setAttribute("value", token);
        input.disabled = false; // Gets disabled when the user navigates back to shipping method
        var form = document.getElementById('payment_form_stripe_payments');
        if (!form) form = document.getElementById('co-payment-form');
        if (!form) form = document.getElementById('order-billing_method_form');
        if (!form) form = document.getElementById('onestepcheckout-form');
        if (!form && typeof payment != 'undefined') form = document.getElementById(payment.formId);
        if (!form)
        {
            form = document.getElementById('new-card');
            input.setAttribute("name", "newcard[cc_stripejs_token]");
        }
        form.appendChild(input);
    } catch (e) {}
}

function deleteStripeToken()
{
    var input, inputs = document.getElementsByClassName('stripejs-token');
    if (inputs && inputs[0]) input = inputs[0];
    if (input && input.parentNode) input.parentNode.removeChild(input);
}

// Multi-shipping form support for Stripe.js
var multiShippingForm = null, multiShippingFormSubmitButton = null;

function submitMultiShippingForm(e)
{
    if (!stripe.isPaymentMethodSelected())
        return true;

    if (e.preventDefault) e.preventDefault();

    if (!multiShippingFormSubmitButton) multiShippingFormSubmitButton = document.getElementById('payment-continue');
    if (multiShippingFormSubmitButton) multiShippingFormSubmitButton.disabled = true;

    createStripeToken(function(err)
    {
        if (multiShippingFormSubmitButton) multiShippingFormSubmitButton.disabled = false;

        if (err)
            stripe.displayCardError(err);
        else
            multiShippingForm.submit();
    });

    return false;
}

// Multi-shipping form
var initMultiShippingForm = function()
{
    if (typeof payment == 'undefined' ||
        payment.formId != 'multishipping-billing-form' ||
        stripe.multiShippingFormInitialized)
        return;

    multiShippingForm = document.getElementById(payment.formId);
    if (!multiShippingForm) return;

    if (multiShippingForm.attachEvent)
        multiShippingForm.attachEvent("submit", submitMultiShippingForm);
    else
        multiShippingForm.addEventListener("submit", submitMultiShippingForm);

    stripe.multiShippingFormInitialized = true;
};

var isCheckbox = function(input)
{
    return input.attributes && input.attributes.length > 0 &&
        (input.type === "checkbox" || input.attributes[0].value === "checkbox" || input.attributes[0].nodeValue === "checkbox");
};

var disablePaymentFormValidation = function()
{
    var i, inputs = document.querySelectorAll(".stripe-input");
    var parentId = 'payment_form_stripe_payments';

    $(parentId).removeClassName("stripe-new");
    for (i = 0; i < inputs.length; i++)
    {
        if (isCheckbox(inputs[i])) continue;
        $(inputs[i]).removeClassName('required-entry');
    }
};

var enablePaymentFormValidation = function()
{
    var i, inputs = document.querySelectorAll(".stripe-input");
    var parentId = 'payment_form_stripe_payments';

    $(parentId).addClassName("stripe-new");
    for (i = 0; i < inputs.length; i++)
    {
        if (isCheckbox(inputs[i])) continue;
        $(inputs[i]).addClassName('required-entry');
    }
};

var toggleValidation = function(evt)
{
    $('new_card').removeClassName('validate-one-required-by-name');
    if (evt.target.value == 'stripe_payments')
        $('new_card').addClassName('validate-one-required-by-name');
};

var initSavedCards = function(isAdmin)
{
    if (isAdmin)
    {
        // Adjust validation if necessary
        var newCardRadio = document.getElementById('new_card');
        if (newCardRadio)
        {
            var methods = document.getElementsByName('payment[method]');
            for (var j = 0; j < methods.length; j++)
                methods[j].addEventListener("click", toggleValidation);
        }
    }
};

var saveNewCard = function()
{
    var saveButton = document.getElementById('stripe-savecard-button');
    var wait = document.getElementById('stripe-savecard-please-wait');
    saveButton.style.display = "none";
    wait.style.display = "block";

    if (typeof Stripe != 'undefined')
    {
        createStripeToken(function(err)
        {
            saveButton.style.display = "block";
            wait.style.display = "none";

            if (err)
                stripe.displayCardError(err);
            else
                document.getElementById("new-card").submit();

        });
        return false;
    }

    return true;
};

var initOSCModules = function()
{
    if (stripe.oscInitialized) return;

    // Front end bindings
    if (typeof IWD != "undefined" && typeof IWD.OPC != "undefined")
    {
        IWD.OPC.isAuthenticationInProgress = false;

        // IWD OnePage Checkout override, which is a tad of a mess
        var proceed = function()
        {
            if (typeof $j == 'undefined') // IWD 4.0.4
                $j = $j_opc; // IWD 4.0.8

            var form = $j('#co-payment-form').serializeArray();
            IWD.OPC.Checkout.xhr = $j.post(IWD.OPC.Checkout.config.baseUrl + 'onepage/json/savePayment',form, IWD.OPC.preparePaymentResponse,'json');
        };

        stripe.placeOrder = function()
        {
            proceed();
        };

        IWD.OPC.savePayment = function()
        {
            if (!IWD.OPC.saveOrderStatus)
                return;

            if (IWD.OPC.Checkout.xhr !== null)
                IWD.OPC.Checkout.xhr.abort();

            IWD.OPC.Checkout.lockPlaceOrder();

            if (!stripe.isPaymentMethodSelected())
                return stripe.placeOrder();

            if (IWD.OPC.isAuthenticationInProgress && typeof IWD.OPC.saveOrder != "undefined") // IWD 4.3.4
            {
                IWD.OPC.isAuthenticationInProgress = false; // Turn it off on the second order submission
                IWD.OPC.saveOrder();
                return;
            }

            createStripeToken(function(err)
            {
                IWD.OPC.Checkout.xhr = null;
                IWD.OPC.Checkout.unlockPlaceOrder();

                if (err)
                {
                    IWD.OPC.Checkout.hideLoader();
                    stripe.displayCardError(err);
                }
                else
                    stripe.placeOrder();
            });
        };

        stripe.onWindowLoaded(function()
        {
            var msgs = $$('.opc-message-container');
            if (msgs.length > 0)
            {
                msgs[0].addEventListener('DOMNodeInserted', function(evt) {
                    stripe.searchForAuthenticationRequiredError(function()
                    {
                        setTimeout(function()
                        {
                            $$('.opc-messages-action button')[0].click();
                        });
                        setTimeout(function()
                        {
                            IWD.OPC.isAuthenticationInProgress = true;

                            stripe.authenticateCustomer(function(err)
                            {
                                if (err)
                                    return stripe.displayCardError(err);

                                // We cannot use stripe.placeOrder with IWD
                                // stripe.placeOrder();
                                $$('#checkout-review-submit button')[0].click();
                            });
                        }, 10);
                    });
                }, false);
            }
        });

        stripe.oscInitialized = true;
    }
    // Magik OneStepCheckout v1.0.1
    else if (typeof MGKOSC != "undefined")
    {
        window.addEventListener("load", function()
        {
            var proceed = checkout.save.bind(checkout);

            stripe.placeOrder = function()
            {
                proceed();
            };

            checkout.save = function(element)
            {
                if (!stripe.isPaymentMethodSelected())
                    return stripe.placeOrder();

                createStripeToken(function(err)
                {
                    if (err)
                        stripe.displayCardError(err);
                    else
                        stripe.placeOrder();
                });
            };
            stripe.initAlertProxy(stripe.triggerCustomerAuthentication);
            stripe.oscInitialized = true;
        });
    }
    // MageCloud Clarion OSC v1.0.2
    else if ($('onestepcheckout_orderform') && $$('.btn-checkout').length > 0)
    {
        var checkoutButton = $$('.btn-checkout').pop();
        stripe.placeOrder = function()
        {
            checkout.save();
        };
        checkoutButton.onclick = function(e)
        {
            e.preventDefault();

            if (!stripe.isPaymentMethodSelected())
                return stripe.placeOrder();

            createStripeToken(function(err)
            {
                if (err)
                    stripe.displayCardError(err);
                else
                    stripe.placeOrder();
            });
        };
        stripe.initAlertProxy(stripe.triggerCustomerAuthentication);
        stripe.oscInitialized = true;
    }
    else if ($('onestep_form'))
    {
        // MageWorld OneStepCheckoutPro v3.4.4
        var initOSC = function()
        {
            OneStep.Views.Init.prototype._updateOrder = OneStep.Views.Init.prototype.updateOrder;
            OneStep.Views.Init.prototype.updateOrder = function()
            {
                var proceed = this._updateOrder.bind(this);

                stripe.placeOrder = function()
                {
                    proceed();
                };

                if (!stripe.isPaymentMethodSelected())
                    return stripe.placeOrder();

                var self = this;

                this.$el.find("#review-please-wait").show();
                window.OneStep.$('.btn-checkout').attr('disabled','disabled');

                createStripeToken(function(err)
                {
                    if (err)
                    {
                        self.$el.find("#review-please-wait").hide();
                        window.OneStep.$('.btn-checkout').removeAttr('disabled');
                        stripe.displayCardError(err);
                    }
                    else
                        stripe.placeOrder();
                });

            };
        };

        window.addEventListener("load", initOSC);
        stripe.initAlertProxy(stripe.triggerCustomerAuthentication);
        stripe.oscInitialized = true;
    }
    // FancyCheckout 1.2.6
    else if ($('fancycheckout_orderform'))
    {
        var placeOrderButton = $$('button.btn-checkout')[0];
        if (!placeOrderButton)
            return;

        stripe.placeOrder = function()
        {
            billingForm.submit();
        };

        placeOrderButton.onclick = function(e)
        {
            if(!billingForm.validator.validate())
                return;

            jQuery('#control_overlay').show();
            jQuery('.opc_wrapper').css('opacity','0.5');

            e.preventDefault();

            if (!stripe.isPaymentMethodSelected())
                return stripe.placeOrder();

            createStripeToken(function(err)
            {
                if (err)
                {
                    stripe.displayCardError(err);
                    jQuery('#control_overlay').hide();
                    jQuery('.opc_wrapper').css('opacity','1');
                }
                else
                    stripe.placeOrder();
            });
        };

        stripe.searchForAuthenticationRequiredError(stripe.triggerCustomerAuthentication);
        stripe.oscInitialized = true;
    }
    else if ($('onestepcheckout-form') && !$('quickcheckout-ajax-loader'))
    {
        // MageBay OneStepCheckout 1.1.5
        // Idev OneStepCheckout 4.5.4
        var setLoading = function(flag)
        {
            if (typeof jQuery == 'undefined')
                return;

            var placeOrderButton = $('onestepcheckout-place-order');
            if (!placeOrderButton)
                return;

            var loading = jQuery('.onestepcheckout-place-order-loading');

            if (flag == true)
            {
                if (loading.length > 0)
                    loading.remove();

                /* Disable button to avoid multiple clicks */
                placeOrderButton.removeClassName('orange').addClassName('grey');
                placeOrderButton.disabled = true;

                var loaderelement = new Element('span').
                    addClassName('onestepcheckout-place-order-loading').
                    update('Please wait, processing your order...');

                placeOrderButton.parentNode.appendChild(loaderelement);
            }
            else
            {
                location.reload();

                if (loading.length > 0)
                    loading.remove();

                placeOrderButton.disabled = false;
            }
        }

        var initIdevOSC = function()
        {
            if (typeof $('onestepcheckout-form').proceed != 'undefined')
                return;

            stripe.placeOrder = function()
            {
                $('onestepcheckout-form').proceed();
            };

            $('onestepcheckout-form').proceed = $('onestepcheckout-form').submit;
            $('onestepcheckout-form').submit = function(e)
            {
                if (!stripe.isPaymentMethodSelected())
                    return stripe.placeOrder();

                setLoading(true);

                createStripeToken(function(err)
                {
                    if (err)
                    {
                        stripe.displayCardError(err);
                        setLoading(false);
                    }
                    else
                        stripe.placeOrder();
                });
            };

            // Idev OneStepCheckout 4.1.0
            if (typeof submitOsc != 'undefined' && typeof $('onestepcheckout-form')._submitOsc == 'undefined')
            {
                $('onestepcheckout-form')._submitOsc = submitOsc;
                submitOsc = function(form, url, message, image)
                {
                    stripe.placeOrder = function()
                    {
                        $('onestepcheckout-form')._submitOsc(form, url, message, image);
                    };

                    if (!stripe.isPaymentMethodSelected())
                        return stripe.placeOrder();

                    setLoading(true);

                    createStripeToken(function(err)
                    {
                        if (err)
                        {
                            stripe.displayCardError(err);
                            setLoading(false);
                        }
                        else
                            stripe.placeOrder();
                    });
                };
            }
        };

        // This is triggered when the billing address changes and the payment method is refreshed
        window.addEventListener("load", initIdevOSC);

        stripe.onWindowLoaded(function()
        {
            stripe.searchForAuthenticationRequiredError(stripe.triggerCustomerAuthentication);
        });

        stripe.oscInitialized = true;
    }
    else if (typeof AWOnestepcheckoutForm != 'undefined')
    {
        // AheadWorks OneStepCheckout 1.3.5
        AWOnestepcheckoutForm.prototype.__sendPlaceOrderRequest = AWOnestepcheckoutForm.prototype._sendPlaceOrderRequest;
        AWOnestepcheckoutForm.prototype._sendPlaceOrderRequest = function()
        {
            var self = this;

            stripe.placeOrder = function()
            {
                self.__sendPlaceOrderRequest();
            };

            if (!stripe.isPaymentMethodSelected())
                return stripe.placeOrder();

            createStripeToken(function(err)
            {
                if (err)
                {
                    stripe.displayCardError(err);
                    try
                    {
                        self.enablePlaceOrderButton();
                        self.hidePleaseWaitNotice();
                        self.hideOverlay();
                    }
                    catch (e) {}
                }
                else
                    stripe.placeOrder();
            });
        };
        stripe.initAlertProxy(stripe.triggerCustomerAuthentication);
        stripe.oscInitialized = true;
    }
    // NextBits OneStepCheckout 1.0.3
    else if (typeof checkoutnext != 'undefined' && typeof Review.prototype.proceed == 'undefined')
    {
        Review.prototype.proceed = Review.prototype.save;
        Review.prototype.save = function()
        {
            var self = this;

            stripe.placeOrder = function()
            {
                self.proceed();
            };

            if (!stripe.isPaymentMethodSelected())
                return stripe.placeOrder();

            createStripeToken(function(err)
            {
                if (err)
                    stripe.displayCardError(err);
                else
                    stripe.placeOrder();
            });
        };

        if (typeof review != 'undefined')
            review.save = Review.prototype.save;

        stripe.oscInitialized = true;
    }
    // Magecheckout OSC 2.2.1
    else if (typeof MagecheckoutSecuredCheckoutPaymentMethod != 'undefined')
    {
        MagecheckoutSecuredCheckoutForm.prototype._placeOrderProcess = MagecheckoutSecuredCheckoutForm.prototype.placeOrderProcess;
        MagecheckoutSecuredCheckoutForm.prototype.placeOrderProcess = function ()
        {
            var self = this;

            stripe.placeOrder = function()
            {
                self._placeOrderProcess();
            };

            if (!stripe.isPaymentMethodSelected())
                return stripe.placeOrder();

            createStripeToken(function(err)
            {
                if (err)
                    stripe.displayCardError(err);
                else
                    stripe.placeOrder();
            });
        };

        if (typeof securedCheckoutForm != 'undefined')
        {
            securedCheckoutForm._placeOrderProcess = MagecheckoutSecuredCheckoutForm.prototype._placeOrderProcess;
            securedCheckoutForm.placeOrderProcess = MagecheckoutSecuredCheckoutForm.prototype.placeOrderProcess;
        }
        stripe.initAlertProxy(stripe.triggerCustomerAuthentication);
        stripe.oscInitialized = true;
    }
    // Lotusbreath OneStepCheckout 4.2.0
    else if (typeof oscObserver != 'undefined' && typeof oscObserver.register != 'undefined')
    {
        window.validToken = false;

        stripe.placeOrder = function()
        {
            $('lbonepage-place-order-btn').click();
        };

        oscObserver.register('beforeSubmitOrder', function()
        {
            if (!stripe.isPaymentMethodSelected())
                return;

            if (window.validToken)
                return;

            oscObserver.stopSubmittingOrder = true;

            createStripeToken(function(err)
            {
                oscObserver.stopSubmittingOrder = false;

                if (err)
                {
                    window.validToken = false;
                    stripe.displayCardError(err, true);
                }
                else
                {
                    window.validToken = true;
                    stripe.placeOrder();
                }
            });

        });

        stripe.onWindowLoaded(function()
        {
            oscObserver.register('afterLoadingNewContent', function()
            {
                // afterLoadingNewContent is called prematurely, allow some time for the DOM to update and the ajax requests to finish
                setTimeout(function(){
                    stripe.searchForAuthenticationRequiredError(stripe.triggerCustomerAuthentication);
                }, 600);
            });
        });

        stripe.oscInitialized = true;
    }
    // FireCheckout 3.2.0
    else if ($('firecheckout-form'))
    {
        var fireCheckoutPlaceOrder = function()
        {
            var self = this;

            if (!stripe.isPaymentMethodSelected())
                return self.proceed();

            if (typeof checkout != "undefined" && typeof checkout.validate != "undefined" && !checkout.validate())
                return;

            createStripeToken(function(err)
            {
                if (err)
                    stripe.displayCardError(err, true);
                else
                    self.proceed();
            });
        };

        window.addEventListener("load", function()
        {
            var btnCheckout = document.getElementsByClassName('btn-checkout');
            if (btnCheckout && btnCheckout.length)
            {
                for (var i = 0; i < btnCheckout.length; i++)
                {
                    var button = btnCheckout[i];
                    button.proceed = button.onclick;
                    button.onclick = fireCheckoutPlaceOrder;

                    stripe.placeOrder = function()
                    {
                        button.proceed();
                    };
                }
            }
        });

        stripe.initAlertProxy(stripe.triggerCustomerAuthentication);

        stripe.oscInitialized = true;
    }
    else if (typeof MagegiantOneStepCheckoutForm != 'undefined')
    {
        // MageGiant OneStepCheckout 4.0.0
        MagegiantOneStepCheckoutForm.prototype.__placeOrderRequest = MagegiantOneStepCheckoutForm.prototype._placeOrderRequest;
        MagegiantOneStepCheckoutForm.prototype._placeOrderRequest = function()
        {
            var self = this;

            stripe.placeOrder = function()
            {
                self.__placeOrderRequest();
            };

            if (!stripe.isPaymentMethodSelected())
                return stripe.placeOrder();

            createStripeToken(function(err)
            {
                if (err)
                    stripe.displayCardError(err);
                else
                    stripe.placeOrder();
            });
        };

        stripe.oscInitialized = true;
    }
    else if (typeof oscPlaceOrder != 'undefined')
    {
        // Magestore OneStepCheckout 3.5.0
        var proceed = oscPlaceOrder;

        oscPlaceOrder = function(element)
        {
            var form = $('one-step-checkout-form');
            var payment_method = $RF(form, 'payment[method]');
            if (payment_method != 'stripe_payments')
                return stripe.placeOrder();

            var validator = new Validation('one-step-checkout-form');

            if (validator.validate())
            {
                createStripeToken(function(err)
                {
                    if (err)
                        stripe.displayCardError(err);
                    else
                        stripe.placeOrder();
                });
            }
        };

        stripe.searchForAuthenticationRequiredError(stripe.triggerCustomerAuthentication);

        stripe.placeOrder = function()
        {
            proceed(document.getElementById('onestepcheckout-button-place-order'));
        };

        stripe.oscInitialized = true;
    }
    // GoMage LightCheckout 5.9
    else if (typeof checkout != 'undefined' && typeof checkout.LightcheckoutSubmit != 'undefined')
    {
        checkout._LightcheckoutSubmit = checkout.LightcheckoutSubmit;

        stripe.placeOrder = function()
        {
            checkout._LightcheckoutSubmit();
        };

        checkout.LightcheckoutSubmit = function()
        {

            if (!stripe.isPaymentMethodSelected())
                return stripe.placeOrder();

            createStripeToken(function(err)
            {
                if (err)
                {
                    stripe.displayCardError(err);
                    checkout.showLoadinfo();
                    location.reload();
                }
                else
                    stripe.placeOrder();
            });
        };

        var triggerModal = null;

        document.getElementsByTagName("BODY")[0].addEventListener('DOMNodeInserted', function(evt)
        {
            if (triggerModal)
                clearTimeout(triggerModal);

            triggerModal = setTimeout(function()
            {
                stripe.searchForAuthenticationRequiredError(stripe.triggerCustomerAuthentication);
            }, 100);

        }, false);

        stripe.oscInitialized = true;
    }
    // Amasty OneStepCheckout 3.0.5
    else if ($('amscheckout-submit') && typeof completeCheckout != 'undefined')
    {
        stripe.placeOrder = function()
        {
            completeCheckout();
        };

        $('amscheckout-submit').onclick = function(el)
        {
            if (!stripe.isPaymentMethodSelected())
                return stripe.placeOrder();

            showLoading();
            createStripeToken(function(err)
            {
                hideLoading();
                if (err)
                    stripe.displayCardError(err);
                else
                    stripe.placeOrder();
            });
        };

        document.getElementById('amasty-scheckout-messagebox').addEventListener('DOMNodeInserted', function(evt) {
            stripe.searchForAuthenticationRequiredError(stripe.triggerCustomerAuthentication);
        }, false);

        stripe.oscInitialized = true;
    }
    else if ((typeof Review != 'undefined' && typeof Review.prototype.proceed == 'undefined') && (
        // Magesolution Athlete Ultimate Magento Theme v1.1.2
        $('oscheckout-form') ||
        // PlumRocket OneStepCheckout 1.3.4
        ($('submit-chackout') && $('submit-chackout-top')) ||
        // Apptha 1StepCheckout v1.9
        (typeof closeLink1 != 'undefined')
    ))
    {
        Review.prototype.proceed = Review.prototype.save;

        stripe.placeOrder = function()
        {
            review.proceed();
        };

        Review.prototype.save = function()
        {
            if (!stripe.isPaymentMethodSelected())
                return stripe.placeOrder();

            createStripeToken(function(err)
            {
                if (err)
                    stripe.displayCardError(err);
                else
                    stripe.placeOrder();
            });
        };

        if (typeof review != 'undefined')
            review.save = Review.prototype.save;

        stripe.initAlertProxy(stripe.triggerCustomerAuthentication);
    }
    else if (typeof OSCheckout != 'undefined' && typeof OSCheckout.prototype.proceed == 'undefined')
    {
        // AdvancedCheckout OSC 2.5.0
        OSCheckout.prototype.proceed = OSCheckout.prototype.placeOrder;
        OSCheckout.prototype.placeOrder = function()
        {
            var self = this;

            stripe.placeOrder = function()
            {
                self.proceed();
            };

            // Payment is not defined
            if (!stripe.isPaymentMethodSelected())
                return stripe.placeOrder();

            createStripeToken(function(err)
            {
                if (err)
                    stripe.displayCardError(err);
                else
                    stripe.placeOrder();
            });
        };

        if (typeof oscheckout != 'undefined')
        {
            oscheckout.proceed = OSCheckout.prototype.proceed;
            oscheckout.placeOrder = OSCheckout.prototype.placeOrder;
        }
        stripe.initAlertProxy(stripe.triggerCustomerAuthentication);
        stripe.oscInitialized = true;
    }
    // Aitoc OnePageCheckout v1.4.17
    else if ($('aitcheckout-place-order') && typeof AitMagentoReview != "undefined" && typeof AitMagentoReview.prototype.proceed != "undefined")
    {
        AitMagentoReview.prototype.proceed = AitMagentoReview.prototype.save;

        stripe.placeOrder = function()
        {
            review.proceed();
        };

        AitMagentoReview.prototype.save = function()
        {
            if (!stripe.isPaymentMethodSelected())
                return stripe.placeOrder();

            var validator = new Validation(aitCheckout.getForm());
            if (validator && validator.validate())
            {
                createStripeToken(function(err)
                {
                    if (err)
                        stripe.displayCardError(err);
                    else
                        stripe.placeOrder();
                });
            }
            else
            {
                if (0 < Ajax.activeRequestCount)
                {
                    aitCheckout.valid = false;
                }
            }
        };

        stripe.initAlertProxy(stripe.triggerCustomerAuthentication);
        stripe.oscInitialized = true;
    }
    // Magebees One Page Checkout v1.1.1
    else if ($$('.magebeesOscFull').length > 0 && typeof Review != 'undefined' && typeof Review.prototype.proceed == 'undefined')
    {
        Review.prototype.proceed = Review.prototype.submit;

        stripe.placeOrder = function()
        {
            review.proceed();
        };

        Review.prototype.submit = function()
        {
            if (!stripe.isPaymentMethodSelected())
                return stripe.placeOrder();

            if (!checkout || !checkout.validateReview(true))
                return;

            createStripeToken(function(err)
            {
                if (err)
                    stripe.displayCardError(err);
                else
                    stripe.placeOrder();
            });
        };

        Event.stopObserving($('order_submit_button'));
        review.firsttimeinitialize();
    }
    // EcommerceTeam Tcheckout 1.0
    else if ($('tcheckout-form') && $('tcheckout-save-btn'))
    {
        $('tcheckout-form').proceed = $('tcheckout-form').submit;

        stripe.placeOrder = function()
        {
            $('tcheckout-form').proceed();
        };

        $('tcheckout-form').onsubmit = function(e)
        {
            if (!stripe.isPaymentMethodSelected())
                return true;

            e.preventDefault();

            createStripeToken(function(err)
            {
                if (err)
                {
                    $('tcheckout-please-wait').style.display = 'none';
                    $('tcheckout-save-btn').disabled = '';
                    $('tcheckout-save-btn').removeClassName('disabled');
                    stripe.displayCardError(err);
                }
                else
                    stripe.placeOrder();
            });
        };

        stripe.searchForAuthenticationRequiredError(stripe.triggerCustomerAuthentication);
        stripe.oscInitialized = true;
    }
    else if (typeof Review != 'undefined' && typeof Review.prototype.proceed == 'undefined')
    {
        // Default Magento Onepage checkout
        // Awesome Checkout 1.5.0
        // PlumRocket OSC 1.3.4
        // Other OSC modules

        /* The Awesome Checkout 1.5.0 configuration whitelist files are:
         *   stripe_payments/js/stripe_payments.js
         *   stripe_payments/js/cctype.js
         *   stripe_payments/css/styles.css
         *   prototype/window.js
         *   prototype/windows/themes/default.css
        */

        Review.prototype.proceed = Review.prototype.save;

        stripe.placeOrder = function()
        {
            // Awesome Checkout && PlumRocket
            checkout.loadWaiting = false;

            // Others
            review.proceed();
        };

        Review.prototype.save = function()
        {
            if (!stripe.isPaymentMethodSelected())
                return stripe.placeOrder();

            createStripeToken(function(err)
            {
                if (err)
                    stripe.displayCardError(err);
                else
                    stripe.placeOrder();
            });
        };

        if (typeof review != 'undefined')
            review.save = Review.prototype.save;

        stripe.initAlertProxy(stripe.triggerCustomerAuthentication);
    }
};



var cardTypes = {
    visa: new RegExp('^4'),
    mastercard: new RegExp('^5[1-5]'),
    amex: new RegExp('^3[47]'),
    discover: new RegExp('^6(?:011|5[0-9]{2})'),
    jcb: new RegExp('^(?:2131|1800|35[0-9]{3})'),
    diners: new RegExp('^3(?:0[0-5]|[68][0-9])')
};

function getCardType(cardNumber)
{
    for (var type in cardTypes)
        if (cardTypes.hasOwnProperty(type))
            if (cardTypes[type].test(cardNumber))
                return type;
}

var iconsContainer;

function resetIconsFade()
{
    iconsContainer.className = 'input-box';
    var children = iconsContainer.getElementsByTagName('img');
    for (var i = 0; i < children.length; i++)
        children[i].className = '';
}

var onCardNumberChangedFade = function(input)
{
    if (!iconsContainer) iconsContainer = document.getElementById('stripe-payments-accepted-cards');
    if (!iconsContainer) return;

    resetIconsFade();

    var cardNumber = input.value;
    if (!cardNumber || cardNumber.length === 0) return;

    var cardType = getCardType(cardNumber);
    if (!cardType) return;

    var img = document.getElementById('stripe_payments_' + cardType + '_type');
    if (!img) return;

    img.className = 'active';
    iconsContainer.className = 'input-box stripe-payments-detected';
};

function resetIconsSlide(input)
{
    input.className = input.className.replace(/ ?cctype-detected cctype-[a-z]+/, '');
}

var onCardNumberChangedSlide = function(input)
{
    var cardNumber = input.value;
    if (!cardNumber || cardNumber.length === 0) return resetIconsSlide(input);

    var cardType = getCardType(cardNumber);
    if (!cardType) return resetIconsSlide(input);

    var ccTypeClass = 'cctype-detected cctype-' + cardType;
    if (input.className.indexOf(ccTypeClass) > 0) return;

    resetIconsSlide(input);
    input.className = input.className + ' ' + ccTypeClass;
};

!function(t,n,i){var e=n.matchMedia;"undefined"!=typeof module&&module.exports?module.exports=i(e):"function"==typeof define&&define.amd?define(function(){return n[t]=i(e)}):n[t]=i(e)}("enquire",this,function(e){"use strict";function o(t,n){for(var i=0,e=t.length;i<e&&!1!==n(t[i],i);i++);}function i(t){(this.options=t).deferSetup||this.setup()}function r(t,n){this.query=t,this.isUnconditional=n,this.handlers=[],this.mql=e(t);var i=this;this.listener=function(t){i.mql=t,i.assess()},this.mql.addListener(this.listener)}function t(){if(!e)throw new Error("matchMedia not present, legacy browsers require a polyfill");this.queries={},this.browserIsIncapable=!e("only all").matches}return i.prototype={setup:function(){this.options.setup&&this.options.setup(),this.initialised=!0},on:function(){this.initialised||this.setup(),this.options.match&&this.options.match()},off:function(){this.options.unmatch&&this.options.unmatch()},destroy:function(){this.options.destroy?this.options.destroy():this.off()},equals:function(t){return this.options===t||this.options.match===t}},r.prototype={addHandler:function(t){var n=new i(t);this.handlers.push(n),this.matches()&&n.on()},removeHandler:function(i){var e=this.handlers;o(e,function(t,n){if(t.equals(i))return t.destroy(),!e.splice(n,1)})},matches:function(){return this.mql.matches||this.isUnconditional},clear:function(){o(this.handlers,function(t){t.destroy()}),this.mql.removeListener(this.listener),this.handlers.length=0},assess:function(){var n=this.matches()?"on":"off";o(this.handlers,function(t){t[n]()})}},t.prototype={register:function(n,t,i){var e=this.queries,s=i&&this.browserIsIncapable;return e[n]||(e[n]=new r(n,s)),function(t){return"function"==typeof t}(t)&&(t={match:t}),function(t){return"[object Array]"===Object.prototype.toString.apply(t)}(t)||(t=[t]),o(t,function(t){e[n].addHandler(t)}),this},unregister:function(t,n){var i=this.queries[t];return i&&(n?i.removeHandler(n):(i.clear(),delete this.queries[t])),this}},new t});
!function(e){var t=function(c,D){"use strict";if(D.getElementsByClassName){var k,H,O=D.documentElement,d=c.Date,a=c.HTMLPictureElement,P="addEventListener",$="getAttribute",I=c[P],q=c.setTimeout,o=c.requestAnimationFrame||q,l=c.requestIdleCallback,U=/^picture$/i,i=["load","error","lazyincluded","_lazyloaded"],n={},j=Array.prototype.forEach,G=function(e,t){return n[t]||(n[t]=new RegExp("(\\s|^)"+t+"(\\s|$)")),n[t].test(e[$]("class")||"")&&n[t]},J=function(e,t){G(e,t)||e.setAttribute("class",(e[$]("class")||"").trim()+" "+t)},K=function(e,t){var n;(n=G(e,t))&&e.setAttribute("class",(e[$]("class")||"").replace(n," "))},Q=function(t,n,e){var a=e?P:"removeEventListener";e&&Q(t,n),i.forEach(function(e){t[a](e,n)})},V=function(e,t,n,a,i){var r=D.createEvent("Event");return n||(n={}),n.instance=k,r.initEvent(t,!a,!i),r.detail=n,e.dispatchEvent(r),r},X=function(e,t){var n;!a&&(n=c.picturefill||H.pf)?(t&&t.src&&!e[$]("srcset")&&e.setAttribute("srcset",t.src),n({reevaluate:!0,elements:[e]})):t&&t.src&&(e.src=t.src)},Y=function(e,t){return(getComputedStyle(e,null)||{})[t]},s=function(e,t,n){for(n=n||e.offsetWidth;n<H.minSize&&t&&!e._lazysizesWidth;)n=t.offsetWidth,t=t.parentNode;return n},Z=function(){var n,a,t=[],i=[],r=t,s=function(){var e=r;for(r=t.length?i:t,n=!0,a=!1;e.length;)e.shift()();n=!1},e=function(e,t){n&&!t?e.apply(this,arguments):(r.push(e),a||(a=!0,(D.hidden?q:o)(s)))};return e._lsFlush=s,e}(),ee=function(n,e){return e?function(){Z(n)}:function(){var e=this,t=arguments;Z(function(){n.apply(e,t)})}},te=function(e){var n,a=0,i=H.throttleDelay,r=H.ricTimeout,t=function(){n=!1,a=d.now(),e()},s=l&&r>49?function(){l(t,{timeout:r}),r!==H.ricTimeout&&(r=H.ricTimeout)}:ee(function(){q(t)},!0);return function(e){var t;(e=!0===e)&&(r=33),n||(n=!0,t=i-(d.now()-a),t<0&&(t=0),e||t<9?s():q(s,t))}},ne=function(e){var t,n,a=99,i=function(){t=null,e()},r=function(){var e=d.now()-n;e<a?q(r,a-e):(l||i)(i)};return function(){n=d.now(),t||(t=q(r,a))}};!function(){var e,t={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",autosizesClass:"lazyautosizes",srcAttr:"data-src",srcsetAttr:"data-srcset",sizesAttr:"data-sizes",minSize:40,customMedia:{},init:!0,expFactor:1.5,hFac:.8,loadMode:2,loadHidden:!0,ricTimeout:0,throttleDelay:125};H=c.lazySizesConfig||c.lazysizesConfig||{};for(e in t)e in H||(H[e]=t[e]);q(function(){H.init&&r()})}();var e=function(){var m,z,u,y,e,v,h,g,p,C,b,A,r=/^img$/i,f=/^iframe$/i,E="onscroll"in c&&!/(gle|ing)bot/.test(navigator.userAgent),_=0,M=0,N=0,w=-1,x=function(e){N--,(!e||N<0||!e.target)&&(N=0)},W=function(e){return null==A&&(A="hidden"==Y(D.body,"visibility")),A||"hidden"!=Y(e.parentNode,"visibility")&&"hidden"!=Y(e,"visibility")},L=function(e,t){var n,a=e,i=W(e);for(g-=t,b+=t,p-=t,C+=t;i&&(a=a.offsetParent)&&a!=D.body&&a!=O;)(i=(Y(a,"opacity")||1)>0)&&"visible"!=Y(a,"overflow")&&(n=a.getBoundingClientRect(),i=C>n.left&&p<n.right&&b>n.top-1&&g<n.bottom+1);return i},t=function(){var e,t,n,a,i,r,s,o,l,c,d,u,f=k.elements;if((y=H.loadMode)&&N<8&&(e=f.length)){for(t=0,w++;t<e;t++)if(f[t]&&!f[t]._lazyRace)if(!E||k.prematureUnveil&&k.prematureUnveil(f[t]))S(f[t]);else if((o=f[t][$]("data-expand"))&&(r=1*o)||(r=M),c||(c=!H.expand||H.expand<1?O.clientHeight>500&&O.clientWidth>500?500:370:H.expand,k._defEx=c,d=c*H.expFactor,u=H.hFac,A=null,M<d&&N<1&&w>2&&y>2&&!D.hidden?(M=d,w=0):M=y>1&&w>1&&N<6?c:_),l!==r&&(v=innerWidth+r*u,h=innerHeight+r,s=-1*r,l=r),n=f[t].getBoundingClientRect(),(b=n.bottom)>=s&&(g=n.top)<=h&&(C=n.right)>=s*u&&(p=n.left)<=v&&(b||C||p||g)&&(H.loadHidden||W(f[t]))&&(z&&N<3&&!o&&(y<3||w<4)||L(f[t],r))){if(S(f[t]),i=!0,N>9)break}else!i&&z&&!a&&N<4&&w<4&&y>2&&(m[0]||H.preloadAfterLoad)&&(m[0]||!o&&(b||C||p||g||"auto"!=f[t][$](H.sizesAttr)))&&(a=m[0]||f[t]);a&&!i&&S(a)}},n=te(t),T=function(e){var t=e.target;if(t._lazyCache)return void delete t._lazyCache;x(e),J(t,H.loadedClass),K(t,H.loadingClass),Q(t,B),V(t,"lazyloaded")},a=ee(T),B=function(e){a({target:e.target})},F=function(t,n){try{t.contentWindow.location.replace(n)}catch(e){t.src=n}},R=function(e){var t,n=e[$](H.srcsetAttr);(t=H.customMedia[e[$]("data-media")||e[$]("media")])&&e.setAttribute("media",t),n&&e.setAttribute("srcset",n)},s=ee(function(t,e,n,a,i){var r,s,o,l,c,d;(c=V(t,"lazybeforeunveil",e)).defaultPrevented||(a&&(n?J(t,H.autosizesClass):t.setAttribute("sizes",a)),s=t[$](H.srcsetAttr),r=t[$](H.srcAttr),i&&(o=t.parentNode,l=o&&U.test(o.nodeName||"")),d=e.firesLoad||"src"in t&&(s||r||l),c={target:t},J(t,H.loadingClass),d&&(clearTimeout(u),u=q(x,2500),Q(t,B,!0)),l&&j.call(o.getElementsByTagName("source"),R),s?t.setAttribute("srcset",s):r&&!l&&(f.test(t.nodeName)?F(t,r):t.src=r),i&&(s||l)&&X(t,{src:r})),t._lazyRace&&delete t._lazyRace,K(t,H.lazyClass),Z(function(){var e=t.complete&&t.naturalWidth>1;d&&!e||(e&&J(t,"ls-is-cached"),T(c),t._lazyCache=!0,q(function(){"_lazyCache"in t&&delete t._lazyCache},9)),"lazy"==t.loading&&N--},!0)}),S=function(e){if(!e._lazyRace){var t,n=r.test(e.nodeName),a=n&&(e[$](H.sizesAttr)||e[$]("sizes")),i="auto"==a;(!i&&z||!n||!e[$]("src")&&!e.srcset||e.complete||G(e,H.errorClass)||!G(e,H.lazyClass))&&(t=V(e,"lazyunveilread").detail,i&&ae.updateElem(e,!0,e.offsetWidth),e._lazyRace=!0,N++,s(e,t,i,a,n))}},i=ne(function(){H.loadMode=3,n()}),o=function(){3==H.loadMode&&(H.loadMode=2),i()},l=function(){if(!z){if(d.now()-e<999)return void q(l,999);z=!0,H.loadMode=3,n(),I("scroll",o,!0)}};return{_:function(){e=d.now(),k.elements=D.getElementsByClassName(H.lazyClass),m=D.getElementsByClassName(H.lazyClass+" "+H.preloadClass),I("scroll",n,!0),I("resize",n,!0),c.MutationObserver?new MutationObserver(n).observe(O,{childList:!0,subtree:!0,attributes:!0}):(O[P]("DOMNodeInserted",n,!0),O[P]("DOMAttrModified",n,!0),setInterval(n,999)),I("hashchange",n,!0),["focus","mouseover","click","load","transitionend","animationend"].forEach(function(e){D[P](e,n,!0)}),/d$|^c/.test(D.readyState)?l():(I("load",l),D[P]("DOMContentLoaded",n),q(l,2e4)),k.elements.length?(t(),Z._lsFlush()):n()},checkElems:n,unveil:S,_aLSL:o}}(),ae=function(){var n,r=ee(function(e,t,n,a){var i,r,s;if(e._lazysizesWidth=a,a+="px",e.setAttribute("sizes",a),U.test(t.nodeName||""))for(i=t.getElementsByTagName("source"),r=0,s=i.length;r<s;r++)i[r].setAttribute("sizes",a);n.detail.dataAttr||X(e,n.detail)}),a=function(e,t,n){var a,i=e.parentNode;i&&(n=s(e,i,n),a=V(e,"lazybeforesizes",{width:n,dataAttr:!!t}),a.defaultPrevented||(n=a.detail.width)&&n!==e._lazysizesWidth&&r(e,i,a,n))},e=function(){var e,t=n.length;if(t)for(e=0;e<t;e++)a(n[e])},t=ne(e);return{_:function(){n=D.getElementsByClassName(H.autosizesClass),I("resize",t)},checkElems:t,updateElem:a}}(),r=function(){r.i||(r.i=!0,ae._(),e._())};return k={cfg:H,autoSizer:ae,loader:e,init:r,uP:X,aC:J,rC:K,hC:G,fire:V,gW:s,rAF:Z}}}(e,e.document);e.lazySizes=t,"object"==typeof module&&module.exports&&(module.exports=t)}(window);
"use strict";var ENotificationType;!function(t){t[t.Success=0]="Success",t[t.Info=1]="Info",t[t.Warning=2]="Warning",t[t.Error=3]="Error"}(ENotificationType=ENotificationType||{});var NotificationCenter=function(){function n(){}return n.notify=function(t){var e,i=t.fadeOutMilisecs?t.fadeOutMilisecs:5e3;switch(t.type){case ENotificationType.Success:n._successNode||(n._successNode=jQuery(n._notificationTemplate).insertAfter("body").addClass("success-msg")),e=n._successNode;break;case ENotificationType.Error:n._errorNode||(n._errorNode=jQuery(n._notificationTemplate).insertAfter("body").addClass("error-msg")),e=n._errorNode}e.find(".notification-center-msg__txt").text(t.message),e.show(),e.find(".notification-center-msg__btn-close").on("click",function(){e.stop().fadeOut()}),i&&e.delay(i).fadeOut()},n._notificationTemplate='<div class="notification-center-msg">\n                                                <span class="notification-center-msg__txt"></span> \n                                                <button class="notification-center-msg__btn-close" type="button">\n                                                    <i class="icon-close"></i>\n                                                </button>\n                                            </div>',n}();
"use strict";var MiniCart=function(){function e(){var a=this;jQuery(document).ready(function(){var e=EventManager.getInstance();e.subscribe(EmmaEventName.DISCOUNT_COUPON_APPLIED,a),e.subscribe(EmmaEventName.DISCOUNT_BEFORE_COUPON_APPLIED,a),e.subscribe(EmmaEventName.MINICART_HTML_UPDATED,a),e.subscribe(EmmaEventName.UPSELLS__PRODUCT_ADDED,a)})}return e.prototype.onEvent=function(e){switch(e.name){case EmmaEventName.DISCOUNT_BEFORE_COUPON_APPLIED:if(!jQuery("#cart.is-open").length)return;this._preloader=new Preloader({container:"#cart.is-open"}),this._preloader.show();break;case EmmaEventName.DISCOUNT_COUPON_APPLIED:case EmmaEventName.UPSELLS__PRODUCT_ADDED:e.payload.minicart_content?this.reloadHtml(e.payload.minicart_content):this.reload();break;case EmmaEventName.MINICART_HTML_UPDATED:if(!e.payload)return;window.aplazameInstallmentsCart&&aplazameInstallmentsCart.formatPrice(e.payload);var a=Math.trunc(100*e.payload);jQuery("#aplazame-rate-calculator").attr("data-amount",a);var t=new Foundation.Reveal(jQuery("#aplazame-rate-calc-modal"));jQuery(".aplazame-rate-calc__cta").click(function(){t.open()})}},e.prototype.reload=function(){var t=this;this._preloader=new Preloader({container:"#cart.is-open"}),this._preloader.show(),jQuery.get(getUrl("")+"emma/checkout_cart/reloadMinicart/",function(e){var a=JSON.parse(e);registry("mini_cart",a.minicart_content,!1),jQuery("#cart").length&&jQuery("#cart").html(a.minicart_content),t._preloader&&t._preloader.hide()})},e.prototype.reloadHtml=function(e){e&&(this._preloader=new Preloader({container:"#cart.is-open"}),this._preloader.show(),registry("mini_cart",e,!1),jQuery("#cart").length&&jQuery("#cart").html(e),this._preloader&&this._preloader.hide())},e}();new MiniCart;
"use strict";var EmmaEventName=function(){function _(){}return _.DISCOUNT_COUPON_APPLIED="DISCOUNT_COUPON_APPLIED",_.DISCOUNT_BEFORE_COUPON_APPLIED="DISCOUNT_BEFORE_COUPON_APPLIED",_.FORTUNE_WHEEL_OPENED="FORTUNE_WHEEL_OPENED",_.FORTUNE_WHEEL_CLOSED="FORTUNE_WHEEL_CLOSED",_.CONFIGURABLE_PRODUCT__EXT_SHOP_CHANGED="CONFIGURABLE_PRODUCT__EXT_SHOP_CHANGED",_.MINICART_HTML_UPDATED="MINICART_HTML_UPDATED",_.PRODUCT_PRICING_CHANGED="PRODUCT_PRICING_CHANGED",_.PRODUCT_PAGE___HARDNESS_CHANGED="PRODUCT_PAGE___HARDNESS_SC_CHANGED",_.PRODUCT_PAGE___DYNAMIC_BEDBOX_BASE_CHANGED="PRODUCT_PAGE___DYNAMIC_BEDBOX_BASE_CHANGED",_.PRODUCT_PAGE___ATTRIBUTE_GROUP_READY="PRODUCT_PAGE___ATTRIBUTE_GROUP_READY",_.BOXBED_V3_COMPONENT_LOADED="BOXBED_V3_COMPONENT_LOADED",_.BOXBED_V3_DEPENDENT_SELECTIONS_READY="BOXBED_V3_DEPENDENT_SELECTIONS_READY",_.BOXBED_V3_OPTIONS_UPDATE="BOXBED_V3_OPTIONS_UPDATE",_.UPSELLS__PRODUCT_ADDED="UPSELLS__PRODUCT_ADDED",_}(),EventManager=function(){function _(){this._subscribers={}}return _.getInstance=function(){return _._eventManagerInstance||(_._eventManagerInstance=new _),_._eventManagerInstance},_.prototype.subscribe=function(_,E){this._subscribers[_]||(this._subscribers[_]=[]),this._subscribers[_].push(E)},_.prototype.unsubscribe=function(_,E){},_.prototype.notify=function(_){if(this._subscribers[_.name]){for(var E=[],D=0,O=this._subscribers[_.name];D<O.length;D++){var P=O[D];E.push(P.onEvent(_))}return E}},_}();
var TWO_THREE_ISO_COUNTRY_CODE={BD:"BGD",BE:"BEL",BF:"BFA",BG:"BGR",BA:"BIH",BB:"BRB",WF:"WLF",BL:"BLM",BM:"BMU",BN:"BRN",BO:"BOL",BH:"BHR",BI:"BDI",BJ:"BEN",BT:"BTN",JM:"JAM",BV:"BVT",BW:"BWA",WS:"WSM",BQ:"BES",BR:"BRA",BS:"BHS",JE:"JEY",BY:"BLR",BZ:"BLZ",RU:"RUS",RW:"RWA",RS:"SRB",TL:"TLS",RE:"REU",TM:"TKM",TJ:"TJK",RO:"ROU",TK:"TKL",GW:"GNB",GU:"GUM",GT:"GTM",GS:"SGS",GR:"GRC",GQ:"GNQ",GP:"GLP",JP:"JPN",GY:"GUY",GG:"GGY",GF:"GUF",GE:"GEO",GD:"GRD",GB:"GBR",GA:"GAB",SV:"SLV",GN:"GIN",GM:"GMB",GL:"GRL",GI:"GIB",GH:"GHA",OM:"OMN",TN:"TUN",JO:"JOR",HR:"HRV",HT:"HTI",HU:"HUN",HK:"HKG",HN:"HND",HM:"HMD",VE:"VEN",PR:"PRI",PS:"PSE",PW:"PLW",PT:"PRT",SJ:"SJM",PY:"PRY",IQ:"IRQ",PA:"PAN",PF:"PYF",PG:"PNG",PE:"PER",PK:"PAK",PH:"PHL",PN:"PCN",PL:"POL",PM:"SPM",ZM:"ZMB",EH:"ESH",EE:"EST",EG:"EGY",ZA:"ZAF",EC:"ECU",IT:"ITA",VN:"VNM",SB:"SLB",ET:"ETH",SO:"SOM",ZW:"ZWE",SA:"SAU",ES:"ESP",ER:"ERI",ME:"MNE",MD:"MDA",MG:"MDG",MF:"MAF",MA:"MAR",MC:"MCO",UZ:"UZB",MM:"MMR",ML:"MLI",MO:"MAC",MN:"MNG",MH:"MHL",MK:"MKD",MU:"MUS",MT:"MLT",MW:"MWI",MV:"MDV",MQ:"MTQ",MP:"MNP",MS:"MSR",MR:"MRT",IM:"IMN",UG:"UGA",TZ:"TZA",MY:"MYS",MX:"MEX",IL:"ISR",FR:"FRA",IO:"IOT",SH:"SHN",FI:"FIN",FJ:"FJI",FK:"FLK",FM:"FSM",FO:"FRO",NI:"NIC",NL:"NLD",NO:"NOR",NA:"NAM",VU:"VUT",NC:"NCL",NE:"NER",NF:"NFK",NG:"NGA",NZ:"NZL",NP:"NPL",NR:"NRU",NU:"NIU",CK:"COK",XK:"XKX",CI:"CIV",CH:"CHE",CO:"COL",CN:"CHN",CM:"CMR",CL:"CHL",CC:"CCK",CA:"CAN",CG:"COG",CF:"CAF",CD:"COD",CZ:"CZE",CY:"CYP",CX:"CXR",CR:"CRI",CW:"CUW",CV:"CPV",CU:"CUB",SZ:"SWZ",SY:"SYR",SX:"SXM",KG:"KGZ",KE:"KEN",SS:"SSD",SR:"SUR",KI:"KIR",KH:"KHM",KN:"KNA",KM:"COM",ST:"STP",SK:"SVK",KR:"KOR",SI:"SVN",KP:"PRK",KW:"KWT",SN:"SEN",SM:"SMR",SL:"SLE",SC:"SYC",KZ:"KAZ",KY:"CYM",SG:"SGP",SE:"SWE",SD:"SDN",DO:"DOM",DM:"DMA",DJ:"DJI",DK:"DNK",VG:"VGB",DE:"DEU",YE:"YEM",DZ:"DZA",US:"USA",UY:"URY",YT:"MYT",UM:"UMI",LB:"LBN",LC:"LCA",LA:"LAO",TV:"TUV",TW:"TWN",TT:"TTO",TR:"TUR",LK:"LKA",LI:"LIE",LV:"LVA",TO:"TON",LT:"LTU",LU:"LUX",LR:"LBR",LS:"LSO",TH:"THA",TF:"ATF",TG:"TGO",TD:"TCD",TC:"TCA",LY:"LBY",VA:"VAT",VC:"VCT",AE:"ARE",AD:"AND",AG:"ATG",AF:"AFG",AI:"AIA",VI:"VIR",IS:"ISL",IR:"IRN",AM:"ARM",AL:"ALB",AO:"AGO",AQ:"ATA",AS:"ASM",AR:"ARG",AU:"AUS",AT:"AUT",AW:"ABW",IN:"IND",AX:"ALA",AZ:"AZE",IE:"IRL",ID:"IDN",UA:"UKR",QA:"QAT",MZ:"MOZ"};
var TELEPHONE_MASK={fr:[{mask:"00 00 00 00 0"}],br:[],in:[]};
"use strict";var HereMapApiKeys=function(){function e(){}return e.getApiKey=function(){return-1!==e._devNTestingDomains.indexOf(window.location.hostname)?e._devNTestingApiKey:e._liveApiKey},e._liveApiKey="89jQfbTaPss4HbLpghARPZY9eM67GZF3TqZ1xUtsIrw",e._devNTestingApiKey="YIUukEYLNTgMZSvAbl4vXGEipwSORJy8PGaDFIo4zWU",e._devNTestingDomains=["deployment.emma.fr","deployment.emma-matratze.de","deployment.emma-colchon.es","deployment.emma-materasso.it"],e}();
"use strict";var DiscountBanner=function(){function t(){this.applyDiscountCodeAutomatically(),this.fetchDiscountBannerHtml()}return t.applyDiscountCode=function(e,t){void 0===t&&(t=!1);var n=EventManager.getInstance().notify({name:EmmaEventName.DISCOUNT_BEFORE_COUPON_APPLIED,payload:e});if(n)for(var o=0,a=n;o<a.length;o++){var r=a[o];if(r&&r.cancelFurtherAction)return}jQuery.post(getUrl("")+"emma/checkout_cart/ajaxCouponPost",{coupon_code:e}).done(function(e){var n=e;(EventManager.getInstance().notify({name:EmmaEventName.DISCOUNT_COUPON_APPLIED,payload:{minicart_content:n.content}}),n.message)?jQuery("#black-friday-modal").length&&t?(new Foundation.Reveal(jQuery("#black-friday-modal")).open(),registry("couponApplied","true")):NotificationCenter.notify({message:n.message,type:ENotificationType.Success}):NotificationCenter.notify({message:n.error,type:ENotificationType.Error})})},t.prototype.applyDiscountCodeAutomatically=function(){var e=/utm_code=([^&#=]*)/.exec(window.location.search),n=e&&e[1];n&&t.applyDiscountCode(n.toString())},t.prototype.fetchDiscountBannerHtml=function(){window.addEventListener("load",function(){var n="cb_storage";if("undefined"!=jsUrls.storeCode&&(n="cb_storage_"+jsUrls.storeCode),0!==parseInt(getCookie("display_coupon_banner"))&&!t.loadDiscountBanner(n)){var e=getUrl("bettzeit_couponBanner/couponBanner/content/");null!==/#t5/.exec(window.location.hash)&&(e+="?t5=true"),jQuery.get({url:e,success:function(e){(e=JSON.parse(e)).html&&(registry(n,e,!1),t.loadDiscountBanner(n))}})}})},t.loadDiscountBanner=function(e){var n=Date.now(),t=registry(e);return!!t&&(t.expire<n?(registry(e,null,!1),!1):("new"==t.type&&parseInt(getCookie("pnc_timestamp"))<n||(t.html&&(jQuery("#discount-banner-wrapper").append(t.html),jQuery(".checkout-header").after(t.html),jQuery("#coupon_banner_tooltip").length&&new Foundation.Tooltip(jQuery("#coupon_banner_tooltip"))),widgetBadgesAnimation(".sticky-container .header","slider-header"),jQuery(document).ready(function(){setTimeout(function(){var e=jQuery(".discount-banner");0!=e.length&&e.addClass("shown")},2e3)})),!0))},t}();new DiscountBanner;
function findGetParameter(parameterName) {
    var result = null,
        tmp = [];
    var items = location.search.substr(1).split("&");
    for (var index = 0; index < items.length; index++) {
        tmp = items[index].split("=");
        if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
    }
    return result;
}
function partnerSetCookie(value) {
    var date = new Date();
    date.setTime(date.getTime() + (40*24*60*60*1000));
    var expires = "; expires=" + date.toUTCString();
    document.cookie = "partner=" + (value || "")  + expires + "; path=/";
}
function partnerGetCookie() {
    var nameEQ = "partner=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}
(function(){
    var partnerCookie = partnerGetCookie(),
        pacid = findGetParameter('pacid'),
        partnerId = findGetParameter('pa-partnerid');
    if ((typeof partnerCookie === 'undefined' || partnerCookie === null) &&
        (typeof pacid === 'string' || typeof pacid === 'number') &&
        (typeof partnerId === 'string' || typeof partnerId === 'number')
    ) {
        partnerSetCookie(btoa(partnerId + '&' + pacid));
    }
})();