ID69 / ConsulWar advanced script

// ==UserScript==
// @name        ConsulWar advanced script
// @namespace   consulwar.ru
// @description add more filter/interface functionality
// @include     consulwar.ru*
// @require     https://code.jquery.com/jquery-1.12.4.js
// @require     https://code.jquery.com/ui/1.12.1/jquery-ui.js
// @version     1.1.40
// @author      ID69 (http://consulwar.ru/game/statistics/general/#ID69)
// @collaborator fusioneer
// @collaborator Eilandor
// @match       https://consulwar.ru/
// @match       https://consulwar.ru/game/*
// @license MIT
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_listValues
// @grant       GM_deleteValue
// @grant       GM_xmlhttpRequest
// ==/UserScript==

/* RELEASE NOTES
  1.1.40
    + цены с уровня на который улучшаемся
  1.1.39
    + фикс цен для исследований
  1.1.38
    - убрана раскраска планет по секторам
    - убрано отображение времени респавна
    - убран фильтр планет в космосе
  1.1.37
    + расчет цен возвращен
  1.1.36
    + Скрипт загружается при заходе через главную consulwar.ru
  1.1.35
    + цвета в фильтре планет поправлены
  1.1.34
    - убран расчет цен для зданий, теперь есть в игре
  1.1.33
    + поправлен расчет цен для зданий
  1.1.32
    - убран устаревший функционал и ненужные вкладки
  1.1.31
    + CWAS не пытается запуститься на неподходящих страницах
  1.1.30
    + Поправлены рассчеты цен для зданий
  1.1.29
    + Возвращена возможность искать только по своей галактике
  1.1.28
    + Исправлено дублирование имён и утечка памяти в фильтрах
  1.1.27
    + Поиск флотов с фильтром по общекосмосу
    + Выбор галактики в фильтрах из списка
  1.1.26
    + Исключающий фильтр артефактов/планет
  1.1.25
    + Фильтр общекосмос. fusioneer
  1.1.24
    + Другая ширина обводки. автор Xorboo
  1.1.23
    + Раскраска планет по секторах. Реализация: Eilandor
  1.1.22
    + Строка для ленивого копировання в гугл таблицу
  1.1.21
    + More planet statistics
  1.1.20
    + fleet filter max value set to 7
  1.1.19
    + container opener updated
  1.1.18
    + возможность отображать весь сектор если есть хотя-бы одна планета
  1.1.17
    + css error fixed
  1.1.16
    + http заменен на https
  1.1.15
    + рефакторинг и чистка
    + выпадающий список планет
  1.1.14
    + улучшения интерфейса
    + фильтр планет по типу
  1.1.13
    + скрипт открытия контейнеров
  1.1.12
    + не показывать спрятаные планеты в списке
    + возможность начинать с текущего уровня
  1.1.11
    + поиск флотов
  1.1.10
    + работает с новыми исследованиями (немного ломает улучшения кораблей)
    + правильно работает с интервалами меньше 20, правильно считает все с 0 по 100 (спасибо @fusioneer)
  1.1.9
    + убрано дублирование сектора+рукава и времени спавна
    + поправлено(теоретически) появление рассчета цены в турнире Колизея
    + добавлен расчёт цен для исследований
  1.1.8
    + расчёт цен вместо описания
  1.1.7
    + вывод сектора планеты в ее попапе
    + вывод времени респавна планеты в ее попапе
  1.1.6
    - расположение награды за бой
    - возможность убрать фон
    + исправлены мелкие недоработки
  1.1.4
    + фильтр планет в диалоге (проценты отображаються для первого из выбраных по списку)
  1.1.3
    + возможность немного подправить отображение награды за бой
  1.1.2
    + кнопка для ревертирования выбраных чекбоксов фильтра планет
  1.1.0
    + добавлена возможность спрятать планету с 3 артефактами из списка выбраных
  1.0.0
    + button to create links in chat
    + removing of background
*/

(function(){

    'use strict';
    console.log(' ================ start CWAS - ');
    var page = new PageData();
    var userOptions = initOptions();
    userOptions.loadUserData(page.currentUser);
    addNewCSSClasses();
    makePropElements();

    applyUserScriptChanges();
    addButtonForCWAS();
    initialSetupCWAS();

    console.log(' ================ end CWAS - ');

    function addButtonForCWAS(){
        Template.main_menu.onRendered(function() {
            var topRight = $(".main_menu");
            topRight.append('<li><label id="cwas_prop-button" style="align-self: center;" for="cwas-modal-1">CWAS</label></li>');
            $('label#cwas_prop-button').click(openProp);
        });
    }

    function initialSetupCWAS(){
        Template.main_menu.onRendered(function() {
        });
    }

    function openProp(){
        var $propDialog = $('#cwas-prop-gui-dialog');
        $propDialog.find('#cwas-gui-addLinkMakerVal').prop('checked', userOptions.val('linkMaker'));
        $propDialog.find('#cwas-gui-addPriceCalculatorVal').prop('checked', userOptions.val('priceCalculator'));
        $propDialog.find('#cwas-gui-startInPriceCalculatorVal').prop('checked', userOptions.val('startInPriceCalculator'));
        $propDialog.find('#cwas-gui-addHandAndSegmentVal').prop('checked', userOptions.val('handAmdSegment'));
        $propDialog.find('#cwas-prop-gui-tabs').tabs({active: 0});
        $propDialog.find('#cwas-prop-gui-tabs').tabs({selected: 0});
        $propDialog.find('#cwas-prop-gui-tabs').tabs({focused: 0});
    }

    function makePropElements(){
        $('body').append(`
     <div id="cwas-prop-gui-dialog">
        <input class="cwas-modal-state" id="cwas-modal-1" type="checkbox" />
        <div class="cwas-modal">
          <label class="cwas-modal__bg" for="cwas-modal-1"></label>
          <div class="cwas-modal__inner">
            <div class="cwas-prop-gui-contentTop">
              <span style="color: #8B857B;font-weight: bold; line-height: 27px; padding-left: 8px;">
                CWAS - Consul War Advanced Script
              </span>
              <label class="cwas-modal__close" for="cwas-modal-1"></label>
            </div>
            <div class="cwas-prop-gui-contentMain">
              <div id="cwas-prop-gui-tabs" style="border: 0 none; position: initial;">
                <ul class="cwas-tabs-nav">
                  <li id="cwas-tabs-nav-0"><a href="#cwas-prop-gui-tab-1"></a></li>
                  <li id="cwas-tabs-nav-1"><a href="#cwas-prop-gui-tab-2"></a></li>
                </ul>
                <div id="cwas-prop-gui-tab-1" class="cwas-tabs-panel">
                  <div class="cwas-tabs-panel-content">
                    <section class="cwas-prop-gui-section">
                      <input id="cwas-gui-addLinkMakerVal" type="checkbox" style="vertical-align: middle;"/>
                      <label id="cwas-gui-addLinkMakerCaption" for="cwas-gui-addLinkMakerVal" style="cursor: pointer;vertical-align: middle;"></label>
                    </section>
                    <section class="cwas-prop-gui-section">
                      <input id="cwas-gui-addPriceCalculatorVal" type="checkbox" style="vertical-align: middle;"/>
                      <label id="cwas-gui-addPriceCalculatorCaption" for="cwas-gui-addPriceCalculatorVal" style="cursor: pointer;vertical-align: middle;"></label>
                      <input id="cwas-gui-startInPriceCalculatorVal" type="checkbox" style="vertical-align: middle;"/>
                      <label id="cwas-gui-startInPriceCalculatorCaption" for="cwas-gui-startInPriceCalculatorVal" style="cursor: pointer;vertical-align: middle;"></label>
                    </section>
                  </div>
                </div>
                <div id="cwas-prop-gui-tab-2" class="cwas-tabs-panel">
                  <div class="cwas-tabs-panel-content">
                    <section class="cwas-prop-gui-section">
                       <input id="cwas-gui-createPlanetFilterDialog" style="padding-left: 20px;
                        padding-right: 20px; height: 30px;" class="ui-button ui-corner-all" value="Planet Filter" type="button">
                    </section>
                    <hr>
                    <section class="cwas-prop-gui-section">
                       <input id="cwas-gui-addHandAndSegmentVal" type="checkbox" style="vertical-align: middle;"/>
                       <label id="cwas-gui-addHandAndSegmentCaption" for="cwas-gui-addHandAndSegmentVal" style="cursor: pointer;vertical-align: middle;"></label>
                    </section>
                    <hr>
                    <section class="cwas-prop-gui-section">
                      <input id="cwas-gui-createFleetFilterDialog" style="padding-left: 20px;
                        padding-right: 20px; height: 30px;" class="ui-button ui-corner-all" value="Fleet Filter" type="button">
                    </section>
                    <hr>
                    <section class="cwas-prop-gui-section">
                      <input id="cwas-gui-createPlanetTypeFilterDialog" style="padding-left: 20px;
                        padding-right: 20px; height: 30px;" class="ui-button ui-corner-all" value="Planet Type Filter" type="button">
                    </section>
                  </div>
                </div>
              </div>
            </div>
            <div  id="cwas-prop-gui-bottomCcontent" class="cwas-prop-gui-contentBottom">
              <input id="cwas-gui-SaveSettings" style="padding-left: 20px;
               padding-right: 20px; height: 30px;" class="ui-button ui-corner-all cwas-prop-gui-button-right" value="Save" type="button">
            </div>
          </div>
        </div>
      </div>
   `);

        $('body').append(`
      <div id="cwas-dialog-linkMaker" title="Добавить ссылку в сообщение" style="display:none;">
        <div style="margin-bottom: 20px;">
         <label for="cwas-dialog-linkURI">Адрес ссылки</label>
         <input id="cwas-dialog-linkURI" class="text ui-widget-content ui-corner-all cwas-input-toRight" type="textarea">
        </div>
        <div style="margin-bottom: 20px;">
         <label for="cwas-dialog-linkText">Отображаемый текст</label>
         <input id="cwas-dialog-linkText" class="text ui-widget-content ui-corner-all cwas-input-toRight" type="textarea">
        </div>
        <div>
         <input id="cwas-dialog-addLinkToMessage" class="ui-button ui-corner-all cwas-input-toRight" value="Add" type="button">
        </div>
      </div>
    `);

        var $propDialog = $('#cwas-prop-gui-dialog');

        $propDialog.find('[id*=cwas-tabs-nav-]').click(function(){
            $propDialog.find('#cwas-prop-gui-tabs').tabs({active: $(this).attr('id').replace('cwas-tabs-nav-', '')});
        });

        makeServiceGUIButton();
        updateGuiLocalize();
    }

    function updateGuiLocalize(){
        var $propDialog = $('#cwas-prop-gui-dialog');
        $propDialog.find('#cwas-gui-addLinkMakerCaption').text(userOptions.getGuiDesc('linkMaker'));
        $propDialog.find('#cwas-gui-addPriceCalculatorCaption').text(userOptions.getGuiDesc('priceCalculator'));
        $propDialog.find('#cwas-gui-startInPriceCalculatorCaption').text(userOptions.getGuiDesc('startInPriceCalculator'));
        $propDialog.find('#cwas-gui-addHandAndSegmentCaption').text(userOptions.getGuiDesc('handAmdSegment'));
        $propDialog.find('#cwas-tabs-nav-0>a').text(userOptions.getGuiDesc('cwasTabsNav0'));
        $propDialog.find('#cwas-tabs-nav-1>a').text(userOptions.getGuiDesc('cwasTabsNav1'));
    }

    function makeServiceGUIButton(){
        var $propDialog = $('#cwas-prop-gui-dialog');

        $propDialog.find('#cwas-gui-SaveSettings').click(function(){
            var $propDialog = $('#cwas-prop-gui-dialog');
            userOptions.val('linkMaker', $propDialog.find('#cwas-gui-addLinkMakerVal').prop('checked'));
            userOptions.val('priceCalculator', $propDialog.find('#cwas-gui-addPriceCalculatorVal').prop('checked'));
            userOptions.val('startInPriceCalculator', $propDialog.find('#cwas-gui-startInPriceCalculatorVal').prop('checked'));
            userOptions.val('handAmdSegment', $propDialog.find('#cwas-gui-addHandAndSegmentVal').prop('checked'));

            updateGuiLocalize();
            userOptions.saveUserData(page.currentUser);
            closeSettingDialog();
            applyUserScriptChanges();
        });

        $propDialog.find('#cwas-gui-createPlanetFilterDialog').click(function(){
            createPlanetFilterDialog();
        });

        $propDialog.find('#cwas-gui-createFleetFilterDialog').click(function(){
            createFleetFilterDialog();
        });

        $propDialog.find('#cwas-gui-createPlanetTypeFilterDialog').click(function(){
            createPlanetTypeFilterDialog();
        });
    }

    function newCssClass(cssClass){
        var head = document.head || document.getElementsByTagName('head')[0];
        var style = document.createElement('style');

        style.type = 'text/css';
        if(style.styleSheet){
            style.styleSheet.cssText = cssClass;
        }else{
            style.appendChild(document.createTextNode(cssClass));
        }
        head.appendChild(style);
    }

    function closeSettingDialog(){
        $('#cwas-prop-gui-dialog').find('label.cwas-modal__close').click();
    }

    function applyUserScriptChanges(){
        if (userOptions.val('linkMaker')) {
            addLinkMaker();
        }
        if (userOptions.val('priceCalculator')) {
            addPriceCalculator();
        }
        if (userOptions.val('handAmdSegment')) {
            addHandAndSegment();
        }
    }

    function addLinkMaker(){
        Template.chat.onRendered(function() {
            var messageBlock = $("#message");
            messageBlock.append(`
        <div style='display: inline-block'>
          <i id="cwas-gui-openLinkMakerTooltip" type="button" class="cwas-button-link fa fa-link fa-3x" aria-hidden="true"></i>
        </div>`);

            $("#cwas-gui-openLinkMakerTooltip").click(function(){
                $("#cwas-dialog-linkMaker").dialog({
                    width: 400,
                    height:170,
                    dialogClass:'cwas-dialog-overlayed'
                });
            });
            $("#cwas-dialog-addLinkToMessage").click(function(){
                var linkVal = $("#cwas-dialog-linkURI").val();
                var textVal = $("#cwas-dialog-linkText").val();
                var currentText = $("#message textarea").val();
                $("#message textarea").val(currentText + '<a href="' + linkVal + '">' + textVal + "</a>");
                $("#cwas-dialog-linkURI").val("");
                $("#cwas-dialog-linkText").val("");
                $("#cwas-dialog-linkMaker").dialog("close");
            });
        });
    }

    function addPriceCalculator(){
        Template.BuildBuilding.onRendered(function() {
            var building = this.component.building;
            var description =$(".cw--BuildBuilding__info");
            createCalculationInterface(building,description);
        });

        Template.BuildResearch.onRendered(function() {
            var research = this.component.research;
            var description = $(".cw--BuildResearch__info");
            createCalculationInterface(research,description);
        });
    }

    function createCalculationInterface(item, container) {
        var width = container.width();
        container.children().remove();
        container.width(width);
        createPriceCalculationUi(container);
        createCalculationForItem(item);
    }

    function createCalculationForItem(item) {
        if(userOptions.val('startInPriceCalculator')){
            var startLevel = $('#cwas-price-calculator-startLvl');
            startLevel.val(item.getLevel());
            if(item.getQueue() != undefined){
                startLevel.val(item.getQueue().level);
            }
        }
        $("#cwas-price-calculator-calculate").click(function(){
            var startLvl = parseInt($("#cwas-price-calculator-startLvl").val());
            var endLvl = parseInt($("#cwas-price-calculator-endLvl").val());
            var results = $("#cwas-price-calculator-results");
            results.children().remove();

            var basePrice = item.getBasePrice({fromLevel: startLvl, level: endLvl});
            var resourceDict = item.applyPriceEffects({
                price: basePrice,
            });
            for (var r in resourceDict) {
                if (r !== 'time') {
                    results.append(createResourceSection(r, resourceDict[r]));
                }
            }
            results.append(createResourceSection('time', formatTimeFromSeconds(resourceDict.time)));
        });
    }

    function createPriceCalculationUi(parent) {
        parent.append(`
      <div id="cwas-price-calculator-container">
        <div id="cwas-price-calculator-controls">
          <label for="cwas-price-calculator-startLvl" style="cursor: pointer;vertical-align: middle;">От</label>
          <input id="cwas-price-calculator-startLvl" type="number" value="0">
        <label for="cwas-price-calculator-endLvl" style="cursor: pointer;vertical-align: middle;">До</label>
          <input id="cwas-price-calculator-endLvl" type="number" value="100">
          <input id="cwas-price-calculator-calculate" style="padding-left: 20px;
                 padding-right: 20px; height: 30px;" class="ui-button ui-corner-all" type="button" value="Расчитать">
            </div>
            <ul id="cwas-price-calculator-results" class="cwas-prop-gui-artefactNamesSection">
            </ul>
      </div>
      `);
    }

    function createResourceSection(name, value) {
        return '<li style="display: block; padding-left: 5px; padding-right: 5px;margin-bottom: 10px;">' + name + " = " + value + " \n" + '</li>';
    }

    function formatTimeFromSeconds(sec_num) {
        var hours = Math.floor(sec_num / 3600);
        var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
        var seconds = sec_num - (hours * 3600) - (minutes * 60);
        if (hours < 10) {
            hours = "0" + hours;
        }
        if (minutes < 10) {
            minutes = "0" + minutes;
        }
        if (seconds < 10) {
            seconds = "0" + seconds;
        }
        return hours + ':' + minutes + ':' + seconds;
    }

    function addHandAndSegment() {
        Template.cosmosPlanetPopup.onRendered(function() {
            if (!$("#cwas-additional-hand-segment").length) {
                $(".map-planet-popup h2")
                    .first()
                    .append("<span id='cwas-additional-hand-segment'>[" + this.data.planet.hand + ":" + this.data.planet.segment + "]</span>");
            }
        });
    }

    function createPlanetFilterDialog() {
        if (!($("#cwas-dialog-filter-planetFilter").length)) {
            var usernames = {[Meteor.user().username]: true};
            var refreshUsers = function () {
                var usernamesArray = [];
                for (var username in usernames)
                    usernamesArray.push(username);
                var planets = Game.Planets.Collection.find({username: {$nin: usernamesArray}}).fetch();
                var usernamesNew = {};
                var userSelectElement = $("#cwas-prop-gui-filter-planetFilter-username")[0];
                if (userSelectElement.options.length <= 1)
                    usernamesNew[Meteor.user().username] = true;
                for (var k in planets) {
                    var username = planets[k].username;
                    usernames[username] = true;
                    usernamesNew[username] = true;
                }
                for (var username in usernamesNew) {
                    var optionNode = document.createElement('option');
                    optionNode.setAttribute('value', username);
                    optionNode.innerText = username;
                    userSelectElement.appendChild(optionNode);
                }
            };
            $('body').append(`
      <div id="cwas-dialog-filter-planetFilter" title="По артефактам">
        <ul id="cwas-prop-gui-filter-filterPlanetByArtefactSection" class="cwas-prop-gui-artefactNamesSection"></ul>
        <div>Галактика <select id="cwas-prop-gui-filter-planetFilter-username"><option value="">Все открытые</option></select></div>
        <div>
         <input id="cwas-dialog-filter-hideCheckboxes" class="ui-button ui-corner-all" value="Hide" type="button">
         <input id="cwas-dialog-filter-findPlanetsWithArtefacts" class="ui-button ui-corner-all cwas-input-toRight" value="Print Planets" type="button">
        </div>
        <ul id="cwas-prop-gui-filter-resultPlanets" class="cwas-prop-gui-artefactNamesSection"></ul>
        <div id="cwas-dialog-filter-planetFilterAdditional"></div>
      </div>
    `);

            var artefactNamesList = $("#cwas-prop-gui-filter-filterPlanetByArtefactSection");
            var artefactItems = Game.Artefacts.items;
            for (var k in artefactItems) {
                artefactNamesList.append(createArtefactLiItem(artefactItems[k], "filter_", true));
            };
            $('[id^="cwas-artefact_filter_"]').click(function(event) {
                if (this.checked) {
                    $('#cwas-artefact_unneeded_filter_' + this.value)[0].checked = false;
                }
            });
            $('[id^="cwas-artefact_unneeded_filter_"]').click(function(event) {
                if (this.checked) {
                    $('#cwas-artefact_filter_' + this.value)[0].checked = false;
                }
            });
            refreshUsers();

            $("#cwas-prop-gui-filter-planetFilter-username").click(function() {
                refreshUsers();
            });

            $("#cwas-dialog-filter-hideCheckboxes").click(function() {
                var ulOfArtefacts = $("#cwas-prop-gui-filter-filterPlanetByArtefactSection");
                if (ulOfArtefacts.is(":visible")) {
                    ulOfArtefacts.hide();
                } else {
                    ulOfArtefacts.show();
                };
            });

            $("#cwas-dialog-filter-findPlanetsWithArtefacts").click(function() {
                $("#cwas-prop-gui-filter-resultPlanets").children().remove();
                $("#cwas-dialog-filter-planetFilterAdditional").empty();
                var selectedArtefacts = [];
                var unneededArtefacts = [];
                var planets = [];
                $('#cwas-prop-gui-filter-filterPlanetByArtefactSection>li input[id^="cwas-artefact_filter_"]:checked').each(function(index) {
                    selectedArtefacts.push($(this).val());
                });
                $('#cwas-prop-gui-filter-filterPlanetByArtefactSection>li input[id^="cwas-artefact_unneeded_filter_"]:checked').each(function(index) {
                    unneededArtefacts.push($(this).val());
                });
                var query = {};
                var userName = $("#cwas-prop-gui-filter-planetFilter-username").val();
                if (userName.length) {
                    query.username = userName;
                }
                for (var k in selectedArtefacts) {
                    query["artefacts." + selectedArtefacts[k]] = { $gt: 0 };
                }
                for (var k in unneededArtefacts) {
                    query["artefacts." + unneededArtefacts[k]] = { $eq: null };
                }
                if (selectedArtefacts.length) {
                    planets = Game.Planets.Collection.find(query).fetch();
                };
                planets.sort(compare(selectedArtefacts[0]));
                var totalPercentChance = 0;
                for (var i = planets.length - 1; i >= 0; i--) {

                    var chanceInPercent = planets[i].artefacts[selectedArtefacts[0]];
                    $("#cwas-prop-gui-filter-resultPlanets")
                        .append(getLinkToPlanet(planets[i], chanceInPercent + '%'));
                    totalPercentChance+=chanceInPercent;
                }
                var additionalInfoBlock = $("#cwas-dialog-filter-planetFilterAdditional");
                additionalInfoBlock.append("Общий шанс: " + Number(Math.round(totalPercentChance+'e2')+'e-2') + "</br>");
                additionalInfoBlock.append("Количество планет: " + planets.length+ "</br>");
                additionalInfoBlock.append("Среднее: " + Number(Math.round((totalPercentChance / planets.length)+'e2')+'e-2')+ "</br>");

                var preparedText = Number(Math.round(totalPercentChance+'e2')+'e-2') +"\t"
                + planets.length +"\t"
                + Number(Math.round((totalPercentChance / planets.length)+'e2')+'e-2');

                additionalInfoBlock.append("Formatted: " + preparedText.replace(/\./g,","));
            });
        };

        $("#cwas-prop-gui-filter-filterPlanetByArtefactSection").show();
        $("#cwas-dialog-filter-planetFilter").dialog({
            width: 775,
            height: 300,
            dialogClass: 'cwas-dialog-overlayed'
        });
        closeSettingDialog();
    }

    function createFleetFilterDialog() {
        if (!($("#cwas-dialog-filter-fleetFilter").length)) {
            var usernames = {[Meteor.user().username]: true};
            var refreshUsers = function () {
                var usernamesArray = [];
                for (var username in usernames)
                    usernamesArray.push(username);
                var planets = Game.Planets.Collection.find({username: {$nin: usernamesArray}}).fetch();
                var usernamesNew = {};
                var userSelectElement = $("#cwas-prop-gui-filter-fleetFilter-username")[0];
                if (userSelectElement.options.length <= 1)
                    usernamesNew[Meteor.user().username] = true;
                for (var k in planets) {
                    var username = planets[k].username;
                    usernames[username] = true;
                    usernamesNew[username] = true;
                }
                for (var username in usernamesNew) {
                    var optionNode = document.createElement('option');
                    optionNode.setAttribute('value', username);
                    optionNode.innerText = username;
                    userSelectElement.appendChild(optionNode);
                }
            };
            $('body').append(`
      <div id="cwas-dialog-filter-fleetFilter" title="Фильтр флотов">
        <div>Галактика
          <select id="cwas-prop-gui-filter-fleetFilter-username">
            <option value="">Все открытые</option>
          </select>
        </div>
        <div>
          <select id="cwas-prop-gui-filter-filterFleets">
            <option value="patrolfleet">Патруль</option>
            <option value="defencefleet">Ряды обороны</option>
            <option value="battlefleet">Боевой флот</option>
          </select>
          <input id="cwas-filter-fleetLvl" class="ui-corner-all" type="number" min="1" max="7" value="1">
        </div>
        <div>
         <input id="cwas-dialog-filter-findPlanetsWithFleets" class="ui-button ui-corner-all" value="Print Fleets" type="button">
        </div>
        <ul id="cwas-prop-gui-filter-resultFleets" class="cwas-prop-gui-fleetsNamesSection"></ul>
      </div>
    `);
            refreshUsers();

            $("#cwas-prop-gui-filter-fleetFilter-username").click(function() {
                refreshUsers();
            });

            $("#cwas-dialog-filter-findPlanetsWithFleets").click(function() {
                $("#cwas-prop-gui-filter-resultFleets").children().remove();
                var missionType = $("#cwas-prop-gui-filter-filterFleets").val();
                var missionLvl = parseInt($("#cwas-filter-fleetLvl").val(), 10);
                var query = {};
                var userName = $("#cwas-prop-gui-filter-fleetFilter-username").val();
                if (userName.length) {
                    query.username = userName;
                }
                var allPlanets = Game.Planets.Collection.find(query).fetch();

                var planets = allPlanets;
                planets = filterFleets(planets, missionType, missionLvl);
                planets.sort(function compare(a, b) {
                    if (a.hand > b.hand) return -1;
                    if (a.hand < b.hand) return 1;
                    return 0;
                });

                for (var i = planets.length - 1; i >= 0; i--) {
                    $("#cwas-prop-gui-filter-resultFleets")
                        .append(getLinkToPlanet(planets[i]));
                }
            });
        };

        $("#cwas-dialog-filter-fleetFilter").dialog({
            width: 180,
            height: 400,
            position: { my: "right bottom", at: "right-10 bottom-10" },
            dialogClass: 'cwas-dialog-overlayed'
        });
        closeSettingDialog();
    }

    function createPlanetTypeFilterDialog() {
        if (!($("#cwas-dialog-filter-planetTypeFilter").length)) {
            $('body').append(`
      <div id="cwas-dialog-filter-planetTypeFilter" title="По типу">
        <div>
          <select id="cwas-prop-gui-filter-planetType">
          </select>
        </div>
        <div>
         <input id="cwas-dialog-filter-findPlanetsWithType" class="ui-button ui-corner-all" value="Print Planets" type="button">
        </div>
        <ul id="cwas-prop-gui-filter-resultPlanetsWithType" class="cwas-prop-gui-fleetsNamesSection"></ul>
        <div id="cwas-dialog-filter-resultPlanetsWithTypeAdditional"></div>
      </div>
    `);
            var planetTypes = Game.Planets.types;
            var planetTypesKeys = Object.keys(Game.Planets.types);
            var planetTypeSelect = $('#cwas-prop-gui-filter-planetType');

            for (var i = planetTypesKeys.length - 1; i >= 0; i--) {
                var planetTypeEngName = planetTypesKeys[i];
                planetTypeSelect.append('<option value="' + planetTypeEngName +'">' + planetTypes[planetTypeEngName].name + '</option>');
            }
            planetTypeSelect.val('terran');
        };


        $("#cwas-dialog-filter-findPlanetsWithType").click(function() {
            $("#cwas-prop-gui-filter-resultPlanetsWithType").children().remove();
            $("#cwas-dialog-filter-resultPlanetsWithTypeAdditional").empty();
            var planetType = $("#cwas-prop-gui-filter-planetType").val();

            var planets = Game.Planets.getAll().fetch();

            planets = filterPlanetsWithType(planets, planetType);
            planets.sort(function compare(a, b) {
                if (a.hand > b.hand) return -1;
                if (a.hand < b.hand) return 1;
                return 0;
            });

            for (var i = planets.length - 1; i >= 0; i--) {
                $("#cwas-prop-gui-filter-resultPlanetsWithType")
                    .append(getLinkToPlanet(planets[i]));
            }
            var additionalInfoBlock = $("#cwas-dialog-filter-resultPlanetsWithTypeAdditional");
            additionalInfoBlock.append("Количество планет: " + planets.length);
        });

        $("#cwas-dialog-filter-planetTypeFilter").dialog({
            width: 180,
            height: 400,
            position: { my: "right bottom", at: "right-10 bottom-10" },
            dialogClass: 'cwas-dialog-overlayed'
        });
        closeSettingDialog();
    }

    function filterFleets(arr, type, lvl) {
        var result = [];
        for (var i = 0; i < arr.length; i++) {
            if (arr[i]["mission"] != null) {
                var mission = arr[i]["mission"];
                if (mission["type"] === type && mission["level"] === lvl) {
                    result.push(arr[i]);
                }
            };
        }
        return result;
    };

    function filterPlanetsWithType(arr, type) {
        var result = [];
        for (var i = 0; i < arr.length; i++) {
            if (arr[i]["type"] != null) {
                var planetType = arr[i]["type"];
                if (planetType === type) {
                    result.push(arr[i]);
                }
            };
        }
        return result;
    };

    function getLinkToPlanet(planet, additionalInfo) {
        var color = getPlanetColor(planet);
        if (additionalInfo === undefined) {
            additionalInfo = "";
        }

        return '<li style="display: inline-block;">' + '<a style="-webkit-filter: grayscale(0%);' + color + '" href="/game/cosmos#'
            + planet._id + '">' + planet.name + " "
            + additionalInfo
            + ' [' + planet.hand + '|' + planet.segment + ']</a></li>';
    };

    function getPlanetColor(planet) {
        var color = "";
        if (planet.status === Game.Planets.STATUS.HUMANS) {
            color = "color: #56BAF2;";
            var minerUsername = planet.minerUsername;
            if (Game.Alliance.Collection.findOne().participants.includes(minerUsername)){
                color = "color: #D36FFF;";
            }
            if(minerUsername === Meteor.user().username){
                color = "color: #c6e84c;";
            }
        }
        if (planet.status === Game.Planets.STATUS.REPTILES) {
            color = "color: #dc6257;";
        }

        return color;
    };


    function compare(aN) {
        return function(a, b) {
            if (a.artefacts[aN] < b.artefacts[aN]) return -1;
            if (a.artefacts[aN] > b.artefacts[aN]) return 1;
            return 0;
        };
    }

    function intersectSafe(a, b) {
        var result = [];
        for (var i = 0; i < a.length; i++) {
            for (var j = 0; j < b.length; j++) {
                if (a[i]["_id"] === b[j]["_id"]) {
                    result.push(a[i]);
                }
            }
        }
        return result;
    }

    function createArtefactLiItem(artefactItem, artefactIdPrefix, unneeded){
        var liItem =
            '<li>'+
            '<input type="checkbox" value="'+artefactItem.engName+'" id="cwas-artefact_'+artefactIdPrefix+artefactItem.engName+'"' + (unneeded ? ' title="обязателен"' : '') + '>'+
            (unneeded ? '<input type="checkbox" value="'+artefactItem.engName+'" id="cwas-artefact_unneeded_'+artefactIdPrefix+artefactItem.engName+'" title="должен отсутствовать">' : '')+
            '<label for="cwas-artefact_'+artefactIdPrefix+artefactItem.engName+'" class="' + artefactItem.color + '">'+
            artefactItem.name+
            '</label>'+
            '</li>';

        return liItem;
    }

    function PageData(){
        this.currentUser = 'Anonymous';
    }

    function initOptions(){
        var retVal = {
            data: {
                linkMaker: {
                    dt: null,
                    guiDesc: function(){
                        return 'Добавить кнопку создания линков в чат';
                    }
                },
                priceCalculator: {
                    dt: null,
                    guiDesc: function(){
                        return 'Добавить возможность расчёта цен вместо описания';
                    }
                },
                startInPriceCalculator: {
                    dt: null,
                    guiDesc: function(){
                        return 'Начинать с текущего';
                    }
                },
                handAmdSegment: {
                    dt: null,
                    guiDesc: function(){
                        return 'Добавить рукав и сектор в попап планет';
                    }
                },
                cwasTabsNav0: {
                    guiDesc: function(){
                        return 'Основные настройки';
                    }
                },
                cwasTabsNav1: {
                    guiDesc: function(){
                        return 'Космос';
                    }
                },
                collapseCommentWhenSize: {
                    dt: null,
                    validator: function(val){
                        return $.isNumeric(val) && val >= 20 && val <= 10000;
                    },
                    guiDesc: function(){
                        return lng.getVal('JRAS_GUI_COLLAPSECOMMENTWHENSIZE');
                    }
                },
            },

            val: function(option, value){
                if(this.data[option]){
                    if(value === undefined){
                        return this.data[option].dt;
                    }else{
                        if (this.data[option]['validator']){
                            if (this.data[option].validator(value)){
                                this.data[option].dt = value;
                            }
                        }else{
                            this.data[option].dt = value;
                        }
                    }
                }
            },
            getGuiDesc: function(option){
                return this.data[option].guiDesc();
            },

            setDef: function(){
                this.data.linkMaker.dt = false;
                this.data.priceCalculator.dt = false;
                this.data.startInPriceCalculator.dt = false;
                this.data.handAmdSegment.dt = false;
                this.data.collapseCommentWhenSize.dt = 110;
            },

            removeAllSavedData: function(){
                this.removeSavedUserData();
            },

            removeSavedUserData: function(user){
                var pref = (user === undefined) ? '' : user + '_';
                var keys = GM_listValues();
                for(var i = 0; i < keys.length; i++){
                    var key = keys[i];
                    if(!key.match(new RegExp(pref + '.*'))){
                        continue;
                    }
                    GM_deleteValue(key);
                }
            },

            saveUserData: function(forUser){
                var i;
                this.removeSavedUserData(forUser);
                var pref = forUser + '_';

                for(i in this.data){
                    if(i == 'BlockTags'){
                        continue;
                    }
                    GM_setValue(pref + i, this.data[i].dt);
                }

                for(i = 0; i < this.data.BlockTags.length; i++){
                    GM_setValue(pref + 'BlockTags_name_' + i, this.data.BlockTags[i]);
                }
            },

            loadUserDataFrom: function(prefix){
                var retVal = false;
                var posf = '.*';

                var keys = GM_listValues();
                this.data.BlockUsers = [];
                this.data.BlockTags = [];
                for(var i = 0; i < keys.length; i++){
                    var key = keys[i];
                    if(!key.match(new RegExp(prefix + posf))){
                        continue;
                    }
                    if(key.match(new RegExp(prefix + 'BlockTags_name_' + posf))){
                        this.data.BlockTags.push(GM_getValue(key, ''));
                    }else{
                        var rkey = key.replace(prefix, '');
                        if(this.data[rkey] === undefined){
                            continue;
                        }
                        this.data[rkey].dt = GM_getValue(key, this.data[rkey]);
                        retVal = true;
                    }
                }
                this.data.BlockUsers.sort();
                this.data.BlockTags.sort();
                return retVal;
            },

            loadUserData: function(forUser){
                if(this.loadUserDataFrom(forUser + '_')){
                    return;
                }
                if(this.loadUserDataFrom(forUser)){
                    this.saveUserData(forUser);
                }
            }

        };

        retVal.setDef();
        return retVal;
    }

    function addNewCSSClasses(){
        $("head").append (`
      <link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/vader/jquery-ui.min.css" rel="stylesheet" type="text/css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
     `);
        newCssClass(`
      .cwas-user-awards img {
        width: 16px;
        height: 16px;
      }
      .cwas-user-awards-slice img {
        height: 16px;
        padding-left: 3px;
      }
      .cwas-tooltip-button:hover span, .cwas-tooltip-button:hover i {
        color: #CC9622;
        opacity: 1;
      }
      .cwas-tooltip-button-img {
        vertical-align: middle;
        width: 16px;
        height: 16px;
        display: inline-block;
        opacity: 0.7;
      }
      .cwas-tooltip-button-text {
        padding-left: 4px;
        font-size: 10px;
        vertical-align: middle;
        display: inline-block;
        line-height: 10px;
      }
      .cwas-tooltip-section-topborder {
        margin-top: 4px;
        border-top: 1px solid rgb(85, 85, 85);
        padding-top: 3px;
      }
      .cwas-gui-btn-newdesign {
        border-radius: 3px;
        padding-left: 3px;
        padding-right: 3px;
        width: 24px;
        height: 22px;
      }

      .cwas-tooltip-user-awards-hide-btn-close{
        position: relative;
        box-shadow: 0 -4px 8px 0 rgb(0, 0, 0);
        margin-bottom: -6px;
      }
      .cwas-tooltip-user-awards-hide-btn{
        background-color: rgb(80, 80, 80);
        height: 5px;
        width: 105%;
        margin-left: -5px;
        top: -4px;
        border-radius: 0 0 10px 10px;
      }
      .cwas-tooltip-user-awards-hide-btn:hover{
        background-color: rgb(0, 135, 21);
      }
      .cwas-prop-gui-content, .cwas-prop-gui-contentTop, .cwas-prop-gui-contentBottom{
        background-color: #2F2E2E;
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 30px;
        overflow: hidden;
      }
      .cwas-prop-gui-contentTop{
        margin-bottom: 5px;
      }
      .cwas-prop-gui-contentBottom{
        top: auto;
        bottom: 0;
        height: 35px;
        overflow: hidden;
        margin-top: 5px;
      }
      .cwas-prop-gui-contentMain{
        position: absolute;
        top: 30px;
        left: 0;
        right: 0;
        bottom: 30px;
        overflow: auto;
        background-color: #262626;
      }
      .cwas-prop-gui-section{
        margin-top: 5px;
        margin-bottom: 14px;
      }
      .cwas-prop-gui-button-right{
        padding-left: 20px;
        right: 0px;
        padding-right: 20px;
        margin-right: 5px;
        position: absolute;
        margin-top: 4px;
        height: 22px;
      }
      .cwas-prop-gui-button-left{
        left: 0px;
        margin-left: 5px;
        margin-top: 4px;
        cursor: pointer;
      }

     .cwas-tabs-panel-content {
      padding: 6px 10px;
      background: gray;
      }

     #cwas-prop-gui-dialog{
       border: 0;
       width: 100%;
     }

     .cwas-prop-gui-artefactNamesSection{
       column-count: 3;
     }

     .cwas-prop-gui-artefactNamesSection>li{
       list-style-type:none;
     }

     .cwas-prop-gui-fleetsNamesSection{
       column-count: 1;
     }

     .cwas-prop-gui-fleetsNamesSection>li{
       list-style-type:none;
     }

     #cwas-prop-gui-dialog .cwas-tabs-nav{
       margin-left: 6px;
       margin-top: 6px;
       float: left;
       width: 25%;
       border: 0;
       background: none;
     }
     #cwas-prop-gui-dialog .cwas-tabs-nav li{
       height: 45px;
       clear: left;
       width: 90%;
       margin: 0 0 5px 0;
       background: #2d2d2d none repeat scroll 0 0;
       border: 0 none;
       padding: 0 0 3px 5px;
       font-weight: normal;
       border-radius: 3px;
     }
     #cwas-prop-gui-dialog .cwas-tabs-nav li.ui-tabs-active{
       background-color: #3e7a35;
     }
     #cwas-prop-gui-dialog .cwas-tabs-nav li.ui-state-focus{
       background-color: #2b5326;
     }
     #cwas-prop-gui-dialog .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited{
       line-height: 30px;
       color: #818181;
       text-decoration: none;
     }
     #cwas-prop-gui-dialog .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited{
       color: #d4d4d4;
       font-weight: bold;
       text-decoration: none;
       line-height: 30px;
     }
     #cwas-prop-gui-dialog .cwas-tabs-panel{
       box-shadow: -1px 0 20px 0 #000000;
       border: 0;
       left: 25%;
       height: 100%;
       overflow: auto;
       position: absolute;
       float: right;
       right: 0;
     }

     .cwas-button-link{
       padding: 5px;
       margin-top: 3px;
       background-color: gray;
     }

      /* Окно настроек  */
      .cwas-modal {
        z-index: 1000;
        opacity: 0;
        visibility: hidden;
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        text-align: left;
        background: rgba(0,0,0, .9);
        transition: opacity .25s ease;
      }
      .cwas-modal__bg {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        cursor: pointer;
      }
      .cwas-modal-state {
        display: none;
      }
      .cwas-modal-state:checked + .cwas-modal {
        opacity: 1;
        visibility: visible;
      }
      .cwas-modal-state:checked + .cwas-modal .cwas-modal__inner {
        top: 0;
      }
      .cwas-modal__inner {
        transition: top .25s ease;
        position: absolute;
        top: -20%;
        width: 55%;
        margin-left: 42%;
        margin-top: 20px;
        overflow: auto;
        background: #fff;
        border-radius: 5px;
        height: 55%;
      }
      .cwas-modal__close {
        position: absolute;
        right: 8px;
        top: 8px;
        width: 1.1em;
        height: 1.1em;
        cursor: pointer;
      }
      .cwas-modal__close:after,
      .cwas-modal__close:before {
        content: "";
        position: absolute;
        width: 2px;
        height: 1.5em;
        background: #ccc;
        display: block;
        transform: rotate(45deg);
        left: 50%;
        margin: -3px 0 0 -1px;
        top: 0;
      }
      .cwas-modal__close:hover:after,
      .cwas-modal__close:hover:before {
        background: #aaa;
      }
      .cwas-modal__close:before {
        transform: rotate(-45deg);
        }
      .cwas-dialog-overlayed{
        z-index: 1000;
      }
      .cwas-input-toRight{
            right: 0;
            position: absolute;
      }
      @media screen and (max-width: 768px) {
        .cwas-modal__inner {
          width: 93%;
          height: 93%;
          margin-left: 3%;
          box-sizing: border-box;
        }
      }
      @media screen and (max-height: 600px) {
        .cwas-modal__inner {
          height: 75%;
          box-sizing: border-box;
        }
      }
      @media screen and (max-height: 400px) {
        .cwas-modal__inner {
          height: 91%;
          box-sizing: border-box;
        }
      }
    `);
    }

}());