(function () {
    var jQ;
    var fxecConfig = {
        gridselector: "#fxst_grid",
        filterselector: "#fxst_filter",
        host: "https://calendar.fxstreet.com",
        statichost: "https://az687397.vo.msecnd.net",
        frozenmountainhost: "https://sync3.frozenmountain.com/client.js?v=3.5.0",
        pushUpdaterChannel: "/EconomicCalendarPro/EventDateUpdate",
        defaultCountryCodes: "BE,IN,GR,CH,ZA,HU,RU,CL,BR,ID,FR,ES,IT,IE,EE,RO,QA,JP,EMU,NZ,CA,PL,TR,CN,HK,LT,CZ,KR,DK,IS,CO,FI,AU,PE,AE,PT,LV,NO,DE,AR,MX,US,UK,SE,SK,AT,SG,NL",
        culture: 'en-US',
        tabs: "News,Reports,Blogs,History,Webinar,LiveCoverage,OlsenScale,Autochartist",
        timezone: "UTC",
        rowsfeatures: 10,
        showcountrylink: 1,
        showeventlink: 1,
        countdownFormat: "{hnn}:{mnn}",
        countrycode: "BE,IN,GR,CH,ZA,HU,RU,CL,BR,ID,FR,ES,IT,IE,EE,RO,QA,JP,EMU,NZ,CA,PL,TR,CN,HK,LT,CZ,KR,DK,IS,CO,FI,AU,PE,AE,PT,LV,NO,DE,AR,MX,US,UK,SE,SK,AT,SG,NL",
        isSecure: function () { return window.location.protocol === "https:"; },
        eventurl: "./event.aspx?id=",
        countryurl: "./country.aspx?id=",
        newsurl: "/news/forex-news/article.aspx?storyid=",
        version: "0.0.2",
        staticContentServerRefresh: "201612291331",
        css: function () { return getVersionParameterValue(versionConfig.getDefaultCss); }
    },
    versionConfig = {
        mainVersion: "0.0.1",
        responsiveVersion: "0.0.2",
        getMainUrl: "GETMAINURL",
        getDefaultCss: "GETDEFAULTCSS",
        getCheckMark: "GETCHECKMARK"
    },
    checkUrl = fxecConfig.statichost + "/calendarwidget-img/check.png",
    fxStore = {
        hasLS: (function () {
            try {
                return window.localStorage ? true : false;
            }
            catch (err) {
                return false;
            }
        }()),
        set: function (key, value, expires) {
            var objToSave = {}, expiration = new Date(),
			path = window.location.pathname, pathParts;
            if (!key || !value || typeof key !== "string") {
                return false;
            }
            if (expires && typeof expires === "number") {
                expiration.setHours(0, 0, 0, 0);
                expiration.setDate(expiration.getDate() + expires);
                objToSave.expires = expiration;
            }
            if (!fxStore.hasLS) {
                pathParts = path.split("/");
                //mirem si estem en un document final (p.e: algo.htm) o en un path normal
                if (path.charAt(path.length - 1) !== "/" && pathParts[pathParts.length - 1].indexOf(".") !== -1) {
                    pathParts.splice(pathParts.length - 1, 1);
                    path = pathParts.join("/") + "/";
                }
                document.cookie = key + "=" + escape(JSON.stringify(value)) + (expires ? "; expires=" + expiration.toUTCString() : "") + "; path=" + path;
            }
            else {
                objToSave.value = value;
                window.localStorage.setItem(key, JSON.stringify(objToSave));
            }
            return true;
        },
        get: function (key) {
            var stored, expirity, i, cookieValue, cookieName,
			cookies = document.cookie.split(";"),
			cookiesLength = cookies.length;
            if (!key || typeof key !== "string") {
                return undefined;
            }
            if (fxStore.hasLS) {
                stored = JSON.parse(window.localStorage.getItem(key));
                if (stored && stored.value) {
                    if (stored.expires) {
                        expirity = new Date(stored.expires);
                        if (expirity < new Date()) {
                            fxStore.remove(key);
                            return undefined;
                        }
                    }
                    return stored.value;
                }
            }
            else {
                for (i = 0; i < cookiesLength; i++) {
                    cookieValue = unescape(cookies[i].substr(cookies[i].indexOf("=") + 1));
                    if (cookieValue) {
                        cookieName = cookies[i].substr(0, cookies[i].indexOf("="));
                        cookieName = cookieName.replace(/^\s+|\s+$/g, "");
                        if (cookieName === key) {
                            return JSON.parse(cookieValue);
                        }
                    }
                }
            }
            return undefined;
        },
        remove: function (key) {
            if (!key || typeof key !== "string") {
                return false;
            }
            if (fxStore.hasLS) {
                window.localStorage.removeItem(key);
            }
            else {
                document.cookie = key + "=; expires=-1; path=" + window.location.pathname;
            }
            return true;
        }
    },
    getVersionParameters = function () {

        var parameters = [];

        parameters[versionConfig.getMainUrl + versionConfig.mainVersion] = "/EventDateWidget/GetMain";
        parameters[versionConfig.getDefaultCss + versionConfig.mainVersion] = "default";

        parameters[versionConfig.getCheckMark + versionConfig.mainVersion] = '<img src=\"' + checkUrl + '\" title=\"Checkmark\" alt=\"Done\" width=\"16\" height=\"16\" />';
        parameters[versionConfig.getCheckMark + versionConfig.responsiveVersion] = '<i class="fa fa-check"></i>';

        parameters[versionConfig.getMainUrl + versionConfig.responsiveVersion] = "/EventDateWidget/GetMainResponsive";
        parameters[versionConfig.getDefaultCss + versionConfig.responsiveVersion] = "default-responsive";

        var result = parameters;
        return result;

    },
    getVersionParameterValue = function (key) {

        var parameters = getVersionParameters();
        var ver = fxecConfig.version;

        var result = parameters[key + ver];
        return result;

    },
    loading = "",
    //objecte per fer cache
    fxstCache = {
        //per cachejar fem fxstCache.set("guidPerExemple","resposta d'un ajax, per exemple")
        //opcionalment podem posar un temps de vida en segons
        //exemple d'us:
        //fxstCache.set("EURUSD_FusionChartsData", data, 1800);
        set: function (key, value, expires) {
            expires = (expires || 3600) * 1000; //default: 1h
            fxstCache[key].value = value;
            fxstCache[key].expires = expires + (new Date().getTime());
        },
        //recuperem algo de cache
        //exemple d'us:
        //fxstCache.get("EURUSD_FusionChartsData");
        get: function (key) {
            if (fxstCache[key]) {
                //si no ha passat el temps màxim retornem
                if (fxstCache[key].expires > (new Date().getTime())) {
                    return fxstCache[key];
                }
                //si ens hem passat de temps, esborrem
                delete fxstCache[key];
                return false;
            }
            return false;
        }
    },
    findItem = function (id) {
        var r = null;
        jQ("#fxst-calendartable").find("tbody tr").each(function (index, row) {
            if (jQ(row).data("eventdateid") === id) {
                r = jQ(row);
                return;
            }
        });
        return r;
    },
    getparams = function (serialize) {
        var data = {},
            start = jQ("#fxst-filter").data("start"),
            end = jQ("#fxst-filter").data("end"),
            keyword = jQ("#fxit-keyword").val() || "",
            advlink = jQ("#fxit-advlink"),
            //necessitem un datepicker per el format de data, agafem un qualsevol, tots tenen la mateixa config
            instance = jQ("#fxit-start-advanced").data("datepicker"),
            date, date1, date2,
            volatility = jQ('#fxst-volatility').slider("option", "value");

        if (!serialize) {
            data.timezone = fxecConfig.timezone;
            // Number of eventdates to display, or if it's 0, the whole calendar till next friday (next friday if it's friday or weekend)
            data.rows = fxecConfig.rows;
            // View Type
            data.view = fxecConfig.view || "current";
            //  Fechas
        }
        else {
            data.shortcut = jQ(".fxit-prefiltered-date.fxst-selected").data("typefilter");
        }
        if (!start && end) {
            date = jQ.datepicker.parseDate('yymmdd', end, instance.settings);
            data.end = jQ.datepicker.formatDate('yymmdd', date, instance.settings);
            data.start = data.end;
            if (!serialize) {
                data.view = "range";
            }
        } else if (start && !end) {
            date = jQuery.datepicker.parseDate('yymmdd', start, instance.settings);
            data.start = jQ.datepicker.formatDate('yymmdd', date, instance.settings);
            data.end = data.start;
            if (!serialize) {
                data.view = "range";
            }
        } else if (start && end) {
            date1 = jQ.datepicker.parseDate('yymmdd', start, instance.settings);
            date2 = jQ.datepicker.parseDate('yymmdd', end, instance.settings);
            //  Rango maximo de 1 año TODO: esto igual deberia ser configurable
            if (Math.abs((date1 - date2) / 1000 / 60 / 60 / 24) > 366) {
                alert(resources.InvalidFilterRange);
                return;
            }
            data.start = jQ.datepicker.formatDate('yymmdd', date1, instance.settings);
            data.end = jQ.datepicker.formatDate('yymmdd', date2, instance.settings);
            if (!serialize) {
                data.view = "range";
            }
        }
        //
        //  Keyword
        //
        if (advlink.hasClass("fxst-advlink-hide") && keyword.length < 3 && keyword.length > 0) {
            alert(resources.InvalidFilterKeyword);
            return;
        }
        if (keyword) {
            data.keyword = keyword;
        }
        //
        //  Array de countries
        //
        data.countrycode = [];
        // lo que hi ha seleccionat al filtre pel que fa a countries és 
        // o lo que ens passen al fxec_config o lo que tingui a la cookie (si en té)
        // sent més important la cookie que lo que ens passin al fxec_config
        jQ("li.fxst-country input:checked").each(function () {
            data.countrycode.push(jQ(this).val());
        });
        if (data.countrycode.length) {
            data.countrycode = data.countrycode.join();
        }
        else {
            delete data.countrycode;
        }
        //
        //  Array de categories
        //
        data.categories = [];
        jQ("li.fxst-category input:checked").each(function () {
            data.categories.push(jQ(this).val());
        });
        if (data.categories.length) {
            data.categories = data.categories.join();
        }
        else {
            delete data.categories;
        }
        //
        //  Volatility
        //
        data.volatility = typeof volatility !== "number" ? 0 : volatility;
        if (!serialize) {
            data.culture = fxecConfig.culture;
        }
        //columns
        if (fxecConfig.columns && !serialize) {
            data.columns = fxecConfig.columns;
        }

        if (data.view === "Day" || data.view === "Month") {
            data.start = data.start || fxecConfig.start;
            data.end = data.end || fxecConfig.end;
        }

        return data;
    },
    setparams = function (formData) {
        var dateFormat, today = new Date(), tomorrow, week, nextweek;
        if (formData.shortcut) {
            jQ(".fxit-prefiltered-date.fxst-selected").removeClass("fxst-selected");
            jQ(".fxit-prefiltered-date[data-typefilter='" + formData.shortcut + "']").addClass("fxst-selected");
        }
        if (formData.keyword) {
            jQ("#fxit-keyword").val(formData.keyword);
        }
        if (formData.start && formData.end) {
            if (formData.shortcut) {
                switch (formData.shortcut) {
                    case "today":
                        formData.start = jQ.datepicker.formatDate("yymmdd", today);
                        formData.end = jQ.datepicker.formatDate("yymmdd", today);
                        break;
                    case "tomorrow":
                        tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
                        formData.start = jQ.datepicker.formatDate("yymmdd", tomorrow);
                        formData.end = jQ.datepicker.formatDate("yymmdd", tomorrow);
                        break;
                    case "thisweek":
                        week = new Date(today.getFullYear(), today.getMonth(), today.getDate() - today.getDay());
                        formData.start = jQ.datepicker.formatDate("yymmdd", week);
                        formData.end = jQ.datepicker.formatDate("yymmdd", new Date(week.getFullYear(), week.getMonth(), week.getDate() + 6));
                        break;
                    case "nextweek":
                        nextweek = new Date(today.getFullYear(), today.getMonth(), (today.getDate() - today.getDay()) + 7);
                        formData.start = jQ.datepicker.formatDate("yymmdd", nextweek);
                        formData.end = jQ.datepicker.formatDate("yymmdd", new Date(nextweek.getFullYear(), nextweek.getMonth(), nextweek.getDate() + 6));
                        break;
                }
            }
            dateFormat = jQ("#fxit-start-advanced").data("datepicker").settings.dateFormat;
            jQ("#fxit-start-advanced").val(jQ.datepicker.formatDate(dateFormat || 'mm/dd/yy', new Date(jQ.datepicker.parseDate("yymmdd", formData.start))));
            jQ("#fxit-end-advanced").val(jQ.datepicker.formatDate(dateFormat || 'mm/dd/yy', new Date(jQ.datepicker.parseDate("yymmdd", formData.end))));
            jQ("#fxit-start-custom").val(jQ.datepicker.formatDate(dateFormat || 'mm/dd/yy', new Date(jQ.datepicker.parseDate("yymmdd", formData.start))));
            jQ("#fxit-end-custom").val(jQ.datepicker.formatDate(dateFormat || 'mm/dd/yy', new Date(jQ.datepicker.parseDate("yymmdd", formData.end))));
            jQ("#fxst-filter").data("start", formData.start);
            jQ("#fxst-filter").data("end", formData.end);
        }
        if (formData.countrycode) {
            jQ("li.fxst-country input").removeAttr("checked").each(function (index, item) {
                if (formData.countrycode.indexOf(item.value) !== -1) {
                    jQ(item).prop('checked', true);
                }
            });
        }
        if (formData.categories) {
            jQ("li.fxst-category input").removeAttr("checked").each(function (index, item) {
                if (formData.categories.indexOf(item.value) !== -1) {
                    jQ(item).prop('checked', true);
                }
            });
        }
        if (formData.volatility) {
            jQ('#fxst-volatility').slider("option", "value", formData.volatility);
        }
    },
    // test var

    getdata = function () {
        var
        advlink = jQ("#fxit-advlink"),
        advfilter = jQ("#fxst-advfilter"),
        //si ens naveguen un event directe, el mostrem obert
        re = new RegExp("id=({{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})"),
        m = re.exec(window.location.search);
        //
        //  Ocultar el filtro avanzado
        //

        advlink.removeClass("fxst-advlink-hide");
        advlink.addClass("fxst-advlink-normal");
        advlink.text(resources.ShowFilters);
        advfilter.hide();
        //
        //  Llamada ajax
        //
        jQ(fxecConfig.gridselector).empty();
        jQ(fxecConfig.gridselector).append(loading);
        jQ.ajax({
            url: fxecConfig.host + getVersionParameterValue(versionConfig.getMainUrl),
            data: getparams(),
            dataType: "jsonp"
        }).done(function (data) {
            jQ(fxecConfig.gridselector).empty();
            jQ(fxecConfig.gridselector).append(data.Html);

            jQ(".fxit-countryurl").each(function (index, item) {
                jQ(item).attr("href", fxecConfig.countryurl + jQ(item).data("idcountry"));
            });

            jQ(".fxit-eventurl").each(function (index, item) {
                jQ(item).attr("href", fxecConfig.eventurl + jQ(item).data("idevent"));
            });

            //fem que els clicks als events/banderes no facin res si són amb 
            //el click esquerre
            jQ(document).on("click", ".fxit-noleftclick", function (event) {
                if (event.which === 1) {//left click
                    event.preventDefault();
                }
            });
            //si hi ha algo al querystring amb pinta de GUID, mostrem l'event que correspongui obert
            if (m) {
                var eventTarget = jQ("tr.fxit-eventrow[data-eventdateid='" + m[1].toString().toLowerCase() + "']");
                eventTarget.trigger("click", false);
                if (eventTarget.length > 0) {
                    scrollTo(0, eventTarget.offset().top);
                }
            }

            jQ(".fxit-countdown").each(function (index, item) {
                var date = jQ(item).data("countdown") + "";
                jQ(item).countdown({
                    layout: fxecConfig.countdownFormat,
                    until: new Date(date.substring(0, 4), date.substring(4, 6) - 1, date.substring(6, 8), date.substring(8, 10), date.substring(10, 12), date.substring(12, 14)),
                    compact: true,
                    format: "hM",
                    expiryText: '<span class="icon i-loading-s2"></span>',
                    timezone: 0
                });
            });
            //posar ticks a les columnes on el event ja hagi passat
            if (fxecConfig.countdownFormat !== "{hnn}:{mnn}") {
                jQ(".fxst-i-ok.fxst-icon").parents("td").attr("align", "center").html("<img src=\"" + checkUrl + "\" title=\"Checkmark\" alt=\"Done\" width=\"16\" height=\"16\" />");
            }

        });
    },
    //variable per parsejar la versió de jQuery
    version,
    keyCalConf;
    //TODO: mirar de limitar la quantitat de ronya que fiquem a la cache
    //potser borrar-la periòdicament
    if (typeof fxcalendar_config !== "undefined") {
        for (keyCalConf in fxcalendar_config) {
            if (fxcalendar_config.hasOwnProperty(keyCalConf)) {
                fxecConfig[keyCalConf] = fxcalendar_config[keyCalConf];
            }
        }
    };

    //carreguem les css
    asyncLoadcss("https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css");
    asyncLoadcss(fxecConfig.statichost + "/calendarwidget-css/jquery-ui.css");
    asyncLoadcss(fxecConfig.statichost + "/calendarwidget-css/" + fxecConfig.css() + ".css?" + fxecConfig.staticContentServerRefresh);
    asyncLoadcss(fxecConfig.statichost + "/calendarwidget-css/c3.min.css");
    //async_loadcss(fxec_config.host + "/Content/" + getVersionParameterValue(versionConfig.getDefaultCss) + ".css");
    asyncLoadjs(fxecConfig.host + "/scripts/resources/?culture=" + fxecConfig.culture,
        function () {
            fxecConfig.countryurl = fxecConfig.countryurl || resources.Default_Calendar_Link + "countries?id=";
            fxecConfig.eventurl = fxecConfig.eventurl || resources.Default_Calendar_Link + "event.aspx?id=";

            loading = "<span class='fxec_loading2'>" + resources.Loading + "</span>";

            if (typeof jQuery === "undefined") {
                asyncLoadjs(fxecConfig.statichost + "/calendarwidget-js/jquery-1.11.1.min.js", function () {
                    jQ = jQuery;
                    jQueryUILoad();
                });
            }
            else {
                jQ = jQuery;
                version = +(jQuery().jquery.replace(/\./g, ''));
                if (version >= 152) {
                    jQueryUILoad();
                }
                else {
                    alert(resources.JQueryRequired);
                }
            }
        });
    asyncLoadjs(fxecConfig.statichost + "/calendarwidget-js/c3.min.js");
    asyncLoadjs(fxecConfig.statichost + "/calendarwidget-js/d3.min.js");

    function jQueryUILoad() {
        if (!jQuery.ui) {
            asyncLoadjs(fxecConfig.statichost + "/calendarwidget-js/jquery-ui.min-1.9.2.js", function () {
                jsonLoad();
            });
        }
        else {
            jsonLoad();
        }
    };

    function jsonLoad() {
        if (typeof JSON === 'undefined') {
            asyncLoadjs(fxecConfig.statichost + "/calendarwidget-js/json2.js", function () {
                countdownLoad();
            });
        }
        else {
            countdownLoad();
        }
    };

    function countdownLoad() {
        if (typeof Countdown === 'undefined') {
            asyncLoadjs(fxecConfig.statichost + "/calendarwidget-js/jquery.countdown.js", function () {
                postLoad();
            });
        }
        else {
            postLoad();
        }
    };

    function postLoad() {
        var currentEventDetail;
        jQ(document).ready(function () {
            if (resources.Culture !== "en-US") {
                asyncLoadjs(fxecConfig.statichost + "/calendarwidget-js/ui.datepicker-" + resources.Language + ".js");
            }

            //  Si el cliente cambia el timezone
            jQ(document).on("timezonechanged", fxecConfig.gridselector, function (event, timezone) {
                fxecConfig.timezone = timezone;
                getdata();
            });

            var getCalendarUrl = function (format) {
                var params = getparams();
                var url = fxecConfig.host + "/eventdate/?f=" + format + "&v=2&" + jQ.param(params);
                return url;
            }

            var downloadFile = function (url) {
                jQ("body").append("<iframe src='" + url + "' style='display: none;' ></iframe>");
            }

            jQ(document).on("exportcsv", fxecConfig.gridselector, function () {
                var url = getCalendarUrl('csv');
                downloadFile(url);
            });

            //jQ(document).on("downloadics", fxecConfig.gridselector, function () {
            //    var url = getCalendarUrl('ics');
            //    downloadFile(url);
            //});

            //jQ(document).on("linktooutlook", fxecConfig.gridselector, function () {
            //    var url = getCalendarUrl('ics');
            //    url = url.replace(/.*:\/\/(.*)/g, 'webcal://$1');
            //    downloadFile(url);
            //});

            //jQ(document).on("linktogooglecalendar", fxecConfig.gridselector, function () {
            //    var icsUrl = getCalendarUrl('ics');
            //    var googleCalendarLink = 'http://www.google.com/calendar/render?cid=' + icsUrl;
            //    downloadFile(googleCalendarLink);
            //});

            jQ("#fxst_grid, #fxst_filter").addClass("fxst-gnral");

            //keyboard shortcuts
            jQ(document).on("keypress", function (event) {
                var key = String.fromCharCode(event.which),
                highlightedEvent = jQ(".fxst-keyshortcut"),
                eventList = jQ(".fxit-eventrow");
                switch (key) {
                    case "n":
                    case "N":
                        if (highlightedEvent.length) {
                            highlightedEvent.removeClass("fxst-keyshortcut");
                            highlightedEvent.nextAll(".fxit-eventrow").first().addClass("fxst-keyshortcut");
                        }
                        else {
                            eventList.first().addClass("fxst-keyshortcut");
                        }
                        break;
                    case "p":
                    case "P":
                        if (highlightedEvent.length) {
                            highlightedEvent.removeClass("fxst-keyshortcut");
                            highlightedEvent.prevAll(".fxit-eventrow").first().addClass("fxst-keyshortcut");
                        }
                        else {
                            eventList.last().addClass("fxst-keyshortcut");
                        }
                        break;
                    case "o":
                    case "O":
                    case "\r":
                        if (highlightedEvent.length) {
                            //REFACTOR:
                            //molt lleig, ho deixo així de moment, però haurem de posar
                            //la funcionalitat d'expandir una row en una funció i cridar-la
                            //des d'aquí i desde el $("tr.fxit-eventrow").click()
                            highlightedEvent.trigger("click");
                        }
                        break;
                }
            });

            jQ.ajax({
                url: fxecConfig.host + "/FilterWidget/GetAsync?culture=" + fxecConfig.culture,
                dataType: "jsonp"
            }).done(function (data) {
                var settings = fxStore.get("FXstCalendarSettings"),
                    datePickerUtils = function (selectedDate, instance, inputSel, classSubfix) {
                        var date, start, end,
                            startAdv = jQ("#fxit-start-advanced"), endAdv = jQ("#fxit-end-advanced"),
                            startCustom = jQ("#fxit-start-custom"), endCustom = jQ("#fxit-end-custom");
                        selectedDate = selectedDate || jQ(this).val();
                        instance = instance || jQ(this).data("datepicker");
                        if (!selectedDate) {
                            return;
                        }
                        date = jQ.datepicker.parseDate(instance.settings.dateFormat || jQ.datepicker._defaults.dateFormat, selectedDate, instance.settings);
                        //marquem el custom dates dels prefiltres com a selected
                        jQ(".fxit-prefiltered-date.fxst-selected").removeClass("fxst-selected");
                        jQ(".fxit-prefiltered-date").last().addClass("fxst-selected");
                        //ens han picat a start
                        if (inputSel.hasClass("fxit-start")) {
                            start = date;
                            //agafem l'end date que hi hagi a l'advanced o al custom, depenent de quin estiguin fent servir
                            end = classSubfix === "advanced" ? endAdv.datepicker("getDate") : jQ.datepicker.parseDate(instance.settings.dateFormat || jQ.datepicker._defaults.dateFormat, endCustom.val(), instance.settings);
                            //si no hi havia res al input d'end
                            if (!end) {
                                //posem la data escollida als ends
                                endAdv.datepicker("setDate", date);
                                endCustom.val(selectedDate);
                                end = date;

                            }
                                //si hi havia algo a end, si és anterior al nou start, canviem l'end
                            else if (date > end) {
                                endAdv.datepicker("setDate", date);
                                endCustom.val(inputSel.val());
                                inputSel.trigger("blur");
                                end = start;
                            }
                            //actualitzem el start del datepicker que no s'ha tocat
                            if (classSubfix === "advanced") {
                                startCustom.val(selectedDate);
                            }
                            else {
                                startAdv.datepicker("setDate", start);
                                //quan estem al custom i posem una data, canviem al input d'end automàticament
                                endCustom.focus();
                            }
                        } else {
                            end = date;
                            //agafem el start date que hi hagi a l'advanced o al custom, depenent de quin estiguin fent servir
                            start = classSubfix === "advanced" ? startAdv.datepicker("getDate") : jQ.datepicker.parseDate(instance.settings.dateFormat || jQ.datepicker._defaults.dateFormat, startCustom.val(), instance.settings);
                            //si no hi havia res al input de start
                            if (!start) {
                                //posem la data escollida als starts
                                startAdv.datepicker("setDate", date);
                                startCustom.val(selectedDate);
                                start = date;
                            }
                                //si hi havia algo a start, si és posterior al nou end, canviem l'start
                            else if (date < start) {
                                startAdv.datepicker("setDate", date);
                                startCustom.val(inputSel.val());
                                inputSel.trigger("blur");
                                start = end;
                            }
                            //actualitzem el end del datepicker que no s'ha tocat
                            if (classSubfix === "advanced") {
                                endCustom.val(selectedDate);
                            }
                            else {
                                endAdv.datepicker("setDate", end);
                                //quan estem al custom i posem una data, canviem al input d'start automàticament
                                startCustom.focus();
                            }
                        }
                        jQ("#fxst-filter").data("start", jQ.datepicker.formatDate('yymmdd', start, instance.settings));
                        jQ("#fxst-filter").data("end", jQ.datepicker.formatDate('yymmdd', end, instance.settings));
                    };
                jQ(fxecConfig.filterselector).append(data.Html);

                //prefilters
                jQ(document).on("click", ".fxit-prefiltered-date", function (event) {
                    var element = jQ(this), type = element.data("typefilter"),
                    startAdv = jQ("#fxit-start-advanced"), endAdv = jQ("#fxit-end-advanced"),
                    filterCustom = jQ("#fxit-custom-div"),
                    nextweek, newStart, newEnd,
                    today = new Date(), tomorrow, week;
                    event.preventDefault();
                    jQ(".fxit-prefiltered-date.fxst-selected").removeClass("fxst-selected");
                    element.addClass("fxst-selected");
                    switch (type) {
                        case "today":
                            newStart = jQ.datepicker.formatDate(startAdv.data("datepicker").settings.dateFormat || jQ.datepicker._defaults.dateFormat, today);
                            startAdv.val(newStart);
                            endAdv.val(newStart);
                            jQ("#fxst-filter").data("start", jQ.datepicker.formatDate("yymmdd", today));
                            jQ("#fxst-filter").data("end", jQ.datepicker.formatDate("yymmdd", today));
                            break;
                        case "tomorrow":
                            tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
                            newStart = jQ.datepicker.formatDate(startAdv.data("datepicker").settings.dateFormat || jQ.datepicker._defaults.dateFormat, tomorrow);
                            startAdv.val(newStart);
                            endAdv.val(newStart);
                            jQ("#fxst-filter").data("start", jQ.datepicker.formatDate("yymmdd", tomorrow));
                            jQ("#fxst-filter").data("end", jQ.datepicker.formatDate("yymmdd", tomorrow));
                            break;
                        case "thisweek":
                            week = new Date(today.getFullYear(), today.getMonth(), today.getDate() - today.getDay());
                            newStart = jQ.datepicker.formatDate(startAdv.data("datepicker").settings.dateFormat || jQ.datepicker._defaults.dateFormat, week);
                            newEnd = jQ.datepicker.formatDate(endAdv.data("datepicker").settings.dateFormat || jQ.datepicker._defaults.dateFormat, new Date(week.getFullYear(), week.getMonth(), week.getDate() + 6));
                            startAdv.val(newStart);
                            endAdv.val(newEnd);
                            jQ("#fxst-filter").data("start", jQ.datepicker.formatDate("yymmdd", week));
                            jQ("#fxst-filter").data("end", jQ.datepicker.formatDate("yymmdd", new Date(week.getFullYear(), week.getMonth(), week.getDate() + 6)));
                            break;
                        case "nextweek":
                            nextweek = new Date(today.getFullYear(), today.getMonth(), (today.getDate() - today.getDay()) + 7);
                            newStart = jQ.datepicker.formatDate(startAdv.data("datepicker").settings.dateFormat || jQ.datepicker._defaults.dateFormat, nextweek);
                            newEnd = jQ.datepicker.formatDate(endAdv.data("datepicker").settings.dateFormat || jQ.datepicker._defaults.dateFormat, new Date(nextweek.getFullYear(), nextweek.getMonth(), nextweek.getDate() + 6));
                            startAdv.val(newStart);
                            endAdv.val(newEnd);
                            jQ("#fxst-filter").data("start", jQ.datepicker.formatDate("yymmdd", nextweek));
                            jQ("#fxst-filter").data("end", jQ.datepicker.formatDate("yymmdd", new Date(nextweek.getFullYear(), nextweek.getMonth(), nextweek.getDate() + 6)));
                            break;
                        case "custom":
                            //si la custom-div està tancada, la obrim i controlem que si clicken
                            //en qualsevol lloc fora de la custom-div, aquesta es tanqui
                            jQ("#fxit-customdates-datepicker").datepicker("refresh");
                            if (filterCustom.hasClass("fxst-hidden")) {
                                jQ(document).on("click", document, function (event) {
                                    //aquí no fem servir la variable filterCustom per no deixar la closure liant-la
                                    //jQ(event.target).is(":visible") és necessari pq quan clickem al next/prev dels mesos
                                    //l'event no es llença desde la part visible del datepicker, sino desde una div oculta
                                    //que jQuery posa al final de la plana
                                    if (jQ(event.target).is(":visible") && !jQ("#fxit-custom-div").has(event.target).length && event.target.id !== "fxit-custom-button") {
                                        jQ("#fxit-custom-div").addClass("fxst-hidden");
                                    }
                                });
                                filterCustom.removeClass("fxst-hidden");
                            }
                            else {
                                filterCustom.addClass("fxst-hidden");
                            }
                            //si encara no hem inicialitzat el datepicker custom, posem el altField
                            if (!jQ("#fxit-customdates-datepicker").datepicker("option", "altField")) {
                                jQ("#fxit-customdates-datepicker").datepicker("option", "altField", ".fxit-customdates-input.fxst-input-text-active");
                            }

                            if (jQ("#fxst-advfilter").is(":visible")) {
                                jQ("#fxit-advlink").addClass("fxst-advlink-normal").removeClass("fxst-advlink-hide");
                                jQ("#fxit-advlink").text(resources.ShowFilters);
                                jQ("#fxst-advfilter").hide('blind', {}, 1000);
                            }
                            return;
                        case "recentnext":
                            startAdv.val("");
                            endAdv.val("");
                            jQ("#fxst-filter").data("start", "");
                            jQ("#fxst-filter").data("end", "");
                            break;
                    }
                    fxecConfig.start = "";
                    fxecConfig.end = "";
                    fxecConfig.view = "";
                    getdata();
                });
                //restaurem el filtre per defecte
                jQ(document).on("click", "#fxit-clear", function (event) {
                    var defCountries = fxcalendar_config.countrycode || fxecConfig.defaultCountryCodes;
                    event.preventDefault();
                    jQ(".fxit-prefiltered-date.fxst-selected").removeClass("fxst-selected");
                    jQ(".fxit-prefiltered-date").first().addClass("fxst-selected");
                    jQ("#fxst-volatility").slider("option", "value", 0);
                    jQ("#fxit-keyword").val("");
                    jQ("#fxit-start-advanced").val("");
                    jQ("#fxit-end-advanced").val("");
                    jQ("#fxst-filter").data("start", "");
                    jQ("#fxst-filter").data("end", "");
                    jQ(".fxst-category input").removeAttr("checked");
                    jQ(".fxst-country input").removeAttr("checked").each(function (index, item) {
                        if (defCountries.indexOf(item.value) !== -1) {
                            jQ(item).prop("checked", true);
                        }
                    });
                    /*jQ("#fxst-filterform").each(function () {
                        this.reset();
                    });*/
                });
                //preparem el datepicker de custom dates
                //primer fem que quan se seleccioni un input, es posi la classe fxst-input-text-active
                jQ(document).on("click, focus", ".fxit-customdates-input", function (event) {
                    event.preventDefault();
                    jQ(".fxit-customdates-input").removeClass("fxst-input-text-active");
                    jQ(this).addClass("fxst-input-text-active");
                });
                //i llencem el datepicker
                jQ("#fxit-customdates-datepicker").datepicker({
                    changeMonth: true,
                    numberOfMonths: 2,
                    defaultDate: new Date(),
                    firstDay: resources.FirstDayOfWeek,
                    onSelect: function (selectedDate, instance) {
                        return datePickerUtils(selectedDate, instance, jQ(".fxit-customdates-input.fxst-input-text-active"), "custom");
                    },
                    beforeShowDay: function (date) {
                        var start = jQ("#fxit-start-custom").val(), end = jQ("#fxit-end-custom").val();
                        if (start && end) {
                            start = jQ.datepicker.parseDate(jQ(this).data("datepicker").settings.dateFormat || jQ.datepicker._defaults.dateFormat, start);
                            end = jQ.datepicker.parseDate(jQ(this).data("datepicker").settings.dateFormat || jQ.datepicker._defaults.dateFormat, end);
                            if (date.getTime() >= start.getTime() && date.getTime() <= end.getTime()) {
                                return [true, "ui-state-active"];
                            }
                        }
                        return [true, ""];
                    }
                });
                //  Datepickers
                jQ('#fxit-start-advanced, #fxit-end-advanced').datepicker({
                    changeMonth: true,
                    numberOfMonths: 3,
                    showCurrentAtPos: 1,
                    defaultDate: new Date(),
                    firstDay: resources.FirstDayOfWeek,
                    onSelect: function (selectedDate, instance) {
                        return datePickerUtils(selectedDate, instance, jQ(this), "advanced");
                    }
                });
                jQ(document).on("change", "#fxit-start-advanced, #fxit-end-advanced, .fxit-customdates-input.fxst-input-text-active", function () {
                    return datePickerUtils(undefined, undefined, jQ(this), "advanced");
                });

                //posem per idiomes si cal
                jQ('#fxit-start-advanced, #fxit-end-advanced, #fxit-customdates-datepicker').datepicker('option', jQ.datepicker.regional[resources.Language]).val("");

                //  Volatility
                jQ(document).on("click", ".volatilityicon", function () {
                    jQ('#fxst-volatility').slider("value", jQ(this).data("sliderValue"), true);
                });

                jQ('#fxst-volatility').slider({
                    value: 0,
                    min: 0,
                    max: 3,
                    step: 1,
                    range: "max",
                    animate: true
                });

                //si hi ha countries a la config, els carreguem al filtre
                if (fxecConfig.countrycode) {
                    jQ("li.fxst-country input").removeAttr("checked").each(function (index, item) {
                        if (fxecConfig.countrycode.indexOf(item.value) !== -1) {
                            jQ(item).prop('checked', true);
                        }
                    });
                }
                else {
                    //si no hi ha res desmarquem totes perquè estan marcades algunes per default
                    jQ("li.fxst-country input").removeAttr("checked");
                }
                //si hi ha ronya a la cookie, la carreguem
                if (settings) {
                    setparams(settings);
                    fxStore.set("FXstCalendarSettings", settings, 90);
                }
                //
                //  Cargar el grid
                //
                getdata();
                //  Esconder el filtro avanzado
                jQ("#fxst-advfilter").hide();
                //
                // Select All para los checkboxes
                //
                jQ(document).on("click", ".fxst-selectall", function (event) {
                    event.preventDefault();
                    jQ("li." + jQ(this).data("name") + " input[type='checkbox']").not(":checked").each(function (index, item) {
                        jQ(item).trigger("click");
                    });
                });
                //
                //  Select none para los checkboxes
                //
                jQ(document).on("click", ".fxst-selectnone", function (event) {
                    event.preventDefault();
                    jQ("li." + jQ(this).data("name") + " input:checked").each(function (index, item) {
                        jQ(item).trigger("click");
                    });
                });
                //
                //  Combo d'Olsen Scale
                //
                jQ(document).on("change", "select.fxit-olsencombo", function (event) {
                    event.preventDefault();
                    var combo = jQ(this), instrument = combo.val(),
                    caption = combo.find("option:selected").text();

                    jQ(".fxit-olsendata img").each(function (index, item) {
                        var img = jQ(item), reempl = img.attr("src");
                        reempl = reempl.replace(/(instrument|legs)=[^&]+/, "$1=" + instrument);
                        reempl = reempl.replace(/center=[^&]+/, "center=" + caption);
                        reempl = reempl.replace(/caption=[^&]+/, "caption=" + caption);
                        img.attr("src", reempl);
                    });
                });
                //  Botó d'info d'Olsen Scale
                jQ(document).on("click", ".fxit-olseninfoimg", function (event) {
                    event.preventDefault();
                    jQ(this).parents("div.fxit-olsendata").find("div.fxit-olsentext").toggle();
                });

                //  **************************************************
                //      Update vía Push
                //  **************************************************
                asyncLoadjs(fxecConfig.frozenmountainhost, function () {

                    var client = fm.websync.client,
                        util = fm.utilities,
                        websynchannelbase = fxecConfig.pushUpdaterChannel,
                        formatValue = function (valor, precision, unit, pot) {
                            if (!valor || valor === "undefined") {
                                return valor;
                            }

                            var v = valor.toString().split(".");
                            var e = v[0];
                            var ret = e;

                            if (v.length === 2) {
                                if (v[1].length > precision) {
                                    precision = v[1].length;
                                }
                                var d = v[1].substring(0, precision);
                                //	Si tengo menos decimales que precisión relleno con ceros
                                if (precision > d.length) {
                                    d = (d + "000").substring(0, precision);
                                }
                                if (d.length > 0) {
                                    ret = ret + "." + d;
                                }
                            }
                            else {
                                //	Si no tengo decimales pongo tantos ceros como la precisión.
                                if (precision > 0) {
                                    ret = ret + "." + "000".substring(0, precision);
                                }
                            }

                            if (unit === "%") {
                                ret += unit;
                            } else {
                                ret = unit + valor + pot;
                            }

                            return ret;
                        };
                    var calendarActualRevisedFM = function (data) {
                        var actualColumnClass = "";
                        var curItem = findItem(data.EventDateId);

                        if (curItem == null || curItem.data("actual") === data.Actual)
                            return;

                        if (data.IsBetter !== null) {
                            actualColumnClass = data.IsBetter === true ? "fxst-better" : "fxst-worst";
                        }

                        // Guardamos el nuevo dato.
                        curItem.data("actual", data.Actual);
                        curItem.data("isBetter", data.IsBetter);

                        var actualValorDisplay = formatValue(curItem.data("actual"), curItem.data("precision"), curItem.data("unit"), curItem.data("pot"));

                        var actualColumn = curItem.find(".fxit-actual");
                        actualColumn.text(actualValorDisplay);
                        actualColumn.removeClass("fxst-better fxst-worst");
                        actualColumn.addClass(actualColumnClass);

                        var detail = curItem.next().find(".fxit-actual");
                        if (detail) {
                            detail.empty();
                            var span = jQ("<span></span>");
                            span.addClass("fxst-actual");
                            span.append("&nbsp;" + actualValorDisplay);
                            span.addClass(actualColumnClass);
                            detail.append(span);
                            detail.append("<br /><span>" + resources.Actual_Text + "</span>");
                        }

                        //  Activamos el checked en la columna del Countdown si la hay
                        var countdowncol = curItem.find(".fxit-countdown");
                        if (typeof countdowncol !== 'undefined') {
                            countdowncol.html(fxecConfig.countdownFormat === "{hnn}:{mnn}"
                                ? '<i class="icon-ok icon-green"></i>'
                                : getVersionParameterValue(versionConfig.getCheckMark));
                        }

                        //  Disparamos el evento de actualreceived              
                        jQ(fxecConfig.gridselector).trigger("actualreceived", data);

                        curItem.addClass("fxst-activeRow");

                        if (data.Revised !== null && (typeof data.Revised !== 'undefined')) {
                            calendarRevisedFM(data);
                        }
                    };
                    var calendarRevisedFM = function (data) {

                        var curItem = findItem(data.EventDateId);
                        if (curItem == null) return;

                        var previousRevisedItem = curItem.find(".fxit-previous");
                        if (previousRevisedItem !== undefined && previousRevisedItem !== null) {
                            var previusValue = previousRevisedItem.data('revised');
                            
                            var revisedValue = formatValue(data.Revised, curItem.data("precision"), curItem.data("unit"), curItem.data("pot"));
                            previousRevisedItem.html(revisedValue);

                            previousRevisedItem.data("revised", revisedValue);

                            var previusItem = curItem.find(".fxit-previous");
                            if (previusItem.length === 1 && (typeof previusValue !== 'undefined')) {
                                previusItem.empty();

                                var revisedPrevius = resources.Revised + " " + previusValue;

                                var span = $('<span/>');
                                span.append(revisedValue);
                                span.append('<i class="fa fa-info-circle fxs_cal_yellow"></i>');

                                var b = $('<b/>').addClass('fxst-revised').attr('title', revisedPrevius).html(revisedPrevius);
                                span.append(b);

                                previusItem.append(span);
                            }
                        }
                        jQ(fxecConfig.gridselector).trigger("revisedReceived", data);
                    };

                    util.ready();

                    client.initialize({
                        key: "ff969c0f-709e-4086-afb3-d2afe1e9665f"
                    });

                    client.connect();

                    client.subscribe({
                        channel: websynchannelbase,
                        onReceive: function (args) {
                            var messageType = args.data.MessageType;
                            if (messageType === 'CalendarActualRevised')
                                calendarActualRevisedFM(args.data.Data);
                            else if (messageType === 'CalendarRevised')
                                calendarRevisedFM(args.data.Data);
                        }
                    });
                });

                //  Botón de filter
                jQ(document).on("click", "#fxit-filterbutton, #fxit-apply-custom", function (event) {
                    event.preventDefault();
                    //amaguem el custom filter de data
                    jQ("#fxit-custom-div").addClass("fxst-hidden");
                    if (jQ("#fxit-savesettings").is(":checked")) {//guardem cookie
                        fxStore.set("FXstCalendarSettings", getparams(true), 90);
                    }
                    else { //borrem la cookie
                        fxStore.remove("FXstCalendarSettings");
                    }
                    //ens carreguem els countries, de l'usuari.
                    //Si ha posat, ja els hem marcat al filtre
                    if (fxecConfig.countrycode) {
                        fxecConfig.countrycode = "";
                    }
                    getdata();
                });

                //
                //  Pestañas de evento
                //
                jQ(document).on("click", "ul.fxst-tabNavigation li a", function (event, noTrackPageView) {
                    event.preventDefault();
                    var a = jQ(this),
                        li = a.parent(),
                        ul = li.parent(),
                        id = ul.data("id"),
                        selector = "div." + a.data("content"),
                        container = jQ("#content_" + id),
                        url = fxecConfig.host + a[0].pathname + "?timezone=" + fxecConfig.timezone + "&culture=" + fxecConfig.culture + "&Id=" + id + "&rows=" + fxecConfig.rowsfeatures,
                        content = container.find(selector), curItem = findItem(id);

                    if (a[0].pathname.charAt(0) !== "/") {
                        url = fxecConfig.host + a[0].pathname + "?timezone=" + fxecConfig.timezone + "&culture=" + fxecConfig.culture + "&Id=" + id + "&rows=" + fxecConfig.rowsfeatures;
                    }
                    //al loro, aquí sí que necessitem comprovar que la variable és
                    //undefined, ja que això voldrà dir que no ens han passat res
                    //en el trigger del click, i per tant, volem trackejar amb analytics
                    if (noTrackPageView === undefined) {
                        jQ(fxecConfig.gridselector).trigger("tabclicked", a);
                    }
                    ul.find("li").removeClass("fxst-selectedTab ui-state-default ui-corner-top ui-tabs-active ui-state-active");
                    li.addClass("fxst-selectedTab ui-state-default ui-corner-top ui-tabs-active ui-state-active");

                    container.find("div.fxec_tabcontent").hide();
                    //REFACTOR:
                    if (!content.children().length) {
                        //REFACTOR:
                        //què fem si hi ha error? .done() només s'executa quan el 
                        //request té com a resultat un success
                        jQ(content).append(loading);
                        content.show();
                        jQ.ajax({
                            url: url,
                            dataType: "jsonp"
                        }).done(function (data) {
                            jQ(content).empty();
                            jQ(content).append(data.Html);
                            if (!li.hasClass("fxec-it-historytab")) {
                                jQ(content).find(".fxit-newsurl").each(function (index, item) {
                                    jQ(item).attr("href", fxecConfig.newsurl + jQ(item).data("id"));
                                });
                            }
                        }).fail(function () { });
                    } else {
                        content.show();
                    }
                });

                jQ(document).on("click", "div.fxec_historylinks a", function (event) {
                    event.preventDefault();
                    var a = jQ(this),
                        div = a.parent(),
                        id = div.data("id"),
                        selector = "div." + a.data("content"),
                        container = jQ("#content_" + id),
                        url = fxecConfig.host + "/" + a[0].pathname + "?culture=" + fxecConfig.culture,
                        content = container.find(selector);

                    div.find("a").removeClass("fxst-active");
                    a.addClass("fxst-active");
                    if (a[0].pathname.charAt(0) !== "/") {
                        url = fxecConfig.host + "/" + a[0].pathname + "?culture=" + fxecConfig.culture;
                    }
                    container.find("div.fxec_tabcontentdate").hide();
                    if (!content.children().length) {
                        //REFACTOR:
                        //què fem si hi ha error? .done() només s'executa quan el 
                        //request té com a resultat un success
                        jQ.ajax({
                            url: url,
                            dataType: "jsonp"
                        }).done(function (data) {
                            jQ(content).append(data.Html);
                            content.show();
                        }).fail(function () {
                        });
                    } else {
                        content.show();
                    }
                });
                //FIN REFACTOR
                //link cap a country si ens canvien la url
                jQ(".fxit-countryurl").each(function (index, item) {
                    jQ(item).attr("href", fxecConfig.countryurl + jQ(item).data("idcountry"));
                });
                //link cap a event si ens canvien la url
                jQ(".fxit-eventurl").each(function (index, item) {
                    jQ(item).attr("href", fxecConfig.eventurl + jQ(item).data("idevent"));
                });
                //  Paginacion history table
                jQ(document).on("click", "div.fxst-paginationHistoryTable a", function (event) {
                    event.preventDefault();
                    var a = jQ(this),
                        url = fxecConfig.host + "/" + a.attr('href'),
                        content = a.parents("div.fxec_tabcontentdate");

                    jQ.ajax({
                        url: url,
                        dataType: "jsonp"
                    }).done(function (data) {
                        jQ(content).empty();
                        jQ(content).append(data.Html);
                        content.show();
                    }).fail(function () { });
                });

                jQ(document).on("click", "a.fxst-exportcsv", function () {
                    var a = jQ(this);
                    var url = fxecConfig.host + "/" + a.data("historycsv") + "/?f=csv&v=2&culture=" + fxecConfig.culture;
                    a.attr("href", url);
                });
                //  Detalle de evento
                jQ(document).on("click", "tr.fxit-eventrow", function (event, noTrackPageview) {
                    currentEventDetail = true;
                    jQ(this).removeClass("fxst-activeRow");
                    event.preventDefault();
                    jQ(fxecConfig.gridselector).trigger("detailclicked", jQ(this));

                    var eventRow = jQ(this), detailRow = eventRow.next(),
                    detailCell = detailRow.children().first(),
                    openEvent = jQ("tr.fxec_selectedRow"),
                    detailEventRow = openEvent.next(),
                    detailEventCell = detailEventRow.children().first(),
                    detailRows = $('tr.fxst-tr-detail.fxst-detailRow > td');

                    setArrow = function (arrowSpan) {
                        if (arrowSpan.hasClass("fxst-openFull") || arrowSpan.hasClass("fxst-closedFull")) {
                            arrowSpan.toggleClass("fxst-openFull fxst-closedFull");
                        } else {
                            arrowSpan.toggleClass("fxst-openEmpty fxst-closedEmpty");
                        }
                    };
                    //  Si estoy haciendo click en el detalle activo simplemente lo oculto
                    if (detailRow.is(":visible")) {
                        detailRow.hide();
                        detailRows.empty();
                        //  Flechita de hastxitxa
                        setArrow(eventRow.children().last().children().first());
                        eventRow.removeClass("fxec_selectedRow");
                        currentEventDetail = false;
                        return;
                    } else {
                        // Hay un detalle abierto, pero no es el que estoy abriendo ahora mismo.                    
                        if (openEvent.length === 1) {
                            setArrow(openEvent.children().last().children().first());
                            detailEventRow.hide();
                            detailRows.empty();
                            openEvent.removeClass("fxec_selectedRow");
                        }
                    }
                    //REFACTOR:
                    //if (detailCell.children().length === 0) { --> if (!detailCell.children().length) {

                    //REFACTOR:
                    //què fem si hi ha error? .done() només s'executa quan el 
                    //request té com a resultat un success
                    detailCell.append(loading);
                    jQ.ajax({
                        url: fxecConfig.host + "/EventDateWidget/GetEventDateInfo?version=2",
                        dataType: "jsonp",
                        data: {
                            "tabs": fxecConfig.tabs,
                            "timezone": fxecConfig.timezone,
                            "showeventlink": fxecConfig.showeventlink,
                            "showcountrylink": fxecConfig.showcountrylink,
                            "id": eventRow.data("eventdateid"),
                            "culture": fxecConfig.culture
                        }
                    }).done(function (data) {
                        detailCell.empty();
                        detailCell.append(data.Html);
                        detailRow.show();
                        jQ(fxecConfig.gridselector).trigger("detailloaded", eventRow);
                        eventRow.addClass("fxec_selectedRow");
                        setArrow(eventRow.children().last().children().first());
                        jQ(".fxit-countryurl").each(function (index, item) {
                            jQ(item).attr("href", fxecConfig.countryurl + jQ(item).data("idcountry"));
                        });
                        jQ(".fxit-eventurl").each(function (index, item) {
                            jQ(item).attr("href", fxecConfig.eventurl + jQ(item).data("idevent"));
                        });
                        //en aquest cas no volem mai que es trackeji a analytics l'event del tabclicked
                        detailCell.find("ul.fxst-tabNavigation").children().first().children().first().trigger("click", false);
                        currentEventDetail = false;

                        createMarketImpact(jQ, data);
                        /* end chart scripts */

                    }).fail(function () {
                        currentEventDetail = false;
                    });

                });
                //  Link y filtro avanzado
                jQ(document).on("click", "#fxit-advlink", function (event) {
                    event.preventDefault();
                    this.blur();
                    var link = jQ(this);
                    //amaguem el custom selector
                    jQ("#fxit-custom-div").addClass("fxst-hidden");
                    if (link.hasClass("fxst-advlink-normal")) {
                        link.removeClass("fxst-advlink-normal");
                        link.addClass("fxst-advlink-hide");
                        link.text(resources.HideFilters);
                    } else {
                        link.removeClass("fxst-advlink-hide");
                        link.addClass("fxst-advlink-normal");
                        link.text(resources.ShowFilters);
                    }
                    jQ("#fxst-advfilter").toggle();
                });
            }).fail(function () { });

            asyncLoadcss(fxecConfig.statichost + "/calendarwidget-css/jquery.fancybox-1.3.0.css");
            asyncLoadjs(fxecConfig.statichost + "/calendarwidget-js/jquery.fancybox-1.3.0.js", function () {
                jQ.fancybox.init();
                jQ(document).on("click", ".fxec_newspopup", function (event) {
                    event.preventDefault();
                    var id = jQ(this).data("id"),
                        title = jQ(this).data("title"),
                        url = fxecConfig.host + "/NewsWidget/GetNewsInfo/" + id + "?culture=" + fxecConfig.culture;
                    jQ.ajax({
                        dataType: "jsonp",
                        //data: { title: title },
                        url: url
                    }).done(function (data) {
                        jQ.fancybox({
                            'content': "<h3>" + title + "</h3>" + data.Html,
                            'transitionIn': 'elastic',
                            'transitionOut': 'elastic',
                            'overlayOpacity': 0.6,
                            'overlayColor': '#000'
                        });
                    });
                });
            });

            //autochartist
            jQ(document).on("change", ".fxec_autochartistpairselector", function (event) {
                event.preventDefault();
                var id = jQ(this).data("id")
                    , idpair = jQ(this).val();

                jQ('#fxec_autochartistdata_' + id + ' img').each(function (index, item) {
                    var img = jQ(item), reempl = img.attr("src");
                    reempl = reempl.replace(/id=[^&]+/, "id=" + idpair);
                    img.attr("src", reempl);
                });
            });
        });

    };

    function createMarketImpact(jQ, data) {
        /* ********************************************* */
        /* script for TR - VR AND surprise factor charts */
        /* ******************************************** */

        var maxEvents = 40;  // We have 48 (or 46 dependening on the event) samples of pair feed price and more for the event surprise factor chart. We should cut the number of samples by the most restrictive one or even less to make a nice visualization on small screens.
        var pair = 'EURUSD'; // By default we use the EURUSD pair.
        var eventId = jQ(data.Html).find(".fxec-it-historytab").attr('data-idecocalendar'); // By default we use the NFP event.
        var timesLoaded = 0;

        function endsWith(str, suffix) {
            return str.indexOf(suffix, str.length - suffix.length) !== -1;
        }

        function paintCharts() {
            if (typeof eventId === 'undefined') {
                return;
            }

            var jsonUrl = fxecConfig.host + '/api/MarketImpact/GetOtherCharts/' + eventId + '/' + pair;
            console.log('Loading JSON from URL: ' + jsonUrl);

            jQ.getJSON(jsonUrl, function (jsonResultData) {
                console.log("json loaded");

                document.getElementById("deviation_chart_name").innerHTML = '<strong>' + jsonResultData.EventModel.EventName + '</strong> - ' + resources.TabDeviationImpact_Text;
                document.getElementById("tr_chart_name").innerHTML = '<strong>' + jsonResultData.EventModel.EventName + '</strong> - <strong>' + jsonResultData.Pair + '</strong> ' + resources.TabTrueRange_Text;
                document.getElementById("vr_chart_name").innerHTML = '<strong>' + jsonResultData.EventModel.EventName + '</strong> - <strong>' + jsonResultData.Pair + '</strong> ' + resources.TabVolatilityRatio_Text;
                document.getElementById("scatter_chart_name").innerHTML = '<strong>' + jsonResultData.EventModel.EventName + '</strong> - <strong>' + jsonResultData.Pair + '</strong> TR vs ' + resources.TabDeviationImpact_Text;

                function calculateCols() {
                    var eventDateCounter = 0;
                    for (var i = 0; i < jsonResultData.MarketImpactValues.length; i++) {
                        if (eventDateCounter < maxEvents) { // If we have more than maxEvents, we stop counting.
                            eventDateCounter++;
                        }
                        else {
                            break; // We exit the loop for efficiency.
                        }
                    }
                    return eventDateCounter;
                }

                // Surprise Factor (Deviation Ratio) Chart
                var columns = new Array();
                var numRows = 4;
                var numCols = calculateCols();
                var i, j;
                for (i = 0; i < numRows; i++) {
                    columns[i] = new Array();

                    for (j = 0; j < numCols + 1; j++) { // Hi sumo un valor a recòrrer per poder afegir l'etiqueta de la dada hardcoded al principi.
                        if (i === 0) {
                            if (j === 0) {
                                columns[i][j] = 'x'; // Timeseries x-axis
                            }
                            else {
                                columns[i][j] = jsonResultData.MarketImpactValues[j - 1].EventDateModel.Date;
                            }
                        }
                        if (i === 1) {
                            if (j === 0) {
                                columns[i][j] = resources.Deviation_Text;
                            }
                            else {
                                if (typeof jsonResultData.MarketImpactValues[j - 1].EventDateModel.StandardDeviationRatio === 'undefined' || jsonResultData.MarketImpactValues[j - 1].EventDateModel.StandardDeviationRatio == null) { // We filter to null every undefined, null or possible wrong jsonResultData
                                    columns[i][j] = null;
                                } else {
                                    columns[i][j] = (jsonResultData.MarketImpactValues[j - 1].EventDateModel.StandardDeviationRatio.toFixed(2));
                                }
                            }
                        }
                        if (i === 2) {
                            if (j === 0) {
                                columns[i][j] = resources.Consensus_Text;
                            }
                            else {
                                if (typeof jsonResultData.MarketImpactValues[j - 1].EventDateModel.Consensus === 'undefined' || jsonResultData.MarketImpactValues[j - 1].EventDateModel.Consensus == null) { // We filter to null every undefined, null or possible wrong jsonResultData
                                    columns[i][j] = null;
                                } else {
                                    columns[i][j] = (jsonResultData.MarketImpactValues[j - 1].EventDateModel.Consensus.toFixed(2));
                                }
                            }
                        }
                        if (i === 3) {
                            if (j === 0) {
                                columns[i][j] = resources.Actual_Text;
                            }
                            else {
                                if (typeof jsonResultData.MarketImpactValues[j - 1].EventDateModel.Actual === 'undefined' || jsonResultData.MarketImpactValues[j - 1].EventDateModel.Actual == null) { // We filter to null every undefined, null or possible wrong jsonResultData
                                    columns[i][j] = null;
                                } else {
                                    columns[i][j] = (jsonResultData.MarketImpactValues[j - 1].EventDateModel.Actual.toFixed(2));
                                }
                            }
                        }
                    }
                }

                c3.generate({
                    bindto: '#chart_deviation',
                    data: {
                        x: 'x',
                        xFormat: '%m/%d/%Y', // 'xFormat' can be used as custom format of 'x'
                        columns: columns, // Caution! Placing only "columns," works for FF and Chrome but not for Safari!
                        //type: 'bar',
                        types: {
                            Deviation: 'bar', // To assign type individually, the names must start by letters and with no blank spaces.
                            Consensus: 'line',
                            Actual: 'area'
                        },
                        colors: {
                            Deviation: '#efb871',
                            Consensus: '#dc8623',
                            Actual: '#5aa1d9'

                        },
                        axes: {
                            Standard_Deviation_Ratio: 'y',
                            Consensus: 'y2',
                            Actual: 'y2'
                        }
                    },
                    bar: {
                        width: {
                            ratio: 0.5 // this makes bar width 50% of length between ticks
                        }
                        // or
                        //width: 100 // this makes bar width 100px
                    },
                    axis: {
                        x: {
                            type: 'timeseries',
                            tick: {
                                format: '%m/%d/%Y',
                                culling: {
                                    max: 4 // the number of tick texts will be adjusted to less than this value
                                }
                            },
                            label: {
                                position: 'outer-center'
                            }
                        },
                        y: {
                            label: {
                                text: resources.Deviation_Axis_Label,
                                position: 'outer-middle' // text in the middle and outher of graph 
                            }

                        },
                        y2: {
                            show: true,
                            label: {
                                text: resources.Actual_And_Consensus_Axis_Label,
                                position: 'outer-middle'
                            },
                            tick: {
                                format: d3.format(".1f") // esto formatea el valor recibido y muestra 1 decimale
                            }
                        }

                    },
                    grid: {
                        x: {
                            show: false
                        },
                        y: {
                            tick: {
                                opacity: 0
                            },
                            lines: [
                                { value: 0, text: '' }
                            ]
                        },
                        focus: {
                            show: true
                        }
                    },
                    point: {
                        show: false
                    }
                });


                // True Range Chart:
                columns = new Array();
                numRows = 5;
                numCols = calculateCols();
                for (i = 0; i < numRows; i++) {
                    columns[i] = new Array();
                    for (j = 0; j < numCols + 1; j++) { // Hi sumo un valor a recòrrer per poder afagir l'etiqueta de la dada hardcoded al principi.
                        if (i === 0) {
                            if (j === 0) {
                                columns[i][j] = 'x'; // Timeseries x-axis
                            }
                            else {
                                columns[i][j] = jsonResultData.MarketImpactValues[j - 1].EventDateModel.Date;
                            }
                        }
                        if (i === 1) {
                            if (j === 0) {
                                columns[i][j] = 'True_Range_15m';
                            }
                            else {
                                if (typeof jsonResultData.MarketImpactValues[j - 1].TrueRange15Min === 'undefined' || jsonResultData.MarketImpactValues[j - 1].TrueRange15Min == null /*|| jsonResultData.MarketImpactValues[j-1].TrueRange15Min > 0.0300*/) { // We filter to null every undefined, null or possible wrong jsonResultData (more than 300 pips? And if USDJPY?)
                                    columns[i][j] = null;
                                } else {
                                    if (endsWith(jsonResultData.Pair, 'JPY')) { // Pip conversion and check for JPY pairs.
                                        columns[i][j] = ((jsonResultData.MarketImpactValues[j - 1].TrueRange15Min) * 100).toFixed(0);
                                    }
                                    else {
                                        columns[i][j] = ((jsonResultData.MarketImpactValues[j - 1].TrueRange15Min) * 10000).toFixed(0);
                                    }
                                }
                            }
                        }
                        if (i === 2) {
                            if (j === 0) {
                                columns[i][j] = 'True_Range_4h';
                            }
                            else {
                                if (typeof jsonResultData.MarketImpactValues[j - 1].TrueRange4h === 'undefined' || jsonResultData.MarketImpactValues[j - 1].TrueRange4h == null /*|| jsonResultData.MarketImpactValues[j-1].TrueRange4h > 0.0300*/) { // We filter to null every undefined, null or possible wrong jsonResultData (more than 300 pips? And if USDJPY?)
                                    columns[i][j] = null;
                                } else {
                                    if (endsWith(jsonResultData.Pair, 'JPY')) { // Pip conversion and check for JPY pairs.
                                        columns[i][j] = ((jsonResultData.MarketImpactValues[j - 1].TrueRange4h) * 100).toFixed(0);
                                    }
                                    else {
                                        columns[i][j] = ((jsonResultData.MarketImpactValues[j - 1].TrueRange4h) * 10000).toFixed(0);
                                    }
                                }
                            }
                        }
                        if (i === 3) {
                            if (j === 0) {
                                columns[i][j] = 'Avg_True_Range_15m';
                            }
                            else {
                                if (typeof jsonResultData.MarketImpactValues[j - 1].TrueRangeMean15Min === 'undefined' || jsonResultData.MarketImpactValues[j - 1].TrueRangeMean15Min == null /*|| jsonResultData.MarketImpactValues[j-1].TrueRangeMean15Min > 0.0300*/) { // We filter to null every undefined, null or possible wrong jsonResultData (more than 300 pips? And if USDJPY?)
                                    columns[i][j] = null;
                                } else {
                                    if (endsWith(jsonResultData.Pair, 'JPY')) { // Pip conversion and check for JPY pairs.
                                        columns[i][j] = ((jsonResultData.MarketImpactValues[j - 1].TrueRangeMean15Min) * 100).toFixed(0);
                                    }
                                    else {
                                        columns[i][j] = ((jsonResultData.MarketImpactValues[j - 1].TrueRangeMean15Min) * 10000).toFixed(0);
                                    }
                                }
                            }
                        }
                        if (i === 4) {
                            if (j === 0) {
                                columns[i][j] = 'Avg_True_Range_4h';
                            }
                            else {
                                if (typeof jsonResultData.MarketImpactValues[j - 1].TrueRangeMean4h === 'undefined' || jsonResultData.MarketImpactValues[j - 1].TrueRangeMean4h == null /*|| jsonResultData.MarketImpactValues[j-1].TrueRangeMean4h > 0.0300*/) { // We filter to null every undefined, null or possible wrong jsonResultData (more than 300 pips? And if USDJPY?)
                                    columns[i][j] = null;
                                } else {
                                    if (endsWith(jsonResultData.Pair, 'JPY')) { // Pip conversion and check for JPY pairs.
                                        columns[i][j] = ((jsonResultData.MarketImpactValues[j - 1].TrueRangeMean4h) * 100).toFixed(0);
                                    }
                                    else {
                                        columns[i][j] = ((jsonResultData.MarketImpactValues[j - 1].TrueRangeMean4h) * 10000).toFixed(0);
                                    }
                                }
                            }
                        }
                    }
                }

                c3.generate({
                    bindto: '#chart_true_range',
                    data: {
                        x: 'x',
                        xFormat: '%m/%d/%Y', // 'xFormat' can be used as custom format of 'x'
                        columns: columns, // Caution! Placing only "columns," works for FF and Chrome but not for Safari!
                        //type: 'bar',
                        types: {
                            True_Range_15m: 'bar', // To assign type individually, the names must start by letters and with no blank spaces.
                            True_Range_4h: 'bar',
                            Avg_True_Range_15m: 'spline',
                            Avg_True_Range_4h: 'spline'
                        },
                        names: { // custom the var names without undercore
                            True_Range_15m: resources.TrueRange15m_Legend,
                            True_Range_4h: resources.TrueRange4h_Legend,
                            Avg_True_Range_15m: resources.TrueRange_Averaged15m_Legend,
                            Avg_True_Range_4h: resources.TrueRange_Averaged4h_Legend
                        },
                        colors: {
                            True_Range_15m: '#efb877',
                            True_Range_4h: '#9bc7ea',
                            Avg_True_Range_15m: '#e4881b',
                            Avg_True_Range_4h: '#5aa5df'
                        }
                    },
                    bar: {
                        width: {
                            ratio: 0.5 // this makes bar width 50% of length between ticks
                        }
                    },
                    axis: {
                        x: {
                            type: 'timeseries',
                            tick: {
                                format: '%m/%d/%Y',
                                culling: {
                                    max: 4 // the number of tick texts will be adjusted to less than this value
                                }
                            },
                            label: {
                                position: 'outer-center'
                            }
                        },
                        y: {
                            label: {
                                text: resources.TrueRange_PipsAxis_Text,
                                position: 'outer-middle'

                            }
                        }
                    },
                    bar: {
                        width: {
                            ratio: 0.5 // this makes bar width 50% of length between ticks
                        }
                    },
                    grid: {
                        x: {
                            show: false
                        },
                        y: {
                            show: false,
                            tick: {
                                opacity: 0
                            }
                        },
                        focus: {
                            show: true
                        }
                    },
                    point: {
                        show: false
                    }
                });


                // Deviation Ratio Chart
                columns = new Array();
                numRows = 5;
                numCols = calculateCols();
                for (i = 0; i < numRows; i++) {
                    columns[i] = new Array();

                    for (j = 0; j < numCols + 1; j++) { // Hi sumo un valor a recòrrer per poder afagir l'etiqueta de la dada hardcoded al principi.
                        if (i === 0) {
                            if (j === 0) {
                                columns[i][j] = 'x'; // Timeseries x-axis
                            }
                            else {
                                columns[i][j] = jsonResultData.MarketImpactValues[j - 1].EventDateModel.Date;
                            }
                        }
                        if (i === 1) {
                            if (j === 0) {
                                columns[i][j] = 'Volatility_Ratio_15m';
                            }
                            else {
                                if (typeof jsonResultData.MarketImpactValues[j - 1].VolatilityRatio15Min === 'undefined' || jsonResultData.MarketImpactValues[j - 1].VolatilityRatio15Min == null) { // We filter to null every undefined, null or possible wrong jsonResultData
                                    columns[i][j] = null;
                                } else {
                                    columns[i][j] = (jsonResultData.MarketImpactValues[j - 1].VolatilityRatio15Min).toFixed(2);
                                }
                            }
                        }
                        if (i === 2) {
                            if (j === 0) {
                                columns[i][j] = 'Volatility_Ratio_4h';
                            }
                            else {
                                if (typeof jsonResultData.MarketImpactValues[j - 1].VolatilityRatio4h === 'undefined' || jsonResultData.MarketImpactValues[j - 1].VolatilityRatio4h == null) { // We filter to null every undefined, null or possible wrong jsonResultData
                                    columns[i][j] = null;
                                } else {
                                    columns[i][j] = (jsonResultData.MarketImpactValues[j - 1].VolatilityRatio4h).toFixed(2);
                                }
                            }
                        }
                        if (i === 3) {
                            if (j === 0) {
                                columns[i][j] = 'Avg_Volatility_Ratio_15m';
                            }
                            else {
                                if (typeof jsonResultData.MarketImpactValues[j - 1].VolatilityRatioMean15Min === 'undefined' || jsonResultData.MarketImpactValues[j - 1].VolatilityRatioMean15Min == null) { // We filter to null every undefined, null or possible wrong jsonResultData
                                    columns[i][j] = null;
                                } else {
                                    columns[i][j] = (jsonResultData.MarketImpactValues[j - 1].VolatilityRatioMean15Min).toFixed(2);
                                }
                            }
                        }
                        if (i === 4) {
                            if (j === 0) {
                                columns[i][j] = 'Avg_Volatility_Ratio_4h';
                            }
                            else {
                                if (typeof jsonResultData.MarketImpactValues[j - 1].VolatilityRatioMean4h === 'undefined' || jsonResultData.MarketImpactValues[j - 1].VolatilityRatioMean4h == null) { // We filter to null every undefined, null or possible wrong jsonResultData
                                    columns[i][j] = null;
                                } else {
                                    columns[i][j] = (jsonResultData.MarketImpactValues[j - 1].VolatilityRatioMean4h).toFixed(2);
                                }
                            }
                        }
                    }
                }

                c3.generate({
                    bindto: '#chart_volatility_ratio',
                    data: {
                        x: 'x',
                        xFormat: '%m/%d/%Y', // 'xFormat' can be used as custom format of 'x'
                        columns: columns, // Caution! Placing only "columns," works for FF and Chrome but not for Safari!
                        //type: 'bar',
                        types: {
                            Volatility_Ratio_15m: 'bar', // To assign type individually, the names must start by letters and with no blank spaces.
                            Volatility_Ratio_4h: 'bar',
                            Avg_Volatility_Ratio_15m: 'spline',
                            Avg_Volatility_Ratio_4h: 'spline'
                        },
                        names: { // custom the var names without undercore
                            Volatility_Ratio_15m: resources.VolatilityRatio_15m_Legend,
                            Volatility_Ratio_4h: resources.VolatilityRatio_4h_Legend,
                            Avg_Volatility_Ratio_15m: resources.VolatilityRatio_Averaged15m_Legend,
                            Avg_Volatility_Ratio_4h: resources.VolatilityRatio_Averaged4h_Legend
                        },
                        colors: {
                            Volatility_Ratio_15m: '#f7b56b',
                            Volatility_Ratio_4h: '#a1c8e7',
                            Avg_Volatility_Ratio_15m: '#57a5e3',
                            Avg_Volatility_Ratio_4h: '#e88319'
                        }
                    },
                    axis: {
                        x: {
                            type: 'timeseries',
                            tick: {
                                format: '%m/%d/%Y',
                                culling: {
                                    max: 4 // the number of tick texts will be adjusted to less than this value
                                }
                            },
                            label: {
                                position: 'outer-center'
                            }
                        },
                        y: {
                            label: {
                                text: resources.VolatilityRatio_Axis_Label,
                                position: 'outer-middle'

                            }
                        }
                    },
                    grid: {
                        x: {
                            show: false
                        },
                        y: {
                            show: false,
                            tick: {
                                opacity: 0
                            }
                        },
                        focus: {
                            show: true
                        }
                    },
                    point: {
                        show: false
                    }
                });


                // Scatter Plot

                var columnsAux = new Array();
                numRows = 2;
                numCols = calculateCols(); // We load the jsonResultData in a c3.js 'columns' matrix first for the x-axis of TRs:
                for (i = 0; i < numRows; i++) {
                    columnsAux[i] = new Array(); // each row is an array of columns

                    for (j = 0; j < numCols + 1; j++) { // We add one value to the array to be able to add the row tag at the beginning (e.g. EURUSD_x)
                        if (i === 0) {
                            if (j === 0) {
                                //columnsAux[i][j] = String(jsonResultData.Pair) + " 15m True Range_x"; // for the moment we don't need pairs
                                columnsAux[i][j] = "15m True Range_x";
                            }
                            else {
                                if (typeof jsonResultData.MarketImpactValues[j - 1].TrueRange15Min === 'undefined' || jsonResultData.MarketImpactValues[j - 1].TrueRange15Min == null) { // We filter to null every undefined, null or possible wrong jsonResultData
                                    columnsAux[i][j] = null;
                                } else {
                                    if (endsWith(jsonResultData.Pair, 'JPY')) { // Pip conversion and check for JPY pairs.
                                        columnsAux[i][j] = ((jsonResultData.MarketImpactValues[j - 1].TrueRange15Min) * 100);
                                    }
                                    else {
                                        columnsAux[i][j] = ((jsonResultData.MarketImpactValues[j - 1].TrueRange15Min) * 10000);
                                    }
                                }
                            }
                        }
                        if (i === 1) {
                            if (j === 0) {
                                //columnsAux[i][j] = String(jsonResultData.Pair) + "_TR_4h_x"; // for the moment we don't need pairs
                                columnsAux[i][j] = "4h True_Range_x";
                            }
                            else {
                                if (typeof jsonResultData.MarketImpactValues[j - 1].TrueRange4h === 'undefined' || jsonResultData.MarketImpactValues[j - 1].TrueRange4h == null) { // We filter to null every undefined, null or possible wrong jsonResultData
                                    columnsAux[i][j] = null;
                                } else {
                                    if (endsWith(jsonResultData.Pair, 'JPY')) { // Pip conversion and check for JPY pairs.
                                        columnsAux[i][j] = ((jsonResultData.MarketImpactValues[j - 1].TrueRange4h) * 100);
                                    }
                                    else {
                                        columnsAux[i][j] = ((jsonResultData.MarketImpactValues[j - 1].TrueRange4h) * 10000);
                                    }
                                }
                            }
                        }
                    }
                }


                var columnsAux2 = new Array();

                // Now we load the jsonResultData in a c3.js 'columns' matrix  for the y-axis of Deviation Ratios:
                for (i = 0; i < numRows; i++) {
                    columnsAux2[i] = new Array(); // each row is an array of columns

                    for (j = 0; j < numCols + 1; j++) { // We add one value to the array to be able to add the y-axis row tag at the beginning (e.g. EURUSD)
                        if (i === 0) {
                            if (j === 0) {
                                // columnsAux2[i][j] = String(jsonResultData.Pair) + " 15m True Range"; // for the moment we don't need pairs
                                columnsAux2[i][j] = resources.DeviationImpact_TrueRange15m_Legend;
                            }
                            else {
                                if (typeof jsonResultData.MarketImpactValues[j - 1].EventDateModel.StandardDeviationRatio === 'undefined' || jsonResultData.MarketImpactValues[j - 1].EventDateModel.StandardDeviationRatio == null) { // We filter to null every undefined, null or possible wrong jsonResultData
                                    columnsAux2[i][j] = null;
                                } else {
                                    columnsAux2[i][j] = (jsonResultData.MarketImpactValues[j - 1].EventDateModel.StandardDeviationRatio);
                                }
                            }
                        }
                        if (i === 1) {
                            if (j === 0) {
                                //columnsAux2[i][j] = String(jsonResultData.Pair) + "4h True Range"; // for the moment we don't need pairs
                                columnsAux2[i][j] = resources.DeviationImpact_TrueRange4h_Legend;
                            }
                            else {
                                if (typeof jsonResultData.MarketImpactValues[j - 1].EventDateModel.StandardDeviationRatio === 'undefined' || jsonResultData.MarketImpactValues[j - 1].EventDateModel.StandardDeviationRatio == null) { // We filter to null every undefined, null or possible wrong jsonResultData
                                    columnsAux2[i][j] = null;
                                } else {
                                    columnsAux2[i][j] = (jsonResultData.MarketImpactValues[j - 1].EventDateModel.StandardDeviationRatio); // We have the same jsonResultData from the previous row because it's the same eventDates from the same event.
                                }
                            }
                        }
                    }
                }
                columns = columnsAux.concat(columnsAux2); // We merge the auxiliar columns to the final one for plotting

                var xs = new Object(); // We create the xs object for placing it as a property in 'jsonResultData' for associating the y-axis PAIRs with their x-axis PAIR_x

                for (i = 0; i < numRows; i++) {
                    xs[columnsAux2[i][0]] = String(columnsAux[i][0]); // It must be an string even if its null!
                }

                function returnInfoTooltip(value, ratio, id) {
                    var info = '';
                    for (j = 0; j < numCols; j++) {
                        if (String(jsonResultData.MarketImpactValues[j].EventDateModel.StandardDeviationRatio) === value) {
                            if (endsWith(id, 'm')) {
                                info = 'Surprise Factor: ' + Number(value).toFixed(2) + ' | Volatility Ratio: ' + jsonResultData.MarketImpactValues[j].VolatilityRatio15Min.toFixed(2) + ' | ' + String(jsonResultData.MarketImpactValues[j].EventDateModel.Date);
                            }
                            else {
                                info = 'Surprise Factor: ' + Number(value).toFixed(2) + ' | Volatility Ratio: ' + jsonResultData.MarketImpactValues[j].VolatilityRatio4h.toFixed(2) + ' | ' + String(jsonResultData.MarketImpactValues[j].EventDateModel.Date);
                            }
                            break; // We exit the loop for efficiency.
                        }
                    }

                    return (info);
                }

                c3.generate({
                    bindto: '#chart_scatter',
                    data: {
                        xs: xs, // Caution! Placing only "xs," works for FF and Chrome but not for Safari!
                        columns: columns, // Caution! Placing only "columns," works for FF and Chrome but not for Safari!
                        type: 'scatter'
                    },
                    axis: {
                        x: {
                            tick: {
                                fit: false,
                                culling: {
                                    max: 4 // the number of tick texts will be adjusted to less than this value
                                }
                            },
                            label: {
                                text: resources.TrueRange_PipsAxis_Text,
                                position: 'inner-right'
                            }
                        },
                        y: {
                            label: {
                                text: resources.DeviationImpact_Axis_Label, // Deviation Ratio
                                position: 'outer-middle'

                            }
                        }
                    },
                    grid: {
                        x: {
                            show: false
                        },
                        y: {
                            show: false,
                            tick: {
                                opacity: 0
                            }
                        }
                    }, point: {
                        r: 8
                    },
                    tooltip: {
                        format: {
                            title: function (d) {
                                return ' True Range: ' + d.toFixed(0);
                            },
                            name: function (name) {
                                return name;
                            },
                            value: function (value, ratio, id, index) { // id = PAIR / index = column number / value = Deviation Ratio / Ratio will be undefined if the chart is not donut/pie/gauge.
                                value = value.toString();
                                value = returnInfoTooltip(value, ratio, id, index); //get info from parsed JSON jsonResultData[index];
                                return value;
                            }
                        }
                    }
                });
            });

            timesLoaded++;
            console.log('times loaded: ' + timesLoaded);
        }

        paintCharts();


        jQ(document).ready(function () {
            console.log('.pairSelect: ' + jQ(".pairSelect").length);
            jQ(".pairSelect").on('change', function () {
                pair = jQ(this).val();
                console.log("Selected pair: " + pair);
                paintCharts();
                jQ(".pairSelect").val(pair);
            });
        });
    };

    function asyncLoadjs(url, callback) {
        var x = document.getElementsByTagName('script')[0],
            s = document.createElement('script');
        s.type = 'text/javascript';
        s.async = true;
        s.src = url;
        if (callback && typeof callback === "function") {
            if (s.addEventListener) {
                s.addEventListener('load', callback, false);
            } else {
                s.onreadystatechange = function () {
                    if (this.readyState === "complete" || this.readyState === "loaded") {
                        callback.call();
                    }
                };
            }
        }
        x.parentNode.insertBefore(s, x);
    };

    function asyncLoadcss(url, callback) {
        var css = document.createElement('link');
        css.type = 'text/css';
        css.rel = 'stylesheet';
        css.href = url;
        if (callback && typeof callback === "function") {
            if (css.addEventListener) {
                css.addEventListener('load', callback, false);
            }
            else {
                css.onreadystatechange = function () {
                    if (this.readyState === "complete" || this.readyState === "loaded") {
                        callback.call();
                    }
                };
            }
        }
        document.getElementsByTagName('head')[0].appendChild(css);
    };

})();