Полезная информация

Заказывай стафф с атрибутикой Mozilla и... пусть все вокруг завидуют тебе! Быть уникальным - быть с Mozilla!

№1497613-08-2020 14:33:14

Vitaliy V.
Участник
 
Группа: Members
Зарегистрирован: 19-09-2014
Сообщений: 1585
UA: unknown 0.0

Re: Custom Buttons

Dumby пишет

Если я ничего не упускаю, то для этого просто нет API, то есть
нет чего-то типа getDefaultPref(prefName) или isDefaultPref(prefName, prefValue)

может как то так

скрытый текст

Выделить код

Код:

var name = "extensions.user_chrome_files.custom_script";
var getters_pref_type = {
  [Ci.nsIPrefBranch.PREF_BOOL]: "getBoolPref",
  [Ci.nsIPrefBranch.PREF_INT]: "getIntPref",
  [Ci.nsIPrefBranch.PREF_STRING]: "getStringPref",
};
var type = Services.prefs.getPrefType(name);
try {
   console.log("getDefaultPref: " + Services.prefs.getDefaultBranch("")[getters_pref_type[type]](name));
} catch (ex) {
   console.log("getDefaultPref: none");
}

Отсутствует

 

№1497713-08-2020 15:03:00

_zt
Участник
 
Группа: Members
Зарегистрирован: 10-11-2014
Сообщений: 399
UA: unknown 0.0

Re: Custom Buttons

Dumby
Я имел ввиду выделять userChoice, а не наоборот, у себя изменил.
   
По поводу пунктов true-false:
Текст значения после заголовка добавьте пожалуйста, что бы к единому стилю привести. Например после:

скрытый текст

Выделить код

Код:

pref: ["javascript.enabled", "Выполнять скрипты Java", "", "javascript.enabled"],
			userChoice: true, refresh: true,
			values: [[true, "Да"], [false, "Нет"]]

"Выполнять скрипты Java" должно быть длинное тире и "Да"/"Нет" (по подобию с другими пунктами).
   
По поводу всех подменю и выделения в них дефолтных / не дефолтных значений:
Вот здесь же bold для user задается, или я чего то не понял.
скрытый текст

Выделить код

Код:

user
				? node.style.setProperty("font-weight", "bold", "important")
				: node.style.removeProperty("font-weight");

Т.е. получить значение по умолчанию, и выделить его (или отличное от него), можно.
Или как вы это вообще задумывали? То что пишет Dobrov для меня не соответствует действительности, у меня все что отлично от дефолта выделяется.
Заменил себе на курсив:
2020.1597319645.png
   
------------------
У меня ESR 78

Отредактировано _zt (13-08-2020 18:33:41)

Отсутствует

 

№1497813-08-2020 15:46:16

Vitaliy V.
Участник
 
Группа: Members
Зарегистрирован: 19-09-2014
Сообщений: 1585
UA: unknown 0.0

Re: Custom Buttons

_zt пишет

Вот здесь же bold для user задается, или я чего то не понял.

это для текущего значения - prefHasUserValue, а чтобы проверить другие значения (в подменю) нужно определить его дефолтное значение,
не переключать же настройку и проверять каждое...

Отсутствует

 

№1497913-08-2020 16:10:02

_zt
Участник
 
Группа: Members
Зарегистрирован: 10-11-2014
Сообщений: 399
UA: unknown 0.0

Re: Custom Buttons

Vitaliy V.
Теперь понятно. Тогда может на базе вашего кода решение найдется.
   
Dumby
maroon я у помянул так как он у меня не работает. Сами видите какое у меня меню, так что не удивительно, что цвета в нем не работают.
Вы все правильно сделали, только, на мой взгляд, логичнее UserChoice выделять, а не отличные от него.
Хотя, ради баловства, можно для каждого значения свою иконку назначить - UserChoice / notUserChoice.

Отредактировано _zt (13-08-2020 16:12:57)

Отсутствует

 

№1498013-08-2020 18:02:20

_zt
Участник
 
Группа: Members
Зарегистрирован: 10-11-2014
Сообщений: 399
UA: unknown 0.0

Re: Custom Buttons

Dumby
Все таки добавил иконку на notUserChoice. Казалось, что будет сложнее.
2020.1597330070.png
Теперь вопрос появился, а нельзя ли на иконку (или весь пункт) клик ЛКМ повесить? (ПКМ там и так работает, сбрасывает значение на "по умолчанию" (я так понимаю)).
   
Дело в том, что подменю может появится и справа и слева, и все это приводит к бестолковым перемещениям мыши. А так можно будет только информацию снимать глазами с подменю, а переключать щелчком мыши.
   
Последовательное переключение неприемлемо (из-за refresh: true, restart: true), но можно добавить какой нибудь UserAlt и переключать по клику ЛКМ (UserChoice > UserAlt, UserAlt > UserChoice), если UserAlt назначен пункту.
   
В этом случае, UserAlt тоже можно будет свою иконку приделать.

Отредактировано _zt (13-08-2020 18:29:59)

Отсутствует

 

№14981Вчера 05:34:27

Kero
Участник
 
Группа: Members
Зарегистрирован: 09-11-2012
Сообщений: 195
UA: Firefox 52.0

Re: Custom Buttons

а есть ли где коллекция уже готовых кнопок в файле buttonsoverlay.xul ?
И как то можно отключить backup или задать только 1 backup ?

Отредактировано Kero (Вчера 05:36:45)

Отсутствует

 

№14982Вчера 13:34:51

Duche
Участник
 
Группа: Members
Зарегистрирован: 07-02-2016
Сообщений: 190
UA: unknown 0.0

Re: Custom Buttons

Добрый день. Посмотрите пожалуйста  код для FF71 " Удалить куки текущего сайта в контекстном меню на странице" для контекстного меню.


скрытый текст

Выделить код

Код:

// Удалить куки текущего сайта в контекстном меню на странице, от 06.03.2017. ................
  
 (()=> {
(contextMenu=> {
   var menu = contextMenu.appendChild(document.createElement("menu"));
   menu.id = "content-removeCookies."
   menu.setAttribute("label", "Удалить куки текущего сайта");
   menu.setAttribute("class", "menu-iconic");
   addEventListener("popupshowing", ()=> menu.setAttribute("image", gBrowser.mCurrentTab.image), false, contextMenu);
   addDestructor(()=> menu.remove() );
   
   var menuPopup = menu.appendChild(document.createElement("menupopup"));
   var menuitem = menuPopup.appendChild(document.createElement("menuitem"));               
   menuitem.setAttribute("label", "Удалить");
   menuitem.onclick =()=> {
      var host = Services.eTLD.getBaseDomain(gBrowser.currentURI);

      for ( var en = Services.cookies.enumerator; en.hasMoreElements(); ) {
            var cookie = en.getNext().QueryInterface(Ci.nsICookie);
            ~cookie.host.indexOf(host.trim()) && Services.cookies.remove(cookie.host, cookie.name, cookie.path, false); 
            }
   
      var reversedDomain = host.split("").reverse().join("") + ".";
      Cu.import("resource://gre/modules/FileUtils.jsm");
      var file = FileUtils.getFile("ProfD", ["webappsstore.sqlite"]);
      var dbConn = Services.storage.openDatabase(file);
      dbConn.executeSimpleSQL("DELETE FROM webappsstore2 WHERE scope LIKE \"%" + reversedDomain +"%\"");
      dbConn.close();
      
      var host = content.document.domain;
      for( var tab of gBrowser.tabs ) {  
           var tabHost = tab.linkedBrowser.contentDocument.location.host;
           if ( host == tabHost ) gBrowser.reloadTab(tab);
           }
          
      // очистить кэш ....
      try { 
          Services.cache.evictEntries(1);
          Services.cache.evictEntries(2);
          } 
      catch(e) { Services.cache2.clear() };
   
      // удалить все Flash куки
      var dir = Services.dirsvc.get('Home', Ci.nsIFile);
      dir.append("Application Data");
      dir.append("Macromedia");
      //dir.remove(true);
      //dir.create(Ci.nsIFile.DIRECTORY_TYPE, 0777);
      dir.exists() && dir.remove(true);                      // Удалить Flash кукисы222 ....
      !dir.exists() && dir.create(Ci.nsIFile.DIRECTORY_TYPE, 0777);
   
      // Всплывающее сообщение ....
      var win = openDialog("chrome://global/content/alerts/alert.xul", "", "popup=yes", (gBrowser.mCurrentTab.image || "chrome://global/skin/icons/Portrait.png"),
           "", "Очистил куки, кеш текущего сайта и удалил Flash куки", false, null, 4);
      setTimeout(()=> win && win.close(), 2500);          
  };
})(document.getElementById("contentAreaContextMenu"));
})();

Отредактировано Duche (Вчера 13:41:07)

Отсутствует

 

№14983Вчера 16:20:19

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 1207
UA: Firefox 52.0

Re: Custom Buttons

firepox пишет

пробовал в начало кода добавлять это:
gBrowser.selectedTab = gBrowser.addTab('http://site.ru');
Не работает)

Направление мысли верное, но следует дождаться пока загрузится.
Попробуй разместить в Инициализации, и если «нужный сайт»
прям после загрузки ещё не готов быть снапшотнутым, тогда
подними таймаут с нуля до какого-нибудь эмпирического значения.

скрытый текст

Выделить код

Код:

(exec => addEventListener("click", e => {
	if (e.button) return;
	e.preventDefault();

	var url = "http://site.ru";

	var br = (gBrowser.selectedTab = gBrowser.addTab(url)).linkedBrowser;
	br.addEventListener("pageshow", () => setTimeout(exec, 0, br, url), {once: true});

}, true, this))((br, url) => gBrowser.selectedBrowser == br
	&& br.currentURI.spec == url && custombutton.buttonCbExecuteCode(null, this, this.cbCommand)
);

Dobrov пишет

Хотелось бы совместить оба варианта - для _zt и для меня с методом londPress, они почему-то сильно различаются…

Ну, ты выразил пожелание чтобы менюшки закрывались,
а _zt к этому пожеланию не присоединился, и направился
куда-то в сторону единостилия. Поэтому и различаются.


Но londPress достаточно автономен, там только здесь вписан "mousedown":
for(var type of ["command", "contextmenu", "mousedown"])
и, в конце, метод mousedown, обрабатывающий это событие,
и метод londPress, куда передаётся результат обработки.


Vitaliy V. пишет

может как то так

Да! Это работает! Спасибо!
И ведь что-то подобное в коде есть, но мысль проверить
что возвращает defaultBranch мою тупую голову не посетила.


_zt пишет

у себя изменил

Смотрю много измененений.
Скинь тогда свой код целиком, чтобы было с чем возиться.
С проставленными userAlt и userAltImg.


Резюмирую, скорее для себя, что попробовать сделать:
1. italic в субменюшках для недефолтных значений,
    учитывая наставление Виталия.
2. длинное тире + лейбл и для true-false <menu>
    при наличии "values".
3. Последовательное переключение по клику на <menu>
    если отсутствуют restart и refresh,


    иначе, переключение между userChoice и userAlt,
    если присутствуют оба. Плюс иконка userAlt.
    (Если текущее значение не userChoice и не userAlt
    переключать на userChoice или на userAlt ?)
Всё это займёт какое-то время, полагаю.


Kero пишет

как то можно отключить backup

Наверно да, %Profile%\extensions\custombuttons@xsms.org\components\CustomButtonsService.js
function backupProfile (phase) {if(true)return;


Duche пишет

Удалить куки текущего сайта в контекстном меню на странице

Может подойдёт в контекстном меню не на странице, а на кнопке?

Отсутствует

 

№14984Вчера 21:03:43

firepox
Участник
 
Группа: Members
Зарегистрирован: 17-11-2011
Сообщений: 354
UA: Firefox 56.0

Re: Custom Buttons

Dumby пишет

firepox пишетпробовал в начало кода добавлять это:gBrowser.selectedTab = gBrowser.addTab('http://site.ru');Не работает)Направление мысли верное, но следует дождаться пока загрузится.Попробуй разместить в Инициализации, и если «нужный сайт»прям после загрузки ещё не готов быть снапшотнутым, тогдаподними таймаут с нуля до какого-нибудь эмпирического значения.

код вставил инициализацию -  ничего не сохраняются вообще

Отсутствует

 

№14985Вчера 21:24:56

_zt
Участник
 
Группа: Members
Зарегистрирован: 10-11-2014
Сообщений: 399
UA: unknown 0.0

Re: Custom Buttons

Dumby

Резюмирую, скорее для себя, что попробовать сделать:

1. italic в субменюшках для недефолтных значений,
    учитывая наставление Виталия.
2. длинное тире + лейбл и для true-false <menu>
    при наличии "values".
3. Здесь, переключение только между userChoice и userAlt, если userAlt существует.
    Если сделать иначе (например, последовательно), будет путаница и проблемы с restart и refresh.
    ... Думаю не стоит усложнять. Более двух никогда не нужно, и ведь еще есть уже работающий ПКМ.
        Да и вообще, при последовательном переключении смысл UserAlt теряется,
        он был выдуман, что бы избежать проблем последовательного переключения.
   

Если текущее значение не userChoice и не userAlt
    переключать на userChoice или на userAlt ?

На userChoice. Так как он основной.
UserAlt в немногих пунктах потребуется, а userChoice можно прописать везде.
   

Смотрю много измененений.

Вы мне льстите. Не много.
Иконку UserAlt прописал и она работает, но вы проверьте за мной, я просто интуитивно сделал. В трех пунктах добавил новый атрибут.

скрытый текст

Выделить код

Код:

data:text/plain;charset=utf-8;base64,Ly8g0JHRi9GB0YLRgNC+0LUg0L/QtdGA0LXQutC70Y7Rh9C10L3QuNC1INC/0LDRgNCw0LzQtdGC0YDQvtCyIGFib3V0OmNvbmZpZw0KKGFzeW5jIChuYW1lLCBpZCwgZnVuYykgPSZndDsgew0KCWlmIChuYW1lID09ICZxdW90O09iamVjdCZxdW90OykgcmV0dXJuIEN1c3RvbWl6YWJsZVVJLmNyZWF0ZVdpZGdldChmdW5jKCkpOw0KCXZhciB3aW4gPSBuYW1lID09ICZxdW90O1dpbmRvdyZxdW90OywgZyA9IENvbXBvbmVudHMudXRpbHMuaW1wb3J0KCZxdW90O3Jlc291cmNlOi8vZ3JlL21vZHVsZXMvU2VydmljZXMuanNtJnF1b3Q7LCB7fSk7DQoJaWYgKGdbaWRdKSB7aWYgKHdpbikgcmV0dXJuO30gZWxzZSBnW2lkXSA9IGZ1bmMoKTsNCglpZiAod2luKSByZXR1cm4gQ3VzdG9taXphYmxlVUkuY3JlYXRlV2lkZ2V0KGdbaWRdKTsNCglhZGREZXN0cnVjdG9yKHIgPSZndDsgcls1XSA9PSAmcXVvdDtlJnF1b3Q7ICZhbXA7JmFtcDsgZGVsZXRlIGdbaWRdKTsNCglnW2lkXS5vbkNyZWF0ZWQodGhpcyk7DQp9KSh0aGlzLmNvbnN0cnVjdG9yLm5hbWUsICZxdW90O1F1aWNrVG9nZ2xlQWJvdXRDb25maWdTZXR0aW5ncyZxdW90OywgKCkgPSZndDsgew0KDQoJdmFyIHtwcmVmc30gPSBTZXJ2aWNlcywgZGIgPSBwcmVmcy5nZXREZWZhdWx0QnJhbmNoKCZxdW90OyZxdW90Oyk7DQoJdmFyIHB2ID0gcGFyc2VJbnQoU2VydmljZXMuYXBwaW5mby5wbGF0Zm9ybVZlcnNpb24pOw0KCXZhciB4dWxfbnMgPSAmcXVvdDtodHRwOi8vd3d3Lm1vemlsbGEub3JnL2tleW1hc3Rlci9nYXRla2VlcGVyL3RoZXJlLmlzLm9ubHkueHVsJnF1b3Q7Ow0KDQoJdmFyIGxvY2FsaG9zdCA9ICZxdW90OzEyNy4wLjAuMSZxdW90OzsNCgl2YXIgYW50aWNlbnNvcml0eSA9ICZxdW90O2h0dHBzOi8vZ2l0LmlvL2FjLWFudGljZW5zb3JpdHktcGFjJnF1b3Q7Ow0KCXZhciBhbnRpemFwcmV0ID0gJnF1b3Q7aHR0cHM6Ly9hbnRpemFwcmV0LnByb3N0b3Zwbi5vcmcvcHJveHkucGFjJnF1b3Q7Ow0KCXZhciBwYWNmaWxlID0gcHJlZnMuZ2V0U3RyaW5nUHJlZigmcXVvdDt1c2VyLnBhY2ZpbGUmcXVvdDssICZxdW90O2ZpbGU6Ly8vZXRjL3Byb3h5LnBhYyZxdW90Oyk7DQoJdmFyIHVzZXJhZ2VudCA9ICZxdW90O01vemlsbGEvNS4wIChXaW5kb3dzIE5UIDYuMTsgV09XNjQ7IHJ2OjU2LjApIEdlY2tvLzIwMTAwMTAxIEZpcmVmb3gvNTYuMCZxdW90OzsNCg0KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQoNCgkvLyByZWZyZXNoOg0KCS8vCWZhbHNlIC0gcmVsb2FkIGN1cnJlbnQgdGFiDQoJLy8JdHJ1ZSAtIHJlbG9hZCBjdXJyZW50IHRhYiBza2lwIGNhY2hlDQoJLy8NCgkvLyByZXN0YXJ0Og0KCS8vCWZhbHNlIC0gcmVzdGFydCBicm93c2VyDQoJLy8JdHJ1ZSAtIHJlc3RhcnQgYnJvd3NlciB3aXRoIGNvbmZpcm0NCg0KCXZhciBwcmltYXJ5ID0gW3sNCg0KCQkJcHJlZjogWyZxdW90O25ldHdvcmsucHJveHkudHlwZSZxdW90OywgJnF1b3Q70J3QsNGB0YLRgNC+0LnQutC4INC/0YDQvtC60YHQuCZxdW90OywgJnF1b3Q7JnF1b3Q7LCAmcXVvdDtuZXR3b3JrLnByb3h5LnR5cGUmcXVvdDtdLA0KCQkJdXNlckNob2ljZTogNSwgdXNlckFsdDogMSwgcmVmcmVzaDogdHJ1ZSwNCgkJCXZhbHVlczogWw0KCQkJCVswLCAmcXVvdDvQndC1INC/0YDQvtC60YHQuNGA0L7QstCw0YLRjCZxdW90OywgJnF1b3Q7MCZxdW90O10sIFs1LCAmcXVvdDvQodC40YHRgtC10LzQvdGL0LUgKNC40LcgSUUpJnF1b3Q7LCAmcXVvdDs1JnF1b3Q7XSwgWzIsICZxdW90O9CQ0LLRgtC+IChwYWNmaWxlKSZxdW90OywgJnF1b3Q7MiZxdW90O10sDQoJCQkJWzEsICZxdW90O9Cf0YDQvtC/0LjRgdCw0L3QvdGL0LUmcXVvdDssICZxdW90OzEmcXVvdDtdLCBbNCwgJnF1b3Q70JDQstGC0L7QvtC/0YDQtdC00LXQu9C10L3QuNC1JnF1b3Q7LCAmcXVvdDs0JnF1b3Q7XQ0KCV19LA0KCQkJbnVsbCwNCgl7DQoJCQlwcmVmOiBbJnF1b3Q7cGVybWlzc2lvbnMuZGVmYXVsdC5pbWFnZSZxdW90OywgJnF1b3Q70JfQsNCz0YDRg9C20LDRgtGMINCz0YDQsNGE0LjQutGDJnF1b3Q7LCAmcXVvdDsmcXVvdDssICZxdW90O3Blcm1pc3Npb25zLmRlZmF1bHQuaW1hZ2UmcXVvdDtdLA0KCQkJdXNlckNob2ljZTogMSwgcmVmcmVzaDogdHJ1ZSwNCgkJCXZhbHVlczogW1sxLCAmcXVvdDvQlNCwJnF1b3Q7XSwgWzMsICZxdW90O9ChINGB0LDQudGC0LAmcXVvdDtdLCBbMiwgJnF1b3Q70J3QtdGCJnF1b3Q7XV0NCgl9LHsNCgkJCXByZWY6IFsmcXVvdDticm93c2VyLmRpc3BsYXkudXNlX2RvY3VtZW50X2ZvbnRzJnF1b3Q7LCAmcXVvdDvQl9Cw0LPRgNGD0LbQsNGC0Ywgd2ViLdGI0YDQuNGE0YLRiyZxdW90OywgJnF1b3Q7JnF1b3Q7LCAmcXVvdDticm93c2VyLmRpc3BsYXkudXNlX2RvY3VtZW50X2ZvbnRzJnF1b3Q7XSwNCgkJCXVzZXJDaG9pY2U6IDEsIHJlZnJlc2g6IHRydWUsDQoJCQl2YWx1ZXM6IFtbMSwgJnF1b3Q70JTQsCZxdW90O10sIFswLCAmcXVvdDvQndC10YImcXVvdDtdXQ0KCX0sew0KCQkJcHJlZjogWyZxdW90O2phdmFzY3JpcHQuZW5hYmxlZCZxdW90OywgJnF1b3Q70JLRi9C/0L7Qu9C90Y/RgtGMINGB0LrRgNC40L/RgtGLIEphdmEmcXVvdDssICZxdW90OyZxdW90OywgJnF1b3Q7amF2YXNjcmlwdC5lbmFibGVkJnF1b3Q7XSwNCgkJCXVzZXJDaG9pY2U6IHRydWUsIHJlZnJlc2g6IHRydWUsDQoJCQl2YWx1ZXM6IFtbdHJ1ZSwgJnF1b3Q70JTQsCZxdW90O10sIFtmYWxzZSwgJnF1b3Q70J3QtdGCJnF1b3Q7XV0NCgl9LHsNCgkJCXByZWY6IFsmcXVvdDttZWRpYS5hdXRvcGxheS5kZWZhdWx0JnF1b3Q7LCAmcXVvdDvQkNCy0YLQvtC30LDQv9GD0YHQuiDQvNC10LTQuNCwJnF1b3Q7LCAmcXVvdDsmcXVvdDssICZxdW90O21lZGlhLmF1dG9wbGF5LmRlZmF1bHQmcXVvdDtdLA0KCQkJdXNlckNob2ljZTogNSwgcmVmcmVzaDogdHJ1ZSwNCgkJCXZhbHVlczogWw0KCQkJCVs1LCAmcXVvdDvQkdC70L7QutC40YDQvtCy0LDRgtGMINCy0YHQtSZxdW90OywgJnF1b3Q7NSZxdW90O10sDQoJCQkJWzEsICZxdW90O9CR0LvQvtC60LjRgNC+0LLQsNGC0Ywg0L3QtSDQv9GA0LjQs9C70YPRiNC10L3QvdC+0LUmcXVvdDssICZxdW90OzEmcXVvdDtdLA0KCQkJCVswLCAmcXVvdDvQoNCw0LfRgNC10YjQuNGC0Ywg0LLRgdC1JnF1b3Q7LCAmcXVvdDswJnF1b3Q7XQ0KCV19LHsNCgkJCXByZWY6IFsmcXVvdDttZWRpYS5hdXRvcGxheS5ibG9ja2luZ19wb2xpY3kmcXVvdDssICZxdW90O9CQ0LLRgtC+0LfQsNC/0YPRgdC6ICjQv9C+0LvQuNGC0LjQutCwKSZxdW90OywgJnF1b3Q7JnF1b3Q7LCAmcXVvdDttZWRpYS5hdXRvcGxheS5ibG9ja2luZ19wb2xpY3kmcXVvdDtdLA0KCQkJdXNlckNob2ljZTogMSwgdXNlckFsdDogMiwgcmVmcmVzaDogdHJ1ZSwNCgkJCXZhbHVlczogWw0KCQkJCVsxLCAmcXVvdDvQktGA0LXQvNC10L3QvdCw0Y8mcXVvdDssICZxdW90OzEmcXVvdDtdLA0KCQkJCVsyLCAmcXVvdDvQn9C+INC00LXQudGB0YLQstC40Y4mcXVvdDssICZxdW90OzImcXVvdDtdLA0KCQkJCVswLCAmcXVvdDvQn9C+0YHRgtC+0Y/QvdC90LDRjyZxdW90OywgJnF1b3Q7MCZxdW90O10NCgldfSx7DQoJCQlwcmVmOiBbJnF1b3Q7bmV0d29yay5jb29raWUuY29va2llQmVoYXZpb3ImcXVvdDssICZxdW90O0Nvb2tpZXMmcXVvdDssICZxdW90OyZxdW90OywgJnF1b3Q7bmV0d29yay5jb29raWUuY29va2llQmVoYXZpb3ImcXVvdDtdLA0KCQkJdXNlckNob2ljZTogMSwgdXNlckFsdDogMywgcmVmcmVzaDogZmFsc2UsDQoJCQl2YWx1ZXM6IFsNCgkJCQlbMSwgJnF1b3Q70J3QtSDQv9GA0LjQvdC40LzQsNGC0Ywg0YHRgtC+0YDQvtC90L3QuNC1JnF1b3Q7XSwgWzMsICZxdW90O9Cd0LUg0L/RgNC40L3QuNC80LDRgtGMINGBINC90LUg0L/QvtGB0LXRidC10L3QvdGL0YUmcXVvdDtdLCBbNCwgJnF1b3Q70J3QtSDQv9GA0LjQvdC40LzQsNGC0Ywg0L7RgiDRgtGA0LXQutC10YDQvtCyJnF1b3Q7XSwNCgkJCQlbMiwgJnF1b3Q70J3QtSDQv9GA0LjQvdC40LzQsNGC0Ywg0YHQviDQstGB0LXRhSZxdW90O10sIFswLCAmcXVvdDvQn9GA0LjQvdC40LzQsNGC0Ywg0YHQviDQstGB0LXRhSZxdW90O10NCgldfSwNCgkJCW51bGwsDQoJew0KCQkJcHJlZjogWyZxdW90O2RvbS5zdG9yYWdlLmVuYWJsZWQmcXVvdDssICZxdW90O9Cb0L7QutCw0LvRjNC90L7QtSDRhdGA0LDQvdC40LvQuNGJ0LUmcXVvdDssICZxdW90OyZxdW90OywgJnF1b3Q7ZG9tLnN0b3JhZ2UuZW5hYmxlZCZxdW90O10sDQoJCQl1c2VyQ2hvaWNlOiB0cnVlDQoJfQ0KXTsNCg0KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQoNCgl2YXIgc2Vjb25kYXJ5ID0gW3sNCg0KCQkJcHJlZjogWyZxdW90O2RvbS5zZXJ2aWNlV29ya2Vycy5lbmFibGVkJnF1b3Q7LCAmcXVvdDvQktC40LTQtdC+IGRvbS5zZXJ2aWNlV29ya2VycyZxdW90OywgJnF1b3Q7JnF1b3Q7LCAmcXVvdDtkb20uc2VydmljZVdvcmtlcnMuZW5hYmxlZCZxdW90O10sDQoJCQl1c2VyQ2hvaWNlOiBmYWxzZQ0KCX0sew0KCQkJcHJlZjogWyZxdW90O2RvbS5lbmFibGVfcGVyZm9ybWFuY2UmcXVvdDssICZxdW90O9Ch0YLQsNGC0YPRgSDQt9Cw0LPRgNGD0LfQutC4INGB0YLRgNCw0L3QuNGG0YsmcXVvdDssICZxdW90OyZxdW90OywgJnF1b3Q7ZG9tLmVuYWJsZV9wZXJmb3JtYW5jZSZxdW90O10sDQoJCQl1c2VyQ2hvaWNlOiBmYWxzZQ0KCX0sDQoJCQludWxsLA0KCXsNCgkJCXByZWY6IFsmcXVvdDticm93c2VyLmNhY2hlLm1lbW9yeS5lbmFibGUmcXVvdDssICZxdW90O9Ca0Y3RiCDQsiDQvtC/0LXRgNCw0YLQuNCy0L3QvtC5INC/0LDQvNGP0YLQuCZxdW90OywgJnF1b3Q7JnF1b3Q7LCAmcXVvdDticm93c2VyLmNhY2hlLm1lbW9yeS5lbmFibGUmcXVvdDtdLA0KCQkJdXNlckNob2ljZTogdHJ1ZQ0KCX0sDQoJCQludWxsLA0KCXsNCgkJCXByZWY6IFsmcXVvdDtpbnRsLmFjY2VwdF9sYW5ndWFnZXMmcXVvdDssICZxdW90O9Cv0LfRi9C6INC00LvRjyDQstC10LEt0YHRgtGA0LDQvdC40YYmcXVvdDssICZxdW90OyZxdW90OywgJnF1b3Q7aW50bC5hY2NlcHRfbGFuZ3VhZ2VzJnF1b3Q7XSwNCgkJCXVzZXJDaG9pY2U6ICZxdW90O2VuLVVTLCBlbiZxdW90OywNCgkJCXZhbHVlczogW1smcXVvdDtlbi1VUywgZW4mcXVvdDssICZxdW90O2VuLVVTLCBlbiZxdW90O10sIFsmcXVvdDtlbi1VUywgZW4sIHJ1LVJVLCBydSZxdW90OywgJnF1b3Q7ZW4tVVMsIGVuLCBydS1SVSwgcnUmcXVvdDtdXQ0KCX0sew0KCQkJcHJlZjogWyZxdW90O2Jyb3dzZXIuZGlzcGxheS5kb2N1bWVudF9jb2xvcl91c2UmcXVvdDssICZxdW90O9CY0YHQv9C+0LvRjNC30L7QstCw0YLRjCDRhtCy0LXRgtCwINGB0LDQudGC0L7QsiZxdW90OywgJnF1b3Q7JnF1b3Q7LCAmcXVvdDticm93c2VyLmRpc3BsYXkuZG9jdW1lbnRfY29sb3JfdXNlJnF1b3Q7XSwNCgkJCXVzZXJDaG9pY2U6IDAsDQoJCQl2YWx1ZXM6IFtbMCwgJnF1b3Q70JDQstGC0L4mcXVvdDssICZxdW90OzAmcXVvdDtdLCBbMSwgJnF1b3Q70JLRgdC10LPQtNCwJnF1b3Q7LCAmcXVvdDsxJnF1b3Q7XSwgWzIsICZxdW90O9Cd0LjQutC+0LPQtNCwJnF1b3Q7LCAmcXVvdDsyJnF1b3Q7XV0NCgl9LA0KCQkJbnVsbCwNCgl7DQoJCQlwcmVmOiBbJnF1b3Q7bmV0d29yay5odHRwLnNlbmRSZWZlcmVySGVhZGVyJnF1b3Q7LCAmcXVvdDtSZWZlcmVyIC0g0LTQu9GPINGH0LXQs9C+JnF1b3Q7LCAmcXVvdDsmcXVvdDssICZxdW90O25ldHdvcmsuaHR0cC5zZW5kUmVmZXJlckhlYWRlciZxdW90O10sDQoJCQl1c2VyQ2hvaWNlOiAxLA0KCQkJdmFsdWVzOiBbWzAsICZxdW90O9Cd0Lgg0LTQu9GPINGH0LXQs9C+JnF1b3Q7LCAmcXVvdDswJnF1b3Q7XSwgWzEsICZxdW90O9Ci0L7Qu9GM0LrQviDRgdGB0YvQu9C60LgmcXVvdDssICZxdW90OzEmcXVvdDtdLCBbMiwgJnF1b3Q70KHRgdGL0LvQutC4INC4INC40LfQvtCx0YAuJnF1b3Q7LCAmcXVvdDsyJnF1b3Q7XV0NCgl9LHsNCgkJCXByZWY6IFsmcXVvdDtuZXR3b3JrLmh0dHAucmVmZXJlci50cmltbWluZ1BvbGljeSZxdW90OywgJnF1b3Q7UmVmZXJlciAtINGH0YLQviZxdW90OywgJnF1b3Q7JnF1b3Q7LCAmcXVvdDtuZXR3b3JrLmh0dHAucmVmZXJlci50cmltbWluZ1BvbGljeSZxdW90O10sDQoJCQl1c2VyQ2hvaWNlOiAwLA0KCQkJdmFsdWVzOiBbWzAsICZxdW90O9Cf0L7Qu9C90YvQuSBVUkwmcXVvdDssICZxdW90OzAmcXVvdDtdLCBbMSwgJnF1b3Q7c2NoZW1lK2hvc3QrcG9ydCtwYXRoJnF1b3Q7LCAmcXVvdDsxJnF1b3Q7XSwgWzIsICZxdW90O3NjaGVtZStob3N0K3BvcnQmcXVvdDssICZxdW90OzImcXVvdDtdXQ0KCX0sew0KCQkJcHJlZjogWyZxdW90O25ldHdvcmsuaHR0cC5yZWZlcmVyLlhPcmlnaW5Qb2xpY3kmcXVvdDssICZxdW90O1JlZmVyZXJYTyAtINC60L7Qs9C00LAmcXVvdDssICZxdW90OyZxdW90OywgJnF1b3Q7bmV0d29yay5odHRwLnJlZmVyZXIuWE9yaWdpblBvbGljeSZxdW90O10sDQoJCQl1c2VyQ2hvaWNlOiAwLA0KCQkJdmFsdWVzOiBbWzAsICZxdW90O9CSINC70Y7QsdC+0Lwg0YHQu9GD0YfQsNC1JnF1b3Q7LCAmcXVvdDswJnF1b3Q7XSwgWzEsICZxdW90O9Cf0YDQuCDRgdC+0LLQvy4g0LHQsNC3LiDQtNC+0LzQtdC90LAmcXVvdDssICZxdW90OzEmcXVvdDtdLCBbMiwgJnF1b3Q70J/RgNC4INGB0L7QstC/0LDQtNC10L3QuNC4INCw0LTRgNC10YHQsCZxdW90OywgJnF1b3Q7MiZxdW90O11dDQoJfSx7DQoJCQlwcmVmOiBbJnF1b3Q7bmV0d29yay5odHRwLnJlZmVyZXIuWE9yaWdpblRyaW1taW5nUG9saWN5JnF1b3Q7LCAmcXVvdDtSZWZlcmVyWE8gLSDRh9GC0L4mcXVvdDssICZxdW90OyZxdW90OywgJnF1b3Q7bmV0d29yay5odHRwLnJlZmVyZXIuWE9yaWdpblRyaW1taW5nUG9saWN5JnF1b3Q7XSwNCgkJCXVzZXJDaG9pY2U6IDAsDQoJCQl2YWx1ZXM6IFtbMCwgJnF1b3Q70J/QvtC70L3Ri9C5IFVSTCZxdW90OywgJnF1b3Q7MCZxdW90O10sIFsxLCAmcXVvdDtzY2hlbWUraG9zdCtwb3J0K3BhdGgmcXVvdDssICZxdW90OzEmcXVvdDtdLCBbMiwgJnF1b3Q7c2NoZW1lK2hvc3QrcG9ydCZxdW90OywgJnF1b3Q7MiZxdW90O11dDQoJfSx7DQoJCQlwcmVmOiBbJnF1b3Q7bmV0d29yay5odHRwLnJlZmVyZXIuc3Bvb2ZTb3VyY2UmcXVvdDssICZxdW90O1JlZmVyZXIgLSDQutC+0YDQtdC90Ywg0YHQsNC50YLQsCZxdW90OywgJnF1b3Q7JnF1b3Q7LCAmcXVvdDtuZXR3b3JrLmh0dHAucmVmZXJlci5zcG9vZlNvdXJjZSZxdW90O10sDQoJCQl1c2VyQ2hvaWNlOiBmYWxzZQ0KCX0sDQoJCQludWxsLA0KCXsNCgkJCXByZWY6IFsmcXVvdDttZWRpYS5wZWVyY29ubmVjdGlvbi5lbmFibGVkJnF1b3Q7LCAmcXVvdDtXZWJSVEMg0YPRgtC10YfQutCwIElQJnF1b3Q7LCAmcXVvdDsmcXVvdDssICZxdW90O21lZGlhLnBlZXJjb25uZWN0aW9uLmVuYWJsZWQmcXVvdDtdLA0KCQkJdXNlckNob2ljZTogZmFsc2UNCgl9DQoJXTsNCg0KCXJldHVybiB7DQoJCWxhYmVsOiAmcXVvdDtRdWljayB0b2dnbGUmcXVvdDssDQoJCWlkOiAmcXVvdDtRdWlja1RvZ2dsZUFib3V0Q29uZmlnU2V0dGluZ3MmcXVvdDssDQoJCWxvY2FsaXplZDogZmFsc2UsDQoJCWltYWdlOiAmcXVvdDtkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUJBQUFBQVFDQVlBQUFBZjgvOWhBQUFBQVhOU1IwSUFyczRjNlFBQUFBUm5RVTFCQUFDeGp3djhZUVVBQUFBSmNFaFpjd0FBRHNNQUFBN0RBY2R2cUdRQUFBRlBTVVJCVkRoUG5WUE5Tc05BRUo1dGFtbkJrK0E3Qk1FY2lrb2hwL2dpOWkxOG5SYWZRb1QwMGtLMTZ0bm44Q0pvNHZwOW01bTQxZVNnSDB6bWQzZCtkaUovZ2ZkZWR2bDBRVzdrMVBjTHdlbSszVGpvd1phZ0srTm42eWMzZ05DSitMQ0NoOUx6elRNZHFlb05ia1FTRlptcEpMR0NXNUd4MmhaYVFhaE1iWjUyVnVEU2ZIcG5BVkpYT2I0Rkt6aWFuYnpDWGlMckhMWWw1QzN0NU5UUnd0eGFLSnhVVFovSmNPVHI2cTJSeHdmMGFWYjIvaExzNEtxTDNJc2Nrei9tbVNkUlJrc2p5Zyt6N0lNNkx6RENCZnV2QUVPSm1JS0JPcUFXbW8xWW9keExsUU5zeU8wcnNJVi9BWk0rSkdjMmE0R2d6aFoycDltRm1ycGJvQ01xTllCRGRNbHdvbXBvVFdONkYybkZUNWhCWGIwUEVwbW8vR2srb0grUnJxTlpJTlBlSWxuWlZpVjFqUXVMRkpRdVdHQjBnSmR3Z1NodnFkUFhadjZKK0YvUVM3b1hxUTl4QlRGWjVvYThmQUdzOWZlZDVZaFBTd0FBQUFCSlJVNUVya0pnZ2c9PSZxdW90OywNCgkJb25DcmVhdGVkKGJ0bikgew0KCQkJYnRuLnNldEF0dHJpYnV0ZSgmcXVvdDtpbWFnZSZxdW90OywgdGhpcy5pbWFnZSk7DQoJCQl2YXIgZG9jID0gYnRuLm93bmVyRG9jdW1lbnQ7DQoNCgkJCWJ0bi5idG4gPSB0cnVlOw0KCQkJYnRuLmRvbVBhcmVudCA9IG51bGw7DQoJCQlidG4ucG9wdXBzID0gbmV3IGJ0bi5vd25lckdsb2JhbC5BcnJheSgpOw0KCQkJdGhpcy5jcmVhdGVQb3B1cChkb2MsIGJ0biwgJnF1b3Q7cHJpbWFyeSZxdW90OywgcHJpbWFyeSk7DQoJCQl0aGlzLmNyZWF0ZVBvcHVwKGRvYywgYnRuLCAmcXVvdDtzZWNvbmRhcnkmcXVvdDssIHNlY29uZGFyeSk7DQoNCgkJCWJ0bi5saW5rZWRPYmplY3QgPSB0aGlzOw0KCQkJZm9yKHZhciB0eXBlIG9mIFsmcXVvdDtjb21tYW5kJnF1b3Q7LCAmcXVvdDtjb250ZXh0bWVudSZxdW90O10pDQoJCQkJYnRuLnNldEF0dHJpYnV0ZSgmcXVvdDtvbiZxdW90OyArIHR5cGUsIGBsaW5rZWRPYmplY3QuJHt0eXBlfShldmVudClgKTsNCgkJfSwNCgkJY3JlYXRlUG9wdXAoZG9jLCBidG4sIG5hbWUsIGRhdGEpIHsNCgkJCXZhciBwb3B1cCA9IGRvYy5jcmVhdGVFbGVtZW50TlMoeHVsX25zLCAmcXVvdDttZW51cG9wdXAmcXVvdDspOw0KCQkJdmFyIHByb3AgPSBuYW1lICsgJnF1b3Q7UG9wdXAmcXVvdDs7DQoJCQlidG4ucG9wdXBzLnB1c2goYnRuW3Byb3BdID0gcG9wdXApOw0KCQkJcG9wdXAuaWQgPSB0aGlzLmlkICsgJnF1b3Q7LSZxdW90OyArIHByb3A7DQoJCQlwb3B1cC5zZXRBdHRyaWJ1dGUoJnF1b3Q7b25wb3B1cHNob3dpbmcmcXVvdDssICZxdW90O3BhcmVudE5vZGUubGlua2VkT2JqZWN0LnBvcHVwc2hvd2luZyhldmVudCkmcXVvdDspOw0KCQkJZm9yKHZhciBvYmogb2YgZGF0YSkgcG9wdXAuYXBwZW5kKHRoaXMuY3JlYXRlRWxlbWVudChkb2MsIG9iaikpOw0KCQkJYnRuLmFwcGVuZChwb3B1cCk7DQoJCX0sDQoJCWNyZWF0ZUVsZW1lbnQoZG9jLCBvYmopIHsNCgkJCWlmICghb2JqKSByZXR1cm4gZG9jLmNyZWF0ZUVsZW1lbnROUyh4dWxfbnMsICZxdW90O21lbnVzZXBhcmF0b3ImcXVvdDspOw0KCQkJdmFyIHByZWYgPSBkb2Mub3duZXJHbG9iYWwuT2JqZWN0LmNyZWF0ZShudWxsKSwgbm9kZSwgaW1nOw0KCQkJZm9yKHZhciBba2V5LCB2YWxdIG9mIE9iamVjdC5lbnRyaWVzKG9iaikpIHsNCgkJCQlpZiAoa2V5ID09ICZxdW90O3ByZWYmcXVvdDspIHsNCgkJCQkJdmFyIFthcHJlZiwgbGFiLCBha2V5LCB0dHRdID0gdmFsOw0KCQkJCQlwcmVmLnByZWYgPSBhcHJlZjsgcHJlZi5sYWIgPSBsYWIgfHwgYXByZWY7DQoJCQkJCWlmICh0dHQpIHByZWYudHR0ID0gdHR0Ow0KCQkJCX0NCgkJCQllbHNlIGlmIChrZXkgPT0gJnF1b3Q7aW1hZ2UmcXVvdDspIGltZyA9IHZhbCwgcHJlZi5pbWcgPSB0cnVlOw0KCQkJCWVsc2UgaWYgKGtleSAhPSAmcXVvdDt2YWx1ZXMmcXVvdDspIHByZWZba2V5XSA9IHZhbDsNCgkJCX0NCgkJCXZhciB0eXBlID0gcHJlZnMuZ2V0UHJlZlR5cGUocHJlZi5wcmVmKSwgc3RyLCBib29sOw0KCQkJdmFyIHBpbnQgPSB0eXBlID09IHByZWZzLlBSRUZfSU5ULCBpbnYgPSB0eXBlID09IHByZWZzLlBSRUZfSU5WQUxJRDsNCgkJCWlmIChpbnYgJmFtcDsmYW1wOyBvYmoudmFsdWVzIHx8IHBpbnQgfHwgdHlwZSA9PSBwcmVmcy5QUkVGX1NUUklORykNCgkJCQlzdHIgPSBwaW50IHx8IChpbnYgJmFtcDsmYW1wOyB0eXBlb2Ygb2JqLnZhbHVlc1swXVswXSA9PSAmcXVvdDtudW1iZXImcXVvdDspID8gJnF1b3Q7SW50JnF1b3Q7IDogJnF1b3Q7U3RyaW5nJnF1b3Q7LA0KCQkJCXByZWYuYm9vbCA9IGZhbHNlOw0KCQkJZWxzZQ0KCQkJCXN0ciA9ICZxdW90O0Jvb2wmcXVvdDssIHByZWYuYm9vbCA9IHRydWU7DQoJCQlwcmVmLmdldCA9IHByZWZzW2BnZXQke3N0cn1QcmVmYF07DQoJCQlwcmVmLnNldCA9IHByZWZzW2BzZXQke3N0cn1QcmVmYF07DQoNCgkJCW5vZGUgPSBkb2MuY3JlYXRlRWxlbWVudE5TKHh1bF9ucywgJnF1b3Q7bWVudSZxdW90Oyk7DQoJCQlub2RlLmNsYXNzTmFtZSA9ICZxdW90O21lbnUtaWNvbmljJnF1b3Q7Ow0KCQkJbm9kZS5zZXRBdHRyaWJ1dGUoJnF1b3Q7Y2xvc2VtZW51JnF1b3Q7LCAmcXVvdDtub25lJnF1b3Q7KTsNCgkJCWltZyAmYW1wOyZhbXA7IG5vZGUuc2V0QXR0cmlidXRlKCZxdW90O2ltYWdlJnF1b3Q7LCBpbWcpOw0KCQkJYWtleSAmYW1wOyZhbXA7IG5vZGUuc2V0QXR0cmlidXRlKCZxdW90O2FjY2Vzc2tleSZxdW90OywgYWtleSk7DQoJCQkobm9kZS5wcmVmID0gcHJlZikudmFscyA9IGRvYy5vd25lckdsb2JhbC5PYmplY3QuY3JlYXRlKG51bGwpOw0KCQkJdGhpcy5jcmVhdGVSYWRpb3MoZG9jLA0KCQkJCXByZWYuYm9vbCA/IFtbdHJ1ZSwgJnF1b3Q7dHJ1ZSZxdW90O10sIFtmYWxzZSwgJnF1b3Q7ZmFsc2UmcXVvdDtdXSA6IG9iai52YWx1ZXMsDQoJCQkJbm9kZS5hcHBlbmRDaGlsZChkb2MuY3JlYXRlRWxlbWVudE5TKHh1bF9ucywgJnF1b3Q7bWVudXBvcHVwJnF1b3Q7KSkNCgkJCSk7DQoJCQlyZXR1cm4gbm9kZTsNCgkJfSwNCgkJVXNlckNob2ljZUltZzogJnF1b3Q7ZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFCQUFBQUFRQ0FZQUFBQWY4LzloQUFBQ1JVbEVRVlI0MnFXVFMyZ1RRUmpIL3pQSlpvMkJEZmdrQjYydllnNUNqUWR2UlVFOFdCOEhLeWFoWW90SVFRT2VGS0dDRjdFZ3ZRbEJxT0NqV0ZLbGV2QlJEeUw0dUhsb0xYaFlxV0pyb2FFcWxFVFNwdG5kR2IrWlBESDBvak44Tzh2QTk4dnYrL0l0dzM4dTFuU1JZUkU2VWhLeWc0RkYxUjI5Mi9RK3hoaExpNFRJcmdqZ0l6d2U0TWJnbVIybnJaTXR4eEVONjN6WU9SdVBacDdnenBlaHZDdTlYamZ1UG13Q1VISWlFdHc0Zks4OXpWdkQyK0ZIQUQ1NnF1WEJwVjNDVk80cmV0Nm54SHp4WnhkQlJ1cUFEQ0ttejdSSEQ5eTJ0bG1iWWJCVmZ3RThEWEJrRWQveTM5SDUrbXplOFp5b1NJcHNGWEM5dS9WRTMvbGRweWc1QUFNRW9KTVRRaTJoQU5LQmd5S2R5MGgvZW9DaHFjZjlNaW12VkFIamQvZmRpRzBOUndnUXBEQXAxYWdCcERad2RIS0pMS1p6YytoNWUza0NTZXhoNWM1ajhmbWhXMEhHcE5aWEZrcWZzUXBBS2djRktHbUFsQXhIWHA1YmtrbXNyaG9zamg0Y0NJSjVwRzVxZlFYZ3RNc2xxTzFxZ0VNV1RQclIrZXJpRWhvQTR3TjdMOFRXaDBLVlh6ZmdZMlJRQVVqVkJlbldMSDRVQ3JqMDRXYTlCTlhFbzV2YSt3NjN4Q2lKNldSVlAyTVZnTlFJZ2pnRUExN01UT0RaN0x0K0F0U2FHREc0Mzc3YTFtMkZBa0tyYzExL2RVd0lJRDFkU0tIRWNXM3lmdDRSYnBSNmtLMVBZZ2FKdGFZMW5OcDVqSWVNc2pLTmJzMUFXUlVjanZUbnAyS2g5THRMSkdURElOVWhjVElaM0wraHpkcTlaZ3ZXbVNGOS9XdTVnSThMMDNnelA1bDNoZGRMLzMvektEZEE5TWRFMFVFUnJkemFGR01VYWFwNzVZL3BYOVlmYXA3NkVRWWFDZUVBQUFBQVNVVk9SSzVDWUlJPSZxdW90OywNCgkJbm90VXNlckNob2ljZUltZzogJnF1b3Q7ZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFCQUFBQUFRQ0FZQUFBQWY4LzloQUFBQ05VbEVRVlI0MnFYVFQyalRVQndIOEc5ZTB0YTJrczVORDBXdy9xWDFvR3lldkV3UW5PQkE2RUhYd0x3b1VoM2VSR1JzNTAxUlBFNnhncDZLcmV4UUVDWlk4REJQWG1iUlM0Wi9LMGdSdG1tRGEyeWI1UGxMWDdwMkd3cGk0RWZDeThzbjMvZFB3bjllMHNhR25DUkY2WFlGbkE5RGtoS3RSczUxZXA2am10RWNwL0pISU05WWl2bDltZjBYTkRWMk5nbjFZTHpWeGRCMWxKOFU4UDVoenVDV25SNnhyUHdtSU04a0xSamRrVDMyNkJhTEhOZ0xLQUZBOW91WGRoT3c2cWkrKzRqNTg5Y2Q4OXZTYU1xeWMyc0FQVVhsZ0Y4Znl0OVdJM3QyQXY0dzROc0NNSjhBSEFLYXY2aHFxSDc2aXVMSU5jTnVOaE9hd3l0dFlDcCs3dFJFLzZYVDlHRlFBRzRDcG5pQVRRa0lhTlFJTVZHNi94U0wyV2ZUR3VlVGJXRGg1TDJyQTl0MjlRR0JyUVFFUFVEdUF1b0VtRlNyK1A1bEdjOHYzM210QVVmYVFPM000L0dnRE9vWUNJa1VpbjhEMEJERG9CUTJaTXhxTjB3Q1FoMGdNeGFVblliNHV6dCtkd0laOHdCSFRHUWJZQUhNcHUrdUF4YUd4cE1EdlNyM0FIY0ZhQUlsRCtCdG9ONmFnNVdxaE9MTndyb2hUTVdQSDVyb1A3cGRMSXdiM3dXNkV6aVdHQVpocFZkTFdIenhkcHFBeWM0eUtySis0dUtnMm9NVitsZ1JLOUNkd0FWc0cxV3BGOFVIODRadDJRa0NLbXNiaVJBdEZBbGxCNU9IV1E5ZnByODFPd2xjZ0JMOWtQcndzdkRHTVExek5NVjVaeU4xSVNsWllabDkvVEUxdGp1TVNGZ0ExVldPOHVlZitGQXFHNDd0cEZNY203ZHlGeUlPRXpCTWxmQ2FkYW81cWhrMzlsOVA0NzlldndGYmlPY1JTWEt1ZUFBQUFBQkpSVTVFcmtKZ2dnPT0mcXVvdDssDQoJCVVzZXJBbHRJbWc6ICZxdW90O2RhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQkFBQUFBUUNBWUFBQUFmOC85aEFBQUFBWE5TUjBJQXJzNGM2UUFBQUFSblFVMUJBQUN4and2OFlRVUFBQUFKY0VoWmN3QUFEc01BQUE3REFjZHZxR1FBQUFJZlNVUkJWRGhQcFZNOWI5TlFGRDAyY1NLS0ZWR0tJRkZSRUZzbUZpQ0ExQUVRUXJRakMwZ3NzTENrQzBqSmowaUZXRm9HZGlUNEF5MFNFbUpCaFBJNUZCb2tpa0w0U0NDMFRlMlV4SW50MTNNZHUxQ1ZyVmM2NzEzZmU4NngvVDZ3MDlEQ2VUTktKN1EwcHp5VW1vQ21aWU9pVWhYbXM4Uk1jZDZ2QjdVd3RoaE01ZlRMV2l4MkwzUG1ZaktkT3dkejlEREZHdHIxS3Vvdm5xRDI5SkdsZk85R29ldzlEQ1YvRGFaeTJwWEU4UEQ5WS9tYnVwazZ4RTZjVldQUWhFdWpIbzIrNGZYZE83Nnp0bnExVVBZZlNDY3dLQjFIV2plTXl1bkNyYVNaT3NEcWJrQlBzQk9UTm9NR3ZrT1RMdG8vZitGNTZiYmxlMjYyT0svcWVzaVl6SXlkVEpvakZManJnRWU0YmNJT0VkWFdZZTZMSVROMktnbUZTUkZHQnVQcG8wZUFuZ1gwU2V4VEpIRDVMT2dMcEVaVGNnS3VVdU1pakF5eTVsNytyME5TYjIxZzVMUUk1Z0dZU3kyQWpZQkxqUXlSQVVuaVRuSlhzQm9heUJ6bTNSQkJuZHd3SW9PSzNmZ05kSVJFUVlDVi8wRHFMZGlOWnFDUklUS1lheXg4NVJmUXVVTmlaM2s3SWdPK3ZmR2VYR3BraUF5bWErK1dMSHRaaFo4bzVIL0ZFVnBvczFWN3U4VEZ3TFFJZDhudytBZmE1MU9xMnZ5eWNtbGs5S0NXMEdYRlpldTYzSVVPOHo4OEJ4NXMyOFNidVVYZmRkenJ4VmNvYnhwSTBHVGg3SDczNC9kUHpRdDlkMC9DR0JwQ1BCN25iaG13YkFQVnhSNCtQUHRzdVU3L1d1RWx0aC9sS09SVWNzb1RFOFRnTWcwV2JKYVk0WnUzWEtZZEJyQUJBUlVrK2xzNERmUUFBQUFBU1VWT1JLNUNZSUk9JnF1b3Q7LA0KCQl1cGQobm9kZSkgew0KCQkJdmFyIHtwcmVmfSA9IG5vZGUsIGRlZiA9IGZhbHNlLCB1c2VyID0gZmFsc2UsIHZhbDsNCgkJCWlmIChwcmVmcy5nZXRQcmVmVHlwZShwcmVmLnByZWYpICE9IHByZWZzLlBSRUZfSU5WQUxJRCkgew0KCQkJCXZhciBwbiA9IHByZWYucHJlZjsNCgkJCQl0cnkge3ZhbCA9IGRiW3ByZWYuZ2V0Lm5hbWVdKHBuKTsgZGVmID0gdHJ1ZX0gY2F0Y2goZXgpIHtkZWYgPSBmYWxzZTt9DQoJCQkJdmFyIHVzZXIgPSBwcmVmcy5wcmVmSGFzVXNlclZhbHVlKHBuKTsNCgkJCQlpZiAodXNlcikgdHJ5IHt2YWwgPSBwcmVmLmdldChwbiwgdW5kZWZpbmVkKTt9IGNhdGNoKGV4KSB7fQ0KCQkJfQ0KCQkJaWYgKHZhbCA9PSBwcmVmLnZhbCAmYW1wOyZhbXA7IGRlZiA9PSBwcmVmLmRlZiAmYW1wOyZhbXA7IHVzZXIgPT0gcHJlZi51c2VyKSByZXR1cm47DQoJCQlwcmVmLnZhbCA9IHZhbDsgcHJlZi5kZWYgPSBkZWY7IHByZWYudXNlciA9IHVzZXI7DQoJCQl2YXIgZXhpc3RzID0gZGVmIHx8IHVzZXI7DQoNCgkJCXZhciB0dHQgPSBleGlzdHMgPyB2YWwgOiAmcXVvdDvQrdGC0L7Qs9C+INC/0YDQtdGE0LAg0L3QtSDRgdGD0YnQtdGB0YLQstGD0LXRgiZxdW90OzsNCgkJCWlmICh0dHQgPT09ICZxdW90OyZxdW90OykgdHR0ID0gJnF1b3Q7WyBlbXB0eV9zdHJpbmcgXSZxdW90OzsNCgkJCWlmIChwcmVmLnR0dCkgdHR0ICs9ICZxdW90O1xuJnF1b3Q7ICsgcHJlZi50dHQ7DQoJCQlub2RlLnRvb2x0aXBUZXh0ID0gdHR0Ow0KDQoJCQlpZiAoJnF1b3Q7dXNlckNob2ljZSZxdW90OyBpbiBwcmVmKQ0KCQkJCWlmICh2YWwgPT0gcHJlZi51c2VyQ2hvaWNlKQ0KCQkJCQlub2RlLnN0eWxlLnJlbW92ZVByb3BlcnR5KCZxdW90O2NvbG9yJnF1b3Q7KSwNCgkJCQkJcHJlZi5pbWcgfHwgbm9kZS5zZXRBdHRyaWJ1dGUoJnF1b3Q7aW1hZ2UmcXVvdDssIHRoaXMuVXNlckNob2ljZUltZyk7DQoJCQkJZWxzZQ0KCQkJCQlub2RlLnN0eWxlLnNldFByb3BlcnR5KCZxdW90O2NvbG9yJnF1b3Q7LCAmcXVvdDttYXJvb24mcXVvdDssICZxdW90O2ltcG9ydGFudCZxdW90OyksDQoJCQkJCXByZWYuaW1nIHx8IG5vZGUuc2V0QXR0cmlidXRlKCZxdW90O2ltYWdlJnF1b3Q7LCB0aGlzLm5vdFVzZXJDaG9pY2VJbWcpOw0KCQkJZWxzZSAoJnF1b3Q7dXNlckFsdCZxdW90OyBpbiBwcmVmKQ0KCQkJCWlmICh2YWwgPT0gcHJlZi51c2VyQWx0KQ0KCQkJCQlwcmVmLmltZyB8fCBub2RlLnNldEF0dHJpYnV0ZSgmcXVvdDtpbWFnZSZxdW90OywgdGhpcy5Vc2VyQWx0SW1nKTsNCgkJCXVzZXINCgkJCQk/IG5vZGUuc3R5bGUuc2V0UHJvcGVydHkoJnF1b3Q7Zm9udC1zdHlsZSZxdW90OywgJnF1b3Q7aXRhbGljJnF1b3Q7LCAmcXVvdDtpbXBvcnRhbnQmcXVvdDspDQoJCQkJOiBub2RlLnN0eWxlLnJlbW92ZVByb3BlcnR5KCZxdW90O2ZvbnQtc3R5bGUmcXVvdDspOw0KDQoJCQl2YXIge2xhYn0gPSBwcmVmOw0KCQkJaWYgKGV4aXN0cyAmYW1wOyZhbXA7ICFwcmVmLmJvb2wpIHsNCgkJCQlpZiAodmFsIGluIHByZWYudmFscykgdmFyIHNmeCA9IHByZWYudmFsc1t2YWxdIHx8IHZhbDsNCgkJCQllbHNlIHZhciBzZnggPSB1c2VyID8gJnF1b3Q70JTRgNGD0LPQvtC1JnF1b3Q7IDogJnF1b3Q70J/QviDRg9C80L7Qu9GH0LDQvdC40Y4mcXVvdDs7DQoJCQkJbGFiICs9IGAgJm1kYXNoOyAmcXVvdDske3NmeH0mcXVvdDtgOw0KCQkJfQ0KCQkJbm9kZS5zZXRBdHRyaWJ1dGUoJnF1b3Q7bGFiZWwmcXVvdDssIGxhYik7DQoJCX0sDQoJCWNyZWF0ZVJhZGlvcyhkb2MsIHZhbHMsIHBvcHVwKSB7DQoJCQlmb3IodmFyIGFyciBvZiB2YWxzKSB7DQoJCQkJaWYgKCFhcnIpIHsNCgkJCQkJcG9wdXAuYXBwZW5kKGRvYy5jcmVhdGVFbGVtZW50TlMoeHVsX25zLCAmcXVvdDttZW51c2VwYXJhdG9yJnF1b3Q7KSk7DQoJCQkJCWNvbnRpbnVlOw0KCQkJCX0NCgkJCQl2YXIgW3ZhbCwgbGFiLCBrZXksIHR0dF0gPSBhcnI7DQoJCQkJdmFyIG1lbnVpdGVtID0gZG9jLmNyZWF0ZUVsZW1lbnROUyh4dWxfbnMsICZxdW90O21lbnVpdGVtJnF1b3Q7KTsNCgkJCQltZW51aXRlbS5zZXRBdHRyaWJ1dGUoJnF1b3Q7dHlwZSZxdW90OywgJnF1b3Q7cmFkaW8mcXVvdDspOw0KCQkJCW1lbnVpdGVtLnNldEF0dHJpYnV0ZSgmcXVvdDtjbG9zZW1lbnUmcXVvdDssICZxdW90O25vbmUmcXVvdDspOw0KCQkJCW1lbnVpdGVtLnNldEF0dHJpYnV0ZSgmcXVvdDtsYWJlbCZxdW90OywgcG9wdXAucGFyZW50Tm9kZS5wcmVmLnZhbHNbdmFsXSA9IGxhYik7DQoJCQkJa2V5ICZhbXA7JmFtcDsgbWVudWl0ZW0uc2V0QXR0cmlidXRlKCZxdW90O2FjY2Vzc2tleSZxdW90Oywga2V5KTsNCgkJCQl2YXIgdGlwID0gbWVudWl0ZW0udmFsID0gdmFsOw0KCQkJCWlmICh0dHQpIHRpcCArPSAmcXVvdDtcbiZxdW90OyArIHR0dDsNCgkJCQltZW51aXRlbS50b29sdGlwVGV4dCA9IHRpcDsNCgkJCQlwb3B1cC5hcHBlbmQobWVudWl0ZW0pOw0KCQkJfQ0KCQl9LA0KCQlvcGVuUG9wdXAocG9wdXApIHsNCgkJCXZhciBidG4gPSBwb3B1cC5wYXJlbnROb2RlOw0KCQkJaWYgKGJ0bi5kb21QYXJlbnQgIT0gYnRuLnBhcmVudE5vZGUpIHsNCgkJCQlidG4uZG9tUGFyZW50ID0gYnRuLnBhcmVudE5vZGU7DQoJCQkJdmFyIHBvczsNCgkJCQlpZiAoYnRuLm1hdGNoZXMoJnF1b3Q7LndpZGdldC1vdmVyZmxvdy1saXN0ICZndDsgOnNjb3BlJnF1b3Q7KSkNCgkJCQkJcG9zID0gJnF1b3Q7YWZ0ZXJfc3RhcnQmcXVvdDs7DQoJCQkJZWxzZSB2YXIgd2luID0gYnRuLm93bmVyR2xvYmFsLCB7d2lkdGgsIGhlaWdodCwgdG9wLCBib3R0b20sIGxlZnQsIHJpZ2h0fSA9DQoJCQkJCWJ0bi5jbG9zZXN0KCZxdW90O3Rvb2xiYXImcXVvdDspLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLCBwb3MgPSB3aWR0aCAmZ3Q7IGhlaWdodA0KCQkJCQkJPyBgJHt3aW4uaW5uZXJIZWlnaHQgLSBib3R0b20gJmd0OyB0b3AgPyAmcXVvdDthZnRlciZxdW90OyA6ICZxdW90O2JlZm9yZSZxdW90O31fc3RhcnRgDQoJCQkJCQk6IGAke3dpbi5pbm5lcldpZHRoIC0gcmlnaHQgJmd0OyBsZWZ0ID8gJnF1b3Q7ZW5kJnF1b3Q7IDogJnF1b3Q7c3RhcnQmcXVvdDt9X2JlZm9yZWA7DQoJCQkJZm9yKHZhciBwIG9mIGJ0bi5wb3B1cHMpIHAuc2V0QXR0cmlidXRlKCZxdW90O3Bvc2l0aW9uJnF1b3Q7LCBwb3MpOw0KCQkJfQ0KCQkJcG9wdXAub3BlblBvcHVwKGJ0bik7DQoJCX0sDQoJCW1heWJlUmVzdGFydChub2RlLCBjb25mKSB7DQoJCQl2YXIgbXNnUmVzdCA9ICZxdW90O9Cf0LXRgNC10LfQsNC/0YPRgdGC0LjRgtGMINCx0YDQsNGD0LfQtdGAPyZxdW90OywgbXNnQWJvcnQgPSAmcXVvdDvQl9Cw0L/RgNC+0YEg0L3QsCDQstGL0YXQvtC0INC+0YLQvNC10L3QtdC9LiZxdW90OzsNCgkJCWlmIChwdiAmZ3Q7PSA3Nykgew0KCQkJCXZhciB0aXRsZSA9IG5vZGUuY2xvc2VzdCgmcXVvdDt0b29sYmFyYnV0dG9uJnF1b3Q7KS5sYWJlbDsNCgkJCQl2YXIgcHAgPSBkb21XaW4gPSZndDsgU2VydmljZXMucHJvbXB0LndyYXBwZWRKU09iamVjdC5waWNrUHJvbXB0ZXIoew0KCQkJCQlkb21XaW4sIG1vZGFsVHlwZTogQ2kubnNJUHJvbXB0Lk1PREFMX1RZUEVfV0lORE9XDQoJCQkJfSk7DQoJCQkJdmFyIGNvbmZpcm0gPSB3aW4gPSZndDsgcHAod2luKS5jb25maXJtKHRpdGxlLCBtc2dSZXN0KTsNCgkJCQl2YXIgYWxlcnQgPSB3aW4gPSZndDsgcHAod2luKS5hbGVydCh0aXRsZSwgbXNnQWJvcnQpOw0KCQkJfSBlbHNlIHsNCgkJCQl2YXIgY29uZmlybSA9IHdpbiA9Jmd0OyB3aW4uY29uZmlybShtc2dSZXN0KTsNCgkJCQl2YXIgYWxlcnQgPSB3aW4gPSZndDsgd2luLmFsZXJ0KG1zZ0Fib3J0KTsNCgkJCX0NCgkJCXJldHVybiAodGhpcy5tYXlCZVJlc3RhcnQgPSAobm9kZSwgY29uZikgPSZndDsgew0KCQkJCXZhciB3aW4gPSBub2RlLm93bmVyR2xvYmFsOw0KCQkJCWlmIChjb25mICZhbXA7JmFtcDsgIWNvbmZpcm0od2luKSkgcmV0dXJuOw0KCQkJCWlmICh3aW4uQnJvd3NlclV0aWxzLnJlc3RhcnRBcHBsaWNhdGlvbigpID09PSBmYWxzZSkgYWxlcnQod2luKTsNCgkJCQllbHNlIHJldHVybiB0cnVlOw0KCQkJfSkobm9kZSwgY29uZik7DQoJCX0sDQoJCXJlZ2V4cFJlZnJlc2g6IC9eKD86dmlldy1zb3VyY2U6KT8oPzpodHRwcz98ZnRwKS8sDQoJCW1heWJlUmUobm9kZSwgZmUpIHsNCgkJCXZhciB7cHJlZn0gPSBub2RlOw0KCQkJaWYgKCZxdW90O3Jlc3RhcnQmcXVvdDsgaW4gcHJlZikgew0KCQkJCWlmICh0aGlzLm1heWJlUmVzdGFydChub2RlLCBwcmVmLnJlc3RhcnQpKSByZXR1cm47DQoJCQl9DQoJCQllbHNlIHRoaXMucG9wdXBzaG93aW5nKGZlLCBub2RlLnBhcmVudE5vZGUpOw0KCQkJaWYgKCZxdW90O3JlZnJlc2gmcXVvdDsgaW4gcHJlZikgew0KCQkJCXZhciB3aW4gPSBub2RlLm93bmVyR2xvYmFsOw0KCQkJCWlmICh0aGlzLnJlZ2V4cFJlZnJlc2gudGVzdCh3aW4uZ0Jyb3dzZXIuY3VycmVudFVSSS5zcGVjKSkgcHJlZi5yZWZyZXNoDQoJCQkJCT8gd2luLkJyb3dzZXJSZWxvYWRTa2lwQ2FjaGUoKSA6IHdpbi5Ccm93c2VyUmVsb2FkKCk7DQoJCQl9DQoJCX0sDQoJCWNvbW1hbmQoZSkgew0KCQkJdmFyIHRyZyA9IGUudGFyZ2V0Ow0KCQkJaWYgKHRyZy5idG4pIHJldHVybiB0aGlzLm9wZW5Qb3B1cCh0cmcucHJpbWFyeVBvcHVwKTsNCg0KCQkJdmFyIG1lbnUgPSB0cmcuY2xvc2VzdCgmcXVvdDttZW51JnF1b3Q7KSwgbmV3VmFsID0gdHJnLnZhbDsNCgkJCWlmIChuZXdWYWwgIT0gbWVudS5wcmVmLnZhbCkNCgkJCQltZW51LnByZWYuc2V0KG1lbnUucHJlZi5wcmVmLCBuZXdWYWwpLA0KCQkJCXRoaXMubWF5YmVSZShtZW51LCB0cnVlKTsNCgkJfSwNCgkJcG9wdXBzaG93aW5nKGUsIHRyZyA9IGUudGFyZ2V0KSB7DQoJCQlpZiAodHJnLmlkKSB7DQoJCQkJZm9yKHZhciBub2RlIG9mIHRyZy5jaGlsZHJlbikgew0KCQkJCQlpZiAobm9kZS5ub2RlTmFtZS5lbmRzV2l0aCgmcXVvdDtyJnF1b3Q7KSkgY29udGludWU7DQoJCQkJCXRoaXMudXBkKG5vZGUpOw0KCQkJCQkhZSAmYW1wOyZhbXA7IG5vZGUub3BlbiAmYW1wOyZhbXA7IHRoaXMucG9wdXBzaG93aW5nKG51bGwsIG5vZGUucXVlcnlTZWxlY3RvcigmcXVvdDttZW51cG9wdXAmcXVvdDspKTsNCgkJCQl9DQoJCQkJcmV0dXJuOw0KCQkJfQ0KCQkJdmFyIHt2YWx9ID0gdHJnLmNsb3Nlc3QoJnF1b3Q7bWVudSZxdW90OykucHJlZjsNCgkJCXZhciBjaGVja2VkID0gdHJnLnF1ZXJ5U2VsZWN0b3IoJnF1b3Q7W2NoZWNrZWRdJnF1b3Q7KTsNCgkJCWlmIChjaGVja2VkKSB7DQoJCQkJaWYgKGNoZWNrZWQudmFsID09IHZhbCkgcmV0dXJuOw0KCQkJCWVsc2UgY2hlY2tlZC5yZW1vdmVBdHRyaWJ1dGUoJnF1b3Q7Y2hlY2tlZCZxdW90Oyk7DQoJCQl9DQoJCQlmb3IodmFyIG5vZGUgb2YgdHJnLmNoaWxkcmVuKSBpZiAoJnF1b3Q7dmFsJnF1b3Q7IGluIG5vZGUgJmFtcDsmYW1wOyBub2RlLnZhbCA9PSB2YWwpIHsNCgkJCQlub2RlLnNldEF0dHJpYnV0ZSgmcXVvdDtjaGVja2VkJnF1b3Q7LCB0cnVlKTsNCgkJCQlicmVhazsNCgkJCX0NCgkJfSwNCgkJY29udGV4dG1lbnUoZSkgew0KCQkJdmFyIHRyZyA9IGUudGFyZ2V0Ow0KCQkJaWYgKHRyZy5idG4pIHsNCgkJCQlpZiAoZS5jdHJsS2V5IHx8IGUuc2hpZnRLZXkpIHJldHVybjsNCgkJCQlpZiAoZS5kZXRhaWwgPT0gMikgcmV0dXJuIHRyZy5zZWNvbmRhcnlQb3B1cC5oaWRlUG9wdXAoKTsNCgkJCQl0aGlzLm9wZW5Qb3B1cCh0cmcuc2Vjb25kYXJ5UG9wdXApOw0KCQkJfQ0KCQkJZWxzZSBpZiAoJnF1b3Q7cHJlZiZxdW90OyBpbiB0cmcgJmFtcDsmYW1wOyB0cmcucHJlZi51c2VyKQ0KCQkJCXByZWZzLmNsZWFyVXNlclByZWYodHJnLnByZWYucHJlZiksDQoJCQkJdGhpcy5tYXliZVJlKHRyZyk7DQoJCQllLnByZXZlbnREZWZhdWx0KCk7DQoJCX0NCgl9Ow0KfSk7


2020.1597428606.png

Отредактировано _zt (Вчера 21:39:11)

Отсутствует

 

Board footer

Powered by PunBB
Modified by Mozilla Russia
Copyright © 2004–2020 Mozilla Russia
Язык отображения форума: [Русский] [English]