$(document).ready(function(){
    
    // Денежный формат
    Number.prototype.formatMoney = function(c, d, t){
        var n = this, 
            c = isNaN(c = Math.abs(c)) ? 2 : c, 
            d = d == undefined ? "." : d, 
            t = t == undefined ? "," : t, 
            s = n < 0 ? "-" : "", 
            i = String(parseInt(n = Math.abs(Number(n) || 0).toFixed(c))), 
            j = (j = i.length) > 3 ? j % 3 : 0;
        return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
    };
    
    // Замена
    String.prototype.replaceAll = function(search, replace){
        return this.split(search).join(replace);
    }
    
    // Добавление впереди 0 у однозначных значений
    function pad(number) {
        var r = String(number);
        if ( r.length === 1 ) {
          r = '0' + r;
        }
        return r;
    }
    
    // Форматирование даты
    function formatDate(date)
    {
        return date.getFullYear() +'-'+ pad(date.getMonth()+1) +'-'+ pad(date.getDate());
    }
    
    // Округление до 2-х знаков
    function round2t(n)
    {
        return Math.round(n*100)/100;
    }
    
    // Отсеивание пиков (статистический метод)
    function dataErrorFilter(data, period)
    {
        var
            n = data.length,
            ma = 0,         // ср.ариф.
            sigm,           // среднеквадратичная пограшность.
            sum = 0,        // сумма кадратичных откл.
            re;             // относительное отклонение

        data.forEach(function(item, i) {
            ma += item;
        });
        ma = ma/n;

        data.forEach(function(item, i) {
            sum += Math.pow(ma - item, 2);
        });
        sigm = Math.sqrt(sum/(n-1));

        data.forEach(function(item, i) {
            re = Math.abs(ma - item)*Math.sqrt(n/(n-1))/sigm;
            if (re > 4.00)
            {
                console.log('AAA re ', period[i] + ' ' + ' '+ item + ' '+ re);
                //console.log('AAA re ', i + ' ' + ' '+ item + ' '+ re);
                data[i] = Math.round(ma*1000)/1000;
            }
        });
    }
    
    // Переключение состояния isLoadingStat
    function EnableLoadingState(isLoading)
    {
        if (isLoading) {
            $chartStatLoading.show();
            $controlsList.prop('disabled', true);
            $filtersWrap.addClass('state-loading');
        } else {
            $chartStatLoading.hide();
            $controlsList.prop('disabled', false);
            $filtersWrap.removeClass('state-loading');
        }
    }
    
    
    // Выбор дат для Stat http://t1m0n.name/air-datepicker/docs/index-ru.html
    var
        nowDate = new Date(),
        selectorGraphChartStat = '#chart-graph-stat',
        selectorTableChartStat = '#table-line',
        isLoadingStat = false,
        $controlsList = $('.b-content__metric-type-select button, .select-dates input, .select-dates button.btn, .b-filters input, .b-filters button'),
        $filtersWrap = $(".b-minstat-graph-filter"),
        dataLineChartStat = false,
        $applyButton = $('.select-dates button.btn'),
        $selectMetric = $('.select-metric .dropdown-menu a'),
        datepicker1 = $('#date-value-1').datepicker({
            dateFormat: "yyyy-mm-dd",
            autoClose: true,
            maxDate: nowDate
        }).data('datepicker'),
        datepicker2 = $('#date-value-2').datepicker({
            dateFormat: "yyyy-mm-dd",
            autoClose: true,
            maxDate: nowDate
        }).data('datepicker'),
        currentDay1 = new Date($('#date-value-1').val()),
        currentDay2 = new Date($('#date-value-2').val()),
        $datepicker2 = $('#date-value-2'),
        $byDays = $('input#by-days'),
        activeLinesSwitchersSelector = '.b-filter__switch.current',
        $activeLinesSwitchers = $(activeLinesSwitchersSelector),
        activeLinesTableSelector = '.table.table-striped thead tr',
        $activeLinesTable = $(activeLinesTableSelector),
        $timeSwitchers = $('.b-filter__switch.time, .b-filter__switch.time-table'),
        $daysSwitchers = $('.b-filter__switch.days'),
        
        $tableSwitcherTimeSum = $('.b-filter__switch.time-table'),
        $tableSwitcherCountSites = $('.b-filter__switch.count-sites'),
        $tableSwitcherCategory = $('.b-filter__switch.category-table'),
        tableIntervalSwitchersSelector = '.b-filter__switch.category-table .b-filter__switch-item',
        tableCountSitesSwitchersSelector = '.b-filter__switch.count-sites .b-filter__switch-item',
        
        $zonesWrap = $('.b-filters_zone-wrap'),
        actionMetric,
        activeLine,
        $geoExclude = $('#geo-exclude'),
        $siteExclude = $('#site-exclude'),
        $zoneExclude = $('#zone-exclude'),
        activeLineSwitchSelector = '.b-filter__switch.current-metric:not(.metric-data) .b-filter__switch-item',
        activeLineSelector = '.b-filter__switch.current-metric .m-filter__switch-item_active',
        timeSwitchSelector = '.b-filter__switch.time .b-filter__switch-item',
        daysSwitchSelector = '.b-filter__switch.days .b-filter__switch-item',
        dataMinstatSwitchSelector = '.b-filter__switch.metric-data .b-filter__switch-item',
        timeTableSwitchSelector = '.b-filter__switch.time-table .b-filter__switch-item',
        classCurrentMetric = 'current-metric',
        classMetricData = 'metric-data',
        classActive = 'm-filter__switch-item_active',
        $chartStat = $('#chart-graph-stat'),
        $chartTable = $('#b-content__traffic-table'),
        $chartStatInfo = $('.chart-graph-stat-info'),
        $chartStatError = $('.chart-graph-stat-error'),
        $chartStatLoading = $('.chart-graph-stat-loading'),
        $chartStatErrorMessage = $('.chart-graph-stat-error .message'),
        listProvidersMetrics = $.ReportsConf.ListProvidersMetrics,
        defaultCategories = $.ReportsConf.DefaultCategories,
        cookieName = 'active_graph',
        timeOut = 1000*60*5;

    // Установка стартовых значений дат:
    datepicker1.selectDate(currentDay1);
    datepicker2.selectDate(currentDay2);

    // Получение данных (в т.ч. типа метрики) для отрисовки графика Stat при старте:
    if ($('#period-stats').val()) {
        dataLineChartStat = JSON.parse($('#period-stats').val());
        actionMetric = dataLineChartStat.metric;
        processingDataStat(dataLineChartStat);
    }

    // Подсветка активного графика и переключателей при старте:
    (function(){
    
        // Подсвечиваем нужный график (категорию) по кукису:
        if ($.cookie(cookieName))
        {
            activeLine = $.cookie(cookieName);
            
            // Подсвечиваем краткий список
            var $activeLineItem = $(activeLineSwitchSelector + '[data-filter-category=' + activeLine + ']');
            if ($activeLineItem.length > 0)
            {
                $activeLineItem.addClass(classActive);
            }
            else
            {
                // Подсвечиваем первый переключатель-категорию:
                $(activeLineSwitchSelector + ':first').addClass(classActive);
            }
        }
        else
        {
            // Выбираем категорию по-умолчанию:
            var $activeLineItem = $(activeLineSwitchSelector + '[data-filter-category=' + defaultCategories[actionMetric] + ']');
            if ($activeLineItem.length > 0) {
                $activeLineItem.addClass(classActive);
            } else {
                $(activeLineSwitchSelector + ':first').addClass(classActive);
            }
            activeLine = $(activeLineSelector).data('filter-category');
            $.cookie(cookieName, activeLine);
        }


        // Подсвечиваем категории по-умолчанию для неактивных метрик:
        for (var metric in defaultCategories) {
            if (metric != actionMetric) {
                var
                    $metricSwitcher = $('.b-filter__switch.metric-cat:not(.metric-data)[data-metric=' + metric + ']'),
                    $categoryItem = $('.b-filter__switch-item[data-filter-category=' + defaultCategories[metric] + ']', $metricSwitcher);
                    
                if ($categoryItem.length > 0) {
                    $categoryItem.addClass(classActive);
                } else {
                    $('.b-filter__switch-item:first', $metricSwitcher).addClass(classActive);
                }
            }
        }

        // Подсвечиваем интервал отображения Stat, по умолчанию это min или day
        $(timeSwitchSelector + '[data-filter-category=min]').addClass(classActive);
        $(daysSwitchSelector + '[data-filter-category=day]').addClass(classActive);
        $(timeTableSwitchSelector + '[data-filter-category=min]').addClass(classActive);
        
        // Подсвечиваем отображение в таблице по-времени / по сайтам
        $(tableIntervalSwitchersSelector + '[data-filter-category=bytime]').addClass(classActive);
        $(tableCountSitesSwitchersSelector + '[data-filter-category=50]').addClass(classActive);
    
        // Для метрики minstat подсвечиваем переключатель данных:
        $(dataMinstatSwitchSelector + '[data-filter-category=sum]').addClass(classActive);
    
    })();

    // Переключение галочки "По дням":
    $byDays.change(function(){
        if (listProvidersMetrics.indexOf(actionMetric) >= 0) {
            if ($byDays.is(':checked')) {
                $datepicker2.prop('disabled', false);
            } else {
                $datepicker2.prop('disabled', true);
            }
        }
    });
    
    // Переключение типа метрики:
    $selectMetric.click(function(){
        if (!isLoadingStat)
        {
            var $this = $(this);
            
            if ($this.hasClass('current')) {
                $chartStat.click();
                return false;
            }
            
            actionMetric = $this.attr('metric');
            
            // Показываем набор переключателей и столбцов таблицы для выбранной метрики:
            $activeLinesSwitchers.hide();
            $activeLinesSwitchers.removeClass(classCurrentMetric);
            $activeLinesTable.hide();
            
            $(activeLinesSwitchersSelector + '[data-metric=' + actionMetric + ']').show();
            $(activeLinesSwitchersSelector + '[data-metric=' + actionMetric + ']').addClass(classCurrentMetric);
            $(activeLinesTableSelector + '[data-metric=' + actionMetric + ']').show();
            
            $chartTable.hide();
            
            // Обработка самого клика:
            $selectMetric.removeClass('current');
            $this.addClass('current');
            $('button.btn.dropdown-toggle').html($this.html() + ' <span class="caret"></span>');
            $chartStat.click();
            history.replaceState( {} , null, $this.attr('href') + location.hash);
            
            var isLocationHash = (location.hash == "") ? false : true;
            
            loadDataLineChartStat(isLocationHash);
            return false;
            
            /*
            // Логика с перезагрузкой стр. при смене метрики:
            window.location.href = $(this).attr('href') + location.hash;
            return false;
            */
        }
    });

    // Клик на "Применить"
    $applyButton.click(function(){
        if (!isLoadingStat)
        {
            loadDataLineChartStat();
        }
    });
    
    // Обновление данных по таймеру:
    /*
    setTimeout(function runLoad() {
        loadDataLineChartStat();
        setTimeout(runLoad, timeOut);
    }, timeOut);
    */
    
    // Обработка переключателей графиков и таблицы:
    $('.b-filter__switch-item').click(function(){
        
        var $this = $(this);
                
        if ($this.hasClass(classActive)) {
            return false;
        }
        
        $this.siblings().removeClass(classActive);
        
        // Для переключалки типа метрики minstat
        /*
        if ($this.parent().data('metric') == 'minstat') {
            var $minstatSwitchers = $this.parent().siblings().filter('.current-metric');
            $('.b-filter__switch-item', $minstatSwitchers).removeClass(classActive);
        }
        */
        
        $this.addClass(classActive);

        // Подсвечиваем переменную значения категории:
        if ($this.parent().hasClass(classCurrentMetric) && !$this.parent().hasClass(classMetricData))
        {
            activeLine = $this.data('filter-category');
            $.cookie(cookieName, activeLine);
        }
        
        // Подсвечиваем значение в таблице (поминутно/суммарно):
        if ($this.parent().hasClass('time-table'))
        {
            $(selectorTableChartStat).trigger('render-table');
        }
        // В метрике minstat смена режима данных (Сумма/Сайт/Система) :
        
        else if ($this.parent().hasClass('metric-data'))
        {
            $(selectorGraphChartStat).trigger('render-chart');
            $(selectorTableChartStat).trigger('render-table');
        }
        
        // Подсвечиваем значение в таблице (по-дням/по-сайтам/по-зонам/по-странам):
        else if ($this.parent().hasClass('category-table'))
        {
            $(selectorTableChartStat).trigger('change-category-table');
        }
        // Подсвечиваем кол-во сайтов в выборке по сайтам:
        else if ($this.parent().hasClass('count-sites'))
        {
            $(selectorTableChartStat).trigger('change-category-table');
        }
        // Подсвечиваем время в графике (мин/час) или (дни/недели/месяцы):
        else
        {
            $(selectorGraphChartStat).trigger('render-chart');
        }
        
        return false;
    });
    
    // Смена режима графика (минуты/часы)
    $(selectorGraphChartStat).on('render-chart', function(){
        renderLineChart();
    });
    // Смена режима таблицы (поимнутно/суммарно)
    $(selectorTableChartStat).on('render-table', function(){
        renderHourTable();
    });
    // Смена категорий таблицы (по-дням/по-сайтам/по-зонам/по-странам)
    $(selectorTableChartStat).on('change-category-table', function(){
        if (!isLoadingStat)
        {
            loadDataLineChartStat();
        }
    });
    
    
    // Клик на колонку "суммарно" внутри таблицы:
    $('#table-line').on('click', 'b.common-sum', function(){
        $('#table-line input').prop("checked", false);
        renderLineChart();
    });
    // Смена галочек внутри таблицы:
    $('#table-line').on('change', 'input', function(){
       renderLineChart();
    });
    // Сортировка по колонкам внутри таблицы:
    $('#table-line').on('click', 'thead.metric.sortable th b', function(){
        $('#table-line thead.metric.sortable th b').removeClass('selected');
        $(this).addClass('selected');
        $(this).toggleClass('desc');
        renderHourTable();
    });
    // Клик на название домена сайта внутри таблицы:
    $('#table-line').on('click', 'span.site-domain', function(){
        var
            siteDomain = $.trim($(this).text()),
            $showFiltersCheck = $('input#show-filters'),
            $listFiltersSite = $('.b-filters_site .list-filter input'),
            $currentFilterSite = $('.b-filters_site .list-filter input[data-text="'+ siteDomain +'"]'),
            $byZonesSwitcher = $('.b-filter__switch-item[data-filter-category="byzones"]');

        $.TableStat.SetSiteState(true);
        $showFiltersCheck.prop('checked', true);
        $showFiltersCheck.change();
        $listFiltersSite.prop('checked', false);
        $currentFilterSite.prop('checked', true);
        $currentFilterSite.change();
        $byZonesSwitcher.removeClass(classActive);
        $byZonesSwitcher.click();
    });
    
    
    // Загрузка данных графика Stat
    function loadDataLineChartStat(isLocationHash) {
                    
        var
            datesValues = [],
            byDays = $byDays.is(':checked') ? 1 : 0,
            isFiltersApply = $('input#show-filters').is(':checked'),
            geoFilter = null,
            sitesFilter = null,
            zonesFilter = null,
            listGeo = [],
            listSites = [],
            listZones = [],
            filtersUrl = '',
            getHashVars = !(isLocationHash !== undefined && !isLocationHash),
            countByCategory = $(tableCountSitesSwitchersSelector + '.' + classActive).data('filter-category'),
            bySites = $(tableIntervalSwitchersSelector + '[data-filter-category=bysites]').hasClass(classActive) ? countByCategory : 0,
            byZones = $(tableIntervalSwitchersSelector + '[data-filter-category=byzones]').hasClass(classActive) ? countByCategory : 0,
            byCountries = $(tableIntervalSwitchersSelector + '[data-filter-category=bycountries]').hasClass(classActive) ? countByCategory : 0;
        
        // Вторая дата меньше первой:
        if (datepicker2.selectedDates[0]-datepicker1.selectedDates[0] < 0) {
            datepicker2.selectDate(datepicker1.selectedDates[0]);
        }
        
        // Скрываем 2-ю дату для метрик по провайдерам:
        if (listProvidersMetrics.indexOf(actionMetric) >= 0) {
            if (!getHashVars) {
                datepicker1.selectDate(datepicker2.selectedDates[0]);
            }
            if (!byDays) {
                datepicker2.selectDate(datepicker1.selectedDates[0]);
            }
        }
    
        datesValues.push(formatDate(datepicker1.selectedDates[0]));
        datesValues.push(formatDate(datepicker2.selectedDates[0]));
        datesValues.push(byDays);
        
        if  (getHashVars) {
            filtersUrl += '&dates=' + datesValues.join(',');
            filtersUrl += '&al=' + activeLine;
            filtersUrl += '&at=' + $(timeSwitchSelector + '.m-filter__switch-item_active').data('filter-category');
            filtersUrl += '&ad=' + $(daysSwitchSelector + '.m-filter__switch-item_active').data('filter-category');
        }
        
        // Применяем фильтры, если они включены:
        if (isFiltersApply) {

            $('.b-filters_geo input.geo-item').each(function(){
                if ($(this).is(':checked')) {
                    listGeo.push($(this).data('id'));
                }
            });
            $('.b-filters_site .values-string-list li').each(function(){
                listSites.push($('input', $(this)).data('id'));
            });
            // Если нет опции исключить, то добавляем в список сайты, выделенные галочками в таблице:
            if (!$siteExclude.is(':checked') && bySites && $.TableStat.CheckedCategories()) {
                var CheckedCategoriesId = $.TableStat.CheckedCategories();
                if (CheckedCategoriesId) {
                    CheckedCategoriesId.forEach(function(itemId){
                        if (listSites.indexOf(itemId)<0) {
                            listSites.push(itemId);
                        }
                    });
                }
            }
            
            $('.b-filters_zone .values-string-list li').each(function(){
                listZones.push($('input', $(this)).data('id'));
            });

            if (listGeo.length > 0) {
                geoFilter = {
                    'exclude': ($geoExclude.is(':checked')) ? 1 : 0,
                    'list': listGeo
                };

                if (geoFilter.exclude) {
                    filtersUrl += '&geo_not=' + geoFilter.list.join(',');
                } else {
                    filtersUrl += '&geo_in=' + geoFilter.list.join(',');
                }
            }
            if (listSites.length > 0) {
                sitesFilter = {
                    'exclude': ($siteExclude.is(':checked')) ? 1 : 0,
                    'list': listSites
                };
                
                if (sitesFilter.exclude) {
                    filtersUrl += '&sites_not=' + sitesFilter.list.join(',');
                } else {
                    filtersUrl += '&sites_in=' + sitesFilter.list.join(',');
                }
            }
            if (listZones.length > 0) {
                zonesFilter = {
                    'exclude': ($zoneExclude.is(':checked')) ? 1 : 0,
                    'list': listZones
                };
                
                if (zonesFilter.exclude) {
                    filtersUrl += '&zones_not=' + zonesFilter.list.join(',');
                } else {
                    filtersUrl += '&zones_in=' + zonesFilter.list.join(',');
                }
            }    
        }

        //console.log('AAA datesValues = ', datesValues);
        //console.log('AAA geoFilter = ', geoFilter);
        //console.log('AAA sitesFilter = ', sitesFilter);
        //console.log('AAA zonesFilter = ', zonesFilter);
        
        //location.hash = filtersUrl;
        filtersUrl = (filtersUrl == '') ? '' : '#' + filtersUrl;
        history.replaceState( {} , null, location.pathname + filtersUrl);
        
        isLoadingStat = true;
        EnableLoadingState(isLoadingStat);
        
        
        var requestData = {
            action: actionMetric,
            dates: datesValues,
            geo: geoFilter,
            sites_id: sitesFilter,
            zones_id: zonesFilter,
            by_sites: bySites,
            by_zones: byZones,
            by_countries: byCountries,
        };
        
        //console.log('AAA loadDataLineChartStat requestData = ', requestData);
        requestDataStatReport(requestData);
    };
    
    // Отрисовка данных по фильтрам:
    function renderDataCurrentFilters(currentFilters)
    {
        //console.log('AAA renderDataCurrentFilters = ', currentFilters);
        
        var
            datesValues = [],
            geoFilter = null,
            sitesFilter = null,
            zonesFilter = null;
        
        // Устанавливаем переключатели графика по url:
        if (currentFilters.al) {
            if ($(activeLineSwitchSelector + '[data-filter-category=' + currentFilters.al + ']').length) {
                $(activeLineSwitchSelector).removeClass(classActive);
                $(activeLineSwitchSelector + '[data-filter-category=' + currentFilters.al + ']').addClass(classActive);
                activeLine = $(activeLineSelector).data('filter-category');
            }
        }
        if (currentFilters.at) {
            $(timeSwitchSelector).removeClass(classActive);
            $(timeSwitchSelector + '[data-filter-category=' + currentFilters.at + ']').addClass(classActive);
        }
        if (currentFilters.ad) {
            $(daysSwitchSelector).removeClass(classActive);
            $(daysSwitchSelector + '[data-filter-category=' + currentFilters.ad + ']').addClass(classActive);
        }
        
        // dates-filter
        if (currentFilters.dates) {
            datesValues = currentFilters.dates;
            
            var
                date1 = new Date(datesValues[0]),
                date2 = new Date(datesValues[1]),
                byDays = (datesValues[2] == 1);
            
            /*
            // Вторая дата меньше первой:
            if (datepicker2.selectedDates[0]-datepicker1.selectedDates[0] < 0) {
                datepicker2.selectDate(datepicker1.selectedDates[0]);
            }
            // Скрываем 2-ю дату для метрик по провайдерам:
            if (listProvidersMetrics.indexOf(actionMetric) >= 0) {
                if (byDays) {
                    //datepicker1.selectDate(datepicker2.selectedDates[0]);
                } else {
                    datepicker2.selectDate(datepicker1.selectedDates[0]);
                }
            }
            */
            
            datepicker1.selectDate(date1);
            datepicker2.selectDate(date2);
            if (byDays) {
                $byDays.prop("checked", true);
            }
        } else {
            datesValues.push(formatDate(datepicker1.selectedDates[0]));
            datesValues.push(formatDate(datepicker2.selectedDates[0]));
            datesValues.push(0);
        }
        
        // geo-filter
        if (currentFilters.geo_in) {
            geoFilter = {
                'exclude': 0,
                'list': currentFilters.geo_in
            };
        }
        if (currentFilters.geo_not) {
            geoFilter = {
                'exclude': 1,
                'list': currentFilters.geo_not
            };
        }
        
        // sites-filter
        if (currentFilters.sites_in) {
            sitesFilter = {
                'exclude': 0,
                'list': currentFilters.sites_in
            };
        }
        if (currentFilters.sites_not) {
            sitesFilter = {
                'exclude': 1,
                'list': currentFilters.sites_not
            };
        }
        
        // zones-filter
        if (currentFilters.zones_in) {
            zonesFilter = {
                'exclude': 0,
                'list': currentFilters.zones_in
            };
        }
        if (currentFilters.zones_not) {
            zonesFilter = {
                'exclude': 1,
                'list': currentFilters.zones_not
            };
        }
        
        var requestData = {
            action: actionMetric,
            dates: datesValues,
            geo: geoFilter,
            sites_id: sitesFilter,
            zones_id: zonesFilter
        };
        
        requestDataStatReport(requestData);
    }
    
    function requestDataStatReport(dataRequest)
    {
        //console.log("AAA requestDataStatReport: ", dataRequest);
        $.ajax({
            url: '/statistics/',
            method: 'POST',
            data: dataRequest,
            success: function(res) {
                //console.log("AAA requestDataStatReport success res: ", res);
                isLoadingStat = false;
                EnableLoadingState(isLoadingStat);
                
                $chartStatError.hide();
                if (res == null) {
                    $chartStat.hide();
                    $chartTable.hide();
                    $chartStatInfo.show();
                } else if (res.status == 'Error') {
                    $chartStat.hide();
                    $chartTable.hide();
                    $chartStatInfo.hide();
                    $chartStatErrorMessage.text(res.error);
                    $chartStatError.show();
                } else {
                    $chartStatInfo.hide();
                    $chartStat.show();
                    $chartTable.show();
                    dataLineChartStat = res;
                    processingDataStat(dataLineChartStat);
                    renderLineChart();
                    renderHourTable();
                }
            },
            error: function (e) {
                //console.log('error: ', e);
                isLoadingStat = false;
                EnableLoadingState(isLoadingStat);
                $chartStat.hide();
                $chartTable.hide();
                $chartStatInfo.hide();
                $chartStatError.show();
            }
        });
    }
    
    // Обработка данных dataLineChartStat
    function processingDataStat(data)
    {
        if (data) {
            // Скрываем 2-ю дату для метрик по провайдерам при выключенной "по дням":
            if (listProvidersMetrics.indexOf(actionMetric) >= 0 && !$byDays.is(':checked')) {
                $datepicker2.prop('disabled', true);
            }
            // Скрываем списки зон у метрики pagestat
            if (actionMetric == 'pagestat') {
                $zonesWrap.hide();
            } else {
                $zonesWrap.show();
            }
        }
    }
    
    // Отрисовка графика Stat
    function renderLineChart()
    {
        if(dataLineChartStat) {
            //console.log('AAA dataLineChartStat = ', dataLineChartStat);
            
            // Показ переключателей "минуты-часы" и "дни-недели-месяцы" :
            if (dataLineChartStat.type == 'interval') {
                $timeSwitchers.hide();
                $daysSwitchers.show();
            } else {
                $daysSwitchers.hide();
                $timeSwitchers.show();
            }
            
            // Показываем переключатель по-дням/по-сайтам :
            if (dataLineChartStat.type == 'compare') {
                $tableSwitcherCategory.hide();
            } else {
                $tableSwitcherCategory.show();
            }
            
            // Показываем переключатель кол-ва сайтов:
            if (dataLineChartStat.bySites || dataLineChartStat.byZones || dataLineChartStat.byCountries) {
                $tableSwitcherCountSites.show();
                $tableSwitcherTimeSum.hide();
                $byDays.attr("disabled", true);
            } else {
                $tableSwitcherCountSites.hide();
                $byDays.attr("disabled", false);
            }
            
            // Проверка метрики на наличие данных по сайтам, зонам, странам:
            if (dataLineChartStat.bySites || dataLineChartStat.byZones || dataLineChartStat.byCountries) {
                $.ChartStat.CategoryStat(dataLineChartStat);
            }
            // Проверка метрики на наличие данных по провайдерам:
            else if (listProvidersMetrics.indexOf(dataLineChartStat.metric) < 0) {
                $.ChartStat.DateStat(dataLineChartStat);
            } else {
                $.ChartStat.ProviderStat(dataLineChartStat);
            }
        }
    }
        
    // Отрисовка почасовой таблицы
    function renderHourTable()
    {
        if(dataLineChartStat) {
            // Проверка метрики на наличие данных по сайтам:
            if (dataLineChartStat.bySites) {
                $.TableStat.Render(dataLineChartStat);
                $chartTable.show();
            }
            // Проверка метрики на наличие данных по зонам:
            /*
            else if (dataLineChartStat.byZones) {
                $.TableStat.Render(dataLineChartStat);
                $chartTable.show();
            }
            */
            // Проверка метрики на наличие данных по провайдерам:
            else if (listProvidersMetrics.indexOf(dataLineChartStat.metric) < 0) {
                $.TableStat.Render(dataLineChartStat);
                $chartTable.show();
            } else {
                $chartTable.hide();
            }
        } else {
            $chartTable.hide();
        }     
    }
    
    // Распарсиваем строку URL с фильтрами:
    var
        hashUrl = location.hash.replace('#', '').split('&'),
        filtersNames = ['dates', 'geo_in', 'geo_not', 'sites_in', 'sites_not', 'zones_in', 'zones_not', 'al', 'at', 'ad'],
        currentFilters = [];

    hashUrl.forEach(function(item) {
        if (item != '' && item.indexOf('=')>-1) {
            var
                filterItem = item.split('='),
                filterName = filterItem[0],
                filterValue = (filterItem[1] == '') ? null : filterItem[1].split(',');
            
            if (filtersNames.indexOf(filterName) != -1 && filterValue) {
                currentFilters[filterName] = filterValue;
            }
        }
    });
    
    // Отрисовка графика и таблицы при старте:
    if (Object.keys(currentFilters).length == 0)
    {
        // Отрисовка графика и таблицы по стартовым данным: console.log('AAA dataLineChartStat = ', dataLineChartStat);
        renderLineChart();
        renderHourTable();
    }
    else
    {
        // Отрисовка графика и таблицы по фильтрам из url:
        $timeSwitchers.hide();
        $daysSwitchers.hide();
        $chartStatLoading.show();
        renderDataCurrentFilters(currentFilters);
    }
    
    
    // Фильтры
    (function(){
        
        var
            $filters = $('.b-filters'),
            $showFilters = $('input#show-filters'),
            $filtersItems = $('.b-filters_site, .b-filters_zone'),
            $sitesList = $('.b-filters_site .values-string-list'),
            filtersVars = ['geo_in', 'geo_not', 'sites_in', 'sites_not', 'zones_in', 'zones_not'];
        
        // Запрос списка фильтров:
        function RequestFilters() {
            
            // Подгружаем список фильтров:
            var
                templateZoneItem = _.template('' +
                    '<li data-site="<%= data[\'site_id\'] %>" data-domain="<%= data[\'domain\'] %>">' +
                    '    <input type="checkbox" id="zone-id-<%= zoneId %>" data-id="<%= zoneId %>" data-text="<%= zoneId %>" data-size="<%= data[\'size\'] %>">' +
                    '    <label for="zone-id-<%= zoneId %>"><%= zoneId %> [<%= data[\'size\'] %>] - <%= data[\'domain\'] %></label>' +
                    '</li>'
                ),
                templateSiteItem = _.template('' +
                    '<li>' +
                    '    <input type="checkbox" id="site-id-<%= site.id %>" data-id="<%= site.id %>" data-text="<%= site.domain %>">' +
                    '    <label for="site-id-<%= site.id %>">[<%= site.id %>] <%= site.domain %></label>' +
                    '</li>'
                ),
                templateGeoItem = _.template('' +
                    '<input type="checkbox" class="geo-item" id="geo-<%= geoId %>" data-id="<%= geoId %>"> ' +
                    '<label for="geo-<%= geoId %>"><%= geoName %></label> '
                );


            // Запрашиваем списки стран:
            $.ajax({
                url: '/statistics/',
                method: 'POST',
                data: {
                    action: 'geolist',
                    metric: actionMetric,
                },
                success: function(geo) {
                    //console.log('AAA filters geo = ', geo);
                    if (geo) {
                        var $geoListWrap = $('.b-filters_geo .geo-list');
                        for(var geoId in geo){
                            $geoListWrap.append(templateGeoItem({geoId: geoId, geoName: geo[geoId]}));
                        }
                    }
                    SetCurrentFilters(currentFilters, 'geo');
                },
                error: function (e) {
                    console.log('error geolist: ', e);
                }
            });

            
            var
                sitesListIsLoaded = false,
                zonesListIsLoaded = false,
                $filtersSitesZonesControls = $('.b-filters_sites-zones button, .b-filters_sites-zones input'),
                $filtersSitesZonesWrap = $('.b-filters_sites-zones');

            $filtersSitesZonesControls.prop('disabled', true);
            $filtersSitesZonesWrap.addClass('state-loading');
            
            // Запрашиваем списки сайтов:
            $.ajax({
                url: '/statistics/',
                method: 'POST',
                data: {
                    action: 'siteslist',
                },
                success: function(sites) {
                    //console.log('AAA filters sites = ', sites);
                    sitesListIsLoaded = true;
                    if (sites) {
                        var $sitesListWrap = $('.b-filters_site .list-filter');
                        sites.forEach(function(item) {
                            $sitesListWrap.append(templateSiteItem({site: item}));
                        });
                    }
                    
                    if (zonesListIsLoaded) {
                        $filtersSitesZonesControls.prop('disabled', false);
                        $filtersSitesZonesWrap.removeClass('state-loading');
                        SetCurrentFilters(currentFilters, 'sites');
                        SetCurrentFilters(currentFilters, 'zones');
                    }
                },
                error: function (e) {
                    console.log('error siteslist: ', e);
                }
            });
            
            // Запрашиваем списки зон:
            $.ajax({
                url: '/statistics/',
                method: 'POST',
                data: {
                    action: 'zoneslist',
                },
                success: function(zones) {
                    //console.log('AAA filters zones = ', zones);
                    zonesListIsLoaded = true;
                    if (zones) {
                        var $zonesListWrap = $('.b-template-zones-list');
                        for(var zoneId in zones){
                            $zonesListWrap.append(templateZoneItem({zoneId: zoneId, data: zones[zoneId]}));
                        }
                    }
                    
                    if (sitesListIsLoaded) {
                        $filtersSitesZonesControls.prop('disabled', false);
                        $filtersSitesZonesWrap.removeClass('state-loading');
                        SetCurrentFilters(currentFilters, 'sites');
                        SetCurrentFilters(currentFilters, 'zones');
                    }
                },
                error: function (e) {
                    console.log('error zoneslist: ', e);
                }
            });

        }
        
        // Устанавливаем значения для текущих фильтров:
        function SetCurrentFilters(currentFilters, type)
        {
            var isFiltersInCurrent = false;
            filtersVars.forEach(function(item) {
                isFiltersInCurrent = (currentFilters[item]) ? true : isFiltersInCurrent;
            });
            
            if (!isFiltersInCurrent) {
                return false;
            }
            
            // Разворачиваем фильтры:
            $showFilters.attr('checked', true);
            $filters.show();
            
            switch(type) {
                case 'geo':
                    if (currentFilters.geo_in || currentFilters.geo_not) {
                        if (currentFilters.geo_not) {
                            $geoExclude.prop("checked", true);
                        }
                        (currentFilters.geo_in || currentFilters.geo_not).forEach(function(item) {
                            $('.geo-item[data-id="' + item + '"]').prop("checked", true);
                        });
                    }
                    break;
                case 'sites':
                    if (currentFilters.sites_in || currentFilters.sites_not) {
                        if (currentFilters.sites_not) {
                            $siteExclude.prop("checked", true);
                        }
                        (currentFilters.sites_in || currentFilters.sites_not).forEach(function(item) {
                            $('.b-filters_site .list-filter input[data-id="' + item + '"]').click();
                        });
                    }
                    break;
                case 'zones':
                    if (currentFilters.zones_in || currentFilters.zones_not) {
                        if (currentFilters.zones_not) {
                            $zoneExclude.prop("checked", true);
                        }
                        (currentFilters.zones_in || currentFilters.zones_not).forEach(function(item) {
                            $('.b-filters_zone .list-filter input[data-id="' + item + '"]').click();
                        });
                    }
                    break;
            }
            
        }
        
        // Обработка изменения в списках сайтов-фильтров:
        function ChangeListSites() {
            
            /*
            if ($zonesWrap.is(":hidden")) {
                return false;
            }
            */

            var
                $filtersZone = $('.b-filters_zone'),
                $sitesItems = $('.b-filters_site .values-string-list li'),
                noFilterSites = ($sitesItems.length == 0) ? true : false,
                $selectedZones = $('.b-filters_zone .values-string-list'),
                $listZones = $('.b-filters_zone .list-filter');

            // Пустой список фильтров-сайтов:
            if (noFilterSites) {
                
                $filtersZone.hide();
                $selectedZones.empty();
                $listZones.empty();
                
            } else {
                
                //console.log('AAA ChangeListSites');
                
                $listZones.empty();
                $sitesItems.each(function(){
                    
                    var
                        //siteId = $(this).data('id'),
                        siteId = $('input', $(this)).data('id'),
                        $zoneItems = $('.b-template-zones-list li[data-site="'+ siteId +'"]').clone(),
                        $input,
                        $label,
                        zoneId;
                    
                    $zoneItems.each(function(ind, $zoneItem){
                        $input = $('input', $zoneItem),
                        $label = $('label', $zoneItem),
                        zoneId = $input.attr('id');

                        $input.attr('id', 'm_' + zoneId);
                        $label.attr('for', 'm_' + zoneId);
                    });
                    
                    $listZones.append($zoneItems);
                });
                
                // Логика выставления галочек уже выбранных зон:
                $('li', $selectedZones).each(function(){
                    var
                        //zoneItemId = $(this).data('id'),
                        zoneItemId = $('input', $(this)).data('id'),
                        $zoneItem = $('input[data-id="' + zoneItemId + '"]', $listZones);
                    
                    // Удаления зоны из списка при удалении её сайта:
                    if ($zoneItem.length == 0) {
                        $(this).remove();
                    } else {
                        $zoneItem.attr('checked', true);
                    }
                });
                
                $filtersZone.show();
            }
        }
        
        RequestFilters();
        
        // Показ/скрытие фильтров:
        $showFilters.on('change', function(){
            if ($(this).is(':checked')) {
                $filters.show();
            } else {
                $filters.hide();
            }
        });
        
        // Изменение списка фильтров чекбоксом:
        $filtersItems.on('change', '.list-filter input',function(){
            
            var
                $listItems = $('li', $(this).parents('ul')),
                $listString = $('.values-string-list', $(this).parents('.form-group')),
                values = [],
                tplId = ($(this).parents('.b-filters_site').length) ? 'l-site-id-' : 'l-zone-id-';
            
            $listItems.each(function(){
                var
                    $this = $(this),
                    $checkbox = $('input', $this);
                    
                if ($checkbox.is(':checked')) {
                    values.push([$checkbox.data('id'), $checkbox.data('text')]);
                }
            });
            
            $listString.empty();
            if (values.length > 0) {
                values.forEach(function(valuesItem) {
                    //$listString.append('<span data-id="' + valuesItem[0] + '">' + valuesItem[1] + '&nbsp;<a class="close" style="cursor: pointer;">×</a></span> ');
                    $listString.append('<li><input type="checkbox" checked id="' + tplId + valuesItem[0] + '" data-id="' + valuesItem[0] + '" data-text="' + valuesItem[1] + '"> <label for="' + tplId + valuesItem[0] + '">[' + valuesItem[0] + '] ' + valuesItem[1] + '</label></li>');
                });
            }
            $listString.trigger('change');
        });
        
        // Удаление из списка фильтров снятием галочки:
        $filtersItems.on('change', '.values-string-list input',function(){
            var
                itemId = $(this).data('id'),
                $listFilterItem = $('.list-filter input[data-id="' + itemId + '"]', $(this).parents('.form-group'));
            
            $listFilterItem.attr('checked', false);
            $listFilterItem.change();
        });
        
        // Изменение фильтрации внутри фильтра:
        $filtersItems.on('keyup', 'input.filter',function(){
            var
                $this = $(this),
                val = $this.val(),
                $listItems = $('.filters-select li', $this.parents('.form-group'));
            
            // Фильтрация списка сайтов:
            if ($this.attr('name') == 'sites-filter') {
                $listItems.each(function(){
                    var
                        $item = $(this),
                        id = $('input', $item).data('id').toString(),
                        domain = $('input', $item).data('text'),
                        reg = new RegExp("^\\d+"+val+"$", "i");
                        
                    $item.hide();
                    if (domain.indexOf(val) == 0 || id.match(reg)) {
                        $item.show();
                    }
                    
                });
            }
            
            // Фильтрация списка зон:
            if ($this.attr('name') == 'zones-filter') {
                $listItems.each(function(){
                    var
                        $item = $(this),
                        id = $('input', $item).data('id').toString(),
                        size = $('input', $item).data('size'),
                        width = size.split('x')[0],
                        height = size.split('x')[1],
                        reg = new RegExp("^\\d+"+val+"$", "i");
                    
                    $item.hide();
                    if (size == val || width == val || height == val || id.match(reg)) {
                        $item.show();
                    }
                    
                });
            }
            
        });
        
        // Отслеживаем изменение в списках сайтов:
        $sitesList.on('change', function(){
            ChangeListSites();
        });
        
    })();
    
});