Greasy Fork

Greasy Fork is available in English.

Amazon a Pesos Argentinos

Mostrar precios en dolar tarjeta

目前为 2017-02-18 提交的版本。查看 最新版本

// ==UserScript==
// @name          Amazon a Pesos Argentinos
// @namespace     sharkiller-amazon-dolar-tarjeta
// @description   Mostrar precios en dolar tarjeta
// @version       3.2
// @require       http://code.jquery.com/jquery-latest.js
// @require       https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.2.1/mustache.min.js
// @include       *amazon.com/*
// @include       *amazon.co.uk/*
// @include       *amazon.ca/*
// @include       *amazon.es/*
// @include       *amazon.de/*
// @include       *amazon.fr/*
// @include       *amazon.it/*
// @connect       amazon.com
// @connect       amazon.co.uk
// @connect       amazon.ca
// @connect       amazon.es
// @connect       amazon.de
// @connect       amazon.fr
// @connect       amazon.it
// @connect       yahoo.com
// @connect       europa.eu
// @connect       mercadolibre.com
// @grant         GM_getValue
// @grant         GM_setValue
// @grant         GM_xmlhttpRequest
// @grant         GM_addStyle
// ==/UserScript==

(function() {
if( typeof jQuery === 'undefined' ){
    return false;
}

GM_addStyle('.price-ars{color:green;display:inline-block;margin:0 8px;background:linear-gradient(to bottom,#add8e6,#fff,#add8e6);border-radius:8px;padding:0 6px}'+
            '#sc-buy-box .price-ars{font-size:12px;display:block;padding:0;margin:0;background:0 0}div#sc-buy-box{margin-bottom:-14px}');

GM_addStyle('#snoop-icon{margin-left:4px;width:30px;height:20px}#snoop-placeholder{width:32px}div.snoop-loader{width:13px;height:13px}div.snoop-tooltip,div.snoop-tooltip-ml{display:none;font-size:13px;border-image:none;letter-spacing:0}'+
            'div.snoop-tooltip div.entry,div.snoop-tooltip-ml div.entry{padding-top:5px}span.snoop-price{color:#900;font-size:1em;font-weight:700}span.snoop-warning{color:#C60!important}.snoop-not-found{text-decoration:line-through}'+
            'span.snoop-on{color:#000;font-weight:400}div.snoop-credits{font-size:.75em;font-style:italic;text-align:center;margin-top:13px;font-weight:400;color:#666}span.back-link{line-height:0;margin-left:1px;top:-10px;position:relative}'+
            'span.back-link>img{top:1;position:relative}span.back-link>a{font-size:1em;text-decoration:none!important}#snoop-icon-ml{margin-left:10px}');

String.prototype.endsWith = function (pattern) {
	var d = this.length - pattern.length;
	return d >= 0 && this.lastIndexOf(pattern) === d;
};

var amazonCurrencies = ["USD", "GBP", "CAD", "EUR"];
var currencyFrom;

var currencies = {
	"USD" : {
		symbol: "$",
		priceRegex: /\$\s*([\d,.]+\d)/,
        vat: false
	},

	"GBP" : {
		symbol: "£",
		priceRegex: /£\s*([\d,.]+\d)/,
        vat: true
	},

	"CAD" : {
		symbol: "CDN$ ",
		priceRegex: /CDN\$\s*([\d,.]+\d)/,
        vat: false
	},

	"EUR" : {
		symbol: "EUR ",
		priceRegex: /EUR\s*([\s\d,.]+\d)/,
        vat: true
	}
};

if (document.domain.endsWith("com")) {
	currencyFrom = "USD";
} else if (document.domain.endsWith("co.uk")) {
	currencyFrom = "GBP";
} else if (document.domain.endsWith("ca")) {
	currencyFrom = "CAD";
} else if (
    document.domain.endsWith("es") ||
    document.domain.endsWith("de") ||
    document.domain.endsWith("fr") ||
    document.domain.endsWith("it")
) {
	currencyFrom = "EUR";
} else {
	return;
}

var LAST_RUN = "last_run_";
var CURRENCY_RATE = "currency_rate_";

var decimalPlaces = 2;
var prefixCurrencySymbol = true;
var taxPorcentage = 5;

var rounding = Math.pow(10, decimalPlaces);

var rate = GM_getValue(CURRENCY_RATE + currencyFrom);
var lastRun = GM_getValue(LAST_RUN + currencyFrom, "01/01/0001");
var currencyTo = 'ARS';
var todayDate = new Date();
var todayString = todayDate.getDate() + "/" + todayDate.getMonth() + "/" + todayDate.getFullYear();
var currencyToSymbol = 'ARS $';

function regularPriceParser(price, currency) {
    price = price.replace(/\s/g, '');

    var regex = /^[\d.]+,[\d]{2}$/;
    var needProperPrice = regex.exec(price);
    if(needProperPrice) {
        price = price.replace(/\./g, '').replace(/,/, '.');
    }else{
        price = price.replace(/\,/g, '');
    }

    return parseFloat(price);
}

function fetchCurrencyData(coin, callback) {
	GM_xmlhttpRequest({
		method: "GET",
		url: "http://download.finance.yahoo.com/d/quotes.csv?s=" + coin + currencyTo + "=X&f=l1&e=.csv",
		onload: function(responseDetails) {
			var rate = responseDetails.responseText.replace(/[\r\n]/g, "");
			GM_setValue(CURRENCY_RATE + coin, rate);
			GM_setValue(LAST_RUN + coin, todayString);
			callback();
		},
		onerror: function(responseDetails) {
			alert("Error fetching currency data for " + coin);
		}
	});
}

function appendConversionNoVAT(price, matched, offset, string) {
    return appendConversion(price, matched, offset, string, true);
}

function appendConversion(price, matched, offset, string, novat) {

	var originalPrice = regularPriceParser(matched, currencyFrom);

	if (isNaN(originalPrice)) {
		return price;
	}

    if(currencies[currencyFrom].vat && novat === undefined){
        originalPrice /= 1.2;
    }

	var converted = formatCurrency(originalPrice * (rate * (taxPorcentage / 100 + 1)), rounding, currencyToSymbol, prefixCurrencySymbol);

    if(currencies[currencyFrom].vat && novat === undefined){
        originalPrice = formatCurrency(originalPrice, rounding, currencies[currencyFrom].symbol, prefixCurrencySymbol);

        return '<span title="Original: ' + price + '">' + originalPrice + '<div class="price-ars">' + converted + '</div></span>';
    }else{
        return price + '<div class="price-ars">' + converted + '</div>';
    }

}

function formatCurrency(num, rounding, symbol, prefix) {
	sign = (num == (num = Math.abs(num)));
	num = Math.floor(num * rounding + 0.50000000001);
	cents = num % rounding;

	num = Math.floor(num / rounding).toString();

	if (cents < 10) {
		cents = "0" + cents;
	}

	for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++) {
		num = num.substring(0, num.length - (4 * i + 3)) + ',' +
		                       num.substring(num.length-(4*i+3));
	}

	if (prefix) {
		return (symbol + ((sign)?'':'-') + num + '.' + cents);
	} else {
		return (((sign)?'':'-') + num + '.' + cents + symbol);
	}
}

convertCurrency = function(carrito) {
    switch(carrito){
        case 1:
            if(   jQuery('.a-size-base.a-text-bold:contains(Order summary)').length === 0 &&
                  jQuery('.a-size-base.a-text-bold:contains(Récapitulatif de commande)').length === 0 &&
                  jQuery('.a-size-base.a-text-bold:contains(Riepilogo ordine)').length === 0 &&
                  jQuery('.a-size-base.a-text-bold:contains(Resumen del pedido)').length === 0 &&
                  jQuery('.a-size-base.a-text-bold:contains(Zusammenfassung der Bestellung)').length === 0 &&
                  jQuery('.ap_popover.ap_popover_sprited.snoop-tooltip').length === 0
              ){
                return false;
            }else{
                if(jQuery('#sc-buy-box.price-ars-cart').length === 0){
                    jQuery('#sc-buy-box').addClass('price-ars-cart');
                }else{
                    return false;
                }
            }
            break;
        case 2:
            if( jQuery('.entry.snoop-price:not(.snoop-warning):not(.price-ars-cart)').length === 0 ){
                return false;
            }
            break;
        default:
            break;
    }

    //console.log('Cambiando precios', carrito);

	var currency = currencies[currencyFrom];

    jQuery('.a-column.a-span3.a-text-right.a-span-last.sc-value').removeClass('a-span3').addClass('a-span4');
    jQuery('.a-column.a-span9.sc-text').removeClass('a-span9').addClass('a-span8');
    jQuery('a.a-popover-trigger.a-declarative:contains(Estimated)').html('Shipping & handling <i class="a-icon a-icon-popover"></i>');

    if(carrito == 2){
        jQuery('.entry.snoop-price:not(.snoop-warning)').each(function(){
            var text = jQuery(this).text();
            if( jQuery(this).children().length === 0 && text.indexOf(currency.symbol) != -1 && text.indexOf('ARS') == -1){
                jQuery(this).addClass('price-ars-cart').html( text.replace(currency.priceRegex, appendConversion) );
            }
        });
    }else{
        jQuery('span:not(:has(*))').each(function(){
            var text = jQuery(this).text();
            if( jQuery(this).children().length === 0 && text.indexOf(currency.symbol) != -1 && text.indexOf('ARS') == -1){
                if( jQuery(this).parents('#sc-buy-box').length == 1 ||
                   window.location.href.indexOf("/order-details") > -1 ||
                   window.location.href.indexOf("/order-history") > -1
                  ){
                    jQuery(this).html( text.replace(currency.priceRegex, appendConversionNoVAT) );
                }else{
                    jQuery(this).html( text.replace(currency.priceRegex, appendConversion) );
                }
            }
        });
    }
};

var running_convert_1 = false;
var running_convert_2 = false;
$( document ).ready(function(){

    console.log('Page ready!');
    if (rate === undefined || todayString !== lastRun) {
        fetchCurrencyData(currencyFrom, function() {
            rate = GM_getValue(CURRENCY_RATE + currencyFrom);
            convertCurrency();
        });
    } else {
        console.log('Currency rate: ', rate);
        convertCurrency();
    }

    $('.a-fixed-right-grid-col.a-col-right').bind("DOMSubtreeModified",function(e){
        if(running_convert_1 === false){
            console.log('Auto 1');
            running_convert_1 = true;
            setTimeout(function(){convertCurrency(1); running_convert_1=false;}, 1000);
        }
    });

    $('#priceblock_ourprice').bind("DOMSubtreeModified",function(e){
        if(running_convert_2 === false){
            console.log('Auto 2');
            running_convert_2 = true;
            setTimeout(function(){convertCurrency(2); running_convert_2=false;}, 1000);
        }
    });

    /*
    ////////////////////////////////////////////////////////////////
    PRECIOS DE OTRAS TIENDAS
    ////////////////////////////////////////////////////////////////
    */

    var asin = $('#ASIN').val();
    if (asin === undefined)
        return;
    snoop.initialize(asin);

});
})();

//Various currencies' rates to EUR
window.Rates = {
    timestamp: new Date(),
    'EUR': 1,
    'USD': 0,
    'GBP': 0
};
function refreshRates() {
    var cachedRates = JSON.parse(localStorage.getItem("conversionRates"));
    //console.log(cachedRates);
    if (cachedRates !== null && cachedRates.timestamp !== undefined) {
        cachedRates.timestamp = new Date(cachedRates.timestamp);
        Rates = cachedRates;
        var ageInHours = (new Date() - cachedRates.timestamp) / 1000 / 60 / 60;
        if (ageInHours < 7)
            return;
    }
    console.log('Refreshing conversion rates...');
    GM_xmlhttpRequest({
		method: "GET",
		url: 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml',
		onload: function(responseDetails) {
			var $document = $(responseDetails.responseText);
            for (var rate in Rates) {
                if (typeof rate !== 'string' || rate === 'EUR')
                    continue;
                Rates[rate] = parseFloat($document.find('Cube[currency="' + rate + '"]').attr('rate'));
            }
            Rates.timestamp = new Date();
            localStorage.conversionRates = JSON.stringify(Rates);
		},
		onerror: function(responseDetails) {
			alert("Error fetching currency rates.");
		}
	});
}

var Money = function (amount, currency, currency_symbol, extraAmount) {
    this.amount = amount;
    this.extraAmount = extraAmount;
    this.currency = currency;
    this.currency_symbol = currency_symbol;
    //console.log('Money', this);
};
Money.prototype.for = function (currency, currency_symbol) {
    var rate = Rates[currency] / Rates[this.currency];
    var convertedAmount = this.amount * rate;
    var convertedExtraAmount = this.extraAmount !== undefined ? this.extraAmount * rate : undefined;
    //console.log('Conversion\n', this.currency, '->', currency,
    //  '\n', Rates[this.currency], '->', Rates[currency],
    //  '\n', this.amount, '->', convertedAmount);
    return new Money(convertedAmount, currency, currency_symbol, convertedExtraAmount);
};
Money.prototype.toString = function () {
    if (this.extraAmount === undefined)
        return this.currency_symbol+(this.amount.toFixed(2));
    else
        return this.currency_symbol+(this.amount.toFixed(2)) + ' - ' + this.currency_symbol+(this.extraAmount.toFixed(2));
};

var Shop = function (id, title, domain, base_url, currency, currency_symbol, seller) {
    this.id = id;
    this.title = title;
    this.domain = domain;
    this.base_url = base_url;
    this.url = this.base_url;
    this.currency = currency;
    this.currency_symbol = currency_symbol;
    this.seller = seller;
    this.setAsin = function (asin) {
        this.url = this.urlFor(asin);
    };
    this.urlFor = function (asin) {
        return this.base_url.replace('{asin}', asin);
    };
    this.moneyFrom = function (amount) {
        var culture = this.culture;
        if (amount.indexOf('-') == -1) {
            var sanitizedAmount = amount.replace(/[^\d^,^.]/g, '');
            var regex = /^[\d.]+,[\d]{2}$/;
            var needProperPrice = regex.exec(sanitizedAmount);
            if(needProperPrice) {
                sanitizedAmount = sanitizedAmount.replace(/\./g, '').replace(/,/, '.');
            }else{
                sanitizedAmount = sanitizedAmount.replace(/\,/g, '');
            }
            return new Money(sanitizedAmount, this.currency);
        }
        var sanitizedAmounts = amount.split('-').map(function (a) {
            return a.replace(/[^\d^,^.]/g, '');
        });
        return new Money(sanitizedAmounts[0], this.currency, sanitizedAmounts[1]);
    };
};

var Settings = function (asin) {
    this.asin = asin;
    this.shops = [
        new Shop(1, 'amazon.co.uk', 'www.amazon.co.uk', 'https://www.amazon.co.uk/dp/{asin}?smid=A3P5ROKL5A1OLE&tag=r0f340c-21', 'GBP', '£', 'Dispatched from and sold by Amazon'),
        new Shop(2, 'amazon.de', 'www.amazon.de', 'https://www.amazon.de/dp/{asin}?smid=A3JWKAKR8XB7XF&tag=r0f3409-21', 'EUR', 'EUR ', 'Dispatched from and sold by Amazon|Verkauf und Versand durch Amazon'),
        new Shop(3, 'amazon.fr', 'www.amazon.fr', 'https://www.amazon.fr/dp/{asin}?smid=A1X6FK5RDHNB96&tag=r0f3405-21', 'EUR', 'EUR ', 'Expédié et vendu par Amazon'),
        new Shop(4, 'amazon.es', 'www.amazon.es', 'https://www.amazon.es/dp/{asin}?smid=A1AT7YVPFBWXBL&tag=r0f34-21', 'EUR', 'EUR ', 'Vendido y enviado por Amazon'),
        new Shop(5, 'amazon.it', 'www.amazon.it', 'https://www.amazon.it/dp/{asin}?smid=A11IL2PNWYJU7H&tag=r0f3401-21', 'EUR', 'EUR ', 'Venduto e spedito da Amazon'),
        new Shop(6, 'amazon.com', 'www.amazon.com', 'https://www.amazon.com/dp/{asin}?smid=ATVPDKIKX0DER&tag=r0f34-20', 'USD', '$', 'Ships from and sold by Amazon.com')
    ];
    this.shops.forEach(function (shop) {
        shop.setAsin(asin);
    });

    this.currentShop = this.shops.filter(function (shop) {
        return shop.domain == document.domain;
    })[0];

    this.desiredCurrency = this.currentShop.currency;

    if (this.currentShop.currency != this.desiredCurrency) {
        this.filteredShops = this.shops;
    }
    else {
        this.filteredShops = this.shops.filter(function (shop) {
            return shop.domain != document.domain;
        });
    }
    this.shop = function (id) {
        var shopById = this.shops.filter(function (shop) {
            return shop.id == id;
        });
        if (shopById.length == 1)
            return shopById[0];
        return null;
    };
};

var pageScraper = {
    warning: {
        networkError: 'Error al consultar',
        unavailable: 'No disponible',
        wrongSeller: 'No vendido por Amazon',
        notFound: 'No encontrado',
        multipleOptions: 'Opciones multiples'
    },
    getPriceOn: function (shop, displayPrice, displayWarning) {
        var serverUrl = shop.url;
        var sellerText = shop.seller;
        GM_xmlhttpRequest({
            method: "GET",
            url: serverUrl,
            onload: function(data) {
                var regex = /[nb]\s*?id="priceblock_[\w]*?price".*?>(.*?)</img;
                var price = regex.exec(data.responseText);
                if (price === null || price.length != 2) {
                    displayWarning(pageScraper.warning.unavailable, false);
                    return;
                }
                regex =  new RegExp(sellerText);
                var seller = regex.exec(data.responseText);
                if (seller === null) {
                    displayWarning(pageScraper.warning.wrongSeller, false);
                    return;
                }
                displayPrice(price[1]);
            },
            onerror: function(data) {
                if (data.status == 404)
                    displayWarning(pageScraper.warning.notFound, true);
                else
                    displayWarning(pageScraper.warnings.networkError, false);
            }
        });
    }
};

var tooltip = {
    _mouseIsOnIcon: false,
    _mouseIsOnTooltip: false,
    registerShowHideHandlers: function () {
        this._genericRegisterShowHideHandlers($('.snoop-tooltip'), function (on) {
            tooltip._mouseIsOnTooltip = on;
        });
        this._genericRegisterShowHideHandlers($('#snoop-icon'), function (on) {
            tooltip._mouseIsOnIcon = on;
        });
    },
    _genericRegisterShowHideHandlers: function ($selector, isOn) {
        $selector.mouseenter(function () {
            $('.snoop-tooltip').show();
            isOn(true);
        }).mouseleave(function () {
            isOn(false);
            setTimeout(function () {
                if (!tooltip._mouseIsOnIcon && !tooltip._mouseIsOnTooltip)
                    $('.snoop-tooltip').hide();
            }, 100);
        });
    }
};
var tooltipML = {
    _mouseIsOnIcon: false,
    _mouseIsOnTooltip: false,
    registerShowHideHandlers: function () {
        this._genericRegisterShowHideHandlers($('.snoop-tooltip-ml'), function (on) {
            tooltipML._mouseIsOnTooltip = on;
        });
        this._genericRegisterShowHideHandlers($('#snoop-icon-ml'), function (on) {
            tooltipML._mouseIsOnIcon = on;
        });
    },
    _genericRegisterShowHideHandlers: function ($selector, isOn) {
        $selector.mouseenter(function () {
            $('.snoop-tooltip-ml').show();
            isOn(true);
        }).mouseleave(function () {
            isOn(false);
            setTimeout(function () {
                if (!tooltipML._mouseIsOnIcon && !tooltipML._mouseIsOnTooltip)
                    $('.snoop-tooltip-ml').hide();
            }, 100);
        });
    }
};

var tooltipTemplate = '<div class="ap_popover ap_popover_sprited snoop-tooltip" surround="6,16,18,16" tabindex="0" style="z-index: 200; width: 375px;"><div class="ap_header"><div class="ap_left"></div>'+
    '<div class="ap_middle"></div><div class="ap_right"></div></div><div class="ap_body"><div class="ap_left"></div><div class="ap_content" style="padding-left: 17px; padding-right: 17px; padding-bottom: 8px; ">'+
    '<div class="tmm_popover" >{{#shops}}<div class="entry title" style=""><span id="snoop-shop-{{id}}" class="entry snoop-price"><img class="snoop-loader" src="{{loader_url}}" /></span>'+
    '<span class="snoop-on"> en </span><a href="{{base_url}}&snoop-from={{from_shop}}&snoop-from-asin={asin}" class="snoop-link">{{title}}</a></div>{{/shops}}</div></div><div class="ap_right"></div></div>'+
    '<div class="ap_footer"><div class="ap_left"></div><div class="ap_middle"></div><div class="ap_right"></div></div></div>';

var page = {
    addTooltipToPage: function (tooltipMarkup) {
        var $placeholderMarkup = $('<img id="snoop-placeholder" src="https://i.imgur.com/7vqGfyT.png" alt="Placeholder" />');
        var $imageMarkup = $('<img id="snoop-icon" src="https://i.imgur.com/lTWMEoH.png" />');
        var $imageMarkupMELI = $('<img id="snoop-icon-ml" src="https://i.imgur.com/mxQjoLn.png" />');
        var $container = this.findAppropriateTooltipContainer();
        var tooltipTemplateML = '<div class="ap_popover ap_popover_sprited snoop-tooltip-ml" surround="6,16,18,16" tabindex="0" style="z-index: 200; width: 700px;"><div class="ap_header"><div class="ap_left"></div>'+
            '<div class="ap_middle"></div><div class="ap_right"></div></div><div class="ap_body"><div class="ap_left"></div><div class="ap_content" style="padding-left: 17px; padding-right: 17px; padding-bottom: 8px; ">'+
            '<div class="tmm_popover"><img class="snoop-loader" src="https://i.imgur.com/Dp92MjH.gif" /> Cargando...</div></div><div class="ap_right"></div></div><div class="ap_footer"><div class="ap_left"></div><div class="ap_middle"></div><div class="ap_right"></div></div></div>';
        $container.after($imageMarkupMELI);
        $container.after(tooltipTemplateML);
        $container.after($imageMarkup);
        $container.after(tooltipMarkup);
        tooltip.registerShowHideHandlers();
        tooltipML.registerShowHideHandlers();
        convertCurrency();
    },
    findAppropriateTooltipContainer: function () {
        var $tries = [
            $('table.product .priceLarge:first', $('#priceBlock')),
            $('#priceblock_ourprice'),
            $('#priceblock_saleprice'),
            $('#availability_feature_div > #availability > .a-color-price'),
            $('div.buying span.availGreen', $('#handleBuy')),
            $('div.buying span.availRed:nth-child(2)', $('#handleBuy'))
        ];
        for (var i = 0; i < $tries.length; i++) {
            if ($tries[i].length > 0)
                return $tries[i];
        }
        throw new Error('Unable to find the price section.');
    },
    displayPrice: function ($shopInfo, price) {
        var convertedPrice = price.for(settings.currentShop.currency, settings.currentShop.currency_symbol);
        $shopInfo.text(convertedPrice.toString());
        convertCurrency();
    },
    displayWarning: function ($shopInfo, warning, addNotFoundClass) {
        $shopInfo.text(warning).addClass('snoop-warning');
        if (addNotFoundClass)
            $shopInfo.parent().addClass('snoop-not-found');
    },
    registerInitializationHandler: function (shops) {
        $('#snoop-icon').mouseover(function () {
            if (window.snoop_tooltipInitialized !== undefined && window.snoop_tooltipInitialized !== false)
                return;
            window.snoop_tooltipInitialized = true;
            $.each(shops, function (index, shop) {
                var $shopInfo = $('#snoop-shop-' + shop.id);
                pageScraper.getPriceOn(shop, function (price) {
                    page.displayPrice($shopInfo, shop.moneyFrom(price));
                }, function (warning, addNotFoundClass) {
                    page.displayWarning($shopInfo, warning, addNotFoundClass);
                });
            });
        });
        $('#snoop-icon-ml').mouseover(function () {
            if (window.snoopML_tooltipInitialized !== undefined && window.snoopML_tooltipInitialized !== false)
                return;
            window.snoopML_tooltipInitialized = true;
            var productName = decodeURI(jQuery('#productTitle').html().replace('&nbsp;', ' ').replace(/[^\w\d\s\.]/g, ' ').trim());
            meli.showPrices(productName);
        });
    }
};

var settings;
var snoop = {
    tooltip: null,
    asin: null,
    _startMonitoringAsin: function () {
        var observer = new MutationObserver(function (mutations) {
            var asinHasProbablyChanged = mutations.some(function (mutation) {
                return mutation.addedNodes.length > 0;
            });
            if (!asinHasProbablyChanged)
                return;
            var newAsin = $('#ASIN').val();
            if (snoop.asin == newAsin)
                return;
            snoop.run(newAsin);
        });
        observer.observe($('#buybox_feature_div')[0], { attributes: true, subtree: true, childList: true, characterData: true });
    },
    initialize: function (asin) {
        this.asin = asin;
        this._startMonitoringAsin();
        refreshRates();
        settings = new Settings(asin);
        snoop.tooltip = Mustache.to_html(tooltipTemplate, {
                shops: settings.filteredShops,
                from_shop: settings.currentShop.id,
                from_asin: settings.asin,
                loader_url: 'https://i.imgur.com/Dp92MjH.gif'
        });
        snoop.run(asin);
    },
    run: function (asin) {
        this.asin = asin;
        settings = new Settings(asin);
        window.snoop_tooltipInitialized = false;
        window.snoopML_tooltipInitialized = false;
        var ensureTooltipHasBeenLoaded = function () {
            if (snoop.tooltip === null) {
                setTimeout(ensureTooltipHasBeenLoaded, 50);
            }
            else {
                var tooltipMarkup = snoop.tooltip.replace(/{asin}/gm, settings.asin);
                page.addTooltipToPage(tooltipMarkup);
                page.registerInitializationHandler(settings.filteredShops);
            }
        };
        ensureTooltipHasBeenLoaded();
    }
};

Number.prototype.formatMoney = function(c, d, t){
    var n = this;
    c = isNaN(c = Math.abs(c)) ? 2 : c;
    d = d === undefined ? "." : d;
    t = t === undefined ? "," : t;
    var s = n < 0 ? "-" : "",
    i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
    j = (j = i.length) > 3 ? j % 3 : 0;
   return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
};

var meli = {
    showPrices: function(productName) {
        meli.fetchApiData(productName, meli.showProducts);
    },
    showProducts: function (data){
        var meliProducts = $('.snoop-tooltip-ml .tmm_popover');
        meliProducts.html('<div class="entry title" style="font-size:10px"><b>Buscando por:</b> '+data.query+'</div>');
        //console.log(data);
        if(data.results.length === 0){
            meliProducts.append('<div class="entry title">No se encontraron productos en MercadoLibre con esta búsqueda.</div>');
        }
        data.results.forEach(function(product) {
            meliProducts.append('<div class="entry title"><div class="snoop-price" style="width:130px;display:inline-block;text-align:right;"><div class="price-ars">ARS $'+product.price.formatMoney(2)+'</div></div><span class="snoop-on"> &raquo; </span><a href="'+product.permalink+'" target="_blank" class="snoop-link">'+product.title+'</a></div>');
        });
    },
    fetchApiData: function (productName, callback) {
        GM_xmlhttpRequest({
            method: "GET",
            url: "https://api.mercadolibre.com/sites/MLA/search?q=" + encodeURI(productName) + "&condition=new",
            onload: function(responseDetails) {
                var api = JSON.parse(responseDetails.responseText);
                callback(api);
            },
            onerror: function(responseDetails) {
                alert("Error fetching API from MELI");
            }
        });
    }
};