Your IP : 216.73.216.189


Current Path : /var/www/magento.test.indacotrentino.com/www/pub/media/buybutton/
Upload File :
Current File : /var/www/magento.test.indacotrentino.com/www/pub/media/buybutton/init.js

(function(d, $) {

    // Define our constructor
    window.wkBuyButtonRegistry = {};
    window.wkaddTocartLabel = {
        text: 'Aggiungi al carrello'
    }
    let cart = {
         cartItems: [],
         isVisible: 'bb-hide'
     };
    this.BuyButton = function() {

        this.options = null;
        // Define option defaults
        var defaults = {
            template: '<div class=buybutton-container id=buybutton-container-id> <div class=buybutton-head> <div class=buybutton-cart @click=showCart> <i class=rango-cart><i class=bb-cart-count>{{itemsCount}}</i></i><i class=icon-cart><i>{{childData.miniCartText}}</i></i> <mini-cart></mini-cart> </div><div class=clear-float></div></div><div class=buybutton-body> <div class=buybutton-items> <div class=buybutton-item v-for="(value, key) in products"> <div class=buybutton-item-container v-if="designTemplate==1"> <div class=buybutton-item-image><img :src=value.images[0].url @click=view(value)></div><div class=buybutton-item-name @click=redirect(value)><span>{{value.name}}</span></div><div class=buybutton-item-price v-if="value.price_info.final_price > 0"><b v-html=value.price_info.formatted_prices.final_price></b></div><div class=buybutton-item-view><button @click=view(value) class="buybutton-primary buybutton-view-product" type=button><span>{{childData.vButtonText}}</span></button></div></div><div class=buybutton-item-container v-if="designTemplate==2"> <div class="bb-option-wrapper"><options-wrapper :options=value.extension_attributes.custom_options></options-wrapper></div><div class=bb-configurable-option-wrapper><configurable-options :coptions=value.extension_attributes.super_attributes?JSON.parse(value.extension_attributes.super_attributes):{}></configurable-options></div><div class="buybutton-item-view buybutton-add" v-if="value.price_info.final_price > 0">' +
                '<div class="quantity-control"><button @click="decreaseQuantity(value)" class="quantity-button">-</button><input :id="\'quantity-\' + value.extension_attributes.sku" class="quantity-input" type="number" min="1" value="1"><button @click="increaseQuantity(value)" class="quantity-button">+</button></div>' +
                '<button @click=addToCart(value) class="buybutton-primary buybutton-view-product"type=button><span>{{childData.addToCartText}}</span></button></div></div><div class=buybutton-item-container v-if="designTemplate==3"><div class=buybutton-item-image-container><div class=buybutton-item-image><img :src=item.image></div><div class="buybutton-item-view buybutton-add" v-if="value.price_info.final_price > 0">' +
                '<div class="quantity-control"><button @click="decreaseQuantity(value)" class="quantity-button">-</button><input :id="\'quantity-\' + value.extension_attributes.sku" class="quantity-input" type="number" min="1" value="1"><button @click="increaseQuantity(value)" class="quantity-button">+</button></div>' +
                '<button @click=addToCart(value) class="buybutton-primary buybutton-view-product"type=button><span>{{childData.addToCartText}}</span></button></div></div><div class=buybutton-attr-container><div class=buybutton-product-name @click=redirect(value)><span>{{value.name}}</span></div><div class=buybutton-product-price v-if="value.price_info.final_price > 0"><span v-html=formattedPrice></span></div><div class=buybutton-product-description><span v-html=value.extension_attributes.description></span></div><div class="bb-option-wrapper"><options-wrapper :options=value.extension_attributes.custom_options></options-wrapper></div><div class=bb-configurable-option-wrapper><configurable-options :coptions=value.extension_attributes.super_attributes?JSON.parse(value.extension_attributes.super_attributes):{}></configurable-options></div></div></div></div><div class=buybutton-message v-if="products.length === 0"><b>Al momento non ci sono prodotti online</b></div></div></div></div></div>',
            isCheckoutEnable: false,
            baseUrl: '',
//            pathStore: (self.parent.location.pathname).replace("BBGet", 'BB'),
            pathStore: 'buy/'+self.parent.pathStore+'/indaco-BB.php',
            checkoutUrl: '',
            staticUrl:'',
            redirectToProduct: false,
            checkoutTemplate: '',
            cartTemplate:'<div class=bb-mini-cart-container :class=childData.cart.isVisible><div class=bb-cart-wrapper v-if=childData.cart.cartItems.length><div class=bb-mini-cart-head><div class=bb-cart-details><div class=bb-cart-items-summary><span class=bb-strong>{{itemsCount}} </span><span>{{childData.itemInCartText}}</span></div><div class=bb-cart-subtotal><span>{{childData.subTotalText}}: </span><span class=bb-strong>{{subTotal}}</span></div></div><div class=bb-cart-checkout><button @click=checkout() class=button>{{childData.cButtonText}}</button></div><div id="buybutton-modal-close-action" class="buybutton-modal-close"><i class="rango-cross"></i></div></div><div class=bb-mini-cart-body><div class=bb-cart-items><div class=bb-cart-item v-for="(value, key) in childData.cart.cartItems"><div class=bb-cart-item-image><img :src=value.image ></div><div class=bb-cart-item-details><div class=bb-cart-item-name>{{value.name}}<custom-options :options=value></custom-options></div><div class="bb-strong bb-cart-item-price"v-html=value.formattedPrice></div><div class=bb-cart-item-qty><span>{{childData.qtyText}}: </span><input class=bb-item-qty-text v-model=value.qty v-on:focus="takeBackup(value)" @change="updateItem(value)"></div><div class=bb-cart-item-actions><i @click=removeItem(value.id) class="bb-delete-item rango-delete"></i></div></div></div></div></div></div><p class=no-data-found v-else>{{childData.noItemFoundText}}</p></div>',
            quickViewTemplate: '<div class=buybutton-modal-container id=buybutton-modal-container-action><div class=buybutton-modal><div class=buybutton-modal-left><div class=buybutton-modal-image><img :src=item.image class=buybutton-modal-img></div></div><div class=buybutton-modal-right><div class=buybutton-product-details><div class=buybutton-product-name><span>{{item.name}}</span></div><div class=buybutton-item-price v-if="item.price == 0"><b>Al momento questo prodotto non è vendibile online</b></div><div class=buybutton-product-price v-if="item.price > 0"><span>{{formattedPrice}}</span></div><div class="buybutton-product-addtocart buybutton-add" v-if="item.price > 0">' +
                '<div class="quantity-control"><button @click="decreaseQuantity(item)" class="quantity-button">-</button><input :id="\'quantity-\' + item.sku" class="quantity-input" type="number" min="1" value="1"><button @click="increaseQuantity(item)" class="quantity-button">+</button></div>' +
                '<button @click=addToCart(item) class=buybutton-primary type=button><span>{{addToCartLabel}}</span></button></div><div class=buybutton-product-description><span v-html=item.description></span></div><div class="bb-option-wrapper"><options-wrapper :options=item.custom_option></options-wrapper></div><div class=bb-configurable-option-wrapper><configurable-options :coptions=item.super_attributes></configurable-options></div></div></div><div class=buybutton-modal-close id=buybutton-modal-close-action><i class=rango-cross></i></div></div></div>',
            products: {},
            styles:'',
            productIds: [],
            element: 'buybutton-init',
            viewButton: 'buybutton-view-product',
            styleUrl: '/style.css',
            handlebarUrl: '/handlebars.min.js',
            vueUrl: '/vue.min.js',
            jqueryUrl: '/jquery.min.js',
            miniCartText: 'Cart',
            addToCartText: 'Aggiungi al carrello',
            buyNowText: 'Buy Now',
            vButtonText: 'View Details',
            itemInCartText: 'Item In Cart',
            cButtonText: 'Proceed To Checkout',
            noItemFoundText: 'No items found in cart.',
            qtyText: 'Qty',
            subTotalText: 'Cart Subtotal',
            currency_code: 'USD',
            locale: 'en-us',
            designTemplate: 1,
            storeId: self.parent.storeId
        };

        // Create options by extending defaults with the passed in arugments
        if (arguments[0] && typeof arguments[0] === "object") {
            this.options = extendDefaults(defaults, arguments[0]);
        } else {
            this.options = defaults;
        }
        //include necessary js and css files
        this.initialize();

    }

     /**
      * initializing the plugin
      */
     BuyButton.prototype.initialize = function() {
         var self = this;
         /**
          * get promises array for loading js
          */
         let promises = self.extraIncludes();
         wkBuyButtonRegistry.currenctObject = self;
         promises[0].then(function(resolve) {
             return promises[1];
         }).then(function(resolve1) {
             return promises[2];
         }).then(function() {
             /**
              * start loading components
              */
             self.load();
         });
     }

     /**
      * include js and css in the head
      */
     BuyButton.prototype.extraIncludes = function() {
         var self = this;
         //include css
         var style = d.getElementsByTagName('head')[0];
         var link = d.createElement('link');
         link.href =  self.options.staticUrl+self.options.styleUrl;
         link.rel = 'stylesheet';
         link.type = 'text/css';
         style.appendChild(link);
         var jsScripts = d.getElementsByTagName('head')[0];
         var promises = [];

         /**
          * function to load srcipts
          *
          * @param string type
          */
         let loadJs = function(type) {
             let promise = new Promise(function(resolve, reject) {
                 var script = d.createElement('script');
                 script.async = true;
                 script.onload = function () {
                     resolve(1);
                 };
                 switch(type) {
                     case 'jquery':
                     script.src = self.options.staticUrl+self.options.jqueryUrl;
                     break;
                     case 'vue':
                     script.src = self.options.staticUrl+self.options.handlebarUrl;
                     break;
                     case 'handlebar':
                     script.src = self.options.staticUrl+self.options.vueUrl;
                     break;
                     default:
                     //
                 }
                 jsScripts.appendChild(script, jsScripts);
             });

             return promise;

         };
         //load jquery
         if (typeof jQuery == 'undefined') {
             promises.push(loadJs('jquery'));
         }

         //include handlebar js
         if (typeof Handlebars == 'undefined') {
             promises.push(loadJs('handlebar'));
         }

         //include vuejs
         if (typeof Vue == 'undefined') {
             promises.push(loadJs('vue'));
         }

         return promises;
     }

     /**
      * load the plugin with vue components
      */
     BuyButton.prototype.load = function() {

         var self = this;
         if (typeof jQuery != 'undefined') {
             $ = jQuery;
         }
         setupAjaxLoader();
         /**
          * product custom options component
          */
         Vue.component('options-wrapper', {
             props: {
                 options:
                 {
                     type: Array,
                     required: true
                 }
             },

             data: function() {
                 return {
                     parentItem: this.$parent.item
                 };
             },

             methods: {
                 updatePrice: function(event, item) {
                     let optionId = item.option_id;
                     let changePricesArray = this.$parent.changedPrice;
                     let flag = -1;
                     for (var i = 0; i < changePricesArray.length; i++) {
                         if (changePricesArray[i].optionId  == optionId) {
                             flag = i;
                             break;
                         }
                     }

                     if (item.type == 'drop_down' || item.type == 'radio') {

                             let optionValues = item.values;
                             let optionTypeId = 0;
                             if (item.type == 'drop_down') {
                                 let tempVal = $(event.target).val().split("_");
                                 optionTypeId = tempVal[0];
                             } else if (item.type == 'radio') {
                                 optionTypeId = $(event.target).val();
                             }

                             for (var j=0; j< optionValues.length; j++) {

                                 if (optionValues[j].option_type_id == optionTypeId) {
                                     if (flag == -1) {
                                         this.$parent.changedPrice.push(
                                             {
                                                 optionId: optionId,
                                                 optionPrice : this.actualPrice(optionValues[j])
                                             }
                                         );
                                     } else {

                                         changePricesArray[flag].optionPrice = this.actualPrice(optionValues[j]);
                                         this.$parent.changedPrice = [];
                                         this.$parent.changedPrice = changePricesArray;
                                     }
                                 }
                             }
                     } else if (item.type == 'file' || item.type == 'area' || item.type == 'field') {
                         if (flag == -1) {

                             this.$parent.changedPrice.push(
                                 {
                                     optionId: optionId,
                                     optionPrice : this.actualPrice(item)
                                 }
                             );
                         } else {
                             if ($(event.target).val().length > 0) {
                                 changePricesArray[flag].optionPrice = this.actualPrice(item);
                                 this.$parent.changedPrice = [];
                                 this.$parent.changedPrice = changePricesArray;
                             } else {
                                 changePricesArray[flag].optionPrice = 0;
                                 this.$parent.changedPrice = [];
                                 this.$parent.changedPrice = changePricesArray;
                             }

                         }
                     } else if (item.type == 'multiple') {
                             let optionTypeId = $(event.target).val();
                             let tempP = 0;
                             if (optionTypeId && optionTypeId.length) {
                                 for (var i=0; i < optionTypeId.length; i++ ) {
                                     let p = optionTypeId[i].split("_");
                                     tempP += parseFloat(p[1]);
                                 }
                             }

                             if (flag == -1) {
                                 this.$parent.changedPrice.push(
                                     {
                                         optionId: optionId,
                                         optionPrice : tempP
                                     }
                                 );
                             } else {
                                 changePricesArray[flag].optionPrice = tempP;
                                 this.$parent.changedPrice = [];
                                 this.$parent.changedPrice = changePricesArray;
                             }
                     } else if (item.type == 'checkbox') {
                             let optionValues = item.values;
                             let checkboxes = $(".bb-input-text-control > .checkbox");
                             let optionTypeId = $(event.target).val();

                             for (var j=0; j< optionValues.length; j++) {

                                 if (optionValues[j].option_type_id == optionTypeId) {
                                     if (flag == -1) {
                                         this.$parent.changedPrice.push(
                                             {
                                                 optionId: optionId,
                                                 optionPrice : this.actualPrice(optionValues[j])
                                             }
                                         );
                                     } else {
                                         if ($(event.target).is(":checked")) {
                                             changePricesArray[flag].optionPrice += this.actualPrice(optionValues[j]);

                                         } else {
                                             changePricesArray[flag].optionPrice -= this.actualPrice(optionValues[j]);
                                         }
                                         this.$parent.changedPrice = [];
                                         this.$parent.changedPrice = changePricesArray;
                                     }
                                 }
                             }
                     } else if (item.type == 'date') {
                         let dateOptions = $(event.target).parent().find("select");
                         let sFlag = true;
                         for (var i=0; i < dateOptions.length; i++) {

                             if (!dateOptions[i].value) {
                                 sFlag = false;
                                 break;
                             }
                         }
                         if (flag == -1 && sFlag) {

                             this.$parent.changedPrice.push(
                                 {
                                     optionId: optionId,
                                     optionPrice : this.actualPrice(item)
                                 }
                             );
                         } else if (flag != -1) {
                             if (sFlag) {
                                 changePricesArray[flag].optionPrice = this.actualPrice(item);
                                 this.$parent.changedPrice = [];
                                 this.$parent.changedPrice = changePricesArray;
                             } else {
                                 changePricesArray[flag].optionPrice = 0;
                                 this.$parent.changedPrice = [];
                                 this.$parent.changedPrice = changePricesArray;
                             }

                         }
                     } else if (item.type == 'date_time') {
                         let dateTimeOptions = $(event.target).parent().find("select");
                         let sFlag = true;
                         for (var i=0; i < dateTimeOptions.length; i++) {
                             if (!dateTimeOptions[i].value) {
                                 sFlag = false;
                                 break;
                             }
                         }
                         if (flag == -1 && sFlag) {

                             this.$parent.changedPrice.push(
                                 {
                                     optionId: optionId,
                                     optionPrice : this.actualPrice(item)
                                 }
                             );
                         } else if (flag != -1) {
                             if (sFlag) {
                                 changePricesArray[flag].optionPrice = this.actualPrice(item);
                                 this.$parent.changedPrice = [];
                                 this.$parent.changedPrice = changePricesArray;
                             } else {
                                 changePricesArray[flag].optionPrice = 0;
                                 this.$parent.changedPrice = [];
                                 this.$parent.changedPrice = changePricesArray;
                             }

                         }
                     } else if(item.type == 'time') {
                         let timeOptions = $(event.target).parent().find("select");
                         let sFlag = true;
                         for (var i=0; i < timeOptions.length; i++) {
                             if (!timeOptions[i].value) {
                                 sFlag = false;
                                 break;
                             }
                         }
                         if (flag == -1 && sFlag) {

                             this.$parent.changedPrice.push(
                                 {
                                     optionId: optionId,
                                     optionPrice : this.actualPrice(item)
                                 }
                             );
                         } else if (flag != -1) {
                             if (sFlag) {
                                 changePricesArray[flag].optionPrice = this.actualPrice(item);
                                 this.$parent.changedPrice = [];
                                 this.$parent.changedPrice = changePricesArray;
                             } else {
                                 changePricesArray[flag].optionPrice = 0;
                                 this.$parent.changedPrice = [];
                                 this.$parent.changedPrice = changePricesArray;
                             }

                         }
                     }

                 },
                 actualPrice: function(item) {
                     let itemPrice = 0;
                     if (item.default_price_type == 'percent') {
                         itemPrice = this.parentItem.fixedPrice*(parseFloat(item.default_price)/100);
                     } else {
                         itemPrice = parseFloat(item.default_price);
                     }
                     return itemPrice;
                 }
             },

             render: function (createElement) {
                 const that = this;
                 const nameSeparator = '||';
                 let months = ['-','01','02','03','04','05','06','07','08','09','10','11','12'],
                 hours = ['-','01','02','03','04','05','06','07','08','09','10','11','12','13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '00'];
                 let minutes = [];
                 minutes.push('-');
                 for(var m=1; m<=60; m++) {
                     if (m.toString().length == 1) {

                         minutes.push(("0" + m).slice(-2));
                     } else {
                         minutes.push(m.toString());
                     }
                 }
                 let days = [];
                 days.push('-');
                 for(var m=1; m<=31; m++) {
                     if (m.toString().length == 1) {
                         days.push(("0" + m).slice(-2));
                     } else {
                         days.push(m.toString());
                     }

                 }
                 let years = [];
                 years.push('-');
                 years.push((new Date()).getFullYear());
                 var actualPrice =  function(item) {
                     return that.actualPrice(item);
                 };

                 var textArea = function(item) {
                     let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
                     return createElement('div', {class: 'option-elements bb-option'},
                     [
                         createElement('label', {class:item.is_require?'label required':'label'}, item.default_title+' + '+getFormattedPrice(self.options.locate, that.parentItem.currenyCode, actualPrice(item))),
                         createElement('div', {class: 'bb-input-text-control'}, [
                             createElement('textarea', {
                             on:	{
                                 input: (e) => {
                                     that.updatePrice(e, item)
                                 }
                             },
                             class:'textarea', attrs:{dataId:item.option_id, dataValidate: dataValidate, name:`option${nameSeparator}${item.type}${nameSeparator}${item.option_id}`, rows:'5', cols:'25'}}),
                             createElement('div', {class: 'bb-option-notice'}, [
                                 createElement('p', 'Maximum number of characters: '+item.max_characters),
                             ])
                         ])
                     ]
                 )};

                 var textField = function(item) {
                     let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
                     return createElement('div', {class: 'option-elements'},
                     [
                         createElement('label', {class:item.is_require?'label required':'label'}, item.default_title+' + '+getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(item))),
                         createElement('div', {class: 'bb-input-text-control'}, [
                             createElement('input', {
                                 on:	{
                                     input: (e) => {
                                         that.updatePrice(e, item)
                                     }
                                 },
                                 attrs: {dataId:item.option_id, dataValidate:dataValidate, type: 'text',name:`option${nameSeparator}${item.type}${nameSeparator}${item.option_id}`}, class:'text-input'}),
                             createElement('div', {class: 'bb-option-notice'}, [
                                 createElement('p', 'Maximum number of characters: '+item.max_characters),
                             ])
                         ])
                     ]
                 )};

                 var multipleField = function(item) {
                     let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
                     return createElement('div', {class: 'option-elements'},
                     [
                         createElement('label', {class:item.is_require?'label required':'label'}, item.default_title),
                         createElement('div', {class: 'bb-input-text-control'}, [
                             createElement('select', {
                             on:	{
                                     input: (e) => {
                                     that.updatePrice(e, item)
                                 }
                             },
                             class:'select multiple',
                             attrs: {dataId:item.option_id, dataValidate:dataValidate, multiple: 'multiple', name:`option${nameSeparator}${item.type}${nameSeparator}${item.option_id}`},
                             }, [
                                 item.values.map(function(v, i) {
                                     return createElement('option', {domProps: {value: v.option_type_id+'_'+actualPrice(v)} }, v.default_title+' + '+getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(v)))
                                 })
                             ])
                         ])
                     ]
                 )};
                 var timeField = function(item) {
                     let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';

                     return createElement('div', {class: 'option-elements'},
                     [
                         createElement('label', {class:item.is_require?'label required':'label'}, item.default_title+' + '+getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(item))),
                         createElement('div', {class: 'bb-input-text-control'}, [
                             createElement('select', {
                                 on:	{
                                     input: (e) => {
                                         that.updatePrice(e, item)
                                     }
                                 },
                                 attrs: {dataId:item.option_id, dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}hours`}, class:'date-time-options'}, [
                                 hours.map( (v, i) => {
                                     return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
                                 })
                             ]),
                             createElement("b", ':'),
                             createElement('select', {
                                 on:	{
                                     input: (e) => {
                                         that.updatePrice(e, item)
                                     }
                                 },
                                 attrs: {dataId:item.option_id, dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}minutes`}, class:'date-time-options'}, [
                                 minutes.map( (v, i) => {
                                     return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
                                 })
                             ])
                         ])
                     ]
                 )};
                 var dateTimeField = function(item) {
                     let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
                     return createElement('div', {class: 'option-elements'},
                     [
                         createElement('label', {class:item.is_require?'label required':'label'}, item.default_title+' + '+getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(item))),
                         createElement('div', {class: 'bb-input-text-control'}, [
                             createElement('select', {
                                 on:	{
                                     input: (e) => {
                                         that.updatePrice(e, item)
                                     }
                                 },
                                 attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}year`}, class:'date-time-options'}, [
                                 years.map( (v, i) => {
                                     return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
                                 })
                             ]),
                             createElement('select', {
                                 on:	{
                                     input: (e) => {
                                         that.updatePrice(e, item)
                                     }
                                 },
                                 attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}month`}, class:'date-time-options'}, [
                                 months.map( (v, i) => {
                                     return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
                                 })
                             ]),
                             createElement('select', {
                                 on:	{
                                     input: (e) => {
                                         that.updatePrice(e, item)
                                     }
                                 },
                                 attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}day`}, class:'date-time-options'}, [
                                 days.map( (v, i) => {
                                     return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
                                 })
                             ]),

                             createElement('select', {
                                 on:	{
                                     input: (e) => {
                                         that.updatePrice(e, item)
                                     }
                                 },
                                 attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}hours`}, class:'date-time-options'}, [
                                 hours.map( (v, i) => {
                                     return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
                                 })
                             ]),
                             createElement("b", ':'),
                             createElement('select', {
                                 on:	{
                                     input: (e) => {
                                         that.updatePrice(e, item)
                                     }
                                 },
                                 attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}minutes`}, class:'date-time-options'}, [
                                 minutes.map( (v, i) => {
                                     return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
                                 })
                             ])

                         ])
                     ]
                 )};
                 var dateField = function(item) {
                     let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
                     return createElement('div', {class: 'option-elements'},
                     [
                         createElement('label', {class:item.is_require?'label required':'label'}, item.default_title+' + '+getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(item))),
                         createElement('div', {class: 'bb-input-text-control'}, [
                             createElement('select', {
                                 on:	{
                                     input: (e) => {
                                         that.updatePrice(e, item)
                                     }
                                 },
                                 attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}year`}, class:'date-time-options'}, [
                                 years.map( (v, i) => {
                                     return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
                                 })
                             ]),
                             createElement('select', {
                                 on:	{
                                     input: (e) => {
                                         that.updatePrice(e, item)
                                     }
                                 },
                                 attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}month`}, class:'date-time-options'}, [
                                 months.map( (v, i) => {
                                     return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
                                 })
                             ]),
                             createElement('select', {
                                 on:	{
                                     input: (e) => {
                                         that.updatePrice(e, item)
                                     }
                                 },
                                 attrs: {dataValidate:dataValidate, name: `option${nameSeparator}${item.type}${nameSeparator}${item.option_id}${nameSeparator}day`}, class:'date-time-options'}, [
                                 days.map( (v, i) => {
                                     return createElement('option', {domProps: {value: v=='-'?'':v}}, v.toString())
                                 })
                             ])

                         ])
                     ]
                 )};
                 var selectField = function(item) {
                     let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
                     return createElement('div', {class: 'option-elements'},
                     [
                         createElement('label', {class:item.is_require?'label required':'label'}, item.default_title),
                         createElement('div', {class: 'bb-input-text-control'}, [
                             createElement('select', {
                                 on:	{
                                     input: (e) => {
                                     that.updatePrice(e, item)
                                 }
                             }, class:'select', attrs: {
                                 on:	{
                                     input: (e) => {
                                         that.updatePrice(e, item)
                                     }
                                 },
                                 dataValidate:dataValidate, name:`option${nameSeparator}${item.type}${nameSeparator}${item.option_id}`}}, [
                                 item.values.map(function(v, i) {
                                     return createElement('option', {domProps: {value: v.option_type_id+'_'+actualPrice(v)}}, v.default_title+' + '+getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(v)))
                                 })
                             ])
                         ])
                     ]
                 )};
                 var checkboxField = function(item) {
                     let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
                     return createElement('div', {class: 'option-elements'},
                     [
                         createElement('label', {class:item.is_require?'label required':'label'}, item.default_title),
                         item.values.map((v, i)=> {
                             return createElement('div', {class: 'bb-options-container'},[
                                 createElement('div', {class: 'bb-input-text-control'}, [
                                     createElement('input', {
                                         on:	{
                                             input: (e) => {
                                                 that.updatePrice(e, item)
                                             }
                                         },
                                         domProps: {value: v.option_type_id}, attrs: {dataValidate:dataValidate, type: 'checkbox', name:`option${nameSeparator}${item.type}${nameSeparator}${v.option_id}`}, class:'checkbox'}),
                                     createElement('label', v.default_title+' + '+ getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(v)))
                                 ])
                             ])
                         })
                     ]
                 )};
                 var radioField = function(item) {
                     let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
                     return createElement('div', {class: 'option-elements'},
                     [
                         createElement('label', {class:item.is_require?'label required':'label'}, item.default_title),
                         item.values.map((v, i)=> {
                             return createElement('div', {class: 'bb-options-container'},[
                                 createElement('div', {class: 'bb-input-text-control'}, [
                                     createElement('input', {
                                         on:	{
                                             input: (e) => {
                                                 that.updatePrice(e, item)
                                             }
                                         },
                                         domProps: {value: v.option_type_id}, attrs: {dataValidate:dataValidate, type: 'radio', name:`option${nameSeparator}${item.type}${nameSeparator}${v.option_id}`}, class:'radio'}),
                                     createElement('label', v.default_title+' + '+ getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(v)))
                                 ]),
                             ]);

                         })
                     ]
                 )};

                 var fileField = function(item) {
                     let dataValidate = '{"required":'+item.is_require+', "max_charecters": '+item.max_characters+'}';
                     return createElement('div', {class: 'option-elements'},
                     [
                         createElement('label', {class:item.is_require?'label required':'label'}, item.default_title+' + '+ getFormattedPrice(self.options.locale, that.parentItem.currenyCode, actualPrice(item))),
                         createElement('div', {class: 'bb-input-text-control'}, [
                             createElement('input', {
                                 on:	{
                                     input: (e) => {
                                         that.updatePrice(e, item)
                                     }
                                 },
                                 attrs:{dataValidate:dataValidate, type:'file', name:`option${nameSeparator}${item.type}${nameSeparator}${item.option_id}`},class:'file bb-file-type-option'}),
                             createElement('div', {class: 'bb-option-notice'}, [
                                 createElement('p', 'Compatible file extensions to upload: '+item.file_extension),
                                 createElement('p', 'Maximum image width: '+item.image_size_x),
                                 createElement('p', 'Maximum image height: '+item.image_size_y)
                             ])
                         ])
                     ]
                 )};

                 return createElement('div', {class: 'options-wrapper'},
                     [
                         createElement("form", {attrs: {id: 'options-wrapper-form', encType: 'multipart/form-data'}}, [
                             that.options.map((jsonitem, i) => {
                                 let item = JSON.parse(jsonitem);
                                 let type = item.type;
                                 switch(type) {
                                     case 'file':
                                     return createElement('div', {class: 'option-wrapper'}, [fileField(item)]);
                                     case 'drop_down':
                                     return createElement('div', {class: 'option-wrapper'}, [selectField(item)]);
                                     case 'multiple':
                                     return createElement('div', {class: 'option-wrapper'}, [multipleField(item)]);
                                     break;
                                     case 'date':
                                     return createElement('div', {class: 'option-wrapper'}, [dateField(item)]);
                                     break;
                                     case 'date_time':
                                     return createElement('div', {class: 'option-wrapper'}, [dateTimeField(item)]);
                                     break;
                                     case 'time':
                                     return createElement('div', {class: 'option-wrapper'}, [timeField(item)]);
                                     break;
                                     case 'checkbox':
                                     return createElement('div', {class: 'option-wrapper'}, [checkboxField(item)]);
                                     break;
                                     case 'radio':
                                     return createElement('div', {class: 'option-wrapper'}, [radioField(item)]);
                                     break;
                                     case 'area':
                                     return createElement('div', {class: 'option-wrapper'}, [textArea(item)]);
                                     break;
                                     case 'field':
                                     return createElement('div', {class: 'option-wrapper'}, [textField(item)]);
                                     break;
                                 }
                             })
                         ])
                     ],
                 );
             }
         });

         /**
          * component for showing custom option and configurable attributes in cart
          */
         Vue.component('custom-options', {
             props: {
                 options: {
                     type: Object,
                     required: true
                 }
             },

             methods: {
                 getFormattedOptions: function() {
                     /**
                      * array for containing options label and value for showing
                      */
                     let o = [];
                     let products = self.options.products.items;
                     let sku = this.options.sku;
                     if (this.options.custom_options.length > 0) {
                         for(var i=0; i< products.length; i++) {
                             if (products[i].extension_attributes.sku == sku || sku.indexOf(products[i].extension_attributes.sku) == 0) {
                                 for (var j = 0; j < this.options.custom_options.length; j++) {
                                     for (var k=0; k<products[i].extension_attributes.custom_options.length;k++) {
                                         let co = JSON.parse(products[i].extension_attributes.custom_options[k]);
                                         let opV = '';
                                         let opA = [];
                                         if (co.values) {

                                             if (co.type == 'checkbox' || co.type == 'multiple') {
                                                 let tempV = this.options.custom_options[j].option_value.split(",");
                                                 for(m=0; m<co.values.length; m++) {
                                                     if ($.inArray(co.values[m].option_type_id, tempV) != -1) {
                                                         opA.push(co.values[m].default_title);
                                                     }
                                                 }
                                                 opV = opA.join(",");

                                             } else {
                                                 let tempV = this.options.custom_options[j].option_value;
                                                 for(m=0; m<co.values.length; m++) {
                                                     if (parseInt(co.values[m].option_type_id) == parseInt(tempV)) {
                                                         opV = co.values[m].default_title;
                                                     }
                                                 }
                                             }
                                         } else {
                                             if (co.type == 'file') {
                                                 let fileData = this.options.custom_options[j].option_value.split(",");
                                                 opV = fileData[1];
                                             } else if (co.type == 'date') {
                                                 let d = new Date(this.options.custom_options[j].option_value);
                                                 opV = d.toLocaleDateString(self.options.locale, {weekday: 'short', year: 'numeric',month: 'short',day: 'numeric'});
                                             } else if (co.type == 'date_time') {
                                                 let d = new Date(this.options.custom_options[j].option_value);
                                                 opV = d.toLocaleString(self.options.locale, {weekday: 'short', year: 'numeric',month: 'short',day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric'});
                                             } else if (co.type == 'time') {
                                                 let d = new Date(this.options.custom_options[j].option_value);
                                                 opV = d.toLocaleTimeString(self.options.locale, {hour: 'numeric', minute: 'numeric', second: 'numeric'});
                                             } else {
                                                 opV = this.options.custom_options[j].option_value;
                                             }

                                         }
                                         if (co.option_id == this.options.custom_options[j].option_id) {
                                             o.push({option_id: co.default_title, option_value: opV});
                                             break;
                                         }
                                     }

                                 }
                                 break;
                             }
                         }
                     }

                     /**
                      * creating label value array for configuarble products
                      */
                     if (this.options.super_attributes.length > 0) {

                         let fl = 0;
                         if (this.options.super_attributes.length > 0) {
                             for (key in this.options.super_attributes) {
                                 for(var i=0; i< products.length; i++) {
                                     if (products[i].extension_attributes.super_attributes) {
                                         let superAttr = JSON.parse(products[i].extension_attributes.super_attributes);
                                         let attrs = superAttr.attributes;
                                         for (key1 in attrs) {
                                             if (parseInt(key1) == parseInt(this.options.super_attributes[key].option_id)) {

                                                 o.push({option_id: attrs[key1].label, option_value: attrs[key1].options.map((v, i)=>{
                                                     if (this.options.super_attributes[key].option_value == v.id) {
                                                         return v.label;
                                                     }
                                                 })});
                                                 fl = 1;
                                             }
                                         }
                                         if (fl == 1) {
                                             fl = 0;
                                             break;
                                         }
                                     }
                                 }
                             }
                         }

                     }

                     return o;
                 }
             },



             /**
              * render component html
              */
             render: function(ce) {
                 /**
                  * render html for label values for product options
                  */
                 if (this.options.custom_options.length > 0 || this.options.super_attributes.length || this.options.product_option.length) {
                    //  if (this.options.product_option.length > 0) {
                        return ce("div", {class: 'bb-item-options-details'}, [
                            ce("span", {
                                on: {
                                    click: function(event) {
                                        $(event.target).next().slideToggle(1000);
                                }},
                                class: 'bb-view-options-details-show'
                            }, "View Details"),
                            ce("div", {class:"bb-view-options-details-container bb-hide"}, [
                                this.options.product_option.map( (v, i) => {
                                    return ce('div', {class: 'bb-option-details'}, [
                                        ce("b", v.option_id+' : '),
                                        ce("b", v.option_value)
                                    ])
                                }),
                                this.options.custom_options.map( (v, i) => {
                                    return ce('div', {class: 'bb-option-details'}, [
                                        ce("b", v.option_id+' : '),
                                        ce("b", v.option_value)
                                    ])
                                })
                            ])
                        ]);
                    //  }

                 }
             }

         });

         /**
          * component for building configurable options for product add to cart form
          */
         Vue.component('configurable-options', {
             props: {
                 /**
                  * used to get data from parent component
                  */
                 coptions: {
                     type: Object,
                     required: true
                 }
             },
             /**
              * executes after the component and template both loaded
              */
             mounted: function() {
                 this.$nextTick( () => {
                     this.updatePriceAndImage();
                 })
             },
             methods: {
                 updatePriceAndImage: function() {

                     let fields = $(".configuarbele-options").find(':input');

                     let selectedOptions = [];
                     let productId = 0;
                     let images = {};
                     let prices = {};
                     $.each (fields, function(index, value) {
                         selectedOptions.push(value.value);
                     });

                     for (key in this.coptions.index) {

                         if (selectedOptions.sort().join(",") === Object.values(this.coptions.index[key]).sort().join(",")) {
                             productId = key;
                             break;
                         }
                     }

                     if (productId) {
                         for (key in this.coptions.images) {
                             if (productId == key) {
                                 images = this.coptions.images[key];
                                 break;
                             }
                         }

                         for (key in this.coptions.optionPrices) {
                             if (productId == key) {
                                 prices = this.coptions.optionPrices[key];
                             }
                         }

                         if (Object.keys(prices).length) {
                             this.$parent.item.price = prices.finalPrice.amount;
                             if (images) {
                                this.$parent.item.image = images[0].img;
                            }
                         }
                     }
                 }
             },
             render: function (createElement) {
                 let that = this;
                 var selectField = function(item) {
                     let nameSeparator = "-";
                     let dataValidate = '{"required":"1"}';
                     return createElement('div', {class: 'configurable-option-elements'},
                     [
                         createElement('label', {class:'label required'}, item.label),
                         createElement('div', {class: 'bb-input-text-control'}, [
                             createElement('select', {
                                 on:	{
                                     input: (e) => {
                                         that.updatePriceAndImage();
                                     }
                                 },
                                 class:'select', attrs: {
                                 dataValidate:dataValidate, name:`option${nameSeparator}${item.id}`}}, [
                                 item.options.map(function(v, i) {
                                     return createElement('option', {domProps: {value: v.id}}, v.label)
                                 })
                             ])
                         ])
                     ]
                 )};

                 if (this.coptions.attributes) {

                     return createElement('div', {class:'configuarbele-options'}, [
                         Object.values(this.coptions.attributes).map((v, i) => {
                             return selectField(v)
                         })
                     ]);
                 }
             }
         });


         /**
          * product is passed in the plugin
          */
         var pIds = self.options.productIds;

         /**
          * rest url to get the product details from magento
          */
         var getProductsUrl = self.options.baseUrl+"rest/V1/products-render-info?"+
         `storeId=${self.options.storeId}&currencyCode=${self.options.currency_code}&`+
         "searchCriteria[filter_groups][0][filters][0][field]=entity_id&"+
         "searchCriteria[filter_groups][0][filters][0][value]="+pIds+"&"+
         "searchCriteria[filter_groups][0][filters][0][condition_type]=in";

         /**
          * making request for products details with promises
          */
         var getProductsData = getRequestPromise({
             url: getProductsUrl,
             method: 'GET'
         });
         getProductsData.then(
             (function(response) {
                 var self = this;
                 //console.log(response.items[3].extension_attributes.super_attributes);
                 self.options.products = response;

                 if (localStorage) {
                     localStorage.setItem('bb-mage-products', self.options.products);
                 }
                 /**
                  * after successfull api request render vue components
                  */
                 self.renderVue();

             }).bind(self),
             function(error) {
                 console.log(error);
             }
         );
     },

     /**
      * render vue components and child components
      */
     BuyButton.prototype.renderVue = function() {
         var self = this;
         d.getElementById('buybutton-init').insertAdjacentHTML( 'beforeend', self.options.template );
         var productsObject = self.options.products;


         /**
          * initialize cart data for the current website
          */
         getCartInitialData.call(this);

         /**
          * init vue component for products
          */
         self.vueContainerModel = new Vue({
             el: '#buybutton-container-id',
             data: function() {
                 let cartItem = {};
                 if (productsObject.items.length == 1) {
                     let item = productsObject.items[0];
                     cartItem = {
                         name: item.name,
                         price: item.price_info.final_price,
                         currenyCode: item.currency_code,
                         type: item.type,
                         description: item.extension_attributes.description,
                         custom_option: item.extension_attributes.custom_options,
                         super_attributes: item.extension_attributes.super_attributes?JSON.parse(item.extension_attributes.super_attributes):{},
                         sku: item.extension_attributes.sku,
                         image: item.images[0].url,
                         fixedPrice: item.price_info.final_price,
                         qty: item.qty,
                         id: item.id,
                     };
                 }

                 return {
                     products: productsObject.items,
                     cart: cart,
                     styles: self.options.styles,
                     designTemplate: self.options.designTemplate,
                     childData: {
                         miniCartText: self.options.miniCartText,
                         addToCartText: self.options.addToCartText,
                         buyNowText: self.options.buyNowText,
                         itemInCartText: self.options.itemInCartText,
                         cButtonText: self.options.cButtonText,
                         vButtonText: self.options.vButtonText,
                         noItemFoundText:self.options.noItemFoundText,
                         qtyText:self.options.qtyText,
                         subTotalText: self.options.subTotalText,
                         cart:cart
                     },
                     changedPrice: [],
                     item: cartItem
                 };
             },
             watch: {
                 designTemplate: {
                     handler: function(oldV, newV) {
                         if (oldV == 3) {
                             $(".buybutton-items > .buybutton-item").width("100%");
                             $(".buybutton-item-image > img").css("border", "none");
                         } else {
                             $(".buybutton-items > .buybutton-item").removeAttr("style");
                             $(".buybutton-item-image > img").css("border-bottom", "1px solid #ccc");
                         }
                     }
                 },
                 changedPrice : {
                     handler: function(priceArray, changedValue) {
                         let totalPrice = 0;
                         for (var i=0; i < changedValue.length; i++) {
                             totalPrice += parseFloat(changedValue[i].optionPrice);
                         }
                         this.item.price = totalPrice + this.item.fixedPrice;
                     }
                 }
             },
             mounted: function() {
                 this.$nextTick( () => {
                     this.addStyleTag;
                    if (this.products.length == 1) {
                         $(".buybutton-items > .buybutton-item").addClass("buybutton-item-full");
                         $(".buybutton-item-image img").css("border", "none");
                    } else {
                        let width = $("#buybutton-init").width();
                        setResponsiveWith(width);
                    }
                 })
             },
             methods: {
                 addToCart: function(cartItem) {
                     if (validateData.call(this)) {
                         let postData = buildAddToCartData.call(this, cartItem);

                         addProductsToCart.call(this, postData, self);
                     }

                 },
                 increaseQuantity(key) {
                     const quantityInput = document.getElementById("quantity-" + key.extension_attributes.sku);
                     if (quantityInput) {
                         let currentValue = parseInt(quantityInput.value);
                         currentValue++;
                         quantityInput.value = currentValue;
                     }
                 },
                 decreaseQuantity(key) {
                     const quantityInput = document.getElementById("quantity-" + key.extension_attributes.sku);
                     if (quantityInput) {
                         let currentValue = parseInt(quantityInput.value);
                         if (currentValue > 1) {
                             currentValue--;
                             quantityInput.value = currentValue;
                         }
                     }
                 },
                 view: function(data) {
                     self.modalOpen(data);
                 },
                 redirect: function (data) {
                    if (parseInt(self.options.redirectToProduct)) {
                        window.top.location.href = data.url;
                    } else {
                        this.view(data);
                    }
                 },
                 showCart: function(event) {
                     const cartContainer = document.querySelector('.bb-mini-cart-body');
                     if (!cartContainer.contains(event.target)) {
                         if (cart.isVisible == 'bb-show') {
                             cart.isVisible = 'bb-hide';
                         } else {
                             cart.isVisible = 'bb-show';
                         }
                     }
                 },
                 closeCheckout: function() {
                     document.getElementById("bb-checkout-iframe").removeEventListener('load', function(){});
                     $("#bb-checkout-iframe").remove();
                     $("#bb-checkout-container").hide();
                 }
             },
             computed: {
                 addStyleTag: function() {
                     let css = this.styles.trim();
                     var head = document.head || document.getElementsByTagName('head')[0];
                     if (document.getElementById("dynamicCss")) {
                         document.getElementById("dynamicCss").innerText = css;
                     } else {
                         var style = document.createElement('style');
                         style.type = 'text/css';
                         style.id = 'dynamicCss';
                         if (style.styleSheet) {
                             style.styleSheet.cssText = css;
                         } else {
                             style.appendChild(document.createTextNode(css));
                         }
                         head.appendChild(style);
                     }
                     return css;
                 },
                 itemsCount: function() {
                     let cartData = this.cart.cartItems;
                     let itemCount = 0;
                     if (cartData.length > 0) {
                         cartData.forEach(function(value, index) {
                             let qty = parseInt(value.qty)?parseInt(value.qty):0;

                             itemCount = itemCount + qty;
                         });
                     }
                     return itemCount;
                 },
                 formattedPrice: function() {
                     return getFormattedPrice(self.options.locale, this.item.currenyCode, this.item.price)
                 }
             },
             /**
              * adding mini cart child component inside products template
              */
             components: {
                 'mini-cart': {
                     template: self.options.cartTemplate,
                     data: function () {
                         return {
                             childData: this.$parent.childData
                         };
                     },

                     methods: {
                         removeItem: function(itemId) {
                             var currentThis = this;
                             let token = localStorage.getItem("magento-cart-id");
                             let removeFromCart = getRequestPromise({
                                 url: self.options.baseUrl+'rest/V1/guest-carts/'+token+'/items/'+itemId,
                                 method: 'DELETE'
                             });
                             removeFromCart.then(function(response) {
                                 cart.cartItems.forEach(function(value, index) {
                                     if (value.id == itemId) {

                                         cart.cartItems.splice(index, 1);;
                                     }
                                 });
                             });
                         },
                         takeBackup: function(item) {
                             this._beforeEditingCache = item.qty;
                         },
                         updateItem: function(item) {
                             if (item.qty > 0) {
                                 var currentThis = this;
                                 let token = localStorage.getItem("magento-cart-id");
                                 let updateCart = getRequestPromise({
                                     url: self.options.baseUrl+'rest/V1/guest-carts/'+token+'/items/'+item.id,
                                     method: 'PUT',
                                     data: JSON.stringify({
                                         cartItem: {
                                             item_id: item.id,
                                             qty: parseInt(item.qty),
                                             quote_id: token
                                         }
                                     })
                                 });

                                 updateCart.then(function(response) {
                                     this._beforeEditingCache = item.qty;
                                     }, function(reject) {
                                         item.qty = this._beforeEditingCache;
                                     }
                                 );
                             } else {
                                 item.qty = this._beforeEditingCache;
                             }
                             //return updateCart;
                         },

                         checkout: function() {
                             //jQuery('#bb-checkout-container').show();
                             let checkoutSrc = self.options.baseUrl+`bb/index/index/?access=${localStorage.getItem("magento-cart-quote-id")}`;

                             var dualScreenLeft = window.screenLeft != undefined ? window.screenLeft : window.screenX;
                             var dualScreenTop = window.screenTop != undefined ? window.screenTop : window.screenY;

                             var width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
                             var height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;

                             var left = ((width / 2) - (700 / 2)) + dualScreenLeft;
                             var top = ((height / 2) - (700 / 2)) + dualScreenTop;

                             if (window.innerWidth <= 700) {
                                 window.open(checkoutSrc, 'popup', 'scrollbars=yes, width=700px, height=1000px, top=' + top + ', left=' + left);
                             } else {
                                 left = ((width / 2) - (500 / 2)) + dualScreenLeft;
                                 window.open(checkoutSrc, 'popup', 'scrollbars=yes, width=500px, height=500px, top=' + top + ', left=' + left);
                             }
                         },
                         getOptions() {
                             return getFormattedOptions.call(self, cartItem, );
                         }
                     },
                     computed: {
                         subTotal: function() {
                             let cartData = cart.cartItems;
                             let subTotal = 0;
                             if (cartData.length > 0) {
                                 cartData.forEach(function(value, index) {
                                     subTotal = subTotal+(value.price*value.qty);
                                 });
                             }
                             return getFormattedPrice.call(self, self.options.locale, self.options.currency_code, subTotal);
                         },
                         itemsCount: function() {
                             let cartData = cart.cartItems;
                             let itemCount = 0;
                             if (cartData.length > 0) {
                                 cartData.forEach(function(value, index) {
                                     let qty = parseInt(value.qty)?parseInt(value.qty):0;

                                     itemCount = itemCount + qty;
                                 });
                             }
                             return itemCount;
                         }
                     }
                 }
             }
         });
     }

     /**
      * product quick vue modal
      */
     BuyButton.prototype.modalOpen = function() {
         var self = this;
         let item = arguments[0];
         let template = this.options.quickViewTemplate;
         this.optionsData = {
             extensionAttributes: {
                 customOptions: []
             }
         };
         this.optionsPrice = [];
         d.getElementById('buybutton-init').insertAdjacentHTML( 'beforeend', template );
         /**
          * quick view component
          */
         self.vueQuickModel = new Vue({
             el: '.buybutton-modal-container',
             data: {
                 item: {
                     name: item.name,
                     price: item.price_info.final_price,
                     currenyCode: item.currency_code,
                     type: item.type,
                     description: item.extension_attributes.description,
                     custom_option: item.extension_attributes.custom_options,
                     super_attributes: item.extension_attributes.super_attributes?JSON.parse(item.extension_attributes.super_attributes):{},
                     sku: item.extension_attributes.sku,
                     image: item.images[0].url,
                     fixedPrice: item.price_info.final_price,
                     id: item.id,
                 },
                 changedPrice:[],
                 addToCartLabel: window.wkaddTocartLabel.text
             },
             watch: {
                 changedPrice : {
                     handler: function(priceArray, changedValue) {

                         let totalPrice = 0;
                         for (var i=0; i < changedValue.length; i++) {

                             totalPrice += parseFloat(changedValue[i].optionPrice);
                         }

                         this.item.price = totalPrice + this.item.fixedPrice;
                     }
                 }
             },
             methods: {
                 addToCart: function(cartItem) {
                     if (validateData.call(this)) {
                         let postData = buildAddToCartData.call(this, cartItem);

                         addProductsToCart.call(this, postData, self);
                         fetch(self.options.baseUrl+self.options.pathStore, {
                             method: 'POST',
                             body: JSON.stringify({productId: this.item.id, action: 2}),
                             headers: {
                                 'Content-Type': 'application/json'
                             }
                         })
                             .then(response => {})
                             .then(data => {})
                             .catch(error => {});
                     }
                 },
                 increaseQuantity(key) {
                     const quantityInput = document.getElementById("quantity-" + key.sku);
                     if (quantityInput) {
                         let currentValue = parseInt(quantityInput.value);
                         currentValue++;
                         quantityInput.value = currentValue;
                     }
                 },
                 decreaseQuantity(key) {
                     const quantityInput = document.getElementById("quantity-" + key.sku);
                     if (quantityInput) {
                         let currentValue = parseInt(quantityInput.value);
                         if (currentValue > 1) {
                             currentValue--;
                             quantityInput.value = currentValue;
                         }
                     }
                 },

             },
             computed: {
                 formattedPrice: function() {
                     return getFormattedPrice(self.options.locale, this.item.currenyCode, this.item.price)
                 }
             }
         });

         d.getElementById("buybutton-modal-close-action").addEventListener('click', function() {self.modalClose() });
//         let scrollTop = window.top.scrollY - parent.document.getElementById('indacoContainer').getBoundingClientRect().y;//document.body.scrollTop;
         scrollTop = 0;
         if (parent.document.getElementById('indacoContainer')) {
             scrollTop = (parent.document.getElementById('indacoContainer').getBoundingClientRect().y * -1) + 20;
             if (scrollTop<0) { scrollTop = 10; }
             if (scrollTop>(parent.document.getElementById('indacoContainer').getBoundingClientRect().height-document.getElementsByClassName("buybutton-modal")[0].scrollHeight)) {
                 scrollTop = parent.document.getElementById('indacoContainer').getBoundingClientRect().height-document.getElementsByClassName("buybutton-modal")[0].scrollHeight;
             }
             d.getElementsByClassName("buybutton-modal")[0].style.maxHeight = (parent.document.getElementById('indacoContainer').getBoundingClientRect().height - 40) + 'px';
         }
         if (scrollTop<0) { scrollTop = 10; }
         scrollTop = scrollTop + 'px';
         d.getElementsByClassName("buybutton-modal")[0].style.marginTop = scrollTop;

         fetch(self.options.baseUrl+self.options.pathStore, {
             method: 'POST',
             body: JSON.stringify({productId: item.id, action: 1}),
             headers: {
                 'Content-Type': 'application/json'
             }
         })
             .then(response => {})
             .then(data => {})
             .catch(error => {});
     }

     BuyButton.prototype.modalClose = function() {
         d.getElementById("buybutton-modal-container-action").remove();
     }

     /** extend default parameters */
     function extendDefaults(source, properties) {
         var property;
         for (property in properties) {
             if (properties.hasOwnProperty(property)) {
                 source[property] = properties[property];
             }
         }
         return source;
     }

     /**
      * initialize cart data using magento rest
      */
     function getCartInitialData()
         {
             var self = this;
             let token = localStorage.getItem("magento-cart-id");
             if (!token) {
                 getRequestPromise({
                     url: self.options.baseUrl+'rest/V1/guest-carts'
                 }).then(function (response) {
                     token = response
                     localStorage.setItem("magento-cart-id", response);
                     getRequestPromise({
                         url: self.options.baseUrl+'rest/V1/guest-carts/'+token,
                         method: 'GET'
                    }).then(
                        function (response) {
                             cart.quoteId = response.quote_id;
                             localStorage.setItem("magento-cart-quote-id", response.id);

                         },
                        function (error) {
                             localStorage.removeItem("magento-cart-quote-id");
                             localStorage.removeItem("magento-cart-id");
                         }
                    );
                 }, function (error) {
                     localStorage.removeItem("magento-cart-quote-id");
                     localStorage.removeItem("magento-cart-id");
                 });
             } else {
                 getRequestPromise({
                     url: self.options.baseUrl+'rest/V1/guest-carts/'+token+'/items?currency_code='+self.options.currency_code,
                     method: 'GET'
                }).then(
                    function (response) {
                        if(response.length > 0) {
                            updateCart.call(self, response);
                        }

                     },
                    function (error) {
                         localStorage.removeItem("magento-cart-quote-id");
                         localStorage.removeItem("magento-cart-id");
                     }
                );
             }
         }

     /**
      * update cart data
      *
      * @param object response
      */
     function updateCart(response) {
         let self = this;
         if (cart.cartItems.length > 0) {
             cart.cartItems = [];
         }
         if (cart.cartItems.length == 0) {
             if (response.length > 0) {
                 response.forEach( function(value, key) {
                     let customOptions = [];
                     let superAttributes = [];
                     let productOptions = [];
                     if (value.product_option && value.product_option.extension_attributes && value.product_option.extension_attributes.custom_options) {
                         customOptions = value.product_option.extension_attributes.custom_options;
                     }

                     if (value.product_option && value.product_option.extension_attributes && value.product_option.extension_attributes.configurable_item_options) {
                         superAttributes = value.product_option.extension_attributes.configurable_item_options;
                     }
                    if (value.product_option && value.product_option.extension_attributes && value.product_option.extension_attributes.configurable_item_options) {
                        productOptions = value.product_option.extension_attributes.configurable_item_options;
                    }
                     cart.cartItems.push({
                         id: value.item_id,
                         image: '',
                         sku:value.sku,
                         name: value.name,
                         price: value.price,
                         formattedPrice: getFormattedPrice.call(self, self.options.locale, self.options.currency_code, value.price),
                         qty: value.qty,
                         custom_options: customOptions,
                         super_attributes: superAttributes,
                         product_option: productOptions
                     });
                     cart.quoteId = value.quote_id;
                     $.each(cart.cartItems, function(k, value) {
                         let selfScope = self;
                        var getProductsUrl = self.options.baseUrl+"rest/V1/products-render-info?"+
                        `storeId=${self.options.storeId}&currencyCode=${self.options.currency_code}&`+
                        "searchCriteria[filter_groups][0][filters][0][field]=sku&"+
                        "searchCriteria[filter_groups][0][filters][0][value]="+value.sku+"&"+
                        "searchCriteria[filter_groups][0][filters][0][condition_type]=eq";

                        /**
                         * making request for products details with promises
                         */
                        var getProductsData = getRequestPromise({
                            url: getProductsUrl,
                            method: 'GET'
                        });
                        getProductsData.then(
                            (function(response) {
                                if (response.items.length == 0) {
                                    var getProductsUrl = selfScope.options.baseUrl+"rest/V1/products-render-info?"+
                                    `storeId=${selfScope.options.storeId}&currencyCode=${selfScope.options.currency_code}&`+
                                    "searchCriteria[filter_groups][0][filters][0][field]=name&"+
                                    "searchCriteria[filter_groups][0][filters][0][value]="+value.name+"&"+
                                    "searchCriteria[filter_groups][0][filters][0][condition_type]=eq";

                                    var getProductData = getRequestPromise({
                                        url: getProductsUrl,
                                        method: 'GET'
                                    });
                                    getProductData.then(
                                        (function(response) {
                                            var item = response.items;
                                            url = item[0].images[0].url;
                                            value.image = url;

                                            if (value.super_attributes.length > 0) {

                                                let fl = 0;
                                                let o = [];

                                                for (key in value.super_attributes) {
                                                    for(var i=0; i< item.length; i++) {
                                                        if (item[i].extension_attributes.super_attributes) {
                                                            let superAttr = JSON.parse(item[i].extension_attributes.super_attributes);
                                                            let attrs = superAttr.attributes;
                                                            for (key1 in attrs) {
                                                                if (parseInt(key1) == parseInt(value.super_attributes[key].option_id)) {

                                                                    o.push({option_id: attrs[key1].label, option_value: attrs[key1].options.map((v, i)=>{
                                                                        if (value.super_attributes[key].option_value == v.id) {
                                                                            return v.label;
                                                                        }
                                                                    })});
                                                                    fl = 1;
                                                                }
                                                            }
                                                            if (fl == 1) {
                                                                fl = 0;
                                                                break;
                                                            }
                                                        }

                                                    }
                                                }
                                                value.product_option = o;
                                            }
                                            if (value.custom_options.length > 0) {

                                                let fl = 0;
                                                let co = [];

                                                for (key in value.custom_options) {
                                                    for(var i=0; i< item.length; i++) {
                                                        if (item[i].extension_attributes.custom_options) {
                                                            let customOpt = JSON.parse(item[i].extension_attributes.custom_options);
                                                            // let attrs = customOpt.attributes;
                                                            // for (key1 in attrs) {
                                                                if (parseInt(customOpt.option_id) == parseInt(value.custom_options[key].option_id)) {

                                                                    co.push({option_id: customOpt.title, option_value: customOpt.values.map((v, i)=>{
                                                                        if (value.custom_options[key].option_value == v.option_type_id) {
                                                                            return v.title;
                                                                        }
                                                                    })});
                                                                    fl = 1;
                                                                }
                                                            // }
                                                            if (fl == 1) {
                                                                fl = 0;
                                                                break;
                                                            }
                                                        }
                                                    }
                                                }
                                                if (co.length) {
                                                    value.custom_options = co;
                                                }
                                            }
                                        })
                                    );
                                } else {
                                    var self = this;
                                    var item = response.items[0];
                                    url = item.images[0].url;
                                    value.image = url;
                                    if (value.custom_options.length > 0) {

                                        let fl = 0;
                                        let co = [];

                                        for (key in value.custom_options) {
                                            for(var i=0; i< item.extension_attributes.custom_options.length; i++) {
                                                if (item.extension_attributes.custom_options) {
                                                    let customOpt = JSON.parse(item.extension_attributes.custom_options[i]);
                                                    // let attrs = customOpt.attributes;
                                                    // for (key1 in attrs) {
                                                        if (parseInt(customOpt.option_id) == parseInt(value.custom_options[key].option_id)) {

                                                            co.push({option_id: customOpt.title, option_value: customOpt.values.map((v, i)=>{
                                                                if (value.custom_options[key].option_value == v.option_type_id) {
                                                                    return v.title;
                                                                }
                                                            })});
                                                            fl = 1;
                                                        }
                                                    // }
                                                    if (fl == 1) {
                                                        fl = 0;
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                        if (co.length) {
                                            value.custom_options = co;
                                        }
                                    }
                                }
                            })
                        );
                    });
                 });
             } else {
                 cart = {
                     cartItems: [],
                     isVisible: 'bb-hide',
                     quoteId: 0
                 };
             }
         }
     }

     /**
      * build add to cart data
      */
     function buildAddToCartData(cartItem) {
         let optionsData = {
             extensionAttributes: {
                 customOptions: []
             }
         };
         let optionsFormData = $("#options-wrapper-form").serializeArray();

         $.each(optionsFormData, function(index, value) {
             let nameInfo = value.name.split("||");
             let type = nameInfo[1];
             let val = value.value;
             let valInfo = val.split("_");
            //  if (cartItem.custom_option) {
            //     nameInfo[2] = JSON.parse(cartItem.custom_option[index]).title;
            //     valArr = JSON.parse(cartItem.custom_option[index]).values;
            // } else {
            //      nameInfo[2] = JSON.parse(cartItem.extension_attributes.custom_options[index]).title;
            //      valArr = JSON.parse(cartItem.extension_attributes.custom_options[index]).values;
            // }
            //  $.each(valArr, function(ind, v) {
            //              if (v.option_type_id == value.value) {
            //                  val = v.title;
            //              }
            //  });

             let checkKeyExists = function(opId) {
                 let isExist = 'not_exists';
                 for (var keys = 0; keys < optionsData.extensionAttributes.customOptions.length; keys++) {
                     if (optionsData.extensionAttributes.customOptions[keys].option_id == opId) {
                         isExist = keys;
                         break;
                     }
                 }
                 return isExist;
             };

             switch(type) {
                 case 'drop_down':
                     optionsData.extensionAttributes.customOptions.push(
                         {option_id: nameInfo['2'], option_value:  valInfo[0]}
                     );
                 break;
                 case 'checkbox':
                     if (optionsData.extensionAttributes.customOptions.length > 0 ) {
                         let i = checkKeyExists(nameInfo['2']);
                         if (i == 'not_exists') {
                             optionsData.extensionAttributes.customOptions.push(
                                 {option_id: nameInfo['2'], option_value:  val}
                             );
                         } else {
                             optionsData.extensionAttributes.customOptions[i].option_value+=','+val;
                         }
                     } else {
                         optionsData.extensionAttributes.customOptions.push(
                             {option_id: nameInfo['2'], option_value:  val}
                         );
                     }

                 break;
                 case 'multiple':
                     if (optionsData.extensionAttributes.customOptions.length > 0 ) {
                         let i = checkKeyExists(nameInfo['2']);
                         if (i == 'not_exists') {
                             optionsData.extensionAttributes.customOptions.push(
                                 {option_id: nameInfo['2'], option_value:  valInfo[0]}
                             );
                         } else {
                             optionsData.extensionAttributes.customOptions[i].option_value+=','+valInfo[0];
                         }
                     } else {
                         optionsData.extensionAttributes.customOptions.push(
                             {option_id: nameInfo['2'], option_value:  valInfo[0]}
                         );
                     }
                 break;
                 case 'date':
                     if (optionsData.extensionAttributes.customOptions.length > 0 ) {
                         let i = checkKeyExists(nameInfo['2']);
                         let seperator = '-';
                         if (i == 'not_exists') {
                             optionsData.extensionAttributes.customOptions.push(
                                 {option_id: nameInfo['2'], option_value:  val}
                             );
                         } else {

                             optionsData.extensionAttributes.customOptions[i].option_value+=`${seperator}${val}`;
                             if (nameInfo['3'] == 'day') {
                                 optionsData.extensionAttributes.customOptions[i].option_value =`${optionsData.extensionAttributes.customOptions[i].option_value} 00:00:00`
                             }
                         }
                     } else {
                         optionsData.extensionAttributes.customOptions.push(
                             {option_id: nameInfo['2'], option_value:  val}
                         );
                     }
                 break;
                 case 'date_time':
                     if (optionsData.extensionAttributes.customOptions.length > 0 ) {
                         let i = checkKeyExists(nameInfo['2']);
                         let seperator = '-';
                         //console.log(i);
                         if (i == 'not_exists') {
                             optionsData.extensionAttributes.customOptions.push(
                                 {option_id: nameInfo['2'], option_value:  val}
                             );
                         } else {
                             if (nameInfo['3'] == 'hours') {
                                 seperator = ' ';
                             }
                             if (nameInfo['3'] == 'minutes') {
                                 seperator = ':';
                             }
                             // if (nameInfo['3'] == 'day_part') {
                             // 	seperator = ' ';
                             // }
                             optionsData.extensionAttributes.customOptions[i].option_value+=`${seperator}${val}`;
                             if (nameInfo['3'] == 'minutes') {
                                 optionsData.extensionAttributes.customOptions[i].option_value =`${optionsData.extensionAttributes.customOptions[i].option_value}:00`;
                             }
                         }
                     } else {
                         optionsData.extensionAttributes.customOptions.push(
                             {option_id: nameInfo['2'], option_value:  val}
                         );
                     }
                 break;
                 case 'time':
                     if (optionsData.extensionAttributes.customOptions.length > 0 ) {
                         let i = checkKeyExists(nameInfo['2']);
                         let seperator = ":";
                         if (i == 'not_exists') {
                             optionsData.extensionAttributes.customOptions.push(
                                 {option_id: nameInfo['2'], option_value:  val}
                             );
                         } else {
                             // if (nameInfo['3'] == 'day_part') {
                             // 	seperator = ' ';
                             // }
                             optionsData.extensionAttributes.customOptions[i].option_value+=`${seperator}${val}`;
                             if (nameInfo['3'] == 'minutes') {
                                 let today = new Date();
                                 optionsData.extensionAttributes.customOptions[i].option_value =`${today.getFullYear()}-${today.getMonth()}-${today.getDate()} ${optionsData.extensionAttributes.customOptions[i].option_value}:00`;
                             }
                         }
                     } else {
                         optionsData.extensionAttributes.customOptions.push(
                             {option_id: nameInfo['2'], option_value:  val}
                         );
                     }
                 break;
                 default:
                 optionsData.extensionAttributes.customOptions.push(
                     {option_id: nameInfo['2'], option_value:  val}
                 );
             }

         });

         let fileTypeOptions = $("#options-wrapper-form").find(".bb-file-type-option");
         if (fileTypeOptions.length > 0) {
             $.each (fileTypeOptions, function(i, v) {
                 let fileInputNameInfo = $(v).attr("name").split("||");
                 let file = $(v).prop('files')[0];
                 var fr = new FileReader();
                 fr.addEventListener("load", function(e) {
                     optionsData.extensionAttributes.customOptions.push(
                         {
                             option_id: fileInputNameInfo['2'],
                             option_value: "file",
                             extensionAttributes: {
                                 file_info: {
                                     type: file.type,
                                     name: file.name,
                                     base64_encoded_data: e.target.result.replace(/^data:image\/(.*?);base64,/, "")
                                 }
                             }
                         }
                     );
                 });
                 fr.readAsDataURL( file );

             });
         }

         if (cartItem.type == 'configurable') {
             optionsData.extensionAttributes.configurableItemOptions = [];
             let fields = $(".configuarbele-options").find(':input');

             $.each (fields, function(index, value) {
                 let opId = $(value).attr('name').split("-");
                 optionsData.extensionAttributes.configurableItemOptions.push({optionId: opId[1],optionValue:value.value});
             });

         }

         cartItem.sku = cartItem.sku?cartItem.sku:cartItem.extension_attributes.sku;
         cartItem.product_option = optionsData;
         //console.log(optionsData);
         return cartItem;
     }

     /**
      * validate add to cart data
      */
     function validateData() {
         let fields = $(".bb-option-wrapper").find(':input');
         let isValid = true;
         let optionsData = {
             extensionAttributes: {
                 customOptions: []
             }
         };
         $.each(fields, function(index, value) {
             let validation = JSON.parse($(value).attr('datavalidate'));
             if (validation.required) {
                 if ($(value).attr('type') == 'checkbox' || $(value).attr('type') == 'radio') {
                     switch ($(value).attr('type')) {
                         case 'checkbox':
                             if (!$('input[name="'+$(value).attr('name')+'"]').is(":checked")) {
                                 if ($(value).next(".bb-option-notice").find(".error").length == 0) {
                                     $(value).after($("<div></div>").addClass('bb-option-notice').html($('<p></p>').addClass("error").text("This option is required")));
                                 }
                             } else {
                                 if ($(value).next(".bb-option-notice").find(".error").length > 0) {
                                     $(value).next(".bb-option-notice").find(".error").parent().remove();
                                 }
                             }
                         break;
                         case 'radio':
                             if (!$('input[name="'+$(value).attr('name')+'"]').is(":checked")) {
                                 if ($(value).next(".bb-option-notice").find(".error").length == 0) {
                                     $(value).after($("<div></div>").addClass('bb-option-notice').html($('<p></p>').addClass("error").text("This option is required")));
                                 }
                             } else {
                                 if ($(value).next(".bb-option-notice").find(".error").length > 0) {
                                     $(value).next(".bb-option-notice").find(".error").parent().remove();
                                 }
                             }
                         break
                     }
                 } else {
                     if (!$(value).val() || $(value).val().length == 0) {
                         isValid = false;
                         if ($(value).next(".bb-option-notice").find(".error").length == 0) {
                             $(value).after($("<div></div>").addClass('bb-option-notice').html($('<p></p>').addClass("error").text("This option is required")));
                         }
                     } else {
                         if ($(value).next(".bb-option-notice").find(".error").length > 0) {
                             $(value).next(".bb-option-notice").find(".error").parent().remove();
                         }
                     }
                 }
             }
             if (validation.max_charecters > 0) {
                 if ($(value).val().length > validation.max_charecters) {
                     isValid = false;
                     if ($(value).next(".bb-option-notice").find(".error").length == 0) {
                         $(value).after($("<div></div>").addClass('bb-option-notice').html($('<p></p>').addClass("error").text("maximum "+validation.max_charecters+" charecters are allowed")));
                     }
                 }
             }
         });

         return isValid;
     }

     /**
      * add product to the cart
      *
      * object cartItem
      */
     function addProductsToCart(cartItem, self) {
         /**
          * get current cart items
          *
          * @param string token
          */
         let getCartItems = function(token) {
             let cartItemsPromise = getRequestPromise({
                 url: self.options.baseUrl+'rest/V1/guest-carts/'+token+'/items',
                 method: 'GET'
             });
             return cartItemsPromise;
         };

         /**
          * function to add product to cart
          *
          * @param int cartId
          * @param string token
          * @param array params
          */
         let addProductToCart = function(cartId, token, params) {
             let addCartPromise = getRequestPromise({
                 url: self.options.baseUrl+'rest/V1/guest-carts/'+token+'/items',
                 method: 'POST',
                 data: JSON.stringify(params)
             });
             return addCartPromise;
         };

         /**
          * token to interact with user cart
          */
         let token = localStorage.getItem("magento-cart-id");

         if (!token) {
             /**
              * create cart if no token available
              */
             let promise = getRequestPromise({
                 url: self.options.baseUrl+'rest/V1/guest-carts'
             });

             promise.then(
                 function(resolve) {
                     token = resolve;
                     localStorage.setItem("magento-cart-id", token);
                     /**
                      * get cart items after token created
                      */
                     let cartItemsPromise = getCartItems(token);
                     cartItemsPromise.then(
                         function(response) {
                             if (response) {
                                 /**
                                  * save quote id
                                  */
                                 localStorage.setItem("magento-quote-id", token);
                                 /**
                                  * create params to add product to the cart
                                  */
                                 let params = {
                                     cartItem: {
                                         sku: cartItem.sku,
                                         qty: 1,
                                         quoteId: token,
                                         product_option: cartItem.product_option
                                     }
                                 };
                                 /**
                                  * add to product to the cart function call
                                  */
                                 let addCartPromise = addProductToCart(response.id, token, params);
                                 addCartPromise.then(function(resolve) {

                                     if (resolve) {
                                        localStorage.setItem("magento-cart-quote-id", resolve.quote_id);
                                         let cartItemsPromise = getCartItems(token);
                                         cartItemsPromise.then(function(response) {
                                             updateCart.call(self, response);
                                         });
                                     }
                                 }, function(reject) {
                                     if (reject.responseJSON.message) {
                                         close = false;
                                         message = reject.responseJSON.message;
                                         if (message == 'Richiesto un cambio di stato non valido') {
                                             message = 'Ops, qualcosa non è andato a buon fine. Inserisci nuovamente il prodotto in carrello';
                                         }
                                         alert(message);
                                     }
                                     let jqXHR = reject;
                                     let error = JSON.parse(jqXHR.responseText);
                                     if (error.message && (error.message == 'Invalid state change requested' || error.message == 'Richiesto un cambio di stato non valido')) {
                                        localStorage.removeItem("magento-cart-quote-id");
                                        localStorage.removeItem("magento-cart-id");
                                        cart.cartItems = [];
                                        getCartInitialData.call(self);
                                        console.log(error);
                                    }
                                 });
                             }
                         },
                         function(error) {
                             localStorage.removeItem("magento-cart-quote-id");
                             localStorage.removeItem("magento-cart-id");
                         }
                     );
                 },
                 function(reject) {
                     localStorage.removeItem("magento-cart-quote-id");
                     localStorage.removeItem("magento-cart-id");
                 }
             );
         } else {
             let cartItemsPromise = getCartItems(token);
             cartItemsPromise.then(
                 function(response) {
                     if (response) {
                         let params = {
                            cartItem: {
                                 sku: cartItem.sku,
                                 qty: document.getElementById("quantity-"+cartItem.sku).value,
                                 quoteId: token,
                                 product_option: cartItem.product_option
                            }
                         };
                         let addCartPromise = addProductToCart(response.id, token, params);
                         let close = true;
                         addCartPromise.then(function(resolve) {
                             if (resolve) {
                                 localStorage.setItem("magento-cart-quote-id", resolve.quote_id);
                                 let cartItemsPromise = getCartItems(token);
                                 cartItemsPromise.then(function(response) {
                                     updateCart.call(self, response);
                                 });
                             }
                         }, function(reject) {
                             if (reject.responseJSON.message) {
                                 close = false;
                                 message = reject.responseJSON.message;
                                 if (message == 'Richiesto un cambio di stato non valido') {
                                     message = 'Ops, qualcosa non è andato a buon fine. Inserisci nuovamente il prodotto in carrello';
                                 }
                                 alert(message);
                             }
                             let jqXHR = reject;
                             let error = JSON.parse(jqXHR.responseText);
                             if (error.message && (error.message == 'Invalid state change requested' || error.message == 'Richiesto un cambio di stato non valido')) {
                                localStorage.removeItem("magento-cart-quote-id");
                                localStorage.removeItem("magento-cart-id");
                                cart.cartItems = [];
                                getCartInitialData.call(self);
                                console.log(error);
                            }
                         });
                         setTimeout(function() {
                             if (close) {
                                 document.getElementById("buybutton-modal-container-action").remove();
                             }
                         }, 500);
                     }
                 },
                 function(error) {
                     localStorage.removeItem("magento-cart-quote-id");
                     localStorage.removeItem("magento-cart-id");
                 }
             );
         }
     }

     /**
      * get formatted price
      */
     function getFormattedPrice(locale = '', currency = '', price) {
         var self = this;
         if (!locale) {
             locale = this.locale;
         }
         if (!currency) {
             currency = this.currency_code;
         }
         monetary_value = price;
         var format = new Intl.NumberFormat(locale, {
            style: 'currency',
            currency: currency,
            minimumFractionDigits: 2,
        }).format(monetary_value);
        // return format;
         return price.toLocaleString('en-US', {style: 'currency', currency: currency});
     }

     /**
      * general function to get promise for any ajax request
      *
      * @param object requestObj
      */
     function getRequestPromise(requestObj) {

         let ajaRequestObj = {
             url: '',
             crossDomain: true,
             headers: {
                 'Accept': "application/json",
                 'Content-Type' : "application/json"
             },
             useLoader: true,
             method: 'POST',
             processData: false,
         };
         let promise = new Promise(function(resolve, reject) {
             ajaRequestObj = extendDefaults(ajaRequestObj, requestObj);
             ajaRequestObj.success = function(response) {
                 resolve(response);
             };
             ajaRequestObj.error = function(jqXHR, textStatus, errorThrown) {
                 reject(jqXHR);
             };
             $.ajax(ajaRequestObj);
         });
         return promise;
    }

    /**
     * set responsive width
     */
    function setResponsiveWith(width) {
        if (width < 890) {
            $(".buybutton-item").addClass("width-less-then-890");
        }

        if (width < 638) {
            $(".buybutton-item").addClass("width-less-then-638");
        }

        if (width < 383) {
            $(".buybutton-item").addClass("width-less-then-383");
        }
    }

     /**
      * general function to start and stop loader for any ajax request on the page
      */
     function setupAjaxLoader() {

         $(d).ajaxStart( function(event, xhr, options) {
             let ajaxTemplate = '<div class=bb-ajax-loader><div class=bb-loader><div class="cp-spinner cp-skeleton"></div></div></div>';
             $("body").append(ajaxTemplate);
         });

         $(d).ajaxComplete( function(event, xhr, options) {
             $("body").find(".bb-ajax-loader").remove();
         });
     }

     /**
      * is vue js loaded
      */
     function isVueLoaded() {
         var self = this;
         setTimeout(function() {
             if (window.Vue != null) {
                 self.load();
             } else {
                 isVueLoaded.call(self);
             }
         }, 50);
     }

 }(document, ''));