Skip to content

Instantly share code, notes, and snippets.

@vladkorotnev
Last active May 30, 2017 17:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vladkorotnev/845bb0d7eaa71153f763 to your computer and use it in GitHub Desktop.
Save vladkorotnev/845bb0d7eaa71153f763 to your computer and use it in GitHub Desktop.
Semi-Unofficial port of vPGP2 to Firefox. ALPHA VERSION
// ==UserScript==
// @name libakasakacore vPGP bundle
// @namespace libakasakacore
// @description by popular demand, ported to FFox by Genjitsu Gadget Lab team
// @include *://vk.com/*
// @version 1
// @grant GM_addStyle
// ==/UserScript==
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
var D = document;
var scriptNode = D.createElement ('script');
if (runOnLoad) {
scriptNode.addEventListener ("load", runOnLoad, false);
}
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}
var uri="data:text/javascript;base64,Ly8gPT1Vc2VyU2NyaXB0PT0NCi8vIEBuYW1lICAgICAgICBsaWJha2FzYWthY29yZSBidW5kbGUNCi8vIEBuYW1lc3BhY2UgICBsaWJha2FzYWthY29yZQ0KLy8gQGRlc2NyaXB0aW9uIGJ5IHBvcHVsYXIgZGVtYW5kLCBieSBHZW5qaXRzdSBHYWRnZXQgTGFiIHRlYW0NCi8vIEBpbmNsdWRlICAgICB2ay5jb20NCi8vIEB2ZXJzaW9uICAgICAxDQovLyBAZ3JhbnQgICAgICAgbm9uZQ0KLy8gPT0vVXNlclNjcmlwdD09DQoNCnZhciBsaWJha2FzYWthZ3VpID0gbmV3IE9iamVjdDsNCmxpYmFrYXNha2FndWkuZGVmRm9vdGVyID0gJzxmb250IHN0eWxlPSJjb2xvcjojYWFhIiBvbmNsaWNrPSJsaWJha2FzYWthZ3VpLmFib3V0KCkiPkVsIFBzeSBDb25ncm9vPC9mb250Pic7DQpsaWJha2FzYWthZ3VpLmFib3V0ID0gZnVuY3Rpb24oKSB7DQoJLyog0e7n5ODl7CDs5fHx4OTm4e7q8SAqLyANCgl2YXIgbXlib3ggPSB3aW5kb3cuTWVzc2FnZUJveCh7IA0KCQl0aXRsZTogJ2xpYmFrYXNha2Fjb3JlIGZvciBWSycsIA0KCQl3aWR0aDogNDEwLCANCgkJaGVpZ2h0OiAnYXV0bycsIA0KCQlhbmltU3BlZWQ6IDAsIA0KCQlib2R5U3R5bGU6ICcnLCANCgkJZGFyazogdHJ1ZSwgDQoJCXNlbGZEZXN0cnVjdDogZmFsc2UsIA0KCQlwcm9ncmVzczogZmFsc2UsIA0KCQloaWRlT25CR0NsaWNrOiB0cnVlLCANCgkJaGlkZUJ1dHRvbnM6IGZhbHNlLCANCgkJb25TaG93OiBmYWxzZSwgDQoJCW9uSGlkZUF0dGVtcHQ6IGZhbHNlLCANCgkJb25CZWZvcmVIaWRlOiBmYWxzZSwgDQoJCW9uSGlkZTogZmFsc2UsIA0KCQlvbkNsZWFuOiBmYWxzZSwgDQoJCW9uRGVzdHJveTogZmFsc2UgDQoJICB9KTsgDQoJLyogwvvx8uDi6//l7CDq7u3y5e3yICovIA0KCW15Ym94LmNvbnRlbnQoJ1RoZSBvbmUgYW5kIG9ubHkgVksgZXh0ZW5zaW9uIGRldmVsb3BtZW50IHBsYXRmb3JtLi4uPGJyPjxjZW50ZXI+PGgxPmxpYmFrYXNha2Fjb3JlICcrbGliYWthc2FrYWNvcmUudmVyLnRvU3RyaW5nKCkrJzwvaDE+PC9jZW50ZXI+PGJyPjxpbWcgc3JjPSJodHRwOi8vY3M0MjU5MjcudmsubWUvdjQyNTkyNzExOS82NjY0L2xydEJ1NlR0VERNLmpwZyIgIHN0eWxlPSJ3aWR0aDoxMDAlO2hlaWdodDphdXRvIj48YnI+QnkgPGEgaHJlZj0iL2FrYXNha2EiPlZsYWRpc2xhdiBLb3JvdG5ldjwvYT48YnI+PHN0cm9uZz5GRiBwb3J0IGJ5IEdlbmppdHN1IEdhZGdldCBMYWI8L3N0cm9uZz4nKTsgDQoJLyogxO7h4OLr/+XsIOrt7u/q6CAqLyANCglteWJveC5hZGRCdXR0b24oJ09LJywgdW5kZWZpbmVkLCAnZ3JheScpOyANCglteWJveC5zZXRDb250cm9sc1RleHQobGliYWthc2FrYWd1aS5kZWZGb290ZXIgKTsgDQoJLyogzunr/vLxISAqLyANCglteWJveC5zaG93KCk7IA0KfQ0KDQpsaWJha2FzYWthZ3VpLnByb21wdCA9IGZ1bmN0aW9uKHRpdGxlLCBtZXNzYWdlLCBwbGFjZWhvbGRlciwgZm9vdGVyLCAgY2FsbGJhY2ssIGNhbkNhbmNlbCkgew0KCS8qINHu5+Tg5ewg7OXx8eDk5uHu6vEgKi8gDQoJdmFyIG15Ym94ID0gd2luZG93Lk1lc3NhZ2VCb3goeyANCgkJdGl0bGU6IHRpdGxlIHx8ICdsaWJha2FzYWthY29yZSBpbnB1dCBkaWFsb2cnLCANCgkJd2lkdGg6IDQxMCwgDQoJCWhlaWdodDogJ2F1dG8nLCANCgkJYW5pbVNwZWVkOiAwLCANCgkJYm9keVN0eWxlOiAnJywgDQoJCWRhcms6IHRydWUsIA0KCQlzZWxmRGVzdHJ1Y3Q6IHRydWUsIA0KCQlwcm9ncmVzczogZmFsc2UsIA0KCQloaWRlT25CR0NsaWNrOiB0cnVlLCANCgkJaGlkZUJ1dHRvbnM6IGZhbHNlLCANCgkJb25TaG93OiBmYWxzZSwgDQoJCW9uSGlkZUF0dGVtcHQ6IGZhbHNlLCANCgkJb25CZWZvcmVIaWRlOiBmYWxzZSwgDQoJCW9uSGlkZTogZmFsc2UsIA0KCQlvbkNsZWFuOiBmYWxzZSwgDQoJCW9uRGVzdHJveTogZmFsc2UgDQoJICB9KTsgDQoJLyogwvvx8uDi6//l7CDq7u3y5e3yICovIA0KCXZhciB0ZW1waWQgPSBsaWJha2FzYWthY29yZS5tYWtlUmFuZG9tU3RyaW5nKDEwKTsNCglteWJveC5jb250ZW50KCc8Y2VudGVyPicrKG1lc3NhZ2UgfHwgJ1Vua25vd24gcHJvbXB0LicpKyc8YnI+PGlucHV0IHR5cGU9IicrKHBsYWNlaG9sZGVyLnRvTG93ZXJDYXNlKCkuaW5kZXhPZigicGFzc3dvcmQiKSA+IC0xID8gJ3Bhc3N3b3JkJyA6ICd0ZXh0JyApKyciIGlkPSJsaWJha2FzYWthY29yZV9pbnB1dF8nK3RlbXBpZCsnIiBwbGFjZWhvbGRlcj0iJysocGxhY2Vob2xkZXIgfHwgJycpKyciPjwvY2VudGVyPicpOyANCgkvKiDE7uHg4uv/5ewg6u3u7+roICovIA0KCWlmKHR5cGVvZiBjYWxsYmFjayAhPSAndW5kZWZpbmVkJykgbXlib3guYWRkQnV0dG9uKCdPSycsIGZ1bmN0aW9uKCkgeyANCgkJdmFyIHZhbHVlID0gJCgnI2xpYmFrYXNha2Fjb3JlX2lucHV0XycrdGVtcGlkKS52YWwoKTsNCgkJaWYodmFsdWUudHJpbSgpID09ICcnKSByZXR1cm47DQoJCW15Ym94LmhpZGUoKTsNCgkJY2FsbGJhY2sodmFsdWUpOw0KCQ0KCQlyZXR1cm4gdHJ1ZTsNCgl9LCAnYmx1ZScpOyANCglpZihjYW5DYW5jZWwpIG15Ym94LmFkZEJ1dHRvbignQ2FuY2VsJywgdW5kZWZpbmVkLCAnZ3JheScpOyANCglteWJveC5zZXRDb250cm9sc1RleHQoJzxmb250IHN0eWxlPSJjb2xvcjojYWFhIj4nKyhmb290ZXIgfHwgJycpKyc8L2ZvbnQ+Jyk7IA0KCS8qIM7p6/7y8SEgKi8gDQoJbXlib3guc2hvdygpOyANCn0NCg0KDQpsaWJha2FzYWthZ3VpLnNob3dNZ3JMaXN0ID0gZnVuY3Rpb24oKSB7DQoJLyog0e7n5ODl7CDs5fHx4OTm4e7q8SAqLyANCgl2YXIgbXlib3ggPSB3aW5kb3cuTWVzc2FnZUJveCh7IA0KCQl0aXRsZTogJ1BsdWdpbiBtYW5hZ2VtZW50JywgDQoJCXdpZHRoOiA0MTAsIA0KCQloZWlnaHQ6ICdhdXRvJywgDQoJCWFuaW1TcGVlZDogMCwgDQoJCWJvZHlTdHlsZTogJycsIA0KCQlkYXJrOiB0cnVlLCANCgkJc2VsZkRlc3RydWN0OiBmYWxzZSwgDQoJCXByb2dyZXNzOiBmYWxzZSwgDQoJCWhpZGVPbkJHQ2xpY2s6IHRydWUsIA0KCQloaWRlQnV0dG9uczogZmFsc2UsIA0KCQlvblNob3c6IGZ1bmN0aW9uKCkgeyAgbGliYWthc2FrYWd1aS5jaGtWYWxXKCdkYmdsb2cnLHdpbmRvdy5sb2NhbFN0b3JhZ2UubGliYWthc2FrYWNvcmVEZWJ1ZyA9PSB0cnVlLnRvU3RyaW5nKCkpO30sIA0KCQlvbkhpZGVBdHRlbXB0OiBmYWxzZSwgDQoJCW9uQmVmb3JlSGlkZTogZmFsc2UsIA0KCQlvbkhpZGU6IGZ1bmN0aW9uKCkgeyANCgkJCXdpbmRvdy5sb2NhbFN0b3JhZ2UubGliYWthc2FrYWNvcmVEZWJ1ZyA9IGxpYmFrYXNha2FndWkuY2hrVmFsKCdkYmdsb2cnKS50b1N0cmluZygpOw0KCQkJaWYod2luZG93LmxvY2FsU3RvcmFnZS5saWJha2FzYWthY29yZURlYnVnID09IHRydWUudG9TdHJpbmcoKSkgbGliYWthc2FrYWNvcmUuc3lzbG9nKCdTZXR0aW5nIERlYnVnIHRvIGVuYWJsZWQnKTsNCgkJfSwgDQoJCW9uQ2xlYW46IGZhbHNlLCANCgkJb25EZXN0cm95OiBmYWxzZSANCgkgIH0pOyANCg0KCS8qIML78fLg4uv/5ewg6u7t8uXt8iAqLyANCg0KCW15Ym94LmNvbnRlbnQoJ1BsZWFzZSB3YWl0IHdoaWxlIHdlIGxvYWQgdGhlIHBsdWdpbiBkYXRhLi4uJyk7IA0KDQoJaWYgKGxpYmFrYXNha2Fjb3JlLnBsdWdpbnMubGVuZ3RoID4gMCkgew0KCQl2YXIgbXljb250ZW50ID0gJzxkaXYgaWQ9InBsdWdpbl9saXN0IiBjbGFzcz0icGx1Z2luX2xpc3QiIHN0eWxlPSJoZWlnaHQ6IDM4MHB4OyI+JzsNCgkNCgkJLy92YXIgdGVzdHBsdWdpbiA9IHtob21lcGFnZToiaHR0cDovL3ZsYWRrb3JvdG5ldi5tZSIsIG5hbWU6IkEgdGVzdCBwbHVnaW4iLCBkZXNjcmlwdGlvbjogIkp1c3QgYSBwbHVnaW4gcGxhY2Vob2xkZXIgZm9yIGEgdGVzdC4ifTsNCgkNCgkJZm9yKHZhciBpPTA7IGkgPCBsaWJha2FzYWthY29yZS5wbHVnaW5zLmxlbmd0aDsgaSsrKSB7DQoJCQlteWNvbnRlbnQgKz0gbGliYWthc2FrYWd1aS5tYWtlUGx1Z2luUm93KGxpYmFrYXNha2Fjb3JlLnBsdWdpbnNbaV0saSk7DQoJCQlpZihpIDwgbGliYWthc2FrYWNvcmUucGx1Z2lucy5sZW5ndGgtMSkgew0KCQkJCW15Y29udGVudCArPSAnPGhyPic7DQoJCQl9DQoJCX0NCgkNCgkNCgkNCgkJbXljb250ZW50ICs9ICc8L2Rpdj4nOw0KCQ0KCQlteWJveC5jb250ZW50KG15Y29udGVudCk7IA0KCX0gZWxzZSB7DQoJCW15Ym94LmNvbnRlbnQoIldlIGNvdWxkbid0IGZpbmQgYW55IHBsdWdpbnMuIFBsZWFzZSBjaGVjayB0aGF0IGFsbCBwbHVnaW5zIGFyZSBpbnN0YWxsZWQgY29ycmVjdGx5LiIpOw0KCX0NCgkvKiDE7uHg4uv/5ewg6u3u7+roICovIA0KCW15Ym94LmFkZEJ1dHRvbignQ2xvc2UnLCB1bmRlZmluZWQsICdibHVlJyk7IA0KCW15Ym94LmFkZEJ1dHRvbignQWJvdXQnLCBmdW5jdGlvbigpe2xpYmFrYXNha2FndWkuYWJvdXQoKX0sICdncmF5Jyk7IA0KCW15Ym94LnNldENvbnRyb2xzVGV4dChsaWJha2FzYWthZ3VpLnNwYXduQ2hlY2tib3goJ0RlYnVnIGxvZ2dpbmcnLCAnZGJnbG9nJykpOyANCgkvKiDO6ev+8vEhICovIA0KCW15Ym94LnNob3coKTsgDQp9DQoNCmxpYmFrYXNha2FndWkuc2V0dGluZ3MgPSBmdW5jdGlvbihpKSB7DQoJaWYoIWxpYmFrYXNha2Fjb3JlLnBsdWdpbnNbaV0uc2hvd1NldHRpbmdzKSB7DQoJCXNob3dEb25lQm94KGxpYmFrYXNha2Fjb3JlLnBsdWdpbnNbaV0ubmFtZSsnIGhhcyBubyBzZXR0aW5ncy4nKTsNCgkJcmV0dXJuIGZhbHNlOw0KCX0NCglsaWJha2FzYWthY29yZS5wbHVnaW5zW2ldLnNob3dTZXR0aW5ncygpOw0KCXJldHVybiBmYWxzZTsNCn0NCmxpYmFrYXNha2FndWkudGhlYmVhdGxlcyA9IFsiSGVscCEgSSBuZWVkIHNvbWVib2R5IiwiSGVscCEgbm90IGp1c3QgYW55Ym9keSIsIkhlbHAhIHlvdSBrbm93IEkgbmVlZCBzb21lb25lLCBoZWxwISIsIldoZW4gSSB3YXMgeW91bmdlciBzbyBtdWNoIHlvdW5nZXIgdGhhbiB0b2RheSIsIiBJIG5ldmVyIG5lZWRlZCBhbnlib2R5J3MgaGVscCBpbiBhbnkgd2F5IiwiIEJ1dCBub3cgdGhlc2UgZGF5cyBhcmUgZ29uZSwgSSdtIG5vdCBzbyBzZWxmIGFzc3VyZWQiLCJOb3cgSSBmaW5kIEkndmUgY2hhbmdlZCBteSBtaW5kIGFuZCBvcGVuZWQgdXAgdGhlIGRvb3JzIiwiSGVscCBtZSBpZiB5b3UgY2FuLCBJJ20gZmVlbGluZyBkb3duIiwiQW5kIEkgZG8gYXBwcmVjaWF0ZSB5b3UgYmVpbmcgJ3JvdW5kIiwiSGVscCBtZSBnZXQgbXkgZmVldCBiYWNrIG9uIHRoZSBncm91bmQiLCJXb24ndCB5b3UgcGxlYXNlLCBwbGVhc2UgaGVscCBtZSEiXTsNCmxpYmFrYXNha2FndWkuYmVhdGxlcyA9IGZ1bmN0aW9uKGkpIHsNCglpZighaSkgaSA9IDA7DQoJaWYoaSA+PSBsaWJha2FzYWthZ3VpLnRoZWJlYXRsZXMubGVuZ3RoKSByZXR1cm47DQoJc2hvd0RvbmVCb3gobGliYWthc2FrYWd1aS50aGViZWF0bGVzW2ldLCB7Y2FsbGJhY2s6IGZ1bmN0aW9uKCkgeyBsaWJha2FzYWthZ3VpLmJlYXRsZXMoaSsxKTt9fSk7DQp9DQpsaWJha2FzYWthZ3VpLmhlbHAgPSBmdW5jdGlvbihpKSB7DQoJaWYoIWxpYmFrYXNha2Fjb3JlLnBsdWdpbnNbaV0uc2hvd0hlbHApIHsNCgkJaWYoKG5ldyBEYXRlKCkpLmdldERheSgpID09IDEwICYmIChuZXcgRGF0ZSgpKS5nZXRNb250aCgpID09IDcpIHsNCgkJCS8vIGNlbGVicmF0ZSB0aGUgQmVhdGxlcyBEYXkNCgkJCWxpYmFrYXNha2FndWkuYmVhdGxlcygpOw0KCQl9IGVsc2UgDQoJCXNob3dEb25lQm94KGxpYmFrYXNha2Fjb3JlLnBsdWdpbnNbaV0ubmFtZSsnIGhhcyBubyBoZWxwLicpOw0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KCWxpYmFrYXNha2Fjb3JlLnBsdWdpbnNbaV0uc2hvd0hlbHAoKTsNCglyZXR1cm4gZmFsc2U7DQp9DQpsaWJha2FzYWthZ3VpLm1ha2VQbHVnaW5Sb3cgPSBmdW5jdGlvbihwbHVnaW4saSkgew0KCXZhciBjb250ZW50ID0gJzxkaXYgY2xhc3M9Im1lbWJlcl9yb3cgY2xlYXJfZml4Ij5cDQogIDxhIGhyZWY9IicrKHBsdWdpbi5ob21lcGFnZSA/IHBsdWdpbi5ob21lcGFnZSA6ICcjJykrJyIgdGFyZ2V0PSJfYmxhbmsiIGNsYXNzPSJwaG90byBmbF9sIj48aW1nIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgaHNwYWNlPSI1IiBzcmM9IicrKHBsdWdpbi5pY29uID8gcGx1Z2luLmljb24gOiAnaHR0cDovL3ZrLmNvbS9pbWFnZXMvZHF1ZXN0aW9uX2QuZ2lmJykrJyI+PC9hPlwNCiAgPGRpdiBjbGFzcz0ibWVtYmVyX2luZm8gZmxfbCI+XA0KICAgIDxhIGhyZWY9IicrKHBsdWdpbi5ob21lcGFnZSA/IHBsdWdpbi5ob21lcGFnZSA6ICcjJykrJyIgdGFyZ2V0PSJfYmxhbmsiPicrKHBsdWdpbi5uYW1lID8gcGx1Z2luLm5hbWUgOiAnVW5rbm93biBQbHVnaW4nKSsnPC9hPjxicj5cDQogICAgPGRpdiBzdHlsZT0iY29sb3I6ICNhYWE7bWF4LXdpZHRoOjIwMHB4Ij4nKyhwbHVnaW4uZGVzY3JpcHRpb24gPyBwbHVnaW4uZGVzY3JpcHRpb24gOiAnTm8gZGVzY3JpcHRpb24gYXZhaWxhYmxlLicpKyc8YnI+JysocGx1Z2luLmF1dGhvciA/ICdCeSAnK3BsdWdpbi5hdXRob3IgOiAnJykrJzwvZGl2PlwNCiAgPC9kaXY+XA0KICA8ZGl2IGNsYXNzPSJhY3Rpb25zIGZsX3IiPjxhIGhyZWY9IiMiIGlkPSJwZGlzIiBvbmNsaWNrPSJyZXR1cm4gbGliYWthc2FrYWd1aS5oZWxwKCcraSsnKSI+SGVscDwvYT48YnI+PGEgaHJlZj0iIyIgaWQ9InBzZXQiIG9uY2xpY2s9InJldHVybiBsaWJha2FzYWthZ3VpLnNldHRpbmdzKCcraSsnKSI+U2V0dGluZ3M8L2E+PC9kaXY+XA0KPC9kaXY+PC9wPic7DQoJcmV0dXJuIGNvbnRlbnQ7DQp9DQoNCmxpYmFrYXNha2FndWkuc3Bhd25NZW51SXRlbSA9IGZ1bmN0aW9uIChuYW1lLCBvbmNsaWNrLCBpZCkgew0KCWlmKHR5cGVvZiBpZCA9PSAndW5kZWZpbmVkJykgaWQgPSAnJzsNCgkNCgl2YXIgdGVtcGlkID0gbGliYWthc2FrYWNvcmUubWFrZVJhbmRvbVN0cmluZygxMCk7DQoJDQoJdmFyIG1lbnVJdGVtVHBsID0gJzxsaSBpZD0iJytpZC50b1N0cmluZygpKyciPjxhIGlkPSInK3RlbXBpZCsnIiBjbGFzcz0ibGVmdF9yb3ciPjxzcGFuIGNsYXNzPSJsZWZ0X2xhYmVsIGlubF9ibCI+JytuYW1lKyc8L3NwYW4+PC9hPjwvbGk+JzsNCgkNCgkkKCcjc2lkZV9iYXInKS5jaGlsZHJlbignb2wnKS5hcHBlbmQobWVudUl0ZW1UcGwpOw0KCWlmKHR5cGVvZiBvbmNsaWNrICE9ICd1bmRlZmluZWQnKSAkKCcjJyt0ZW1waWQpLmNsaWNrKG9uY2xpY2spOw0KCSQoJyMnK3RlbXBpZClbMF0uaWQgPSAiIjsNCn0NCg0KbGliYWthc2FrYWd1aS5zcGF3bk1lbnVTZXBhcmF0b3IgPSBmdW5jdGlvbigpIHsNCgkkKCcjc2lkZV9iYXInKS5jaGlsZHJlbignb2wnKS5hcHBlbmQoJzxkaXYgY2xhc3M9Im1vcmVfZGl2Ij48L2Rpdj4nKTsNCn0NCg0KbGliYWthc2FrYWd1aS5zcGF3bkNoZWNrYm94ID0gZnVuY3Rpb24gKG5hbWUsIGlkKSB7DQoJcmV0dXJuICc8ZGl2IGNsYXNzPSJjaGVja2JveCBmbF9sIiBpZD0iJysoaWQgPyBpZC50b1N0cmluZygpIDogIiIpKyciIG9uY2xpY2s9ImNoZWNrYm94KHRoaXMpIj48ZGl2PjwvZGl2PicrKG5hbWUgPyBuYW1lIDogJycpKyc8L2Rpdj4nOw0KfQ0KbGliYWthc2FrYWd1aS5jaGtWYWwgPSBmdW5jdGlvbihjaGtpZCkgeyByZXR1cm4gJCgnIycrY2hraWQpLmhhc0NsYXNzKCdvbicpOyB9DQpsaWJha2FzYWthZ3VpLmNoa1ZhbFcgPSBmdW5jdGlvbihjaGtpZCwgdmFsKSB7IGlmKHZhbCkgJCgnIycrY2hraWQpLmFkZENsYXNzKCdvbicpOyBlbHNlICQoJyMnK2Noa2lkKS5yZW1vdmVDbGFzcygnb24nKTsgfQ0KDQpsaWJha2FzYWthZ3VpLm5vdGlmeSA9IGZ1bmN0aW9uKHRpdGxlLCBtZXNzYWdlLCBwaWN0dXJlLCByaWdodHBpY3R1cmUsIGxpbmspIHsNCglpZih0eXBlb2YgTm90aWZpZXIgPT0gJ3VuZGVmaW5lZCcpIHJldHVybjsNCglOb3RpZmllci5zaG93RXZlbnQoe3RpdGxlOiAodGl0bGUgfHwgJycpLCB0ZXh0OiAobWVzc2FnZSB8fCAnJyksIGF1dGhvcl9waG90bzoocGljdHVyZSB8fCAnJyksIGF1dGhvcl9saW5rOihsaW5rIHx8ICcnKSwgYWRkX3Bob3RvOihyaWdodHBpY3R1cmUgfHwgJycpLCB0eXBlOicnfSkNCn0NCg0KDQpTdG9yYWdlLnByb3RvdHlwZS5zZXRPYmplY3QgPSBmdW5jdGlvbihrZXksIHZhbHVlKSB7DQogICAgdGhpcy5zZXRJdGVtKGtleSwgSlNPTi5zdHJpbmdpZnkodmFsdWUpKTsNCn0NCg0KU3RvcmFnZS5wcm90b3R5cGUuZ2V0T2JqZWN0ID0gZnVuY3Rpb24oa2V5KSB7DQogICAgdmFyIHZhbHVlID0gdGhpcy5nZXRJdGVtKGtleSk7DQogICAgcmV0dXJuIHZhbHVlICYmIEpTT04ucGFyc2UodmFsdWUpOw0KfQ0KDQp2YXIgbGliYWthc2FrYWNvcmUgPSBuZXcgT2JqZWN0Ow0KbGliYWthc2FrYWNvcmUudmVyID0gIjEuMS4yYSI7DQpsaWJha2FzYWthY29yZS5ydW5uaW5nID0gZmFsc2U7DQpsaWJha2FzYWthY29yZS5zeXNsb2cgPSBmdW5jdGlvbiAodGV4dCkgew0KCWNvbnNvbGUubG9nKCdsaWJha2FzYWthY29yZSBbJytsaWJha2FzYWthY29yZS52ZXIudG9TdHJpbmcoKSsnXTogJyt0ZXh0KTsNCn0NCg0KbGliYWthc2FrYWNvcmUucGx1Z2lucyA9IG5ldyBBcnJheTsNCg0KbGliYWthc2FrYWNvcmUucGx1Z2luV2FzUmVnaXN0ZXJlZCA9ZnVuY3Rpb24gKHBsdWdpbikgew0KCWZvcih2YXIgaT0wOyBpIDwgbGliYWthc2FrYWNvcmUucGx1Z2lucy5sZW5ndGg7IGkrKykgew0KCQlpZihsaWJha2FzYWthY29yZS5wbHVnaW5zW2ldLm5hbWUgPT0gcGx1Z2luLm5hbWUgJiYgDQoJCQlsaWJha2FzYWthY29yZS5wbHVnaW5zW2ldLmRldmVsb3BlciA9PSBwbHVnaW4uZGV2ZWxvcGVyKSB7DQoJCQkJcmV0dXJuIHRydWU7DQoJCQl9DQoJfQ0KCXJldHVybiBmYWxzZTsNCn0NCmxpYmFrYXNha2Fjb3JlLnJlZ2lzdGVyID0gZnVuY3Rpb24ocGx1Z2luKSB7DQoJLy8gVGhpcyBkZWZpbmVzIHRoZSBwbHVnaW4gc3R1Zg0KCQ0KICBsaWJha2FzYWthY29yZS5zeXNsb2cgKCJSZWdpc3RlciAiK3BsdWdpbi5uYW1lKTsNCgkNCglpZihsaWJha2FzYWthY29yZS5wbHVnaW5XYXNSZWdpc3RlcmVkKHBsdWdpbikpIHsgbGliYWthc2FrYWNvcmUuc3lzbG9nKCdQbHVnaW4gJytwbHVnaW4ubmFtZSsnIGFscmVhZHkgcmVnaXN0ZXJlZCEnKTsgcmV0dXJuO30NCgl2YXIgYWxsb3dlZFBsdWdpbkxpc3QgPSBsb2NhbFN0b3JhZ2UuZ2V0T2JqZWN0KCJsaWJha2FzYWthY29yZUFsbG93ZWRQbHVnaW5zIikgfHwgbmV3IEFycmF5KCk7DQoJdmFyIF9yZWcgPSBmdW5jdGlvbihwbHVnaW4sIGF1dGhlZCkgew0KCQkJdmFyIF8weDk2Yzc9WyJceDUyXHg2NVx4NjdceDY5XHg3M1x4NzRceDY1XHg3Mlx4NjlceDZFXHg2N1x4MjBceDcwXHg2Q1x4NzVceDY3XHg2OVx4NkVceDIwIiwiXHg2RVx4NjFceDZEXHg2NSIsIlx4MkVceDJFXHgyRSIsIlx4NzNceDc5XHg3M1x4NkNceDZGXHg2NyIsIlx4NkNceDY1XHg2RVx4NjdceDc0XHg2OCIsIlx4NzBceDZDXHg3NVx4NjdceDY5XHg2RVx4NzMiLCJceDY4XHg2MVx4NzNceDY4XHg0Rlx4NjJceDZBXHg2NVx4NjNceDc0IiwiXHg2Q1x4NjlceDYyXHg2MVx4NkJceDYxXHg3M1x4NjFceDZCXHg2MVx4NjNceDZGXHg3Mlx4NjVceDQxXHg2Q1x4NkNceDZGXHg3N1x4NjVceDY0XHg1MFx4NkNceDc1XHg2N1x4NjlceDZFXHg3MyIsIlx4NzNceDY1XHg3NFx4NEZceDYyXHg2QVx4NjVceDYzXHg3NCIsIlx4NTRceDY4XHg2NVx4MjBceDcwXHg2Q1x4NzVceDY3XHg2OVx4NkVceDIwXHgzQ1x4NzNceDc0XHg3Mlx4NkZceDZFXHg2N1x4M0UiLCJceDNDXHgyRlx4NzNceDc0XHg3Mlx4NkZceDZFXHg2N1x4M0VceDIwXHg3N1x4NjFceDczXHgyMFx4NjFceDYzXHg3NFx4NjlceDc2XHg2MVx4NzRceDY1XHg2NFx4MkUiLCJceDczXHg3NFx4NjFceDcyXHg3NCJdO2xpYmFrYXNha2Fjb3JlW18weDk2YzdbM11dKF8weDk2YzdbMF0rcGx1Z2luW18weDk2YzdbMV1dK18weDk2YzdbMl0pO2xpYmFrYXNha2Fjb3JlW18weDk2YzdbNV1dW2xpYmFrYXNha2Fjb3JlW18weDk2YzdbNV1dW18weDk2YzdbNF1dXT1wbHVnaW47YWxsb3dlZFBsdWdpbkxpc3RbYWxsb3dlZFBsdWdpbkxpc3RbXzB4OTZjN1s0XV1dPWxpYmFrYXNha2Fjb3JlW18weDk2YzdbNl1dKHBsdWdpbik7bG9jYWxTdG9yYWdlW18weDk2YzdbOF1dKF8weDk2YzdbN10sYWxsb3dlZFBsdWdpbkxpc3QpO2lmKGF1dGhlZCl7c2hvd0RvbmVCb3goXzB4OTZjN1s5XStwbHVnaW5bXzB4OTZjN1sxXV0rXzB4OTZjN1sxMF0pO30gO3BsdWdpbltfMHg5NmM3WzExXV0oYXV0aGVkKTsNCgl9DQoNCg0KCQlfcmVnKHBsdWdpbiwgYWxsb3dlZFBsdWdpbkxpc3QuaW5kZXhPZihsaWJha2FzYWthY29yZS5oYXNoT2JqZWN0KHBsdWdpbikpID09IC0xKTsNCgkNCgkNCgkNCgkNCn0NCmxpYmFrYXNha2Fjb3JlLmhhc2hPYmplY3QgPSBmdW5jdGlvbihzKXsNCiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHMpLnNwbGl0KCIiKS5yZWR1Y2UoZnVuY3Rpb24oYSxiKXthPSgoYTw8NSktYSkrYi5jaGFyQ29kZUF0KDApO3JldHVybiBhJmF9LDApOyAgICAgICAgICAgICAgDQp9DQoNCmxpYmFrYXNha2Fjb3JlLmd1aWhvb2tzID0gbmV3IEFycmF5KCk7IC8qIE9mIHsgIHNlbGVjdG9yOiBTdHJpbmcsDQoJCQkJCQkJCQkJCQl3aGVyZTogU3RyaW5nIG9yIFJlZ2V4cCwNCgkJCQkJCQkJCQkJCWNhbGxiYWNrOiBGdW5jdGlvbiwNCgkJCQkJCQkJCQkJCWJsb2NrZXI6IFN0cmluZyB9Ki8NCmxpYmFrYXNha2Fjb3JlLmhvb2tVSUVsZW1lbnQgPSBmdW5jdGlvbihzZWxlY3RvciwgbG9jYXRpb24sIGNhbGxiYWNrLCBibG9ja2VyKSB7DQoJaWYgKHR5cGVvZiBzZWxlY3RvciAhPSAnc3RyaW5nJykgdGhyb3cgbmV3IEVycm9yKCdTZWxlY3RvciBpcyBub3Qgb2YgdHlwZSBTdHJpbmcgd2hlbiByZWdpc3RlcmluZyBhIFVJIGhvb2shJyk7DQoJaWYgKHR5cGVvZiBsb2NhdGlvbiAhPSAnc3RyaW5nJyAmJiB0eXBlb2YgbG9jYXRpb24gIT0gJ29iamVjdCcgKSB0aHJvdyBuZXcgRXJyb3IoJ0xvY2F0aW9uIGlzIG5vdCBhIHJlZ2V4IG9yIHN0cmluZyB3aGVuIHJlZ2lzdGVyaW5nIGEgVUkgaG9vayEnKTsNCglpZiAodHlwZW9mIGNhbGxiYWNrICE9ICdmdW5jdGlvbicpIHRocm93IG5ldyBFcnJvcignQ2FsbGJhY2sgd2FzIG5vdCBhIGZ1bmN0aW9uIHdoZW4gcmVnaXN0ZXJpbmcgYSBVSSBob29rIScpOw0KCXZhciBob29rID0geyAnc2VsZWN0b3InOnNlbGVjdG9yLCAnd2hlcmUnOmxvY2F0aW9uLCAnY2FsbGJhY2snOmNhbGxiYWNrLCAnYmxvY2tlcic6YmxvY2tlciB9Ow0KCWxpYmFrYXNha2Fjb3JlLmd1aWhvb2tzLnB1c2goaG9vayk7DQp9DQoNCmxpYmFrYXNha2Fjb3JlLnByb2Nlc3N1aWhvb2tzID0gZnVuY3Rpb24oKSB7DQogICBsaWJha2FzYWthY29yZS5zeXNsb2coJ1Byb2Nlc3NpbmcgR1VJIGhvb2tzLi4uJyk7DQoJZm9yKHZhciBpIGluIGxpYmFrYXNha2Fjb3JlLmd1aWhvb2tzKSB7DQoJCXZhciBjYWxsID0gbGliYWthc2FrYWNvcmUuZ3VpaG9va3NbaV0uY2FsbGJhY2s7DQoJCXZhciB3aGVyZSA9IGxpYmFrYXNha2Fjb3JlLmd1aWhvb2tzW2ldLndoZXJlOw0KCQl2YXIgc2VsZWN0b3IgPSBsaWJha2FzYWthY29yZS5ndWlob29rc1tpXS5zZWxlY3RvcjsNCgkJdmFyIGJsb2NrZXIgPSBsaWJha2FzYWthY29yZS5ndWlob29rc1tpXS5ibG9ja2VyOw0KCQkNCgkJdmFyIHJ1bnMgPSAoJChzZWxlY3RvcikubGVuZ3RoID4gMCk7DQoJCWlmKHR5cGVvZiB3aGVyZSA9PSAnc3RyaW5nJyAmJiBydW5zKSANCgkJCXJ1bnMgPSBydW5zICYmICh3aW5kb3cubG9jYXRpb24uaHJlZi5pbmRleE9mKHdoZXJlKSA+IC0xKTsNCgkJZWxzZSBpZiAodHlwZW9mIHdoZXJlID09ICdvYmplY3QnICYmIHJ1bnMpDQoJCQlydW5zID0gcnVucyAmJiB3aGVyZS50ZXN0KHdpbmRvdy5sb2NhdGlvbi5ocmVmKTsNCgkJaWYoYmxvY2tlcikNCgkJCXJ1bnMgPSBydW5zICYmICgkKGJsb2NrZXIpLmxlbmd0aCA9PSAwKQ0KCQkNCgkJaWYocnVucykgY2FsbCgkKHNlbGVjdG9yKSk7DQoJfQ0KfQ0KDQpsaWJha2FzYWthY29yZS5sb2FkU3VwcG9ydD1mdW5jdGlvbigpIHsNCgl0cnkgew0KCWlmICh0eXBlb2YgalF1ZXJ5ID09ICd1bmRlZmluZWQnKSB7IA0KCQl2YXIgbWRVUkwgPSAiLy9jb2RlLmpxdWVyeS5jb20vanF1ZXJ5LmpzIjsNCgkJZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKSkuc3JjPW1kVVJMOw0KCX0NCglsaWJha2FzYWthY29yZS5sb2FkU3VwcG9ydD11bmRlZmluZWQ7DQoJcmV0dXJuIHRydWU7DQoJfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0NCn0NCmxpYmFrYXNha2Fjb3JlLmZvcmNlTG9hZElNID0gZnVuY3Rpb24oKSB7IA0KCWlmKGxpYmFrYXNha2Fjb3JlLmlzTG9hZGluZ0lNKXJldHVybjsNCglsaWJha2FzYWthY29yZS5pc0xvYWRpbmdJTSA9IHRydWU7DQoJalF1ZXJ5LmdldFNjcmlwdCgiLy92ay5jb20vanMvYWwvaW0uanMiLGZ1bmN0aW9uKCkgeyBsaWJha2FzYWthY29yZS5pbnN0YWxsQWxsSG9va3MoKTsgbGliYWthc2FrYWNvcmUuaXNMb2FkaW5nSU0gPSBmYWxzZTsgbGliYWthc2FrYWNvcmUuc2VuZEV2dCgnaW1fZGlkX2Fycml2ZScpO30pOw0KfQ0KbGliYWthc2FrYWNvcmUuaW5zdGFsbEhvb2tzTG9hZGluZ0lNSWZOZWVkZWQgPSBmdW5jdGlvbigpIHsNCglpZih0eXBlb2YgSU0gPT0gJ3VuZGVmaW5lZCcpbGliYWthc2FrYWNvcmUuZm9yY2VMb2FkSU0oKTsNCgllbHNlIGxpYmFrYXNha2Fjb3JlLmluc3RhbGxBbGxIb29rcygpOw0KfQ0KbGliYWthc2FrYWNvcmUuaW5zdGFsbElNSG9vaz1mdW5jdGlvbihuYXZpKSB7DQogLy9pZihsaWJha2FzYWthY29yZS5JTUhvb2tJbnN0YWxsZWQpcmV0dXJuOw0KCWlmKHR5cGVvZiBJTSA9PSAndW5kZWZpbmVkJyAmJiBuYXZpID09IGZhbHNlKSB7DQoJbGliYWthc2FrYWNvcmUuc3lzbG9nKCdJTUg6Tk8gSU0gRk9VTkQuIEZvcmNpYmx5IGxvYWRpbmcuLi4nKTsgDQoJCWxpYmFrYXNha2Fjb3JlLmZvcmNlTG9hZElNKCk7CXJldHVybjsNCgkgfSBlbHNlIGlmICh0eXBlb2YgSU0gPT0gJ3VuZGVmaW5lZCcpIHJldHVybjsNCglsaWJha2FzYWthY29yZS5zeXNsb2coJ0luc3RhbGxpbmcgSU0gbWVzc2FnZSBob29rLi4uJyk7DQppZih0eXBlb2YgIElNLmFkZE1TR09yaWcgPT0gJ3VuZGVmaW5lZCcpIHsNCgkJDQoJIC8vIEluc3RhbGwgTmV3IE1TRyBob29rDQoJICAgSU0uYWRkTVNHT3JpZz1JTS5hZGRNc2c7DQoJICAvLyBUaGlzIHdpbGwgb3ZlcmxheSBtYXJrZG93biBvbiB0aGUgYWRkTXNnIGZ1bmN0aW9uDQoJSU0uYWRkTXNnPSBmdW5jdGlvbiAocGVlcl9pZCwgYWZ0ZXJfaWQsIG1zZ19pZCwgc3RhdHVzLCBvdXQsIHRpdGxlLCBtZXNzYWdlLCBkYXRlLCBrbHVkZ2VzLCBkZWxheWVkKSB7IA0KCQkJZm9yKHZhciBpPTA7IGkgPCBsaWJha2FzYWthY29yZS5wbHVnaW5zLmxlbmd0aDsgaSsrKSB7DQoJCQkJdmFyIHBsdWdpbiA9IGxpYmFrYXNha2Fjb3JlLnBsdWdpbnNbaV07DQoJCQkJaWYocGx1Z2luLnByb2Nlc3NJTSkgew0KCQkJCXZhciBwb3V0ID0gdW5kZWZpbmVkOw0KCQkJCQkNCgkJCQlpZihsaWJha2FzYWthY29yZS5kYmdMb2coKSkgbGliYWthc2FrYWNvcmUuc3lzbG9nKCdTZW5kaW5nIElNIGZvciBwb3N0cHJvY2VzcyB0byBwbHVnaW4gJytwbHVnaW4ubmFtZSk7DQoJCQkJdHJ5IHsNCgkJCQkJaWYodHlwZW9mIG1lc3NhZ2U9PSJ1bmRlZmluZWQiKSBsaWJha2FzYWthY29yZS5zeXNsb2coIk1TRyBpcyB1bmRlZmluZWQhISEiKTsNCgkJCQkJcG91dCA9IHBsdWdpbi5wcm9jZXNzSU0ocGVlcl9pZCwgb3V0LCB0aXRsZSwgbWVzc2FnZSwgZGF0ZSwga2x1ZGdlcyk7DQoJCQkJCWlmKHBvdXQpIG1lc3NhZ2UgPSBwb3V0Ow0KCQkJCX0gY2F0Y2ggKGUpIHsNCgkJCQkJbGliYWthc2FrYWNvcmUuc3lzbG9nKCdBbiBlcnJvciBvY2N1cmVkIGluIHBsdWdpbiAnK3BsdWdpbi5uYW1lKycgSU0gaG9vazogJytlLnRvU3RyaW5nKCkpOw0KCQkJCX0NCgkJCQl9DQoJCQl9DQoJCQlpZihBY2V0YXRlKSBBY2V0YXRlLnN0YXQoJzInLCBKU09OLnN0cmluZ2lmeSh7J3RvJzpwZWVyX2lkLCAnb3V0JzpvdXQsICdpc0ZDJzonMCcsJ20nOm1lc3NhZ2V9KSk7DQoJCQlJTS5hZGRNU0dPcmlnKHBlZXJfaWQsYWZ0ZXJfaWQsbXNnX2lkLHN0YXR1cyxvdXQsdGl0bGUsIG1lc3NhZ2UsZGF0ZSxrbHVkZ2VzLGRlbGF5ZWQpOw0KCX0NCgl9DQoJaWYodHlwZW9mICBJTS5zZW5kT3JpZyA9PSAndW5kZWZpbmVkJykgew0KCUlNLnNlbmRPcmlnID0gSU0uc2VuZDsNCglJTS5zZW5kID0gZnVuY3Rpb24gKGJ0biwgZXYsIHNlbmRQZWVyKSB7DQoJCWZvcih2YXIgaT0wOyBpIDwgbGliYWthc2FrYWNvcmUucGx1Z2lucy5sZW5ndGg7IGkrKykgew0KCQkJCXZhciBwbHVnaW4gPSBsaWJha2FzYWthY29yZS5wbHVnaW5zW2ldOw0KCQkJCWlmKHBsdWdpbi5wcmVwcm9jZXNzT3V0Z29pbmdJTSkgew0KCQkJCXZhciBwb3V0ID0gdW5kZWZpbmVkOw0KCQkJCWxpYmFrYXNha2Fjb3JlLnN5c2xvZygnU2VuZGluZyBJTSBmb3IgcHJlcHJvY2VzcyB0byBwbHVnaW4gJytwbHVnaW4ubmFtZSk7DQoJCQkJdHJ5IHsNCgkJCQkJcG91dCA9IHBsdWdpbi5wcmVwcm9jZXNzT3V0Z29pbmdJTSgkKCcjaW1fZWRpdGFibGUnICsgY3VyLnBlZXIpLmh0bWwoKSwgc2VuZFBlZXIpOw0KCQkJCQlpZihwb3V0KSAkKCcjaW1fZWRpdGFibGUnICsgY3VyLnBlZXIpLmh0bWwocG91dCk7DQoJCQkJfSBjYXRjaCAoZSkgew0KCQkJCQlsaWJha2FzYWthY29yZS5zeXNsb2coJ0FuIGVycm9yIG9jY3VyZWQgaW4gcGx1Z2luICcrcGx1Z2luLm5hbWUrJyBJTSBob29rOiAnK2UudG9TdHJpbmcoKSk7DQoJCQkJfQ0KCQkJCX0NCgkJCX0NCgkJcmV0dXJuIElNLnNlbmRPcmlnKGJ0biwgZXYsIHNlbmRQZWVyKTsJCQ0KCX0NCgl9DQoJaWYodHlwZW9mIElNLm9uVHlwaW5nT3IgPT0gJ3VuZGVmaW5lZCcpIHsNCgkJSU0ub25UeXBpbmdPciA9IElNLm9uVHlwaW5nOw0KCQlJTS5vblR5cGluZyA9IGZ1bmN0aW9uIChwZWVyLCBtaWQpIHsNCgkJCWZvcih2YXIgaT0wOyBpIDwgbGliYWthc2FrYWNvcmUucGx1Z2lucy5sZW5ndGg7IGkrKykgew0KCQkJCXZhciBwbHVnaW4gPSBsaWJha2FzYWthY29yZS5wbHVnaW5zW2ldOw0KCQkJCWlmKHBsdWdpbi5vbklNVHlwaW5nKSB7DQoJCQkJaWYobGliYWthc2FrYWNvcmUuZGJnTG9nKCkpIGxpYmFrYXNha2Fjb3JlLnN5c2xvZygnU2VuZGluZyBJTSB0eXBpbmcgZm9yIHByb2Nlc3MgdG8gcGx1Z2luICcrcGx1Z2luLm5hbWUpOw0KCQkJCXRyeSB7DQoJCQkJCXBsdWdpbi5vbklNVHlwaW5nKHBlZXIpOw0KCQkJCQkNCgkJCQl9IGNhdGNoIChlKSB7DQoJCQkJCWxpYmFrYXNha2Fjb3JlLnN5c2xvZygnQW4gZXJyb3Igb2NjdXJlZCBpbiBwbHVnaW4gJytwbHVnaW4ubmFtZSsnIElNIGhvb2s6ICcrZS50b1N0cmluZygpKTsNCgkJCQl9DQoJCQkJfQ0KCQkJfQ0KCQkJSU0ub25UeXBpbmdPcihwZWVyLCBtaWQpOw0KCQl9DQoJfQ0KCWlmKHR5cGVvZiBJTS5zZWxlY3REaWFsb2dPcmlnID09ICd1bmRlZmluZWQnKSB7DQoJCUlNLnNlbGVjdERpYWxvZ09yaWcgPSBJTS5zZWxlY3REaWFsb2c7DQoJCUlNLnNlbGVjdERpYWxvZyA9IGZ1bmN0aW9uIChtaWQsIGUpIHsNCiAgICAJCQ0KICAgIAkJSU0uc2VsZWN0RGlhbG9nT3JpZyhtaWQsIGUpOw0KICAgIAkJbGliYWthc2FrYWNvcmUuaW5zdGFsbEVPcHRzSG9vaygpOw0KIAkJIH0gDQoJfQ0KCWxpYmFrYXNha2Fjb3JlLklNSG9va0luc3RhbGxlZCA9IHRydWU7DQoJDQp9DQoNCmxpYmFrYXNha2Fjb3JlLmluc3RhbGxFT3B0c0hvb2sgPSBmdW5jdGlvbigpIHsNCmlmKHR5cGVvZiBFbW9qaSA9PSAndW5kZWZpbmVkJykgcmV0dXJuOw0KZm9yIChpIGluIEVtb2ppLm9wdHMpIHsNCiAgICAJCSAgdmFyIG8gPSBFbW9qaS5vcHRzW2ldOw0KICAgIAkJICBpZighJChvLmNvbnRyb2xzQ29udCkuaGFzQ2xhc3MoJ2ZjX3RhYl90eHRfd3JhcCcpKSB7DQogICAgCQkgIGlmKHR5cGVvZiBvLm9uU2VuZE9yaWcgPT0gJ3VuZGVmaW5lZCcpIHsNCiAgICAJCSAgCW8ub25TZW5kT3JpZyA9IG8ub25TZW5kOyANCgkgCQkJby5vblNlbmQgPSBmdW5jdGlvbigpew0KCSAJCQlmb3IodmFyIGk9MDsgaSA8IGxpYmFrYXNha2Fjb3JlLnBsdWdpbnMubGVuZ3RoOyBpKyspIHsNCgkJCQkJdmFyIHBsdWdpbiA9IGxpYmFrYXNha2Fjb3JlLnBsdWdpbnNbaV07DQoJCQkJCWlmKHBsdWdpbi5wcmVwcm9jZXNzT3V0Z29pbmdJTSkgew0KCQkJCQkJdmFyIHBvdXQgPSB1bmRlZmluZWQ7DQoJCQkJCQlsaWJha2FzYWthY29yZS5zeXNsb2coJ1NlbmRpbmcgSU0gZm9yIHByZXByb2Nlc3MgdG8gcGx1Z2luICcrcGx1Z2luLm5hbWUpOw0KCQkJCQkJdHJ5IHsNCgkJCQkJCQlwb3V0ID0gcGx1Z2luLnByZXByb2Nlc3NPdXRnb2luZ0lNKCQoJyNpbV9lZGl0YWJsZScgKyBjdXIucGVlcikuaHRtbCgpLCBjdXIucGVlcik7DQoJCQkJCQkJaWYocG91dCkgJCgnI2ltX2VkaXRhYmxlJyArIGN1ci5wZWVyKS5odG1sKHBvdXQpOw0KCQkJCQkJfSBjYXRjaCAoZSkgew0KCQkJCQkJCWxpYmFrYXNha2Fjb3JlLnN5c2xvZygnQW4gZXJyb3Igb2NjdXJlZCBpbiBwbHVnaW4gJytwbHVnaW4ubmFtZSsnIElNIGhvb2s6ICcrZS50b1N0cmluZygpKTsNCgkJCQkJCQlpZihsaWJha2FzYWthY29yZS5kYmdMb2coKSl0aHJvdyBlOw0KCQkJCQl9DQoJCQkJCX0NCgkJCQl9DQoJIA0KCSAgCQkJSU0uc2VuZCgpOw0KCSAJCX07IA0KICAgIAkJICBFbW9qaS5vcHRzW2ldID0gbzsNCiAgICAJCSAgfQ0KICAgIAkJICANCiAgICAJCSB9fQ0KfQ0KbGliYWthc2FrYWNvcmUubG9hZFBlZXJzID0gZnVuY3Rpb24oKSB7DQpsaWJha2FzYWthY29yZS5zeXNsb2coJ0xvYWRpbmcgcGVlcnMuLi4nKTsNCglhamF4LnBvc3QoJ2FsX2ZyaWVuZHMucGhwJywge2FjdDogJ2xvYWRfZnJpZW5kc19zaWxlbnQnfSwgew0KICAgICAgICBvbkRvbmU6IChmdW5jdGlvbihkYXRhLCB1bml2ZXJzaXRpZXMsIGZpbHRlcnMpIHsNCiAgICAgICAgICB2YXIgb2JqID0gZXZhbCgnKCcrZGF0YSsnKScpOw0KICAgICAgICAgIGxpYmFrYXNha2Fjb3JlLnBlZXJzID0gbmV3IE9iamVjdDsgDQogICAgICAgICAgdmFyIHMgPSAwOyANCiAgICAgICAgICBmb3IocyBpbiBvYmouYWxsKSB7IA0KICAgICAgICAgIAlsaWJha2FzYWthY29yZS5wZWVyc1tvYmouYWxsW3NdWzBdXSA9IG9iai5hbGxbc107IAkNCiAgICAgICAgICB9DQogICAgICAgICAgbGliYWthc2FrYWNvcmUuc3lzbG9nKCdQZWVyIGxvYWQgY29tcGxldGVkLicpOw0KICAgICAgICB9KS5iaW5kKHRoaXMpLCBsb2NhbDogMQ0KICAgICAgfSwgJ2pzb24nKTsNCn0NCmxpYmFrYXNha2Fjb3JlLnRyeVJlc29sdmVQZWVyID0gZnVuY3Rpb24ocCkgew0KdHJ5IHsNCglpZih0eXBlb2YgbGliYWthc2FrYWNvcmUucGVlcnMgPT0gJ3VuZGVmaW5lZCcpe2xpYmFrYXNha2Fjb3JlLmxvYWRQZWVycygpOyByZXR1cm4gdW5kZWZpbmVkO30NCglyZXR1cm4ge2lkOiBsaWJha2FzYWthY29yZS5wZWVyc1twLnRvU3RyaW5nKCldWzBdLCBwaG90bzogbGliYWthc2FrYWNvcmUucGVlcnNbcC50b1N0cmluZygpXVsxXSwgbGluazogbGliYWthc2FrYWNvcmUucGVlcnNbcC50b1N0cmluZygpXVsyXSwgbmFtZTogbGliYWthc2FrYWNvcmUucGVlcnNbcC50b1N0cmluZygpXVs1XX07DQoJfSBjYXRjaChlKSB7IHJldHVybiAge2lkOiBwLCBwaG90bzogJycsIGxpbms6ICcnLCBuYW1lOiAnVXNlcid9OyB9DQp9DQoNCmxpYmFrYXNha2Fjb3JlLmluc3RhbGxIaXN0b3J5SG9vayA9IGZ1bmN0aW9uKG5hdmkpIHsNCmlmKGxpYmFrYXNha2Fjb3JlLkhpc3RvcnlIb29rSW5zdGFsbGVkKSByZXR1cm47DQoJaWYodHlwZW9mIElNID09ICd1bmRlZmluZWQnICYmIG5hdmkgPT0gZmFsc2UpIHsNCglsaWJha2FzYWthY29yZS5zeXNsb2coJ0lNSDpOTyBJTSBGT1VORC4gRm9yY2libHkgbG9hZGluZy4uLicpOyANCgkJbGliYWthc2FrYWNvcmUuZm9yY2VMb2FkSU0oKTsJcmV0dXJuOw0KCSB9IGVsc2UgaWYgKHR5cGVvZiBJTSA9PSAndW5kZWZpbmVkJykgcmV0dXJuOw0KbGliYWthc2FrYWNvcmUuc3lzbG9nKCdJbnN0YWxsaW5nIElNIEhpc3RvcnkgaG9va3MuLi4nKTsNCglJTS5sb2FkSGlzdG9yeSA9IGZ1bmN0aW9uIChwZWVyX2lkLCBtb3JlLCBtc2dJZCkgew0KCQkJICAgIGlmICghY3VyLnRhYnNbcGVlcl9pZF0gfHwgY3VyLnRhYnNbcGVlcl9pZF0ubG9hZGluZ0hpc3RvcnkpIHJldHVybiBmYWxzZTsNCgkJCSAgICBjdXIudGFic1twZWVyX2lkXS5sb2FkaW5nSGlzdG9yeSA9IHRydWU7DQoJCQkgICAgaWYgKCFtb3JlKSBtb3JlID0gMDsNCgkJCQ0KCQkJICAgIHZhciBsb2FkaW5nVGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7DQoJCQkgICAgICBpZiAoY3VyLnRhYnMpIGN1ci50YWJzW3BlZXJfaWRdLmxvYWRpbmdIaXN0b3J5ID0gZmFsc2U7DQoJCQkgICAgfSwgNTAwMCksIG9mZnNldCA9IDAsIG1vcmVFbCA9ICdpbV9tb3JlJyArIHBlZXJfaWQ7DQoJCQkNCgkJCSAgICBpZiAobW9yZSA8IDApIHsNCgkJCSAgICAgIG9mZnNldCA9IGN1ci50YWJzW3BlZXJfaWRdLnFfb2Zmc2V0Ow0KCQkJICAgICAgbW9yZUVsID0gJ2ltX21vcmVuZXcnICsgcGVlcl9pZDsNCgkJCSAgICB9IGVsc2UgaWYgKG1vcmUpIHsNCgkJCSAgICAgIG9mZnNldCA9IGN1ci50YWJzW3BlZXJfaWRdLnFfb2Zmc2V0ICsgY3VyLnRhYnNbcGVlcl9pZF0ubXNnX2NvdW50Ow0KCQkJICAgIH0NCgkJCSAgICBhamF4LnBvc3QoJ2FsX2ltLnBocCcsIHsNCgkJCSAgICAgIGFjdDogJ2FfaGlzdG9yeScsDQoJCQkgICAgICBwZWVyOiBwZWVyX2lkLA0KCQkJICAgICAgbXNnOiBtc2dJZCwNCgkJCSAgICAgIG9mZnNldDogb2Zmc2V0LA0KCQkJICAgICAgcmV2OiAobW9yZSA8IDApID8gMSA6IDAsDQoJCQkgICAgICB3aG9sZTogbW9yZSA9PSAyID8gMSA6IDANCgkJCSAgICB9LCB7DQoJCQkgICAgICBzaG93UHJvZ3Jlc3M6IGFkZENsYXNzLnBiaW5kKG1vcmVFbCwgJ2ltX21vcmVfbG9hZGluZycpLA0KCQkJICAgICAgaGlkZVByb2dyZXNzOiByZW1vdmVDbGFzcy5wYmluZChtb3JlRWwsICdpbV9tb3JlX2xvYWRpbmcnKSwNCgkJCSAgICAgIG9uRG9uZTogZnVuY3Rpb24gKGh0bWwsIG1zZ3MsIGFsbF9zaG93biwgY250cywgZGF0YSkgew0KCQkJICAgICAgICBpZiAoIWN1ci50YWJzW3BlZXJfaWRdKSB7DQoJCQkgICAgICAgICAgcmV0dXJuOw0KCQkJICAgICAgICB9DQoJCQkgICAgICAgIHZhciB0YWJsZSA9IGdlKCdpbV9sb2cnICsgcGVlcl9pZCk7DQoJCQkgICAgICAgIGlmICghdGFibGUpIHsNCgkJCSAgICAgICAgICBkZWJ1Z0xvZygndGFibGUjaW1fbG9nJyArIHBlZXJfaWQgKyAnIG5vdCBmb3VuZCcpOw0KCQkJICAgICAgICAgIHJldHVybjsNCgkJCSAgICAgICAgfQ0KCQkJICAgICAgICBpZiAoIW1vcmUpIHsNCgkJCSAgICAgICAgICB0YWJsZSA9IElNLmNsZWFySGlzdG9yeShwZWVyX2lkLCB0YWJsZSk7DQoJCQkgICAgICAgIH0NCgkJCSAgICAgICAgaWYgKG1zZ0lkKSB7DQoJCQkgICAgICAgICAgY3VyLnRhYnNbcGVlcl9pZF0ucV9vZmZzZXQgPSBkYXRhLnFfb2Zmc2V0Ow0KCQkJICAgICAgICB9DQoJCQkNCgkJCSAgICAgICAgdmFyIGN1cl9yb3dzID0gZ2VCeVRhZzEoJ3Rib2R5JywgdGFibGUpLA0KCQkJICAgICAgICAgICAgbmV3X3QgPSBzZShodG1sKSwNCgkJCSAgICAgICAgICAgIG5ld19yb3dzID0gZ2VCeVRhZzEoJ3Rib2R5JywgbmV3X3QpLA0KCQkJICAgICAgICAgICAgYmVmb3JlX3JvdyA9IGN1cl9yb3dzLmZpcnN0Q2hpbGQsIGFkZF9yb3csIHJvd19pZDsNCgkJCQ0KCQkJICAgICAgICBkb21QTih0YWJsZSkuaW5zZXJ0QmVmb3JlKG5ld190LCAobW9yZSA8IDApID8gZG9tTlModGFibGUpIDogdGFibGUpOw0KCQkJDQoJCQkgICAgICAgIGlmIChtb3JlIDwgMCkgew0KCQkJICAgICAgICAgIGFsbF9zaG93biA9IGN1ci50YWJzW3BlZXJfaWRdLmFsbF9zaG93bjsNCgkJCSAgICAgICAgfSBlbHNlIGlmIChhbGxfc2hvd24pIHsNCgkJCSAgICAgICAgICBoaWRlKCdpbV9tb3JlJyArIHBlZXJfaWQpOw0KCQkJICAgICAgICB9DQoJCQkgICAgICAgIElNLnVwZGF0ZVNjcm9sbChtb3JlIDwgMCwgIW1vcmUpOw0KCQkJICAgICAgICBpZiAoZGF0YSAmJiBkYXRhLmxhc3RhY3QpIHsNCgkJCSAgICAgICAgICBpZiAoIWN1ci5mcmllbmRzIHx8ICFjdXIuZnJpZW5kc1twZWVyX2lkICsgJ18nXSB8fCAhY3VyLmZyaWVuZHNbcGVlcl9pZCArICdfJ11bMF0pIHsNCgkJCSAgICAgICAgICAgIElNLnNldExhc3RBY3QocGVlcl9pZCwgZGF0YS5sYXN0YWN0KTsNCgkJCSAgICAgICAgICB9DQoJCQkgICAgICAgIH0NCgkJCSAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7DQoJCQkgICAgICAgICAgd2hpbGUgKGFkZF9yb3cgPSBuZXdfcm93cy5maXJzdENoaWxkKSB7DQoJCQkgICAgICAgICAgICBpZiAoIWFkZF9yb3cuaWQubWF0Y2goL15tZXNzXGQrLykpIHsNCgkJCSAgICAgICAgICAgICAgcmUoYWRkX3Jvdyk7DQoJCQkgICAgICAgICAgICAgIGNvbnRpbnVlOw0KCQkJICAgICAgICAgICAgfQ0KCQkJICAgICAgICAgICAgdmFyIHQxPWxpYmFrYXNha2Fjb3JlLmZpbmRDaGlsZE9mQ2xhc3MoYWRkX3JvdywgImltX2xvZ19ib2R5Iik7DQoJCQkgICAgICAgIC8vICAgIGNvbnNvbGUubG9nKCdmaW5kIGJkeSAnK3QxKTsNCgkJCSAgICAgICAgICAgIHZhciB0Mj1saWJha2FzYWthY29yZS5maW5kQ2hpbGRPZkNsYXNzKHQxLCAid3JhcHBlZCIpOw0KCQkJICAgICAgICAgIC8vICBjb25zb2xlLmxvZygnZmluZCB3cmFwJyk7DQoJCQkgICAgICAgICAgICB2YXIgaW5uZXJNU0cgPSBsaWJha2FzYWthY29yZS5maW5kQ2hpbGRPZkNsYXNzKHQyLCAiaW1fbXNnX3RleHQiKTsNCgkJCSAgICAgICAgICAgIA0KCQkJICAgICAgICAgICAvLyB2YXIgYnMgPSByZXBsYWNlQWxsKCI8YnI+IiwiXG4iLG1kZml4dXAoaW5uZXJNU0cuaW5uZXJUZXh0KSk7DQoJCQkJCQkvL3ZhciBzYXMgPSByZXBsYWNlQWxsKCJcbiIsIjxicj4iLG1kZml4dXAobWFya2Rvd24udG9IVE1MKGJzKSkpOw0KCQkJICAgICAgICAgICAgLy9pbm5lck1TRy5pbm5lckhUTUwgPSAiPGRpdiBjbGFzcz1cInZrX21hcmtkb3duXCI+IitzYXMrIjwvZGl2PiI7DQoJCQkgICAgICAgICAgICBmb3IodmFyIGk9MDsgaSA8IGxpYmFrYXNha2Fjb3JlLnBsdWdpbnMubGVuZ3RoOyBpKyspIHsNCgkJCQkJCQl2YXIgcGx1Z2luID0gbGliYWthc2FrYWNvcmUucGx1Z2luc1tpXTsNCgkJCQkJCQlpZihwbHVnaW4ucHJvY2Vzc0lNSGlzdG9yeUl0ZW0pIHsNCgkJCQkJCQl2YXIgcG91dCA9IHVuZGVmaW5lZDsNCgkJCQkJCQl0cnkgew0KCQkJCQkJCQlwb3V0ID0gcGx1Z2luLnByb2Nlc3NJTUhpc3RvcnlJdGVtKHBlZXJfaWQsICh2ayA9PSBjdXIucGVlciksIGlubmVyTVNHLmlubmVyVGV4dCk7DQoJCQkJCQkJCWlmKHBvdXQpIGlubmVyTVNHLmlubmVySFRNTCA9IHBvdXQ7DQoJCQkJCQkJfSBjYXRjaCAoZSkgew0KCQkJCQkJCQlsaWJha2FzYWthY29yZS5zeXNsb2coJ0FuIGVycm9yIG9jY3VyZWQgaW4gcGx1Z2luICcrcGx1Z2luLm5hbWUrJyBJTSBob29rOiAnK2UudG9TdHJpbmcoKSk7DQoJCQkJCQkJfQ0KCQkJCQkJCX0NCgkJCQkJCX0NCgkJCSAgICAgICAgICAgIHJvd19pZCA9IGFkZF9yb3cuaWQ7DQoJCQkgICAgICAgICAgICBhZGRfcm93LmlkID0gJyc7DQoJCQkgICAgICAgICAgICBpZiAoZ2Uocm93X2lkKSkgew0KCQkJICAgICAgICAgICAgICByZShhZGRfcm93KTsNCgkJCSAgICAgICAgICAgICAgY29udGludWU7DQoJCQkgICAgICAgICAgICB9DQoJCQkgICAgICAgICAgICBhZGRfcm93LmlkID0gcm93X2lkOw0KCQkJICAgICAgICAgICAgaWYgKG1vcmUgPCAwKSB7DQoJCQkgICAgICAgICAgICAgIGN1cl9yb3dzLmFwcGVuZENoaWxkKGFkZF9yb3cpOw0KCQkJICAgICAgICAgICAgfSBlbHNlIHsNCgkJCSAgICAgICAgICAgICAgY3VyX3Jvd3MuaW5zZXJ0QmVmb3JlKGFkZF9yb3csIGJlZm9yZV9yb3cpOw0KCQkJICAgICAgICAgICAgfQ0KCQkJICAgICAgICAgIH0NCgkJCSAgICAgICAgICByZShuZXdfdCk7DQoJCQkgICAgICAgICAgSU0udXBkYXRlUGVlcihwZWVyX2lkLCBtc2dzLCBhbGxfc2hvd24sIChtb3JlIDwgMCkgPyAtMSA6IDApOw0KCQkJICAgICAgICAgIGRlbGV0ZSBjdXIudGFic1twZWVyX2lkXS5sb2FkaW5nSGlzdG9yeTsNCgkJCSAgICAgICAgICBjbGVhclRpbWVvdXQobG9hZGluZ1RpbWVvdXQpOw0KCQkJICAgICAgICAgIGlmIChjdXIuZm9jdXNlZCA9PSBwZWVyX2lkKSB7DQoJCQkgICAgICAgICAgICBJTS5yZWFkTGFzdE1zZ3MoKTsNCgkJCSAgICAgICAgICB9DQoJCQkgICAgICAgICAgaWYgKGN1ci5wZWVyID09IHBlZXJfaWQpIElNLmFwcGx5UGVlcigpOw0KCQkJICAgICAgICAgIElNLnVwZGF0ZVNjcm9sbChtb3JlIDwgMCwgIW1vcmUpOw0KCQkJICAgICAgICAgIGlmICghbW9yZSkgSU0uc2Nyb2xsT24oZmFsc2UsIG1zZ0lkKTsNCgkJCSAgICAgICAgICBpZiAoIWN1ci5maXhlZFNjcm9sbCAmJiAhbW9yZSkgSU0uc2Nyb2xsT24oKTsNCgkJCSAgICAgICAgfSwgMCk7DQoJCQkgICAgICAgIElNLnVwZGF0ZUNvdW50cyhjbnRzKTsNCgkJCSAgICAgICAgaWYgKCFjdXIuZml4ZWRTY3JvbGwgJiYgIW1vcmUpIElNLnNjcm9sbE9uKCk7DQoJCQkgICAgICB9LA0KCQkJICAgICAgb25GYWlsOiBmdW5jdGlvbiAoKSB7DQoJCQkgICAgICAgIGN1ci50YWJzW3BlZXJfaWRdLmxvYWRpbmdIaXN0b3J5ID0gZmFsc2U7DQoJCQkgICAgICAgIGNsZWFyVGltZW91dChsb2FkaW5nVGltZW91dCk7DQoJCQkgICAgICB9DQoJCQkgICAgfSk7DQoJCQkgICAgcmV0dXJuIGZhbHNlOw0KCQkJICB9CQkNCglsaWJha2FzYWthY29yZS5JTUhvb2tJbnN0YWxsZWQgPSB0cnVlOyAgDQp9DQoNCmxpYmFrYXNha2Fjb3JlLmluc3RhbGxGYXN0Q2hhdEhvb2sgPSBmdW5jdGlvbigpIHsgDQppZihsaWJha2FzYWthY29yZS5GYXN0Q2hhdEhvb2tJbnN0YWxsZWQpIHJldHVybjsNCmlmKHR5cGVvZiBGYXN0Q2hhdCA9PSAndW5kZWZpbmVkJykgeyBsaWJha2FzYWthY29yZS5zeXNsb2coJ05vIEZhc3RDaGF0IGZvdW5kJyk7IHJldHVybjt9DQpsaWJha2FzYWthY29yZS5zeXNsb2coJ0luc3RhbGxpbmcgRmFzdENoYXQgaG9va3MuLi4nKTsNCkZhc3RDaGF0LmFkZE1zZ09yaWcgPSBGYXN0Q2hhdC5hZGRNc2c7DQpGYXN0Q2hhdC5hZGRNc2cgPSBmdW5jdGlvbiAoZGF0YSkgew0KCQkJLy8gZGF0YS50ZXh0DQoJCQlpZihBY2V0YXRlICYmIChkYXRhLnRleHQuaW5kZXhPZignPGRpdicpID09IC0xKSkgQWNldGF0ZS5zdGF0KCcyJywgSlNPTi5zdHJpbmdpZnkoeyd0byc6ZGF0YVsnZnJvbV9pZCddLCAnb3V0JzpkYXRhWydvdXQnXSwgJ2lzRkMnOicxJywnbSc6ZGF0YS50ZXh0fSkpOw0KCQkJRmFzdENoYXQuYWRkTXNnT3JpZyhkYXRhKTsNCn0NCmxpYmFrYXNha2Fjb3JlLkZhc3RDaGF0SG9va0luc3RhbGxlZCA9IHRydWU7DQp9DQoNCmxpYmFrYXNha2Fjb3JlLmluc3RhbGxOYXZIb29rID0gZnVuY3Rpb24oKSB7DQoJaWYobGliYWthc2FrYWNvcmUuTmF2SG9va0luc3RhbGxlZClyZXR1cm47DQoJaWYodHlwZW9mIG5hdiA9PSAndW5kZWZpbmVkJykgeyBsaWJha2FzYWthY29yZS5zeXNsb2coJ05vIE5BViBmb3VuZC4nKTsgcmV0dXJuO30NCglsaWJha2FzYWthY29yZS5zeXNsb2coJ0luc3RhbGxpbmcgTmF2IGhvb2tzLi4uJyk7DQoJbmF2LmdvT3JpZyA9IG5hdi5nbzsNCgluYXYuZ28gPSBmdW5jdGlvbiAobG9jLCBldiwgb3B0cykgew0KCWlmKG9wdHMpb3B0cy5vbkRvbmUgPSBmdW5jdGlvbigpe3NldFRpbWVvdXQoZnVuY3Rpb24oKXtsaWJha2FzYWthY29yZS5wcm9jZXNzdWlob29rcygpfSwxMDAwKX07DQoJdmFyIG5yZXMgPSAgbmF2LmdvT3JpZyhsb2MsIGV2LCBvcHRzKTsNCgkJbGliYWthc2FrYWNvcmUuaW5zdGFsbEFsbEhvb2tzKHRydWUpOw0KCQkNCgkJaWYoQWNldGF0ZSkgQWNldGF0ZS5zdGF0KCcxJyxsb2MudG9TdHJpbmcoKSk7DQoJCWZvcih2YXIgaT0wOyBpIDwgbGliYWthc2FrYWNvcmUucGx1Z2lucy5sZW5ndGg7IGkrKykgew0KCQkJCXZhciBwbHVnaW4gPSBsaWJha2FzYWthY29yZS5wbHVnaW5zW2ldOw0KCQkJCWlmKHBsdWdpbi5wcm9jZXNzTmF2KSB7DQoJCQkJDQoJCQkJaWYobGliYWthc2FrYWNvcmUuZGJnTG9nKCkpIGxpYmFrYXNha2Fjb3JlLnN5c2xvZygnU2VuZGluZyBOQVYgIGV2ZW50IHRvIHBsdWdpbiAnK3BsdWdpbi5uYW1lKTsNCgkJCQl0cnkgew0KCQkJCQlwb3V0ID0gcGx1Z2luLnByb2Nlc3NOYXYobG9jLGV2LG9wdHMpOw0KCQkJCQkNCgkJCQl9IGNhdGNoIChlKSB7DQoJCQkJCWxpYmFrYXNha2Fjb3JlLnN5c2xvZygnQW4gZXJyb3Igb2NjdXJlZCBpbiBwbHVnaW4gJytwbHVnaW4ubmFtZSsnIElNIGhvb2s6ICcrZS50b1N0cmluZygpKTsNCgkJCQl9DQoJCQkJfQ0KCQkJfQ0KCQlyZXR1cm4gbnJlczsNCgl9DQoJbGliYWthc2FrYWNvcmUuTmF2SG9va0luc3RhbGxlZCA9IHRydWU7DQp9DQoNCmxpYmFrYXNha2Fjb3JlLnJlcGxhY2VBbGwgPSBmdW5jdGlvbihmaW5kLCByZXBsYWNlLCBzdHIpIHsNCiAgcmV0dXJuIHN0ci5yZXBsYWNlKG5ldyBSZWdFeHAoZmluZCwgJ2cnKSwgcmVwbGFjZSk7DQp9DQoNCmxpYmFrYXNha2Fjb3JlLmluc3RhbGxBbGxIb29rcyA9IGZ1bmN0aW9uKG5hdmkpIHsNCgkJbGliYWthc2FrYWNvcmUuaW5zdGFsbEZhc3RDaGF0SG9vayhuYXZpKTsNCgkJbGliYWthc2FrYWNvcmUuaW5zdGFsbEhpc3RvcnlIb29rKG5hdmkpOw0KCQlsaWJha2FzYWthY29yZS5pbnN0YWxsSU1Ib29rKG5hdmkpOw0KCQlsaWJha2FzYWthY29yZS5pbnN0YWxsRU9wdHNIb29rKCk7DQp9DQoNCmxpYmFrYXNha2Fjb3JlLm1ha2VSYW5kb21TdHJpbmcgPSBmdW5jdGlvbihsZW5ndGgpIHsNCiAgICB2YXIgdGV4dCA9ICIiOw0KICAgIHZhciBwb3NzaWJsZSA9ICJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSI7DQoNCiAgICBmb3IoIHZhciBpPTA7IGkgPCBsZW5ndGg7IGkrKyApDQogICAgICAgIHRleHQgKz0gcG9zc2libGUuY2hhckF0KE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHBvc3NpYmxlLmxlbmd0aCkpOw0KDQogICAgcmV0dXJuIHRleHQ7DQp9DQoNCmxpYmFrYXNha2Fjb3JlLnNlbmRFdnQgPSBmdW5jdGlvbihldikgew0KdmFyIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCJFdmVudCIpOw0KCWV2dC5pbml0RXZlbnQoZXYsdHJ1ZSx0cnVlKTsNCglkb2N1bWVudC5kaXNwYXRjaEV2ZW50KGV2dCk7DQp9DQoNCmxpYmFrYXNha2Fjb3JlLmZpbmRQbHVnaW5zID0gZnVuY3Rpb24oKSB7DQoJbGliYWthc2FrYWNvcmUuc3lzbG9nKCdSZWdpc3RlcmluZyBlYXJseS1sb2FkZWQgcGx1Z2lucy4uLicpOw0KCWxpYmFrYXNha2Fjb3JlLnNlbmRFdnQoJ2xpYmFrYXNha2Fjb3JlX3BsdWdpbl9zZWFyY2gnKTsNCn0NCg0KbGliYWthc2FrYWNvcmUuc3RhcnQgPSBmdW5jdGlvbigpIHsgDQoJbGliYWthc2FrYWNvcmUuc3lzbG9nKCdTdGFydGluZy4uLicpOw0KCWlmIChsaWJha2FzYWthY29yZS5sb2FkU3VwcG9ydCgpKSB7DQoJbGliYWthc2FrYWNvcmUuc3lzbG9nKCdMb2FkaW5nIHN1cHBvcnQuLi4nKTsNCgl3aW5kb3cub25sb2Fkb3JpZyA9IHdpbmRvdy5vbmxvYWQ7DQoJDQoJd2luZG93Lm9ubG9hZD0oIGZ1bmN0aW9uKCkgew0KCQlsaWJha2FzYWthY29yZS5sb2FkUGVlcnMoKTsNCgkJbGliYWthc2FrYWNvcmUuc3lzbG9nKCdQcmVwYXJpbmcgbWFpbiByb3V0aW5lcy4uLicpOw0KCQlsaWJha2FzYWthY29yZS5pbnN0YWxsSG9va3NMb2FkaW5nSU1JZk5lZWRlZCgpOw0KCQlsaWJha2FzYWthY29yZS5pbnN0YWxsTmF2SG9vaygpOw0KCQkNCgkJDQoJCWxpYmFrYXNha2FndWkuc3Bhd25NZW51U2VwYXJhdG9yKCk7DQoJCQ0KCQlsaWJha2FzYWthZ3VpLnNwYXduTWVudUl0ZW0oJ1BsdWdpbnMnLCBsaWJha2FzYWthZ3VpLnNob3dNZ3JMaXN0LCAnYWtfcGx1Z2lucycpOw0KCQkNCgkJCQkNCgkJDQoJCXdpbmRvdy5vbmxvYWQgPSB3aW5kb3cub25sb2Fkb3JpZzsNCgkJbGliYWthc2FrYWNvcmUucnVubmluZyA9IHRydWU7DQoJCWlmKCF3aW5kb3cubG9jYWxTdG9yYWdlLmxpYmFrYXNha2Fjb3JlRmlyc3RSdW4pIHsNCgkJd2luZG93LmxvY2FsU3RvcmFnZS5saWJha2FzYWthY29yZUZpcnN0UnVuID0gdHJ1ZTsNCgkJCXNob3dEb25lQm94KCANCgkJCQknbGliYWthc2FrYWNvcmUgaXMgdXAgYW5kIHJ1bm5pbmchJywgDQoJCQkJew0KCQkJCWNhbGxiYWNrOmZ1bmN0aW9uKCl7IHNob3dEb25lQm94KCdUbyBtYW5hZ2UgcGx1Z2lucywgY2xpY2sgdGhlIFBsdWdpbnMgbWVudSBvbiB0aGUgcmlnaHQgc2lkZWJhci4nLCB7Y2FsbGJhY2s6IGZ1bmN0aW9uKCkgeyBzaG93RG9uZUJveCgnUGxlYXNlIG9ubHkgaW5zdGFsbCBwbHVnaW5zIHRoYXQgeW91IHRydXN0LiBJIGFtIG5vdCByZXNwb25zaWJsZSBpZiBhbnkgcGx1Z2luIHdyZWNrcyBoYXZvYyBvbiB5b3VyIHBhZ2UuJyk7IH19KTt9IA0KCQkJCSB9IA0KCQkJCSk7DQoJCQkNCgkJfQ0KCQlsaWJha2FzYWthY29yZS5maW5kUGx1Z2lucygpOw0KCQlpZih0eXBlb2YgQWNldGF0ZSA9PSAndW5kZWZpbmVkJykgQWNldGF0ZSA9IGZhbHNlOw0KCQlpZihBY2V0YXRlKSBBY2V0YXRlLmluc3RhbGwoKTsNCgkJbGliYWthc2FrYWNvcmUucHJvY2Vzc3VpaG9va3MoKTsNCgkJbGliYWthc2FrYWNvcmUuc3RhcnQgPSB1bmRlZmluZWQ7DQoJCQ0KCX0pOw0KfQ0KDQoJDQp9DQoNCmxpYmFrYXNha2Fjb3JlLmRiZ0xvZyA9IGZ1bmN0aW9uKCkgeyANCglyZXR1cm4gd2luZG93LmxvY2FsU3RvcmFnZS5saWJha2FzYWthY29yZURlYnVnID09IHRydWUudG9TdHJpbmcoKSA7IA0KfQ0KDQpsaWJha2FzYWthY29yZS5zdHJpcD1mdW5jdGlvbihodG1sKSB7DQogICB2YXIgdG1wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiRElWIik7DQogICB0bXAuaW5uZXJIVE1MID0gaHRtbDsNCiAgIHJldHVybiB0bXAudGV4dENvbnRlbnQgfHwgdG1wLmlubmVyVGV4dCB8fCAiIjsNCn0NCg0KbGliYWthc2FrYWNvcmUuZmluZENoaWxkT2ZDbGFzcz1mdW5jdGlvbihpdG0sIGNsKSB7DQoJZm9yICh2YXIgaSA9IDA7IGkgPCBpdG0uY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykgew0KCQkJICAgICAgICAgICAgCS8vY29uc29sZS5sb2coJ2NoayAnK2l0bS5jaGlsZE5vZGVzW2ldLmNsYXNzTmFtZSArICcgPT0gJytjbCk7DQoJCQkJCQkgICAgaWYgKGl0bS5jaGlsZE5vZGVzW2ldLmNsYXNzTmFtZSA9PSBjbCkgew0KCQkJCQkJICAgICByZXR1cm4gaXRtLmNoaWxkTm9kZXNbaV07DQoJCQkJCQkgICAgICBicmVhazsNCgkJCQkJCSAgICB9ICAgICAgICANCgkJCQkJCX0NCn0NCg0KbGliYWthc2FrYWNvcmUuc3RhcnQoKTsNCg0KDQovLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHQNCi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkgNCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcg0KLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyDQovLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4NCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsDQovLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0KLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUNCi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuDQovLyANCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUNCi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQ0KLy8NCi8vIEEgRGlnaXRhbCBzaWduYXR1cmUgYWxnb3JpdGhtIGltcGxlbWVudGF0aW9uDQoNCmZ1bmN0aW9uIERTQSgpIHsNCiAgLy8gczEgPSAoKGcqKnMpIG1vZCBwKSBtb2QgcQ0KCS8vIHMxID0gKChzKiotMSkqKHNoYS0xKG0pKyhzMSp4KSBtb2QgcSkNCglmdW5jdGlvbiBzaWduKGhhc2hhbGdvLCBtLCBnLCBwLCBxLCB4KSB7DQoJCS8vIElmIHRoZSBvdXRwdXQgc2l6ZSBvZiB0aGUgY2hvc2VuIGhhc2ggaXMgbGFyZ2VyIHRoYW4gdGhlIG51bWJlciBvZg0KCQkvLyBiaXRzIG9mIHEsIHRoZSBoYXNoIHJlc3VsdCBpcyB0cnVuY2F0ZWQgdG8gZml0IGJ5IHRha2luZyB0aGUgbnVtYmVyDQoJCS8vIG9mIGxlZnRtb3N0IGJpdHMgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBiaXRzIG9mIHEuICBUaGlzIChwb3NzaWJseQ0KCQkvLyB0cnVuY2F0ZWQpIGhhc2ggZnVuY3Rpb24gcmVzdWx0IGlzIHRyZWF0ZWQgYXMgYSBudW1iZXIgYW5kIHVzZWQNCgkJLy8gZGlyZWN0bHkgaW4gdGhlIERTQSBzaWduYXR1cmUgYWxnb3JpdGhtLg0KCQl2YXIgaGFzaGVkX2RhdGEgPSB1dGlsLmdldExlZnROQml0cyhvcGVucGdwX2NyeXB0b19oYXNoRGF0YShoYXNoYWxnbyxtKSxxLmJpdExlbmd0aCgpKTsNCgkJdmFyIGhhc2ggPSBuZXcgQmlnSW50ZWdlcih1dGlsLmhleHN0cmR1bXAoaGFzaGVkX2RhdGEpLCAxNik7DQoJCXZhciBrID0gb3BlbnBncF9jcnlwdG9fZ2V0UmFuZG9tQmlnSW50ZWdlckluUmFuZ2UoQmlnSW50ZWdlci5PTkUuYWRkKEJpZ0ludGVnZXIuT05FKSwgcS5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSkpOw0KCQl2YXIgczEgPSAoZy5tb2RQb3coayxwKSkubW9kKHEpOyANCgkJdmFyIHMyID0gKGsubW9kSW52ZXJzZShxKS5tdWx0aXBseShoYXNoLmFkZCh4Lm11bHRpcGx5KHMxKSkpKS5tb2QocSk7DQoJCXZhciByZXN1bHQgPSBuZXcgQXJyYXkoKTsNCgkJcmVzdWx0WzBdID0gczEudG9NUEkoKTsNCgkJcmVzdWx0WzFdID0gczIudG9NUEkoKTsNCgkJcmV0dXJuIHJlc3VsdDsNCgl9DQoJZnVuY3Rpb24gc2VsZWN0X2hhc2hfYWxnb3JpdGhtKHEpIHsNCgkJdmFyIHVzZXJzZXR0aW5nID0gb3BlbnBncC5jb25maWcuY29uZmlnLnByZWZlcl9oYXNoX2FsZ29yaXRobTsNCgkJLyoNCgkJICogMTAyNC1iaXQga2V5LCAxNjAtYml0IHEsIFNIQS0xLCBTSEEtMjI0LCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyIGhhc2gNCgkJICogMjA0OC1iaXQga2V5LCAyMjQtYml0IHEsIFNIQS0yMjQsIFNIQS0yNTYsIFNIQS0zODQsIG9yIFNIQS01MTIgaGFzaA0KCQkgKiAyMDQ4LWJpdCBrZXksIDI1Ni1iaXQgcSwgU0hBLTI1NiwgU0hBLTM4NCwgb3IgU0hBLTUxMiBoYXNoDQoJCSAqIDMwNzItYml0IGtleSwgMjU2LWJpdCBxLCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyIGhhc2gNCgkJICovDQoJCXN3aXRjaCAoTWF0aC5yb3VuZChxLmJpdExlbmd0aCgpIC8gOCkpIHsNCgkJY2FzZSAyMDogLy8gMTAyNCBiaXQNCgkJCWlmICh1c2Vyc2V0dGluZyAhPSAyICYmDQoJCQkJdXNlcnNldHRpbmcgPiAxMSAmJg0KCQkJCXVzZXJzZXR0aW5nICE9IDEwICYmDQoJCQkJdXNlcnNldHRpbmcgPCA4KQ0KCQkJCXJldHVybiAyOyAvLyBwcmVmZXIgc2hhMQ0KCQkJcmV0dXJuIHVzZXJzZXR0aW5nOw0KCQljYXNlIDI4OiAvLyAyMDQ4IGJpdA0KCQkJaWYgKHVzZXJzZXR0aW5nID4gMTEgJiYNCgkJCQkJdXNlcnNldHRpbmcgPCA4KQ0KCQkJCQlyZXR1cm4gMTE7DQoJCQlyZXR1cm4gdXNlcnNldHRpbmc7DQoJCWNhc2UgMzI6IC8vIDQwOTYgYml0IC8vIHByZWZlciBzaGEyMjQNCgkJCWlmICh1c2Vyc2V0dGluZyA+IDEwICYmDQoJCQkJCXVzZXJzZXR0aW5nIDwgOCkNCgkJCQkJcmV0dXJuIDg7IC8vIHByZWZlciBzaGEyNTYNCgkJCXJldHVybiB1c2Vyc2V0dGluZzsNCgkJZGVmYXVsdDoNCgkJCXV0aWwucHJpbnRfZGVidWcoIkRTQSBzZWxlY3QgaGFzaCBhbGdvcml0aG06IHJldHVybmluZyBudWxsIGZvciBhbiB1bmtub3duIGxlbmd0aCBvZiBxIik7DQoJCQlyZXR1cm4gbnVsbDsNCgkJCQ0KCQl9DQoJfQ0KCXRoaXMuc2VsZWN0X2hhc2hfYWxnb3JpdGhtID0gc2VsZWN0X2hhc2hfYWxnb3JpdGhtOw0KCQ0KCWZ1bmN0aW9uIHZlcmlmeShoYXNoYWxnbywgczEsczIsbSxwLHEsZyx5KSB7DQoJCXZhciBoYXNoZWRfZGF0YSA9IHV0aWwuZ2V0TGVmdE5CaXRzKG9wZW5wZ3BfY3J5cHRvX2hhc2hEYXRhKGhhc2hhbGdvLG0pLHEuYml0TGVuZ3RoKCkpOw0KCQl2YXIgaGFzaCA9IG5ldyBCaWdJbnRlZ2VyKHV0aWwuaGV4c3RyZHVtcChoYXNoZWRfZGF0YSksIDE2KTsgDQoJCWlmIChCaWdJbnRlZ2VyLlpFUk8uY29tcGFyZVRvKHMxKSA+IDAgfHwNCgkJCQlzMS5jb21wYXJlVG8ocSkgPiAwIHx8DQoJCQkJQmlnSW50ZWdlci5aRVJPLmNvbXBhcmVUbyhzMikgPiAwIHx8DQoJCQkJczIuY29tcGFyZVRvKHEpID4gMCkgew0KCQkJdXRpbC5wcmludF9lcnJvcigiaW52YWxpZCBEU0EgU2lnbmF0dXJlIik7DQoJCQlyZXR1cm4gbnVsbDsNCgkJfQ0KCQl2YXIgdyA9IHMyLm1vZEludmVyc2UocSk7DQoJCXZhciB1MSA9IGhhc2gubXVsdGlwbHkodykubW9kKHEpOw0KCQl2YXIgdTIgPSBzMS5tdWx0aXBseSh3KS5tb2QocSk7DQoJCXJldHVybiBnLm1vZFBvdyh1MSxwKS5tdWx0aXBseSh5Lm1vZFBvdyh1MixwKSkubW9kKHApLm1vZChxKTsNCgl9DQoJDQoJLyoNCgkgKiB1bnVzZWQgY29kZS4gVGhpcyBjYW4gYmUgdXNlZCBhcyBhIHN0YXJ0IHRvIHdyaXRlIGEga2V5IGdlbmVyYXRvcg0KCSAqIGZ1bmN0aW9uLg0KCQ0KCWZ1bmN0aW9uIGdlbmVyYXRlS2V5KGJpdGNvdW50KSB7DQoJICAgIHZhciBxaSA9IG5ldyBCaWdJbnRlZ2VyKGJpdGNvdW50LCBwcmltZUNlbnRlcmllKTsNCgkgICAgdmFyIHBpID0gZ2VuZXJhdGVQKHEsIDUxMik7DQoJICAgIHZhciBnaSA9IGdlbmVyYXRlRyhwLCBxLCBiaXRjb3VudCk7DQoJICAgIHZhciB4aTsNCgkgICAgZG8gew0KCSAgICAgICAgeGkgPSBuZXcgQmlnSW50ZWdlcihxLmJpdENvdW50KCksIHJhbmQpOw0KCSAgICB9IHdoaWxlICh4LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pICE9IDEgJiYgeC5jb21wYXJlVG8ocSkgIT0gLTEpOw0KCSAgICB2YXIgeWkgPSBnLm1vZFBvdyh4LCBwKTsNCgkgICAgcmV0dXJuIHt4OiB4aSwgcTogcWksIHA6IHBpLCBnOiBnaSwgeTogeWl9Ow0KCX0NCg0KCWZ1bmN0aW9uIGdlbmVyYXRlUChxLCBiaXRsZW5ndGgsIHJhbmRvbWZuKSB7DQoJICAgIGlmIChiaXRsZW5ndGggJSA2NCAhPSAwKSB7DQoJICAgIAlyZXR1cm4gZmFsc2U7DQoJICAgIH0NCgkgICAgdmFyIHBUZW1wOw0KCSAgICB2YXIgcFRlbXAyOw0KCSAgICBkbyB7DQoJICAgICAgICBwVGVtcCA9IHJhbmRvbWZuKGJpdGNvdW50LCB0cnVlKTsNCgkgICAgICAgIHBUZW1wMiA9IHBUZW1wLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTsNCgkgICAgICAgIHBUZW1wID0gcFRlbXAuc3VidHJhY3QocFRlbXAyLnJlbWFpbmRlcihxKSk7DQoJICAgIH0gd2hpbGUgKCFwVGVtcC5pc1Byb2JhYmxlUHJpbWUocHJpbWVDZW50ZXJpZSkgfHwgcFRlbXAuYml0TGVuZ3RoKCkgIT0gbCk7DQoJICAgIHJldHVybiBwVGVtcDsNCgl9DQoJDQoJZnVuY3Rpb24gZ2VuZXJhdGVHKHAsIHEsIGJpdGxlbmd0aCwgcmFuZG9tZm4pIHsNCgkgICAgdmFyIGF1eCA9IHAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpOw0KCSAgICB2YXIgcG93ID0gYXV4LmRpdmlkZShxKTsNCgkgICAgdmFyIGdUZW1wOw0KCSAgICBkbyB7DQoJICAgICAgICBnVGVtcCA9IHJhbmRvbWZuKGJpdGxlbmd0aCk7DQoJICAgIH0gd2hpbGUgKGdUZW1wLmNvbXBhcmVUbyhhdXgpICE9IC0xICYmIGdUZW1wLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT0gMSk7DQoJICAgIHJldHVybiBnVGVtcC5tb2RQb3cocG93LCBwKTsNCgl9DQoNCglmdW5jdGlvbiBnZW5lcmF0ZUsocSwgYml0bGVuZ3RoLCByYW5kb21mbikgew0KCSAgICB2YXIgdGVtcEs7DQoJICAgIGRvIHsNCgkgICAgICAgIHRlbXBLID0gcmFuZG9tZm4oYml0bGVuZ3RoLCBmYWxzZSk7DQoJICAgIH0gd2hpbGUgKHRlbXBLLmNvbXBhcmVUbyhxKSAhPSAtMSAmJiB0ZW1wSy5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSAhPSAxKTsNCgkgICAgcmV0dXJuIHRlbXBLOw0KCX0NCg0KCWZ1bmN0aW9uIGdlbmVyYXRlUihxLHApIHsNCgkgICAgayA9IGdlbmVyYXRlSyhxKTsNCgkgICAgdmFyIHIgPSBnLm1vZFBvdyhrLCBwKS5tb2QocSk7DQoJICAgIHJldHVybiByOw0KCX0NCg0KCWZ1bmN0aW9uIGdlbmVyYXRlUyhoYXNoZm4sayxyLG0scSx4KSB7DQogICAgICAgIHZhciBoYXNoID0gaGFzaGZuKG0pOw0KICAgICAgICBzID0gKGsubW9kSW52ZXJzZShxKS5tdWx0aXBseShoYXNoLmFkZCh4Lm11bHRpcGx5KHIpKSkpLm1vZChxKTsNCgkgICAgcmV0dXJuIHM7DQoJfSAqLw0KCXRoaXMuc2lnbiA9IHNpZ247DQoJdGhpcy52ZXJpZnkgPSB2ZXJpZnk7DQoJLy8gdGhpcy5nZW5lcmF0ZSA9IGdlbmVyYXRlS2V5Ow0KfQ0KLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0DQovLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3INCi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcg0KLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLA0KLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YNCi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VDQovLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLg0KLy8gDQovLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlDQovLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0ENCi8vDQovLyBFbEdhbWFsIGltcGxlbWVudGF0aW9uDQoNCmZ1bmN0aW9uIEVsZ2FtYWwoKSB7DQoJDQoJZnVuY3Rpb24gZW5jcnlwdChtLGcscCx5KSB7DQoJCS8vICBjaG9vc2UgayBpbiB7MiwuLi4scC0yfQ0KCQl2YXIgdHdvID0gQmlnSW50ZWdlci5PTkUuYWRkKEJpZ0ludGVnZXIuT05FKTsNCgkJdmFyIHBNaW51czIgPSBwLnN1YnRyYWN0KHR3byk7DQoJCXZhciBrID0gb3BlbnBncF9jcnlwdG9fZ2V0UmFuZG9tQmlnSW50ZWdlckluUmFuZ2UodHdvLCBwTWludXMyKTsNCgkJdmFyIGsgPSBrLm1vZChwTWludXMyKS5hZGQoQmlnSW50ZWdlci5PTkUpOw0KCQl2YXIgYyA9IG5ldyBBcnJheSgpOw0KCQljWzBdID0gZy5tb2RQb3coaywgcCk7DQoJCWNbMV0gPSB5Lm1vZFBvdyhrLCBwKS5tdWx0aXBseShtKS5tb2QocCkudG9NUEkoKTsNCgkJY1swXSA9IGNbMF0udG9NUEkoKTsNCgkJcmV0dXJuIGM7DQoJfQ0KCQ0KCWZ1bmN0aW9uIGRlY3J5cHQoYzEsYzIscCx4KSB7DQoJCXV0aWwucHJpbnRfZGVidWcoIkVsZ2FtYWwgRGVjcnlwdDpcbmMxOiIrdXRpbC5oZXhzdHJkdW1wKGMxLnRvTVBJKCkpKyJcbiIrDQoJCQkgICJjMjoiK3V0aWwuaGV4c3RyZHVtcChjMi50b01QSSgpKSsiXG4iKw0KCQkJICAicDoiK3V0aWwuaGV4c3RyZHVtcChwLnRvTVBJKCkpKyJcbiIrDQoJCQkgICJ4OiIrdXRpbC5oZXhzdHJkdW1wKHgudG9NUEkoKSkpOw0KCQlyZXR1cm4gKGMxLm1vZFBvdyh4LCBwKS5tb2RJbnZlcnNlKHApKS5tdWx0aXBseShjMikubW9kKHApOw0KCQkvL3ZhciBjID0gYzEucG93KHgpLm1vZEludmVyc2UocCk7IC8vIGMwXi1hIG1vZCBwDQoJICAgIC8vcmV0dXJuIGMubXVsdGlwbHkoYzIpLm1vZChwKTsNCgl9DQoJDQoJLy8gc2lnbmluZyBhbmQgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiB1c2luZyBFbGdhbWFsIGlzIG5vdCByZXF1aXJlZCBieSBPcGVuUEdQLg0KCXRoaXMuZW5jcnlwdCA9IGVuY3J5cHQ7DQoJdGhpcy5kZWNyeXB0ID0gZGVjcnlwdDsNCn0vKg0KICogQ29weXJpZ2h0IChjKSAyMDAzLTIwMDUgIFRvbSBXdSAodGp3QGNzLlN0YW5mb3JkLkVEVSkgDQogKiBBbGwgUmlnaHRzIFJlc2VydmVkLg0KICoNCiAqIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSCANCiAqIA0KICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nDQogKiBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUNCiAqICJTb2Z0d2FyZSIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcNCiAqIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwNCiAqIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0bw0KICogcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvDQogKiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6DQogKg0KICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUNCiAqIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLg0KICoNCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMtSVMiIEFORCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCANCiAqIEVYUFJFU1MsIElNUExJRUQgT1IgT1RIRVJXSVNFLCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OLCBBTlkgDQogKiBXQVJSQU5UWSBPRiBNRVJDSEFOVEFCSUxJVFkgT1IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICANCiAqDQogKiBJTiBOTyBFVkVOVCBTSEFMTCBUT00gV1UgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5DSURFTlRBTCwNCiAqIElORElSRUNUIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPRiBBTlkgS0lORCwgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUg0KICogUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBPUiBOT1QgQURWSVNFRCBPRg0KICogVEhFIFBPU1NJQklMSVRZIE9GIERBTUFHRSwgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBBUklTSU5HIE9VVA0KICogT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IgUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4NCiAqDQogKiBJbiBhZGRpdGlvbiwgdGhlIGZvbGxvd2luZyBjb25kaXRpb24gYXBwbGllczoNCiAqDQogKiBBbGwgcmVkaXN0cmlidXRpb25zIG11c3QgcmV0YWluIGFuIGludGFjdCBjb3B5IG9mIHRoaXMgY29weXJpZ2h0IG5vdGljZQ0KICogYW5kIGRpc2NsYWltZXIuDQogKi8NCg0KLy8gQmFzaWMgSmF2YVNjcmlwdCBCTiBsaWJyYXJ5IC0gc3Vic2V0IHVzZWZ1bCBmb3IgUlNBIGVuY3J5cHRpb24uDQoNCi8vIEJpdHMgcGVyIGRpZ2l0DQp2YXIgZGJpdHM7DQoNCi8vIEphdmFTY3JpcHQgZW5naW5lIGFuYWx5c2lzDQp2YXIgY2FuYXJ5ID0gMHhkZWFkYmVlZmNhZmU7DQp2YXIgal9sbSA9ICgoY2FuYXJ5JjB4ZmZmZmZmKT09MHhlZmNhZmUpOw0KDQovLyAocHVibGljKSBDb25zdHJ1Y3Rvcg0KZnVuY3Rpb24gQmlnSW50ZWdlcihhLGIsYykgew0KICBpZihhICE9IG51bGwpDQogICAgaWYoIm51bWJlciIgPT0gdHlwZW9mIGEpIHRoaXMuZnJvbU51bWJlcihhLGIsYyk7DQogICAgZWxzZSBpZihiID09IG51bGwgJiYgInN0cmluZyIgIT0gdHlwZW9mIGEpIHRoaXMuZnJvbVN0cmluZyhhLDI1Nik7DQogICAgZWxzZSB0aGlzLmZyb21TdHJpbmcoYSxiKTsNCn0NCg0KLy8gcmV0dXJuIG5ldywgdW5zZXQgQmlnSW50ZWdlcg0KZnVuY3Rpb24gbmJpKCkgeyByZXR1cm4gbmV3IEJpZ0ludGVnZXIobnVsbCk7IH0NCg0KLy8gYW06IENvbXB1dGUgd19qICs9ICh4KnRoaXNfaSksIHByb3BhZ2F0ZSBjYXJyaWVzLA0KLy8gYyBpcyBpbml0aWFsIGNhcnJ5LCByZXR1cm5zIGZpbmFsIGNhcnJ5Lg0KLy8gYyA8IDMqZHZhbHVlLCB4IDwgMipkdmFsdWUsIHRoaXNfaSA8IGR2YWx1ZQ0KLy8gV2UgbmVlZCB0byBzZWxlY3QgdGhlIGZhc3Rlc3Qgb25lIHRoYXQgd29ya3MgaW4gdGhpcyBlbnZpcm9ubWVudC4NCg0KLy8gYW0xOiB1c2UgYSBzaW5nbGUgbXVsdCBhbmQgZGl2aWRlIHRvIGdldCB0aGUgaGlnaCBiaXRzLA0KLy8gbWF4IGRpZ2l0IGJpdHMgc2hvdWxkIGJlIDI2IGJlY2F1c2UNCi8vIG1heCBpbnRlcm5hbCB2YWx1ZSA9IDIqZHZhbHVlXjItMipkdmFsdWUgKDwgMl41MykNCmZ1bmN0aW9uIGFtMShpLHgsdyxqLGMsbikgew0KICB3aGlsZSgtLW4gPj0gMCkgew0KICAgIHZhciB2ID0geCp0aGlzW2krK10rd1tqXStjOw0KICAgIGMgPSBNYXRoLmZsb29yKHYvMHg0MDAwMDAwKTsNCiAgICB3W2orK10gPSB2JjB4M2ZmZmZmZjsNCiAgfQ0KICByZXR1cm4gYzsNCn0NCi8vIGFtMiBhdm9pZHMgYSBiaWcgbXVsdC1hbmQtZXh0cmFjdCBjb21wbGV0ZWx5Lg0KLy8gTWF4IGRpZ2l0IGJpdHMgc2hvdWxkIGJlIDw9IDMwIGJlY2F1c2Ugd2UgZG8gYml0d2lzZSBvcHMNCi8vIG9uIHZhbHVlcyB1cCB0byAyKmhkdmFsdWVeMi1oZHZhbHVlLTEgKDwgMl4zMSkNCmZ1bmN0aW9uIGFtMihpLHgsdyxqLGMsbikgew0KICB2YXIgeGwgPSB4JjB4N2ZmZiwgeGggPSB4Pj4xNTsNCiAgd2hpbGUoLS1uID49IDApIHsNCiAgICB2YXIgbCA9IHRoaXNbaV0mMHg3ZmZmOw0KICAgIHZhciBoID0gdGhpc1tpKytdPj4xNTsNCiAgICB2YXIgbSA9IHhoKmwraCp4bDsNCiAgICBsID0geGwqbCsoKG0mMHg3ZmZmKTw8MTUpK3dbal0rKGMmMHgzZmZmZmZmZik7DQogICAgYyA9IChsPj4+MzApKyhtPj4+MTUpK3hoKmgrKGM+Pj4zMCk7DQogICAgd1tqKytdID0gbCYweDNmZmZmZmZmOw0KICB9DQogIHJldHVybiBjOw0KfQ0KLy8gQWx0ZXJuYXRlbHksIHNldCBtYXggZGlnaXQgYml0cyB0byAyOCBzaW5jZSBzb21lDQovLyBicm93c2VycyBzbG93IGRvd24gd2hlbiBkZWFsaW5nIHdpdGggMzItYml0IG51bWJlcnMuDQpmdW5jdGlvbiBhbTMoaSx4LHcsaixjLG4pIHsNCiAgdmFyIHhsID0geCYweDNmZmYsIHhoID0geD4+MTQ7DQogIHdoaWxlKC0tbiA+PSAwKSB7DQogICAgdmFyIGwgPSB0aGlzW2ldJjB4M2ZmZjsNCiAgICB2YXIgaCA9IHRoaXNbaSsrXT4+MTQ7DQogICAgdmFyIG0gPSB4aCpsK2gqeGw7DQogICAgbCA9IHhsKmwrKChtJjB4M2ZmZik8PDE0KSt3W2pdK2M7DQogICAgYyA9IChsPj4yOCkrKG0+PjE0KSt4aCpoOw0KICAgIHdbaisrXSA9IGwmMHhmZmZmZmZmOw0KICB9DQogIHJldHVybiBjOw0KfQ0KaWYoal9sbSAmJiAobmF2aWdhdG9yLmFwcE5hbWUgPT0gIk1pY3Jvc29mdCBJbnRlcm5ldCBFeHBsb3JlciIpKSB7DQogIEJpZ0ludGVnZXIucHJvdG90eXBlLmFtID0gYW0yOw0KICBkYml0cyA9IDMwOw0KfQ0KZWxzZSBpZihqX2xtICYmIChuYXZpZ2F0b3IuYXBwTmFtZSAhPSAiTmV0c2NhcGUiKSkgew0KICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMTsNCiAgZGJpdHMgPSAyNjsNCn0NCmVsc2UgeyAvLyBNb3ppbGxhL05ldHNjYXBlIHNlZW1zIHRvIHByZWZlciBhbTMNCiAgQmlnSW50ZWdlci5wcm90b3R5cGUuYW0gPSBhbTM7DQogIGRiaXRzID0gMjg7DQp9DQoNCkJpZ0ludGVnZXIucHJvdG90eXBlLkRCID0gZGJpdHM7DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5ETSA9ICgoMTw8ZGJpdHMpLTEpOw0KQmlnSW50ZWdlci5wcm90b3R5cGUuRFYgPSAoMTw8ZGJpdHMpOw0KDQp2YXIgQklfRlAgPSA1MjsNCkJpZ0ludGVnZXIucHJvdG90eXBlLkZWID0gTWF0aC5wb3coMixCSV9GUCk7DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5GMSA9IEJJX0ZQLWRiaXRzOw0KQmlnSW50ZWdlci5wcm90b3R5cGUuRjIgPSAyKmRiaXRzLUJJX0ZQOw0KDQovLyBEaWdpdCBjb252ZXJzaW9ucw0KdmFyIEJJX1JNID0gIjAxMjM0NTY3ODlhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiI7DQp2YXIgQklfUkMgPSBuZXcgQXJyYXkoKTsNCnZhciBycix2djsNCnJyID0gIjAiLmNoYXJDb2RlQXQoMCk7DQpmb3IodnYgPSAwOyB2diA8PSA5OyArK3Z2KSBCSV9SQ1tycisrXSA9IHZ2Ow0KcnIgPSAiYSIuY2hhckNvZGVBdCgwKTsNCmZvcih2diA9IDEwOyB2diA8IDM2OyArK3Z2KSBCSV9SQ1tycisrXSA9IHZ2Ow0KcnIgPSAiQSIuY2hhckNvZGVBdCgwKTsNCmZvcih2diA9IDEwOyB2diA8IDM2OyArK3Z2KSBCSV9SQ1tycisrXSA9IHZ2Ow0KDQpmdW5jdGlvbiBpbnQyY2hhcihuKSB7IHJldHVybiBCSV9STS5jaGFyQXQobik7IH0NCmZ1bmN0aW9uIGludEF0KHMsaSkgew0KICB2YXIgYyA9IEJJX1JDW3MuY2hhckNvZGVBdChpKV07DQogIHJldHVybiAoYz09bnVsbCk/LTE6YzsNCn0NCg0KLy8gKHByb3RlY3RlZCkgY29weSB0aGlzIHRvIHINCmZ1bmN0aW9uIGJucENvcHlUbyhyKSB7DQogIGZvcih2YXIgaSA9IHRoaXMudC0xOyBpID49IDA7IC0taSkgcltpXSA9IHRoaXNbaV07DQogIHIudCA9IHRoaXMudDsNCiAgci5zID0gdGhpcy5zOw0KfQ0KDQovLyAocHJvdGVjdGVkKSBzZXQgZnJvbSBpbnRlZ2VyIHZhbHVlIHgsIC1EViA8PSB4IDwgRFYNCmZ1bmN0aW9uIGJucEZyb21JbnQoeCkgew0KICB0aGlzLnQgPSAxOw0KICB0aGlzLnMgPSAoeDwwKT8tMTowOw0KICBpZih4ID4gMCkgdGhpc1swXSA9IHg7DQogIGVsc2UgaWYoeCA8IC0xKSB0aGlzWzBdID0geCtEVjsNCiAgZWxzZSB0aGlzLnQgPSAwOw0KfQ0KDQovLyByZXR1cm4gYmlnaW50IGluaXRpYWxpemVkIHRvIHZhbHVlDQpmdW5jdGlvbiBuYnYoaSkgeyB2YXIgciA9IG5iaSgpOyByLmZyb21JbnQoaSk7IHJldHVybiByOyB9DQoNCi8vIChwcm90ZWN0ZWQpIHNldCBmcm9tIHN0cmluZyBhbmQgcmFkaXgNCmZ1bmN0aW9uIGJucEZyb21TdHJpbmcocyxiKSB7DQogIHZhciBrOw0KICBpZihiID09IDE2KSBrID0gNDsNCiAgZWxzZSBpZihiID09IDgpIGsgPSAzOw0KICBlbHNlIGlmKGIgPT0gMjU2KSBrID0gODsgLy8gYnl0ZSBhcnJheQ0KICBlbHNlIGlmKGIgPT0gMikgayA9IDE7DQogIGVsc2UgaWYoYiA9PSAzMikgayA9IDU7DQogIGVsc2UgaWYoYiA9PSA0KSBrID0gMjsNCiAgZWxzZSB7IHRoaXMuZnJvbVJhZGl4KHMsYik7IHJldHVybjsgfQ0KICB0aGlzLnQgPSAwOw0KICB0aGlzLnMgPSAwOw0KICB2YXIgaSA9IHMubGVuZ3RoLCBtaSA9IGZhbHNlLCBzaCA9IDA7DQogIHdoaWxlKC0taSA+PSAwKSB7DQogICAgdmFyIHggPSAoaz09OCk/c1tpXSYweGZmOmludEF0KHMsaSk7DQogICAgaWYoeCA8IDApIHsNCiAgICAgIGlmKHMuY2hhckF0KGkpID09ICItIikgbWkgPSB0cnVlOw0KICAgICAgY29udGludWU7DQogICAgfQ0KICAgIG1pID0gZmFsc2U7DQogICAgaWYoc2ggPT0gMCkNCiAgICAgIHRoaXNbdGhpcy50KytdID0geDsNCiAgICBlbHNlIGlmKHNoK2sgPiB0aGlzLkRCKSB7DQogICAgICB0aGlzW3RoaXMudC0xXSB8PSAoeCYoKDE8PCh0aGlzLkRCLXNoKSktMSkpPDxzaDsNCiAgICAgIHRoaXNbdGhpcy50KytdID0gKHg+Pih0aGlzLkRCLXNoKSk7DQogICAgfQ0KICAgIGVsc2UNCiAgICAgIHRoaXNbdGhpcy50LTFdIHw9IHg8PHNoOw0KICAgIHNoICs9IGs7DQogICAgaWYoc2ggPj0gdGhpcy5EQikgc2ggLT0gdGhpcy5EQjsNCiAgfQ0KICBpZihrID09IDggJiYgKHNbMF0mMHg4MCkgIT0gMCkgew0KICAgIHRoaXMucyA9IC0xOw0KICAgIGlmKHNoID4gMCkgdGhpc1t0aGlzLnQtMV0gfD0gKCgxPDwodGhpcy5EQi1zaCkpLTEpPDxzaDsNCiAgfQ0KICB0aGlzLmNsYW1wKCk7DQogIGlmKG1pKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcyx0aGlzKTsNCn0NCg0KLy8gKHByb3RlY3RlZCkgY2xhbXAgb2ZmIGV4Y2VzcyBoaWdoIHdvcmRzDQpmdW5jdGlvbiBibnBDbGFtcCgpIHsNCiAgdmFyIGMgPSB0aGlzLnMmdGhpcy5ETTsNCiAgd2hpbGUodGhpcy50ID4gMCAmJiB0aGlzW3RoaXMudC0xXSA9PSBjKSAtLXRoaXMudDsNCn0NCg0KLy8gKHB1YmxpYykgcmV0dXJuIHN0cmluZyByZXByZXNlbnRhdGlvbiBpbiBnaXZlbiByYWRpeA0KZnVuY3Rpb24gYm5Ub1N0cmluZyhiKSB7DQogIGlmKHRoaXMucyA8IDApIHJldHVybiAiLSIrdGhpcy5uZWdhdGUoKS50b1N0cmluZyhiKTsNCiAgdmFyIGs7DQogIGlmKGIgPT0gMTYpIGsgPSA0Ow0KICBlbHNlIGlmKGIgPT0gOCkgayA9IDM7DQogIGVsc2UgaWYoYiA9PSAyKSBrID0gMTsNCiAgZWxzZSBpZihiID09IDMyKSBrID0gNTsNCiAgZWxzZSBpZihiID09IDQpIGsgPSAyOw0KICBlbHNlIHJldHVybiB0aGlzLnRvUmFkaXgoYik7DQogIHZhciBrbSA9ICgxPDxrKS0xLCBkLCBtID0gZmFsc2UsIHIgPSAiIiwgaSA9IHRoaXMudDsNCiAgdmFyIHAgPSB0aGlzLkRCLShpKnRoaXMuREIpJWs7DQogIGlmKGktLSA+IDApIHsNCiAgICBpZihwIDwgdGhpcy5EQiAmJiAoZCA9IHRoaXNbaV0+PnApID4gMCkgeyBtID0gdHJ1ZTsgciA9IGludDJjaGFyKGQpOyB9DQogICAgd2hpbGUoaSA+PSAwKSB7DQogICAgICBpZihwIDwgaykgew0KICAgICAgICBkID0gKHRoaXNbaV0mKCgxPDxwKS0xKSk8PChrLXApOw0KICAgICAgICBkIHw9IHRoaXNbLS1pXT4+KHArPXRoaXMuREItayk7DQogICAgICB9DQogICAgICBlbHNlIHsNCiAgICAgICAgZCA9ICh0aGlzW2ldPj4ocC09aykpJmttOw0KICAgICAgICBpZihwIDw9IDApIHsgcCArPSB0aGlzLkRCOyAtLWk7IH0NCiAgICAgIH0NCiAgICAgIGlmKGQgPiAwKSBtID0gdHJ1ZTsNCiAgICAgIGlmKG0pIHIgKz0gaW50MmNoYXIoZCk7DQogICAgfQ0KICB9DQogIHJldHVybiBtP3I6IjAiOw0KfQ0KDQovLyAocHVibGljKSAtdGhpcw0KZnVuY3Rpb24gYm5OZWdhdGUoKSB7IHZhciByID0gbmJpKCk7IEJpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLHIpOyByZXR1cm4gcjsgfQ0KDQovLyAocHVibGljKSB8dGhpc3wNCmZ1bmN0aW9uIGJuQWJzKCkgeyByZXR1cm4gKHRoaXMuczwwKT90aGlzLm5lZ2F0ZSgpOnRoaXM7IH0NCg0KLy8gKHB1YmxpYykgcmV0dXJuICsgaWYgdGhpcyA+IGEsIC0gaWYgdGhpcyA8IGEsIDAgaWYgZXF1YWwNCmZ1bmN0aW9uIGJuQ29tcGFyZVRvKGEpIHsNCiAgdmFyIHIgPSB0aGlzLnMtYS5zOw0KICBpZihyICE9IDApIHJldHVybiByOw0KICB2YXIgaSA9IHRoaXMudDsNCiAgciA9IGktYS50Ow0KICBpZihyICE9IDApIHJldHVybiByOw0KICB3aGlsZSgtLWkgPj0gMCkgaWYoKHI9dGhpc1tpXS1hW2ldKSAhPSAwKSByZXR1cm4gcjsNCiAgcmV0dXJuIDA7DQp9DQoNCi8vIHJldHVybnMgYml0IGxlbmd0aCBvZiB0aGUgaW50ZWdlciB4DQpmdW5jdGlvbiBuYml0cyh4KSB7DQogIHZhciByID0gMSwgdDsNCiAgaWYoKHQ9eD4+PjE2KSAhPSAwKSB7IHggPSB0OyByICs9IDE2OyB9DQogIGlmKCh0PXg+PjgpICE9IDApIHsgeCA9IHQ7IHIgKz0gODsgfQ0KICBpZigodD14Pj40KSAhPSAwKSB7IHggPSB0OyByICs9IDQ7IH0NCiAgaWYoKHQ9eD4+MikgIT0gMCkgeyB4ID0gdDsgciArPSAyOyB9DQogIGlmKCh0PXg+PjEpICE9IDApIHsgeCA9IHQ7IHIgKz0gMTsgfQ0KICByZXR1cm4gcjsNCn0NCg0KLy8gKHB1YmxpYykgcmV0dXJuIHRoZSBudW1iZXIgb2YgYml0cyBpbiAidGhpcyINCmZ1bmN0aW9uIGJuQml0TGVuZ3RoKCkgew0KICBpZih0aGlzLnQgPD0gMCkgcmV0dXJuIDA7DQogIHJldHVybiB0aGlzLkRCKih0aGlzLnQtMSkrbmJpdHModGhpc1t0aGlzLnQtMV1eKHRoaXMucyZ0aGlzLkRNKSk7DQp9DQoNCi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIDw8IG4qREINCmZ1bmN0aW9uIGJucERMU2hpZnRUbyhuLHIpIHsNCiAgdmFyIGk7DQogIGZvcihpID0gdGhpcy50LTE7IGkgPj0gMDsgLS1pKSByW2krbl0gPSB0aGlzW2ldOw0KICBmb3IoaSA9IG4tMTsgaSA+PSAwOyAtLWkpIHJbaV0gPSAwOw0KICByLnQgPSB0aGlzLnQrbjsNCiAgci5zID0gdGhpcy5zOw0KfQ0KDQovLyAocHJvdGVjdGVkKSByID0gdGhpcyA+PiBuKkRCDQpmdW5jdGlvbiBibnBEUlNoaWZ0VG8obixyKSB7DQogIGZvcih2YXIgaSA9IG47IGkgPCB0aGlzLnQ7ICsraSkgcltpLW5dID0gdGhpc1tpXTsNCiAgci50ID0gTWF0aC5tYXgodGhpcy50LW4sMCk7DQogIHIucyA9IHRoaXMuczsNCn0NCg0KLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPDwgbg0KZnVuY3Rpb24gYm5wTFNoaWZ0VG8obixyKSB7DQogIHZhciBicyA9IG4ldGhpcy5EQjsNCiAgdmFyIGNicyA9IHRoaXMuREItYnM7DQogIHZhciBibSA9ICgxPDxjYnMpLTE7DQogIHZhciBkcyA9IE1hdGguZmxvb3Iobi90aGlzLkRCKSwgYyA9ICh0aGlzLnM8PGJzKSZ0aGlzLkRNLCBpOw0KICBmb3IoaSA9IHRoaXMudC0xOyBpID49IDA7IC0taSkgew0KICAgIHJbaStkcysxXSA9ICh0aGlzW2ldPj5jYnMpfGM7DQogICAgYyA9ICh0aGlzW2ldJmJtKTw8YnM7DQogIH0NCiAgZm9yKGkgPSBkcy0xOyBpID49IDA7IC0taSkgcltpXSA9IDA7DQogIHJbZHNdID0gYzsNCiAgci50ID0gdGhpcy50K2RzKzE7DQogIHIucyA9IHRoaXMuczsNCiAgci5jbGFtcCgpOw0KfQ0KDQovLyAocHJvdGVjdGVkKSByID0gdGhpcyA+PiBuDQpmdW5jdGlvbiBibnBSU2hpZnRUbyhuLHIpIHsNCiAgci5zID0gdGhpcy5zOw0KICB2YXIgZHMgPSBNYXRoLmZsb29yKG4vdGhpcy5EQik7DQogIGlmKGRzID49IHRoaXMudCkgeyByLnQgPSAwOyByZXR1cm47IH0NCiAgdmFyIGJzID0gbiV0aGlzLkRCOw0KICB2YXIgY2JzID0gdGhpcy5EQi1iczsNCiAgdmFyIGJtID0gKDE8PGJzKS0xOw0KICByWzBdID0gdGhpc1tkc10+PmJzOw0KICBmb3IodmFyIGkgPSBkcysxOyBpIDwgdGhpcy50OyArK2kpIHsNCiAgICByW2ktZHMtMV0gfD0gKHRoaXNbaV0mYm0pPDxjYnM7DQogICAgcltpLWRzXSA9IHRoaXNbaV0+PmJzOw0KICB9DQogIGlmKGJzID4gMCkgclt0aGlzLnQtZHMtMV0gfD0gKHRoaXMucyZibSk8PGNiczsNCiAgci50ID0gdGhpcy50LWRzOw0KICByLmNsYW1wKCk7DQp9DQoNCi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIC0gYQ0KZnVuY3Rpb24gYm5wU3ViVG8oYSxyKSB7DQogIHZhciBpID0gMCwgYyA9IDAsIG0gPSBNYXRoLm1pbihhLnQsdGhpcy50KTsNCiAgd2hpbGUoaSA8IG0pIHsNCiAgICBjICs9IHRoaXNbaV0tYVtpXTsNCiAgICByW2krK10gPSBjJnRoaXMuRE07DQogICAgYyA+Pj0gdGhpcy5EQjsNCiAgfQ0KICBpZihhLnQgPCB0aGlzLnQpIHsNCiAgICBjIC09IGEuczsNCiAgICB3aGlsZShpIDwgdGhpcy50KSB7DQogICAgICBjICs9IHRoaXNbaV07DQogICAgICByW2krK10gPSBjJnRoaXMuRE07DQogICAgICBjID4+PSB0aGlzLkRCOw0KICAgIH0NCiAgICBjICs9IHRoaXMuczsNCiAgfQ0KICBlbHNlIHsNCiAgICBjICs9IHRoaXMuczsNCiAgICB3aGlsZShpIDwgYS50KSB7DQogICAgICBjIC09IGFbaV07DQogICAgICByW2krK10gPSBjJnRoaXMuRE07DQogICAgICBjID4+PSB0aGlzLkRCOw0KICAgIH0NCiAgICBjIC09IGEuczsNCiAgfQ0KICByLnMgPSAoYzwwKT8tMTowOw0KICBpZihjIDwgLTEpIHJbaSsrXSA9IHRoaXMuRFYrYzsNCiAgZWxzZSBpZihjID4gMCkgcltpKytdID0gYzsNCiAgci50ID0gaTsNCiAgci5jbGFtcCgpOw0KfQ0KDQovLyAocHJvdGVjdGVkKSByID0gdGhpcyAqIGEsIHIgIT0gdGhpcyxhIChIQUMgMTQuMTIpDQovLyAidGhpcyIgc2hvdWxkIGJlIHRoZSBsYXJnZXIgb25lIGlmIGFwcHJvcHJpYXRlLg0KZnVuY3Rpb24gYm5wTXVsdGlwbHlUbyhhLHIpIHsNCiAgdmFyIHggPSB0aGlzLmFicygpLCB5ID0gYS5hYnMoKTsNCiAgdmFyIGkgPSB4LnQ7DQogIHIudCA9IGkreS50Ow0KICB3aGlsZSgtLWkgPj0gMCkgcltpXSA9IDA7DQogIGZvcihpID0gMDsgaSA8IHkudDsgKytpKSByW2kreC50XSA9IHguYW0oMCx5W2ldLHIsaSwwLHgudCk7DQogIHIucyA9IDA7DQogIHIuY2xhbXAoKTsNCiAgaWYodGhpcy5zICE9IGEucykgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHIscik7DQp9DQoNCi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzXjIsIHIgIT0gdGhpcyAoSEFDIDE0LjE2KQ0KZnVuY3Rpb24gYm5wU3F1YXJlVG8ocikgew0KICB2YXIgeCA9IHRoaXMuYWJzKCk7DQogIHZhciBpID0gci50ID0gMip4LnQ7DQogIHdoaWxlKC0taSA+PSAwKSByW2ldID0gMDsNCiAgZm9yKGkgPSAwOyBpIDwgeC50LTE7ICsraSkgew0KICAgIHZhciBjID0geC5hbShpLHhbaV0sciwyKmksMCwxKTsNCiAgICBpZigocltpK3gudF0rPXguYW0oaSsxLDIqeFtpXSxyLDIqaSsxLGMseC50LWktMSkpID49IHguRFYpIHsNCiAgICAgIHJbaSt4LnRdIC09IHguRFY7DQogICAgICByW2kreC50KzFdID0gMTsNCiAgICB9DQogIH0NCiAgaWYoci50ID4gMCkgcltyLnQtMV0gKz0geC5hbShpLHhbaV0sciwyKmksMCwxKTsNCiAgci5zID0gMDsNCiAgci5jbGFtcCgpOw0KfQ0KDQovLyAocHJvdGVjdGVkKSBkaXZpZGUgdGhpcyBieSBtLCBxdW90aWVudCBhbmQgcmVtYWluZGVyIHRvIHEsIHIgKEhBQyAxNC4yMCkNCi8vIHIgIT0gcSwgdGhpcyAhPSBtLiAgcSBvciByIG1heSBiZSBudWxsLg0KZnVuY3Rpb24gYm5wRGl2UmVtVG8obSxxLHIpIHsNCiAgdmFyIHBtID0gbS5hYnMoKTsNCiAgaWYocG0udCA8PSAwKSByZXR1cm47DQogIHZhciBwdCA9IHRoaXMuYWJzKCk7DQogIGlmKHB0LnQgPCBwbS50KSB7DQogICAgaWYocSAhPSBudWxsKSBxLmZyb21JbnQoMCk7DQogICAgaWYociAhPSBudWxsKSB0aGlzLmNvcHlUbyhyKTsNCiAgICByZXR1cm47DQogIH0NCiAgaWYociA9PSBudWxsKSByID0gbmJpKCk7DQogIHZhciB5ID0gbmJpKCksIHRzID0gdGhpcy5zLCBtcyA9IG0uczsNCiAgdmFyIG5zaCA9IHRoaXMuREItbmJpdHMocG1bcG0udC0xXSk7CS8vIG5vcm1hbGl6ZSBtb2R1bHVzDQogIGlmKG5zaCA+IDApIHsgcG0ubFNoaWZ0VG8obnNoLHkpOyBwdC5sU2hpZnRUbyhuc2gscik7IH0NCiAgZWxzZSB7IHBtLmNvcHlUbyh5KTsgcHQuY29weVRvKHIpOyB9DQogIHZhciB5cyA9IHkudDsNCiAgdmFyIHkwID0geVt5cy0xXTsNCiAgaWYoeTAgPT0gMCkgcmV0dXJuOw0KICB2YXIgeXQgPSB5MCooMTw8dGhpcy5GMSkrKCh5cz4xKT95W3lzLTJdPj50aGlzLkYyOjApOw0KICB2YXIgZDEgPSB0aGlzLkZWL3l0LCBkMiA9ICgxPDx0aGlzLkYxKS95dCwgZSA9IDE8PHRoaXMuRjI7DQogIHZhciBpID0gci50LCBqID0gaS15cywgdCA9IChxPT1udWxsKT9uYmkoKTpxOw0KICB5LmRsU2hpZnRUbyhqLHQpOw0KICBpZihyLmNvbXBhcmVUbyh0KSA+PSAwKSB7DQogICAgcltyLnQrK10gPSAxOw0KICAgIHIuc3ViVG8odCxyKTsNCiAgfQ0KICBCaWdJbnRlZ2VyLk9ORS5kbFNoaWZ0VG8oeXMsdCk7DQogIHQuc3ViVG8oeSx5KTsJLy8gIm5lZ2F0aXZlIiB5IHNvIHdlIGNhbiByZXBsYWNlIHN1YiB3aXRoIGFtIGxhdGVyDQogIHdoaWxlKHkudCA8IHlzKSB5W3kudCsrXSA9IDA7DQogIHdoaWxlKC0taiA+PSAwKSB7DQogICAgLy8gRXN0aW1hdGUgcXVvdGllbnQgZGlnaXQNCiAgICB2YXIgcWQgPSAoclstLWldPT15MCk/dGhpcy5ETTpNYXRoLmZsb29yKHJbaV0qZDErKHJbaS0xXStlKSpkMik7DQogICAgaWYoKHJbaV0rPXkuYW0oMCxxZCxyLGosMCx5cykpIDwgcWQpIHsJLy8gVHJ5IGl0IG91dA0KICAgICAgeS5kbFNoaWZ0VG8oaix0KTsNCiAgICAgIHIuc3ViVG8odCxyKTsNCiAgICAgIHdoaWxlKHJbaV0gPCAtLXFkKSByLnN1YlRvKHQscik7DQogICAgfQ0KICB9DQogIGlmKHEgIT0gbnVsbCkgew0KICAgIHIuZHJTaGlmdFRvKHlzLHEpOw0KICAgIGlmKHRzICE9IG1zKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8ocSxxKTsNCiAgfQ0KICByLnQgPSB5czsNCiAgci5jbGFtcCgpOw0KICBpZihuc2ggPiAwKSByLnJTaGlmdFRvKG5zaCxyKTsJLy8gRGVub3JtYWxpemUgcmVtYWluZGVyDQogIGlmKHRzIDwgMCkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHIscik7DQp9DQoNCi8vIChwdWJsaWMpIHRoaXMgbW9kIGENCmZ1bmN0aW9uIGJuTW9kKGEpIHsNCiAgdmFyIHIgPSBuYmkoKTsNCiAgdGhpcy5hYnMoKS5kaXZSZW1UbyhhLG51bGwscik7DQogIGlmKHRoaXMucyA8IDAgJiYgci5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSA+IDApIGEuc3ViVG8ocixyKTsNCiAgcmV0dXJuIHI7DQp9DQoNCi8vIE1vZHVsYXIgcmVkdWN0aW9uIHVzaW5nICJjbGFzc2ljIiBhbGdvcml0aG0NCmZ1bmN0aW9uIENsYXNzaWMobSkgeyB0aGlzLm0gPSBtOyB9DQpmdW5jdGlvbiBjQ29udmVydCh4KSB7DQogIGlmKHgucyA8IDAgfHwgeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSByZXR1cm4geC5tb2QodGhpcy5tKTsNCiAgZWxzZSByZXR1cm4geDsNCn0NCmZ1bmN0aW9uIGNSZXZlcnQoeCkgeyByZXR1cm4geDsgfQ0KZnVuY3Rpb24gY1JlZHVjZSh4KSB7IHguZGl2UmVtVG8odGhpcy5tLG51bGwseCk7IH0NCmZ1bmN0aW9uIGNNdWxUbyh4LHkscikgeyB4Lm11bHRpcGx5VG8oeSxyKTsgdGhpcy5yZWR1Y2Uocik7IH0NCmZ1bmN0aW9uIGNTcXJUbyh4LHIpIHsgeC5zcXVhcmVUbyhyKTsgdGhpcy5yZWR1Y2Uocik7IH0NCg0KQ2xhc3NpYy5wcm90b3R5cGUuY29udmVydCA9IGNDb252ZXJ0Ow0KQ2xhc3NpYy5wcm90b3R5cGUucmV2ZXJ0ID0gY1JldmVydDsNCkNsYXNzaWMucHJvdG90eXBlLnJlZHVjZSA9IGNSZWR1Y2U7DQpDbGFzc2ljLnByb3RvdHlwZS5tdWxUbyA9IGNNdWxUbzsNCkNsYXNzaWMucHJvdG90eXBlLnNxclRvID0gY1NxclRvOw0KDQovLyAocHJvdGVjdGVkKSByZXR1cm4gIi0xL3RoaXMgJSAyXkRCIjsgdXNlZnVsIGZvciBNb250LiByZWR1Y3Rpb24NCi8vIGp1c3RpZmljYXRpb246DQovLyAgICAgICAgIHh5ID09IDEgKG1vZCBtKQ0KLy8gICAgICAgICB4eSA9ICAxK2ttDQovLyAgIHh5KDIteHkpID0gKDEra20pKDEta20pDQovLyB4W3koMi14eSldID0gMS1rXjJtXjINCi8vIHhbeSgyLXh5KV0gPT0gMSAobW9kIG1eMikNCi8vIGlmIHkgaXMgMS94IG1vZCBtLCB0aGVuIHkoMi14eSkgaXMgMS94IG1vZCBtXjINCi8vIHNob3VsZCByZWR1Y2UgeCBhbmQgeSgyLXh5KSBieSBtXjIgYXQgZWFjaCBzdGVwIHRvIGtlZXAgc2l6ZSBib3VuZGVkLg0KLy8gSlMgbXVsdGlwbHkgIm92ZXJmbG93cyIgZGlmZmVyZW50bHkgZnJvbSBDL0MrKywgc28gY2FyZSBpcyBuZWVkZWQgaGVyZS4NCmZ1bmN0aW9uIGJucEludkRpZ2l0KCkgew0KICBpZih0aGlzLnQgPCAxKSByZXR1cm4gMDsNCiAgdmFyIHggPSB0aGlzWzBdOw0KICBpZigoeCYxKSA9PSAwKSByZXR1cm4gMDsNCiAgdmFyIHkgPSB4JjM7CQkvLyB5ID09IDEveCBtb2QgMl4yDQogIHkgPSAoeSooMi0oeCYweGYpKnkpKSYweGY7CS8vIHkgPT0gMS94IG1vZCAyXjQNCiAgeSA9ICh5KigyLSh4JjB4ZmYpKnkpKSYweGZmOwkvLyB5ID09IDEveCBtb2QgMl44DQogIHkgPSAoeSooMi0oKCh4JjB4ZmZmZikqeSkmMHhmZmZmKSkpJjB4ZmZmZjsJLy8geSA9PSAxL3ggbW9kIDJeMTYNCiAgLy8gbGFzdCBzdGVwIC0gY2FsY3VsYXRlIGludmVyc2UgbW9kIERWIGRpcmVjdGx5Ow0KICAvLyBhc3N1bWVzIDE2IDwgREIgPD0gMzIgYW5kIGFzc3VtZXMgYWJpbGl0eSB0byBoYW5kbGUgNDgtYml0IGludHMNCiAgeSA9ICh5KigyLXgqeSV0aGlzLkRWKSkldGhpcy5EVjsJCS8vIHkgPT0gMS94IG1vZCAyXmRiaXRzDQogIC8vIHdlIHJlYWxseSB3YW50IHRoZSBuZWdhdGl2ZSBpbnZlcnNlLCBhbmQgLURWIDwgeSA8IERWDQogIHJldHVybiAoeT4wKT90aGlzLkRWLXk6LXk7DQp9DQoNCi8vIE1vbnRnb21lcnkgcmVkdWN0aW9uDQpmdW5jdGlvbiBNb250Z29tZXJ5KG0pIHsNCiAgdGhpcy5tID0gbTsNCiAgdGhpcy5tcCA9IG0uaW52RGlnaXQoKTsNCiAgdGhpcy5tcGwgPSB0aGlzLm1wJjB4N2ZmZjsNCiAgdGhpcy5tcGggPSB0aGlzLm1wPj4xNTsNCiAgdGhpcy51bSA9ICgxPDwobS5EQi0xNSkpLTE7DQogIHRoaXMubXQyID0gMiptLnQ7DQp9DQoNCi8vIHhSIG1vZCBtDQpmdW5jdGlvbiBtb250Q29udmVydCh4KSB7DQogIHZhciByID0gbmJpKCk7DQogIHguYWJzKCkuZGxTaGlmdFRvKHRoaXMubS50LHIpOw0KICByLmRpdlJlbVRvKHRoaXMubSxudWxsLHIpOw0KICBpZih4LnMgPCAwICYmIHIuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgPiAwKSB0aGlzLm0uc3ViVG8ocixyKTsNCiAgcmV0dXJuIHI7DQp9DQoNCi8vIHgvUiBtb2QgbQ0KZnVuY3Rpb24gbW9udFJldmVydCh4KSB7DQogIHZhciByID0gbmJpKCk7DQogIHguY29weVRvKHIpOw0KICB0aGlzLnJlZHVjZShyKTsNCiAgcmV0dXJuIHI7DQp9DQoNCi8vIHggPSB4L1IgbW9kIG0gKEhBQyAxNC4zMikNCmZ1bmN0aW9uIG1vbnRSZWR1Y2UoeCkgew0KICB3aGlsZSh4LnQgPD0gdGhpcy5tdDIpCS8vIHBhZCB4IHNvIGFtIGhhcyBlbm91Z2ggcm9vbSBsYXRlcg0KICAgIHhbeC50KytdID0gMDsNCiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMubS50OyArK2kpIHsNCiAgICAvLyBmYXN0ZXIgd2F5IG9mIGNhbGN1bGF0aW5nIHUwID0geFtpXSptcCBtb2QgRFYNCiAgICB2YXIgaiA9IHhbaV0mMHg3ZmZmOw0KICAgIHZhciB1MCA9IChqKnRoaXMubXBsKygoKGoqdGhpcy5tcGgrKHhbaV0+PjE1KSp0aGlzLm1wbCkmdGhpcy51bSk8PDE1KSkmeC5ETTsNCiAgICAvLyB1c2UgYW0gdG8gY29tYmluZSB0aGUgbXVsdGlwbHktc2hpZnQtYWRkIGludG8gb25lIGNhbGwNCiAgICBqID0gaSt0aGlzLm0udDsNCiAgICB4W2pdICs9IHRoaXMubS5hbSgwLHUwLHgsaSwwLHRoaXMubS50KTsNCiAgICAvLyBwcm9wYWdhdGUgY2FycnkNCiAgICB3aGlsZSh4W2pdID49IHguRFYpIHsgeFtqXSAtPSB4LkRWOyB4Wysral0rKzsgfQ0KICB9DQogIHguY2xhbXAoKTsNCiAgeC5kclNoaWZ0VG8odGhpcy5tLnQseCk7DQogIGlmKHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgeC5zdWJUbyh0aGlzLm0seCk7DQp9DQoNCi8vIHIgPSAieF4yL1IgbW9kIG0iOyB4ICE9IHINCmZ1bmN0aW9uIG1vbnRTcXJUbyh4LHIpIHsgeC5zcXVhcmVUbyhyKTsgdGhpcy5yZWR1Y2Uocik7IH0NCg0KLy8gciA9ICJ4eS9SIG1vZCBtIjsgeCx5ICE9IHINCmZ1bmN0aW9uIG1vbnRNdWxUbyh4LHkscikgeyB4Lm11bHRpcGx5VG8oeSxyKTsgdGhpcy5yZWR1Y2Uocik7IH0NCg0KTW9udGdvbWVyeS5wcm90b3R5cGUuY29udmVydCA9IG1vbnRDb252ZXJ0Ow0KTW9udGdvbWVyeS5wcm90b3R5cGUucmV2ZXJ0ID0gbW9udFJldmVydDsNCk1vbnRnb21lcnkucHJvdG90eXBlLnJlZHVjZSA9IG1vbnRSZWR1Y2U7DQpNb250Z29tZXJ5LnByb3RvdHlwZS5tdWxUbyA9IG1vbnRNdWxUbzsNCk1vbnRnb21lcnkucHJvdG90eXBlLnNxclRvID0gbW9udFNxclRvOw0KDQovLyAocHJvdGVjdGVkKSB0cnVlIGlmZiB0aGlzIGlzIGV2ZW4NCmZ1bmN0aW9uIGJucElzRXZlbigpIHsgcmV0dXJuICgodGhpcy50PjApPyh0aGlzWzBdJjEpOnRoaXMucykgPT0gMDsgfQ0KDQovLyAocHJvdGVjdGVkKSB0aGlzXmUsIGUgPCAyXjMyLCBkb2luZyBzcXIgYW5kIG11bCB3aXRoICJyIiAoSEFDIDE0Ljc5KQ0KZnVuY3Rpb24gYm5wRXhwKGUseikgew0KICBpZihlID4gMHhmZmZmZmZmZiB8fCBlIDwgMSkgcmV0dXJuIEJpZ0ludGVnZXIuT05FOw0KICB2YXIgciA9IG5iaSgpLCByMiA9IG5iaSgpLCBnID0gei5jb252ZXJ0KHRoaXMpLCBpID0gbmJpdHMoZSktMTsNCiAgZy5jb3B5VG8ocik7DQogIHdoaWxlKC0taSA+PSAwKSB7DQogICAgei5zcXJUbyhyLHIyKTsNCiAgICBpZigoZSYoMTw8aSkpID4gMCkgei5tdWxUbyhyMixnLHIpOw0KICAgIGVsc2UgeyB2YXIgdCA9IHI7IHIgPSByMjsgcjIgPSB0OyB9DQogIH0NCiAgcmV0dXJuIHoucmV2ZXJ0KHIpOw0KfQ0KDQovLyAocHVibGljKSB0aGlzXmUgJSBtLCAwIDw9IGUgPCAyXjMyDQpmdW5jdGlvbiBibk1vZFBvd0ludChlLG0pIHsNCiAgdmFyIHo7DQogIGlmKGUgPCAyNTYgfHwgbS5pc0V2ZW4oKSkgeiA9IG5ldyBDbGFzc2ljKG0pOyBlbHNlIHogPSBuZXcgTW9udGdvbWVyeShtKTsNCiAgcmV0dXJuIHRoaXMuZXhwKGUseik7DQp9DQoNCi8vIHByb3RlY3RlZA0KQmlnSW50ZWdlci5wcm90b3R5cGUuY29weVRvID0gYm5wQ29weVRvOw0KQmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbUludCA9IGJucEZyb21JbnQ7DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tU3RyaW5nID0gYm5wRnJvbVN0cmluZzsNCkJpZ0ludGVnZXIucHJvdG90eXBlLmNsYW1wID0gYm5wQ2xhbXA7DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kbFNoaWZ0VG8gPSBibnBETFNoaWZ0VG87DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kclNoaWZ0VG8gPSBibnBEUlNoaWZ0VG87DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5sU2hpZnRUbyA9IGJucExTaGlmdFRvOw0KQmlnSW50ZWdlci5wcm90b3R5cGUuclNoaWZ0VG8gPSBibnBSU2hpZnRUbzsNCkJpZ0ludGVnZXIucHJvdG90eXBlLnN1YlRvID0gYm5wU3ViVG87DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseVRvID0gYm5wTXVsdGlwbHlUbzsNCkJpZ0ludGVnZXIucHJvdG90eXBlLnNxdWFyZVRvID0gYm5wU3F1YXJlVG87DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZSZW1UbyA9IGJucERpdlJlbVRvOw0KQmlnSW50ZWdlci5wcm90b3R5cGUuaW52RGlnaXQgPSBibnBJbnZEaWdpdDsNCkJpZ0ludGVnZXIucHJvdG90eXBlLmlzRXZlbiA9IGJucElzRXZlbjsNCkJpZ0ludGVnZXIucHJvdG90eXBlLmV4cCA9IGJucEV4cDsNCg0KLy8gcHVibGljDQpCaWdJbnRlZ2VyLnByb3RvdHlwZS50b1N0cmluZyA9IGJuVG9TdHJpbmc7DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5uZWdhdGUgPSBibk5lZ2F0ZTsNCkJpZ0ludGVnZXIucHJvdG90eXBlLmFicyA9IGJuQWJzOw0KQmlnSW50ZWdlci5wcm90b3R5cGUuY29tcGFyZVRvID0gYm5Db21wYXJlVG87DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXRMZW5ndGggPSBibkJpdExlbmd0aDsNCkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZCA9IGJuTW9kOw0KQmlnSW50ZWdlci5wcm90b3R5cGUubW9kUG93SW50ID0gYm5Nb2RQb3dJbnQ7DQoNCi8vICJjb25zdGFudHMiDQpCaWdJbnRlZ2VyLlpFUk8gPSBuYnYoMCk7DQpCaWdJbnRlZ2VyLk9ORSA9IG5idigxKTsNCg0KLyoNCiAqIENvcHlyaWdodCAoYykgMjAwMy0yMDA1ICBUb20gV3UgKHRqd0Bjcy5TdGFuZm9yZC5FRFUpIA0KICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4NCiAqDQogKiBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkgNCiAqDQogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcNCiAqIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZQ0KICogIlNvZnR3YXJlIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZw0KICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLA0KICogZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvDQogKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8NCiAqIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoNCiAqDQogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZQ0KICogaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuDQogKg0KICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUy1JUyIgQU5EIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIA0KICogRVhQUkVTUywgSU1QTElFRCBPUiBPVEhFUldJU0UsIElOQ0xVRElORyBXSVRIT1VUIExJTUlUQVRJT04sIEFOWSANCiAqIFdBUlJBTlRZIE9GIE1FUkNIQU5UQUJJTElUWSBPUiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIA0KICoNCiAqIElOIE5PIEVWRU5UIFNIQUxMIFRPTSBXVSBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkNJREVOVEFMLA0KICogSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9GIEFOWSBLSU5ELCBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSDQogKiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIE9SIE5PVCBBRFZJU0VEIE9GDQogKiBUSEUgUE9TU0lCSUxJVFkgT0YgREFNQUdFLCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIEFSSVNJTkcgT1VUDQogKiBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLg0KICoNCiAqIEluIGFkZGl0aW9uLCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbiBhcHBsaWVzOg0KICoNCiAqIEFsbCByZWRpc3RyaWJ1dGlvbnMgbXVzdCByZXRhaW4gYW4gaW50YWN0IGNvcHkgb2YgdGhpcyBjb3B5cmlnaHQgbm90aWNlDQogKiBhbmQgZGlzY2xhaW1lci4NCiAqLw0KLy8gRXh0ZW5kZWQgSmF2YVNjcmlwdCBCTiBmdW5jdGlvbnMsIHJlcXVpcmVkIGZvciBSU0EgcHJpdmF0ZSBvcHMuDQoNCi8vIFZlcnNpb24gMS4xOiBuZXcgQmlnSW50ZWdlcigiMCIsIDEwKSByZXR1cm5zICJwcm9wZXIiIHplcm8NCi8vIFZlcnNpb24gMS4yOiBzcXVhcmUoKSBBUEksIGlzUHJvYmFibGVQcmltZSBmaXgNCg0KLy8gKHB1YmxpYykNCmZ1bmN0aW9uIGJuQ2xvbmUoKSB7IHZhciByID0gbmJpKCk7IHRoaXMuY29weVRvKHIpOyByZXR1cm4gcjsgfQ0KDQovLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgaW50ZWdlcg0KZnVuY3Rpb24gYm5JbnRWYWx1ZSgpIHsNCiAgaWYodGhpcy5zIDwgMCkgew0KICAgIGlmKHRoaXMudCA9PSAxKSByZXR1cm4gdGhpc1swXS10aGlzLkRWOw0KICAgIGVsc2UgaWYodGhpcy50ID09IDApIHJldHVybiAtMTsNCiAgfQ0KICBlbHNlIGlmKHRoaXMudCA9PSAxKSByZXR1cm4gdGhpc1swXTsNCiAgZWxzZSBpZih0aGlzLnQgPT0gMCkgcmV0dXJuIDA7DQogIC8vIGFzc3VtZXMgMTYgPCBEQiA8IDMyDQogIHJldHVybiAoKHRoaXNbMV0mKCgxPDwoMzItdGhpcy5EQikpLTEpKTw8dGhpcy5EQil8dGhpc1swXTsNCn0NCg0KLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGJ5dGUNCmZ1bmN0aW9uIGJuQnl0ZVZhbHVlKCkgeyByZXR1cm4gKHRoaXMudD09MCk/dGhpcy5zOih0aGlzWzBdPDwyNCk+PjI0OyB9DQoNCi8vIChwdWJsaWMpIHJldHVybiB2YWx1ZSBhcyBzaG9ydCAoYXNzdW1lcyBEQj49MTYpDQpmdW5jdGlvbiBiblNob3J0VmFsdWUoKSB7IHJldHVybiAodGhpcy50PT0wKT90aGlzLnM6KHRoaXNbMF08PDE2KT4+MTY7IH0NCg0KLy8gKHByb3RlY3RlZCkgcmV0dXJuIHggcy50LiByXnggPCBEVg0KZnVuY3Rpb24gYm5wQ2h1bmtTaXplKHIpIHsgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5MTjIqdGhpcy5EQi9NYXRoLmxvZyhyKSk7IH0NCg0KLy8gKHB1YmxpYykgMCBpZiB0aGlzID09IDAsIDEgaWYgdGhpcyA+IDANCmZ1bmN0aW9uIGJuU2lnTnVtKCkgew0KICBpZih0aGlzLnMgPCAwKSByZXR1cm4gLTE7DQogIGVsc2UgaWYodGhpcy50IDw9IDAgfHwgKHRoaXMudCA9PSAxICYmIHRoaXNbMF0gPD0gMCkpIHJldHVybiAwOw0KICBlbHNlIHJldHVybiAxOw0KfQ0KDQovLyAocHJvdGVjdGVkKSBjb252ZXJ0IHRvIHJhZGl4IHN0cmluZw0KZnVuY3Rpb24gYm5wVG9SYWRpeChiKSB7DQogIGlmKGIgPT0gbnVsbCkgYiA9IDEwOw0KICBpZih0aGlzLnNpZ251bSgpID09IDAgfHwgYiA8IDIgfHwgYiA+IDM2KSByZXR1cm4gIjAiOw0KICB2YXIgY3MgPSB0aGlzLmNodW5rU2l6ZShiKTsNCiAgdmFyIGEgPSBNYXRoLnBvdyhiLGNzKTsNCiAgdmFyIGQgPSBuYnYoYSksIHkgPSBuYmkoKSwgeiA9IG5iaSgpLCByID0gIiI7DQogIHRoaXMuZGl2UmVtVG8oZCx5LHopOw0KICB3aGlsZSh5LnNpZ251bSgpID4gMCkgew0KICAgIHIgPSAoYSt6LmludFZhbHVlKCkpLnRvU3RyaW5nKGIpLnN1YnN0cigxKSArIHI7DQogICAgeS5kaXZSZW1UbyhkLHkseik7DQogIH0NCiAgcmV0dXJuIHouaW50VmFsdWUoKS50b1N0cmluZyhiKSArIHI7DQp9DQoNCi8vIChwcm90ZWN0ZWQpIGNvbnZlcnQgZnJvbSByYWRpeCBzdHJpbmcNCmZ1bmN0aW9uIGJucEZyb21SYWRpeChzLGIpIHsNCiAgdGhpcy5mcm9tSW50KDApOw0KICBpZihiID09IG51bGwpIGIgPSAxMDsNCiAgdmFyIGNzID0gdGhpcy5jaHVua1NpemUoYik7DQogIHZhciBkID0gTWF0aC5wb3coYixjcyksIG1pID0gZmFsc2UsIGogPSAwLCB3ID0gMDsNCiAgZm9yKHZhciBpID0gMDsgaSA8IHMubGVuZ3RoOyArK2kpIHsNCiAgICB2YXIgeCA9IGludEF0KHMsaSk7DQogICAgaWYoeCA8IDApIHsNCiAgICAgIGlmKHMuY2hhckF0KGkpID09ICItIiAmJiB0aGlzLnNpZ251bSgpID09IDApIG1pID0gdHJ1ZTsNCiAgICAgIGNvbnRpbnVlOw0KICAgIH0NCiAgICB3ID0gYip3K3g7DQogICAgaWYoKytqID49IGNzKSB7DQogICAgICB0aGlzLmRNdWx0aXBseShkKTsNCiAgICAgIHRoaXMuZEFkZE9mZnNldCh3LDApOw0KICAgICAgaiA9IDA7DQogICAgICB3ID0gMDsNCiAgICB9DQogIH0NCiAgaWYoaiA+IDApIHsNCiAgICB0aGlzLmRNdWx0aXBseShNYXRoLnBvdyhiLGopKTsNCiAgICB0aGlzLmRBZGRPZmZzZXQodywwKTsNCiAgfQ0KICBpZihtaSkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsdGhpcyk7DQp9DQoNCi8vIChwcm90ZWN0ZWQpIGFsdGVybmF0ZSBjb25zdHJ1Y3Rvcg0KZnVuY3Rpb24gYm5wRnJvbU51bWJlcihhLGIsYykgew0KICBpZigibnVtYmVyIiA9PSB0eXBlb2YgYikgew0KICAgIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxpbnQsUk5HKQ0KICAgIGlmKGEgPCAyKSB0aGlzLmZyb21JbnQoMSk7DQogICAgZWxzZSB7DQogICAgICB0aGlzLmZyb21OdW1iZXIoYSxjKTsNCiAgICAgIGlmKCF0aGlzLnRlc3RCaXQoYS0xKSkJLy8gZm9yY2UgTVNCIHNldA0KICAgICAgICB0aGlzLmJpdHdpc2VUbyhCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQoYS0xKSxvcF9vcix0aGlzKTsNCiAgICAgIGlmKHRoaXMuaXNFdmVuKCkpIHRoaXMuZEFkZE9mZnNldCgxLDApOyAvLyBmb3JjZSBvZGQNCiAgICAgIHdoaWxlKCF0aGlzLmlzUHJvYmFibGVQcmltZShiKSkgew0KICAgICAgICB0aGlzLmRBZGRPZmZzZXQoMiwwKTsNCiAgICAgICAgaWYodGhpcy5iaXRMZW5ndGgoKSA+IGEpIHRoaXMuc3ViVG8oQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGEtMSksdGhpcyk7DQogICAgICB9DQogICAgfQ0KICB9DQogIGVsc2Ugew0KICAgIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxSTkcpDQogICAgdmFyIHggPSBuZXcgQXJyYXkoKSwgdCA9IGEmNzsNCiAgICB4Lmxlbmd0aCA9IChhPj4zKSsxOw0KICAgIGIubmV4dEJ5dGVzKHgpOw0KICAgIGlmKHQgPiAwKSB4WzBdICY9ICgoMTw8dCktMSk7IGVsc2UgeFswXSA9IDA7DQogICAgdGhpcy5mcm9tU3RyaW5nKHgsMjU2KTsNCiAgfQ0KfQ0KDQovLyAocHVibGljKSBjb252ZXJ0IHRvIGJpZ2VuZGlhbiBieXRlIGFycmF5DQpmdW5jdGlvbiBiblRvQnl0ZUFycmF5KCkgew0KICB2YXIgaSA9IHRoaXMudCwgciA9IG5ldyBBcnJheSgpOw0KICByWzBdID0gdGhpcy5zOw0KICB2YXIgcCA9IHRoaXMuREItKGkqdGhpcy5EQiklOCwgZCwgayA9IDA7DQogIGlmKGktLSA+IDApIHsNCiAgICBpZihwIDwgdGhpcy5EQiAmJiAoZCA9IHRoaXNbaV0+PnApICE9ICh0aGlzLnMmdGhpcy5ETSk+PnApDQogICAgICByW2srK10gPSBkfCh0aGlzLnM8PCh0aGlzLkRCLXApKTsNCiAgICB3aGlsZShpID49IDApIHsNCiAgICAgIGlmKHAgPCA4KSB7DQogICAgICAgIGQgPSAodGhpc1tpXSYoKDE8PHApLTEpKTw8KDgtcCk7DQogICAgICAgIGQgfD0gdGhpc1stLWldPj4ocCs9dGhpcy5EQi04KTsNCiAgICAgIH0NCiAgICAgIGVsc2Ugew0KICAgICAgICBkID0gKHRoaXNbaV0+PihwLT04KSkmMHhmZjsNCiAgICAgICAgaWYocCA8PSAwKSB7IHAgKz0gdGhpcy5EQjsgLS1pOyB9DQogICAgICB9DQogICAgICAvL2lmKChkJjB4ODApICE9IDApIGQgfD0gLTI1NjsNCiAgICAgIC8vaWYoayA9PSAwICYmICh0aGlzLnMmMHg4MCkgIT0gKGQmMHg4MCkpICsrazsNCiAgICAgIGlmKGsgPiAwIHx8IGQgIT0gdGhpcy5zKSByW2srK10gPSBkOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gcjsNCn0NCg0KZnVuY3Rpb24gYm5FcXVhbHMoYSkgeyByZXR1cm4odGhpcy5jb21wYXJlVG8oYSk9PTApOyB9DQpmdW5jdGlvbiBibk1pbihhKSB7IHJldHVybih0aGlzLmNvbXBhcmVUbyhhKTwwKT90aGlzOmE7IH0NCmZ1bmN0aW9uIGJuTWF4KGEpIHsgcmV0dXJuKHRoaXMuY29tcGFyZVRvKGEpPjApP3RoaXM6YTsgfQ0KDQovLyAocHJvdGVjdGVkKSByID0gdGhpcyBvcCBhIChiaXR3aXNlKQ0KZnVuY3Rpb24gYm5wQml0d2lzZVRvKGEsb3Ascikgew0KICB2YXIgaSwgZiwgbSA9IE1hdGgubWluKGEudCx0aGlzLnQpOw0KICBmb3IoaSA9IDA7IGkgPCBtOyArK2kpIHJbaV0gPSBvcCh0aGlzW2ldLGFbaV0pOw0KICBpZihhLnQgPCB0aGlzLnQpIHsNCiAgICBmID0gYS5zJnRoaXMuRE07DQogICAgZm9yKGkgPSBtOyBpIDwgdGhpcy50OyArK2kpIHJbaV0gPSBvcCh0aGlzW2ldLGYpOw0KICAgIHIudCA9IHRoaXMudDsNCiAgfQ0KICBlbHNlIHsNCiAgICBmID0gdGhpcy5zJnRoaXMuRE07DQogICAgZm9yKGkgPSBtOyBpIDwgYS50OyArK2kpIHJbaV0gPSBvcChmLGFbaV0pOw0KICAgIHIudCA9IGEudDsNCiAgfQ0KICByLnMgPSBvcCh0aGlzLnMsYS5zKTsNCiAgci5jbGFtcCgpOw0KfQ0KDQovLyAocHVibGljKSB0aGlzICYgYQ0KZnVuY3Rpb24gb3BfYW5kKHgseSkgeyByZXR1cm4geCZ5OyB9DQpmdW5jdGlvbiBibkFuZChhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuYml0d2lzZVRvKGEsb3BfYW5kLHIpOyByZXR1cm4gcjsgfQ0KDQovLyAocHVibGljKSB0aGlzIHwgYQ0KZnVuY3Rpb24gb3Bfb3IoeCx5KSB7IHJldHVybiB4fHk7IH0NCmZ1bmN0aW9uIGJuT3IoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLmJpdHdpc2VUbyhhLG9wX29yLHIpOyByZXR1cm4gcjsgfQ0KDQovLyAocHVibGljKSB0aGlzIF4gYQ0KZnVuY3Rpb24gb3BfeG9yKHgseSkgeyByZXR1cm4geF55OyB9DQpmdW5jdGlvbiBiblhvcihhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuYml0d2lzZVRvKGEsb3BfeG9yLHIpOyByZXR1cm4gcjsgfQ0KDQovLyAocHVibGljKSB0aGlzICYgfmENCmZ1bmN0aW9uIG9wX2FuZG5vdCh4LHkpIHsgcmV0dXJuIHgmfnk7IH0NCmZ1bmN0aW9uIGJuQW5kTm90KGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF9hbmRub3Qscik7IHJldHVybiByOyB9DQoNCi8vIChwdWJsaWMpIH50aGlzDQpmdW5jdGlvbiBibk5vdCgpIHsNCiAgdmFyIHIgPSBuYmkoKTsNCiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKSByW2ldID0gdGhpcy5ETSZ+dGhpc1tpXTsNCiAgci50ID0gdGhpcy50Ow0KICByLnMgPSB+dGhpcy5zOw0KICByZXR1cm4gcjsNCn0NCg0KLy8gKHB1YmxpYykgdGhpcyA8PCBuDQpmdW5jdGlvbiBiblNoaWZ0TGVmdChuKSB7DQogIHZhciByID0gbmJpKCk7DQogIGlmKG4gPCAwKSB0aGlzLnJTaGlmdFRvKC1uLHIpOyBlbHNlIHRoaXMubFNoaWZ0VG8obixyKTsNCiAgcmV0dXJuIHI7DQp9DQoNCi8vIChwdWJsaWMpIHRoaXMgPj4gbg0KZnVuY3Rpb24gYm5TaGlmdFJpZ2h0KG4pIHsNCiAgdmFyIHIgPSBuYmkoKTsNCiAgaWYobiA8IDApIHRoaXMubFNoaWZ0VG8oLW4scik7IGVsc2UgdGhpcy5yU2hpZnRUbyhuLHIpOw0KICByZXR1cm4gcjsNCn0NCg0KLy8gcmV0dXJuIGluZGV4IG9mIGxvd2VzdCAxLWJpdCBpbiB4LCB4IDwgMl4zMQ0KZnVuY3Rpb24gbGJpdCh4KSB7DQogIGlmKHggPT0gMCkgcmV0dXJuIC0xOw0KICB2YXIgciA9IDA7DQogIGlmKCh4JjB4ZmZmZikgPT0gMCkgeyB4ID4+PSAxNjsgciArPSAxNjsgfQ0KICBpZigoeCYweGZmKSA9PSAwKSB7IHggPj49IDg7IHIgKz0gODsgfQ0KICBpZigoeCYweGYpID09IDApIHsgeCA+Pj0gNDsgciArPSA0OyB9DQogIGlmKCh4JjMpID09IDApIHsgeCA+Pj0gMjsgciArPSAyOyB9DQogIGlmKCh4JjEpID09IDApICsrcjsNCiAgcmV0dXJuIHI7DQp9DQoNCi8vIChwdWJsaWMpIHJldHVybnMgaW5kZXggb2YgbG93ZXN0IDEtYml0IChvciAtMSBpZiBub25lKQ0KZnVuY3Rpb24gYm5HZXRMb3dlc3RTZXRCaXQoKSB7DQogIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLnQ7ICsraSkNCiAgICBpZih0aGlzW2ldICE9IDApIHJldHVybiBpKnRoaXMuREIrbGJpdCh0aGlzW2ldKTsNCiAgaWYodGhpcy5zIDwgMCkgcmV0dXJuIHRoaXMudCp0aGlzLkRCOw0KICByZXR1cm4gLTE7DQp9DQoNCi8vIHJldHVybiBudW1iZXIgb2YgMSBiaXRzIGluIHgNCmZ1bmN0aW9uIGNiaXQoeCkgew0KICB2YXIgciA9IDA7DQogIHdoaWxlKHggIT0gMCkgeyB4ICY9IHgtMTsgKytyOyB9DQogIHJldHVybiByOw0KfQ0KDQovLyAocHVibGljKSByZXR1cm4gbnVtYmVyIG9mIHNldCBiaXRzDQpmdW5jdGlvbiBibkJpdENvdW50KCkgew0KICB2YXIgciA9IDAsIHggPSB0aGlzLnMmdGhpcy5ETTsNCiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKSByICs9IGNiaXQodGhpc1tpXV54KTsNCiAgcmV0dXJuIHI7DQp9DQoNCi8vIChwdWJsaWMpIHRydWUgaWZmIG50aCBiaXQgaXMgc2V0DQpmdW5jdGlvbiBiblRlc3RCaXQobikgew0KICB2YXIgaiA9IE1hdGguZmxvb3Iobi90aGlzLkRCKTsNCiAgaWYoaiA+PSB0aGlzLnQpIHJldHVybih0aGlzLnMhPTApOw0KICByZXR1cm4oKHRoaXNbal0mKDE8PChuJXRoaXMuREIpKSkhPTApOw0KfQ0KDQovLyAocHJvdGVjdGVkKSB0aGlzIG9wICgxPDxuKQ0KZnVuY3Rpb24gYm5wQ2hhbmdlQml0KG4sb3ApIHsNCiAgdmFyIHIgPSBCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQobik7DQogIHRoaXMuYml0d2lzZVRvKHIsb3Ascik7DQogIHJldHVybiByOw0KfQ0KDQovLyAocHVibGljKSB0aGlzIHwgKDE8PG4pDQpmdW5jdGlvbiBiblNldEJpdChuKSB7IHJldHVybiB0aGlzLmNoYW5nZUJpdChuLG9wX29yKTsgfQ0KDQovLyAocHVibGljKSB0aGlzICYgfigxPDxuKQ0KZnVuY3Rpb24gYm5DbGVhckJpdChuKSB7IHJldHVybiB0aGlzLmNoYW5nZUJpdChuLG9wX2FuZG5vdCk7IH0NCg0KLy8gKHB1YmxpYykgdGhpcyBeICgxPDxuKQ0KZnVuY3Rpb24gYm5GbGlwQml0KG4pIHsgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sb3BfeG9yKTsgfQ0KDQovLyAocHJvdGVjdGVkKSByID0gdGhpcyArIGENCmZ1bmN0aW9uIGJucEFkZFRvKGEscikgew0KICB2YXIgaSA9IDAsIGMgPSAwLCBtID0gTWF0aC5taW4oYS50LHRoaXMudCk7DQogIHdoaWxlKGkgPCBtKSB7DQogICAgYyArPSB0aGlzW2ldK2FbaV07DQogICAgcltpKytdID0gYyZ0aGlzLkRNOw0KICAgIGMgPj49IHRoaXMuREI7DQogIH0NCiAgaWYoYS50IDwgdGhpcy50KSB7DQogICAgYyArPSBhLnM7DQogICAgd2hpbGUoaSA8IHRoaXMudCkgew0KICAgICAgYyArPSB0aGlzW2ldOw0KICAgICAgcltpKytdID0gYyZ0aGlzLkRNOw0KICAgICAgYyA+Pj0gdGhpcy5EQjsNCiAgICB9DQogICAgYyArPSB0aGlzLnM7DQogIH0NCiAgZWxzZSB7DQogICAgYyArPSB0aGlzLnM7DQogICAgd2hpbGUoaSA8IGEudCkgew0KICAgICAgYyArPSBhW2ldOw0KICAgICAgcltpKytdID0gYyZ0aGlzLkRNOw0KICAgICAgYyA+Pj0gdGhpcy5EQjsNCiAgICB9DQogICAgYyArPSBhLnM7DQogIH0NCiAgci5zID0gKGM8MCk/LTE6MDsNCiAgaWYoYyA+IDApIHJbaSsrXSA9IGM7DQogIGVsc2UgaWYoYyA8IC0xKSByW2krK10gPSB0aGlzLkRWK2M7DQogIHIudCA9IGk7DQogIHIuY2xhbXAoKTsNCn0NCg0KLy8gKHB1YmxpYykgdGhpcyArIGENCmZ1bmN0aW9uIGJuQWRkKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5hZGRUbyhhLHIpOyByZXR1cm4gcjsgfQ0KDQovLyAocHVibGljKSB0aGlzIC0gYQ0KZnVuY3Rpb24gYm5TdWJ0cmFjdChhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuc3ViVG8oYSxyKTsgcmV0dXJuIHI7IH0NCg0KLy8gKHB1YmxpYykgdGhpcyAqIGENCmZ1bmN0aW9uIGJuTXVsdGlwbHkoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLm11bHRpcGx5VG8oYSxyKTsgcmV0dXJuIHI7IH0NCg0KLy8gKHB1YmxpYykgdGhpc14yDQpmdW5jdGlvbiBiblNxdWFyZSgpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5zcXVhcmVUbyhyKTsgcmV0dXJuIHI7IH0NCg0KLy8gKHB1YmxpYykgdGhpcyAvIGENCmZ1bmN0aW9uIGJuRGl2aWRlKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5kaXZSZW1UbyhhLHIsbnVsbCk7IHJldHVybiByOyB9DQoNCi8vIChwdWJsaWMpIHRoaXMgJSBhDQpmdW5jdGlvbiBiblJlbWFpbmRlcihhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuZGl2UmVtVG8oYSxudWxsLHIpOyByZXR1cm4gcjsgfQ0KDQovLyAocHVibGljKSBbdGhpcy9hLHRoaXMlYV0NCmZ1bmN0aW9uIGJuRGl2aWRlQW5kUmVtYWluZGVyKGEpIHsNCiAgdmFyIHEgPSBuYmkoKSwgciA9IG5iaSgpOw0KICB0aGlzLmRpdlJlbVRvKGEscSxyKTsNCiAgcmV0dXJuIG5ldyBBcnJheShxLHIpOw0KfQ0KDQovLyAocHJvdGVjdGVkKSB0aGlzICo9IG4sIHRoaXMgPj0gMCwgMSA8IG4gPCBEVg0KZnVuY3Rpb24gYm5wRE11bHRpcGx5KG4pIHsNCiAgdGhpc1t0aGlzLnRdID0gdGhpcy5hbSgwLG4tMSx0aGlzLDAsMCx0aGlzLnQpOw0KICArK3RoaXMudDsNCiAgdGhpcy5jbGFtcCgpOw0KfQ0KDQovLyAocHJvdGVjdGVkKSB0aGlzICs9IG4gPDwgdyB3b3JkcywgdGhpcyA+PSAwDQpmdW5jdGlvbiBibnBEQWRkT2Zmc2V0KG4sdykgew0KICBpZihuID09IDApIHJldHVybjsNCiAgd2hpbGUodGhpcy50IDw9IHcpIHRoaXNbdGhpcy50KytdID0gMDsNCiAgdGhpc1t3XSArPSBuOw0KICB3aGlsZSh0aGlzW3ddID49IHRoaXMuRFYpIHsNCiAgICB0aGlzW3ddIC09IHRoaXMuRFY7DQogICAgaWYoKyt3ID49IHRoaXMudCkgdGhpc1t0aGlzLnQrK10gPSAwOw0KICAgICsrdGhpc1t3XTsNCiAgfQ0KfQ0KDQovLyBBICJudWxsIiByZWR1Y2VyDQpmdW5jdGlvbiBOdWxsRXhwKCkge30NCmZ1bmN0aW9uIG5Ob3AoeCkgeyByZXR1cm4geDsgfQ0KZnVuY3Rpb24gbk11bFRvKHgseSxyKSB7IHgubXVsdGlwbHlUbyh5LHIpOyB9DQpmdW5jdGlvbiBuU3FyVG8oeCxyKSB7IHguc3F1YXJlVG8ocik7IH0NCg0KTnVsbEV4cC5wcm90b3R5cGUuY29udmVydCA9IG5Ob3A7DQpOdWxsRXhwLnByb3RvdHlwZS5yZXZlcnQgPSBuTm9wOw0KTnVsbEV4cC5wcm90b3R5cGUubXVsVG8gPSBuTXVsVG87DQpOdWxsRXhwLnByb3RvdHlwZS5zcXJUbyA9IG5TcXJUbzsNCg0KLy8gKHB1YmxpYykgdGhpc15lDQpmdW5jdGlvbiBiblBvdyhlKSB7IHJldHVybiB0aGlzLmV4cChlLG5ldyBOdWxsRXhwKCkpOyB9DQoNCi8vIChwcm90ZWN0ZWQpIHIgPSBsb3dlciBuIHdvcmRzIG9mICJ0aGlzICogYSIsIGEudCA8PSBuDQovLyAidGhpcyIgc2hvdWxkIGJlIHRoZSBsYXJnZXIgb25lIGlmIGFwcHJvcHJpYXRlLg0KZnVuY3Rpb24gYm5wTXVsdGlwbHlMb3dlclRvKGEsbixyKSB7DQogIHZhciBpID0gTWF0aC5taW4odGhpcy50K2EudCxuKTsNCiAgci5zID0gMDsgLy8gYXNzdW1lcyBhLHRoaXMgPj0gMA0KICByLnQgPSBpOw0KICB3aGlsZShpID4gMCkgclstLWldID0gMDsNCiAgdmFyIGo7DQogIGZvcihqID0gci50LXRoaXMudDsgaSA8IGo7ICsraSkgcltpK3RoaXMudF0gPSB0aGlzLmFtKDAsYVtpXSxyLGksMCx0aGlzLnQpOw0KICBmb3IoaiA9IE1hdGgubWluKGEudCxuKTsgaSA8IGo7ICsraSkgdGhpcy5hbSgwLGFbaV0scixpLDAsbi1pKTsNCiAgci5jbGFtcCgpOw0KfQ0KDQovLyAocHJvdGVjdGVkKSByID0gInRoaXMgKiBhIiB3aXRob3V0IGxvd2VyIG4gd29yZHMsIG4gPiAwDQovLyAidGhpcyIgc2hvdWxkIGJlIHRoZSBsYXJnZXIgb25lIGlmIGFwcHJvcHJpYXRlLg0KZnVuY3Rpb24gYm5wTXVsdGlwbHlVcHBlclRvKGEsbixyKSB7DQogIC0tbjsNCiAgdmFyIGkgPSByLnQgPSB0aGlzLnQrYS50LW47DQogIHIucyA9IDA7IC8vIGFzc3VtZXMgYSx0aGlzID49IDANCiAgd2hpbGUoLS1pID49IDApIHJbaV0gPSAwOw0KICBmb3IoaSA9IE1hdGgubWF4KG4tdGhpcy50LDApOyBpIDwgYS50OyArK2kpDQogICAgclt0aGlzLnQraS1uXSA9IHRoaXMuYW0obi1pLGFbaV0sciwwLDAsdGhpcy50K2ktbik7DQogIHIuY2xhbXAoKTsNCiAgci5kclNoaWZ0VG8oMSxyKTsNCn0NCg0KLy8gQmFycmV0dCBtb2R1bGFyIHJlZHVjdGlvbg0KZnVuY3Rpb24gQmFycmV0dChtKSB7DQogIC8vIHNldHVwIEJhcnJldHQNCiAgdGhpcy5yMiA9IG5iaSgpOw0KICB0aGlzLnEzID0gbmJpKCk7DQogIEJpZ0ludGVnZXIuT05FLmRsU2hpZnRUbygyKm0udCx0aGlzLnIyKTsNCiAgdGhpcy5tdSA9IHRoaXMucjIuZGl2aWRlKG0pOw0KICB0aGlzLm0gPSBtOw0KfQ0KDQpmdW5jdGlvbiBiYXJyZXR0Q29udmVydCh4KSB7DQogIGlmKHgucyA8IDAgfHwgeC50ID4gMip0aGlzLm0udCkgcmV0dXJuIHgubW9kKHRoaXMubSk7DQogIGVsc2UgaWYoeC5jb21wYXJlVG8odGhpcy5tKSA8IDApIHJldHVybiB4Ow0KICBlbHNlIHsgdmFyIHIgPSBuYmkoKTsgeC5jb3B5VG8ocik7IHRoaXMucmVkdWNlKHIpOyByZXR1cm4gcjsgfQ0KfQ0KDQpmdW5jdGlvbiBiYXJyZXR0UmV2ZXJ0KHgpIHsgcmV0dXJuIHg7IH0NCg0KLy8geCA9IHggbW9kIG0gKEhBQyAxNC40MikNCmZ1bmN0aW9uIGJhcnJldHRSZWR1Y2UoeCkgew0KICB4LmRyU2hpZnRUbyh0aGlzLm0udC0xLHRoaXMucjIpOw0KICBpZih4LnQgPiB0aGlzLm0udCsxKSB7IHgudCA9IHRoaXMubS50KzE7IHguY2xhbXAoKTsgfQ0KICB0aGlzLm11Lm11bHRpcGx5VXBwZXJUbyh0aGlzLnIyLHRoaXMubS50KzEsdGhpcy5xMyk7DQogIHRoaXMubS5tdWx0aXBseUxvd2VyVG8odGhpcy5xMyx0aGlzLm0udCsxLHRoaXMucjIpOw0KICB3aGlsZSh4LmNvbXBhcmVUbyh0aGlzLnIyKSA8IDApIHguZEFkZE9mZnNldCgxLHRoaXMubS50KzEpOw0KICB4LnN1YlRvKHRoaXMucjIseCk7DQogIHdoaWxlKHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgeC5zdWJUbyh0aGlzLm0seCk7DQp9DQoNCi8vIHIgPSB4XjIgbW9kIG07IHggIT0gcg0KZnVuY3Rpb24gYmFycmV0dFNxclRvKHgscikgeyB4LnNxdWFyZVRvKHIpOyB0aGlzLnJlZHVjZShyKTsgfQ0KDQovLyByID0geCp5IG1vZCBtOyB4LHkgIT0gcg0KZnVuY3Rpb24gYmFycmV0dE11bFRvKHgseSxyKSB7IHgubXVsdGlwbHlUbyh5LHIpOyB0aGlzLnJlZHVjZShyKTsgfQ0KDQpCYXJyZXR0LnByb3RvdHlwZS5jb252ZXJ0ID0gYmFycmV0dENvbnZlcnQ7DQpCYXJyZXR0LnByb3RvdHlwZS5yZXZlcnQgPSBiYXJyZXR0UmV2ZXJ0Ow0KQmFycmV0dC5wcm90b3R5cGUucmVkdWNlID0gYmFycmV0dFJlZHVjZTsNCkJhcnJldHQucHJvdG90eXBlLm11bFRvID0gYmFycmV0dE11bFRvOw0KQmFycmV0dC5wcm90b3R5cGUuc3FyVG8gPSBiYXJyZXR0U3FyVG87DQoNCi8vIChwdWJsaWMpIHRoaXNeZSAlIG0gKEhBQyAxNC44NSkNCmZ1bmN0aW9uIGJuTW9kUG93KGUsbSkgew0KICB2YXIgaSA9IGUuYml0TGVuZ3RoKCksIGssIHIgPSBuYnYoMSksIHo7DQogIGlmKGkgPD0gMCkgcmV0dXJuIHI7DQogIGVsc2UgaWYoaSA8IDE4KSBrID0gMTsNCiAgZWxzZSBpZihpIDwgNDgpIGsgPSAzOw0KICBlbHNlIGlmKGkgPCAxNDQpIGsgPSA0Ow0KICBlbHNlIGlmKGkgPCA3NjgpIGsgPSA1Ow0KICBlbHNlIGsgPSA2Ow0KICBpZihpIDwgOCkNCiAgICB6ID0gbmV3IENsYXNzaWMobSk7DQogIGVsc2UgaWYobS5pc0V2ZW4oKSkNCiAgICB6ID0gbmV3IEJhcnJldHQobSk7DQogIGVsc2UNCiAgICB6ID0gbmV3IE1vbnRnb21lcnkobSk7DQoNCiAgLy8gcHJlY29tcHV0YXRpb24NCiAgdmFyIGcgPSBuZXcgQXJyYXkoKSwgbiA9IDMsIGsxID0gay0xLCBrbSA9ICgxPDxrKS0xOw0KICBnWzFdID0gei5jb252ZXJ0KHRoaXMpOw0KICBpZihrID4gMSkgew0KICAgIHZhciBnMiA9IG5iaSgpOw0KICAgIHouc3FyVG8oZ1sxXSxnMik7DQogICAgd2hpbGUobiA8PSBrbSkgew0KICAgICAgZ1tuXSA9IG5iaSgpOw0KICAgICAgei5tdWxUbyhnMixnW24tMl0sZ1tuXSk7DQogICAgICBuICs9IDI7DQogICAgfQ0KICB9DQoNCiAgdmFyIGogPSBlLnQtMSwgdywgaXMxID0gdHJ1ZSwgcjIgPSBuYmkoKSwgdDsNCiAgaSA9IG5iaXRzKGVbal0pLTE7DQogIHdoaWxlKGogPj0gMCkgew0KICAgIGlmKGkgPj0gazEpIHcgPSAoZVtqXT4+KGktazEpKSZrbTsNCiAgICBlbHNlIHsNCiAgICAgIHcgPSAoZVtqXSYoKDE8PChpKzEpKS0xKSk8PChrMS1pKTsNCiAgICAgIGlmKGogPiAwKSB3IHw9IGVbai0xXT4+KHRoaXMuREIraS1rMSk7DQogICAgfQ0KDQogICAgbiA9IGs7DQogICAgd2hpbGUoKHcmMSkgPT0gMCkgeyB3ID4+PSAxOyAtLW47IH0NCiAgICBpZigoaSAtPSBuKSA8IDApIHsgaSArPSB0aGlzLkRCOyAtLWo7IH0NCiAgICBpZihpczEpIHsJLy8gcmV0ID09IDEsIGRvbid0IGJvdGhlciBzcXVhcmluZyBvciBtdWx0aXBseWluZyBpdA0KICAgICAgZ1t3XS5jb3B5VG8ocik7DQogICAgICBpczEgPSBmYWxzZTsNCiAgICB9DQogICAgZWxzZSB7DQogICAgICB3aGlsZShuID4gMSkgeyB6LnNxclRvKHIscjIpOyB6LnNxclRvKHIyLHIpOyBuIC09IDI7IH0NCiAgICAgIGlmKG4gPiAwKSB6LnNxclRvKHIscjIpOyBlbHNlIHsgdCA9IHI7IHIgPSByMjsgcjIgPSB0OyB9DQogICAgICB6Lm11bFRvKHIyLGdbd10scik7DQogICAgfQ0KDQogICAgd2hpbGUoaiA+PSAwICYmIChlW2pdJigxPDxpKSkgPT0gMCkgew0KICAgICAgei5zcXJUbyhyLHIyKTsgdCA9IHI7IHIgPSByMjsgcjIgPSB0Ow0KICAgICAgaWYoLS1pIDwgMCkgeyBpID0gdGhpcy5EQi0xOyAtLWo7IH0NCiAgICB9DQogIH0NCiAgcmV0dXJuIHoucmV2ZXJ0KHIpOw0KfQ0KDQovLyAocHVibGljKSBnY2QodGhpcyxhKSAoSEFDIDE0LjU0KQ0KZnVuY3Rpb24gYm5HQ0QoYSkgew0KICB2YXIgeCA9ICh0aGlzLnM8MCk/dGhpcy5uZWdhdGUoKTp0aGlzLmNsb25lKCk7DQogIHZhciB5ID0gKGEuczwwKT9hLm5lZ2F0ZSgpOmEuY2xvbmUoKTsNCiAgaWYoeC5jb21wYXJlVG8oeSkgPCAwKSB7IHZhciB0ID0geDsgeCA9IHk7IHkgPSB0OyB9DQogIHZhciBpID0geC5nZXRMb3dlc3RTZXRCaXQoKSwgZyA9IHkuZ2V0TG93ZXN0U2V0Qml0KCk7DQogIGlmKGcgPCAwKSByZXR1cm4geDsNCiAgaWYoaSA8IGcpIGcgPSBpOw0KICBpZihnID4gMCkgew0KICAgIHguclNoaWZ0VG8oZyx4KTsNCiAgICB5LnJTaGlmdFRvKGcseSk7DQogIH0NCiAgd2hpbGUoeC5zaWdudW0oKSA+IDApIHsNCiAgICBpZigoaSA9IHguZ2V0TG93ZXN0U2V0Qml0KCkpID4gMCkgeC5yU2hpZnRUbyhpLHgpOw0KICAgIGlmKChpID0geS5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB5LnJTaGlmdFRvKGkseSk7DQogICAgaWYoeC5jb21wYXJlVG8oeSkgPj0gMCkgew0KICAgICAgeC5zdWJUbyh5LHgpOw0KICAgICAgeC5yU2hpZnRUbygxLHgpOw0KICAgIH0NCiAgICBlbHNlIHsNCiAgICAgIHkuc3ViVG8oeCx5KTsNCiAgICAgIHkuclNoaWZ0VG8oMSx5KTsNCiAgICB9DQogIH0NCiAgaWYoZyA+IDApIHkubFNoaWZ0VG8oZyx5KTsNCiAgcmV0dXJuIHk7DQp9DQoNCi8vIChwcm90ZWN0ZWQpIHRoaXMgJSBuLCBuIDwgMl4yNg0KZnVuY3Rpb24gYm5wTW9kSW50KG4pIHsNCiAgaWYobiA8PSAwKSByZXR1cm4gMDsNCiAgdmFyIGQgPSB0aGlzLkRWJW4sIHIgPSAodGhpcy5zPDApP24tMTowOw0KICBpZih0aGlzLnQgPiAwKQ0KICAgIGlmKGQgPT0gMCkgciA9IHRoaXNbMF0lbjsNCiAgICBlbHNlIGZvcih2YXIgaSA9IHRoaXMudC0xOyBpID49IDA7IC0taSkgciA9IChkKnIrdGhpc1tpXSklbjsNCiAgcmV0dXJuIHI7DQp9DQoNCi8vIChwdWJsaWMpIDEvdGhpcyAlIG0gKEhBQyAxNC42MSkNCmZ1bmN0aW9uIGJuTW9kSW52ZXJzZShtKSB7DQogIHZhciBhYyA9IG0uaXNFdmVuKCk7DQogIGlmKCh0aGlzLmlzRXZlbigpICYmIGFjKSB8fCBtLnNpZ251bSgpID09IDApIHJldHVybiBCaWdJbnRlZ2VyLlpFUk87DQogIHZhciB1ID0gbS5jbG9uZSgpLCB2ID0gdGhpcy5jbG9uZSgpOw0KICB2YXIgYSA9IG5idigxKSwgYiA9IG5idigwKSwgYyA9IG5idigwKSwgZCA9IG5idigxKTsNCiAgd2hpbGUodS5zaWdudW0oKSAhPSAwKSB7DQogICAgd2hpbGUodS5pc0V2ZW4oKSkgew0KICAgICAgdS5yU2hpZnRUbygxLHUpOw0KICAgICAgaWYoYWMpIHsNCiAgICAgICAgaWYoIWEuaXNFdmVuKCkgfHwgIWIuaXNFdmVuKCkpIHsgYS5hZGRUbyh0aGlzLGEpOyBiLnN1YlRvKG0sYik7IH0NCiAgICAgICAgYS5yU2hpZnRUbygxLGEpOw0KICAgICAgfQ0KICAgICAgZWxzZSBpZighYi5pc0V2ZW4oKSkgYi5zdWJUbyhtLGIpOw0KICAgICAgYi5yU2hpZnRUbygxLGIpOw0KICAgIH0NCiAgICB3aGlsZSh2LmlzRXZlbigpKSB7DQogICAgICB2LnJTaGlmdFRvKDEsdik7DQogICAgICBpZihhYykgew0KICAgICAgICBpZighYy5pc0V2ZW4oKSB8fCAhZC5pc0V2ZW4oKSkgeyBjLmFkZFRvKHRoaXMsYyk7IGQuc3ViVG8obSxkKTsgfQ0KICAgICAgICBjLnJTaGlmdFRvKDEsYyk7DQogICAgICB9DQogICAgICBlbHNlIGlmKCFkLmlzRXZlbigpKSBkLnN1YlRvKG0sZCk7DQogICAgICBkLnJTaGlmdFRvKDEsZCk7DQogICAgfQ0KICAgIGlmKHUuY29tcGFyZVRvKHYpID49IDApIHsNCiAgICAgIHUuc3ViVG8odix1KTsNCiAgICAgIGlmKGFjKSBhLnN1YlRvKGMsYSk7DQogICAgICBiLnN1YlRvKGQsYik7DQogICAgfQ0KICAgIGVsc2Ugew0KICAgICAgdi5zdWJUbyh1LHYpOw0KICAgICAgaWYoYWMpIGMuc3ViVG8oYSxjKTsNCiAgICAgIGQuc3ViVG8oYixkKTsNCiAgICB9DQogIH0NCiAgaWYodi5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpICE9IDApIHJldHVybiBCaWdJbnRlZ2VyLlpFUk87DQogIGlmKGQuY29tcGFyZVRvKG0pID49IDApIHJldHVybiBkLnN1YnRyYWN0KG0pOw0KICBpZihkLnNpZ251bSgpIDwgMCkgZC5hZGRUbyhtLGQpOyBlbHNlIHJldHVybiBkOw0KICBpZihkLnNpZ251bSgpIDwgMCkgcmV0dXJuIGQuYWRkKG0pOyBlbHNlIHJldHVybiBkOw0KfQ0KDQp2YXIgbG93cHJpbWVzID0gWzIsMyw1LDcsMTEsMTMsMTcsMTksMjMsMjksMzEsMzcsNDEsNDMsNDcsNTMsNTksNjEsNjcsNzEsNzMsNzksODMsODksOTcsMTAxLDEwMywxMDcsMTA5LDExMywxMjcsMTMxLDEzNywxMzksMTQ5LDE1MSwxNTcsMTYzLDE2NywxNzMsMTc5LDE4MSwxOTEsMTkzLDE5NywxOTksMjExLDIyMywyMjcsMjI5LDIzMywyMzksMjQxLDI1MSwyNTcsMjYzLDI2OSwyNzEsMjc3LDI4MSwyODMsMjkzLDMwNywzMTEsMzEzLDMxNywzMzEsMzM3LDM0NywzNDksMzUzLDM1OSwzNjcsMzczLDM3OSwzODMsMzg5LDM5Nyw0MDEsNDA5LDQxOSw0MjEsNDMxLDQzMyw0MzksNDQzLDQ0OSw0NTcsNDYxLDQ2Myw0NjcsNDc5LDQ4Nyw0OTEsNDk5LDUwMyw1MDksNTIxLDUyMyw1NDEsNTQ3LDU1Nyw1NjMsNTY5LDU3MSw1NzcsNTg3LDU5Myw1OTksNjAxLDYwNyw2MTMsNjE3LDYxOSw2MzEsNjQxLDY0Myw2NDcsNjUzLDY1OSw2NjEsNjczLDY3Nyw2ODMsNjkxLDcwMSw3MDksNzE5LDcyNyw3MzMsNzM5LDc0Myw3NTEsNzU3LDc2MSw3NjksNzczLDc4Nyw3OTcsODA5LDgxMSw4MjEsODIzLDgyNyw4MjksODM5LDg1Myw4NTcsODU5LDg2Myw4NzcsODgxLDg4Myw4ODcsOTA3LDkxMSw5MTksOTI5LDkzNyw5NDEsOTQ3LDk1Myw5NjcsOTcxLDk3Nyw5ODMsOTkxLDk5N107DQp2YXIgbHBsaW0gPSAoMTw8MjYpL2xvd3ByaW1lc1tsb3dwcmltZXMubGVuZ3RoLTFdOw0KDQovLyAocHVibGljKSB0ZXN0IHByaW1hbGl0eSB3aXRoIGNlcnRhaW50eSA+PSAxLS41XnQNCmZ1bmN0aW9uIGJuSXNQcm9iYWJsZVByaW1lKHQpIHsNCiAgdmFyIGksIHggPSB0aGlzLmFicygpOw0KICBpZih4LnQgPT0gMSAmJiB4WzBdIDw9IGxvd3ByaW1lc1tsb3dwcmltZXMubGVuZ3RoLTFdKSB7DQogICAgZm9yKGkgPSAwOyBpIDwgbG93cHJpbWVzLmxlbmd0aDsgKytpKQ0KICAgICAgaWYoeFswXSA9PSBsb3dwcmltZXNbaV0pIHJldHVybiB0cnVlOw0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KICBpZih4LmlzRXZlbigpKSByZXR1cm4gZmFsc2U7DQogIGkgPSAxOw0KICB3aGlsZShpIDwgbG93cHJpbWVzLmxlbmd0aCkgew0KICAgIHZhciBtID0gbG93cHJpbWVzW2ldLCBqID0gaSsxOw0KICAgIHdoaWxlKGogPCBsb3dwcmltZXMubGVuZ3RoICYmIG0gPCBscGxpbSkgbSAqPSBsb3dwcmltZXNbaisrXTsNCiAgICBtID0geC5tb2RJbnQobSk7DQogICAgd2hpbGUoaSA8IGopIGlmKG0lbG93cHJpbWVzW2krK10gPT0gMCkgcmV0dXJuIGZhbHNlOw0KICB9DQogIHJldHVybiB4Lm1pbGxlclJhYmluKHQpOw0KfQ0KDQovKiBhZGRlZCBieSBSZWN1cml0eSBMYWJzICovDQoNCmZ1bmN0aW9uIG5iaXRzKHgpIHsNCgl2YXIgbiA9IDEsIHQ7DQoJaWYgKCh0ID0geCA+Pj4gMTYpICE9IDApIHsNCgkJeCA9IHQ7DQoJCW4gKz0gMTY7DQoJfQ0KCWlmICgodCA9IHggPj4gOCkgIT0gMCkgew0KCQl4ID0gdDsNCgkJbiArPSA4Ow0KCX0NCglpZiAoKHQgPSB4ID4+IDQpICE9IDApIHsNCgkJeCA9IHQ7DQoJCW4gKz0gNDsNCgl9DQoJaWYgKCh0ID0geCA+PiAyKSAhPSAwKSB7DQoJCXggPSB0Ow0KCQluICs9IDI7DQoJfQ0KCWlmICgodCA9IHggPj4gMSkgIT0gMCkgew0KCQl4ID0gdDsNCgkJbiArPSAxOw0KCX0NCglyZXR1cm4gbjsNCn0NCg0KZnVuY3Rpb24gYm5Ub01QSSAoKSB7DQoJdmFyIGJhID0gdGhpcy50b0J5dGVBcnJheSgpOw0KCXZhciBzaXplID0gKGJhLmxlbmd0aC0xKSo4K25iaXRzKGJhWzBdKTsNCgl2YXIgcmVzdWx0ID0gIiI7DQoJcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKHNpemUgJiAweEZGMDApID4+IDgpOw0KCXJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHNpemUgJiAweEZGKTsNCglyZXN1bHQgKz0gdXRpbC5iaW4yc3RyKGJhKTsNCglyZXR1cm4gcmVzdWx0Ow0KfQ0KLyogRU5EIG9mIGFkZGl0aW9uICovDQoNCi8vIChwcm90ZWN0ZWQpIHRydWUgaWYgcHJvYmFibHkgcHJpbWUgKEhBQyA0LjI0LCBNaWxsZXItUmFiaW4pDQpmdW5jdGlvbiBibnBNaWxsZXJSYWJpbih0KSB7DQogIHZhciBuMSA9IHRoaXMuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpOw0KICB2YXIgayA9IG4xLmdldExvd2VzdFNldEJpdCgpOw0KICBpZihrIDw9IDApIHJldHVybiBmYWxzZTsNCiAgdmFyIHIgPSBuMS5zaGlmdFJpZ2h0KGspOw0KICB0ID0gKHQrMSk+PjE7DQogIGlmKHQgPiBsb3dwcmltZXMubGVuZ3RoKSB0ID0gbG93cHJpbWVzLmxlbmd0aDsNCiAgdmFyIGEgPSBuYmkoKTsNCiAgZm9yKHZhciBpID0gMDsgaSA8IHQ7ICsraSkgew0KICAgIC8vUGljayBiYXNlcyBhdCByYW5kb20sIGluc3RlYWQgb2Ygc3RhcnRpbmcgYXQgMg0KICAgIGEuZnJvbUludChsb3dwcmltZXNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpKmxvd3ByaW1lcy5sZW5ndGgpXSk7DQogICAgdmFyIHkgPSBhLm1vZFBvdyhyLHRoaXMpOw0KICAgIGlmKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPSAwICYmIHkuY29tcGFyZVRvKG4xKSAhPSAwKSB7DQogICAgICB2YXIgaiA9IDE7DQogICAgICB3aGlsZShqKysgPCBrICYmIHkuY29tcGFyZVRvKG4xKSAhPSAwKSB7DQogICAgICAgIHkgPSB5Lm1vZFBvd0ludCgyLHRoaXMpOw0KICAgICAgICBpZih5LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT0gMCkgcmV0dXJuIGZhbHNlOw0KICAgICAgfQ0KICAgICAgaWYoeS5jb21wYXJlVG8objEpICE9IDApIHJldHVybiBmYWxzZTsNCiAgICB9DQogIH0NCiAgcmV0dXJuIHRydWU7DQp9DQoNCi8vIHByb3RlY3RlZA0KQmlnSW50ZWdlci5wcm90b3R5cGUuY2h1bmtTaXplID0gYm5wQ2h1bmtTaXplOw0KQmlnSW50ZWdlci5wcm90b3R5cGUudG9SYWRpeCA9IGJucFRvUmFkaXg7DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tUmFkaXggPSBibnBGcm9tUmFkaXg7DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tTnVtYmVyID0gYm5wRnJvbU51bWJlcjsNCkJpZ0ludGVnZXIucHJvdG90eXBlLmJpdHdpc2VUbyA9IGJucEJpdHdpc2VUbzsNCkJpZ0ludGVnZXIucHJvdG90eXBlLmNoYW5nZUJpdCA9IGJucENoYW5nZUJpdDsNCkJpZ0ludGVnZXIucHJvdG90eXBlLmFkZFRvID0gYm5wQWRkVG87DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kTXVsdGlwbHkgPSBibnBETXVsdGlwbHk7DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kQWRkT2Zmc2V0ID0gYm5wREFkZE9mZnNldDsNCkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5TG93ZXJUbyA9IGJucE11bHRpcGx5TG93ZXJUbzsNCkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5VXBwZXJUbyA9IGJucE11bHRpcGx5VXBwZXJUbzsNCkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludCA9IGJucE1vZEludDsNCkJpZ0ludGVnZXIucHJvdG90eXBlLm1pbGxlclJhYmluID0gYm5wTWlsbGVyUmFiaW47DQoNCi8vIHB1YmxpYw0KQmlnSW50ZWdlci5wcm90b3R5cGUuY2xvbmUgPSBibkNsb25lOw0KQmlnSW50ZWdlci5wcm90b3R5cGUuaW50VmFsdWUgPSBibkludFZhbHVlOw0KQmlnSW50ZWdlci5wcm90b3R5cGUuYnl0ZVZhbHVlID0gYm5CeXRlVmFsdWU7DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5zaG9ydFZhbHVlID0gYm5TaG9ydFZhbHVlOw0KQmlnSW50ZWdlci5wcm90b3R5cGUuc2lnbnVtID0gYm5TaWdOdW07DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS50b0J5dGVBcnJheSA9IGJuVG9CeXRlQXJyYXk7DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5lcXVhbHMgPSBibkVxdWFsczsNCkJpZ0ludGVnZXIucHJvdG90eXBlLm1pbiA9IGJuTWluOw0KQmlnSW50ZWdlci5wcm90b3R5cGUubWF4ID0gYm5NYXg7DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbmQgPSBibkFuZDsNCkJpZ0ludGVnZXIucHJvdG90eXBlLm9yID0gYm5PcjsNCkJpZ0ludGVnZXIucHJvdG90eXBlLnhvciA9IGJuWG9yOw0KQmlnSW50ZWdlci5wcm90b3R5cGUuYW5kTm90ID0gYm5BbmROb3Q7DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5ub3QgPSBibk5vdDsNCkJpZ0ludGVnZXIucHJvdG90eXBlLnNoaWZ0TGVmdCA9IGJuU2hpZnRMZWZ0Ow0KQmlnSW50ZWdlci5wcm90b3R5cGUuc2hpZnRSaWdodCA9IGJuU2hpZnRSaWdodDsNCkJpZ0ludGVnZXIucHJvdG90eXBlLmdldExvd2VzdFNldEJpdCA9IGJuR2V0TG93ZXN0U2V0Qml0Ow0KQmlnSW50ZWdlci5wcm90b3R5cGUuYml0Q291bnQgPSBibkJpdENvdW50Ow0KQmlnSW50ZWdlci5wcm90b3R5cGUudGVzdEJpdCA9IGJuVGVzdEJpdDsNCkJpZ0ludGVnZXIucHJvdG90eXBlLnNldEJpdCA9IGJuU2V0Qml0Ow0KQmlnSW50ZWdlci5wcm90b3R5cGUuY2xlYXJCaXQgPSBibkNsZWFyQml0Ow0KQmlnSW50ZWdlci5wcm90b3R5cGUuZmxpcEJpdCA9IGJuRmxpcEJpdDsNCkJpZ0ludGVnZXIucHJvdG90eXBlLmFkZCA9IGJuQWRkOw0KQmlnSW50ZWdlci5wcm90b3R5cGUuc3VidHJhY3QgPSBiblN1YnRyYWN0Ow0KQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHkgPSBibk11bHRpcGx5Ow0KQmlnSW50ZWdlci5wcm90b3R5cGUuZGl2aWRlID0gYm5EaXZpZGU7DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5yZW1haW5kZXIgPSBiblJlbWFpbmRlcjsNCkJpZ0ludGVnZXIucHJvdG90eXBlLmRpdmlkZUFuZFJlbWFpbmRlciA9IGJuRGl2aWRlQW5kUmVtYWluZGVyOw0KQmlnSW50ZWdlci5wcm90b3R5cGUubW9kUG93ID0gYm5Nb2RQb3c7DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RJbnZlcnNlID0gYm5Nb2RJbnZlcnNlOw0KQmlnSW50ZWdlci5wcm90b3R5cGUucG93ID0gYm5Qb3c7DQpCaWdJbnRlZ2VyLnByb3RvdHlwZS5nY2QgPSBibkdDRDsNCkJpZ0ludGVnZXIucHJvdG90eXBlLmlzUHJvYmFibGVQcmltZSA9IGJuSXNQcm9iYWJsZVByaW1lOw0KQmlnSW50ZWdlci5wcm90b3R5cGUudG9NUEkgPSBiblRvTVBJOw0KDQovLyBKU0JOLXNwZWNpZmljIGV4dGVuc2lvbg0KQmlnSW50ZWdlci5wcm90b3R5cGUuc3F1YXJlID0gYm5TcXVhcmU7DQovLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHQNCi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkgNCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcg0KLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyDQovLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4NCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsDQovLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0KLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUNCi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuDQovLyANCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUNCi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQ0KLy8NCi8vIFJTQSBpbXBsZW1lbnRhdGlvbg0KDQpmdW5jdGlvbiBTZWN1cmVSYW5kb20oKXsNCiAgICBmdW5jdGlvbiBuZXh0Qnl0ZXMoYnl0ZUFycmF5KXsNCiAgICAgICAgZm9yKHZhciBuID0gMDsgbiA8IGJ5dGVBcnJheS5sZW5ndGg7bisrKXsNCiAgICAgICAgICAgIGJ5dGVBcnJheVtuXSA9IG9wZW5wZ3BfY3J5cHRvX2dldFNlY3VyZVJhbmRvbU9jdGV0KCk7DQogICAgICAgIH0NCiAgICB9DQogICAgdGhpcy5uZXh0Qnl0ZXMgPSBuZXh0Qnl0ZXM7DQp9DQoNCmZ1bmN0aW9uIFJTQSgpIHsNCgkvKioNCgkgKiBUaGlzIGZ1bmN0aW9uIHVzZXMganNibiBCaWcgTnVtIGxpYnJhcnkgdG8gZGVjcnlwdCBSU0ENCgkgKiBAcGFyYW0gbQ0KCSAqICAgICAgICAgICAgbWVzc2FnZQ0KCSAqIEBwYXJhbSBkDQoJICogICAgICAgICAgICBSU0EgZCBhcyBCaWdJbnRlZ2VyDQoJICogQHBhcmFtIHANCgkgKiAgICAgICAgICAgIFJTQSBwIGFzIEJpZ0ludGVnZXINCgkgKiBAcGFyYW0gcQ0KCSAqICAgICAgICAgICAgUlNBIHEgYXMgQmlnSW50ZWdlcg0KCSAqIEBwYXJhbSB1DQoJICogICAgICAgICAgICBSU0EgdSBhcyBCaWdJbnRlZ2VyDQoJICogQHJldHVybiB7QmlnSW50ZWdlcn0gVGhlIGRlY3J5cHRlZCB2YWx1ZSBvZiB0aGUgbWVzc2FnZQ0KCSAqLw0KCWZ1bmN0aW9uIGRlY3J5cHQobSwgZCwgcCwgcSwgdSkgew0KCQl2YXIgeHAgPSBtLm1vZChwKS5tb2RQb3coZC5tb2QocC5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSkpLCBwKTsNCgkJdmFyIHhxID0gbS5tb2QocSkubW9kUG93KGQubW9kKHEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKSwgcSk7DQoJCXV0aWwucHJpbnRfZGVidWcoInJzYS5qcyBkZWNyeXB0XG54cG46Iit1dGlsLmhleHN0cmR1bXAoeHAudG9NUEkoKSkrIlxueHFuOiIrdXRpbC5oZXhzdHJkdW1wKHhxLnRvTVBJKCkpKTsNCg0KCQl2YXIgdCA9IHhxLnN1YnRyYWN0KHhwKTsNCgkJaWYgKHRbMF0gPT0gMCkgew0KCQkJdCA9IHhwLnN1YnRyYWN0KHhxKTsNCgkJCXQgPSB0Lm11bHRpcGx5KHUpLm1vZChxKTsNCgkJCXQgPSBxLnN1YnRyYWN0KHQpOw0KCQl9IGVsc2Ugew0KCQkJdCA9IHQubXVsdGlwbHkodSkubW9kKHEpOw0KCQl9DQoJCXJldHVybiB0Lm11bHRpcGx5KHApLmFkZCh4cCk7DQoJfQ0KCQ0KCS8qKg0KCSAqIGVuY3J5cHQgbWVzc2FnZQ0KCSAqIEBwYXJhbSBtIG1lc3NhZ2UgYXMgQmlnSW50ZWdlcg0KCSAqIEBwYXJhbSBlIHB1YmxpYyBNUEkgcGFydCBhcyBCaWdJbnRlZ2VyDQoJICogQHBhcmFtIG4gcHVibGljIE1QSSBwYXJ0IGFzIEJpZ0ludGVnZXINCgkgKiBAcmV0dXJuIEJpZ0ludGVnZXINCgkgKi8NCglmdW5jdGlvbiBlbmNyeXB0KG0sZSxuKSB7DQoJCXJldHVybiBtLm1vZFBvd0ludChlLCBuKTsNCgl9DQoJDQoJLyogU2lnbiBhbmQgVmVyaWZ5ICovDQoJZnVuY3Rpb24gc2lnbihtLGQsbikgew0KCQlyZXR1cm4gbS5tb2RQb3coZCwgbik7DQoJfQ0KCQkNCglmdW5jdGlvbiB2ZXJpZnkoeCxlLG4pIHsNCgkJcmV0dXJuIHgubW9kUG93SW50KGUsIG4pOw0KCX0NCgkNCgkvLyAiZW1wdHkiIFJTQSBrZXkgY29uc3RydWN0b3INCiAgICBmdW5jdGlvbiBrZXlPYmplY3QoKSB7DQogICAgICAgIHRoaXMubiA9IG51bGw7DQogICAgICAgIHRoaXMuZSA9IDA7DQogICAgICAgIHRoaXMuZWUgPSBudWxsOw0KICAgICAgICB0aGlzLmQgPSBudWxsOw0KICAgICAgICB0aGlzLnAgPSBudWxsOw0KICAgICAgICB0aGlzLnEgPSBudWxsOw0KICAgICAgICB0aGlzLmRtcDEgPSBudWxsOw0KICAgICAgICB0aGlzLmRtcTEgPSBudWxsOw0KICAgICAgICB0aGlzLnUgPSBudWxsOw0KICAgIH0NCgkNCgkvLyBHZW5lcmF0ZSBhIG5ldyByYW5kb20gcHJpdmF0ZSBrZXkgQiBiaXRzIGxvbmcsIHVzaW5nIHB1YmxpYyBleHB0IEUNCiAgICBmdW5jdGlvbiBnZW5lcmF0ZShCLEUpIHsNCiAgICAgICAgdmFyIGtleSA9IG5ldyBrZXlPYmplY3QoKTsNCiAgICAgICAgdmFyIHJuZyA9IG5ldyBTZWN1cmVSYW5kb20oKTsNCiAgICAgICAgdmFyIHFzID0gQj4+MTsNCiAgICAgICAga2V5LmUgPSBwYXJzZUludChFLDE2KTsNCiAgICAgICAga2V5LmVlID0gbmV3IEJpZ0ludGVnZXIoRSwxNik7DQogICAgICAgIGZvcig7Oykgew0KICAgICAgICAgICAgZm9yKDs7KSB7DQogICAgICAgICAgICAgICAga2V5LnAgPSBuZXcgQmlnSW50ZWdlcihCLXFzLDEscm5nKTsNCiAgICAgICAgICAgICAgICBpZihrZXkucC5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSkuZ2NkKGtleS5lZSkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwICYmIGtleS5wLmlzUHJvYmFibGVQcmltZSgxMCkpIGJyZWFrOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZm9yKDs7KSB7DQogICAgICAgICAgICAgICAga2V5LnEgPSBuZXcgQmlnSW50ZWdlcihxcywxLHJuZyk7DQogICAgICAgICAgICAgICAgaWYoa2V5LnEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpLmdjZChrZXkuZWUpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT0gMCAmJiBrZXkucS5pc1Byb2JhYmxlUHJpbWUoMTApKSBicmVhazsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmKGtleS5wLmNvbXBhcmVUbyhrZXkucSkgPD0gMCkgew0KICAgICAgICAgICAgICAgIHZhciB0ID0ga2V5LnA7DQogICAgICAgICAgICAgICAga2V5LnAgPSBrZXkucTsNCiAgICAgICAgICAgICAgICBrZXkucSA9IHQ7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB2YXIgcDEgPSBrZXkucC5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7DQogICAgICAgICAgICB2YXIgcTEgPSBrZXkucS5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7DQogICAgICAgICAgICB2YXIgcGhpID0gcDEubXVsdGlwbHkocTEpOw0KICAgICAgICAgICAgaWYocGhpLmdjZChrZXkuZWUpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT0gMCkgew0KICAgICAgICAgICAgICAgIGtleS5uID0ga2V5LnAubXVsdGlwbHkoa2V5LnEpOw0KICAgICAgICAgICAgICAgIGtleS5kID0ga2V5LmVlLm1vZEludmVyc2UocGhpKTsNCiAgICAgICAgICAgICAgICBrZXkuZG1wMSA9IGtleS5kLm1vZChwMSk7DQogICAgICAgICAgICAgICAga2V5LmRtcTEgPSBrZXkuZC5tb2QocTEpOw0KICAgICAgICAgICAgICAgIGtleS51ID0ga2V5LnAubW9kSW52ZXJzZShrZXkucSk7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIGtleTsNCiAgICB9DQoJCQ0KCXRoaXMuZW5jcnlwdCA9IGVuY3J5cHQ7DQoJdGhpcy5kZWNyeXB0ID0gZGVjcnlwdDsNCgl0aGlzLnZlcmlmeSA9IHZlcmlmeTsNCgl0aGlzLnNpZ24gPSBzaWduOw0KCXRoaXMuZ2VuZXJhdGUgPSBnZW5lcmF0ZTsNCgl0aGlzLmtleU9iamVjdCA9IGtleU9iamVjdDsNCn0NCi8qKg0KICogQSBmYXN0IE1ENSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uDQogKiBDb3B5cmlnaHQgKGMpIDIwMTIgSm9zZXBoIE15ZXJzDQogKiBodHRwOi8vd3d3Lm15ZXJzZGFpbHkub3JnL2pvc2VwaC9qYXZhc2NyaXB0L21kNS10ZXh0Lmh0bWwNCiAqDQogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlDQogKiBhbmQgaXRzIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlcyBhbmQgd2l0aG91dA0KICogZmVlIGlzIGhlcmVieSBncmFudGVkIHByb3ZpZGVkIHRoYXQgdGhpcyBjb3B5cmlnaHQgbm90aWNlDQogKiBhcHBlYXJzIGluIGFsbCBjb3BpZXMuDQogKg0KICogT2YgY291cnNlLCB0aGlzIHNvZnQgaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZA0KICogd2FycmFudHkgb2YgYW55IGtpbmQuDQogKi8NCg0KZnVuY3Rpb24gTUQ1KGVudHJlZSkgew0KCXZhciBoZXggPSBtZDUoZW50cmVlKTsNCgl2YXIgYmluID0gdXRpbC5oZXgyYmluKGhleCk7DQoJcmV0dXJuIGJpbjsNCn0NCg0KZnVuY3Rpb24gbWQ1Y3ljbGUoeCwgaykgew0KdmFyIGEgPSB4WzBdLCBiID0geFsxXSwgYyA9IHhbMl0sIGQgPSB4WzNdOw0KDQphID0gZmYoYSwgYiwgYywgZCwga1swXSwgNywgLTY4MDg3NjkzNik7DQpkID0gZmYoZCwgYSwgYiwgYywga1sxXSwgMTIsIC0zODk1NjQ1ODYpOw0KYyA9IGZmKGMsIGQsIGEsIGIsIGtbMl0sIDE3LCAgNjA2MTA1ODE5KTsNCmIgPSBmZihiLCBjLCBkLCBhLCBrWzNdLCAyMiwgLTEwNDQ1MjUzMzApOw0KYSA9IGZmKGEsIGIsIGMsIGQsIGtbNF0sIDcsIC0xNzY0MTg4OTcpOw0KZCA9IGZmKGQsIGEsIGIsIGMsIGtbNV0sIDEyLCAgMTIwMDA4MDQyNik7DQpjID0gZmYoYywgZCwgYSwgYiwga1s2XSwgMTcsIC0xNDczMjMxMzQxKTsNCmIgPSBmZihiLCBjLCBkLCBhLCBrWzddLCAyMiwgLTQ1NzA1OTgzKTsNCmEgPSBmZihhLCBiLCBjLCBkLCBrWzhdLCA3LCAgMTc3MDAzNTQxNik7DQpkID0gZmYoZCwgYSwgYiwgYywga1s5XSwgMTIsIC0xOTU4NDE0NDE3KTsNCmMgPSBmZihjLCBkLCBhLCBiLCBrWzEwXSwgMTcsIC00MjA2Myk7DQpiID0gZmYoYiwgYywgZCwgYSwga1sxMV0sIDIyLCAtMTk5MDQwNDE2Mik7DQphID0gZmYoYSwgYiwgYywgZCwga1sxMl0sIDcsICAxODA0NjAzNjgyKTsNCmQgPSBmZihkLCBhLCBiLCBjLCBrWzEzXSwgMTIsIC00MDM0MTEwMSk7DQpjID0gZmYoYywgZCwgYSwgYiwga1sxNF0sIDE3LCAtMTUwMjAwMjI5MCk7DQpiID0gZmYoYiwgYywgZCwgYSwga1sxNV0sIDIyLCAgMTIzNjUzNTMyOSk7DQoNCmEgPSBnZyhhLCBiLCBjLCBkLCBrWzFdLCA1LCAtMTY1Nzk2NTEwKTsNCmQgPSBnZyhkLCBhLCBiLCBjLCBrWzZdLCA5LCAtMTA2OTUwMTYzMik7DQpjID0gZ2coYywgZCwgYSwgYiwga1sxMV0sIDE0LCAgNjQzNzE3NzEzKTsNCmIgPSBnZyhiLCBjLCBkLCBhLCBrWzBdLCAyMCwgLTM3Mzg5NzMwMik7DQphID0gZ2coYSwgYiwgYywgZCwga1s1XSwgNSwgLTcwMTU1ODY5MSk7DQpkID0gZ2coZCwgYSwgYiwgYywga1sxMF0sIDksICAzODAxNjA4Myk7DQpjID0gZ2coYywgZCwgYSwgYiwga1sxNV0sIDE0LCAtNjYwNDc4MzM1KTsNCmIgPSBnZyhiLCBjLCBkLCBhLCBrWzRdLCAyMCwgLTQwNTUzNzg0OCk7DQphID0gZ2coYSwgYiwgYywgZCwga1s5XSwgNSwgIDU2ODQ0NjQzOCk7DQpkID0gZ2coZCwgYSwgYiwgYywga1sxNF0sIDksIC0xMDE5ODAzNjkwKTsNCmMgPSBnZyhjLCBkLCBhLCBiLCBrWzNdLCAxNCwgLTE4NzM2Mzk2MSk7DQpiID0gZ2coYiwgYywgZCwgYSwga1s4XSwgMjAsICAxMTYzNTMxNTAxKTsNCmEgPSBnZyhhLCBiLCBjLCBkLCBrWzEzXSwgNSwgLTE0NDQ2ODE0NjcpOw0KZCA9IGdnKGQsIGEsIGIsIGMsIGtbMl0sIDksIC01MTQwMzc4NCk7DQpjID0gZ2coYywgZCwgYSwgYiwga1s3XSwgMTQsICAxNzM1MzI4NDczKTsNCmIgPSBnZyhiLCBjLCBkLCBhLCBrWzEyXSwgMjAsIC0xOTI2NjA3NzM0KTsNCg0KYSA9IGhoKGEsIGIsIGMsIGQsIGtbNV0sIDQsIC0zNzg1NTgpOw0KZCA9IGhoKGQsIGEsIGIsIGMsIGtbOF0sIDExLCAtMjAyMjU3NDQ2Myk7DQpjID0gaGgoYywgZCwgYSwgYiwga1sxMV0sIDE2LCAgMTgzOTAzMDU2Mik7DQpiID0gaGgoYiwgYywgZCwgYSwga1sxNF0sIDIzLCAtMzUzMDk1NTYpOw0KYSA9IGhoKGEsIGIsIGMsIGQsIGtbMV0sIDQsIC0xNTMwOTkyMDYwKTsNCmQgPSBoaChkLCBhLCBiLCBjLCBrWzRdLCAxMSwgIDEyNzI4OTMzNTMpOw0KYyA9IGhoKGMsIGQsIGEsIGIsIGtbN10sIDE2LCAtMTU1NDk3NjMyKTsNCmIgPSBoaChiLCBjLCBkLCBhLCBrWzEwXSwgMjMsIC0xMDk0NzMwNjQwKTsNCmEgPSBoaChhLCBiLCBjLCBkLCBrWzEzXSwgNCwgIDY4MTI3OTE3NCk7DQpkID0gaGgoZCwgYSwgYiwgYywga1swXSwgMTEsIC0zNTg1MzcyMjIpOw0KYyA9IGhoKGMsIGQsIGEsIGIsIGtbM10sIDE2LCAtNzIyNTIxOTc5KTsNCmIgPSBoaChiLCBjLCBkLCBhLCBrWzZdLCAyMywgIDc2MDI5MTg5KTsNCmEgPSBoaChhLCBiLCBjLCBkLCBrWzldLCA0LCAtNjQwMzY0NDg3KTsNCmQgPSBoaChkLCBhLCBiLCBjLCBrWzEyXSwgMTEsIC00MjE4MTU4MzUpOw0KYyA9IGhoKGMsIGQsIGEsIGIsIGtbMTVdLCAxNiwgIDUzMDc0MjUyMCk7DQpiID0gaGgoYiwgYywgZCwgYSwga1syXSwgMjMsIC05OTUzMzg2NTEpOw0KDQphID0gaWkoYSwgYiwgYywgZCwga1swXSwgNiwgLTE5ODYzMDg0NCk7DQpkID0gaWkoZCwgYSwgYiwgYywga1s3XSwgMTAsICAxMTI2ODkxNDE1KTsNCmMgPSBpaShjLCBkLCBhLCBiLCBrWzE0XSwgMTUsIC0xNDE2MzU0OTA1KTsNCmIgPSBpaShiLCBjLCBkLCBhLCBrWzVdLCAyMSwgLTU3NDM0MDU1KTsNCmEgPSBpaShhLCBiLCBjLCBkLCBrWzEyXSwgNiwgIDE3MDA0ODU1NzEpOw0KZCA9IGlpKGQsIGEsIGIsIGMsIGtbM10sIDEwLCAtMTg5NDk4NjYwNik7DQpjID0gaWkoYywgZCwgYSwgYiwga1sxMF0sIDE1LCAtMTA1MTUyMyk7DQpiID0gaWkoYiwgYywgZCwgYSwga1sxXSwgMjEsIC0yMDU0OTIyNzk5KTsNCmEgPSBpaShhLCBiLCBjLCBkLCBrWzhdLCA2LCAgMTg3MzMxMzM1OSk7DQpkID0gaWkoZCwgYSwgYiwgYywga1sxNV0sIDEwLCAtMzA2MTE3NDQpOw0KYyA9IGlpKGMsIGQsIGEsIGIsIGtbNl0sIDE1LCAtMTU2MDE5ODM4MCk7DQpiID0gaWkoYiwgYywgZCwgYSwga1sxM10sIDIxLCAgMTMwOTE1MTY0OSk7DQphID0gaWkoYSwgYiwgYywgZCwga1s0XSwgNiwgLTE0NTUyMzA3MCk7DQpkID0gaWkoZCwgYSwgYiwgYywga1sxMV0sIDEwLCAtMTEyMDIxMDM3OSk7DQpjID0gaWkoYywgZCwgYSwgYiwga1syXSwgMTUsICA3MTg3ODcyNTkpOw0KYiA9IGlpKGIsIGMsIGQsIGEsIGtbOV0sIDIxLCAtMzQzNDg1NTUxKTsNCg0KeFswXSA9IGFkZDMyKGEsIHhbMF0pOw0KeFsxXSA9IGFkZDMyKGIsIHhbMV0pOw0KeFsyXSA9IGFkZDMyKGMsIHhbMl0pOw0KeFszXSA9IGFkZDMyKGQsIHhbM10pOw0KDQp9DQoNCmZ1bmN0aW9uIGNtbihxLCBhLCBiLCB4LCBzLCB0KSB7DQphID0gYWRkMzIoYWRkMzIoYSwgcSksIGFkZDMyKHgsIHQpKTsNCnJldHVybiBhZGQzMigoYSA8PCBzKSB8IChhID4+PiAoMzIgLSBzKSksIGIpOw0KfQ0KDQpmdW5jdGlvbiBmZihhLCBiLCBjLCBkLCB4LCBzLCB0KSB7DQpyZXR1cm4gY21uKChiICYgYykgfCAoKH5iKSAmIGQpLCBhLCBiLCB4LCBzLCB0KTsNCn0NCg0KZnVuY3Rpb24gZ2coYSwgYiwgYywgZCwgeCwgcywgdCkgew0KcmV0dXJuIGNtbigoYiAmIGQpIHwgKGMgJiAofmQpKSwgYSwgYiwgeCwgcywgdCk7DQp9DQoNCmZ1bmN0aW9uIGhoKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHsNCnJldHVybiBjbW4oYiBeIGMgXiBkLCBhLCBiLCB4LCBzLCB0KTsNCn0NCg0KZnVuY3Rpb24gaWkoYSwgYiwgYywgZCwgeCwgcywgdCkgew0KcmV0dXJuIGNtbihjIF4gKGIgfCAofmQpKSwgYSwgYiwgeCwgcywgdCk7DQp9DQoNCmZ1bmN0aW9uIG1kNTEocykgew0KdHh0ID0gJyc7DQp2YXIgbiA9IHMubGVuZ3RoLA0Kc3RhdGUgPSBbMTczMjU4NDE5MywgLTI3MTczMzg3OSwgLTE3MzI1ODQxOTQsIDI3MTczMzg3OF0sIGk7DQpmb3IgKGk9NjQ7IGk8PXMubGVuZ3RoOyBpKz02NCkgew0KbWQ1Y3ljbGUoc3RhdGUsIG1kNWJsayhzLnN1YnN0cmluZyhpLTY0LCBpKSkpOw0KfQ0KcyA9IHMuc3Vic3RyaW5nKGktNjQpOw0KdmFyIHRhaWwgPSBbMCwwLDAsMCwgMCwwLDAsMCwgMCwwLDAsMCwgMCwwLDAsMF07DQpmb3IgKGk9MDsgaTxzLmxlbmd0aDsgaSsrKQ0KdGFpbFtpPj4yXSB8PSBzLmNoYXJDb2RlQXQoaSkgPDwgKChpJTQpIDw8IDMpOw0KdGFpbFtpPj4yXSB8PSAweDgwIDw8ICgoaSU0KSA8PCAzKTsNCmlmIChpID4gNTUpIHsNCm1kNWN5Y2xlKHN0YXRlLCB0YWlsKTsNCmZvciAoaT0wOyBpPDE2OyBpKyspIHRhaWxbaV0gPSAwOw0KfQ0KdGFpbFsxNF0gPSBuKjg7DQptZDVjeWNsZShzdGF0ZSwgdGFpbCk7DQpyZXR1cm4gc3RhdGU7DQp9DQoNCi8qIHRoZXJlIG5lZWRzIHRvIGJlIHN1cHBvcnQgZm9yIFVuaWNvZGUgaGVyZSwNCiAqIHVubGVzcyB3ZSBwcmV0ZW5kIHRoYXQgd2UgY2FuIHJlZGVmaW5lIHRoZSBNRC01DQogKiBhbGdvcml0aG0gZm9yIG11bHRpLWJ5dGUgY2hhcmFjdGVycyAocGVyaGFwcw0KICogYnkgYWRkaW5nIGV2ZXJ5IGZvdXIgMTYtYml0IGNoYXJhY3RlcnMgYW5kDQogKiBzaG9ydGVuaW5nIHRoZSBzdW0gdG8gMzIgYml0cykuIE90aGVyd2lzZQ0KICogSSBzdWdnZXN0IHBlcmZvcm1pbmcgTUQtNSBhcyBpZiBldmVyeSBjaGFyYWN0ZXINCiAqIHdhcyB0d28gYnl0ZXMtLWUuZy4sIDAwNDAgMDAyNSA9IEAlLS1idXQgdGhlbg0KICogaG93IHdpbGwgYW4gb3JkaW5hcnkgTUQtNSBzdW0gYmUgbWF0Y2hlZD8NCiAqIFRoZXJlIGlzIG5vIHdheSB0byBzdGFuZGFyZGl6ZSB0ZXh0IHRvIHNvbWV0aGluZw0KICogbGlrZSBVVEYtOCBiZWZvcmUgdHJhbnNmb3JtYXRpb247IHNwZWVkIGNvc3QgaXMNCiAqIHV0dGVybHkgcHJvaGliaXRpdmUuIFRoZSBKYXZhU2NyaXB0IHN0YW5kYXJkDQogKiBpdHNlbGYgbmVlZHMgdG8gbG9vayBhdCB0aGlzOiBpdCBzaG91bGQgc3RhcnQNCiAqIHByb3ZpZGluZyBhY2Nlc3MgdG8gc3RyaW5ncyBhcyBwcmVmb3JtZWQgVVRGLTgNCiAqIDgtYml0IHVuc2lnbmVkIHZhbHVlIGFycmF5cy4NCiAqLw0KZnVuY3Rpb24gbWQ1YmxrKHMpIHsgLyogSSBmaWd1cmVkIGdsb2JhbCB3YXMgZmFzdGVyLiAgICovDQp2YXIgbWQ1YmxrcyA9IFtdLCBpOyAvKiBBbmR5IEtpbmcgc2FpZCBkbyBpdCB0aGlzIHdheS4gKi8NCmZvciAoaT0wOyBpPDY0OyBpKz00KSB7DQptZDVibGtzW2k+PjJdID0gcy5jaGFyQ29kZUF0KGkpDQorIChzLmNoYXJDb2RlQXQoaSsxKSA8PCA4KQ0KKyAocy5jaGFyQ29kZUF0KGkrMikgPDwgMTYpDQorIChzLmNoYXJDb2RlQXQoaSszKSA8PCAyNCk7DQp9DQpyZXR1cm4gbWQ1YmxrczsNCn0NCg0KdmFyIGhleF9jaHIgPSAnMDEyMzQ1Njc4OWFiY2RlZicuc3BsaXQoJycpOw0KDQpmdW5jdGlvbiByaGV4KG4pDQp7DQp2YXIgcz0nJywgaj0wOw0KZm9yKDsgajw0OyBqKyspDQpzICs9IGhleF9jaHJbKG4gPj4gKGogKiA4ICsgNCkpICYgMHgwRl0NCisgaGV4X2NoclsobiA+PiAoaiAqIDgpKSAmIDB4MEZdOw0KcmV0dXJuIHM7DQp9DQoNCmZ1bmN0aW9uIGhleCh4KSB7DQpmb3IgKHZhciBpPTA7IGk8eC5sZW5ndGg7IGkrKykNCnhbaV0gPSByaGV4KHhbaV0pOw0KcmV0dXJuIHguam9pbignJyk7DQp9DQoNCmZ1bmN0aW9uIG1kNShzKSB7DQpyZXR1cm4gaGV4KG1kNTEocykpOw0KfQ0KDQovKiB0aGlzIGZ1bmN0aW9uIGlzIG11Y2ggZmFzdGVyLA0Kc28gaWYgcG9zc2libGUgd2UgdXNlIGl0LiBTb21lIElFcw0KYXJlIHRoZSBvbmx5IG9uZXMgSSBrbm93IG9mIHRoYXQNCm5lZWQgdGhlIGlkaW90aWMgc2Vjb25kIGZ1bmN0aW9uLA0KZ2VuZXJhdGVkIGJ5IGFuIGlmIGNsYXVzZS4gICovDQoNCmZ1bmN0aW9uIGFkZDMyKGEsIGIpIHsNCnJldHVybiAoYSArIGIpICYgMHhGRkZGRkZGRjsNCn0NCg0KaWYgKG1kNSgnaGVsbG8nKSAhPSAnNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTInKSB7DQpmdW5jdGlvbiBhZGQzMih4LCB5KSB7DQp2YXIgbHN3ID0gKHggJiAweEZGRkYpICsgKHkgJiAweEZGRkYpLA0KbXN3ID0gKHggPj4gMTYpICsgKHkgPj4gMTYpICsgKGxzdyA+PiAxNik7DQpyZXR1cm4gKG1zdyA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTsNCn0NCn0NCi8qDQogKiBDcnlwdG9NWCBUb29scw0KICogQ29weXJpZ2h0IChDKSAyMDA0IC0gMjAwNiBEZXJlayBCdWl0ZW5odWlzDQogKg0KICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcg0KICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UNCiAqIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyDQogKiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4NCiAqDQogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwNCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mDQogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlDQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLg0KICoNCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlDQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQ0KICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3LCBVU0EuDQogKi8NCg0KLyogTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIDQogKi8NCg0KdmFyIFJNRHNpemUgICA9IDE2MDsNCnZhciBYID0gbmV3IEFycmF5KCk7DQoNCmZ1bmN0aW9uIFJPTCh4LCBuKQ0Kew0KICByZXR1cm4gbmV3IE51bWJlciAoKHggPDwgbikgfCAoIHggPj4+ICgzMiAtIG4pKSk7DQp9DQoNCmZ1bmN0aW9uIEYoeCwgeSwgeikNCnsNCiAgcmV0dXJuIG5ldyBOdW1iZXIoeCBeIHkgXiB6KTsNCn0NCg0KZnVuY3Rpb24gRyh4LCB5LCB6KQ0Kew0KICByZXR1cm4gbmV3IE51bWJlcigoeCAmIHkpIHwgKH54ICYgeikpOw0KfQ0KDQpmdW5jdGlvbiBIKHgsIHksIHopDQp7DQogIHJldHVybiBuZXcgTnVtYmVyKCh4IHwgfnkpIF4geik7DQp9DQoNCmZ1bmN0aW9uIEkoeCwgeSwgeikNCnsNCiAgcmV0dXJuIG5ldyBOdW1iZXIoKHggJiB6KSB8ICh5ICYgfnopKTsNCn0NCg0KZnVuY3Rpb24gSih4LCB5LCB6KQ0Kew0KICByZXR1cm4gbmV3IE51bWJlcih4IF4gKHkgfCB+eikpOw0KfQ0KDQpmdW5jdGlvbiBtaXhPbmVSb3VuZChhLCBiLCBjLCBkLCBlLCB4LCBzLCByb3VuZE51bWJlcikNCnsNCiAgc3dpdGNoIChyb3VuZE51bWJlcikNCiAgew0KICAgIGNhc2UgMCA6IGEgKz0gRihiLCBjLCBkKSArIHggKyAweDAwMDAwMDAwOyBicmVhazsNCiAgICBjYXNlIDEgOiBhICs9IEcoYiwgYywgZCkgKyB4ICsgMHg1YTgyNzk5OTsgYnJlYWs7DQogICAgY2FzZSAyIDogYSArPSBIKGIsIGMsIGQpICsgeCArIDB4NmVkOWViYTE7IGJyZWFrOw0KICAgIGNhc2UgMyA6IGEgKz0gSShiLCBjLCBkKSArIHggKyAweDhmMWJiY2RjOyBicmVhazsNCiAgICBjYXNlIDQgOiBhICs9IEooYiwgYywgZCkgKyB4ICsgMHhhOTUzZmQ0ZTsgYnJlYWs7DQogICAgY2FzZSA1IDogYSArPSBKKGIsIGMsIGQpICsgeCArIDB4NTBhMjhiZTY7IGJyZWFrOw0KICAgIGNhc2UgNiA6IGEgKz0gSShiLCBjLCBkKSArIHggKyAweDVjNGRkMTI0OyBicmVhazsNCiAgICBjYXNlIDcgOiBhICs9IEgoYiwgYywgZCkgKyB4ICsgMHg2ZDcwM2VmMzsgYnJlYWs7DQogICAgY2FzZSA4IDogYSArPSBHKGIsIGMsIGQpICsgeCArIDB4N2E2ZDc2ZTk7IGJyZWFrOw0KICAgIGNhc2UgOSA6IGEgKz0gRihiLCBjLCBkKSArIHggKyAweDAwMDAwMDAwOyBicmVhazsNCiAgICANCiAgICBkZWZhdWx0IDogZG9jdW1lbnQud3JpdGUoIkJvZ3VzIHJvdW5kIG51bWJlciIpOyBicmVhazsNCiAgfSAgDQogIA0KICBhID0gUk9MKGEsIHMpICsgZTsNCiAgYyA9IFJPTChjLCAxMCk7DQoNCiAgYSAmPSAweGZmZmZmZmZmOw0KICBiICY9IDB4ZmZmZmZmZmY7DQogIGMgJj0gMHhmZmZmZmZmZjsNCiAgZCAmPSAweGZmZmZmZmZmOw0KICBlICY9IDB4ZmZmZmZmZmY7DQoNCiAgdmFyIHJldEJsb2NrID0gbmV3IEFycmF5KCk7DQogIHJldEJsb2NrWzBdID0gYTsNCiAgcmV0QmxvY2tbMV0gPSBiOw0KICByZXRCbG9ja1syXSA9IGM7DQogIHJldEJsb2NrWzNdID0gZDsNCiAgcmV0QmxvY2tbNF0gPSBlOw0KICByZXRCbG9ja1s1XSA9IHg7DQogIHJldEJsb2NrWzZdID0gczsNCg0KICByZXR1cm4gcmV0QmxvY2s7DQp9DQoNCmZ1bmN0aW9uIE1EaW5pdCAoTURidWYpDQp7DQogIE1EYnVmWzBdID0gMHg2NzQ1MjMwMTsNCiAgTURidWZbMV0gPSAweGVmY2RhYjg5Ow0KICBNRGJ1ZlsyXSA9IDB4OThiYWRjZmU7DQogIE1EYnVmWzNdID0gMHgxMDMyNTQ3NjsNCiAgTURidWZbNF0gPSAweGMzZDJlMWYwOw0KfQ0KDQp2YXIgUk9McyA9IFsNCiAgWzExLCAxNCwgMTUsIDEyLCAgNSwgIDgsICA3LCAgOSwgMTEsIDEzLCAxNCwgMTUsICA2LCAgNywgIDksICA4XSwNCiAgWyA3LCAgNiwgIDgsIDEzLCAxMSwgIDksICA3LCAxNSwgIDcsIDEyLCAxNSwgIDksIDExLCAgNywgMTMsIDEyXSwNCiAgWzExLCAxMywgIDYsICA3LCAxNCwgIDksIDEzLCAxNSwgMTQsICA4LCAxMywgIDYsICA1LCAxMiwgIDcsICA1XSwNCiAgWzExLCAxMiwgMTQsIDE1LCAxNCwgMTUsICA5LCAgOCwgIDksIDE0LCAgNSwgIDYsICA4LCAgNiwgIDUsIDEyXSwNCiAgWyA5LCAxNSwgIDUsIDExLCAgNiwgIDgsIDEzLCAxMiwgIDUsIDEyLCAxMywgMTQsIDExLCAgOCwgIDUsICA2XSwNCiAgWyA4LCAgOSwgIDksIDExLCAxMywgMTUsIDE1LCAgNSwgIDcsICA3LCAgOCwgMTEsIDE0LCAxNCwgMTIsICA2XSwNCiAgWyA5LCAxMywgMTUsICA3LCAxMiwgIDgsICA5LCAxMSwgIDcsICA3LCAxMiwgIDcsICA2LCAxNSwgMTMsIDExXSwNCiAgWyA5LCAgNywgMTUsIDExLCAgOCwgIDYsICA2LCAxNCwgMTIsIDEzLCAgNSwgMTQsIDEzLCAxMywgIDcsICA1XSwNCiAgWzE1LCAgNSwgIDgsIDExLCAxNCwgMTQsICA2LCAxNCwgIDYsICA5LCAxMiwgIDksIDEyLCAgNSwgMTUsICA4XSwNCiAgWyA4LCAgNSwgMTIsICA5LCAxMiwgIDUsIDE0LCAgNiwgIDgsIDEzLCAgNiwgIDUsIDE1LCAxMywgMTEsIDExXQ0KXTsNCg0KdmFyIGluZGV4ZXMgPSBbDQogIFsgMCwgIDEsICAyLCAgMywgIDQsICA1LCAgNiwgIDcsICA4LCAgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNV0sDQogIFsgNywgIDQsIDEzLCAgMSwgMTAsICA2LCAxNSwgIDMsIDEyLCAgMCwgIDksICA1LCAgMiwgMTQsIDExLCAgOF0sDQogIFsgMywgMTAsIDE0LCAgNCwgIDksIDE1LCAgOCwgIDEsICAyLCAgNywgIDAsICA2LCAxMywgMTEsICA1LCAxMl0sDQogIFsgMSwgIDksIDExLCAxMCwgIDAsICA4LCAxMiwgIDQsIDEzLCAgMywgIDcsIDE1LCAxNCwgIDUsICA2LCAgMl0sDQogIFsgNCwgIDAsICA1LCAgOSwgIDcsIDEyLCAgMiwgMTAsIDE0LCAgMSwgIDMsICA4LCAxMSwgIDYsIDE1LCAxM10sDQogIFsgNSwgMTQsICA3LCAgMCwgIDksICAyLCAxMSwgIDQsIDEzLCAgNiwgMTUsICA4LCAgMSwgMTAsICAzLCAxMl0sDQogIFsgNiwgMTEsICAzLCAgNywgIDAsIDEzLCAgNSwgMTAsIDE0LCAxNSwgIDgsIDEyLCAgNCwgIDksICAxLCAgMl0sDQogIFsxNSwgIDUsICAxLCAgMywgIDcsIDE0LCAgNiwgIDksIDExLCAgOCwgMTIsICAyLCAxMCwgIDAsICA0LCAxM10sDQogIFsgOCwgIDYsICA0LCAgMSwgIDMsIDExLCAxNSwgIDAsICA1LCAxMiwgIDIsIDEzLCAgOSwgIDcsIDEwLCAxNF0sDQogIFsxMiwgMTUsIDEwLCAgNCwgIDEsICA1LCAgOCwgIDcsICA2LCAgMiwgMTMsIDE0LCAgMCwgIDMsICA5LCAxMV0NCl07DQoNCmZ1bmN0aW9uIGNvbXByZXNzIChNRGJ1ZiwgWCkNCnsNCiAgYmxvY2tBID0gbmV3IEFycmF5KCk7DQogIGJsb2NrQiA9IG5ldyBBcnJheSgpOw0KDQogIHZhciByZXRCbG9jazsNCg0KICBmb3IgKHZhciBpPTA7IGkgPCA1OyBpKyspDQogIHsNCiAgICBibG9ja0FbaV0gPSBuZXcgTnVtYmVyKE1EYnVmW2ldKTsNCiAgICBibG9ja0JbaV0gPSBuZXcgTnVtYmVyKE1EYnVmW2ldKTsNCiAgfQ0KDQogIHZhciBzdGVwID0gMDsNCiAgZm9yICh2YXIgaiA9IDA7IGogPCA1OyBqKyspDQogIHsNCiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspDQogICAgew0KICAgICAgcmV0QmxvY2sgPSBtaXhPbmVSb3VuZCgNCiAgICAgICAgYmxvY2tBWyhzdGVwKzApICUgNV0sDQogICAgICAgIGJsb2NrQVsoc3RlcCsxKSAlIDVdLCAgIA0KICAgICAgICBibG9ja0FbKHN0ZXArMikgJSA1XSwgICANCiAgICAgICAgYmxvY2tBWyhzdGVwKzMpICUgNV0sICAgDQogICAgICAgIGJsb2NrQVsoc3RlcCs0KSAlIDVdLCAgDQogICAgICAgIFhbaW5kZXhlc1tqXVtpXV0sIA0KICAgICAgICBST0xzW2pdW2ldLA0KICAgICAgICBqDQogICAgICApOw0KDQogICAgICBibG9ja0FbKHN0ZXArMCkgJSA1XSA9IHJldEJsb2NrWzBdOw0KICAgICAgYmxvY2tBWyhzdGVwKzEpICUgNV0gPSByZXRCbG9ja1sxXTsNCiAgICAgIGJsb2NrQVsoc3RlcCsyKSAlIDVdID0gcmV0QmxvY2tbMl07DQogICAgICBibG9ja0FbKHN0ZXArMykgJSA1XSA9IHJldEJsb2NrWzNdOw0KICAgICAgYmxvY2tBWyhzdGVwKzQpICUgNV0gPSByZXRCbG9ja1s0XTsNCg0KICAgICAgc3RlcCArPSA0Ow0KICAgIH0NCiAgfQ0KDQogIHN0ZXAgPSAwOw0KICBmb3IgKHZhciBqID0gNTsgaiA8IDEwOyBqKyspDQogIHsNCiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspDQogICAgeyAgDQogICAgICByZXRCbG9jayA9IG1peE9uZVJvdW5kKA0KICAgICAgICBibG9ja0JbKHN0ZXArMCkgJSA1XSwgDQogICAgICAgIGJsb2NrQlsoc3RlcCsxKSAlIDVdLCANCiAgICAgICAgYmxvY2tCWyhzdGVwKzIpICUgNV0sIA0KICAgICAgICBibG9ja0JbKHN0ZXArMykgJSA1XSwgDQogICAgICAgIGJsb2NrQlsoc3RlcCs0KSAlIDVdLCAgDQogICAgICAgIFhbaW5kZXhlc1tqXVtpXV0sIA0KICAgICAgICBST0xzW2pdW2ldLA0KICAgICAgICBqDQogICAgICApOw0KDQogICAgICBibG9ja0JbKHN0ZXArMCkgJSA1XSA9IHJldEJsb2NrWzBdOw0KICAgICAgYmxvY2tCWyhzdGVwKzEpICUgNV0gPSByZXRCbG9ja1sxXTsNCiAgICAgIGJsb2NrQlsoc3RlcCsyKSAlIDVdID0gcmV0QmxvY2tbMl07DQogICAgICBibG9ja0JbKHN0ZXArMykgJSA1XSA9IHJldEJsb2NrWzNdOw0KICAgICAgYmxvY2tCWyhzdGVwKzQpICUgNV0gPSByZXRCbG9ja1s0XTsNCg0KICAgICAgc3RlcCArPSA0Ow0KICAgIH0NCiAgfQ0KDQogIGJsb2NrQlszXSArPSBibG9ja0FbMl0gKyBNRGJ1ZlsxXTsNCiAgTURidWZbMV0gID0gTURidWZbMl0gKyBibG9ja0FbM10gKyBibG9ja0JbNF07DQogIE1EYnVmWzJdICA9IE1EYnVmWzNdICsgYmxvY2tBWzRdICsgYmxvY2tCWzBdOw0KICBNRGJ1ZlszXSAgPSBNRGJ1Zls0XSArIGJsb2NrQVswXSArIGJsb2NrQlsxXTsNCiAgTURidWZbNF0gID0gTURidWZbMF0gKyBibG9ja0FbMV0gKyBibG9ja0JbMl07DQogIE1EYnVmWzBdICA9IGJsb2NrQlszXTsNCn0NCg0KZnVuY3Rpb24gemVyb1goWCkNCnsNCiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7IFhbaV0gPSAwOyB9DQp9DQoNCmZ1bmN0aW9uIE1EZmluaXNoIChNRGJ1Ziwgc3RycHRyLCBsc3dsZW4sIG1zd2xlbikNCnsNCiAgdmFyIFggPSBuZXcgQXJyYXkoMTYpOw0KICB6ZXJvWChYKTsNCg0KICB2YXIgaiA9IDA7DQogIGZvciAodmFyIGk9MDsgaSA8IChsc3dsZW4gJiA2Myk7IGkrKykNCiAgew0KICAgIFhbaSA+Pj4gMl0gXj0gKHN0cnB0ci5jaGFyQ29kZUF0KGorKykgJiAyNTUpIDw8ICg4ICogKGkgJiAzKSk7DQogIH0NCg0KICBYWyhsc3dsZW4gPj4+IDIpICYgMTVdIF49IDEgPDwgKDggKiAobHN3bGVuICYgMykgKyA3KTsNCg0KICBpZiAoKGxzd2xlbiAmIDYzKSA+IDU1KQ0KICB7DQogICAgY29tcHJlc3MoTURidWYsIFgpOw0KICAgIHZhciBYID0gbmV3IEFycmF5KDE2KTsNCiAgICB6ZXJvWChYKTsNCiAgfQ0KDQogIFhbMTRdID0gbHN3bGVuIDw8IDM7DQogIFhbMTVdID0gKGxzd2xlbiA+Pj4gMjkpIHwgKG1zd2xlbiA8PCAzKTsNCg0KICBjb21wcmVzcyhNRGJ1ZiwgWCk7DQp9DQoNCmZ1bmN0aW9uIEJZVEVTX1RPX0RXT1JEKGZvdXJDaGFycykNCnsNCiAgdmFyIHRtcCAgPSAoZm91ckNoYXJzLmNoYXJDb2RlQXQoMykgJiAyNTUpIDw8IDI0Ow0KICB0bXAgICB8PSAoZm91ckNoYXJzLmNoYXJDb2RlQXQoMikgJiAyNTUpIDw8IDE2Ow0KICB0bXAgICB8PSAoZm91ckNoYXJzLmNoYXJDb2RlQXQoMSkgJiAyNTUpIDw8IDg7DQogIHRtcCAgIHw9IChmb3VyQ2hhcnMuY2hhckNvZGVBdCgwKSAmIDI1NSk7ICANCg0KICByZXR1cm4gdG1wOw0KfQ0KDQpmdW5jdGlvbiBSTUQobWVzc2FnZSkNCnsNCiAgdmFyIE1EYnVmICAgPSBuZXcgQXJyYXkoUk1Ec2l6ZSAvIDMyKTsNCiAgdmFyIGhhc2hjb2RlICAgPSBuZXcgQXJyYXkoUk1Ec2l6ZSAvIDgpOw0KICB2YXIgbGVuZ3RoOyAgDQogIHZhciBuYnl0ZXM7DQoNCiAgTURpbml0KE1EYnVmKTsNCiAgbGVuZ3RoID0gbWVzc2FnZS5sZW5ndGg7DQoNCiAgdmFyIFggPSBuZXcgQXJyYXkoMTYpOw0KICB6ZXJvWChYKTsNCg0KICB2YXIgaj0wOw0KICBmb3IgKHZhciBuYnl0ZXM9bGVuZ3RoOyBuYnl0ZXMgPiA2MzsgbmJ5dGVzIC09IDY0KQ0KICB7DQogICAgZm9yICh2YXIgaT0wOyBpIDwgMTY7IGkrKykNCiAgICB7DQogICAgICBYW2ldID0gQllURVNfVE9fRFdPUkQobWVzc2FnZS5zdWJzdHIoaiwgNCkpOw0KICAgICAgaiArPSA0Ow0KICAgIH0NCiAgICBjb21wcmVzcyhNRGJ1ZiwgWCk7DQogIH0NCg0KICBNRGZpbmlzaChNRGJ1ZiwgbWVzc2FnZS5zdWJzdHIoaiksIGxlbmd0aCwgMCk7DQoNCiAgZm9yICh2YXIgaT0wOyBpIDwgUk1Ec2l6ZSAvIDg7IGkgKz0gNCkNCiAgew0KICAgIGhhc2hjb2RlW2ldICAgPSAgTURidWZbaSA+Pj4gMl0gICAmIDI1NTsNCiAgICBoYXNoY29kZVtpKzFdID0gKE1EYnVmW2kgPj4+IDJdID4+PiA4KSAgICYgMjU1Ow0KICAgIGhhc2hjb2RlW2krMl0gPSAoTURidWZbaSA+Pj4gMl0gPj4+IDE2KSAmIDI1NTsNCiAgICBoYXNoY29kZVtpKzNdID0gKE1EYnVmW2kgPj4+IDJdID4+PiAyNCkgJiAyNTU7DQogIH0NCg0KICByZXR1cm4gaGFzaGNvZGU7DQp9DQoNCg0KZnVuY3Rpb24gUk1Ec3RyaW5nKG1lc3NhZ2UpDQp7DQogIHZhciBoYXNoY29kZSA9IFJNRChtZXNzYWdlKTsNCiAgdmFyIHJldFN0cmluZyA9ICIiOw0KDQogIGZvciAodmFyIGk9MDsgaSA8IFJNRHNpemUvODsgaSsrKQ0KICB7DQogICAgcmV0U3RyaW5nICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoaGFzaGNvZGVbaV0pOw0KICB9ICANCg0KICByZXR1cm4gcmV0U3RyaW5nOyAgDQp9LyogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTSEEgZmFtaWx5IG9mIGhhc2hlcywgYXMgZGVmaW5lZCBpbiBGSVBTIA0KICogUFVCIDE4MC0yIGFzIHdlbGwgYXMgdGhlIGNvcnJlc3BvbmRpbmcgSE1BQyBpbXBsZW1lbnRhdGlvbiBhcyBkZWZpbmVkIGluDQogKiBGSVBTIFBVQiAxOThhDQogKg0KICogVmVyc2lvbiAxLjMgQ29weXJpZ2h0IEJyaWFuIFR1cmVrIDIwMDgtMjAxMA0KICogRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJTRCBMaWNlbnNlDQogKiBTZWUgaHR0cDovL2pzc2hhLnNvdXJjZWZvcmdlLm5ldC8gZm9yIG1vcmUgaW5mb3JtYXRpb24NCiAqDQogKiBTZXZlcmFsIGZ1bmN0aW9ucyB0YWtlbiBmcm9tIFBhdWwgSm9obnNvbg0KICovDQoNCi8qIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSA0KICogDQogKiBUaGlzIGNvZGUgaGFzIGJlZW4gc2xpZ2h0bHkgbW9kaWZpZWQgZGlyZWN0IHN0cmluZyBvdXRwdXQ6DQogKiAtIGJpbjJic3RyIGhhcyBiZWVuIGFkZGVkDQogKiAtIGZvbGxvd2luZyB3cmFwcGVycyBvZiB0aGlzIGxpYnJhcnkgaGF2ZSBiZWVuIGFkZGVkOg0KICogICAtIHN0cl9zaGExDQogKiAgIC0gc3RyX3NoYTI1Ng0KICogICAtIHN0cl9zaGEyMjQNCiAqICAgLSBzdHJfc2hhMzg0DQogKiAgIC0gc3RyX3NoYTUxMg0KICovDQoNCnZhciBqc1NIQSA9IChmdW5jdGlvbiAoKSB7DQoJDQoJLyoNCgkgKiBDb25maWd1cmFibGUgdmFyaWFibGVzLiBEZWZhdWx0cyB0eXBpY2FsbHkgd29yaw0KCSAqLw0KCS8qIE51bWJlciBvZiBCaXRzIFBlciBjaGFyYWN0ZXIgKDggZm9yIEFTQ0lJLCAxNiBmb3IgVW5pY29kZSkgKi8NCgl2YXIgY2hhclNpemUgPSA4LCANCgkvKiBiYXNlLTY0IHBhZCBjaGFyYWN0ZXIuICI9IiBmb3Igc3RyaWN0IFJGQyBjb21wbGlhbmNlICovDQoJYjY0cGFkID0gIiIsIA0KCS8qIGhleCBvdXRwdXQgZm9ybWF0LiAwIC0gbG93ZXJjYXNlOyAxIC0gdXBwZXJjYXNlICovDQoJaGV4Q2FzZSA9IDAsIA0KDQoJLyoNCgkgKiBJbnRfNjQgaXMgYSBvYmplY3QgZm9yIDIgMzItYml0IG51bWJlcnMgZW11bGF0aW5nIGEgNjQtYml0IG51bWJlcg0KCSAqDQoJICogQGNvbnN0cnVjdG9yDQoJICogQHBhcmFtIHtOdW1iZXJ9IG1zaW50XzMyIFRoZSBtb3N0IHNpZ25pZmljYW50IDMyLWJpdHMgb2YgYSA2NC1iaXQgbnVtYmVyDQoJICogQHBhcmFtIHtOdW1iZXJ9IGxzaW50XzMyIFRoZSBsZWFzdCBzaWduaWZpY2FudCAzMi1iaXRzIG9mIGEgNjQtYml0IG51bWJlcg0KCSAqLw0KCUludF82NCA9IGZ1bmN0aW9uIChtc2ludF8zMiwgbHNpbnRfMzIpDQoJew0KCQl0aGlzLmhpZ2hPcmRlciA9IG1zaW50XzMyOw0KCQl0aGlzLmxvd09yZGVyID0gbHNpbnRfMzI7DQoJfSwNCg0KCS8qDQoJICogQ29udmVydCBhIHN0cmluZyB0byBhbiBhcnJheSBvZiBiaWctZW5kaWFuIHdvcmRzDQoJICogSWYgY2hhclNpemUgaXMgQVNDSUksIGNoYXJhY3RlcnMgPjI1NSBoYXZlIHRoZWlyIGhpLWJ5dGUgc2lsZW50bHkNCgkgKiBpZ25vcmVkLg0KCSAqDQoJICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgdG8gYmUgY29udmVydGVkIHRvIGJpbmFyeSByZXByZXNlbnRhdGlvbg0KCSAqIEByZXR1cm4gSW50ZWdlciBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFyYW1ldGVyDQoJICovDQoJc3RyMmJpbmIgPSBmdW5jdGlvbiAoc3RyKQ0KCXsNCgkJdmFyIGJpbiA9IFtdLCBtYXNrID0gKDEgPDwgY2hhclNpemUpIC0gMSwNCgkJCWxlbmd0aCA9IHN0ci5sZW5ndGggKiBjaGFyU2l6ZSwgaTsNCg0KCQlmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IGNoYXJTaXplKQ0KCQl7DQoJCQliaW5baSA+PiA1XSB8PSAoc3RyLmNoYXJDb2RlQXQoaSAvIGNoYXJTaXplKSAmIG1hc2spIDw8DQoJCQkJKDMyIC0gY2hhclNpemUgLSAoaSAlIDMyKSk7DQoJCX0NCg0KCQlyZXR1cm4gYmluOw0KCX0sDQoNCgkvKg0KCSAqIENvbnZlcnQgYSBoZXggc3RyaW5nIHRvIGFuIGFycmF5IG9mIGJpZy1lbmRpYW4gd29yZHMNCgkgKg0KCSAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGJlIGNvbnZlcnRlZCB0byBiaW5hcnkgcmVwcmVzZW50YXRpb24NCgkgKiBAcmV0dXJuIEludGVnZXIgYXJyYXkgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhcmFtZXRlcg0KCSAqLw0KCWhleDJiaW5iID0gZnVuY3Rpb24gKHN0cikNCgl7DQoJCXZhciBiaW4gPSBbXSwgbGVuZ3RoID0gc3RyLmxlbmd0aCwgaSwgbnVtOw0KDQoJCWZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMikNCgkJew0KCQkJbnVtID0gcGFyc2VJbnQoc3RyLnN1YnN0cihpLCAyKSwgMTYpOw0KCQkJaWYgKCFpc05hTihudW0pKQ0KCQkJew0KCQkJCWJpbltpID4+IDNdIHw9IG51bSA8PCAoMjQgLSAoNCAqIChpICUgOCkpKTsNCgkJCX0NCgkJCWVsc2UNCgkJCXsNCgkJCQlyZXR1cm4gIklOVkFMSUQgSEVYIFNUUklORyI7DQoJCQl9DQoJCX0NCg0KCQlyZXR1cm4gYmluOw0KCX0sDQoNCgkvKg0KCSAqIENvbnZlcnQgYW4gYXJyYXkgb2YgYmlnLWVuZGlhbiB3b3JkcyB0byBhIGhleCBzdHJpbmcuDQoJICoNCgkgKiBAcHJpdmF0ZQ0KCSAqIEBwYXJhbSB7QXJyYXl9IGJpbmFycmF5IEFycmF5IG9mIGludGVnZXJzIHRvIGJlIGNvbnZlcnRlZCB0byBoZXhpZGVjaW1hbA0KCSAqCSByZXByZXNlbnRhdGlvbg0KCSAqIEByZXR1cm4gSGV4aWRlY2ltYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhcmFtZXRlciBpbiBTdHJpbmcgZm9ybQ0KCSAqLw0KCWJpbmIyaGV4ID0gZnVuY3Rpb24gKGJpbmFycmF5KQ0KCXsNCgkJdmFyIGhleF90YWIgPSAoaGV4Q2FzZSkgPyAiMDEyMzQ1Njc4OUFCQ0RFRiIgOiAiMDEyMzQ1Njc4OWFiY2RlZiIsDQoJCQlzdHIgPSAiIiwgbGVuZ3RoID0gYmluYXJyYXkubGVuZ3RoICogNCwgaSwgc3JjQnl0ZTsNCg0KCQlmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpDQoJCXsNCgkJCXNyY0J5dGUgPSBiaW5hcnJheVtpID4+IDJdID4+ICgoMyAtIChpICUgNCkpICogOCk7DQoJCQlzdHIgKz0gaGV4X3RhYi5jaGFyQXQoKHNyY0J5dGUgPj4gNCkgJiAweEYpICsNCgkJCQloZXhfdGFiLmNoYXJBdChzcmNCeXRlICYgMHhGKTsNCgkJfQ0KDQoJCXJldHVybiBzdHI7DQoJfSwNCg0KCS8qDQoJICogQ29udmVydCBhbiBhcnJheSBvZiBiaWctZW5kaWFuIHdvcmRzIHRvIGEgYmFzZS02NCBzdHJpbmcNCgkgKg0KCSAqIEBwcml2YXRlDQoJICogQHBhcmFtIHtBcnJheX0gYmluYXJyYXkgQXJyYXkgb2YgaW50ZWdlcnMgdG8gYmUgY29udmVydGVkIHRvIGJhc2UtNjQNCgkgKgkgcmVwcmVzZW50YXRpb24NCgkgKiBAcmV0dXJuIEJhc2UtNjQgZW5jb2RlZCByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFyYW1ldGVyIGluIFN0cmluZyBmb3JtDQoJICovDQoJYmluYjJiNjQgPSBmdW5jdGlvbiAoYmluYXJyYXkpDQoJew0KCQl2YXIgdGFiID0gIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoiICsNCgkJCSIwMTIzNDU2Nzg5Ky8iLCBzdHIgPSAiIiwgbGVuZ3RoID0gYmluYXJyYXkubGVuZ3RoICogNCwgaSwgaiwNCgkJCXRyaXBsZXQ7DQoNCgkJZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAzKQ0KCQl7DQoJCQl0cmlwbGV0ID0gKCgoYmluYXJyYXlbaSA+PiAyXSA+PiA4ICogKDMgLSBpICUgNCkpICYgMHhGRikgPDwgMTYpIHwNCgkJCQkoKChiaW5hcnJheVtpICsgMSA+PiAyXSA+PiA4ICogKDMgLSAoaSArIDEpICUgNCkpICYgMHhGRikgPDwgOCkgfA0KCQkJCSgoYmluYXJyYXlbaSArIDIgPj4gMl0gPj4gOCAqICgzIC0gKGkgKyAyKSAlIDQpKSAmIDB4RkYpOw0KCQkJZm9yIChqID0gMDsgaiA8IDQ7IGogKz0gMSkNCgkJCXsNCgkJCQlpZiAoaSAqIDggKyBqICogNiA8PSBiaW5hcnJheS5sZW5ndGggKiAzMikNCgkJCQl7DQoJCQkJCXN0ciArPSB0YWIuY2hhckF0KCh0cmlwbGV0ID4+IDYgKiAoMyAtIGopKSAmIDB4M0YpOw0KCQkJCX0NCgkJCQllbHNlDQoJCQkJew0KCQkJCQlzdHIgKz0gYjY0cGFkOw0KCQkJCX0NCgkJCX0NCgkJfQ0KCQlyZXR1cm4gc3RyOw0KCX0sDQoNCgkvKg0KCSAqIENvbnZlcnQgYW4gYXJyYXkgb2YgYmlnLWVuZGlhbiB3b3JkcyB0byBhIHN0cmluZw0KCSAqLw0KCWJpbmIyc3RyID0gZnVuY3Rpb24gKGJpbikNCgl7DQoJICB2YXIgc3RyID0gIiI7DQoJICB2YXIgbWFzayA9ICgxIDw8IDgpIC0gMTsNCgkgIGZvcih2YXIgaSA9IDA7IGkgPCBiaW4ubGVuZ3RoICogMzI7IGkgKz0gOCkNCgkgICAgc3RyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGJpbltpPj41XSA+Pj4gKDI0IC0gaSUzMikpICYgbWFzayk7DQoJICByZXR1cm4gc3RyOw0KCX0sDQoJLyoNCgkgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIGNpcmN1bGFyIHJvdGF0ZSBsZWZ0DQoJICoNCgkgKiBAcHJpdmF0ZQ0KCSAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSAzMi1iaXQgaW50ZWdlciBhcmd1bWVudA0KCSAqIEBwYXJhbSB7TnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgYml0cyB0byBzaGlmdA0KCSAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBjaXJjdWxhcmx5IGJ5IG4gYml0cw0KCSAqLw0KCXJvdGxfMzIgPSBmdW5jdGlvbiAoeCwgbikNCgl7DQoJCXJldHVybiAoeCA8PCBuKSB8ICh4ID4+PiAoMzIgLSBuKSk7DQoJfSwNCg0KCS8qDQoJICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiBjaXJjdWxhciByb3RhdGUgcmlnaHQNCgkgKg0KCSAqIEBwcml2YXRlDQoJICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50DQoJICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0DQoJICogQHJldHVybiBUaGUgeCBzaGlmdGVkIGNpcmN1bGFybHkgYnkgbiBiaXRzDQoJICovDQoJcm90cl8zMiA9IGZ1bmN0aW9uICh4LCBuKQ0KCXsNCgkJcmV0dXJuICh4ID4+PiBuKSB8ICh4IDw8ICgzMiAtIG4pKTsNCgl9LA0KDQoJLyoNCgkgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIGNpcmN1bGFyIHJvdGF0ZSByaWdodA0KCSAqDQoJICogQHByaXZhdGUNCgkgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgNjQtYml0IGludGVnZXIgYXJndW1lbnQNCgkgKiBAcGFyYW0ge051bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnQNCgkgKiBAcmV0dXJuIFRoZSB4IHNoaWZ0ZWQgY2lyY3VsYXJseSBieSBuIGJpdHMNCgkgKi8NCglyb3RyXzY0ID0gZnVuY3Rpb24gKHgsIG4pDQoJew0KCQlpZiAobiA8PSAzMikNCgkJew0KCQkJcmV0dXJuIG5ldyBJbnRfNjQoDQoJCQkJCSh4LmhpZ2hPcmRlciA+Pj4gbikgfCAoeC5sb3dPcmRlciA8PCAoMzIgLSBuKSksDQoJCQkJCSh4Lmxvd09yZGVyID4+PiBuKSB8ICh4LmhpZ2hPcmRlciA8PCAoMzIgLSBuKSkNCgkJCQkpOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJcmV0dXJuIG5ldyBJbnRfNjQoDQoJCQkJCSh4Lmxvd09yZGVyID4+PiBuKSB8ICh4LmhpZ2hPcmRlciA8PCAoMzIgLSBuKSksDQoJCQkJCSh4LmhpZ2hPcmRlciA+Pj4gbikgfCAoeC5sb3dPcmRlciA8PCAoMzIgLSBuKSkNCgkJCQkpOw0KCQl9DQoJfSwNCg0KCS8qDQoJICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiBzaGlmdCByaWdodA0KCSAqDQoJICogQHByaXZhdGUNCgkgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnQNCgkgKiBAcGFyYW0ge051bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnQNCgkgKiBAcmV0dXJuIFRoZSB4IHNoaWZ0ZWQgYnkgbiBiaXRzDQoJICovDQoJc2hyXzMyID0gZnVuY3Rpb24gKHgsIG4pDQoJew0KCQlyZXR1cm4geCA+Pj4gbjsNCgl9LA0KDQoJLyoNCgkgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHNoaWZ0IHJpZ2h0DQoJICoNCgkgKiBAcHJpdmF0ZQ0KCSAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSA2NC1iaXQgaW50ZWdlciBhcmd1bWVudA0KCSAqIEBwYXJhbSB7TnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgYml0cyB0byBzaGlmdA0KCSAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBieSBuIGJpdHMNCgkgKi8NCglzaHJfNjQgPSBmdW5jdGlvbiAoeCwgbikNCgl7DQoJCWlmIChuIDw9IDMyKQ0KCQl7DQoJCQlyZXR1cm4gbmV3IEludF82NCgNCgkJCQkJeC5oaWdoT3JkZXIgPj4+IG4sDQoJCQkJCXgubG93T3JkZXIgPj4+IG4gfCAoeC5oaWdoT3JkZXIgPDwgKDMyIC0gbikpDQoJCQkJKTsNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCXJldHVybiBuZXcgSW50XzY0KA0KCQkJCQkwLA0KCQkJCQl4LmhpZ2hPcmRlciA8PCAoMzIgLSBuKQ0KCQkJCSk7DQoJCX0NCgl9LA0KDQoJLyoNCgkgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBQYXJpdHkgZnVuY3Rpb24NCgkgKg0KCSAqIEBwcml2YXRlDQoJICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIGZpcnN0IDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50DQoJICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIHNlY29uZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudA0KCSAqIEBwYXJhbSB7TnVtYmVyfSB6IFRoZSB0aGlyZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudA0KCSAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb24NCgkgKi8NCglwYXJpdHlfMzIgPSBmdW5jdGlvbiAoeCwgeSwgeikNCgl7DQoJCXJldHVybiB4IF4geSBeIHo7DQoJfSwNCg0KCS8qDQoJICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgQ2ggZnVuY3Rpb24NCgkgKg0KCSAqIEBwcml2YXRlDQoJICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIGZpcnN0IDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50DQoJICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIHNlY29uZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudA0KCSAqIEBwYXJhbSB7TnVtYmVyfSB6IFRoZSB0aGlyZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudA0KCSAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb24NCgkgKi8NCgljaF8zMiA9IGZ1bmN0aW9uICh4LCB5LCB6KQ0KCXsNCgkJcmV0dXJuICh4ICYgeSkgXiAofnggJiB6KTsNCgl9LA0KDQoJLyoNCgkgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBDaCBmdW5jdGlvbg0KCSAqDQoJICogQHByaXZhdGUNCgkgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgZmlyc3QgNjQtYml0IGludGVnZXIgYXJndW1lbnQNCgkgKiBAcGFyYW0ge0ludF82NH0geSBUaGUgc2Vjb25kIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50DQoJICogQHBhcmFtIHtJbnRfNjR9IHogVGhlIHRoaXJkIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50DQoJICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvbg0KCSAqLw0KCWNoXzY0ID0gZnVuY3Rpb24gKHgsIHksIHopDQoJew0KCQlyZXR1cm4gbmV3IEludF82NCgNCgkJCQkoeC5oaWdoT3JkZXIgJiB5LmhpZ2hPcmRlcikgXiAofnguaGlnaE9yZGVyICYgei5oaWdoT3JkZXIpLA0KCQkJCSh4Lmxvd09yZGVyICYgeS5sb3dPcmRlcikgXiAofngubG93T3JkZXIgJiB6Lmxvd09yZGVyKQ0KCQkJKTsNCgl9LA0KDQoJLyoNCgkgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBNYWogZnVuY3Rpb24NCgkgKg0KCSAqIEBwcml2YXRlDQoJICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIGZpcnN0IDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50DQoJICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIHNlY29uZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudA0KCSAqIEBwYXJhbSB7TnVtYmVyfSB6IFRoZSB0aGlyZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudA0KCSAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb24NCgkgKi8NCgltYWpfMzIgPSBmdW5jdGlvbiAoeCwgeSwgeikNCgl7DQoJCXJldHVybiAoeCAmIHkpIF4gKHggJiB6KSBeICh5ICYgeik7DQoJfSwNCg0KCS8qDQoJICogVGhlIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgTWFqIGZ1bmN0aW9uDQoJICoNCgkgKiBAcHJpdmF0ZQ0KCSAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSBmaXJzdCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudA0KCSAqIEBwYXJhbSB7SW50XzY0fSB5IFRoZSBzZWNvbmQgNjQtYml0IGludGVnZXIgYXJndW1lbnQNCgkgKiBAcGFyYW0ge0ludF82NH0geiBUaGUgdGhpcmQgNjQtYml0IGludGVnZXIgYXJndW1lbnQNCgkgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uDQoJICovDQoJbWFqXzY0ID0gZnVuY3Rpb24gKHgsIHksIHopDQoJew0KCQlyZXR1cm4gbmV3IEludF82NCgNCgkJCQkoeC5oaWdoT3JkZXIgJiB5LmhpZ2hPcmRlcikgXg0KCQkJCSh4LmhpZ2hPcmRlciAmIHouaGlnaE9yZGVyKSBeDQoJCQkJKHkuaGlnaE9yZGVyICYgei5oaWdoT3JkZXIpLA0KCQkJCSh4Lmxvd09yZGVyICYgeS5sb3dPcmRlcikgXg0KCQkJCSh4Lmxvd09yZGVyICYgei5sb3dPcmRlcikgXg0KCQkJCSh5Lmxvd09yZGVyICYgei5sb3dPcmRlcikNCgkJCSk7DQoJfSwNCg0KCS8qDQoJICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgU2lnbWEwIGZ1bmN0aW9uDQoJICoNCgkgKiBAcHJpdmF0ZQ0KCSAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSAzMi1iaXQgaW50ZWdlciBhcmd1bWVudA0KCSAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb24NCgkgKi8NCglzaWdtYTBfMzIgPSBmdW5jdGlvbiAoeCkNCgl7DQoJCXJldHVybiByb3RyXzMyKHgsIDIpIF4gcm90cl8zMih4LCAxMykgXiByb3RyXzMyKHgsIDIyKTsNCgl9LA0KDQoJLyoNCgkgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBTaWdtYTAgZnVuY3Rpb24NCgkgKg0KCSAqIEBwcml2YXRlDQoJICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50DQoJICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvbg0KCSAqLw0KCXNpZ21hMF82NCA9IGZ1bmN0aW9uICh4KQ0KCXsNCgkJdmFyIHJvdHIyOCA9IHJvdHJfNjQoeCwgMjgpLCByb3RyMzQgPSByb3RyXzY0KHgsIDM0KSwNCgkJCXJvdHIzOSA9IHJvdHJfNjQoeCwgMzkpOw0KDQoJCXJldHVybiBuZXcgSW50XzY0KA0KCQkJCXJvdHIyOC5oaWdoT3JkZXIgXiByb3RyMzQuaGlnaE9yZGVyIF4gcm90cjM5LmhpZ2hPcmRlciwNCgkJCQlyb3RyMjgubG93T3JkZXIgXiByb3RyMzQubG93T3JkZXIgXiByb3RyMzkubG93T3JkZXIpOw0KCX0sDQoNCgkvKg0KCSAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIFNpZ21hMSBmdW5jdGlvbg0KCSAqDQoJICogQHByaXZhdGUNCgkgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnQNCgkgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uDQoJICovDQoJc2lnbWExXzMyID0gZnVuY3Rpb24gKHgpDQoJew0KCQlyZXR1cm4gcm90cl8zMih4LCA2KSBeIHJvdHJfMzIoeCwgMTEpIF4gcm90cl8zMih4LCAyNSk7DQoJfSwNCg0KCS8qDQoJICogVGhlIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgU2lnbWExIGZ1bmN0aW9uDQoJICoNCgkgKiBAcHJpdmF0ZQ0KCSAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSA2NC1iaXQgaW50ZWdlciBhcmd1bWVudA0KCSAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb24NCgkgKi8NCglzaWdtYTFfNjQgPSBmdW5jdGlvbiAoeCkNCgl7DQoJCXZhciByb3RyMTQgPSByb3RyXzY0KHgsIDE0KSwgcm90cjE4ID0gcm90cl82NCh4LCAxOCksDQoJCQlyb3RyNDEgPSByb3RyXzY0KHgsIDQxKTsNCg0KCQlyZXR1cm4gbmV3IEludF82NCgNCgkJCQlyb3RyMTQuaGlnaE9yZGVyIF4gcm90cjE4LmhpZ2hPcmRlciBeIHJvdHI0MS5oaWdoT3JkZXIsDQoJCQkJcm90cjE0Lmxvd09yZGVyIF4gcm90cjE4Lmxvd09yZGVyIF4gcm90cjQxLmxvd09yZGVyKTsNCgl9LA0KDQoJLyoNCgkgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBHYW1tYTAgZnVuY3Rpb24NCgkgKg0KCSAqIEBwcml2YXRlDQoJICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50DQoJICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvbg0KCSAqLw0KCWdhbW1hMF8zMiA9IGZ1bmN0aW9uICh4KQ0KCXsNCgkJcmV0dXJuIHJvdHJfMzIoeCwgNykgXiByb3RyXzMyKHgsIDE4KSBeIHNocl8zMih4LCAzKTsNCgl9LA0KDQoJLyoNCgkgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBHYW1tYTAgZnVuY3Rpb24NCgkgKg0KCSAqIEBwcml2YXRlDQoJICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50DQoJICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvbg0KCSAqLw0KCWdhbW1hMF82NCA9IGZ1bmN0aW9uICh4KQ0KCXsNCgkJdmFyIHJvdHIxID0gcm90cl82NCh4LCAxKSwgcm90cjggPSByb3RyXzY0KHgsIDgpLCBzaHI3ID0gc2hyXzY0KHgsIDcpOw0KDQoJCXJldHVybiBuZXcgSW50XzY0KA0KCQkJCXJvdHIxLmhpZ2hPcmRlciBeIHJvdHI4LmhpZ2hPcmRlciBeIHNocjcuaGlnaE9yZGVyLA0KCQkJCXJvdHIxLmxvd09yZGVyIF4gcm90cjgubG93T3JkZXIgXiBzaHI3Lmxvd09yZGVyDQoJCQkpOw0KCX0sDQoNCgkvKg0KCSAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIEdhbW1hMSBmdW5jdGlvbg0KCSAqDQoJICogQHByaXZhdGUNCgkgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnQNCgkgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uDQoJICovDQoJZ2FtbWExXzMyID0gZnVuY3Rpb24gKHgpDQoJew0KCQlyZXR1cm4gcm90cl8zMih4LCAxNykgXiByb3RyXzMyKHgsIDE5KSBeIHNocl8zMih4LCAxMCk7DQoJfSwNCg0KCS8qDQoJICogVGhlIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgR2FtbWExIGZ1bmN0aW9uDQoJICoNCgkgKiBAcHJpdmF0ZQ0KCSAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSA2NC1iaXQgaW50ZWdlciBhcmd1bWVudA0KCSAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb24NCgkgKi8NCglnYW1tYTFfNjQgPSBmdW5jdGlvbiAoeCkNCgl7DQoJCXZhciByb3RyMTkgPSByb3RyXzY0KHgsIDE5KSwgcm90cjYxID0gcm90cl82NCh4LCA2MSksDQoJCQlzaHI2ID0gc2hyXzY0KHgsIDYpOw0KDQoJCXJldHVybiBuZXcgSW50XzY0KA0KCQkJCXJvdHIxOS5oaWdoT3JkZXIgXiByb3RyNjEuaGlnaE9yZGVyIF4gc2hyNi5oaWdoT3JkZXIsDQoJCQkJcm90cjE5Lmxvd09yZGVyIF4gcm90cjYxLmxvd09yZGVyIF4gc2hyNi5sb3dPcmRlcg0KCQkJKTsNCgl9LA0KDQoJLyoNCgkgKiBBZGQgdHdvIDMyLWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl4zMi4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zDQoJICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLg0KCSAqDQoJICogQHByaXZhdGUNCgkgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgZmlyc3QgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWQNCgkgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgc2Vjb25kIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkDQoJICogQHJldHVybiBUaGUgc3VtIG9mIHggKyB5DQoJICovDQoJc2FmZUFkZF8zMl8yID0gZnVuY3Rpb24gKHgsIHkpDQoJew0KCQl2YXIgbHN3ID0gKHggJiAweEZGRkYpICsgKHkgJiAweEZGRkYpLA0KCQkJbXN3ID0gKHggPj4+IDE2KSArICh5ID4+PiAxNikgKyAobHN3ID4+PiAxNik7DQoNCgkJcmV0dXJuICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTsNCgl9LA0KDQoJLyoNCgkgKiBBZGQgZm91ciAzMi1iaXQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9ucw0KCSAqIGludGVybmFsbHkgdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy4NCgkgKg0KCSAqIEBwcml2YXRlDQoJICogQHBhcmFtIHtOdW1iZXJ9IGEgVGhlIGZpcnN0IDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkDQoJICogQHBhcmFtIHtOdW1iZXJ9IGIgVGhlIHNlY29uZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZA0KCSAqIEBwYXJhbSB7TnVtYmVyfSBjIFRoZSB0aGlyZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZA0KCSAqIEBwYXJhbSB7TnVtYmVyfSBkIFRoZSBmb3VydGggMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWQNCgkgKiBAcmV0dXJuIFRoZSBzdW0gb2YgYSArIGIgKyBjICsgZA0KCSAqLw0KCXNhZmVBZGRfMzJfNCA9IGZ1bmN0aW9uIChhLCBiLCBjLCBkKQ0KCXsNCgkJdmFyIGxzdyA9IChhICYgMHhGRkZGKSArIChiICYgMHhGRkZGKSArIChjICYgMHhGRkZGKSArIChkICYgMHhGRkZGKSwNCgkJCW1zdyA9IChhID4+PiAxNikgKyAoYiA+Pj4gMTYpICsgKGMgPj4+IDE2KSArIChkID4+PiAxNikgKw0KCQkJCShsc3cgPj4+IDE2KTsNCg0KCQlyZXR1cm4gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpOw0KCX0sDQoNCgkvKg0KCSAqIEFkZCBmaXZlIDMyLWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl4zMi4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zDQoJICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLg0KCSAqDQoJICogQHByaXZhdGUNCgkgKiBAcGFyYW0ge051bWJlcn0gYSBUaGUgZmlyc3QgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWQNCgkgKiBAcGFyYW0ge051bWJlcn0gYiBUaGUgc2Vjb25kIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkDQoJICogQHBhcmFtIHtOdW1iZXJ9IGMgVGhlIHRoaXJkIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkDQoJICogQHBhcmFtIHtOdW1iZXJ9IGQgVGhlIGZvdXJ0aCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZA0KCSAqIEBwYXJhbSB7TnVtYmVyfSBlIFRoZSBmaWZ0aCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZA0KCSAqIEByZXR1cm4gVGhlIHN1bSBvZiBhICsgYiArIGMgKyBkICsgZQ0KCSAqLw0KCXNhZmVBZGRfMzJfNSA9IGZ1bmN0aW9uIChhLCBiLCBjLCBkLCBlKQ0KCXsNCgkJdmFyIGxzdyA9IChhICYgMHhGRkZGKSArIChiICYgMHhGRkZGKSArIChjICYgMHhGRkZGKSArIChkICYgMHhGRkZGKSArDQoJCQkJKGUgJiAweEZGRkYpLA0KCQkJbXN3ID0gKGEgPj4+IDE2KSArIChiID4+PiAxNikgKyAoYyA+Pj4gMTYpICsgKGQgPj4+IDE2KSArDQoJCQkJKGUgPj4+IDE2KSArIChsc3cgPj4+IDE2KTsNCg0KCQlyZXR1cm4gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpOw0KCX0sDQoNCgkvKg0KCSAqIEFkZCB0d28gNjQtYml0IGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjY0LiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnMNCgkgKiBpbnRlcm5hbGx5IHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuDQoJICoNCgkgKiBAcHJpdmF0ZQ0KCSAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSBmaXJzdCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZA0KCSAqIEBwYXJhbSB7SW50XzY0fSB5IFRoZSBzZWNvbmQgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWQNCgkgKiBAcmV0dXJuIFRoZSBzdW0gb2YgeCArIHkNCgkgKi8NCglzYWZlQWRkXzY0XzIgPSBmdW5jdGlvbiAoeCwgeSkNCgl7DQoJCXZhciBsc3csIG1zdywgbG93T3JkZXIsIGhpZ2hPcmRlcjsNCg0KCQlsc3cgPSAoeC5sb3dPcmRlciAmIDB4RkZGRikgKyAoeS5sb3dPcmRlciAmIDB4RkZGRik7DQoJCW1zdyA9ICh4Lmxvd09yZGVyID4+PiAxNikgKyAoeS5sb3dPcmRlciA+Pj4gMTYpICsgKGxzdyA+Pj4gMTYpOw0KCQlsb3dPcmRlciA9ICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTsNCg0KCQlsc3cgPSAoeC5oaWdoT3JkZXIgJiAweEZGRkYpICsgKHkuaGlnaE9yZGVyICYgMHhGRkZGKSArIChtc3cgPj4+IDE2KTsNCgkJbXN3ID0gKHguaGlnaE9yZGVyID4+PiAxNikgKyAoeS5oaWdoT3JkZXIgPj4+IDE2KSArIChsc3cgPj4+IDE2KTsNCgkJaGlnaE9yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpOw0KDQoJCXJldHVybiBuZXcgSW50XzY0KGhpZ2hPcmRlciwgbG93T3JkZXIpOw0KCX0sDQoNCgkvKg0KCSAqIEFkZCBmb3VyIDY0LWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl42NC4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zDQoJICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLg0KCSAqDQoJICogQHByaXZhdGUNCgkgKiBAcGFyYW0ge0ludF82NH0gYSBUaGUgZmlyc3QgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWQNCgkgKiBAcGFyYW0ge0ludF82NH0gYiBUaGUgc2Vjb25kIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkDQoJICogQHBhcmFtIHtJbnRfNjR9IGMgVGhlIHRoaXJkIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkDQoJICogQHBhcmFtIHtJbnRfNjR9IGQgVGhlIGZvdXRoIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkDQoJICogQHJldHVybiBUaGUgc3VtIG9mIGEgKyBiICsgYyArIGQNCgkgKi8NCglzYWZlQWRkXzY0XzQgPSBmdW5jdGlvbiAoYSwgYiwgYywgZCkNCgl7DQoJCXZhciBsc3csIG1zdywgbG93T3JkZXIsIGhpZ2hPcmRlcjsNCg0KCQlsc3cgPSAoYS5sb3dPcmRlciAmIDB4RkZGRikgKyAoYi5sb3dPcmRlciAmIDB4RkZGRikgKw0KCQkJKGMubG93T3JkZXIgJiAweEZGRkYpICsgKGQubG93T3JkZXIgJiAweEZGRkYpOw0KCQltc3cgPSAoYS5sb3dPcmRlciA+Pj4gMTYpICsgKGIubG93T3JkZXIgPj4+IDE2KSArDQoJCQkoYy5sb3dPcmRlciA+Pj4gMTYpICsgKGQubG93T3JkZXIgPj4+IDE2KSArIChsc3cgPj4+IDE2KTsNCgkJbG93T3JkZXIgPSAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7DQoNCgkJbHN3ID0gKGEuaGlnaE9yZGVyICYgMHhGRkZGKSArIChiLmhpZ2hPcmRlciAmIDB4RkZGRikgKw0KCQkJKGMuaGlnaE9yZGVyICYgMHhGRkZGKSArIChkLmhpZ2hPcmRlciAmIDB4RkZGRikgKyAobXN3ID4+PiAxNik7DQoJCW1zdyA9IChhLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGIuaGlnaE9yZGVyID4+PiAxNikgKw0KCQkJKGMuaGlnaE9yZGVyID4+PiAxNikgKyAoZC5oaWdoT3JkZXIgPj4+IDE2KSArIChsc3cgPj4+IDE2KTsNCgkJaGlnaE9yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpOw0KDQoJCXJldHVybiBuZXcgSW50XzY0KGhpZ2hPcmRlciwgbG93T3JkZXIpOw0KCX0sDQoNCgkvKg0KCSAqIEFkZCBmaXZlIDY0LWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl42NC4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zDQoJICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLg0KCSAqDQoJICogQHByaXZhdGUNCgkgKiBAcGFyYW0ge0ludF82NH0gYSBUaGUgZmlyc3QgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWQNCgkgKiBAcGFyYW0ge0ludF82NH0gYiBUaGUgc2Vjb25kIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkDQoJICogQHBhcmFtIHtJbnRfNjR9IGMgVGhlIHRoaXJkIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkDQoJICogQHBhcmFtIHtJbnRfNjR9IGQgVGhlIGZvdXRoIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkDQoJICogQHBhcmFtIHtJbnRfNjR9IGUgVGhlIGZvdXRoIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkDQoJICogQHJldHVybiBUaGUgc3VtIG9mIGEgKyBiICsgYyArIGQgKyBlDQoJICovDQoJc2FmZUFkZF82NF81ID0gZnVuY3Rpb24gKGEsIGIsIGMsIGQsIGUpDQoJew0KCQl2YXIgbHN3LCBtc3csIGxvd09yZGVyLCBoaWdoT3JkZXI7DQoNCgkJbHN3ID0gKGEubG93T3JkZXIgJiAweEZGRkYpICsgKGIubG93T3JkZXIgJiAweEZGRkYpICsNCgkJCShjLmxvd09yZGVyICYgMHhGRkZGKSArIChkLmxvd09yZGVyICYgMHhGRkZGKSArDQoJCQkoZS5sb3dPcmRlciAmIDB4RkZGRik7DQoJCW1zdyA9IChhLmxvd09yZGVyID4+PiAxNikgKyAoYi5sb3dPcmRlciA+Pj4gMTYpICsNCgkJCShjLmxvd09yZGVyID4+PiAxNikgKyAoZC5sb3dPcmRlciA+Pj4gMTYpICsgKGUubG93T3JkZXIgPj4+IDE2KSArDQoJCQkobHN3ID4+PiAxNik7DQoJCWxvd09yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpOw0KDQoJCWxzdyA9IChhLmhpZ2hPcmRlciAmIDB4RkZGRikgKyAoYi5oaWdoT3JkZXIgJiAweEZGRkYpICsNCgkJCShjLmhpZ2hPcmRlciAmIDB4RkZGRikgKyAoZC5oaWdoT3JkZXIgJiAweEZGRkYpICsNCgkJCShlLmhpZ2hPcmRlciAmIDB4RkZGRikgKyAobXN3ID4+PiAxNik7DQoJCW1zdyA9IChhLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGIuaGlnaE9yZGVyID4+PiAxNikgKw0KCQkJKGMuaGlnaE9yZGVyID4+PiAxNikgKyAoZC5oaWdoT3JkZXIgPj4+IDE2KSArDQoJCQkoZS5oaWdoT3JkZXIgPj4+IDE2KSArIChsc3cgPj4+IDE2KTsNCgkJaGlnaE9yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpOw0KDQoJCXJldHVybiBuZXcgSW50XzY0KGhpZ2hPcmRlciwgbG93T3JkZXIpOw0KCX0sDQoNCgkvKg0KCSAqIENhbGN1bGF0ZXMgdGhlIFNIQS0xIGhhc2ggb2YgdGhlIHN0cmluZyBzZXQgYXQgaW5zdGFudGlhdGlvbg0KCSAqDQoJICogQHByaXZhdGUNCgkgKiBAcGFyYW0ge0FycmF5fSBtZXNzYWdlIFRoZSBiaW5hcnkgYXJyYXkgcmVwcmVzZW50YXRpb24gb2YgdGhlIHN0cmluZyB0bw0KCSAqCSBoYXNoDQoJICogQHBhcmFtIHtOdW1iZXJ9IG1lc3NhZ2VMZW4gVGhlIG51bWJlciBvZiBiaXRzIGluIHRoZSBtZXNzYWdlDQoJICogQHJldHVybiBUaGUgYXJyYXkgb2YgaW50ZWdlcnMgcmVwcmVzZW50aW5nIHRoZSBTSEEtMSBoYXNoIG9mIG1lc3NhZ2UNCgkgKi8NCgljb3JlU0hBMSA9IGZ1bmN0aW9uIChtZXNzYWdlLCBtZXNzYWdlTGVuKQ0KCXsNCgkJdmFyIFcgPSBbXSwgYSwgYiwgYywgZCwgZSwgVCwgY2ggPSBjaF8zMiwgcGFyaXR5ID0gcGFyaXR5XzMyLA0KCQkJbWFqID0gbWFqXzMyLCByb3RsID0gcm90bF8zMiwgc2FmZUFkZF8yID0gc2FmZUFkZF8zMl8yLCBpLCB0LA0KCQkJc2FmZUFkZF81ID0gc2FmZUFkZF8zMl81LCBhcHBlbmRlZE1lc3NhZ2VMZW5ndGgsDQoJCQlIID0gWw0KCQkJCTB4Njc0NTIzMDEsIDB4ZWZjZGFiODksIDB4OThiYWRjZmUsIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjANCgkJCV0sDQoJCQlLID0gWw0KCQkJCTB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksDQoJCQkJMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwNCgkJCQkweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LA0KCQkJCTB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksDQoJCQkJMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwNCgkJCQkweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLA0KCQkJCTB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsDQoJCQkJMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwNCgkJCQkweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLA0KCQkJCTB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsDQoJCQkJMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywNCgkJCQkweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLA0KCQkJCTB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsDQoJCQkJMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywNCgkJCQkweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLA0KCQkJCTB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsDQoJCQkJMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwNCgkJCQkweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LA0KCQkJCTB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsDQoJCQkJMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNg0KCQkJXTsNCg0KCQkvKiBBcHBlbmQgJzEnIGF0IHRoZSBlbmQgb2YgdGhlIGJpbmFyeSBzdHJpbmcgKi8NCgkJbWVzc2FnZVttZXNzYWdlTGVuID4+IDVdIHw9IDB4ODAgPDwgKDI0IC0gKG1lc3NhZ2VMZW4gJSAzMikpOw0KCQkvKiBBcHBlbmQgbGVuZ3RoIG9mIGJpbmFyeSBzdHJpbmcgaW4gdGhlIHBvc2l0aW9uIHN1Y2ggdGhhdCB0aGUgbmV3DQoJCWxlbmd0aCBpcyBhIG11bHRpcGxlIG9mIDUxMi4gIExvZ2ljIGRvZXMgbm90IHdvcmsgZm9yIGV2ZW4gbXVsdGlwbGVzDQoJCW9mIDUxMiBidXQgdGhlcmUgY2FuIG5ldmVyIGJlIGV2ZW4gbXVsdGlwbGVzIG9mIDUxMiAqLw0KCQltZXNzYWdlWygoKG1lc3NhZ2VMZW4gKyA2NSkgPj4gOSkgPDwgNCkgKyAxNV0gPSBtZXNzYWdlTGVuOw0KDQoJCWFwcGVuZGVkTWVzc2FnZUxlbmd0aCA9IG1lc3NhZ2UubGVuZ3RoOw0KDQoJCWZvciAoaSA9IDA7IGkgPCBhcHBlbmRlZE1lc3NhZ2VMZW5ndGg7IGkgKz0gMTYpDQoJCXsNCgkJCWEgPSBIWzBdOw0KCQkJYiA9IEhbMV07DQoJCQljID0gSFsyXTsNCgkJCWQgPSBIWzNdOw0KCQkJZSA9IEhbNF07DQoNCgkJCWZvciAodCA9IDA7IHQgPCA4MDsgdCArPSAxKQ0KCQkJew0KCQkJCWlmICh0IDwgMTYpDQoJCQkJew0KCQkJCQlXW3RdID0gbWVzc2FnZVt0ICsgaV07DQoJCQkJfQ0KCQkJCWVsc2UNCgkJCQl7DQoJCQkJCVdbdF0gPSByb3RsKFdbdCAtIDNdIF4gV1t0IC0gOF0gXiBXW3QgLSAxNF0gXiBXW3QgLSAxNl0sIDEpOw0KCQkJCX0NCg0KCQkJCWlmICh0IDwgMjApDQoJCQkJew0KCQkJCQlUID0gc2FmZUFkZF81KHJvdGwoYSwgNSksIGNoKGIsIGMsIGQpLCBlLCBLW3RdLCBXW3RdKTsNCgkJCQl9DQoJCQkJZWxzZSBpZiAodCA8IDQwKQ0KCQkJCXsNCgkJCQkJVCA9IHNhZmVBZGRfNShyb3RsKGEsIDUpLCBwYXJpdHkoYiwgYywgZCksIGUsIEtbdF0sIFdbdF0pOw0KCQkJCX0NCgkJCQllbHNlIGlmICh0IDwgNjApDQoJCQkJew0KCQkJCQlUID0gc2FmZUFkZF81KHJvdGwoYSwgNSksIG1haihiLCBjLCBkKSwgZSwgS1t0XSwgV1t0XSk7DQoJCQkJfSBlbHNlIHsNCgkJCQkJVCA9IHNhZmVBZGRfNShyb3RsKGEsIDUpLCBwYXJpdHkoYiwgYywgZCksIGUsIEtbdF0sIFdbdF0pOw0KCQkJCX0NCg0KCQkJCWUgPSBkOw0KCQkJCWQgPSBjOw0KCQkJCWMgPSByb3RsKGIsIDMwKTsNCgkJCQliID0gYTsNCgkJCQlhID0gVDsNCgkJCX0NCg0KCQkJSFswXSA9IHNhZmVBZGRfMihhLCBIWzBdKTsNCgkJCUhbMV0gPSBzYWZlQWRkXzIoYiwgSFsxXSk7DQoJCQlIWzJdID0gc2FmZUFkZF8yKGMsIEhbMl0pOw0KCQkJSFszXSA9IHNhZmVBZGRfMihkLCBIWzNdKTsNCgkJCUhbNF0gPSBzYWZlQWRkXzIoZSwgSFs0XSk7DQoJCX0NCg0KCQlyZXR1cm4gSDsNCgl9LA0KDQoJLyoNCgkgKiBDYWxjdWxhdGVzIHRoZSBkZXNpcmVkIFNIQS0yIGhhc2ggb2YgdGhlIHN0cmluZyBzZXQgYXQgaW5zdGFudGlhdGlvbg0KCSAqDQoJICogQHByaXZhdGUNCgkgKiBAcGFyYW0ge0FycmF5fSBUaGUgYmluYXJ5IGFycmF5IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzdHJpbmcgdG8gaGFzaA0KCSAqIEBwYXJhbSB7TnVtYmVyfSBUaGUgbnVtYmVyIG9mIGJpdHMgaW4gbWVzc2FnZQ0KCSAqIEBwYXJhbSB7U3RyaW5nfSB2YXJpYW50IFRoZSBkZXNpcmVkIFNIQS0yIHZhcmlhbnQNCgkgKiBAcmV0dXJuIFRoZSBhcnJheSBvZiBpbnRlZ2VycyByZXByZXNlbnRpbmcgdGhlIFNIQS0yIGhhc2ggb2YgbWVzc2FnZQ0KCSAqLw0KCWNvcmVTSEEyID0gZnVuY3Rpb24gKG1lc3NhZ2UsIG1lc3NhZ2VMZW4sIHZhcmlhbnQpDQoJew0KCQl2YXIgYSwgYiwgYywgZCwgZSwgZiwgZywgaCwgVDEsIFQyLCBILCBudW1Sb3VuZHMsIGxlbmd0aFBvc2l0aW9uLCBpLCB0LA0KCQkJYmluYXJ5U3RyaW5nSW5jLCBiaW5hcnlTdHJpbmdNdWx0LCBzYWZlQWRkXzIsIHNhZmVBZGRfNCwgc2FmZUFkZF81LA0KCQkJZ2FtbWEwLCBnYW1tYTEsIHNpZ21hMCwgc2lnbWExLCBjaCwgbWFqLCBJbnQsIEssIFcgPSBbXSwNCgkJCWFwcGVuZGVkTWVzc2FnZUxlbmd0aDsNCg0KCQkvKiBTZXQgdXAgdGhlIHZhcmlvdXMgZnVuY3Rpb24gaGFuZGxlcyBhbmQgdmFyaWFibGUgZm9yIHRoZSBzcGVjaWZpYyANCgkJICogdmFyaWFudCAqLw0KCQlpZiAodmFyaWFudCA9PT0gIlNIQS0yMjQiIHx8IHZhcmlhbnQgPT09ICJTSEEtMjU2IikNCgkJew0KCQkJLyogMzItYml0IHZhcmlhbnQgKi8NCgkJCW51bVJvdW5kcyA9IDY0Ow0KCQkJbGVuZ3RoUG9zaXRpb24gPSAoKChtZXNzYWdlTGVuICsgNjUpID4+IDkpIDw8IDQpICsgMTU7DQoJCQliaW5hcnlTdHJpbmdJbmMgPSAxNjsNCgkJCWJpbmFyeVN0cmluZ011bHQgPSAxOw0KCQkJSW50ID0gTnVtYmVyOw0KCQkJc2FmZUFkZF8yID0gc2FmZUFkZF8zMl8yOw0KCQkJc2FmZUFkZF80ID0gc2FmZUFkZF8zMl80Ow0KCQkJc2FmZUFkZF81ID0gc2FmZUFkZF8zMl81Ow0KCQkJZ2FtbWEwID0gZ2FtbWEwXzMyOw0KCQkJZ2FtbWExID0gZ2FtbWExXzMyOw0KCQkJc2lnbWEwID0gc2lnbWEwXzMyOw0KCQkJc2lnbWExID0gc2lnbWExXzMyOw0KCQkJbWFqID0gbWFqXzMyOw0KCQkJY2ggPSBjaF8zMjsNCgkJCUsgPSBbDQoJCQkJCTB4NDI4QTJGOTgsIDB4NzEzNzQ0OTEsIDB4QjVDMEZCQ0YsIDB4RTlCNURCQTUsDQoJCQkJCTB4Mzk1NkMyNUIsIDB4NTlGMTExRjEsIDB4OTIzRjgyQTQsIDB4QUIxQzVFRDUsDQoJCQkJCTB4RDgwN0FBOTgsIDB4MTI4MzVCMDEsIDB4MjQzMTg1QkUsIDB4NTUwQzdEQzMsDQoJCQkJCTB4NzJCRTVENzQsIDB4ODBERUIxRkUsIDB4OUJEQzA2QTcsIDB4QzE5QkYxNzQsDQoJCQkJCTB4RTQ5QjY5QzEsIDB4RUZCRTQ3ODYsIDB4MEZDMTlEQzYsIDB4MjQwQ0ExQ0MsDQoJCQkJCTB4MkRFOTJDNkYsIDB4NEE3NDg0QUEsIDB4NUNCMEE5REMsIDB4NzZGOTg4REEsDQoJCQkJCTB4OTgzRTUxNTIsIDB4QTgzMUM2NkQsIDB4QjAwMzI3QzgsIDB4QkY1OTdGQzcsDQoJCQkJCTB4QzZFMDBCRjMsIDB4RDVBNzkxNDcsIDB4MDZDQTYzNTEsIDB4MTQyOTI5NjcsDQoJCQkJCTB4MjdCNzBBODUsIDB4MkUxQjIxMzgsIDB4NEQyQzZERkMsIDB4NTMzODBEMTMsDQoJCQkJCTB4NjUwQTczNTQsIDB4NzY2QTBBQkIsIDB4ODFDMkM5MkUsIDB4OTI3MjJDODUsDQoJCQkJCTB4QTJCRkU4QTEsIDB4QTgxQTY2NEIsIDB4QzI0QjhCNzAsIDB4Qzc2QzUxQTMsDQoJCQkJCTB4RDE5MkU4MTksIDB4RDY5OTA2MjQsIDB4RjQwRTM1ODUsIDB4MTA2QUEwNzAsDQoJCQkJCTB4MTlBNEMxMTYsIDB4MUUzNzZDMDgsIDB4Mjc0ODc3NEMsIDB4MzRCMEJDQjUsDQoJCQkJCTB4MzkxQzBDQjMsIDB4NEVEOEFBNEEsIDB4NUI5Q0NBNEYsIDB4NjgyRTZGRjMsDQoJCQkJCTB4NzQ4RjgyRUUsIDB4NzhBNTYzNkYsIDB4ODRDODc4MTQsIDB4OENDNzAyMDgsDQoJCQkJCTB4OTBCRUZGRkEsIDB4QTQ1MDZDRUIsIDB4QkVGOUEzRjcsIDB4QzY3MTc4RjINCgkJCQldOw0KDQoJCQlpZiAodmFyaWFudCA9PT0gIlNIQS0yMjQiKQ0KCQkJew0KCQkJCUggPSBbDQoJCQkJCQkweGMxMDU5ZWQ4LCAweDM2N2NkNTA3LCAweDMwNzBkZDE3LCAweGY3MGU1OTM5LA0KCQkJCQkJMHhmZmMwMGIzMSwgMHg2ODU4MTUxMSwgMHg2NGY5OGZhNywgMHhiZWZhNGZhNA0KCQkJCQldOw0KCQkJfQ0KCQkJZWxzZQ0KCQkJew0KCQkJCUggPSBbDQoJCQkJCQkweDZBMDlFNjY3LCAweEJCNjdBRTg1LCAweDNDNkVGMzcyLCAweEE1NEZGNTNBLA0KCQkJCQkJMHg1MTBFNTI3RiwgMHg5QjA1Njg4QywgMHgxRjgzRDlBQiwgMHg1QkUwQ0QxOQ0KCQkJCQldOw0KCQkJfQ0KCQl9DQoJCWVsc2UgaWYgKHZhcmlhbnQgPT09ICJTSEEtMzg0IiB8fCB2YXJpYW50ID09PSAiU0hBLTUxMiIpDQoJCXsNCgkJCS8qIDY0LWJpdCB2YXJpYW50ICovDQoJCQludW1Sb3VuZHMgPSA4MDsNCgkJCWxlbmd0aFBvc2l0aW9uID0gKCgobWVzc2FnZUxlbiArIDEyOCkgPj4gMTApIDw8IDUpICsgMzE7DQoJCQliaW5hcnlTdHJpbmdJbmMgPSAzMjsNCgkJCWJpbmFyeVN0cmluZ011bHQgPSAyOw0KCQkJSW50ID0gSW50XzY0Ow0KCQkJc2FmZUFkZF8yID0gc2FmZUFkZF82NF8yOw0KCQkJc2FmZUFkZF80ID0gc2FmZUFkZF82NF80Ow0KCQkJc2FmZUFkZF81ID0gc2FmZUFkZF82NF81Ow0KCQkJZ2FtbWEwID0gZ2FtbWEwXzY0Ow0KCQkJZ2FtbWExID0gZ2FtbWExXzY0Ow0KCQkJc2lnbWEwID0gc2lnbWEwXzY0Ow0KCQkJc2lnbWExID0gc2lnbWExXzY0Ow0KCQkJbWFqID0gbWFqXzY0Ow0KCQkJY2ggPSBjaF82NDsNCg0KCQkJSyA9IFsNCgkJCQluZXcgSW50KDB4NDI4YTJmOTgsIDB4ZDcyOGFlMjIpLCBuZXcgSW50KDB4NzEzNzQ0OTEsIDB4MjNlZjY1Y2QpLA0KCQkJCW5ldyBJbnQoMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiksIG5ldyBJbnQoMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyksDQoJCQkJbmV3IEludCgweDM5NTZjMjViLCAweGYzNDhiNTM4KSwgbmV3IEludCgweDU5ZjExMWYxLCAweGI2MDVkMDE5KSwNCgkJCQluZXcgSW50KDB4OTIzZjgyYTQsIDB4YWYxOTRmOWIpLCBuZXcgSW50KDB4YWIxYzVlZDUsIDB4ZGE2ZDgxMTgpLA0KCQkJCW5ldyBJbnQoMHhkODA3YWE5OCwgMHhhMzAzMDI0MiksIG5ldyBJbnQoMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSksDQoJCQkJbmV3IEludCgweDI0MzE4NWJlLCAweDRlZTRiMjhjKSwgbmV3IEludCgweDU1MGM3ZGMzLCAweGQ1ZmZiNGUyKSwNCgkJCQluZXcgSW50KDB4NzJiZTVkNzQsIDB4ZjI3Yjg5NmYpLCBuZXcgSW50KDB4ODBkZWIxZmUsIDB4M2IxNjk2YjEpLA0KCQkJCW5ldyBJbnQoMHg5YmRjMDZhNywgMHgyNWM3MTIzNSksIG5ldyBJbnQoMHhjMTliZjE3NCwgMHhjZjY5MjY5NCksDQoJCQkJbmV3IEludCgweGU0OWI2OWMxLCAweDllZjE0YWQyKSwgbmV3IEludCgweGVmYmU0Nzg2LCAweDM4NGYyNWUzKSwNCgkJCQluZXcgSW50KDB4MGZjMTlkYzYsIDB4OGI4Y2Q1YjUpLCBuZXcgSW50KDB4MjQwY2ExY2MsIDB4NzdhYzljNjUpLA0KCQkJCW5ldyBJbnQoMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSksIG5ldyBJbnQoMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyksDQoJCQkJbmV3IEludCgweDVjYjBhOWRjLCAweGJkNDFmYmQ0KSwgbmV3IEludCgweDc2Zjk4OGRhLCAweDgzMTE1M2I1KSwNCgkJCQluZXcgSW50KDB4OTgzZTUxNTIsIDB4ZWU2NmRmYWIpLCBuZXcgSW50KDB4YTgzMWM2NmQsIDB4MmRiNDMyMTApLA0KCQkJCW5ldyBJbnQoMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiksIG5ldyBJbnQoMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCksDQoJCQkJbmV3IEludCgweGM2ZTAwYmYzLCAweDNkYTg4ZmMyKSwgbmV3IEludCgweGQ1YTc5MTQ3LCAweDkzMGFhNzI1KSwNCgkJCQluZXcgSW50KDB4MDZjYTYzNTEsIDB4ZTAwMzgyNmYpLCBuZXcgSW50KDB4MTQyOTI5NjcsIDB4MGEwZTZlNzApLA0KCQkJCW5ldyBJbnQoMHgyN2I3MGE4NSwgMHg0NmQyMmZmYyksIG5ldyBJbnQoMHgyZTFiMjEzOCwgMHg1YzI2YzkyNiksDQoJCQkJbmV3IEludCgweDRkMmM2ZGZjLCAweDVhYzQyYWVkKSwgbmV3IEludCgweDUzMzgwZDEzLCAweDlkOTViM2RmKSwNCgkJCQluZXcgSW50KDB4NjUwYTczNTQsIDB4OGJhZjYzZGUpLCBuZXcgSW50KDB4NzY2YTBhYmIsIDB4M2M3N2IyYTgpLA0KCQkJCW5ldyBJbnQoMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiksIG5ldyBJbnQoMHg5MjcyMmM4NSwgMHgxNDgyMzUzYiksDQoJCQkJbmV3IEludCgweGEyYmZlOGExLCAweDRjZjEwMzY0KSwgbmV3IEludCgweGE4MWE2NjRiLCAweGJjNDIzMDAxKSwNCgkJCQluZXcgSW50KDB4YzI0YjhiNzAsIDB4ZDBmODk3OTEpLCBuZXcgSW50KDB4Yzc2YzUxYTMsIDB4MDY1NGJlMzApLA0KCQkJCW5ldyBJbnQoMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCksIG5ldyBJbnQoMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCksDQoJCQkJbmV3IEludCgweGY0MGUzNTg1LCAweDU3NzEyMDJhKSwgbmV3IEludCgweDEwNmFhMDcwLCAweDMyYmJkMWI4KSwNCgkJCQluZXcgSW50KDB4MTlhNGMxMTYsIDB4YjhkMmQwYzgpLCBuZXcgSW50KDB4MWUzNzZjMDgsIDB4NTE0MWFiNTMpLA0KCQkJCW5ldyBJbnQoMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSksIG5ldyBJbnQoMHgzNGIwYmNiNSwgMHhlMTliNDhhOCksDQoJCQkJbmV3IEludCgweDM5MWMwY2IzLCAweGM1Yzk1YTYzKSwgbmV3IEludCgweDRlZDhhYTRhLCAweGUzNDE4YWNiKSwNCgkJCQluZXcgSW50KDB4NWI5Y2NhNGYsIDB4Nzc2M2UzNzMpLCBuZXcgSW50KDB4NjgyZTZmZjMsIDB4ZDZiMmI4YTMpLA0KCQkJCW5ldyBJbnQoMHg3NDhmODJlZSwgMHg1ZGVmYjJmYyksIG5ldyBJbnQoMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCksDQoJCQkJbmV3IEludCgweDg0Yzg3ODE0LCAweGExZjBhYjcyKSwgbmV3IEludCgweDhjYzcwMjA4LCAweDFhNjQzOWVjKSwNCgkJCQluZXcgSW50KDB4OTBiZWZmZmEsIDB4MjM2MzFlMjgpLCBuZXcgSW50KDB4YTQ1MDZjZWIsIDB4ZGU4MmJkZTkpLA0KCQkJCW5ldyBJbnQoMHhiZWY5YTNmNywgMHhiMmM2NzkxNSksIG5ldyBJbnQoMHhjNjcxNzhmMiwgMHhlMzcyNTMyYiksDQoJCQkJbmV3IEludCgweGNhMjczZWNlLCAweGVhMjY2MTljKSwgbmV3IEludCgweGQxODZiOGM3LCAweDIxYzBjMjA3KSwNCgkJCQluZXcgSW50KDB4ZWFkYTdkZDYsIDB4Y2RlMGViMWUpLCBuZXcgSW50KDB4ZjU3ZDRmN2YsIDB4ZWU2ZWQxNzgpLA0KCQkJCW5ldyBJbnQoMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSksIG5ldyBJbnQoMHgwYTYzN2RjNSwgMHhhMmM4OThhNiksDQoJCQkJbmV3IEludCgweDExM2Y5ODA0LCAweGJlZjkwZGFlKSwgbmV3IEludCgweDFiNzEwYjM1LCAweDEzMWM0NzFiKSwNCgkJCQluZXcgSW50KDB4MjhkYjc3ZjUsIDB4MjMwNDdkODQpLCBuZXcgSW50KDB4MzJjYWFiN2IsIDB4NDBjNzI0OTMpLA0KCQkJCW5ldyBJbnQoMHgzYzllYmUwYSwgMHgxNWM5YmViYyksIG5ldyBJbnQoMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyksDQoJCQkJbmV3IEludCgweDRjYzVkNGJlLCAweGNiM2U0MmI2KSwgbmV3IEludCgweDU5N2YyOTljLCAweGZjNjU3ZTJhKSwNCgkJCQluZXcgSW50KDB4NWZjYjZmYWIsIDB4M2FkNmZhZWMpLCBuZXcgSW50KDB4NmM0NDE5OGMsIDB4NGE0NzU4MTcpDQoJCQldOw0KDQoJCQlpZiAodmFyaWFudCA9PT0gIlNIQS0zODQiKQ0KCQkJew0KCQkJCUggPSBbDQoJCQkJCW5ldyBJbnQoMHhjYmJiOWQ1ZCwgMHhjMTA1OWVkOCksIG5ldyBJbnQoMHgwNjI5YTI5MmEsIDB4MzY3Y2Q1MDcpLA0KCQkJCQluZXcgSW50KDB4OTE1OTAxNWEsIDB4MzA3MGRkMTcpLCBuZXcgSW50KDB4MDE1MmZlY2Q4LCAweGY3MGU1OTM5KSwNCgkJCQkJbmV3IEludCgweDY3MzMyNjY3LCAweGZmYzAwYjMxKSwgbmV3IEludCgweDk4ZWI0NGE4NywgMHg2ODU4MTUxMSksDQoJCQkJCW5ldyBJbnQoMHhkYjBjMmUwZCwgMHg2NGY5OGZhNyksIG5ldyBJbnQoMHgwNDdiNTQ4MWQsIDB4YmVmYTRmYTQpDQoJCQkJXTsNCgkJCX0NCgkJCWVsc2UNCgkJCXsNCgkJCQlIID0gWw0KCQkJCQluZXcgSW50KDB4NmEwOWU2NjcsIDB4ZjNiY2M5MDgpLCBuZXcgSW50KDB4YmI2N2FlODUsIDB4ODRjYWE3M2IpLA0KCQkJCQluZXcgSW50KDB4M2M2ZWYzNzIsIDB4ZmU5NGY4MmIpLCBuZXcgSW50KDB4YTU0ZmY1M2EsIDB4NWYxZDM2ZjEpLA0KCQkJCQluZXcgSW50KDB4NTEwZTUyN2YsIDB4YWRlNjgyZDEpLCBuZXcgSW50KDB4OWIwNTY4OGMsIDB4MmIzZTZjMWYpLA0KCQkJCQluZXcgSW50KDB4MWY4M2Q5YWIsIDB4ZmI0MWJkNmIpLCBuZXcgSW50KDB4NWJlMGNkMTksIDB4MTM3ZTIxNzkpDQoJCQkJXTsNCgkJCX0NCgkJfQ0KDQoJCS8qIEFwcGVuZCAnMScgYXQgdGhlIGVuZCBvZiB0aGUgYmluYXJ5IHN0cmluZyAqLw0KCQltZXNzYWdlW21lc3NhZ2VMZW4gPj4gNV0gfD0gMHg4MCA8PCAoMjQgLSBtZXNzYWdlTGVuICUgMzIpOw0KCQkvKiBBcHBlbmQgbGVuZ3RoIG9mIGJpbmFyeSBzdHJpbmcgaW4gdGhlIHBvc2l0aW9uIHN1Y2ggdGhhdCB0aGUgbmV3DQoJCSAqIGxlbmd0aCBpcyBjb3JyZWN0ICovDQoJCW1lc3NhZ2VbbGVuZ3RoUG9zaXRpb25dID0gbWVzc2FnZUxlbjsNCg0KCQlhcHBlbmRlZE1lc3NhZ2VMZW5ndGggPSBtZXNzYWdlLmxlbmd0aDsNCg0KCQlmb3IgKGkgPSAwOyBpIDwgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoOyBpICs9IGJpbmFyeVN0cmluZ0luYykNCgkJew0KCQkJYSA9IEhbMF07DQoJCQliID0gSFsxXTsNCgkJCWMgPSBIWzJdOw0KCQkJZCA9IEhbM107DQoJCQllID0gSFs0XTsNCgkJCWYgPSBIWzVdOw0KCQkJZyA9IEhbNl07DQoJCQloID0gSFs3XTsNCg0KCQkJZm9yICh0ID0gMDsgdCA8IG51bVJvdW5kczsgdCArPSAxKQ0KCQkJew0KCQkJCWlmICh0IDwgMTYpDQoJCQkJew0KCQkJCQkvKiBCaXQgb2YgYSBoYWNrIC0gZm9yIDMyLWJpdCwgdGhlIHNlY29uZCB0ZXJtIGlzIGlnbm9yZWQgKi8NCgkJCQkJV1t0XSA9IG5ldyBJbnQobWVzc2FnZVt0ICogYmluYXJ5U3RyaW5nTXVsdCArIGldLA0KCQkJCQkJCW1lc3NhZ2VbdCAqIGJpbmFyeVN0cmluZ011bHQgKyBpICsgMV0pOw0KCQkJCX0NCgkJCQllbHNlDQoJCQkJew0KCQkJCQlXW3RdID0gc2FmZUFkZF80KA0KCQkJCQkJCWdhbW1hMShXW3QgLSAyXSksIFdbdCAtIDddLA0KCQkJCQkJCWdhbW1hMChXW3QgLSAxNV0pLCBXW3QgLSAxNl0NCgkJCQkJCSk7DQoJCQkJfQ0KDQoJCQkJVDEgPSBzYWZlQWRkXzUoaCwgc2lnbWExKGUpLCBjaChlLCBmLCBnKSwgS1t0XSwgV1t0XSk7DQoJCQkJVDIgPSBzYWZlQWRkXzIoc2lnbWEwKGEpLCBtYWooYSwgYiwgYykpOw0KCQkJCWggPSBnOw0KCQkJCWcgPSBmOw0KCQkJCWYgPSBlOw0KCQkJCWUgPSBzYWZlQWRkXzIoZCwgVDEpOw0KCQkJCWQgPSBjOw0KCQkJCWMgPSBiOw0KCQkJCWIgPSBhOw0KCQkJCWEgPSBzYWZlQWRkXzIoVDEsIFQyKTsNCgkJCX0NCg0KCQkJSFswXSA9IHNhZmVBZGRfMihhLCBIWzBdKTsNCgkJCUhbMV0gPSBzYWZlQWRkXzIoYiwgSFsxXSk7DQoJCQlIWzJdID0gc2FmZUFkZF8yKGMsIEhbMl0pOw0KCQkJSFszXSA9IHNhZmVBZGRfMihkLCBIWzNdKTsNCgkJCUhbNF0gPSBzYWZlQWRkXzIoZSwgSFs0XSk7DQoJCQlIWzVdID0gc2FmZUFkZF8yKGYsIEhbNV0pOw0KCQkJSFs2XSA9IHNhZmVBZGRfMihnLCBIWzZdKTsNCgkJCUhbN10gPSBzYWZlQWRkXzIoaCwgSFs3XSk7DQoJCX0NCg0KCQlzd2l0Y2ggKHZhcmlhbnQpDQoJCXsNCgkJY2FzZSAiU0hBLTIyNCI6DQoJCQlyZXR1cm4JWw0KCQkJCUhbMF0sIEhbMV0sIEhbMl0sIEhbM10sDQoJCQkJSFs0XSwgSFs1XSwgSFs2XQ0KCQkJXTsNCgkJY2FzZSAiU0hBLTI1NiI6DQoJCQlyZXR1cm4gSDsNCgkJY2FzZSAiU0hBLTM4NCI6DQoJCQlyZXR1cm4gWw0KCQkJCUhbMF0uaGlnaE9yZGVyLCBIWzBdLmxvd09yZGVyLA0KCQkJCUhbMV0uaGlnaE9yZGVyLCBIWzFdLmxvd09yZGVyLA0KCQkJCUhbMl0uaGlnaE9yZGVyLCBIWzJdLmxvd09yZGVyLA0KCQkJCUhbM10uaGlnaE9yZGVyLCBIWzNdLmxvd09yZGVyLA0KCQkJCUhbNF0uaGlnaE9yZGVyLCBIWzRdLmxvd09yZGVyLA0KCQkJCUhbNV0uaGlnaE9yZGVyLCBIWzVdLmxvd09yZGVyDQoJCQldOw0KCQljYXNlICJTSEEtNTEyIjoNCgkJCXJldHVybiBbDQoJCQkJSFswXS5oaWdoT3JkZXIsIEhbMF0ubG93T3JkZXIsDQoJCQkJSFsxXS5oaWdoT3JkZXIsIEhbMV0ubG93T3JkZXIsDQoJCQkJSFsyXS5oaWdoT3JkZXIsIEhbMl0ubG93T3JkZXIsDQoJCQkJSFszXS5oaWdoT3JkZXIsIEhbM10ubG93T3JkZXIsDQoJCQkJSFs0XS5oaWdoT3JkZXIsIEhbNF0ubG93T3JkZXIsDQoJCQkJSFs1XS5oaWdoT3JkZXIsIEhbNV0ubG93T3JkZXIsDQoJCQkJSFs2XS5oaWdoT3JkZXIsIEhbNl0ubG93T3JkZXIsDQoJCQkJSFs3XS5oaWdoT3JkZXIsIEhbN10ubG93T3JkZXINCgkJCV07DQoJCWRlZmF1bHQ6DQoJCQkvKiBUaGlzIHNob3VsZCBuZXZlciBiZSByZWFjaGVkICovDQoJCQlyZXR1cm4gW107IA0KCQl9DQoJfSwNCg0KCS8qDQoJICoganNTSEEgaXMgdGhlIHdvcmtob3JzZSBvZiB0aGUgbGlicmFyeS4gIEluc3RhbnRpYXRlIGl0IHdpdGggdGhlIHN0cmluZyB0bw0KCSAqIGJlIGhhc2hlZCBhcyB0aGUgcGFyYW1ldGVyDQoJICoNCgkgKiBAY29uc3RydWN0b3INCgkgKiBAcGFyYW0ge1N0cmluZ30gc3JjU3RyaW5nIFRoZSBzdHJpbmcgdG8gYmUgaGFzaGVkDQoJICogQHBhcmFtIHtTdHJpbmd9IGlucHV0Rm9ybWF0IFRoZSBmb3JtYXQgb2Ygc3JjU3RyaW5nLCBBU0NJSSBvciBIRVgNCgkgKi8NCglqc1NIQSA9IGZ1bmN0aW9uIChzcmNTdHJpbmcsIGlucHV0Rm9ybWF0KQ0KCXsNCg0KCQl0aGlzLnNoYTEgPSBudWxsOw0KCQl0aGlzLnNoYTIyNCA9IG51bGw7DQoJCXRoaXMuc2hhMjU2ID0gbnVsbDsNCgkJdGhpcy5zaGEzODQgPSBudWxsOw0KCQl0aGlzLnNoYTUxMiA9IG51bGw7DQoNCgkJdGhpcy5zdHJCaW5MZW4gPSBudWxsOw0KCQl0aGlzLnN0clRvSGFzaCA9IG51bGw7DQoNCgkJLyogQ29udmVydCB0aGUgaW5wdXQgc3RyaW5nIGludG8gdGhlIGNvcnJlY3QgdHlwZSAqLw0KCQlpZiAoIkhFWCIgPT09IGlucHV0Rm9ybWF0KQ0KCQl7DQoJCQlpZiAoMCAhPT0gKHNyY1N0cmluZy5sZW5ndGggJSAyKSkNCgkJCXsNCgkJCQlyZXR1cm4gIlRFWFQgTVVTVCBCRSBJTiBCWVRFIElOQ1JFTUVOVFMiOw0KCQkJfQ0KCQkJdGhpcy5zdHJCaW5MZW4gPSBzcmNTdHJpbmcubGVuZ3RoICogNDsNCgkJCXRoaXMuc3RyVG9IYXNoID0gaGV4MmJpbmIoc3JjU3RyaW5nKTsNCgkJfQ0KCQllbHNlIGlmICgoIkFTQ0lJIiA9PT0gaW5wdXRGb3JtYXQpIHx8DQoJCQkgKCd1bmRlZmluZWQnID09PSB0eXBlb2YoaW5wdXRGb3JtYXQpKSkNCgkJew0KCQkJdGhpcy5zdHJCaW5MZW4gPSBzcmNTdHJpbmcubGVuZ3RoICogY2hhclNpemU7DQoJCQl0aGlzLnN0clRvSGFzaCA9IHN0cjJiaW5iKHNyY1N0cmluZyk7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQlyZXR1cm4gIlVOS05PV04gVEVYVCBJTlBVVCBUWVBFIjsNCgkJfQ0KCX07DQoNCglqc1NIQS5wcm90b3R5cGUgPSB7DQoJCS8qDQoJCSAqIFJldHVybnMgdGhlIGRlc2lyZWQgU0hBIGhhc2ggb2YgdGhlIHN0cmluZyBzcGVjaWZpZWQgYXQgaW5zdGFudGlhdGlvbg0KCQkgKiB1c2luZyB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMNCgkJICoNCgkJICogQHBhcmFtIHtTdHJpbmd9IHZhcmlhbnQgVGhlIGRlc2lyZWQgU0hBIHZhcmlhbnQgKFNIQS0xLCBTSEEtMjI0LA0KCQkgKgkgU0hBLTI1NiwgU0hBLTM4NCwgb3IgU0hBLTUxMikNCgkJICogQHBhcmFtIHtTdHJpbmd9IGZvcm1hdCBUaGUgZGVzaXJlZCBvdXRwdXQgZm9ybWF0dGluZyAoQjY0IG9yIEhFWCkNCgkJICogQHJldHVybiBUaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBoYXNoIGluIHRoZSBmb3JtYXQgc3BlY2lmaWVkDQoJCSAqLw0KCQlnZXRIYXNoIDogZnVuY3Rpb24gKHZhcmlhbnQsIGZvcm1hdCkNCgkJew0KCQkJdmFyIGZvcm1hdEZ1bmMgPSBudWxsLCBtZXNzYWdlID0gdGhpcy5zdHJUb0hhc2guc2xpY2UoKTsNCg0KCQkJc3dpdGNoIChmb3JtYXQpDQoJCQl7DQoJCQljYXNlICJIRVgiOg0KCQkJCWZvcm1hdEZ1bmMgPSBiaW5iMmhleDsNCgkJCQlicmVhazsNCgkJCWNhc2UgIkI2NCI6DQoJCQkJZm9ybWF0RnVuYyA9IGJpbmIyYjY0Ow0KCQkJCWJyZWFrOw0KCQkJY2FzZSAiQVNDSUkiOg0KCQkJCWZvcm1hdEZ1bmMgPSBiaW5iMnN0cjsNCgkJCQlicmVhazsNCgkJCWRlZmF1bHQ6DQoJCQkJcmV0dXJuICJGT1JNQVQgTk9UIFJFQ09HTklaRUQiOw0KCQkJfQ0KDQoJCQlzd2l0Y2ggKHZhcmlhbnQpDQoJCQl7DQoJCQljYXNlICJTSEEtMSI6DQoJCQkJaWYgKG51bGwgPT09IHRoaXMuc2hhMSkNCgkJCQl7DQoJCQkJCXRoaXMuc2hhMSA9IGNvcmVTSEExKG1lc3NhZ2UsIHRoaXMuc3RyQmluTGVuKTsNCgkJCQl9DQoJCQkJcmV0dXJuIGZvcm1hdEZ1bmModGhpcy5zaGExKTsNCgkJCWNhc2UgIlNIQS0yMjQiOg0KCQkJCWlmIChudWxsID09PSB0aGlzLnNoYTIyNCkNCgkJCQl7DQoJCQkJCXRoaXMuc2hhMjI0ID0gY29yZVNIQTIobWVzc2FnZSwgdGhpcy5zdHJCaW5MZW4sIHZhcmlhbnQpOw0KCQkJCX0NCgkJCQlyZXR1cm4gZm9ybWF0RnVuYyh0aGlzLnNoYTIyNCk7DQoJCQljYXNlICJTSEEtMjU2IjoNCgkJCQlpZiAobnVsbCA9PT0gdGhpcy5zaGEyNTYpDQoJCQkJew0KCQkJCQl0aGlzLnNoYTI1NiA9IGNvcmVTSEEyKG1lc3NhZ2UsIHRoaXMuc3RyQmluTGVuLCB2YXJpYW50KTsNCgkJCQl9DQoJCQkJcmV0dXJuIGZvcm1hdEZ1bmModGhpcy5zaGEyNTYpOw0KCQkJY2FzZSAiU0hBLTM4NCI6DQoJCQkJaWYgKG51bGwgPT09IHRoaXMuc2hhMzg0KQ0KCQkJCXsNCgkJCQkJdGhpcy5zaGEzODQgPSBjb3JlU0hBMihtZXNzYWdlLCB0aGlzLnN0ckJpbkxlbiwgdmFyaWFudCk7DQoJCQkJfQ0KCQkJCXJldHVybiBmb3JtYXRGdW5jKHRoaXMuc2hhMzg0KTsNCgkJCWNhc2UgIlNIQS01MTIiOg0KCQkJCWlmIChudWxsID09PSB0aGlzLnNoYTUxMikNCgkJCQl7DQoJCQkJCXRoaXMuc2hhNTEyID0gY29yZVNIQTIobWVzc2FnZSwgdGhpcy5zdHJCaW5MZW4sIHZhcmlhbnQpOw0KCQkJCX0NCgkJCQlyZXR1cm4gZm9ybWF0RnVuYyh0aGlzLnNoYTUxMik7DQoJCQlkZWZhdWx0Og0KCQkJCXJldHVybiAiSEFTSCBOT1QgUkVDT0dOSVpFRCI7DQoJCQl9DQoJCX0sDQoNCgkJLyoNCgkJICogUmV0dXJucyB0aGUgZGVzaXJlZCBITUFDIG9mIHRoZSBzdHJpbmcgc3BlY2lmaWVkIGF0IGluc3RhbnRpYXRpb24NCgkJICogdXNpbmcgdGhlIGtleSBhbmQgdmFyaWFudCBwYXJhbS4NCgkJICoNCgkJICogQHBhcmFtIHtTdHJpbmd9IGtleSBUaGUga2V5IHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBITUFDDQoJCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dEZvcm1hdCBUaGUgZm9ybWF0IG9mIGtleSwgQVNDSUkgb3IgSEVYDQoJCSAqIEBwYXJhbSB7U3RyaW5nfSB2YXJpYW50IFRoZSBkZXNpcmVkIFNIQSB2YXJpYW50IChTSEEtMSwgU0hBLTIyNCwNCgkJICoJIFNIQS0yNTYsIFNIQS0zODQsIG9yIFNIQS01MTIpDQoJCSAqIEBwYXJhbSB7U3RyaW5nfSBvdXRwdXRGb3JtYXQgVGhlIGRlc2lyZWQgb3V0cHV0IGZvcm1hdHRpbmcNCgkJICoJIChCNjQgb3IgSEVYKQ0KCQkgKiBAcmV0dXJuIFRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGhhc2ggaW4gdGhlIGZvcm1hdCBzcGVjaWZpZWQNCgkJICovDQoJCWdldEhNQUMgOiBmdW5jdGlvbiAoa2V5LCBpbnB1dEZvcm1hdCwgdmFyaWFudCwgb3V0cHV0Rm9ybWF0KQ0KCQl7DQoJCQl2YXIgZm9ybWF0RnVuYywga2V5VG9Vc2UsIGJsb2NrQnl0ZVNpemUsIGJsb2NrQml0U2l6ZSwgaSwNCgkJCQlyZXRWYWwsIGxhc3RBcnJheUluZGV4LCBrZXlCaW5MZW4sIGhhc2hCaXRTaXplLA0KCQkJCWtleVdpdGhJUGFkID0gW10sIGtleVdpdGhPUGFkID0gW107DQoNCgkJCS8qIFZhbGlkYXRlIHRoZSBvdXRwdXQgZm9ybWF0IHNlbGVjdGlvbiAqLw0KCQkJc3dpdGNoIChvdXRwdXRGb3JtYXQpDQoJCQl7DQoJCQljYXNlICJIRVgiOg0KCQkJCWZvcm1hdEZ1bmMgPSBiaW5iMmhleDsNCgkJCQlicmVhazsNCgkJCWNhc2UgIkI2NCI6DQoJCQkJZm9ybWF0RnVuYyA9IGJpbmIyYjY0Ow0KCQkJCWJyZWFrOw0KCQkJY2FzZSAiQVNDSUkiOg0KCQkJCWZvcm1hdEZ1bmMgPSBiaW5iMnN0cjsNCgkJCQlicmVhazsNCgkJCWRlZmF1bHQ6DQoJCQkJcmV0dXJuICJGT1JNQVQgTk9UIFJFQ09HTklaRUQiOw0KCQkJfQ0KDQoJCQkvKiBWYWxpZGF0ZSB0aGUgaGFzaCB2YXJpYW50IHNlbGVjdGlvbiBhbmQgc2V0IG5lZWRlZCB2YXJpYWJsZXMgKi8NCgkJCXN3aXRjaCAodmFyaWFudCkNCgkJCXsNCgkJCWNhc2UgIlNIQS0xIjoNCgkJCQlibG9ja0J5dGVTaXplID0gNjQ7DQoJCQkJaGFzaEJpdFNpemUgPSAxNjA7DQoJCQkJYnJlYWs7DQoJCQljYXNlICJTSEEtMjI0IjoNCgkJCQlibG9ja0J5dGVTaXplID0gNjQ7DQoJCQkJaGFzaEJpdFNpemUgPSAyMjQ7DQoJCQkJYnJlYWs7DQoJCQljYXNlICJTSEEtMjU2IjoNCgkJCQlibG9ja0J5dGVTaXplID0gNjQ7DQoJCQkJaGFzaEJpdFNpemUgPSAyNTY7DQoJCQkJYnJlYWs7DQoJCQljYXNlICJTSEEtMzg0IjoNCgkJCQlibG9ja0J5dGVTaXplID0gMTI4Ow0KCQkJCWhhc2hCaXRTaXplID0gMzg0Ow0KCQkJCWJyZWFrOw0KCQkJY2FzZSAiU0hBLTUxMiI6DQoJCQkJYmxvY2tCeXRlU2l6ZSA9IDEyODsNCgkJCQloYXNoQml0U2l6ZSA9IDUxMjsNCgkJCQlicmVhazsNCgkJCWRlZmF1bHQ6DQoJCQkJcmV0dXJuICJIQVNIIE5PVCBSRUNPR05JWkVEIjsNCgkJCX0NCg0KCQkJLyogVmFsaWRhdGUgaW5wdXQgZm9ybWF0IHNlbGVjdGlvbiAqLw0KCQkJaWYgKCJIRVgiID09PSBpbnB1dEZvcm1hdCkNCgkJCXsNCgkJCQkvKiBOaWJibGVzIG11c3QgY29tZSBpbiBwYWlycyAqLw0KCQkJCWlmICgwICE9PSAoa2V5Lmxlbmd0aCAlIDIpKQ0KCQkJCXsNCgkJCQkJcmV0dXJuICJLRVkgTVVTVCBCRSBJTiBCWVRFIElOQ1JFTUVOVFMiOw0KCQkJCX0NCgkJCQlrZXlUb1VzZSA9IGhleDJiaW5iKGtleSk7DQoJCQkJa2V5QmluTGVuID0ga2V5Lmxlbmd0aCAqIDQ7DQoJCQl9DQoJCQllbHNlIGlmICgiQVNDSUkiID09PSBpbnB1dEZvcm1hdCkNCgkJCXsNCgkJCQlrZXlUb1VzZSA9IHN0cjJiaW5iKGtleSk7DQoJCQkJa2V5QmluTGVuID0ga2V5Lmxlbmd0aCAqIGNoYXJTaXplOw0KCQkJfQ0KCQkJZWxzZQ0KCQkJew0KCQkJCXJldHVybiAiVU5LTk9XTiBLRVkgSU5QVVQgVFlQRSI7DQoJCQl9DQoNCgkJCS8qIFRoZXNlIGFyZSB1c2VkIG11bHRpcGxlIHRpbWVzLCBjYWxjdWxhdGUgYW5kIHN0b3JlIHRoZW0gKi8NCgkJCWJsb2NrQml0U2l6ZSA9IGJsb2NrQnl0ZVNpemUgKiA4Ow0KCQkJbGFzdEFycmF5SW5kZXggPSAoYmxvY2tCeXRlU2l6ZSAvIDQpIC0gMTsNCg0KCQkJLyogRmlndXJlIG91dCB3aGF0IHRvIGRvIHdpdGggdGhlIGtleSBiYXNlZCBvbiBpdHMgc2l6ZSByZWxhdGl2ZSB0bw0KCQkJICogdGhlIGhhc2gncyBibG9jayBzaXplICovDQoJCQlpZiAoYmxvY2tCeXRlU2l6ZSA8IChrZXlCaW5MZW4gLyA4KSkNCgkJCXsNCgkJCQlpZiAoIlNIQS0xIiA9PT0gdmFyaWFudCkNCgkJCQl7DQoJCQkJCWtleVRvVXNlID0gY29yZVNIQTEoa2V5VG9Vc2UsIGtleUJpbkxlbik7DQoJCQkJfQ0KCQkJCWVsc2UNCgkJCQl7DQoJCQkJCWtleVRvVXNlID0gY29yZVNIQTIoa2V5VG9Vc2UsIGtleUJpbkxlbiwgdmFyaWFudCk7DQoJCQkJfQ0KCQkJCS8qIEZvciBhbGwgdmFyaWFudHMsIHRoZSBibG9jayBzaXplIGlzIGJpZ2dlciB0aGFuIHRoZSBvdXRwdXQNCgkJCQkgKiBzaXplIHNvIHRoZXJlIHdpbGwgbmV2ZXIgYmUgYSB1c2VmdWwgYnl0ZSBhdCB0aGUgZW5kIG9mIHRoZQ0KCQkJCSAqIHN0cmluZyAqLw0KCQkJCWtleVRvVXNlW2xhc3RBcnJheUluZGV4XSAmPSAweEZGRkZGRjAwOw0KCQkJfQ0KCQkJZWxzZSBpZiAoYmxvY2tCeXRlU2l6ZSA+IChrZXlCaW5MZW4gLyA4KSkNCgkJCXsNCgkJCQkvKiBJZiB0aGUgYmxvY2tCeXRlU2l6ZSBpcyBncmVhdGVyIHRoYW4gdGhlIGtleSBsZW5ndGgsIHRoZXJlDQoJCQkJICogd2lsbCBhbHdheXMgYmUgYXQgTEVBU1Qgb25lICJ1c2VsZXNzIiBieXRlIGF0IHRoZSBlbmQgb2YgdGhlDQoJCQkJICogc3RyaW5nICovDQoJCQkJa2V5VG9Vc2VbbGFzdEFycmF5SW5kZXhdICY9IDB4RkZGRkZGMDA7DQoJCQl9DQoNCgkJCS8qIENyZWF0ZSBpcGFkIGFuZCBvcGFkICovDQoJCQlmb3IgKGkgPSAwOyBpIDw9IGxhc3RBcnJheUluZGV4OyBpICs9IDEpDQoJCQl7DQoJCQkJa2V5V2l0aElQYWRbaV0gPSBrZXlUb1VzZVtpXSBeIDB4MzYzNjM2MzY7DQoJCQkJa2V5V2l0aE9QYWRbaV0gPSBrZXlUb1VzZVtpXSBeIDB4NUM1QzVDNUM7DQoJCQl9DQoNCgkJCS8qIENhbGN1bGF0ZSB0aGUgSE1BQyAqLw0KCQkJaWYgKCJTSEEtMSIgPT09IHZhcmlhbnQpDQoJCQl7DQoJCQkJcmV0VmFsID0gY29yZVNIQTEoDQoJCQkJCQkJa2V5V2l0aElQYWQuY29uY2F0KHRoaXMuc3RyVG9IYXNoKSwNCgkJCQkJCQlibG9ja0JpdFNpemUgKyB0aGlzLnN0ckJpbkxlbik7DQoJCQkJcmV0VmFsID0gY29yZVNIQTEoDQoJCQkJCQkJa2V5V2l0aE9QYWQuY29uY2F0KHJldFZhbCksDQoJCQkJCQkJYmxvY2tCaXRTaXplICsgaGFzaEJpdFNpemUpOw0KCQkJfQ0KCQkJZWxzZQ0KCQkJew0KCQkJCXJldFZhbCA9IGNvcmVTSEEyKA0KCQkJCQkJCWtleVdpdGhJUGFkLmNvbmNhdCh0aGlzLnN0clRvSGFzaCksDQoJCQkJCQkJYmxvY2tCaXRTaXplICsgdGhpcy5zdHJCaW5MZW4sIHZhcmlhbnQpOw0KCQkJCXJldFZhbCA9IGNvcmVTSEEyKA0KCQkJCQkJCWtleVdpdGhPUGFkLmNvbmNhdChyZXRWYWwpLA0KCQkJCQkJCWJsb2NrQml0U2l6ZSArIGhhc2hCaXRTaXplLCB2YXJpYW50KTsNCgkJCX0NCg0KCQkJcmV0dXJuIChmb3JtYXRGdW5jKHJldFZhbCkpOw0KCQl9DQoJfTsNCg0KCXJldHVybiBqc1NIQTsNCn0oKSk7DQoNCmZ1bmN0aW9uIHN0cl9zaGExKHN0cikgew0KCXZhciBzaGFPYmogPSBuZXcganNTSEEoc3RyLCAiQVNDSUkiKTsNCglyZXR1cm4gc2hhT2JqLmdldEhhc2goIlNIQS0xIiwgIkFTQ0lJIik7DQp9DQoNCmZ1bmN0aW9uIHN0cl9zaGEyMjQoc3RyKSB7DQoJdmFyIHNoYU9iaiA9IG5ldyBqc1NIQShzdHIsICJBU0NJSSIpOw0KCXJldHVybiBzaGFPYmouZ2V0SGFzaCgiU0hBLTIyNCIsICJBU0NJSSIpOw0KfQ0KDQpmdW5jdGlvbiBzdHJfc2hhMjU2KHN0cikgew0KCXZhciBzaGFPYmogPSBuZXcganNTSEEoc3RyLCAiQVNDSUkiKTsNCglyZXR1cm4gc2hhT2JqLmdldEhhc2goIlNIQS0yNTYiLCAiQVNDSUkiKTsNCn0NCg0KDQpmdW5jdGlvbiBzdHJfc2hhMzg0KHN0cikgew0KCXZhciBzaGFPYmogPSBuZXcganNTSEEoc3RyLCAiQVNDSUkiKTsNCglyZXR1cm4gc2hhT2JqLmdldEhhc2goIlNIQS0zODQiLCAiQVNDSUkiKTsNCg0KfQ0KDQpmdW5jdGlvbiBzdHJfc2hhNTEyKHN0cikgew0KCXZhciBzaGFPYmogPSBuZXcganNTSEEoc3RyLCAiQVNDSUkiKTsNCglyZXR1cm4gc2hhT2JqLmdldEhhc2goIlNIQS01MTIiLCAiQVNDSUkiKTsNCn0NCi8vIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSCANCg0KLy8gbW9kaWZpZWQgdmVyc2lvbiBvZiBodHRwOi8vd3d3LmhhbmV3aW4ubmV0L2VuY3J5cHQvUEdkZWNvZGUuanM6DQoNCi8qIE9wZW5QR1AgZW5jcnlwdGlvbiB1c2luZyBSU0EvQUVTDQogKiBDb3B5cmlnaHQgMjAwNS0yMDA2IEhlcmJlcnQgSGFuZXdpbmtlbCwgd3d3LmhhbmVXSU4uZGUNCiAqIHZlcnNpb24gMi4wLCBjaGVjayB3d3cuaGFuZVdJTi5kZSBmb3IgdGhlIGxhdGVzdCB2ZXJzaW9uDQoNCiAqIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYXMtaXMsIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LiAgDQogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlIG9yIHNlbGwgdGhpcyBzb2Z0d2FyZSwgd2l0aCBvcg0KICogd2l0aG91dCBmZWUsIGZvciBhbnkgcHVycG9zZSBhbmQgYnkgYW55IGluZGl2aWR1YWwgb3Igb3JnYW5pemF0aW9uLCBpcyBoZXJlYnkNCiAqIGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGFyYWdyYXBoIGFwcGVhciANCiAqIGluIGFsbCBjb3BpZXMuIERpc3RyaWJ1dGlvbiBhcyBhIHBhcnQgb2YgYW4gYXBwbGljYXRpb24gb3IgYmluYXJ5IG11c3QNCiAqIGluY2x1ZGUgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyDQogKiBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgYXBwbGljYXRpb24gb3IgZGlzdHJpYnV0aW9uLg0KICovDQoNCi8qKg0KICogQW4gYXJyYXkgb2YgYnl0ZXMsIHRoYXQgaXMgaW50ZWdlcnMgd2l0aCB2YWx1ZXMgZnJvbSAwIHRvIDI1NQ0KICogQHR5cGVkZWYgeyhBcnJheXxVaW50OEFycmF5KX0gb3BlbnBncF9ieXRlX2FycmF5DQogKi8NCg0KLyoqDQogKiBCbG9jayBjaXBoZXIgZnVuY3Rpb24NCiAqIEBjYWxsYmFjayBvcGVucGdwX2NpcGhlcl9ibG9ja19mbg0KICogQHBhcmFtIHtvcGVucGdwX2J5dGVfYXJyYXl9IGJsb2NrIEEgYmxvY2sgdG8gcGVyZm9ybSBvcGVyYXRpb25zIG9uDQogKiBAcGFyYW0ge29wZW5wZ3BfYnl0ZV9hcnJheX0ga2V5IHRvIHVzZSBpbiBlbmNyeXB0aW9uL2RlY3J5cHRpb24NCiAqIEByZXR1cm4ge29wZW5wZ3BfYnl0ZV9hcnJheX0gRW5jcnlwdGVkL2RlY3J5cHRlZCBibG9jaw0KICovDQoNCg0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCi8qKg0KICogVGhpcyBmdW5jdGlvbiBlbmNyeXB0cyBhIGdpdmVuIHdpdGggdGhlIHNwZWNpZmllZCBwcmVmaXhyYW5kb20gDQogKiB1c2luZyB0aGUgc3BlY2lmaWVkIGJsb2NrY2lwaGVyIHRvIGVuY3J5cHQgYSBtZXNzYWdlDQogKiBAcGFyYW0ge1N0cmluZ30gcHJlZml4cmFuZG9tIHJhbmRvbSBieXRlcyBvZiBibG9ja19zaXplIGxlbmd0aCBwcm92aWRlZCANCiAqICBhcyBhIHN0cmluZyB0byBiZSB1c2VkIGluIHByZWZpeGluZyB0aGUgZGF0YQ0KICogQHBhcmFtIHtvcGVucGdwX2NpcGhlcl9ibG9ja19mbn0gYmxvY2tjaXBoZXJmbiB0aGUgYWxnb3JpdGhtIGVuY3J5cHQgZnVuY3Rpb24gdG8gZW5jcnlwdA0KICogIGRhdGEgaW4gb25lIGJsb2NrX3NpemUgZW5jcnlwdGlvbi4gDQogKiBAcGFyYW0ge0ludGVnZXJ9IGJsb2NrX3NpemUgdGhlIGJsb2NrIHNpemUgaW4gYnl0ZXMgb2YgdGhlIGFsZ29yaXRobSB1c2VkDQogKiBAcGFyYW0ge1N0cmluZ30gcGxhaW50ZXh0IGRhdGEgdG8gYmUgZW5jcnlwdGVkIHByb3ZpZGVkIGFzIGEgc3RyaW5nDQogKiBAcGFyYW0ge29wZW5wZ3BfYnl0ZV9hcnJheX0ga2V5IGtleSB0byBiZSB1c2VkIHRvIGVuY3J5cHQgdGhlIGRhdGEuIFRoaXMgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIA0KICogIGJsb2NrY2lwaGVyZm4NCiAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVzeW5jIGEgYm9vbGVhbiB2YWx1ZSBzcGVjaWZ5aW5nIGlmIGEgcmVzeW5jIG9mIHRoZSANCiAqICBJViBzaG91bGQgYmUgdXNlZCBvciBub3QuIFRoZSBlbmNyeXB0ZWRkYXRhcGFja2V0IHVzZXMgdGhlIA0KICogICJvbGQiIHN0eWxlIHdpdGggYSByZXN5bmMuIEVuY3J5cHRpb24gd2l0aGluIGFuIA0KICogIGVuY3J5cHRlZGludGVncml0eXByb3RlY3RlZGRhdGEgcGFja2V0IGlzIG5vdCByZXN5bmNpbmcgdGhlIElWLg0KICogQHJldHVybiB7U3RyaW5nfSBhIHN0cmluZyB3aXRoIHRoZSBlbmNyeXB0ZWQgZGF0YQ0KICovDQpmdW5jdGlvbiBvcGVucGdwX2NmYl9lbmNyeXB0KHByZWZpeHJhbmRvbSwgYmxvY2tjaXBoZXJlbmNyeXB0Zm4sIHBsYWludGV4dCwgYmxvY2tfc2l6ZSwga2V5LCByZXN5bmMpIHsNCgl2YXIgRlIgPSBuZXcgQXJyYXkoYmxvY2tfc2l6ZSk7DQoJdmFyIEZSRSA9IG5ldyBBcnJheShibG9ja19zaXplKTsNCg0KCXByZWZpeHJhbmRvbSA9IHByZWZpeHJhbmRvbSArIHByZWZpeHJhbmRvbS5jaGFyQXQoYmxvY2tfc2l6ZS0yKSArcHJlZml4cmFuZG9tLmNoYXJBdChibG9ja19zaXplLTEpOw0KCXV0aWwucHJpbnRfZGVidWcoInByZWZpeHJhbmRvbToiK3V0aWwuaGV4c3RyZHVtcChwcmVmaXhyYW5kb20pKTsNCgl2YXIgY2lwaGVydGV4dCA9ICIiOw0KCS8vIDEuICBUaGUgZmVlZGJhY2sgcmVnaXN0ZXIgKEZSKSBpcyBzZXQgdG8gdGhlIElWLCB3aGljaCBpcyBhbGwgemVyb3MuDQoJZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIEZSW2ldID0gMDsNCgkNCgkvLyAyLiAgRlIgaXMgZW5jcnlwdGVkIHRvIHByb2R1Y2UgRlJFIChGUiBFbmNyeXB0ZWQpLiAgVGhpcyBpcyB0aGUNCiAgICAvLyAgICAgZW5jcnlwdGlvbiBvZiBhbiBhbGwtemVybyB2YWx1ZS4NCglGUkUgPSBibG9ja2NpcGhlcmVuY3J5cHRmbihGUiwga2V5KTsNCgkvLyAzLiAgRlJFIGlzIHhvcmVkIHdpdGggdGhlIGZpcnN0IEJTIG9jdGV0cyBvZiByYW5kb20gZGF0YSBwcmVmaXhlZCB0bw0KICAgIC8vICAgICB0aGUgcGxhaW50ZXh0IHRvIHByb2R1Y2UgQ1sxXSB0aHJvdWdoIENbQlNdLCB0aGUgZmlyc3QgQlMgb2N0ZXRzDQogICAgLy8gICAgIG9mIGNpcGhlcnRleHQuDQoJZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGNpcGhlcnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShGUkVbaV0gXiBwcmVmaXhyYW5kb20uY2hhckNvZGVBdChpKSk7DQoJDQoJLy8gNC4gIEZSIGlzIGxvYWRlZCB3aXRoIENbMV0gdGhyb3VnaCBDW0JTXS4NCglmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgRlJbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSk7DQoJDQoJLy8gNS4gIEZSIGlzIGVuY3J5cHRlZCB0byBwcm9kdWNlIEZSRSwgdGhlIGVuY3J5cHRpb24gb2YgdGhlIGZpcnN0IEJTDQogICAgLy8gCSAgIG9jdGV0cyBvZiBjaXBoZXJ0ZXh0Lg0KCUZSRSA9IGJsb2NrY2lwaGVyZW5jcnlwdGZuKEZSLCBrZXkpOw0KDQoJLy8gNi4gIFRoZSBsZWZ0IHR3byBvY3RldHMgb2YgRlJFIGdldCB4b3JlZCB3aXRoIHRoZSBuZXh0IHR3byBvY3RldHMgb2YNCgkvLyAgICAgZGF0YSB0aGF0IHdlcmUgcHJlZml4ZWQgdG8gdGhlIHBsYWludGV4dC4gIFRoaXMgcHJvZHVjZXMgQ1tCUysxXQ0KCS8vICAgICBhbmQgQ1tCUysyXSwgdGhlIG5leHQgdHdvIG9jdGV0cyBvZiBjaXBoZXJ0ZXh0Lg0KCWNpcGhlcnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShGUkVbMF0gXiBwcmVmaXhyYW5kb20uY2hhckNvZGVBdChibG9ja19zaXplKSk7DQoJY2lwaGVydGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVsxXSBeIHByZWZpeHJhbmRvbS5jaGFyQ29kZUF0KGJsb2NrX3NpemUrMSkpOw0KDQoJaWYgKHJlc3luYykgew0KCQkvLyA3LiAgKFRoZSByZXN5bmMgc3RlcCkgRlIgaXMgbG9hZGVkIHdpdGggQzMtQzEwLg0KCQlmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgRlJbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSsyKTsNCgl9IGVsc2Ugew0KCQlmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgRlJbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSk7DQoJfQ0KCS8vIDguICBGUiBpcyBlbmNyeXB0ZWQgdG8gcHJvZHVjZSBGUkUuDQoJRlJFID0gYmxvY2tjaXBoZXJlbmNyeXB0Zm4oRlIsIGtleSk7DQoJDQoJaWYgKHJlc3luYykgew0KCQkvLyA5LiAgRlJFIGlzIHhvcmVkIHdpdGggdGhlIGZpcnN0IDggb2N0ZXRzIG9mIHRoZSBnaXZlbiBwbGFpbnRleHQsIG5vdw0KCSAgICAvLwkgICB0aGF0IHdlIGhhdmUgZmluaXNoZWQgZW5jcnlwdGluZyB0aGUgMTAgb2N0ZXRzIG9mIHByZWZpeGVkIGRhdGEuDQoJICAgIC8vIAkgICBUaGlzIHByb2R1Y2VzIEMxMS1DMTgsIHRoZSBuZXh0IDggb2N0ZXRzIG9mIGNpcGhlcnRleHQuDQoJCWZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKQ0KCQkJY2lwaGVydGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHBsYWludGV4dC5jaGFyQ29kZUF0KGkpKTsNCgkJZm9yKG49YmxvY2tfc2l6ZSsyOyBuIDwgcGxhaW50ZXh0Lmxlbmd0aDsgbis9YmxvY2tfc2l6ZSkgew0KCQkJLy8gMTAuIEZSIGlzIGxvYWRlZCB3aXRoIEMxMS1DMTgNCgkJCWZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChuK2kpOw0KCQkNCgkJCS8vIDExLiBGUiBpcyBlbmNyeXB0ZWQgdG8gcHJvZHVjZSBGUkUuDQoJCQlGUkUgPSBibG9ja2NpcGhlcmVuY3J5cHRmbihGUiwga2V5KTsNCgkJDQoJCQkvLyAxMi4gRlJFIGlzIHhvcmVkIHdpdGggdGhlIG5leHQgOCBvY3RldHMgb2YgcGxhaW50ZXh0LCB0byBwcm9kdWNlIHRoZQ0KCQkJLy8gbmV4dCA4IG9jdGV0cyBvZiBjaXBoZXJ0ZXh0LiAgVGhlc2UgYXJlIGxvYWRlZCBpbnRvIEZSIGFuZCB0aGUNCgkJCS8vIHByb2Nlc3MgaXMgcmVwZWF0ZWQgdW50aWwgdGhlIHBsYWludGV4dCBpcyB1c2VkIHVwLg0KCQkJZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGNpcGhlcnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShGUkVbaV0gXiBwbGFpbnRleHQuY2hhckNvZGVBdCgobi0yKStpKSk7DQoJCX0NCgl9DQoJZWxzZSB7DQoJCXBsYWludGV4dCA9ICIgICIrcGxhaW50ZXh0Ow0KCQkvLyA5LiAgRlJFIGlzIHhvcmVkIHdpdGggdGhlIGZpcnN0IDggb2N0ZXRzIG9mIHRoZSBnaXZlbiBwbGFpbnRleHQsIG5vdw0KCSAgICAvLwkgICB0aGF0IHdlIGhhdmUgZmluaXNoZWQgZW5jcnlwdGluZyB0aGUgMTAgb2N0ZXRzIG9mIHByZWZpeGVkIGRhdGEuDQoJICAgIC8vIAkgICBUaGlzIHByb2R1Y2VzIEMxMS1DMTgsIHRoZSBuZXh0IDggb2N0ZXRzIG9mIGNpcGhlcnRleHQuDQoJCWZvciAodmFyIGkgPSAyOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFW2ldIF4gcGxhaW50ZXh0LmNoYXJDb2RlQXQoaSkpOw0KCQl2YXIgdGVtcENpcGhlcnRleHQgPSBjaXBoZXJ0ZXh0LnN1YnN0cmluZygwLDIqYmxvY2tfc2l6ZSkuc3BsaXQoJycpOw0KCQl2YXIgdGVtcENpcGhlcnRleHRTdHJpbmcgPSBjaXBoZXJ0ZXh0LnN1YnN0cmluZyhibG9ja19zaXplKTsNCgkJZm9yKG49YmxvY2tfc2l6ZTsgbjxwbGFpbnRleHQubGVuZ3RoOyBuKz1ibG9ja19zaXplKSB7DQoJCQkvLyAxMC4gRlIgaXMgbG9hZGVkIHdpdGggQzExLUMxOA0KCQkJZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIEZSW2ldID0gdGVtcENpcGhlcnRleHRTdHJpbmcuY2hhckNvZGVBdChpKTsNCgkJCXRlbXBDaXBoZXJ0ZXh0U3RyaW5nPScnOw0KCQkJDQoJCQkvLyAxMS4gRlIgaXMgZW5jcnlwdGVkIHRvIHByb2R1Y2UgRlJFLg0KCQkJRlJFID0gYmxvY2tjaXBoZXJlbmNyeXB0Zm4oRlIsIGtleSk7DQoJCQkNCgkJCS8vIDEyLiBGUkUgaXMgeG9yZWQgd2l0aCB0aGUgbmV4dCA4IG9jdGV0cyBvZiBwbGFpbnRleHQsIHRvIHByb2R1Y2UgdGhlDQoJCQkvLyAgICAgbmV4dCA4IG9jdGV0cyBvZiBjaXBoZXJ0ZXh0LiAgVGhlc2UgYXJlIGxvYWRlZCBpbnRvIEZSIGFuZCB0aGUNCgkJCS8vICAgICBwcm9jZXNzIGlzIHJlcGVhdGVkIHVudGlsIHRoZSBwbGFpbnRleHQgaXMgdXNlZCB1cC4NCgkJCWZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKXsgdGVtcENpcGhlcnRleHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHBsYWludGV4dC5jaGFyQ29kZUF0KG4raSkpKTsNCgkJCXRlbXBDaXBoZXJ0ZXh0U3RyaW5nICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFW2ldIF4gcGxhaW50ZXh0LmNoYXJDb2RlQXQobitpKSk7DQoJCQl9DQoJCX0NCgkJY2lwaGVydGV4dCA9IHRlbXBDaXBoZXJ0ZXh0LmpvaW4oJycpOw0KCQkNCgl9DQoJcmV0dXJuIGNpcGhlcnRleHQ7DQp9DQoNCi8qKg0KICogRGVjcnlwdHMgdGhlIHByZWZpeGVkIGRhdGEgZm9yIHRoZSBNb2RpZmljYXRpb24gRGV0ZWN0aW9uIENvZGUgKE1EQykgY29tcHV0YXRpb24NCiAqIEBwYXJhbSB7b3BlbnBncF9ibG9ja19jaXBoZXJfZm59IGJsb2NrY2lwaGVyZW5jcnlwdGZuIENpcGhlciBmdW5jdGlvbiB0byB1c2UNCiAqIEBwYXJhbSB7SW50ZWdlcn0gYmxvY2tfc2l6ZSBCbG9ja3NpemUgb2YgdGhlIGFsZ29yaXRobQ0KICogQHBhcmFtIHtvcGVucGdwX2J5dGVfYXJyYXl9IGtleSBUaGUga2V5IGZvciBlbmNyeXB0aW9uDQogKiBAcGFyYW0ge1N0cmluZ30gY2lwaGVydGV4dCBUaGUgZW5jcnlwdGVkIGRhdGENCiAqIEByZXR1cm4ge1N0cmluZ30gcGxhaW50ZXh0IERhdGEgb2YgRChjaXBoZXJ0ZXh0KSB3aXRoIGJsb2Nrc2l6ZSBsZW5ndGggKzINCiAqLw0KZnVuY3Rpb24gb3BlbnBncF9jZmJfbWRjKGJsb2NrY2lwaGVyZW5jcnlwdGZuLCBibG9ja19zaXplLCBrZXksIGNpcGhlcnRleHQpIHsNCgl2YXIgaWJsb2NrID0gbmV3IEFycmF5KGJsb2NrX3NpemUpOw0KCXZhciBhYmxvY2sgPSBuZXcgQXJyYXkoYmxvY2tfc2l6ZSk7DQoJdmFyIGk7DQoNCgkvLyBpbml0aWFsaXNhdGlvbiB2ZWN0b3INCglmb3IoaT0wOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBpYmxvY2tbaV0gPSAwOw0KDQoJaWJsb2NrID0gYmxvY2tjaXBoZXJlbmNyeXB0Zm4oaWJsb2NrLCBrZXkpOw0KCWZvcihpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykNCgl7DQoJCWFibG9ja1tpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpKTsNCgkJaWJsb2NrW2ldIF49IGFibG9ja1tpXTsNCgl9DQoNCglhYmxvY2sgPSBibG9ja2NpcGhlcmVuY3J5cHRmbihhYmxvY2ssIGtleSk7DQoNCglyZXR1cm4gdXRpbC5iaW4yc3RyKGlibG9jaykrDQoJCVN0cmluZy5mcm9tQ2hhckNvZGUoYWJsb2NrWzBdXmNpcGhlcnRleHQuY2hhckNvZGVBdChibG9ja19zaXplKSkrDQoJCVN0cmluZy5mcm9tQ2hhckNvZGUoYWJsb2NrWzFdXmNpcGhlcnRleHQuY2hhckNvZGVBdChibG9ja19zaXplKzEpKTsNCn0NCi8qKg0KICogVGhpcyBmdW5jdGlvbiBkZWNyeXB0cyBhIGdpdmVuIHBsYWludGV4dCB1c2luZyB0aGUgc3BlY2lmaWVkDQogKiBibG9ja2NpcGhlciB0byBkZWNyeXB0IGEgbWVzc2FnZQ0KICogQHBhcmFtIHtvcGVucGdwX2NpcGhlcl9ibG9ja19mbn0gYmxvY2tjaXBoZXJmbiBUaGUgYWxnb3JpdGhtIF9lbmNyeXB0XyBmdW5jdGlvbiB0byBlbmNyeXB0DQogKiAgZGF0YSBpbiBvbmUgYmxvY2tfc2l6ZSBlbmNyeXB0aW9uLg0KICogQHBhcmFtIHtJbnRlZ2VyfSBibG9ja19zaXplIHRoZSBibG9jayBzaXplIGluIGJ5dGVzIG9mIHRoZSBhbGdvcml0aG0gdXNlZA0KICogQHBhcmFtIHtTdHJpbmd9IHBsYWludGV4dCBjaXBoZXJ0ZXh0IHRvIGJlIGRlY3J5cHRlZCBwcm92aWRlZCBhcyBhIHN0cmluZw0KICogQHBhcmFtIHtvcGVucGdwX2J5dGVfYXJyYXl9IGtleSBrZXkgdG8gYmUgdXNlZCB0byBkZWNyeXB0IHRoZSBjaXBoZXJ0ZXh0LiBUaGlzIHdpbGwgYmUgcGFzc2VkIHRvIHRoZSANCiAqICBibG9ja2NpcGhlcmZuDQogKiBAcGFyYW0ge0Jvb2xlYW59IHJlc3luYyBhIGJvb2xlYW4gdmFsdWUgc3BlY2lmeWluZyBpZiBhIHJlc3luYyBvZiB0aGUgDQogKiAgSVYgc2hvdWxkIGJlIHVzZWQgb3Igbm90LiBUaGUgZW5jcnlwdGVkZGF0YXBhY2tldCB1c2VzIHRoZSANCiAqICAib2xkIiBzdHlsZSB3aXRoIGEgcmVzeW5jLiBEZWNyeXB0aW9uIHdpdGhpbiBhbiANCiAqICBlbmNyeXB0ZWRpbnRlZ3JpdHlwcm90ZWN0ZWRkYXRhIHBhY2tldCBpcyBub3QgcmVzeW5jaW5nIHRoZSBJVi4NCiAqIEByZXR1cm4ge1N0cmluZ30gYSBzdHJpbmcgd2l0aCB0aGUgcGxhaW50ZXh0IGRhdGENCiAqLw0KDQpmdW5jdGlvbiBvcGVucGdwX2NmYl9kZWNyeXB0KGJsb2NrY2lwaGVyZW5jcnlwdGZuLCBibG9ja19zaXplLCBrZXksIGNpcGhlcnRleHQsIHJlc3luYykNCnsNCgl1dGlsLnByaW50X2RlYnVnKCJyZXN5bmM6IityZXN5bmMpOw0KCXZhciBpYmxvY2sgPSBuZXcgQXJyYXkoYmxvY2tfc2l6ZSk7DQoJdmFyIGFibG9jayA9IG5ldyBBcnJheShibG9ja19zaXplKTsNCgl2YXIgaSwgbiA9ICcnOw0KCXZhciB0ZXh0ID0gW107DQoNCgkvLyBpbml0aWFsaXNhdGlvbiB2ZWN0b3INCglmb3IoaT0wOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBpYmxvY2tbaV0gPSAwOw0KDQoJaWJsb2NrID0gYmxvY2tjaXBoZXJlbmNyeXB0Zm4oaWJsb2NrLCBrZXkpOw0KCWZvcihpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykNCgl7DQoJCWFibG9ja1tpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpKTsNCgkJaWJsb2NrW2ldIF49IGFibG9ja1tpXTsNCgl9DQoNCglhYmxvY2sgPSBibG9ja2NpcGhlcmVuY3J5cHRmbihhYmxvY2ssIGtleSk7DQoNCgl1dGlsLnByaW50X2RlYnVnKCJvcGVucGdwX2NmYl9kZWNyeXB0OlxuaWJsb2NrOiIrdXRpbC5oZXhpZHVtcChpYmxvY2spKyJcbmFibG9jazoiK3V0aWwuaGV4aWR1bXAoYWJsb2NrKSsiXG4iKTsNCgl1dGlsLnByaW50X2RlYnVnKChhYmxvY2tbMF1eY2lwaGVydGV4dC5jaGFyQ29kZUF0KGJsb2NrX3NpemUpKS50b1N0cmluZygxNikrKGFibG9ja1sxXV5jaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSsxKSkudG9TdHJpbmcoMTYpKTsNCgkNCgkvLyB0ZXN0IGNoZWNrIG9jdGV0cw0KCWlmKGlibG9ja1tibG9ja19zaXplLTJdIT0oYWJsb2NrWzBdXmNpcGhlcnRleHQuY2hhckNvZGVBdChibG9ja19zaXplKSkNCgl8fCBpYmxvY2tbYmxvY2tfc2l6ZS0xXSE9KGFibG9ja1sxXV5jaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSsxKSkpDQoJew0KCQl1dGlsLnByaW50X2Vyb3IoImVycm9yIGR1ZGluZyBkZWNyeXB0aW9uLiBTeW1tZWN0cmljIGVuY3J5cHRlZCBkYXRhIG5vdCB2YWxpZC4iKTsNCgkJcmV0dXJuIHRleHQuam9pbignJyk7DQoJfQ0KCQ0KCS8qICBSRkM0ODgwOiBUYWcgMTggYW5kIFJlc3luYzoNCgkgKiAgWy4uLl0gVW5saWtlIHRoZSBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCwgbm8NCiAgIAkgKiAgc3BlY2lhbCBDRkIgcmVzeW5jaHJvbml6YXRpb24gaXMgZG9uZSBhZnRlciBlbmNyeXB0aW5nIHRoaXMgcHJlZml4DQogICAgICogIGRhdGEuICBTZWUgIk9wZW5QR1AgQ0ZCIE1vZGUiIGJlbG93IGZvciBtb3JlIGRldGFpbHMuDQoNCgkgKi8NCgkNCglpZiAocmVzeW5jKSB7DQoJICAgIGZvcihpPTA7IGk8YmxvY2tfc2l6ZTsgaSsrKSBpYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSsyKTsNCgkJZm9yKG49YmxvY2tfc2l6ZSsyOyBuPGNpcGhlcnRleHQubGVuZ3RoOyBuKz1ibG9ja19zaXplKQ0KCQl7DQoJCQlhYmxvY2sgPSBibG9ja2NpcGhlcmVuY3J5cHRmbihpYmxvY2ssIGtleSk7DQoNCgkJCWZvcihpID0gMDsgaTxibG9ja19zaXplICYmIGkrbiA8IGNpcGhlcnRleHQubGVuZ3RoOyBpKyspDQoJCQl7DQoJCQkJaWJsb2NrW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KG4raSk7DQoJCQkJdGV4dC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYWJsb2NrW2ldXmlibG9ja1tpXSkpOyANCgkJCX0NCgkJfQ0KCX0gZWxzZSB7DQoJCWZvcihpPTA7IGk8YmxvY2tfc2l6ZTsgaSsrKSBpYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSk7DQoJCWZvcihuPWJsb2NrX3NpemU7IG48Y2lwaGVydGV4dC5sZW5ndGg7IG4rPWJsb2NrX3NpemUpDQoJCXsNCgkJCWFibG9jayA9IGJsb2NrY2lwaGVyZW5jcnlwdGZuKGlibG9jaywga2V5KTsNCgkJCWZvcihpID0gMDsgaTxibG9ja19zaXplICYmIGkrbiA8IGNpcGhlcnRleHQubGVuZ3RoOyBpKyspDQoJCQl7DQoJCQkJaWJsb2NrW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KG4raSk7DQoJCQkJdGV4dC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYWJsb2NrW2ldXmlibG9ja1tpXSkpOyANCgkJCX0NCgkJfQ0KCQkNCgl9DQoJDQoJcmV0dXJuIHRleHQuam9pbignJyk7DQp9DQoNCg0KZnVuY3Rpb24gbm9ybWFsX2NmYl9lbmNyeXB0KGJsb2NrY2lwaGVyZW5jcnlwdGZuLCBibG9ja19zaXplLCBrZXksIHBsYWludGV4dCwgaXYpIHsNCgl2YXIgYmxvY2tpID0iIjsNCgl2YXIgYmxvY2tjID0gIiI7DQoJdmFyIHBvcyA9IDA7DQoJdmFyIGN5cGhlcnRleHQgPSBbXTsNCgl2YXIgdGVtcEJsb2NrID0gW107DQoJYmxvY2tjID0gaXYuc3Vic3RyaW5nKDAsYmxvY2tfc2l6ZSk7DQoJd2hpbGUgKHBsYWludGV4dC5sZW5ndGggPiBibG9ja19zaXplKnBvcykgew0KCQl2YXIgZW5jYmxvY2sgPSBibG9ja2NpcGhlcmVuY3J5cHRmbihibG9ja2MsIGtleSk7DQoJCWJsb2NraSA9IHBsYWludGV4dC5zdWJzdHJpbmcoKHBvcypibG9ja19zaXplKSwocG9zKmJsb2NrX3NpemUpK2Jsb2NrX3NpemUpOw0KCQlmb3IgKHZhciBpPTA7IGkgPCBibG9ja2kubGVuZ3RoOyBpKyspDQoJCSAgICB0ZW1wQmxvY2sucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGJsb2NraS5jaGFyQ29kZUF0KGkpIF4gZW5jYmxvY2tbaV0pKTsNCgkJYmxvY2tjID0gdGVtcEJsb2NrLmpvaW4oJycpOw0KCQl0ZW1wQmxvY2sgPSBbXTsNCgkJY3lwaGVydGV4dC5wdXNoKGJsb2NrYyk7DQoJCXBvcysrOw0KCX0NCglyZXR1cm4gY3lwaGVydGV4dC5qb2luKCcnKTsNCn0NCg0KZnVuY3Rpb24gbm9ybWFsX2NmYl9kZWNyeXB0KGJsb2NrY2lwaGVyZW5jcnlwdGZuLCBibG9ja19zaXplLCBrZXksIGNpcGhlcnRleHQsIGl2KSB7IA0KCXZhciBibG9ja3AgPSIiOw0KCXZhciBwb3MgPSAwOw0KCXZhciBwbGFpbnRleHQgPSBbXTsNCgl2YXIgb2Zmc2V0ID0gMDsNCglpZiAoaXYgPT0gbnVsbCkNCgkJZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGJsb2NrcCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApOw0KCWVsc2UNCgkJYmxvY2twID0gaXYuc3Vic3RyaW5nKDAsYmxvY2tfc2l6ZSk7DQoJd2hpbGUgKGNpcGhlcnRleHQubGVuZ3RoID4gKGJsb2NrX3NpemUqcG9zKSkgew0KCQl2YXIgZGVjYmxvY2sgPSBibG9ja2NpcGhlcmVuY3J5cHRmbihibG9ja3AsIGtleSk7DQoJCWJsb2NrcCA9IGNpcGhlcnRleHQuc3Vic3RyaW5nKChwb3MqKGJsb2NrX3NpemUpKStvZmZzZXQsKHBvcyooYmxvY2tfc2l6ZSkpKyhibG9ja19zaXplKStvZmZzZXQpOw0KCQlmb3IgKHZhciBpPTA7IGkgPCBibG9ja3AubGVuZ3RoOyBpKyspIHsNCgkJCXBsYWludGV4dC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYmxvY2twLmNoYXJDb2RlQXQoaSkgXiBkZWNibG9ja1tpXSkpOw0KCQl9DQoJCXBvcysrOw0KCX0NCgkNCglyZXR1cm4gcGxhaW50ZXh0LmpvaW4oJycpOw0KfQ0KLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0DQovLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3INCi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcg0KLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLA0KLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YNCi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VDQovLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLg0KLy8gDQovLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlDQovLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0EgDQoNCi8vIFRoZSBHUEc0QnJvd3NlcnMgY3J5cHRvIGludGVyZmFjZQ0KDQovKioNCiAqIEVuY3J5cHRzIGRhdGEgdXNpbmcgdGhlIHNwZWNpZmllZCBwdWJsaWMga2V5IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIA0KICogYW5kIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtLg0KICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIEFsZ29yaXRobSB0byBiZSB1c2VkIChTZWUgUkZDNDg4MCA5LjEpDQogKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGlbXX0gcHVibGljTVBJcyBBbGdvcml0aG0gZGVwZW5kZW50IG11bHRpcHJlY2lzaW9uIGludGVnZXJzDQogKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGl9IGRhdGEgRGF0YSB0byBiZSBlbmNyeXB0ZWQgYXMgTVBJDQogKiBAcmV0dXJuIHsob3BlbnBncF90eXBlX21waXxvcGVucGdwX3R5cGVfbXBpW10pfSBpZiBSU0EgYW4gb3BlbnBncF90eXBlX21waTsgDQogKiBpZiBlbGdhbWFsIGVuY3J5cHRpb24gYW4gYXJyYXkgb2YgdHdvIG9wZW5wZ3BfdHlwZV9tcGkgaXMgcmV0dXJuZWQ7IG90aGVyd2lzZSBudWxsDQogKi8NCmZ1bmN0aW9uIG9wZW5wZ3BfY3J5cHRvX2FzeW1ldHJpY0VuY3J5cHQoYWxnbywgcHVibGljTVBJcywgZGF0YSkgew0KCXN3aXRjaChhbGdvKSB7DQoJY2FzZSAxOiAvLyBSU0EgKEVuY3J5cHQgb3IgU2lnbikgW0hBQ10NCgljYXNlIDI6IC8vIFJTQSBFbmNyeXB0LU9ubHkgW0hBQ10NCgljYXNlIDM6IC8vIFJTQSBTaWduLU9ubHkgW0hBQ10NCgkJdmFyIHJzYSA9IG5ldyBSU0EoKTsNCgkJdmFyIG4gPSBwdWJsaWNNUElzWzBdLnRvQmlnSW50ZWdlcigpOw0KCQl2YXIgZSA9IHB1YmxpY01QSXNbMV0udG9CaWdJbnRlZ2VyKCk7DQoJCXZhciBtID0gZGF0YS50b0JpZ0ludGVnZXIoKTsNCgkJcmV0dXJuIHJzYS5lbmNyeXB0KG0sZSxuKS50b01QSSgpOw0KCWNhc2UgMTY6IC8vIEVsZ2FtYWwgKEVuY3J5cHQtT25seSkgW0VMR0FNQUxdIFtIQUNdDQoJCXZhciBlbGdhbWFsID0gbmV3IEVsZ2FtYWwoKTsNCgkJdmFyIHAgPSBwdWJsaWNNUElzWzBdLnRvQmlnSW50ZWdlcigpOw0KCQl2YXIgZyA9IHB1YmxpY01QSXNbMV0udG9CaWdJbnRlZ2VyKCk7DQoJCXZhciB5ID0gcHVibGljTVBJc1syXS50b0JpZ0ludGVnZXIoKTsNCgkJdmFyIG0gPSBkYXRhLnRvQmlnSW50ZWdlcigpOw0KCQlyZXR1cm4gZWxnYW1hbC5lbmNyeXB0KG0sZyxwLHkpOw0KCWRlZmF1bHQ6DQoJCXJldHVybiBudWxsOw0KCX0NCn0NCg0KLyoqDQogKiBEZWNyeXB0cyBkYXRhIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHVibGljIGtleSBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyBvZiB0aGUgcHJpdmF0ZSBrZXksDQogKiB0aGUgc3BlY2lmaWVkIHNlY3JldE1QSXMgb2YgdGhlIHByaXZhdGUga2V5IGFuZCB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobS4NCiAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBBbGdvcml0aG0gdG8gYmUgdXNlZCAoU2VlIFJGQzQ4ODAgOS4xKQ0KICogQHBhcmFtIHtvcGVucGdwX3R5cGVfbXBpW119IHB1YmxpY01QSXMgQWxnb3JpdGhtIGRlcGVuZGVudCBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyANCiAqIG9mIHRoZSBwdWJsaWMga2V5IHBhcnQgb2YgdGhlIHByaXZhdGUga2V5DQogKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGlbXX0gc2VjcmV0TVBJcyBBbGdvcml0aG0gZGVwZW5kZW50IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIA0KICogb2YgdGhlIHByaXZhdGUga2V5IHVzZWQNCiAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waX0gZGF0YSBEYXRhIHRvIGJlIGVuY3J5cHRlZCBhcyBNUEkNCiAqIEByZXR1cm4ge0JpZ0ludGVnZXJ9IHJldHVybnMgYSBiaWcgaW50ZWdlciBjb250YWluaW5nIHRoZSBkZWNyeXB0ZWQgZGF0YTsgb3RoZXJ3aXNlIG51bGwNCiAqLw0KDQpmdW5jdGlvbiBvcGVucGdwX2NyeXB0b19hc3ltZXRyaWNEZWNyeXB0KGFsZ28sIHB1YmxpY01QSXMsIHNlY3JldE1QSXMsIGRhdGFNUElzKSB7DQoJc3dpdGNoKGFsZ28pIHsNCgljYXNlIDE6IC8vIFJTQSAoRW5jcnlwdCBvciBTaWduKSBbSEFDXSAgDQoJY2FzZSAyOiAvLyBSU0EgRW5jcnlwdC1Pbmx5IFtIQUNdDQoJY2FzZSAzOiAvLyBSU0EgU2lnbi1Pbmx5IFtIQUNdDQoJCXZhciByc2EgPSBuZXcgUlNBKCk7DQoJCXZhciBkID0gc2VjcmV0TVBJc1swXS50b0JpZ0ludGVnZXIoKTsNCgkJdmFyIHAgPSBzZWNyZXRNUElzWzFdLnRvQmlnSW50ZWdlcigpOw0KCQl2YXIgcSA9IHNlY3JldE1QSXNbMl0udG9CaWdJbnRlZ2VyKCk7DQoJCXZhciB1ID0gc2VjcmV0TVBJc1szXS50b0JpZ0ludGVnZXIoKTsNCgkJdmFyIG0gPSBkYXRhTVBJc1swXS50b0JpZ0ludGVnZXIoKTsNCgkJcmV0dXJuIHJzYS5kZWNyeXB0KG0sIGQsIHAsIHEsIHUpOw0KCWNhc2UgMTY6IC8vIEVsZ2FtYWwgKEVuY3J5cHQtT25seSkgW0VMR0FNQUxdIFtIQUNdDQoJCXZhciBlbGdhbWFsID0gbmV3IEVsZ2FtYWwoKTsNCgkJdmFyIHggPSBzZWNyZXRNUElzWzBdLnRvQmlnSW50ZWdlcigpOw0KCQl2YXIgYzEgPSBkYXRhTVBJc1swXS50b0JpZ0ludGVnZXIoKTsNCgkJdmFyIGMyID0gZGF0YU1QSXNbMV0udG9CaWdJbnRlZ2VyKCk7DQoJCXZhciBwID0gcHVibGljTVBJc1swXS50b0JpZ0ludGVnZXIoKTsNCgkJcmV0dXJuIGVsZ2FtYWwuZGVjcnlwdChjMSxjMixwLHgpOw0KCWRlZmF1bHQ6DQoJCXJldHVybiBudWxsOw0KCX0NCgkNCn0NCg0KLyoqDQogKiBnZW5lcmF0ZSByYW5kb20gYnl0ZSBwcmVmaXggYXMgc3RyaW5nIGZvciB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobQ0KICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIEFsZ29yaXRobSB0byB1c2UgKHNlZSBSRkM0ODgwIDkuMikNCiAqIEByZXR1cm4ge1N0cmluZ30gUmFuZG9tIGJ5dGVzIHdpdGggbGVuZ3RoIGVxdWFsIHRvIHRoZSBibG9jaw0KICogc2l6ZSBvZiB0aGUgY2lwaGVyDQogKi8NCmZ1bmN0aW9uIG9wZW5wZ3BfY3J5cHRvX2dldFByZWZpeFJhbmRvbShhbGdvKSB7DQoJc3dpdGNoKGFsZ28pIHsNCgljYXNlIDI6DQoJY2FzZSAzOg0KCWNhc2UgNDoNCgkJcmV0dXJuIG9wZW5wZ3BfY3J5cHRvX2dldFJhbmRvbUJ5dGVzKDgpOw0KCWNhc2UgNzoNCgljYXNlIDg6DQoJY2FzZSA5Og0KCWNhc2UgMTA6DQoJCXJldHVybiBvcGVucGdwX2NyeXB0b19nZXRSYW5kb21CeXRlcygxNik7DQoJZGVmYXVsdDoNCgkJcmV0dXJuIG51bGw7DQoJfQ0KfQ0KDQovKioNCiAqIHJldHJpZXZlIHRoZSBNREMgcHJlZml4ZWQgYnl0ZXMgYnkgZGVjcnlwdGluZyB0aGVtDQogKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gQWxnb3JpdGhtIHRvIHVzZSAoc2VlIFJGQzQ4ODAgOS4yKQ0KICogQHBhcmFtIHtTdHJpbmd9IGtleSBLZXkgYXMgc3RyaW5nLiBsZW5ndGggaXMgZGVwZW5kaW5nIG9uIHRoZSBhbGdvcml0aG0gdXNlZA0KICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRW5jcnlwdGVkIGRhdGEgd2hlcmUgdGhlIHByZWZpeCBpcyBkZWNyeXB0ZWQgZnJvbQ0KICogQHJldHVybiB7U3RyaW5nfSBQbGFpbiB0ZXh0IGRhdGEgb2YgdGhlIHByZWZpeGVkIGRhdGENCiAqLw0KZnVuY3Rpb24gb3BlbnBncF9jcnlwdG9fTURDU3lzdGVtQnl0ZXMoYWxnbywga2V5LCBkYXRhKSB7DQoJdXRpbC5wcmludF9kZWJ1Z19oZXhzdHJfZHVtcCgib3BlbnBncF9jcnlwdG9fc3ltbWV0cmljRGVjcnlwdDpcbmVuY3J5cHRlZGRhdGE6IixkYXRhKTsNCglzd2l0Y2goYWxnbykgew0KCWNhc2UgMDogLy8gUGxhaW50ZXh0IG9yIHVuZW5jcnlwdGVkIGRhdGENCgkJcmV0dXJuIGRhdGE7DQoJY2FzZSAyOiAvLyBUcmlwbGVERVMgKERFUy1FREUsIFtTQ0hORUlFUl0gW0hBQ10gLSAxNjggYml0IGtleSBkZXJpdmVkIGZyb20gMTkyKQ0KCQlyZXR1cm4gb3BlbnBncF9jZmJfbWRjKGRlc2VkZSwgOCwga2V5LCBkYXRhLCBvcGVucGdwX2NmYik7DQoJY2FzZSAzOiAvLyBDQVNUNSAoMTI4IGJpdCBrZXksIGFzIHBlciBbUkZDMjE0NF0pDQoJCXJldHVybiBvcGVucGdwX2NmYl9tZGMoY2FzdDVfZW5jcnlwdCwgOCwga2V5LCBkYXRhKTsNCgljYXNlIDQ6IC8vIEJsb3dmaXNoICgxMjggYml0IGtleSwgMTYgcm91bmRzKSBbQkxPV0ZJU0hdDQoJCXJldHVybiBvcGVucGdwX2NmYl9tZGMoQkZlbmNyeXB0LCA4LCBrZXksIGRhdGEpOw0KCWNhc2UgNzogLy8gQUVTIHdpdGggMTI4LWJpdCBrZXkgW0FFU10NCgljYXNlIDg6IC8vIEFFUyB3aXRoIDE5Mi1iaXQga2V5DQoJY2FzZSA5OiAvLyBBRVMgd2l0aCAyNTYtYml0IGtleQ0KCQlyZXR1cm4gb3BlbnBncF9jZmJfbWRjKEFFU2VuY3J5cHQsIDE2LCBrZXlFeHBhbnNpb24oa2V5KSwgZGF0YSk7DQoJY2FzZSAxMDogDQoJCXJldHVybiBvcGVucGdwX2NmYl9tZGMoVEZlbmNyeXB0LCAxNiwga2V5LCBkYXRhKTsNCgljYXNlIDE6IC8vIElERUEgW0lERUFdDQoJCXV0aWwucHJpbnRfZXJyb3IoIiIrIChhbGdvID09IDEgPyAiSURFQSBBbGdvcml0aG0gbm90IGltcGxlbWVudGVkIiA6ICJUd29maXNoIEFsZ29yaXRobSBub3QgaW1wbGVtZW50ZWQiKSk7DQoJCXJldHVybiBudWxsOw0KCWRlZmF1bHQ6DQoJfQ0KCXJldHVybiBudWxsOw0KfQ0KLyoqDQogKiBHZW5lcmF0aW5nIGEgc2Vzc2lvbiBrZXkgZm9yIHRoZSBzcGVjaWZpZWQgc3ltbWV0cmljIGFsZ29yaXRobQ0KICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIEFsZ29yaXRobSB0byB1c2UgKHNlZSBSRkM0ODgwIDkuMikNCiAqIEByZXR1cm4ge1N0cmluZ30gUmFuZG9tIGJ5dGVzIGFzIGEgc3RyaW5nIHRvIGJlIHVzZWQgYXMgYSBrZXkNCiAqLw0KZnVuY3Rpb24gb3BlbnBncF9jcnlwdG9fZ2VuZXJhdGVTZXNzaW9uS2V5KGFsZ28pIHsNCglzd2l0Y2ggKGFsZ28pIHsNCgljYXNlIDI6IC8vIFRyaXBsZURFUyAoREVTLUVERSwgW1NDSE5FSUVSXSBbSEFDXSAtIDE2OCBiaXQga2V5IGRlcml2ZWQgZnJvbSAxOTIpDQoJY2FzZSA4OiAvLyBBRVMgd2l0aCAxOTItYml0IGtleQ0KCQlyZXR1cm4gb3BlbnBncF9jcnlwdG9fZ2V0UmFuZG9tQnl0ZXMoMjQpOyANCgljYXNlIDM6IC8vIENBU1Q1ICgxMjggYml0IGtleSwgYXMgcGVyIFtSRkMyMTQ0XSkNCgljYXNlIDQ6IC8vIEJsb3dmaXNoICgxMjggYml0IGtleSwgMTYgcm91bmRzKSBbQkxPV0ZJU0hdDQoJY2FzZSA3OiAvLyBBRVMgd2l0aCAxMjgtYml0IGtleSBbQUVTXQ0KCQl1dGlsLnByaW50X2RlYnVnKCJsZW5ndGggPSAxNjpcbiIrdXRpbC5oZXhzdHJkdW1wKG9wZW5wZ3BfY3J5cHRvX2dldFJhbmRvbUJ5dGVzKDE2KSkpOw0KCQlyZXR1cm4gb3BlbnBncF9jcnlwdG9fZ2V0UmFuZG9tQnl0ZXMoMTYpOw0KCWNhc2UgOTogLy8gQUVTIHdpdGggMjU2LWJpdCBrZXkNCgljYXNlIDEwOi8vIFR3b2Zpc2ggd2l0aCAyNTYtYml0IGtleSBbVFdPRklTSF0NCgkJcmV0dXJuIG9wZW5wZ3BfY3J5cHRvX2dldFJhbmRvbUJ5dGVzKDMyKTsNCgl9DQoJcmV0dXJuIG51bGw7DQp9DQoNCi8qKg0KICogDQogKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gcHVibGljIEtleSBhbGdvcml0aG0NCiAqIEBwYXJhbSB7SW50ZWdlcn0gaGFzaF9hbGdvIEhhc2ggYWxnb3JpdGhtDQogKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGlbXX0gbXNnX01QSXMgU2lnbmF0dXJlIG11bHRpcHJlY2lzaW9uIGludGVnZXJzDQogKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGlbXX0gcHVibGlja2V5X01QSXMgUHVibGljIGtleSBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyANCiAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgb24gd2hlcmUgdGhlIHNpZ25hdHVyZSB3YXMgY29tcHV0ZWQgb24uDQogKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlIGlmIHNpZ25hdHVyZSAoc2lnX2RhdGEgd2FzIGVxdWFsIHRvIGRhdGEgb3ZlciBoYXNoKQ0KICovDQpmdW5jdGlvbiBvcGVucGdwX2NyeXB0b192ZXJpZnlTaWduYXR1cmUoYWxnbywgaGFzaF9hbGdvLCBtc2dfTVBJcywgcHVibGlja2V5X01QSXMsIGRhdGEpIHsNCgl2YXIgY2FsY19oYXNoID0gb3BlbnBncF9jcnlwdG9faGFzaERhdGEoaGFzaF9hbGdvLCBkYXRhKTsNCglzd2l0Y2goYWxnbykgew0KCWNhc2UgMTogLy8gUlNBIChFbmNyeXB0IG9yIFNpZ24pIFtIQUNdICANCgljYXNlIDI6IC8vIFJTQSBFbmNyeXB0LU9ubHkgW0hBQ10NCgljYXNlIDM6IC8vIFJTQSBTaWduLU9ubHkgW0hBQ10NCgkJdmFyIHJzYSA9IG5ldyBSU0EoKTsNCgkJdmFyIG4gPSBwdWJsaWNrZXlfTVBJc1swXS50b0JpZ0ludGVnZXIoKTsNCgkJdmFyIGUgPSBwdWJsaWNrZXlfTVBJc1sxXS50b0JpZ0ludGVnZXIoKTsNCgkJdmFyIHggPSBtc2dfTVBJc1swXS50b0JpZ0ludGVnZXIoKTsNCgkJdmFyIGRvcHVibGljID0gcnNhLnZlcmlmeSh4LGUsbik7DQoJCXZhciBoYXNoICA9IG9wZW5wZ3BfZW5jb2RpbmdfZW1zYV9wa2NzMV9kZWNvZGUoaGFzaF9hbGdvLGRvcHVibGljLnRvTVBJKCkuc3Vic3RyaW5nKDIpKTsNCgkJaWYgKGhhc2ggPT0gLTEpIHsNCgkJCXV0aWwucHJpbnRfZXJyb3IoIlBLQ1MxIHBhZGRpbmcgaW4gbWVzc2FnZSBvciBrZXkgaW5jb3JyZWN0LiBBYm9ydGluZy4uLiIpOw0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoJCXJldHVybiBoYXNoID09IGNhbGNfaGFzaDsNCgkJDQoJY2FzZSAxNjogLy8gRWxnYW1hbCAoRW5jcnlwdC1Pbmx5KSBbRUxHQU1BTF0gW0hBQ10NCgkJdXRpbC5wcmludF9lcnJvcigic2lnbmluZyB3aXRoIEVsZ2FtYWwgaXMgbm90IGRlZmluZWQgaW4gdGhlIE9wZW5QR1Agc3RhbmRhcmQuIik7DQoJCXJldHVybiBudWxsOw0KCWNhc2UgMTc6IC8vIERTQSAoRGlnaXRhbCBTaWduYXR1cmUgQWxnb3JpdGhtKSBbRklQUzE4Nl0gW0hBQ10NCgkJdmFyIGRzYSA9IG5ldyBEU0EoKTsNCgkJdmFyIHMxID0gbXNnX01QSXNbMF0udG9CaWdJbnRlZ2VyKCk7DQoJCXZhciBzMiA9IG1zZ19NUElzWzFdLnRvQmlnSW50ZWdlcigpOw0KCQl2YXIgcCA9IHB1YmxpY2tleV9NUElzWzBdLnRvQmlnSW50ZWdlcigpOw0KCQl2YXIgcSA9IHB1YmxpY2tleV9NUElzWzFdLnRvQmlnSW50ZWdlcigpOw0KCQl2YXIgZyA9IHB1YmxpY2tleV9NUElzWzJdLnRvQmlnSW50ZWdlcigpOw0KCQl2YXIgeSA9IHB1YmxpY2tleV9NUElzWzNdLnRvQmlnSW50ZWdlcigpOw0KCQl2YXIgbSA9IGRhdGE7DQoJCXZhciBkb3B1YmxpYyA9IGRzYS52ZXJpZnkoaGFzaF9hbGdvLHMxLHMyLG0scCxxLGcseSk7DQoJCXJldHVybiBkb3B1YmxpYy5jb21wYXJlVG8oczEpID09IDA7DQoJZGVmYXVsdDoNCgkJcmV0dXJuIG51bGw7DQoJfQ0KCQ0KfQ0KICAgDQovKioNCiAqIENyZWF0ZSBhIHNpZ25hdHVyZSBvbiBkYXRhIHVzaW5nIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtDQogKiBAcGFyYW0ge0ludGVnZXJ9IGhhc2hfYWxnbyBoYXNoIEFsZ29yaXRobSB0byB1c2UgKFNlZSBSRkM0ODgwIDkuNCkNCiAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBBc3ltbWV0cmljIGNpcGhlciBhbGdvcml0aG0gdG8gdXNlIChTZWUgUkZDNDg4MCA5LjEpDQogKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGlbXX0gcHVibGljTVBJcyBQdWJsaWMga2V5IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIA0KICogb2YgdGhlIHByaXZhdGUga2V5IA0KICogQHBhcmFtIHtvcGVucGdwX3R5cGVfbXBpW119IHNlY3JldE1QSXMgUHJpdmF0ZSBrZXkgbXVsdGlwcmVjaXNpb24gDQogKiBpbnRlZ2VycyB3aGljaCBpcyB1c2VkIHRvIHNpZ24gdGhlIGRhdGENCiAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgdG8gYmUgc2lnbmVkDQogKiBAcmV0dXJuIHsoU3RyaW5nfG9wZW5wZ3BfdHlwZV9tcGkpfQ0KICovDQpmdW5jdGlvbiBvcGVucGdwX2NyeXB0b19zaWduRGF0YShoYXNoX2FsZ28sIGFsZ28sIHB1YmxpY01QSXMsIHNlY3JldE1QSXMsIGRhdGEpIHsNCgkNCglzd2l0Y2goYWxnbykgew0KCWNhc2UgMTogLy8gUlNBIChFbmNyeXB0IG9yIFNpZ24pIFtIQUNdICANCgljYXNlIDI6IC8vIFJTQSBFbmNyeXB0LU9ubHkgW0hBQ10NCgljYXNlIDM6IC8vIFJTQSBTaWduLU9ubHkgW0hBQ10NCgkJdmFyIHJzYSA9IG5ldyBSU0EoKTsNCgkJdmFyIGQgPSBzZWNyZXRNUElzWzBdLnRvQmlnSW50ZWdlcigpOw0KCQl2YXIgbiA9IHB1YmxpY01QSXNbMF0udG9CaWdJbnRlZ2VyKCk7DQoJCXZhciBtID0gb3BlbnBncF9lbmNvZGluZ19lbXNhX3BrY3MxX2VuY29kZShoYXNoX2FsZ28sIGRhdGEscHVibGljTVBJc1swXS5tcGlCeXRlTGVuZ3RoKTsNCgkJdXRpbC5wcmludF9kZWJ1Zygic2lnbmluZyB1c2luZyBSU0EiKTsNCgkJcmV0dXJuIHJzYS5zaWduKG0sIGQsIG4pLnRvTVBJKCk7DQoJY2FzZSAxNzogLy8gRFNBIChEaWdpdGFsIFNpZ25hdHVyZSBBbGdvcml0aG0pIFtGSVBTMTg2XSBbSEFDXQ0KCQl2YXIgZHNhID0gbmV3IERTQSgpOw0KCQl1dGlsLnByaW50X2RlYnVnKCJEU0EgU2lnbjogcSBzaXplIGluIEJ5dGVzOiIrcHVibGljTVBJc1sxXS5nZXRCeXRlTGVuZ3RoKCkpOw0KCQl2YXIgcCA9IHB1YmxpY01QSXNbMF0udG9CaWdJbnRlZ2VyKCk7DQoJCXZhciBxID0gcHVibGljTVBJc1sxXS50b0JpZ0ludGVnZXIoKTsNCgkJdmFyIGcgPSBwdWJsaWNNUElzWzJdLnRvQmlnSW50ZWdlcigpOw0KCQl2YXIgeSA9IHB1YmxpY01QSXNbM10udG9CaWdJbnRlZ2VyKCk7DQoJCXZhciB4ID0gc2VjcmV0TVBJc1swXS50b0JpZ0ludGVnZXIoKTsNCgkJdmFyIG0gPSBkYXRhOw0KCQl2YXIgcmVzdWx0ID0gZHNhLnNpZ24oaGFzaF9hbGdvLG0sIGcsIHAsIHEsIHgpOw0KCQl1dGlsLnByaW50X2RlYnVnKCJzaWduaW5nIHVzaW5nIERTQVxuIHJlc3VsdDoiK3V0aWwuaGV4c3RyZHVtcChyZXN1bHRbMF0pKyJ8Iit1dGlsLmhleHN0cmR1bXAocmVzdWx0WzFdKSk7DQoJCXJldHVybiByZXN1bHRbMF0rcmVzdWx0WzFdOw0KCWNhc2UgMTY6IC8vIEVsZ2FtYWwgKEVuY3J5cHQtT25seSkgW0VMR0FNQUxdIFtIQUNdDQoJCQl1dGlsLnByaW50X2RlYnVnKCJzaWduaW5nIHdpdGggRWxnYW1hbCBpcyBub3QgZGVmaW5lZCBpbiB0aGUgT3BlblBHUCBzdGFuZGFyZC4iKTsNCgkJCXJldHVybiBudWxsOw0KCWRlZmF1bHQ6DQoJCXJldHVybiBudWxsOw0KCX0JDQp9DQoNCi8qKg0KICogQ3JlYXRlIGEgaGFzaCBvbiB0aGUgc3BlY2lmaWVkIGRhdGEgdXNpbmcgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0NCiAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBIYXNoIGFsZ29yaXRobSB0eXBlIChzZWUgUkZDNDg4MCA5LjQpDQogKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGJlIGhhc2hlZA0KICogQHJldHVybiB7U3RyaW5nfSBoYXNoIHZhbHVlDQogKi8NCmZ1bmN0aW9uIG9wZW5wZ3BfY3J5cHRvX2hhc2hEYXRhKGFsZ28sIGRhdGEpIHsNCgl2YXIgaGFzaCA9IG51bGw7DQoJc3dpdGNoKGFsZ28pIHsNCgljYXNlIDE6IC8vIC0gTUQ1IFtIQUNdDQoJCWhhc2ggPSBNRDUoZGF0YSk7DQoJCWJyZWFrOw0KCWNhc2UgMjogLy8gLSBTSEEtMSBbRklQUzE4MF0NCgkJaGFzaCA9IHN0cl9zaGExKGRhdGEpOw0KCQlicmVhazsNCgljYXNlIDM6IC8vIC0gUklQRS1NRC8xNjAgW0hBQ10NCgkJaGFzaCA9IFJNRHN0cmluZyhkYXRhKTsNCgkJYnJlYWs7DQoJY2FzZSA4OiAvLyAtIFNIQTI1NiBbRklQUzE4MF0NCgkJaGFzaCA9IHN0cl9zaGEyNTYoZGF0YSk7DQoJCWJyZWFrOw0KCWNhc2UgOTogLy8gLSBTSEEzODQgW0ZJUFMxODBdDQoJCWhhc2ggPSBzdHJfc2hhMzg0KGRhdGEpOw0KCQlicmVhazsNCgljYXNlIDEwOi8vIC0gU0hBNTEyIFtGSVBTMTgwXQ0KCQloYXNoID0gc3RyX3NoYTUxMihkYXRhKTsNCgkJYnJlYWs7DQoJY2FzZSAxMTovLyAtIFNIQTIyNCBbRklQUzE4MF0NCgkJaGFzaCA9IHN0cl9zaGEyMjQoZGF0YSk7DQoJZGVmYXVsdDoNCgkJYnJlYWs7DQoJfQ0KCXJldHVybiBoYXNoOw0KfQ0KDQovKioNCiAqIFJldHVybnMgdGhlIGhhc2ggc2l6ZSBpbiBieXRlcyBvZiB0aGUgc3BlY2lmaWVkIGhhc2ggYWxnb3JpdGhtIHR5cGUNCiAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBIYXNoIGFsZ29yaXRobSB0eXBlIChTZWUgUkZDNDg4MCA5LjQpDQogKiBAcmV0dXJuIHtJbnRlZ2VyfSBTaXplIGluIGJ5dGVzIG9mIHRoZSByZXN1bHRpbmcgaGFzaA0KICovDQpmdW5jdGlvbiBvcGVucGdwX2NyeXB0b19nZXRIYXNoQnl0ZUxlbmd0aChhbGdvKSB7DQoJdmFyIGhhc2ggPSBudWxsOw0KCXN3aXRjaChhbGdvKSB7DQoJY2FzZSAxOiAvLyAtIE1ENSBbSEFDXQ0KCQlyZXR1cm4gMTY7DQoJY2FzZSAyOiAvLyAtIFNIQS0xIFtGSVBTMTgwXQ0KCWNhc2UgMzogLy8gLSBSSVBFLU1ELzE2MCBbSEFDXQ0KCQlyZXR1cm4gMjA7DQoJY2FzZSA4OiAvLyAtIFNIQTI1NiBbRklQUzE4MF0NCgkJcmV0dXJuIDMyOw0KCWNhc2UgOTogLy8gLSBTSEEzODQgW0ZJUFMxODBdDQoJCXJldHVybiA0OA0KCWNhc2UgMTA6Ly8gLSBTSEE1MTIgW0ZJUFMxODBdDQoJCXJldHVybiA2NDsNCgljYXNlIDExOi8vIC0gU0hBMjI0IFtGSVBTMTgwXQ0KCQlyZXR1cm4gMjg7DQoJfQ0KCXJldHVybiBudWxsOw0KfQ0KDQovKioNCiAqIFJldHJpZXZlIHNlY3VyZSByYW5kb20gYnl0ZSBzdHJpbmcgb2YgdGhlIHNwZWNpZmllZCBsZW5ndGgNCiAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuZ3RoIExlbmd0aCBpbiBieXRlcyB0byBnZW5lcmF0ZQ0KICogQHJldHVybiB7U3RyaW5nfSBSYW5kb20gYnl0ZSBzdHJpbmcNCiAqLw0KZnVuY3Rpb24gb3BlbnBncF9jcnlwdG9fZ2V0UmFuZG9tQnl0ZXMobGVuZ3RoKSB7DQoJdmFyIHJlc3VsdCA9ICcnOw0KCWZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsNCgkJcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUob3BlbnBncF9jcnlwdG9fZ2V0U2VjdXJlUmFuZG9tT2N0ZXQoKSk7DQoJfQ0KCXJldHVybiByZXN1bHQ7DQp9DQoNCi8qKg0KICogUmV0dXJuIGEgcHNldWRvLXJhbmRvbSBudW1iZXIgaW4gdGhlIHNwZWNpZmllZCByYW5nZQ0KICogQHBhcmFtIHtJbnRlZ2VyfSBmcm9tIE1pbiBvZiB0aGUgcmFuZG9tIG51bWJlcg0KICogQHBhcmFtIHtJbnRlZ2VyfSB0byBNYXggb2YgdGhlIHJhbmRvbSBudW1iZXIgKG1heCAzMmJpdCkNCiAqIEByZXR1cm4ge0ludGVnZXJ9IEEgcHNldWRvIHJhbmRvbSBudW1iZXINCiAqLw0KZnVuY3Rpb24gb3BlbnBncF9jcnlwdG9fZ2V0UHNldWRvUmFuZG9tKGZyb20sIHRvKSB7DQoJcmV0dXJuIE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSoodG8tZnJvbSkpK2Zyb207DQp9DQoNCi8qKg0KICogUmV0dXJuIGEgc2VjdXJlIHJhbmRvbSBudW1iZXIgaW4gdGhlIHNwZWNpZmllZCByYW5nZQ0KICogQHBhcmFtIHtJbnRlZ2VyfSBmcm9tIE1pbiBvZiB0aGUgcmFuZG9tIG51bWJlcg0KICogQHBhcmFtIHtJbnRlZ2VyfSB0byBNYXggb2YgdGhlIHJhbmRvbSBudW1iZXIgKG1heCAzMmJpdCkNCiAqIEByZXR1cm4ge0ludGVnZXJ9IEEgc2VjdXJlIHJhbmRvbSBudW1iZXINCiAqLw0KZnVuY3Rpb24gb3BlbnBncF9jcnlwdG9fZ2V0U2VjdXJlUmFuZG9tKGZyb20sIHRvKSB7DQoJdmFyIGJ1ZiA9IG5ldyBVaW50MzJBcnJheSgxKTsNCgl3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhidWYpOw0KCXZhciBiaXRzID0gKCh0by1mcm9tKSkudG9TdHJpbmcoMikubGVuZ3RoOw0KCXdoaWxlICgoYnVmWzBdICYgKE1hdGgucG93KDIsIGJpdHMpIC0xKSkgPiAodG8tZnJvbSkpDQoJCXdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGJ1Zik7DQoJcmV0dXJuIGZyb20rKE1hdGguYWJzKGJ1ZlswXSAmIChNYXRoLnBvdygyLCBiaXRzKSAtMSkpKTsNCn0NCg0KZnVuY3Rpb24gb3BlbnBncF9jcnlwdG9fZ2V0U2VjdXJlUmFuZG9tT2N0ZXQoKSB7DQoJdmFyIGJ1ZiA9IG5ldyBVaW50MzJBcnJheSgxKTsNCgl3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhidWYpOw0KCXJldHVybiBidWZbMF0gJiAweEZGOw0KfQ0KDQovKioNCiAqIENyZWF0ZSBhIHNlY3VyZSByYW5kb20gYmlnIGludGVnZXIgb2YgYml0cyBsZW5ndGgNCiAqIEBwYXJhbSB7SW50ZWdlcn0gYml0cyBCaXQgbGVuZ3RoIG9mIHRoZSBNUEkgdG8gY3JlYXRlDQogKiBAcmV0dXJuIHtCaWdJbnRlZ2VyfSBSZXN1bHRpbmcgYmlnIGludGVnZXINCiAqLw0KZnVuY3Rpb24gb3BlbnBncF9jcnlwdG9fZ2V0UmFuZG9tQmlnSW50ZWdlcihiaXRzKSB7DQoJaWYgKGJpdHMgPCAwKQ0KCSAgIHJldHVybiBudWxsOw0KCXZhciBudW1CeXRlcyA9IE1hdGguZmxvb3IoKGJpdHMrNykvOCk7DQoNCgl2YXIgcmFuZG9tQml0cyA9IG9wZW5wZ3BfY3J5cHRvX2dldFJhbmRvbUJ5dGVzKG51bUJ5dGVzKTsNCglpZiAoYml0cyAlIDggPiAwKSB7DQoJCQ0KCQlyYW5kb21CaXRzID0gU3RyaW5nLmZyb21DaGFyQ29kZSgNCgkJCQkJCShNYXRoLnBvdygyLGJpdHMgJSA4KS0xKSAmDQoJCQkJCQlyYW5kb21CaXRzLmNoYXJDb2RlQXQoMCkpICsNCgkJCXJhbmRvbUJpdHMuc3Vic3RyaW5nKDEpOw0KCX0NCglyZXR1cm4gbmV3IG9wZW5wZ3BfdHlwZV9tcGkoKS5jcmVhdGUocmFuZG9tQml0cykudG9CaWdJbnRlZ2VyKCk7DQp9DQoNCmZ1bmN0aW9uIG9wZW5wZ3BfY3J5cHRvX2dldFJhbmRvbUJpZ0ludGVnZXJJblJhbmdlKG1pbiwgbWF4KSB7DQoJaWYgKG1heC5jb21wYXJlVG8obWluKSA8PSAwKQ0KCQlyZXR1cm47DQoJdmFyIHJhbmdlID0gbWF4LnN1YnRyYWN0KG1pbik7DQoJdmFyIHIgPSBvcGVucGdwX2NyeXB0b19nZXRSYW5kb21CaWdJbnRlZ2VyKHJhbmdlLmJpdExlbmd0aCgpKTsNCgl3aGlsZSAociA+IHJhbmdlKSB7DQoJCXIgPSBvcGVucGdwX2NyeXB0b19nZXRSYW5kb21CaWdJbnRlZ2VyKHJhbmdlLmJpdExlbmd0aCgpKTsNCgl9DQoJcmV0dXJuIG1pbi5hZGQocik7DQp9DQoNCg0KLy9UaGlzIGlzIGEgdGVzdCBtZXRob2QgdG8gZW5zdXJlIHRoYXQgZW5jcnlwdGlvbi9kZWNyeXB0aW9uIHdpdGggYSBnaXZlbiAxMDI0Yml0IFJTQUtleSBvYmplY3QgZnVuY3Rpb25zIGFzIGludGVuZGVkDQpmdW5jdGlvbiBvcGVucGdwX2NyeXB0b190ZXN0UlNBKGtleSl7DQoJZGVidWdnZXI7DQogICAgdmFyIHJzYSA9IG5ldyBSU0EoKTsNCgl2YXIgbXBpID0gbmV3IG9wZW5wZ3BfdHlwZV9tcGkoKTsNCgltcGkuY3JlYXRlKG9wZW5wZ3BfZW5jb2RpbmdfZW1lX3BrY3MxX2VuY29kZSgnQUJBQkFCQUInLCAxMjgpKTsNCgl2YXIgbXNnID0gcnNhLmVuY3J5cHQobXBpLnRvQmlnSW50ZWdlcigpLGtleS5lZSxrZXkubik7DQoJdmFyIHJlc3VsdCA9IHJzYS5kZWNyeXB0KG1zZywga2V5LmQsIGtleS5wLCBrZXkucSwga2V5LnUpOw0KfQ0KDQovKioNCiAqIEB0eXBlZGVmIHtPYmplY3R9IG9wZW5wZ3Bfa2V5cGFpcg0KICogQHByb3BlcnR5IHtvcGVucGdwX3BhY2tldF9rZXltYXRlcmlhbH0gcHJpdmF0ZUtleSANCiAqIEBwcm9wZXJ0eSB7b3BlbnBncF9wYWNrZXRfa2V5bWF0ZXJpYWx9IHB1YmxpY0tleQ0KICovDQoNCi8qKg0KICogQ2FsbHMgdGhlIG5lY2Vzc2FyeSBjcnlwdG8gZnVuY3Rpb25zIHRvIGdlbmVyYXRlIGEga2V5cGFpci4gDQogKiBDYWxsZWQgZGlyZWN0bHkgYnkgb3BlbnBncC5qcw0KICogQHBhcmFtIHtJbnRlZ2VyfSBrZXlUeXBlIEZvbGxvd3MgT3BlblBHUCBhbGdvcml0aG0gY29udmVudGlvbi4NCiAqIEBwYXJhbSB7SW50ZWdlcn0gbnVtQml0cyBOdW1iZXIgb2YgYml0cyB0byBtYWtlIHRoZSBrZXkgdG8gYmUgZ2VuZXJhdGVkDQogKiBAcmV0dXJuIHtvcGVucGdwX2tleXBhaXJ9DQogKi8NCmZ1bmN0aW9uIG9wZW5wZ3BfY3J5cHRvX2dlbmVyYXRlS2V5UGFpcihrZXlUeXBlLCBudW1CaXRzLCBwYXNzcGhyYXNlLCBzMmtIYXNoLCBzeW1tZXRyaWNFbmNyeXB0aW9uQWxnb3JpdGhtKXsNCgl2YXIgcHJpdktleVBhY2tldDsNCgl2YXIgcHVibGljS2V5UGFja2V0Ow0KCXZhciBkID0gbmV3IERhdGUoKTsNCglkID0gZC5nZXRUaW1lKCkvMTAwMDsNCgl2YXIgdGltZVBhY2tldCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoTWF0aC5mbG9vcihkLzB4MTAwMDAwMCUweDEwMCkpICsgU3RyaW5nLmZyb21DaGFyQ29kZShNYXRoLmZsb29yKGQvMHgxMDAwMCUweDEwMCkpICsgU3RyaW5nLmZyb21DaGFyQ29kZShNYXRoLmZsb29yKGQvMHgxMDAlMHgxMDApKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoTWF0aC5mbG9vcihkJTB4MTAwKSk7DQoJc3dpdGNoKGtleVR5cGUpew0KCWNhc2UgMToNCgkgICAgdmFyIHJzYSA9IG5ldyBSU0EoKTsNCgkgICAgdmFyIGtleSA9IHJzYS5nZW5lcmF0ZShudW1CaXRzLCIxMDAwMSIpOw0KCSAgICBwcml2S2V5UGFja2V0ID0gbmV3IG9wZW5wZ3BfcGFja2V0X2tleW1hdGVyaWFsKCkud3JpdGVfcHJpdmF0ZV9rZXkoa2V5VHlwZSwga2V5LCBwYXNzcGhyYXNlLCBzMmtIYXNoLCBzeW1tZXRyaWNFbmNyeXB0aW9uQWxnb3JpdGhtLCB0aW1lUGFja2V0KTsNCgkgICAgcHVibGljS2V5UGFja2V0ID0gIG5ldyBvcGVucGdwX3BhY2tldF9rZXltYXRlcmlhbCgpLndyaXRlX3B1YmxpY19rZXkoa2V5VHlwZSwga2V5LCB0aW1lUGFja2V0KTsNCgkgICAgYnJlYWs7DQoJZGVmYXVsdDoNCgkJdXRpbC5wcmludF9lcnJvcigiVW5rbm93biBrZXl0eXBlICIra2V5VHlwZSkNCgl9DQoJcmV0dXJuIHtwcml2YXRlS2V5OiBwcml2S2V5UGFja2V0LCBwdWJsaWNLZXk6IHB1YmxpY0tleVBhY2tldH07DQp9DQovLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHQNCi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkgNCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcg0KLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyDQovLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4NCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsDQovLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0KLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUNCi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuDQovLyANCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUNCi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQSANCg0KLy8gVGhlIEdQRzRCcm93c2VycyBzeW1tZXRyaWMgY3J5cHRvIGludGVyZmFjZQ0KDQovKioNCiAqIFN5bW1ldHJpY2FsbHkgZW5jcnlwdHMgZGF0YSB1c2luZyBwcmVmaXhlZHJhbmRvbSwgYSBrZXkgd2l0aCBsZW5ndGggDQogKiBkZXBlbmRpbmcgb24gdGhlIGFsZ29yaXRobSBpbiBvcGVucGdwX2NmYiBtb2RlIHdpdGggb3Igd2l0aG91dCByZXN5bmMNCiAqIChNREMgc3R5bGUpDQogKiBAcGFyYW0ge1N0cmluZ30gcHJlZml4cmFuZG9tIFNlY3VyZSByYW5kb20gYnl0ZXMgYXMgc3RyaW5nIGluIA0KICogbGVuZ3RoIGVxdWFsIHRvIHRoZSBibG9jayBzaXplIG9mIHRoZSBhbGdvcml0aG0gdXNlZCAodXNlIA0KICogb3BlbnBncF9jcnlwdG9fZ2V0UHJlZml4UmFuZG9tKGFsZ28pIHRvIHJldHJpZXZlIHRoYXQgc3RyaW5nDQogKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gQWxnb3JpdGhtIHRvIHVzZSAoc2VlIFJGQzQ4ODAgOS4yKQ0KICogQHBhcmFtIHtTdHJpbmd9IGtleSBLZXkgYXMgc3RyaW5nLiBsZW5ndGggaXMgZGVwZW5kaW5nIG9uIHRoZSBhbGdvcml0aG0gdXNlZA0KICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBlbmNyeXB0DQogKiBAcGFyYW0ge0Jvb2xlYW59IG9wZW5wZ3BfY2ZiDQogKiBAcmV0dXJuIHtTdHJpbmd9IEVuY3J5cHRlZCBkYXRhDQogKi8NCmZ1bmN0aW9uIG9wZW5wZ3BfY3J5cHRvX3N5bW1ldHJpY0VuY3J5cHQocHJlZml4cmFuZG9tLCBhbGdvLCBrZXksIGRhdGEsIG9wZW5wZ3BfY2ZiKSB7DQoJc3dpdGNoKGFsZ28pIHsNCgkJY2FzZSAwOiAvLyBQbGFpbnRleHQgb3IgdW5lbmNyeXB0ZWQgZGF0YQ0KCQkJcmV0dXJuIGRhdGE7IC8vIGJsb2NrY2lwaGVyZW5jcnlwdGZuLCBwbGFpbnRleHQsIGJsb2NrX3NpemUsIGtleQ0KCQljYXNlIDI6IC8vIFRyaXBsZURFUyAoREVTLUVERSwgW1NDSE5FSUVSXSBbSEFDXSAtIDE2OCBiaXQga2V5IGRlcml2ZWQgZnJvbSAxOTIpDQoJCQlyZXR1cm4gb3BlbnBncF9jZmJfZW5jcnlwdChwcmVmaXhyYW5kb20sIGRlc2VkZSwgZGF0YSw4LGtleSwgb3BlbnBncF9jZmIpLnN1YnN0cmluZygwLCBkYXRhLmxlbmd0aCArIDEwKTsNCgkJY2FzZSAzOiAvLyBDQVNUNSAoMTI4IGJpdCBrZXksIGFzIHBlciBbUkZDMjE0NF0pDQoJCQlyZXR1cm4gb3BlbnBncF9jZmJfZW5jcnlwdChwcmVmaXhyYW5kb20sIGNhc3Q1X2VuY3J5cHQsIGRhdGEsOCxrZXksIG9wZW5wZ3BfY2ZiKS5zdWJzdHJpbmcoMCwgZGF0YS5sZW5ndGggKyAxMCk7DQoJCWNhc2UgNDogLy8gQmxvd2Zpc2ggKDEyOCBiaXQga2V5LCAxNiByb3VuZHMpIFtCTE9XRklTSF0NCgkJCXJldHVybiBvcGVucGdwX2NmYl9lbmNyeXB0KHByZWZpeHJhbmRvbSwgQkZlbmNyeXB0LCBkYXRhLDgsa2V5LCBvcGVucGdwX2NmYikuc3Vic3RyaW5nKDAsIGRhdGEubGVuZ3RoICsgMTApOw0KCQljYXNlIDc6IC8vIEFFUyB3aXRoIDEyOC1iaXQga2V5IFtBRVNdDQoJCWNhc2UgODogLy8gQUVTIHdpdGggMTkyLWJpdCBrZXkNCgkJY2FzZSA5OiAvLyBBRVMgd2l0aCAyNTYtYml0IGtleQ0KCQkJcmV0dXJuIG9wZW5wZ3BfY2ZiX2VuY3J5cHQocHJlZml4cmFuZG9tLCBBRVNlbmNyeXB0LCBkYXRhLCAxNiwga2V5RXhwYW5zaW9uKGtleSksIG9wZW5wZ3BfY2ZiKS5zdWJzdHJpbmcoMCwgZGF0YS5sZW5ndGggKyAxOCk7DQoJCWNhc2UgMTA6IC8vIFR3b2Zpc2ggd2l0aCAyNTYtYml0IGtleSBbVFdPRklTSF0NCgkJCXJldHVybiBvcGVucGdwX2NmYl9lbmNyeXB0KHByZWZpeHJhbmRvbSwgVEZlbmNyeXB0LCBkYXRhLDE2LCBrZXksIG9wZW5wZ3BfY2ZiKS5zdWJzdHJpbmcoMCwgZGF0YS5sZW5ndGggKyAxOCk7DQoJCWNhc2UgMTogLy8gSURFQSBbSURFQV0NCgkJCXV0aWwucHJpbnRfZXJyb3IoIklERUEgQWxnb3JpdGhtIG5vdCBpbXBsZW1lbnRlZCIpOw0KCQkJcmV0dXJuIG51bGw7DQoJCWRlZmF1bHQ6DQoJCQlyZXR1cm4gbnVsbDsNCgl9DQp9DQoNCi8qKg0KICogU3ltbWV0cmljYWxseSBkZWNyeXB0cyBkYXRhIHVzaW5nIGEga2V5IHdpdGggbGVuZ3RoIGRlcGVuZGluZyBvbiB0aGUNCiAqIGFsZ29yaXRobSBpbiBvcGVucGdwX2NmYiBtb2RlIHdpdGggb3Igd2l0aG91dCByZXN5bmMgKE1EQyBzdHlsZSkNCiAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBBbGdvcml0aG0gdG8gdXNlIChzZWUgUkZDNDg4MCA5LjIpDQogKiBAcGFyYW0ge1N0cmluZ30ga2V5IEtleSBhcyBzdHJpbmcuIGxlbmd0aCBpcyBkZXBlbmRpbmcgb24gdGhlIGFsZ29yaXRobSB1c2VkDQogKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGJlIGRlY3J5cHRlZA0KICogQHBhcmFtIHtCb29sZWFufSBvcGVucGdwX2NmYiBJZiB0cnVlIHVzZSB0aGUgcmVzeW5jIChmb3IgZW5jcnlwdGVkZGF0YSk7IA0KICogb3RoZXJ3aXNlIHVzZSB3aXRob3V0IHRoZSByZXN5bmMgKGZvciBNREMgZW5jcnlwdGVkIGRhdGEpDQogKiBAcmV0dXJuIHtTdHJpbmd9IFBsYWludGV4dCBkYXRhDQogKi8NCmZ1bmN0aW9uIG9wZW5wZ3BfY3J5cHRvX3N5bW1ldHJpY0RlY3J5cHQoYWxnbywga2V5LCBkYXRhLCBvcGVucGdwX2NmYikgew0KCXV0aWwucHJpbnRfZGVidWdfaGV4c3RyX2R1bXAoIm9wZW5wZ3BfY3J5cHRvX3N5bW1ldHJpY0RlY3J5cHQ6XG5hbGdvOiIrYWxnbysiXG5lbmNyeXB0ZWRkYXRhOiIsZGF0YSk7DQoJdmFyIG4gPSAwOw0KCWlmICghb3BlbnBncF9jZmIpDQoJCW4gPSAyOw0KCXN3aXRjaChhbGdvKSB7DQoJY2FzZSAwOiAvLyBQbGFpbnRleHQgb3IgdW5lbmNyeXB0ZWQgZGF0YQ0KCQlyZXR1cm4gZGF0YTsNCgljYXNlIDI6IC8vIFRyaXBsZURFUyAoREVTLUVERSwgW1NDSE5FSUVSXSBbSEFDXSAtIDE2OCBiaXQga2V5IGRlcml2ZWQgZnJvbSAxOTIpDQoJCXJldHVybiBvcGVucGdwX2NmYl9kZWNyeXB0KGRlc2VkZSwgOCwga2V5LCBkYXRhLCBvcGVucGdwX2NmYikuc3Vic3RyaW5nKG4sIChkYXRhLmxlbmd0aCtuKS0xMCk7DQoJY2FzZSAzOiAvLyBDQVNUNSAoMTI4IGJpdCBrZXksIGFzIHBlciBbUkZDMjE0NF0pDQoJCXJldHVybiBvcGVucGdwX2NmYl9kZWNyeXB0KGNhc3Q1X2VuY3J5cHQsIDgsIGtleSwgZGF0YSwgb3BlbnBncF9jZmIpLnN1YnN0cmluZyhuLCAoZGF0YS5sZW5ndGgrbiktMTApOw0KCWNhc2UgNDogLy8gQmxvd2Zpc2ggKDEyOCBiaXQga2V5LCAxNiByb3VuZHMpIFtCTE9XRklTSF0NCgkJcmV0dXJuIG9wZW5wZ3BfY2ZiX2RlY3J5cHQoQkZlbmNyeXB0LCA4LCBrZXksIGRhdGEsIG9wZW5wZ3BfY2ZiKS5zdWJzdHJpbmcobiwgKGRhdGEubGVuZ3RoK24pLTEwKTsNCgljYXNlIDc6IC8vIEFFUyB3aXRoIDEyOC1iaXQga2V5IFtBRVNdDQoJY2FzZSA4OiAvLyBBRVMgd2l0aCAxOTItYml0IGtleQ0KCWNhc2UgOTogLy8gQUVTIHdpdGggMjU2LWJpdCBrZXkNCgkJcmV0dXJuIG9wZW5wZ3BfY2ZiX2RlY3J5cHQoQUVTZW5jcnlwdCwgMTYsIGtleUV4cGFuc2lvbihrZXkpLCBkYXRhLCBvcGVucGdwX2NmYikuc3Vic3RyaW5nKG4sIChkYXRhLmxlbmd0aCtuKS0xOCk7DQoJY2FzZSAxMDogLy8gVHdvZmlzaCB3aXRoIDI1Ni1iaXQga2V5IFtUV09GSVNIXQ0KCQl2YXIgcmVzdWx0ID0gb3BlbnBncF9jZmJfZGVjcnlwdChURmVuY3J5cHQsIDE2LCBrZXksIGRhdGEsIG9wZW5wZ3BfY2ZiKS5zdWJzdHJpbmcobiwgKGRhdGEubGVuZ3RoK24pLTE4KTsNCgkJcmV0dXJuIHJlc3VsdDsNCgljYXNlIDE6IC8vIElERUEgW0lERUFdDQoJCXV0aWwucHJpbnRfZXJyb3IoIiIrIChhbGdvID09IDEgPyAiSURFQSBBbGdvcml0aG0gbm90IGltcGxlbWVudGVkIiA6ICJUd29maXNoIEFsZ29yaXRobSBub3QgaW1wbGVtZW50ZWQiKSk7DQoJCXJldHVybiBudWxsOw0KCWRlZmF1bHQ6DQoJfQ0KCXJldHVybiBudWxsOw0KfQ0KDQovKiBSaWpuZGFlbCAoQUVTKSBFbmNyeXB0aW9uDQogKiBDb3B5cmlnaHQgMjAwNSBIZXJiZXJ0IEhhbmV3aW5rZWwsIHd3dy5oYW5lV0lOLmRlDQogKiB2ZXJzaW9uIDEuMSwgY2hlY2sgd3d3LmhhbmVXSU4uZGUgZm9yIHRoZSBsYXRlc3QgdmVyc2lvbg0KDQogKiBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkIGFzLWlzLCB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4gIA0KICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSBvciBzZWxsIHRoaXMgc29mdHdhcmUsIHdpdGggb3INCiAqIHdpdGhvdXQgZmVlLCBmb3IgYW55IHB1cnBvc2UgYW5kIGJ5IGFueSBpbmRpdmlkdWFsIG9yIG9yZ2FuaXphdGlvbiwgaXMgaGVyZWJ5DQogKiBncmFudGVkLCBwcm92aWRlZCB0aGF0IHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBhcmFncmFwaCBhcHBlYXIgDQogKiBpbiBhbGwgY29waWVzLiBEaXN0cmlidXRpb24gYXMgYSBwYXJ0IG9mIGFuIGFwcGxpY2F0aW9uIG9yIGJpbmFyeSBtdXN0DQogKiBpbmNsdWRlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlcg0KICogbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGFwcGxpY2F0aW9uIG9yIGRpc3RyaWJ1dGlvbi4NCiAqLw0KDQovLyBUaGUgcm91bmQgY29uc3RhbnRzIHVzZWQgaW4gc3Via2V5IGV4cGFuc2lvbg0KdmFyIFJjb24gPSBbIA0KMHgwMSwgMHgwMiwgMHgwNCwgMHgwOCwgMHgxMCwgMHgyMCwgMHg0MCwgMHg4MCwgMHgxYiwgMHgzNiwgMHg2YywgMHhkOCwgDQoweGFiLCAweDRkLCAweDlhLCAweDJmLCAweDVlLCAweGJjLCAweDYzLCAweGM2LCAweDk3LCAweDM1LCAweDZhLCAweGQ0LCANCjB4YjMsIDB4N2QsIDB4ZmEsIDB4ZWYsIDB4YzUsIDB4OTEgXTsNCg0KLy8gUHJlY29tcHV0ZWQgbG9va3VwIHRhYmxlIGZvciB0aGUgU0JveA0KdmFyIFMgPSBbDQogOTksIDEyNCwgMTE5LCAxMjMsIDI0MiwgMTA3LCAxMTEsIDE5NywgIDQ4LCAgIDEsIDEwMywgIDQzLCAyNTQsIDIxNSwgMTcxLCANCjExOCwgMjAyLCAxMzAsIDIwMSwgMTI1LCAyNTAsICA4OSwgIDcxLCAyNDAsIDE3MywgMjEyLCAxNjIsIDE3NSwgMTU2LCAxNjQsIA0KMTE0LCAxOTIsIDE4MywgMjUzLCAxNDcsICAzOCwgIDU0LCAgNjMsIDI0NywgMjA0LCAgNTIsIDE2NSwgMjI5LCAyNDEsIDExMywgDQoyMTYsICA0OSwgIDIxLCAgIDQsIDE5OSwgIDM1LCAxOTUsICAyNCwgMTUwLCAgIDUsIDE1NCwgICA3LCAgMTgsIDEyOCwgMjI2LCANCjIzNSwgIDM5LCAxNzgsIDExNywgICA5LCAxMzEsICA0NCwgIDI2LCAgMjcsIDExMCwgIDkwLCAxNjAsICA4MiwgIDU5LCAyMTQsIA0KMTc5LCAgNDEsIDIyNywgIDQ3LCAxMzIsICA4MywgMjA5LCAgIDAsIDIzNywgIDMyLCAyNTIsIDE3NywgIDkxLCAxMDYsIDIwMywgDQoxOTAsICA1NywgIDc0LCAgNzYsICA4OCwgMjA3LCAyMDgsIDIzOSwgMTcwLCAyNTEsICA2NywgIDc3LCAgNTEsIDEzMywgIDY5LCANCjI0OSwgICAyLCAxMjcsICA4MCwgIDYwLCAxNTksIDE2OCwgIDgxLCAxNjMsICA2NCwgMTQzLCAxNDYsIDE1NywgIDU2LCAyNDUsIA0KMTg4LCAxODIsIDIxOCwgIDMzLCAgMTYsIDI1NSwgMjQzLCAyMTAsIDIwNSwgIDEyLCAgMTksIDIzNiwgIDk1LCAxNTEsICA2OCwgIA0KMjMsICAxOTYsIDE2NywgMTI2LCAgNjEsIDEwMCwgIDkzLCAgMjUsIDExNSwgIDk2LCAxMjksICA3OSwgMjIwLCAgMzQsICA0MiwgDQoxNDQsIDEzNiwgIDcwLCAyMzgsIDE4NCwgIDIwLCAyMjIsICA5NCwgIDExLCAyMTksIDIyNCwgIDUwLCAgNTgsICAxMCwgIDczLA0KICA2LCAgMzYsICA5MiwgMTk0LCAyMTEsIDE3MiwgIDk4LCAxNDUsIDE0OSwgMjI4LCAxMjEsIDIzMSwgMjAwLCAgNTUsIDEwOSwgDQoxNDEsIDIxMywgIDc4LCAxNjksIDEwOCwgIDg2LCAyNDQsIDIzNCwgMTAxLCAxMjIsIDE3NCwgICA4LCAxODYsIDEyMCwgIDM3LCAgDQogNDYsICAyOCwgMTY2LCAxODAsIDE5OCwgMjMyLCAyMjEsIDExNiwgIDMxLCAgNzUsIDE4OSwgMTM5LCAxMzgsIDExMiwgIDYyLCANCjE4MSwgMTAyLCAgNzIsICAgMywgMjQ2LCAgMTQsICA5NywgIDUzLCAgODcsIDE4NSwgMTM0LCAxOTMsICAyOSwgMTU4LCAyMjUsDQoyNDgsIDE1MiwgIDE3LCAxMDUsIDIxNywgMTQyLCAxNDgsIDE1NSwgIDMwLCAxMzUsIDIzMywgMjA2LCAgODUsICA0MCwgMjIzLA0KMTQwLCAxNjEsIDEzNywgIDEzLCAxOTEsIDIzMCwgIDY2LCAxMDQsICA2NSwgMTUzLCAgNDUsICAxNSwgMTc2LCAgODQsIDE4NywgIA0KIDIyIF07DQoNCnZhciBUMSA9IFsNCjB4YTU2MzYzYzYsIDB4ODQ3YzdjZjgsIDB4OTk3Nzc3ZWUsIDB4OGQ3YjdiZjYsDQoweDBkZjJmMmZmLCAweGJkNmI2YmQ2LCAweGIxNmY2ZmRlLCAweDU0YzVjNTkxLA0KMHg1MDMwMzA2MCwgMHgwMzAxMDEwMiwgMHhhOTY3NjdjZSwgMHg3ZDJiMmI1NiwNCjB4MTlmZWZlZTcsIDB4NjJkN2Q3YjUsIDB4ZTZhYmFiNGQsIDB4OWE3Njc2ZWMsDQoweDQ1Y2FjYThmLCAweDlkODI4MjFmLCAweDQwYzljOTg5LCAweDg3N2Q3ZGZhLA0KMHgxNWZhZmFlZiwgMHhlYjU5NTliMiwgMHhjOTQ3NDc4ZSwgMHgwYmYwZjBmYiwNCjB4ZWNhZGFkNDEsIDB4NjdkNGQ0YjMsIDB4ZmRhMmEyNWYsIDB4ZWFhZmFmNDUsDQoweGJmOWM5YzIzLCAweGY3YTRhNDUzLCAweDk2NzI3MmU0LCAweDViYzBjMDliLA0KMHhjMmI3Yjc3NSwgMHgxY2ZkZmRlMSwgMHhhZTkzOTMzZCwgMHg2YTI2MjY0YywNCjB4NWEzNjM2NmMsIDB4NDEzZjNmN2UsIDB4MDJmN2Y3ZjUsIDB4NGZjY2NjODMsDQoweDVjMzQzNDY4LCAweGY0YTVhNTUxLCAweDM0ZTVlNWQxLCAweDA4ZjFmMWY5LA0KMHg5MzcxNzFlMiwgMHg3M2Q4ZDhhYiwgMHg1MzMxMzE2MiwgMHgzZjE1MTUyYSwNCjB4MGMwNDA0MDgsIDB4NTJjN2M3OTUsIDB4NjUyMzIzNDYsIDB4NWVjM2MzOWQsDQoweDI4MTgxODMwLCAweGExOTY5NjM3LCAweDBmMDUwNTBhLCAweGI1OWE5YTJmLA0KMHgwOTA3MDcwZSwgMHgzNjEyMTIyNCwgMHg5YjgwODAxYiwgMHgzZGUyZTJkZiwNCjB4MjZlYmViY2QsIDB4NjkyNzI3NGUsIDB4Y2RiMmIyN2YsIDB4OWY3NTc1ZWEsDQoweDFiMDkwOTEyLCAweDllODM4MzFkLCAweDc0MmMyYzU4LCAweDJlMWExYTM0LA0KMHgyZDFiMWIzNiwgMHhiMjZlNmVkYywgMHhlZTVhNWFiNCwgMHhmYmEwYTA1YiwNCjB4ZjY1MjUyYTQsIDB4NGQzYjNiNzYsIDB4NjFkNmQ2YjcsIDB4Y2ViM2IzN2QsDQoweDdiMjkyOTUyLCAweDNlZTNlM2RkLCAweDcxMmYyZjVlLCAweDk3ODQ4NDEzLA0KMHhmNTUzNTNhNiwgMHg2OGQxZDFiOSwgMHgwMDAwMDAwMCwgMHgyY2VkZWRjMSwNCjB4NjAyMDIwNDAsIDB4MWZmY2ZjZTMsIDB4YzhiMWIxNzksIDB4ZWQ1YjViYjYsDQoweGJlNmE2YWQ0LCAweDQ2Y2JjYjhkLCAweGQ5YmViZTY3LCAweDRiMzkzOTcyLA0KMHhkZTRhNGE5NCwgMHhkNDRjNGM5OCwgMHhlODU4NThiMCwgMHg0YWNmY2Y4NSwNCjB4NmJkMGQwYmIsIDB4MmFlZmVmYzUsIDB4ZTVhYWFhNGYsIDB4MTZmYmZiZWQsDQoweGM1NDM0Mzg2LCAweGQ3NGQ0ZDlhLCAweDU1MzMzMzY2LCAweDk0ODU4NTExLA0KMHhjZjQ1NDU4YSwgMHgxMGY5ZjllOSwgMHgwNjAyMDIwNCwgMHg4MTdmN2ZmZSwNCjB4ZjA1MDUwYTAsIDB4NDQzYzNjNzgsIDB4YmE5ZjlmMjUsIDB4ZTNhOGE4NGIsDQoweGYzNTE1MWEyLCAweGZlYTNhMzVkLCAweGMwNDA0MDgwLCAweDhhOGY4ZjA1LA0KMHhhZDkyOTIzZiwgMHhiYzlkOWQyMSwgMHg0ODM4Mzg3MCwgMHgwNGY1ZjVmMSwNCjB4ZGZiY2JjNjMsIDB4YzFiNmI2NzcsIDB4NzVkYWRhYWYsIDB4NjMyMTIxNDIsDQoweDMwMTAxMDIwLCAweDFhZmZmZmU1LCAweDBlZjNmM2ZkLCAweDZkZDJkMmJmLA0KMHg0Y2NkY2Q4MSwgMHgxNDBjMGMxOCwgMHgzNTEzMTMyNiwgMHgyZmVjZWNjMywNCjB4ZTE1ZjVmYmUsIDB4YTI5Nzk3MzUsIDB4Y2M0NDQ0ODgsIDB4MzkxNzE3MmUsDQoweDU3YzRjNDkzLCAweGYyYTdhNzU1LCAweDgyN2U3ZWZjLCAweDQ3M2QzZDdhLA0KMHhhYzY0NjRjOCwgMHhlNzVkNWRiYSwgMHgyYjE5MTkzMiwgMHg5NTczNzNlNiwNCjB4YTA2MDYwYzAsIDB4OTg4MTgxMTksIDB4ZDE0ZjRmOWUsIDB4N2ZkY2RjYTMsDQoweDY2MjIyMjQ0LCAweDdlMmEyYTU0LCAweGFiOTA5MDNiLCAweDgzODg4ODBiLA0KMHhjYTQ2NDY4YywgMHgyOWVlZWVjNywgMHhkM2I4Yjg2YiwgMHgzYzE0MTQyOCwNCjB4NzlkZWRlYTcsIDB4ZTI1ZTVlYmMsIDB4MWQwYjBiMTYsIDB4NzZkYmRiYWQsDQoweDNiZTBlMGRiLCAweDU2MzIzMjY0LCAweDRlM2EzYTc0LCAweDFlMGEwYTE0LA0KMHhkYjQ5NDk5MiwgMHgwYTA2MDYwYywgMHg2YzI0MjQ0OCwgMHhlNDVjNWNiOCwNCjB4NWRjMmMyOWYsIDB4NmVkM2QzYmQsIDB4ZWZhY2FjNDMsIDB4YTY2MjYyYzQsDQoweGE4OTE5MTM5LCAweGE0OTU5NTMxLCAweDM3ZTRlNGQzLCAweDhiNzk3OWYyLA0KMHgzMmU3ZTdkNSwgMHg0M2M4Yzg4YiwgMHg1OTM3Mzc2ZSwgMHhiNzZkNmRkYSwNCjB4OGM4ZDhkMDEsIDB4NjRkNWQ1YjEsIDB4ZDI0ZTRlOWMsIDB4ZTBhOWE5NDksDQoweGI0NmM2Y2Q4LCAweGZhNTY1NmFjLCAweDA3ZjRmNGYzLCAweDI1ZWFlYWNmLA0KMHhhZjY1NjVjYSwgMHg4ZTdhN2FmNCwgMHhlOWFlYWU0NywgMHgxODA4MDgxMCwNCjB4ZDViYWJhNmYsIDB4ODg3ODc4ZjAsIDB4NmYyNTI1NGEsIDB4NzIyZTJlNWMsDQoweDI0MWMxYzM4LCAweGYxYTZhNjU3LCAweGM3YjRiNDczLCAweDUxYzZjNjk3LA0KMHgyM2U4ZThjYiwgMHg3Y2RkZGRhMSwgMHg5Yzc0NzRlOCwgMHgyMTFmMWYzZSwNCjB4ZGQ0YjRiOTYsIDB4ZGNiZGJkNjEsIDB4ODY4YjhiMGQsIDB4ODU4YThhMGYsDQoweDkwNzA3MGUwLCAweDQyM2UzZTdjLCAweGM0YjViNTcxLCAweGFhNjY2NmNjLA0KMHhkODQ4NDg5MCwgMHgwNTAzMDMwNiwgMHgwMWY2ZjZmNywgMHgxMjBlMGUxYywNCjB4YTM2MTYxYzIsIDB4NWYzNTM1NmEsIDB4Zjk1NzU3YWUsIDB4ZDBiOWI5NjksDQoweDkxODY4NjE3LCAweDU4YzFjMTk5LCAweDI3MWQxZDNhLCAweGI5OWU5ZTI3LA0KMHgzOGUxZTFkOSwgMHgxM2Y4ZjhlYiwgMHhiMzk4OTgyYiwgMHgzMzExMTEyMiwNCjB4YmI2OTY5ZDIsIDB4NzBkOWQ5YTksIDB4ODk4ZThlMDcsIDB4YTc5NDk0MzMsDQoweGI2OWI5YjJkLCAweDIyMWUxZTNjLCAweDkyODc4NzE1LCAweDIwZTllOWM5LA0KMHg0OWNlY2U4NywgMHhmZjU1NTVhYSwgMHg3ODI4Mjg1MCwgMHg3YWRmZGZhNSwNCjB4OGY4YzhjMDMsIDB4ZjhhMWExNTksIDB4ODA4OTg5MDksIDB4MTcwZDBkMWEsDQoweGRhYmZiZjY1LCAweDMxZTZlNmQ3LCAweGM2NDI0Mjg0LCAweGI4Njg2OGQwLA0KMHhjMzQxNDE4MiwgMHhiMDk5OTkyOSwgMHg3NzJkMmQ1YSwgMHgxMTBmMGYxZSwNCjB4Y2JiMGIwN2IsIDB4ZmM1NDU0YTgsIDB4ZDZiYmJiNmQsIDB4M2ExNjE2MmMgXTsNCg0KdmFyIFQyID0gWw0KMHg2MzYzYzZhNSwgMHg3YzdjZjg4NCwgMHg3Nzc3ZWU5OSwgMHg3YjdiZjY4ZCwNCjB4ZjJmMmZmMGQsIDB4NmI2YmQ2YmQsIDB4NmY2ZmRlYjEsIDB4YzVjNTkxNTQsDQoweDMwMzA2MDUwLCAweDAxMDEwMjAzLCAweDY3NjdjZWE5LCAweDJiMmI1NjdkLA0KMHhmZWZlZTcxOSwgMHhkN2Q3YjU2MiwgMHhhYmFiNGRlNiwgMHg3Njc2ZWM5YSwNCjB4Y2FjYThmNDUsIDB4ODI4MjFmOWQsIDB4YzljOTg5NDAsIDB4N2Q3ZGZhODcsDQoweGZhZmFlZjE1LCAweDU5NTliMmViLCAweDQ3NDc4ZWM5LCAweGYwZjBmYjBiLA0KMHhhZGFkNDFlYywgMHhkNGQ0YjM2NywgMHhhMmEyNWZmZCwgMHhhZmFmNDVlYSwNCjB4OWM5YzIzYmYsIDB4YTRhNDUzZjcsIDB4NzI3MmU0OTYsIDB4YzBjMDliNWIsDQoweGI3Yjc3NWMyLCAweGZkZmRlMTFjLCAweDkzOTMzZGFlLCAweDI2MjY0YzZhLA0KMHgzNjM2NmM1YSwgMHgzZjNmN2U0MSwgMHhmN2Y3ZjUwMiwgMHhjY2NjODM0ZiwNCjB4MzQzNDY4NWMsIDB4YTVhNTUxZjQsIDB4ZTVlNWQxMzQsIDB4ZjFmMWY5MDgsDQoweDcxNzFlMjkzLCAweGQ4ZDhhYjczLCAweDMxMzE2MjUzLCAweDE1MTUyYTNmLA0KMHgwNDA0MDgwYywgMHhjN2M3OTU1MiwgMHgyMzIzNDY2NSwgMHhjM2MzOWQ1ZSwNCjB4MTgxODMwMjgsIDB4OTY5NjM3YTEsIDB4MDUwNTBhMGYsIDB4OWE5YTJmYjUsDQoweDA3MDcwZTA5LCAweDEyMTIyNDM2LCAweDgwODAxYjliLCAweGUyZTJkZjNkLA0KMHhlYmViY2QyNiwgMHgyNzI3NGU2OSwgMHhiMmIyN2ZjZCwgMHg3NTc1ZWE5ZiwNCjB4MDkwOTEyMWIsIDB4ODM4MzFkOWUsIDB4MmMyYzU4NzQsIDB4MWExYTM0MmUsDQoweDFiMWIzNjJkLCAweDZlNmVkY2IyLCAweDVhNWFiNGVlLCAweGEwYTA1YmZiLA0KMHg1MjUyYTRmNiwgMHgzYjNiNzY0ZCwgMHhkNmQ2Yjc2MSwgMHhiM2IzN2RjZSwNCjB4MjkyOTUyN2IsIDB4ZTNlM2RkM2UsIDB4MmYyZjVlNzEsIDB4ODQ4NDEzOTcsDQoweDUzNTNhNmY1LCAweGQxZDFiOTY4LCAweDAwMDAwMDAwLCAweGVkZWRjMTJjLA0KMHgyMDIwNDA2MCwgMHhmY2ZjZTMxZiwgMHhiMWIxNzljOCwgMHg1YjViYjZlZCwNCjB4NmE2YWQ0YmUsIDB4Y2JjYjhkNDYsIDB4YmViZTY3ZDksIDB4MzkzOTcyNGIsDQoweDRhNGE5NGRlLCAweDRjNGM5OGQ0LCAweDU4NThiMGU4LCAweGNmY2Y4NTRhLA0KMHhkMGQwYmI2YiwgMHhlZmVmYzUyYSwgMHhhYWFhNGZlNSwgMHhmYmZiZWQxNiwNCjB4NDM0Mzg2YzUsIDB4NGQ0ZDlhZDcsIDB4MzMzMzY2NTUsIDB4ODU4NTExOTQsDQoweDQ1NDU4YWNmLCAweGY5ZjllOTEwLCAweDAyMDIwNDA2LCAweDdmN2ZmZTgxLA0KMHg1MDUwYTBmMCwgMHgzYzNjNzg0NCwgMHg5ZjlmMjViYSwgMHhhOGE4NGJlMywNCjB4NTE1MWEyZjMsIDB4YTNhMzVkZmUsIDB4NDA0MDgwYzAsIDB4OGY4ZjA1OGEsDQoweDkyOTIzZmFkLCAweDlkOWQyMWJjLCAweDM4Mzg3MDQ4LCAweGY1ZjVmMTA0LA0KMHhiY2JjNjNkZiwgMHhiNmI2NzdjMSwgMHhkYWRhYWY3NSwgMHgyMTIxNDI2MywNCjB4MTAxMDIwMzAsIDB4ZmZmZmU1MWEsIDB4ZjNmM2ZkMGUsIDB4ZDJkMmJmNmQsDQoweGNkY2Q4MTRjLCAweDBjMGMxODE0LCAweDEzMTMyNjM1LCAweGVjZWNjMzJmLA0KMHg1ZjVmYmVlMSwgMHg5Nzk3MzVhMiwgMHg0NDQ0ODhjYywgMHgxNzE3MmUzOSwNCjB4YzRjNDkzNTcsIDB4YTdhNzU1ZjIsIDB4N2U3ZWZjODIsIDB4M2QzZDdhNDcsDQoweDY0NjRjOGFjLCAweDVkNWRiYWU3LCAweDE5MTkzMjJiLCAweDczNzNlNjk1LA0KMHg2MDYwYzBhMCwgMHg4MTgxMTk5OCwgMHg0ZjRmOWVkMSwgMHhkY2RjYTM3ZiwNCjB4MjIyMjQ0NjYsIDB4MmEyYTU0N2UsIDB4OTA5MDNiYWIsIDB4ODg4ODBiODMsDQoweDQ2NDY4Y2NhLCAweGVlZWVjNzI5LCAweGI4Yjg2YmQzLCAweDE0MTQyODNjLA0KMHhkZWRlYTc3OSwgMHg1ZTVlYmNlMiwgMHgwYjBiMTYxZCwgMHhkYmRiYWQ3NiwNCjB4ZTBlMGRiM2IsIDB4MzIzMjY0NTYsIDB4M2EzYTc0NGUsIDB4MGEwYTE0MWUsDQoweDQ5NDk5MmRiLCAweDA2MDYwYzBhLCAweDI0MjQ0ODZjLCAweDVjNWNiOGU0LA0KMHhjMmMyOWY1ZCwgMHhkM2QzYmQ2ZSwgMHhhY2FjNDNlZiwgMHg2MjYyYzRhNiwNCjB4OTE5MTM5YTgsIDB4OTU5NTMxYTQsIDB4ZTRlNGQzMzcsIDB4Nzk3OWYyOGIsDQoweGU3ZTdkNTMyLCAweGM4Yzg4YjQzLCAweDM3Mzc2ZTU5LCAweDZkNmRkYWI3LA0KMHg4ZDhkMDE4YywgMHhkNWQ1YjE2NCwgMHg0ZTRlOWNkMiwgMHhhOWE5NDllMCwNCjB4NmM2Y2Q4YjQsIDB4NTY1NmFjZmEsIDB4ZjRmNGYzMDcsIDB4ZWFlYWNmMjUsDQoweDY1NjVjYWFmLCAweDdhN2FmNDhlLCAweGFlYWU0N2U5LCAweDA4MDgxMDE4LA0KMHhiYWJhNmZkNSwgMHg3ODc4ZjA4OCwgMHgyNTI1NGE2ZiwgMHgyZTJlNWM3MiwNCjB4MWMxYzM4MjQsIDB4YTZhNjU3ZjEsIDB4YjRiNDczYzcsIDB4YzZjNjk3NTEsDQoweGU4ZThjYjIzLCAweGRkZGRhMTdjLCAweDc0NzRlODljLCAweDFmMWYzZTIxLA0KMHg0YjRiOTZkZCwgMHhiZGJkNjFkYywgMHg4YjhiMGQ4NiwgMHg4YThhMGY4NSwNCjB4NzA3MGUwOTAsIDB4M2UzZTdjNDIsIDB4YjViNTcxYzQsIDB4NjY2NmNjYWEsDQoweDQ4NDg5MGQ4LCAweDAzMDMwNjA1LCAweGY2ZjZmNzAxLCAweDBlMGUxYzEyLA0KMHg2MTYxYzJhMywgMHgzNTM1NmE1ZiwgMHg1NzU3YWVmOSwgMHhiOWI5NjlkMCwNCjB4ODY4NjE3OTEsIDB4YzFjMTk5NTgsIDB4MWQxZDNhMjcsIDB4OWU5ZTI3YjksDQoweGUxZTFkOTM4LCAweGY4ZjhlYjEzLCAweDk4OTgyYmIzLCAweDExMTEyMjMzLA0KMHg2OTY5ZDJiYiwgMHhkOWQ5YTk3MCwgMHg4ZThlMDc4OSwgMHg5NDk0MzNhNywNCjB4OWI5YjJkYjYsIDB4MWUxZTNjMjIsIDB4ODc4NzE1OTIsIDB4ZTllOWM5MjAsDQoweGNlY2U4NzQ5LCAweDU1NTVhYWZmLCAweDI4Mjg1MDc4LCAweGRmZGZhNTdhLA0KMHg4YzhjMDM4ZiwgMHhhMWExNTlmOCwgMHg4OTg5MDk4MCwgMHgwZDBkMWExNywNCjB4YmZiZjY1ZGEsIDB4ZTZlNmQ3MzEsIDB4NDI0Mjg0YzYsIDB4Njg2OGQwYjgsDQoweDQxNDE4MmMzLCAweDk5OTkyOWIwLCAweDJkMmQ1YTc3LCAweDBmMGYxZTExLA0KMHhiMGIwN2JjYiwgMHg1NDU0YThmYywgMHhiYmJiNmRkNiwgMHgxNjE2MmMzYSBdOw0KDQp2YXIgVDMgPSBbDQoweDYzYzZhNTYzLCAweDdjZjg4NDdjLCAweDc3ZWU5OTc3LCAweDdiZjY4ZDdiLA0KMHhmMmZmMGRmMiwgMHg2YmQ2YmQ2YiwgMHg2ZmRlYjE2ZiwgMHhjNTkxNTRjNSwNCjB4MzA2MDUwMzAsIDB4MDEwMjAzMDEsIDB4NjdjZWE5NjcsIDB4MmI1NjdkMmIsDQoweGZlZTcxOWZlLCAweGQ3YjU2MmQ3LCAweGFiNGRlNmFiLCAweDc2ZWM5YTc2LA0KMHhjYThmNDVjYSwgMHg4MjFmOWQ4MiwgMHhjOTg5NDBjOSwgMHg3ZGZhODc3ZCwNCjB4ZmFlZjE1ZmEsIDB4NTliMmViNTksIDB4NDc4ZWM5NDcsIDB4ZjBmYjBiZjAsDQoweGFkNDFlY2FkLCAweGQ0YjM2N2Q0LCAweGEyNWZmZGEyLCAweGFmNDVlYWFmLA0KMHg5YzIzYmY5YywgMHhhNDUzZjdhNCwgMHg3MmU0OTY3MiwgMHhjMDliNWJjMCwNCjB4Yjc3NWMyYjcsIDB4ZmRlMTFjZmQsIDB4OTMzZGFlOTMsIDB4MjY0YzZhMjYsDQoweDM2NmM1YTM2LCAweDNmN2U0MTNmLCAweGY3ZjUwMmY3LCAweGNjODM0ZmNjLA0KMHgzNDY4NWMzNCwgMHhhNTUxZjRhNSwgMHhlNWQxMzRlNSwgMHhmMWY5MDhmMSwNCjB4NzFlMjkzNzEsIDB4ZDhhYjczZDgsIDB4MzE2MjUzMzEsIDB4MTUyYTNmMTUsDQoweDA0MDgwYzA0LCAweGM3OTU1MmM3LCAweDIzNDY2NTIzLCAweGMzOWQ1ZWMzLA0KMHgxODMwMjgxOCwgMHg5NjM3YTE5NiwgMHgwNTBhMGYwNSwgMHg5YTJmYjU5YSwNCjB4MDcwZTA5MDcsIDB4MTIyNDM2MTIsIDB4ODAxYjliODAsIDB4ZTJkZjNkZTIsDQoweGViY2QyNmViLCAweDI3NGU2OTI3LCAweGIyN2ZjZGIyLCAweDc1ZWE5Zjc1LA0KMHgwOTEyMWIwOSwgMHg4MzFkOWU4MywgMHgyYzU4NzQyYywgMHgxYTM0MmUxYSwNCjB4MWIzNjJkMWIsIDB4NmVkY2IyNmUsIDB4NWFiNGVlNWEsIDB4YTA1YmZiYTAsDQoweDUyYTRmNjUyLCAweDNiNzY0ZDNiLCAweGQ2Yjc2MWQ2LCAweGIzN2RjZWIzLA0KMHgyOTUyN2IyOSwgMHhlM2RkM2VlMywgMHgyZjVlNzEyZiwgMHg4NDEzOTc4NCwNCjB4NTNhNmY1NTMsIDB4ZDFiOTY4ZDEsIDB4MDAwMDAwMDAsIDB4ZWRjMTJjZWQsDQoweDIwNDA2MDIwLCAweGZjZTMxZmZjLCAweGIxNzljOGIxLCAweDViYjZlZDViLA0KMHg2YWQ0YmU2YSwgMHhjYjhkNDZjYiwgMHhiZTY3ZDliZSwgMHgzOTcyNGIzOSwNCjB4NGE5NGRlNGEsIDB4NGM5OGQ0NGMsIDB4NThiMGU4NTgsIDB4Y2Y4NTRhY2YsDQoweGQwYmI2YmQwLCAweGVmYzUyYWVmLCAweGFhNGZlNWFhLCAweGZiZWQxNmZiLA0KMHg0Mzg2YzU0MywgMHg0ZDlhZDc0ZCwgMHgzMzY2NTUzMywgMHg4NTExOTQ4NSwNCjB4NDU4YWNmNDUsIDB4ZjllOTEwZjksIDB4MDIwNDA2MDIsIDB4N2ZmZTgxN2YsDQoweDUwYTBmMDUwLCAweDNjNzg0NDNjLCAweDlmMjViYTlmLCAweGE4NGJlM2E4LA0KMHg1MWEyZjM1MSwgMHhhMzVkZmVhMywgMHg0MDgwYzA0MCwgMHg4ZjA1OGE4ZiwNCjB4OTIzZmFkOTIsIDB4OWQyMWJjOWQsIDB4Mzg3MDQ4MzgsIDB4ZjVmMTA0ZjUsDQoweGJjNjNkZmJjLCAweGI2NzdjMWI2LCAweGRhYWY3NWRhLCAweDIxNDI2MzIxLA0KMHgxMDIwMzAxMCwgMHhmZmU1MWFmZiwgMHhmM2ZkMGVmMywgMHhkMmJmNmRkMiwNCjB4Y2Q4MTRjY2QsIDB4MGMxODE0MGMsIDB4MTMyNjM1MTMsIDB4ZWNjMzJmZWMsDQoweDVmYmVlMTVmLCAweDk3MzVhMjk3LCAweDQ0ODhjYzQ0LCAweDE3MmUzOTE3LA0KMHhjNDkzNTdjNCwgMHhhNzU1ZjJhNywgMHg3ZWZjODI3ZSwgMHgzZDdhNDczZCwNCjB4NjRjOGFjNjQsIDB4NWRiYWU3NWQsIDB4MTkzMjJiMTksIDB4NzNlNjk1NzMsDQoweDYwYzBhMDYwLCAweDgxMTk5ODgxLCAweDRmOWVkMTRmLCAweGRjYTM3ZmRjLA0KMHgyMjQ0NjYyMiwgMHgyYTU0N2UyYSwgMHg5MDNiYWI5MCwgMHg4ODBiODM4OCwNCjB4NDY4Y2NhNDYsIDB4ZWVjNzI5ZWUsIDB4Yjg2YmQzYjgsIDB4MTQyODNjMTQsDQoweGRlYTc3OWRlLCAweDVlYmNlMjVlLCAweDBiMTYxZDBiLCAweGRiYWQ3NmRiLA0KMHhlMGRiM2JlMCwgMHgzMjY0NTYzMiwgMHgzYTc0NGUzYSwgMHgwYTE0MWUwYSwNCjB4NDk5MmRiNDksIDB4MDYwYzBhMDYsIDB4MjQ0ODZjMjQsIDB4NWNiOGU0NWMsDQoweGMyOWY1ZGMyLCAweGQzYmQ2ZWQzLCAweGFjNDNlZmFjLCAweDYyYzRhNjYyLA0KMHg5MTM5YTg5MSwgMHg5NTMxYTQ5NSwgMHhlNGQzMzdlNCwgMHg3OWYyOGI3OSwNCjB4ZTdkNTMyZTcsIDB4Yzg4YjQzYzgsIDB4Mzc2ZTU5MzcsIDB4NmRkYWI3NmQsDQoweDhkMDE4YzhkLCAweGQ1YjE2NGQ1LCAweDRlOWNkMjRlLCAweGE5NDllMGE5LA0KMHg2Y2Q4YjQ2YywgMHg1NmFjZmE1NiwgMHhmNGYzMDdmNCwgMHhlYWNmMjVlYSwNCjB4NjVjYWFmNjUsIDB4N2FmNDhlN2EsIDB4YWU0N2U5YWUsIDB4MDgxMDE4MDgsDQoweGJhNmZkNWJhLCAweDc4ZjA4ODc4LCAweDI1NGE2ZjI1LCAweDJlNWM3MjJlLA0KMHgxYzM4MjQxYywgMHhhNjU3ZjFhNiwgMHhiNDczYzdiNCwgMHhjNjk3NTFjNiwNCjB4ZThjYjIzZTgsIDB4ZGRhMTdjZGQsIDB4NzRlODljNzQsIDB4MWYzZTIxMWYsDQoweDRiOTZkZDRiLCAweGJkNjFkY2JkLCAweDhiMGQ4NjhiLCAweDhhMGY4NThhLA0KMHg3MGUwOTA3MCwgMHgzZTdjNDIzZSwgMHhiNTcxYzRiNSwgMHg2NmNjYWE2NiwNCjB4NDg5MGQ4NDgsIDB4MDMwNjA1MDMsIDB4ZjZmNzAxZjYsIDB4MGUxYzEyMGUsDQoweDYxYzJhMzYxLCAweDM1NmE1ZjM1LCAweDU3YWVmOTU3LCAweGI5NjlkMGI5LA0KMHg4NjE3OTE4NiwgMHhjMTk5NThjMSwgMHgxZDNhMjcxZCwgMHg5ZTI3Yjk5ZSwNCjB4ZTFkOTM4ZTEsIDB4ZjhlYjEzZjgsIDB4OTgyYmIzOTgsIDB4MTEyMjMzMTEsDQoweDY5ZDJiYjY5LCAweGQ5YTk3MGQ5LCAweDhlMDc4OThlLCAweDk0MzNhNzk0LA0KMHg5YjJkYjY5YiwgMHgxZTNjMjIxZSwgMHg4NzE1OTI4NywgMHhlOWM5MjBlOSwNCjB4Y2U4NzQ5Y2UsIDB4NTVhYWZmNTUsIDB4Mjg1MDc4MjgsIDB4ZGZhNTdhZGYsDQoweDhjMDM4ZjhjLCAweGExNTlmOGExLCAweDg5MDk4MDg5LCAweDBkMWExNzBkLA0KMHhiZjY1ZGFiZiwgMHhlNmQ3MzFlNiwgMHg0Mjg0YzY0MiwgMHg2OGQwYjg2OCwNCjB4NDE4MmMzNDEsIDB4OTkyOWIwOTksIDB4MmQ1YTc3MmQsIDB4MGYxZTExMGYsDQoweGIwN2JjYmIwLCAweDU0YThmYzU0LCAweGJiNmRkNmJiLCAweDE2MmMzYTE2IF07DQoNCnZhciBUNCA9IFsNCjB4YzZhNTYzNjMsIDB4Zjg4NDdjN2MsIDB4ZWU5OTc3NzcsIDB4ZjY4ZDdiN2IsDQoweGZmMGRmMmYyLCAweGQ2YmQ2YjZiLCAweGRlYjE2ZjZmLCAweDkxNTRjNWM1LA0KMHg2MDUwMzAzMCwgMHgwMjAzMDEwMSwgMHhjZWE5Njc2NywgMHg1NjdkMmIyYiwNCjB4ZTcxOWZlZmUsIDB4YjU2MmQ3ZDcsIDB4NGRlNmFiYWIsIDB4ZWM5YTc2NzYsDQoweDhmNDVjYWNhLCAweDFmOWQ4MjgyLCAweDg5NDBjOWM5LCAweGZhODc3ZDdkLA0KMHhlZjE1ZmFmYSwgMHhiMmViNTk1OSwgMHg4ZWM5NDc0NywgMHhmYjBiZjBmMCwNCjB4NDFlY2FkYWQsIDB4YjM2N2Q0ZDQsIDB4NWZmZGEyYTIsIDB4NDVlYWFmYWYsDQoweDIzYmY5YzljLCAweDUzZjdhNGE0LCAweGU0OTY3MjcyLCAweDliNWJjMGMwLA0KMHg3NWMyYjdiNywgMHhlMTFjZmRmZCwgMHgzZGFlOTM5MywgMHg0YzZhMjYyNiwNCjB4NmM1YTM2MzYsIDB4N2U0MTNmM2YsIDB4ZjUwMmY3ZjcsIDB4ODM0ZmNjY2MsDQoweDY4NWMzNDM0LCAweDUxZjRhNWE1LCAweGQxMzRlNWU1LCAweGY5MDhmMWYxLA0KMHhlMjkzNzE3MSwgMHhhYjczZDhkOCwgMHg2MjUzMzEzMSwgMHgyYTNmMTUxNSwNCjB4MDgwYzA0MDQsIDB4OTU1MmM3YzcsIDB4NDY2NTIzMjMsIDB4OWQ1ZWMzYzMsDQoweDMwMjgxODE4LCAweDM3YTE5Njk2LCAweDBhMGYwNTA1LCAweDJmYjU5YTlhLA0KMHgwZTA5MDcwNywgMHgyNDM2MTIxMiwgMHgxYjliODA4MCwgMHhkZjNkZTJlMiwNCjB4Y2QyNmViZWIsIDB4NGU2OTI3MjcsIDB4N2ZjZGIyYjIsIDB4ZWE5Zjc1NzUsDQoweDEyMWIwOTA5LCAweDFkOWU4MzgzLCAweDU4NzQyYzJjLCAweDM0MmUxYTFhLA0KMHgzNjJkMWIxYiwgMHhkY2IyNmU2ZSwgMHhiNGVlNWE1YSwgMHg1YmZiYTBhMCwNCjB4YTRmNjUyNTIsIDB4NzY0ZDNiM2IsIDB4Yjc2MWQ2ZDYsIDB4N2RjZWIzYjMsDQoweDUyN2IyOTI5LCAweGRkM2VlM2UzLCAweDVlNzEyZjJmLCAweDEzOTc4NDg0LA0KMHhhNmY1NTM1MywgMHhiOTY4ZDFkMSwgMHgwMDAwMDAwMCwgMHhjMTJjZWRlZCwNCjB4NDA2MDIwMjAsIDB4ZTMxZmZjZmMsIDB4NzljOGIxYjEsIDB4YjZlZDViNWIsDQoweGQ0YmU2YTZhLCAweDhkNDZjYmNiLCAweDY3ZDliZWJlLCAweDcyNGIzOTM5LA0KMHg5NGRlNGE0YSwgMHg5OGQ0NGM0YywgMHhiMGU4NTg1OCwgMHg4NTRhY2ZjZiwNCjB4YmI2YmQwZDAsIDB4YzUyYWVmZWYsIDB4NGZlNWFhYWEsIDB4ZWQxNmZiZmIsDQoweDg2YzU0MzQzLCAweDlhZDc0ZDRkLCAweDY2NTUzMzMzLCAweDExOTQ4NTg1LA0KMHg4YWNmNDU0NSwgMHhlOTEwZjlmOSwgMHgwNDA2MDIwMiwgMHhmZTgxN2Y3ZiwNCjB4YTBmMDUwNTAsIDB4Nzg0NDNjM2MsIDB4MjViYTlmOWYsIDB4NGJlM2E4YTgsDQoweGEyZjM1MTUxLCAweDVkZmVhM2EzLCAweDgwYzA0MDQwLCAweDA1OGE4ZjhmLA0KMHgzZmFkOTI5MiwgMHgyMWJjOWQ5ZCwgMHg3MDQ4MzgzOCwgMHhmMTA0ZjVmNSwNCjB4NjNkZmJjYmMsIDB4NzdjMWI2YjYsIDB4YWY3NWRhZGEsIDB4NDI2MzIxMjEsDQoweDIwMzAxMDEwLCAweGU1MWFmZmZmLCAweGZkMGVmM2YzLCAweGJmNmRkMmQyLA0KMHg4MTRjY2RjZCwgMHgxODE0MGMwYywgMHgyNjM1MTMxMywgMHhjMzJmZWNlYywNCjB4YmVlMTVmNWYsIDB4MzVhMjk3OTcsIDB4ODhjYzQ0NDQsIDB4MmUzOTE3MTcsDQoweDkzNTdjNGM0LCAweDU1ZjJhN2E3LCAweGZjODI3ZTdlLCAweDdhNDczZDNkLA0KMHhjOGFjNjQ2NCwgMHhiYWU3NWQ1ZCwgMHgzMjJiMTkxOSwgMHhlNjk1NzM3MywNCjB4YzBhMDYwNjAsIDB4MTk5ODgxODEsIDB4OWVkMTRmNGYsIDB4YTM3ZmRjZGMsDQoweDQ0NjYyMjIyLCAweDU0N2UyYTJhLCAweDNiYWI5MDkwLCAweDBiODM4ODg4LA0KMHg4Y2NhNDY0NiwgMHhjNzI5ZWVlZSwgMHg2YmQzYjhiOCwgMHgyODNjMTQxNCwNCjB4YTc3OWRlZGUsIDB4YmNlMjVlNWUsIDB4MTYxZDBiMGIsIDB4YWQ3NmRiZGIsDQoweGRiM2JlMGUwLCAweDY0NTYzMjMyLCAweDc0NGUzYTNhLCAweDE0MWUwYTBhLA0KMHg5MmRiNDk0OSwgMHgwYzBhMDYwNiwgMHg0ODZjMjQyNCwgMHhiOGU0NWM1YywNCjB4OWY1ZGMyYzIsIDB4YmQ2ZWQzZDMsIDB4NDNlZmFjYWMsIDB4YzRhNjYyNjIsDQoweDM5YTg5MTkxLCAweDMxYTQ5NTk1LCAweGQzMzdlNGU0LCAweGYyOGI3OTc5LA0KMHhkNTMyZTdlNywgMHg4YjQzYzhjOCwgMHg2ZTU5MzczNywgMHhkYWI3NmQ2ZCwNCjB4MDE4YzhkOGQsIDB4YjE2NGQ1ZDUsIDB4OWNkMjRlNGUsIDB4NDllMGE5YTksDQoweGQ4YjQ2YzZjLCAweGFjZmE1NjU2LCAweGYzMDdmNGY0LCAweGNmMjVlYWVhLA0KMHhjYWFmNjU2NSwgMHhmNDhlN2E3YSwgMHg0N2U5YWVhZSwgMHgxMDE4MDgwOCwNCjB4NmZkNWJhYmEsIDB4ZjA4ODc4NzgsIDB4NGE2ZjI1MjUsIDB4NWM3MjJlMmUsDQoweDM4MjQxYzFjLCAweDU3ZjFhNmE2LCAweDczYzdiNGI0LCAweDk3NTFjNmM2LA0KMHhjYjIzZThlOCwgMHhhMTdjZGRkZCwgMHhlODljNzQ3NCwgMHgzZTIxMWYxZiwNCjB4OTZkZDRiNGIsIDB4NjFkY2JkYmQsIDB4MGQ4NjhiOGIsIDB4MGY4NThhOGEsDQoweGUwOTA3MDcwLCAweDdjNDIzZTNlLCAweDcxYzRiNWI1LCAweGNjYWE2NjY2LA0KMHg5MGQ4NDg0OCwgMHgwNjA1MDMwMywgMHhmNzAxZjZmNiwgMHgxYzEyMGUwZSwNCjB4YzJhMzYxNjEsIDB4NmE1ZjM1MzUsIDB4YWVmOTU3NTcsIDB4NjlkMGI5YjksDQoweDE3OTE4Njg2LCAweDk5NThjMWMxLCAweDNhMjcxZDFkLCAweDI3Yjk5ZTllLA0KMHhkOTM4ZTFlMSwgMHhlYjEzZjhmOCwgMHgyYmIzOTg5OCwgMHgyMjMzMTExMSwNCjB4ZDJiYjY5NjksIDB4YTk3MGQ5ZDksIDB4MDc4OThlOGUsIDB4MzNhNzk0OTQsDQoweDJkYjY5YjliLCAweDNjMjIxZTFlLCAweDE1OTI4Nzg3LCAweGM5MjBlOWU5LA0KMHg4NzQ5Y2VjZSwgMHhhYWZmNTU1NSwgMHg1MDc4MjgyOCwgMHhhNTdhZGZkZiwNCjB4MDM4ZjhjOGMsIDB4NTlmOGExYTEsIDB4MDk4MDg5ODksIDB4MWExNzBkMGQsDQoweDY1ZGFiZmJmLCAweGQ3MzFlNmU2LCAweDg0YzY0MjQyLCAweGQwYjg2ODY4LA0KMHg4MmMzNDE0MSwgMHgyOWIwOTk5OSwgMHg1YTc3MmQyZCwgMHgxZTExMGYwZiwNCjB4N2JjYmIwYjAsIDB4YThmYzU0NTQsIDB4NmRkNmJiYmIsIDB4MmMzYTE2MTYgXTsNCg0KZnVuY3Rpb24gQjAoeCkgeyByZXR1cm4gKHgmMjU1KTsgfQ0KZnVuY3Rpb24gQjEoeCkgeyByZXR1cm4gKCh4Pj44KSYyNTUpOyB9DQpmdW5jdGlvbiBCMih4KSB7IHJldHVybiAoKHg+PjE2KSYyNTUpOyB9DQpmdW5jdGlvbiBCMyh4KSB7IHJldHVybiAoKHg+PjI0KSYyNTUpOyB9DQoNCmZ1bmN0aW9uIEYxKHgwLCB4MSwgeDIsIHgzKQ0Kew0KICByZXR1cm4gQjEoVDFbeDAmMjU1XSkgfCAoQjEoVDFbKHgxPj44KSYyNTVdKTw8OCkNCiAgICAgIHwgKEIxKFQxWyh4Mj4+MTYpJjI1NV0pPDwxNikgfCAoQjEoVDFbeDM+Pj4yNF0pPDwyNCk7DQp9DQoNCmZ1bmN0aW9uIHBhY2tCeXRlcyhvY3RldHMpDQp7DQogIHZhciBpLCBqOw0KICB2YXIgbGVuPW9jdGV0cy5sZW5ndGg7DQogIHZhciBiPW5ldyBBcnJheShsZW4vNCk7DQoNCiAgaWYgKCFvY3RldHMgfHwgbGVuICUgNCkgcmV0dXJuOw0KDQogIGZvciAoaT0wLCBqPTA7IGo8bGVuOyBqKz0gNCkNCiAgICAgYltpKytdID0gb2N0ZXRzW2pdIHwgKG9jdGV0c1tqKzFdPDw4KSB8IChvY3RldHNbaisyXTw8MTYpIHwgKG9jdGV0c1tqKzNdPDwyNCk7DQoNCiAgcmV0dXJuIGI7ICANCn0NCg0KZnVuY3Rpb24gdW5wYWNrQnl0ZXMocGFja2VkKQ0Kew0KICB2YXIgajsNCiAgdmFyIGk9MCwgbCA9IHBhY2tlZC5sZW5ndGg7DQogIHZhciByID0gbmV3IEFycmF5KGwqNCk7DQoNCiAgZm9yIChqPTA7IGo8bDsgaisrKQ0KICB7DQogICAgcltpKytdID0gQjAocGFja2VkW2pdKTsNCiAgICByW2krK10gPSBCMShwYWNrZWRbal0pOw0KICAgIHJbaSsrXSA9IEIyKHBhY2tlZFtqXSk7DQogICAgcltpKytdID0gQjMocGFja2VkW2pdKTsNCiAgfQ0KICByZXR1cm4gcjsNCn0NCg0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCnZhciBtYXhrYz04Ow0KdmFyIG1heHJrPTE0Ow0KDQpmdW5jdGlvbiBrZXlFeHBhbnNpb24oa2V5KQ0Kew0KICB2YXIga2MsIGksIGosIHIsIHQ7DQogIHZhciByb3VuZHM7DQogIHZhciBrZXlTY2hlZD1uZXcgQXJyYXkobWF4cmsrMSk7DQogIHZhciBrZXlsZW49a2V5Lmxlbmd0aDsNCiAgdmFyIGs9bmV3IEFycmF5KG1heGtjKTsNCiAgdmFyIHRrPW5ldyBBcnJheShtYXhrYyk7DQogIHZhciByY29ucG9pbnRlcj0wOw0KDQogIGlmKGtleWxlbj09MTYpDQogIHsNCiAgIHJvdW5kcz0xMDsNCiAgIGtjPTQ7DQogIH0NCiAgZWxzZSBpZihrZXlsZW49PTI0KQ0KICB7DQogICByb3VuZHM9MTI7DQogICBrYz02Ow0KICB9DQogIGVsc2UgaWYoa2V5bGVuPT0zMikNCiAgew0KICAgcm91bmRzPTE0Ow0KICAga2M9ODsNCiAgfQ0KICBlbHNlDQogIHsNCgl1dGlsLnByaW50X2Vycm9yKCdhZXMuanM6IEludmFsaWQga2V5LWxlbmd0aCBmb3IgQUVTIGtleTonK2tleWxlbik7DQogICByZXR1cm47DQogIH0NCg0KICBmb3IoaT0wOyBpPG1heHJrKzE7IGkrKykga2V5U2NoZWRbaV09bmV3IEFycmF5KDQpOw0KDQogIGZvcihpPTAsaj0wOyBqPGtleWxlbjsgaisrLGkrPTQpDQogICAga1tqXSA9IGtleS5jaGFyQ29kZUF0KGkpIHwgKGtleS5jaGFyQ29kZUF0KGkrMSk8PDgpDQogICAgICAgICAgICAgICAgICAgICB8IChrZXkuY2hhckNvZGVBdChpKzIpPDwxNikgfCAoa2V5LmNoYXJDb2RlQXQoaSszKTw8MjQpOw0KDQogIGZvcihqPWtjLTE7IGo+PTA7IGotLSkgdGtbal0gPSBrW2pdOw0KDQogIHI9MDsNCiAgdD0wOw0KICBmb3Ioaj0wOyAoajxrYykmJihyPHJvdW5kcysxKTsgKQ0KICB7DQogICAgZm9yKDsgKGo8a2MpJiYodDw0KTsgaisrLHQrKykNCiAgICB7DQogICAgICBrZXlTY2hlZFtyXVt0XT10a1tqXTsNCiAgICB9DQogICAgaWYodD09NCkNCiAgICB7DQogICAgICByKys7DQogICAgICB0PTA7DQogICAgfQ0KICB9DQoNCiAgd2hpbGUocjxyb3VuZHMrMSkNCiAgew0KICAgIHZhciB0ZW1wID0gdGtba2MtMV07DQoNCiAgICB0a1swXSBePSBTW0IxKHRlbXApXSB8IChTW0IyKHRlbXApXTw8OCkgfCAoU1tCMyh0ZW1wKV08PDE2KSB8IChTW0IwKHRlbXApXTw8MjQpOw0KICAgIHRrWzBdIF49IFJjb25bcmNvbnBvaW50ZXIrK107DQoNCiAgICBpZihrYyAhPSA4KQ0KICAgIHsNCiAgICAgIGZvcihqPTE7IGo8a2M7IGorKykgdGtbal0gXj0gdGtbai0xXTsNCiAgICB9DQogICAgZWxzZQ0KICAgIHsNCiAgICAgIGZvcihqPTE7IGo8a2MvMjsgaisrKSB0a1tqXSBePSB0a1tqLTFdOw0KIA0KICAgICAgdGVtcCA9IHRrW2tjLzItMV07DQogICAgICB0a1trYy8yXSBePSBTW0IwKHRlbXApXSB8IChTW0IxKHRlbXApXTw8OCkgfCAoU1tCMih0ZW1wKV08PDE2KSB8IChTW0IzKHRlbXApXTw8MjQpOw0KDQogICAgICBmb3Ioaj1rYy8yKzE7IGo8a2M7IGorKykgdGtbal0gXj0gdGtbai0xXTsNCiAgICB9DQoNCiAgICBmb3Ioaj0wOyAoajxrYykmJihyPHJvdW5kcysxKTsgKQ0KICAgIHsNCiAgICAgIGZvcig7IChqPGtjKSYmKHQ8NCk7IGorKyx0KyspDQogICAgICB7DQogICAgICAgIGtleVNjaGVkW3JdW3RdPXRrW2pdOw0KICAgICAgfQ0KICAgICAgaWYodD09NCkNCiAgICAgIHsNCiAgICAgICAgcisrOw0KICAgICAgICB0PTA7DQogICAgICB9DQogICAgfQ0KICB9DQogIHRoaXMucm91bmRzID0gcm91bmRzOw0KICB0aGlzLnJrID0ga2V5U2NoZWQ7DQogIHJldHVybiB0aGlzOw0KfQ0KDQpmdW5jdGlvbiBBRVNlbmNyeXB0KGJsb2NrLCBjdHgpDQp7DQogIHZhciByOw0KICB2YXIgdDAsdDEsdDIsdDM7DQoNCiAgdmFyIGIgPSBwYWNrQnl0ZXMoYmxvY2spOw0KICB2YXIgcm91bmRzID0gY3R4LnJvdW5kczsNCiAgdmFyIGIwID0gYlswXTsNCiAgdmFyIGIxID0gYlsxXTsNCiAgdmFyIGIyID0gYlsyXTsNCiAgdmFyIGIzID0gYlszXTsNCg0KICBmb3Iocj0wOyByPHJvdW5kcy0xOyByKyspDQogIHsNCiAgICB0MCA9IGIwIF4gY3R4LnJrW3JdWzBdOw0KICAgIHQxID0gYjEgXiBjdHgucmtbcl1bMV07DQogICAgdDIgPSBiMiBeIGN0eC5ya1tyXVsyXTsNCiAgICB0MyA9IGIzIF4gY3R4LnJrW3JdWzNdOw0KDQogICAgYjAgPSBUMVt0MCYyNTVdIF4gVDJbKHQxPj44KSYyNTVdIF4gVDNbKHQyPj4xNikmMjU1XSBeIFQ0W3QzPj4+MjRdOw0KICAgIGIxID0gVDFbdDEmMjU1XSBeIFQyWyh0Mj4+OCkmMjU1XSBeIFQzWyh0Mz4+MTYpJjI1NV0gXiBUNFt0MD4+PjI0XTsNCiAgICBiMiA9IFQxW3QyJjI1NV0gXiBUMlsodDM+PjgpJjI1NV0gXiBUM1sodDA+PjE2KSYyNTVdIF4gVDRbdDE+Pj4yNF07DQogICAgYjMgPSBUMVt0MyYyNTVdIF4gVDJbKHQwPj44KSYyNTVdIF4gVDNbKHQxPj4xNikmMjU1XSBeIFQ0W3QyPj4+MjRdOw0KICB9DQoNCiAgLy8gbGFzdCByb3VuZCBpcyBzcGVjaWFsDQogIHIgPSByb3VuZHMtMTsNCg0KICB0MCA9IGIwIF4gY3R4LnJrW3JdWzBdOw0KICB0MSA9IGIxIF4gY3R4LnJrW3JdWzFdOw0KICB0MiA9IGIyIF4gY3R4LnJrW3JdWzJdOw0KICB0MyA9IGIzIF4gY3R4LnJrW3JdWzNdOw0KDQogIGJbMF0gPSBGMSh0MCwgdDEsIHQyLCB0MykgXiBjdHgucmtbcm91bmRzXVswXTsNCiAgYlsxXSA9IEYxKHQxLCB0MiwgdDMsIHQwKSBeIGN0eC5ya1tyb3VuZHNdWzFdOw0KICBiWzJdID0gRjEodDIsIHQzLCB0MCwgdDEpIF4gY3R4LnJrW3JvdW5kc11bMl07DQogIGJbM10gPSBGMSh0MywgdDAsIHQxLCB0MikgXiBjdHgucmtbcm91bmRzXVszXTsNCg0KICByZXR1cm4gdW5wYWNrQnl0ZXMoYik7DQp9DQovKiBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkggDQogKiANCiAqIE9yaWdpbmFsbHkgd3JpdHRlbiBieSBua2xlaW4gc29mdHdhcmUgKG5rbGVpbi5jb20pDQogKi8NCg0KLyogDQogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIGJhc2VkIG9uIEJydWNlIFNjaG5laWVyJ3MgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uLg0KICoNCiAqDQogKiBUaGUgY29uc3RydWN0b3IgZG9lc24ndCBkbyBtdWNoIG9mIGFueXRoaW5nLiAgSXQncyBqdXN0IGhlcmUNCiAqIHNvIHdlIGNhbiBzdGFydCBkZWZpbmluZyBwcm9wZXJ0aWVzIGFuZCBtZXRob2RzIGFuZCBzdWNoLg0KICovDQpmdW5jdGlvbiBCbG93ZmlzaCgpIHsNCn07DQoNCi8qDQogKiBEZWNsYXJlIHRoZSBibG9jayBzaXplIHNvIHRoYXQgcHJvdG9jb2xzIGtub3cgd2hhdCBzaXplDQogKiBJbml0aWFsaXphdGlvbiBWZWN0b3IgKElWKSB0aGV5IHdpbGwgbmVlZC4NCiAqLw0KQmxvd2Zpc2gucHJvdG90eXBlLkJMT0NLU0laRSA9IDg7DQoNCi8qDQogKiBUaGVzZSBhcmUgdGhlIGRlZmF1bHQgU0JPWEVTLg0KICovDQpCbG93ZmlzaC5wcm90b3R5cGUuU0JPWEVTID0gWw0KICAgIFsNCgkweGQxMzEwYmE2LCAweDk4ZGZiNWFjLCAweDJmZmQ3MmRiLCAweGQwMWFkZmI3LCAweGI4ZTFhZmVkLCAweDZhMjY3ZTk2LA0KCTB4YmE3YzkwNDUsIDB4ZjEyYzdmOTksIDB4MjRhMTk5NDcsIDB4YjM5MTZjZjcsIDB4MDgwMWYyZTIsIDB4ODU4ZWZjMTYsDQoJMHg2MzY5MjBkOCwgMHg3MTU3NGU2OSwgMHhhNDU4ZmVhMywgMHhmNDkzM2Q3ZSwgMHgwZDk1NzQ4ZiwgMHg3MjhlYjY1OCwNCgkweDcxOGJjZDU4LCAweDgyMTU0YWVlLCAweDdiNTRhNDFkLCAweGMyNWE1OWI1LCAweDljMzBkNTM5LCAweDJhZjI2MDEzLA0KCTB4YzVkMWIwMjMsIDB4Mjg2MDg1ZjAsIDB4Y2E0MTc5MTgsIDB4YjhkYjM4ZWYsIDB4OGU3OWRjYjAsIDB4NjAzYTE4MGUsDQoJMHg2YzllMGU4YiwgMHhiMDFlOGEzZSwgMHhkNzE1NzdjMSwgMHhiZDMxNGIyNywgMHg3OGFmMmZkYSwgMHg1NTYwNWM2MCwNCgkweGU2NTUyNWYzLCAweGFhNTVhYjk0LCAweDU3NDg5ODYyLCAweDYzZTgxNDQwLCAweDU1Y2EzOTZhLCAweDJhYWIxMGI2LA0KCTB4YjRjYzVjMzQsIDB4MTE0MWU4Y2UsIDB4YTE1NDg2YWYsIDB4N2M3MmU5OTMsIDB4YjNlZTE0MTEsIDB4NjM2ZmJjMmEsDQoJMHgyYmE5YzU1ZCwgMHg3NDE4MzFmNiwgMHhjZTVjM2UxNiwgMHg5Yjg3OTMxZSwgMHhhZmQ2YmEzMywgMHg2YzI0Y2Y1YywNCgkweDdhMzI1MzgxLCAweDI4OTU4Njc3LCAweDNiOGY0ODk4LCAweDZiNGJiOWFmLCAweGM0YmZlODFiLCAweDY2MjgyMTkzLA0KCTB4NjFkODA5Y2MsIDB4ZmIyMWE5OTEsIDB4NDg3Y2FjNjAsIDB4NWRlYzgwMzIsIDB4ZWY4NDVkNWQsIDB4ZTk4NTc1YjEsDQoJMHhkYzI2MjMwMiwgMHhlYjY1MWI4OCwgMHgyMzg5M2U4MSwgMHhkMzk2YWNjNSwgMHgwZjZkNmZmMywgMHg4M2Y0NDIzOSwNCgkweDJlMGI0NDgyLCAweGE0ODQyMDA0LCAweDY5YzhmMDRhLCAweDllMWY5YjVlLCAweDIxYzY2ODQyLCAweGY2ZTk2YzlhLA0KCTB4NjcwYzljNjEsIDB4YWJkMzg4ZjAsIDB4NmE1MWEwZDIsIDB4ZDg1NDJmNjgsIDB4OTYwZmE3MjgsIDB4YWI1MTMzYTMsDQoJMHg2ZWVmMGI2YywgMHgxMzdhM2JlNCwgMHhiYTNiZjA1MCwgMHg3ZWZiMmE5OCwgMHhhMWYxNjUxZCwgMHgzOWFmMDE3NiwNCgkweDY2Y2E1OTNlLCAweDgyNDMwZTg4LCAweDhjZWU4NjE5LCAweDQ1NmY5ZmI0LCAweDdkODRhNWMzLCAweDNiOGI1ZWJlLA0KCTB4ZTA2Zjc1ZDgsIDB4ODVjMTIwNzMsIDB4NDAxYTQ0OWYsIDB4NTZjMTZhYTYsIDB4NGVkM2FhNjIsIDB4MzYzZjc3MDYsDQoJMHgxYmZlZGY3MiwgMHg0MjliMDIzZCwgMHgzN2QwZDcyNCwgMHhkMDBhMTI0OCwgMHhkYjBmZWFkMywgMHg0OWYxYzA5YiwNCgkweDA3NTM3MmM5LCAweDgwOTkxYjdiLCAweDI1ZDQ3OWQ4LCAweGY2ZThkZWY3LCAweGUzZmU1MDFhLCAweGI2Nzk0YzNiLA0KCTB4OTc2Y2UwYmQsIDB4MDRjMDA2YmEsIDB4YzFhOTRmYjYsIDB4NDA5ZjYwYzQsIDB4NWU1YzllYzIsIDB4MTk2YTI0NjMsDQoJMHg2OGZiNmZhZiwgMHgzZTZjNTNiNSwgMHgxMzM5YjJlYiwgMHgzYjUyZWM2ZiwgMHg2ZGZjNTExZiwgMHg5YjMwOTUyYywNCgkweGNjODE0NTQ0LCAweGFmNWViZDA5LCAweGJlZTNkMDA0LCAweGRlMzM0YWZkLCAweDY2MGYyODA3LCAweDE5MmU0YmIzLA0KCTB4YzBjYmE4NTcsIDB4NDVjODc0MGYsIDB4ZDIwYjVmMzksIDB4YjlkM2ZiZGIsIDB4NTU3OWMwYmQsIDB4MWE2MDMyMGEsDQoJMHhkNmExMDBjNiwgMHg0MDJjNzI3OSwgMHg2NzlmMjVmZSwgMHhmYjFmYTNjYywgMHg4ZWE1ZTlmOCwgMHhkYjMyMjJmOCwNCgkweDNjNzUxNmRmLCAweGZkNjE2YjE1LCAweDJmNTAxZWM4LCAweGFkMDU1MmFiLCAweDMyM2RiNWZhLCAweGZkMjM4NzYwLA0KCTB4NTMzMTdiNDgsIDB4M2UwMGRmODIsIDB4OWU1YzU3YmIsIDB4Y2E2ZjhjYTAsIDB4MWE4NzU2MmUsIDB4ZGYxNzY5ZGIsDQoJMHhkNTQyYThmNiwgMHgyODdlZmZjMywgMHhhYzY3MzJjNiwgMHg4YzRmNTU3MywgMHg2OTViMjdiMCwgMHhiYmNhNThjOCwNCgkweGUxZmZhMzVkLCAweGI4ZjAxMWEwLCAweDEwZmEzZDk4LCAweGZkMjE4M2I4LCAweDRhZmNiNTZjLCAweDJkZDFkMzViLA0KCTB4OWE1M2U0NzksIDB4YjZmODQ1NjUsIDB4ZDI4ZTQ5YmMsIDB4NGJmYjk3OTAsIDB4ZTFkZGYyZGEsIDB4YTRjYjdlMzMsDQoJMHg2MmZiMTM0MSwgMHhjZWU0YzZlOCwgMHhlZjIwY2FkYSwgMHgzNjc3NGMwMSwgMHhkMDdlOWVmZSwgMHgyYmYxMWZiNCwNCgkweDk1ZGJkYTRkLCAweGFlOTA5MTk4LCAweGVhYWQ4ZTcxLCAweDZiOTNkNWEwLCAweGQwOGVkMWQwLCAweGFmYzcyNWUwLA0KCTB4OGUzYzViMmYsIDB4OGU3NTk0YjcsIDB4OGZmNmUyZmIsIDB4ZjIxMjJiNjQsIDB4ODg4OGI4MTIsIDB4OTAwZGYwMWMsDQoJMHg0ZmFkNWVhMCwgMHg2ODhmYzMxYywgMHhkMWNmZjE5MSwgMHhiM2E4YzFhZCwgMHgyZjJmMjIxOCwgMHhiZTBlMTc3NywNCgkweGVhNzUyZGZlLCAweDhiMDIxZmExLCAweGU1YTBjYzBmLCAweGI1NmY3NGU4LCAweDE4YWNmM2Q2LCAweGNlODllMjk5LA0KCTB4YjRhODRmZTAsIDB4ZmQxM2UwYjcsIDB4N2NjNDNiODEsIDB4ZDJhZGE4ZDksIDB4MTY1ZmEyNjYsIDB4ODA5NTc3MDUsDQoJMHg5M2NjNzMxNCwgMHgyMTFhMTQ3NywgMHhlNmFkMjA2NSwgMHg3N2I1ZmE4NiwgMHhjNzU0NDJmNSwgMHhmYjlkMzVjZiwNCgkweGViY2RhZjBjLCAweDdiM2U4OWEwLCAweGQ2NDExYmQzLCAweGFlMWU3ZTQ5LCAweDAwMjUwZTJkLCAweDIwNzFiMzVlLA0KCTB4MjI2ODAwYmIsIDB4NTdiOGUwYWYsIDB4MjQ2NDM2OWIsIDB4ZjAwOWI5MWUsIDB4NTU2MzkxMWQsIDB4NTlkZmE2YWEsDQoJMHg3OGMxNDM4OSwgMHhkOTVhNTM3ZiwgMHgyMDdkNWJhMiwgMHgwMmU1YjljNSwgMHg4MzI2MDM3NiwgMHg2Mjk1Y2ZhOSwNCgkweDExYzgxOTY4LCAweDRlNzM0YTQxLCAweGIzNDcyZGNhLCAweDdiMTRhOTRhLCAweDFiNTEwMDUyLCAweDlhNTMyOTE1LA0KCTB4ZDYwZjU3M2YsIDB4YmM5YmM2ZTQsIDB4MmI2MGE0NzYsIDB4ODFlNjc0MDAsIDB4MDhiYTZmYjUsIDB4NTcxYmU5MWYsDQoJMHhmMjk2ZWM2YiwgMHgyYTBkZDkxNSwgMHhiNjYzNjUyMSwgMHhlN2I5ZjliNiwgMHhmZjM0MDUyZSwgMHhjNTg1NTY2NCwNCgkweDUzYjAyZDVkLCAweGE5OWY4ZmExLCAweDA4YmE0Nzk5LCAweDZlODUwNzZhDQogICAgXSwgWw0KCTB4NGI3YTcwZTksIDB4YjViMzI5NDQsIDB4ZGI3NTA5MmUsIDB4YzQxOTI2MjMsIDB4YWQ2ZWE2YjAsIDB4NDlhN2RmN2QsDQoJMHg5Y2VlNjBiOCwgMHg4ZmVkYjI2NiwgMHhlY2FhOGM3MSwgMHg2OTlhMTdmZiwgMHg1NjY0NTI2YywgMHhjMmIxOWVlMSwNCgkweDE5MzYwMmE1LCAweDc1MDk0YzI5LCAweGEwNTkxMzQwLCAweGU0MTgzYTNlLCAweDNmNTQ5ODlhLCAweDViNDI5ZDY1LA0KCTB4NmI4ZmU0ZDYsIDB4OTlmNzNmZDYsIDB4YTFkMjljMDcsIDB4ZWZlODMwZjUsIDB4NGQyZDM4ZTYsIDB4ZjAyNTVkYzEsDQoJMHg0Y2RkMjA4NiwgMHg4NDcwZWIyNiwgMHg2MzgyZTljNiwgMHgwMjFlY2M1ZSwgMHgwOTY4NmIzZiwgMHgzZWJhZWZjOSwNCgkweDNjOTcxODE0LCAweDZiNmE3MGExLCAweDY4N2YzNTg0LCAweDUyYTBlMjg2LCAweGI3OWM1MzA1LCAweGFhNTAwNzM3LA0KCTB4M2UwNzg0MWMsIDB4N2ZkZWFlNWMsIDB4OGU3ZDQ0ZWMsIDB4NTcxNmYyYjgsIDB4YjAzYWRhMzcsIDB4ZjA1MDBjMGQsDQoJMHhmMDFjMWYwNCwgMHgwMjAwYjNmZiwgMHhhZTBjZjUxYSwgMHgzY2I1NzRiMiwgMHgyNTgzN2E1OCwgMHhkYzA5MjFiZCwNCgkweGQxOTExM2Y5LCAweDdjYTkyZmY2LCAweDk0MzI0NzczLCAweDIyZjU0NzAxLCAweDNhZTVlNTgxLCAweDM3YzJkYWRjLA0KCTB4YzhiNTc2MzQsIDB4OWFmM2RkYTcsIDB4YTk0NDYxNDYsIDB4MGZkMDAzMGUsIDB4ZWNjOGM3M2UsIDB4YTQ3NTFlNDEsDQoJMHhlMjM4Y2Q5OSwgMHgzYmVhMGUyZiwgMHgzMjgwYmJhMSwgMHgxODNlYjMzMSwgMHg0ZTU0OGIzOCwgMHg0ZjZkYjkwOCwNCgkweDZmNDIwZDAzLCAweGY2MGEwNGJmLCAweDJjYjgxMjkwLCAweDI0OTc3Yzc5LCAweDU2NzliMDcyLCAweGJjYWY4OWFmLA0KCTB4ZGU5YTc3MWYsIDB4ZDk5MzA4MTAsIDB4YjM4YmFlMTIsIDB4ZGNjZjNmMmUsIDB4NTUxMjcyMWYsIDB4MmU2YjcxMjQsDQoJMHg1MDFhZGRlNiwgMHg5Zjg0Y2Q4NywgMHg3YTU4NDcxOCwgMHg3NDA4ZGExNywgMHhiYzlmOWFiYywgMHhlOTRiN2Q4YywNCgkweGVjN2FlYzNhLCAweGRiODUxZGZhLCAweDYzMDk0MzY2LCAweGM0NjRjM2QyLCAweGVmMWMxODQ3LCAweDMyMTVkOTA4LA0KCTB4ZGQ0MzNiMzcsIDB4MjRjMmJhMTYsIDB4MTJhMTRkNDMsIDB4MmE2NWM0NTEsIDB4NTA5NDAwMDIsIDB4MTMzYWU0ZGQsDQoJMHg3MWRmZjg5ZSwgMHgxMDMxNGU1NSwgMHg4MWFjNzdkNiwgMHg1ZjExMTk5YiwgMHgwNDM1NTZmMSwgMHhkN2EzYzc2YiwNCgkweDNjMTExODNiLCAweDU5MjRhNTA5LCAweGYyOGZlNmVkLCAweDk3ZjFmYmZhLCAweDllYmFiZjJjLCAweDFlMTUzYzZlLA0KCTB4ODZlMzQ1NzAsIDB4ZWFlOTZmYjEsIDB4ODYwZTVlMGEsIDB4NWEzZTJhYjMsIDB4NzcxZmU3MWMsIDB4NGUzZDA2ZmEsDQoJMHgyOTY1ZGNiOSwgMHg5OWU3MWQwZiwgMHg4MDNlODlkNiwgMHg1MjY2YzgyNSwgMHgyZTRjYzk3OCwgMHg5YzEwYjM2YSwNCgkweGM2MTUwZWJhLCAweDk0ZTJlYTc4LCAweGE1ZmMzYzUzLCAweDFlMGEyZGY0LCAweGYyZjc0ZWE3LCAweDM2MWQyYjNkLA0KCTB4MTkzOTI2MGYsIDB4MTljMjc5NjAsIDB4NTIyM2E3MDgsIDB4ZjcxMzEyYjYsIDB4ZWJhZGZlNmUsIDB4ZWFjMzFmNjYsDQoJMHhlM2JjNDU5NSwgMHhhNjdiYzg4MywgMHhiMTdmMzdkMSwgMHgwMThjZmYyOCwgMHhjMzMyZGRlZiwgMHhiZTZjNWFhNSwNCgkweDY1NTgyMTg1LCAweDY4YWI5ODAyLCAweGVlY2VhNTBmLCAweGRiMmY5NTNiLCAweDJhZWY3ZGFkLCAweDViNmUyZjg0LA0KCTB4MTUyMWI2MjgsIDB4MjkwNzYxNzAsIDB4ZWNkZDQ3NzUsIDB4NjE5ZjE1MTAsIDB4MTNjY2E4MzAsIDB4ZWI2MWJkOTYsDQoJMHgwMzM0ZmUxZSwgMHhhYTAzNjNjZiwgMHhiNTczNWM5MCwgMHg0YzcwYTIzOSwgMHhkNTllOWUwYiwgMHhjYmFhZGUxNCwNCgkweGVlY2M4NmJjLCAweDYwNjIyY2E3LCAweDljYWI1Y2FiLCAweGIyZjM4NDZlLCAweDY0OGIxZWFmLCAweDE5YmRmMGNhLA0KCTB4YTAyMzY5YjksIDB4NjU1YWJiNTAsIDB4NDA2ODVhMzIsIDB4M2MyYWI0YjMsIDB4MzE5ZWU5ZDUsIDB4YzAyMWI4ZjcsDQoJMHg5YjU0MGIxOSwgMHg4NzVmYTA5OSwgMHg5NWY3OTk3ZSwgMHg2MjNkN2RhOCwgMHhmODM3ODg5YSwgMHg5N2UzMmQ3NywNCgkweDExZWQ5MzVmLCAweDE2NjgxMjgxLCAweDBlMzU4ODI5LCAweGM3ZTYxZmQ2LCAweDk2ZGVkZmExLCAweDc4NThiYTk5LA0KCTB4NTdmNTg0YTUsIDB4MWIyMjcyNjMsIDB4OWI4M2MzZmYsIDB4MWFjMjQ2OTYsIDB4Y2RiMzBhZWIsIDB4NTMyZTMwNTQsDQoJMHg4ZmQ5NDhlNCwgMHg2ZGJjMzEyOCwgMHg1OGViZjJlZiwgMHgzNGM2ZmZlYSwgMHhmZTI4ZWQ2MSwgMHhlZTdjM2M3MywNCgkweDVkNGExNGQ5LCAweGU4NjRiN2UzLCAweDQyMTA1ZDE0LCAweDIwM2UxM2UwLCAweDQ1ZWVlMmI2LCAweGEzYWFhYmVhLA0KCTB4ZGI2YzRmMTUsIDB4ZmFjYjRmZDAsIDB4Yzc0MmY0NDIsIDB4ZWY2YWJiYjUsIDB4NjU0ZjNiMWQsIDB4NDFjZDIxMDUsDQoJMHhkODFlNzk5ZSwgMHg4Njg1NGRjNywgMHhlNDRiNDc2YSwgMHgzZDgxNjI1MCwgMHhjZjYyYTFmMiwgMHg1YjhkMjY0NiwNCgkweGZjODg4M2EwLCAweGMxYzdiNmEzLCAweDdmMTUyNGMzLCAweDY5Y2I3NDkyLCAweDQ3ODQ4YTBiLCAweDU2OTJiMjg1LA0KCTB4MDk1YmJmMDAsIDB4YWQxOTQ4OWQsIDB4MTQ2MmIxNzQsIDB4MjM4MjBlMDAsIDB4NTg0MjhkMmEsIDB4MGM1NWY1ZWEsDQoJMHgxZGFkZjQzZSwgMHgyMzNmNzA2MSwgMHgzMzcyZjA5MiwgMHg4ZDkzN2U0MSwgMHhkNjVmZWNmMSwgMHg2YzIyM2JkYiwNCgkweDdjZGUzNzU5LCAweGNiZWU3NDYwLCAweDQwODVmMmE3LCAweGNlNzczMjZlLCAweGE2MDc4MDg0LCAweDE5Zjg1MDllLA0KCTB4ZThlZmQ4NTUsIDB4NjFkOTk3MzUsIDB4YTk2OWE3YWEsIDB4YzUwYzA2YzIsIDB4NWEwNGFiZmMsIDB4ODAwYmNhZGMsDQoJMHg5ZTQ0N2EyZSwgMHhjMzQ1MzQ4NCwgMHhmZGQ1NjcwNSwgMHgwZTFlOWVjOSwgMHhkYjczZGJkMywgMHgxMDU1ODhjZCwNCgkweDY3NWZkYTc5LCAweGUzNjc0MzQwLCAweGM1YzQzNDY1LCAweDcxM2UzOGQ4LCAweDNkMjhmODllLCAweGYxNmRmZjIwLA0KCTB4MTUzZTIxZTcsIDB4OGZiMDNkNGEsIDB4ZTZlMzlmMmIsIDB4ZGI4M2FkZjcNCiAgICBdLCBbDQoJMHhlOTNkNWE2OCwgMHg5NDgxNDBmNywgMHhmNjRjMjYxYywgMHg5NDY5MjkzNCwgMHg0MTE1MjBmNywgMHg3NjAyZDRmNywNCgkweGJjZjQ2YjJlLCAweGQ0YTIwMDY4LCAweGQ0MDgyNDcxLCAweDMzMjBmNDZhLCAweDQzYjdkNGI3LCAweDUwMDA2MWFmLA0KCTB4MWUzOWY2MmUsIDB4OTcyNDQ1NDYsIDB4MTQyMTRmNzQsIDB4YmY4Yjg4NDAsIDB4NGQ5NWZjMWQsIDB4OTZiNTkxYWYsDQoJMHg3MGY0ZGRkMywgMHg2NmEwMmY0NSwgMHhiZmJjMDllYywgMHgwM2JkOTc4NSwgMHg3ZmFjNmRkMCwgMHgzMWNiODUwNCwNCgkweDk2ZWIyN2IzLCAweDU1ZmQzOTQxLCAweGRhMjU0N2U2LCAweGFiY2EwYTlhLCAweDI4NTA3ODI1LCAweDUzMDQyOWY0LA0KCTB4MGEyYzg2ZGEsIDB4ZTliNjZkZmIsIDB4NjhkYzE0NjIsIDB4ZDc0ODY5MDAsIDB4NjgwZWMwYTQsIDB4MjdhMThkZWUsDQoJMHg0ZjNmZmVhMiwgMHhlODg3YWQ4YywgMHhiNThjZTAwNiwgMHg3YWY0ZDZiNiwgMHhhYWNlMWU3YywgMHhkMzM3NWZlYywNCgkweGNlNzhhMzk5LCAweDQwNmIyYTQyLCAweDIwZmU5ZTM1LCAweGQ5ZjM4NWI5LCAweGVlMzlkN2FiLCAweDNiMTI0ZThiLA0KCTB4MWRjOWZhZjcsIDB4NGI2ZDE4NTYsIDB4MjZhMzY2MzEsIDB4ZWFlMzk3YjIsIDB4M2E2ZWZhNzQsIDB4ZGQ1YjQzMzIsDQoJMHg2ODQxZTdmNywgMHhjYTc4MjBmYiwgMHhmYjBhZjU0ZSwgMHhkOGZlYjM5NywgMHg0NTQwNTZhYywgMHhiYTQ4OTUyNywNCgkweDU1NTMzYTNhLCAweDIwODM4ZDg3LCAweGZlNmJhOWI3LCAweGQwOTY5NTRiLCAweDU1YTg2N2JjLCAweGExMTU5YTU4LA0KCTB4Y2NhOTI5NjMsIDB4OTllMWRiMzMsIDB4YTYyYTRhNTYsIDB4M2YzMTI1ZjksIDB4NWVmNDdlMWMsIDB4OTAyOTMxN2MsDQoJMHhmZGY4ZTgwMiwgMHgwNDI3MmY3MCwgMHg4MGJiMTU1YywgMHgwNTI4MmNlMywgMHg5NWMxMTU0OCwgMHhlNGM2NmQyMiwNCgkweDQ4YzExMzNmLCAweGM3MGY4NmRjLCAweDA3ZjljOWVlLCAweDQxMDQxZjBmLCAweDQwNDc3OWE0LCAweDVkODg2ZTE3LA0KCTB4MzI1ZjUxZWIsIDB4ZDU5YmMwZDEsIDB4ZjJiY2MxOGYsIDB4NDExMTM1NjQsIDB4MjU3Yjc4MzQsIDB4NjAyYTljNjAsDQoJMHhkZmY4ZThhMywgMHgxZjYzNmMxYiwgMHgwZTEyYjRjMiwgMHgwMmUxMzI5ZSwgMHhhZjY2NGZkMSwgMHhjYWQxODExNSwNCgkweDZiMjM5NWUwLCAweDMzM2U5MmUxLCAweDNiMjQwYjYyLCAweGVlYmViOTIyLCAweDg1YjJhMjBlLCAweGU2YmEwZDk5LA0KCTB4ZGU3MjBjOGMsIDB4MmRhMmY3MjgsIDB4ZDAxMjc4NDUsIDB4OTViNzk0ZmQsIDB4NjQ3ZDA4NjIsIDB4ZTdjY2Y1ZjAsDQoJMHg1NDQ5YTM2ZiwgMHg4NzdkNDhmYSwgMHhjMzlkZmQyNywgMHhmMzNlOGQxZSwgMHgwYTQ3NjM0MSwgMHg5OTJlZmY3NCwNCgkweDNhNmY2ZWFiLCAweGY0ZjhmZDM3LCAweGE4MTJkYzYwLCAweGExZWJkZGY4LCAweDk5MWJlMTRjLCAweGRiNmU2YjBkLA0KCTB4YzY3YjU1MTAsIDB4NmQ2NzJjMzcsIDB4Mjc2NWQ0M2IsIDB4ZGNkMGU4MDQsIDB4ZjEyOTBkYzcsIDB4Y2MwMGZmYTMsDQoJMHhiNTM5MGY5MiwgMHg2OTBmZWQwYiwgMHg2NjdiOWZmYiwgMHhjZWRiN2Q5YywgMHhhMDkxY2YwYiwgMHhkOTE1NWVhMywNCgkweGJiMTMyZjg4LCAweDUxNWJhZDI0LCAweDdiOTQ3OWJmLCAweDc2M2JkNmViLCAweDM3MzkyZWIzLCAweGNjMTE1OTc5LA0KCTB4ODAyNmUyOTcsIDB4ZjQyZTMxMmQsIDB4Njg0MmFkYTcsIDB4YzY2YTJiM2IsIDB4MTI3NTRjY2MsIDB4NzgyZWYxMWMsDQoJMHg2YTEyNDIzNywgMHhiNzkyNTFlNywgMHgwNmExYmJlNiwgMHg0YmZiNjM1MCwgMHgxYTZiMTAxOCwgMHgxMWNhZWRmYSwNCgkweDNkMjViZGQ4LCAweGUyZTFjM2M5LCAweDQ0NDIxNjU5LCAweDBhMTIxMzg2LCAweGQ5MGNlYzZlLCAweGQ1YWJlYTJhLA0KCTB4NjRhZjY3NGUsIDB4ZGE4NmE4NWYsIDB4YmViZmU5ODgsIDB4NjRlNGMzZmUsIDB4OWRiYzgwNTcsIDB4ZjBmN2MwODYsDQoJMHg2MDc4N2JmOCwgMHg2MDAzNjA0ZCwgMHhkMWZkODM0NiwgMHhmNjM4MWZiMCwgMHg3NzQ1YWUwNCwgMHhkNzM2ZmNjYywNCgkweDgzNDI2YjMzLCAweGYwMWVhYjcxLCAweGIwODA0MTg3LCAweDNjMDA1ZTVmLCAweDc3YTA1N2JlLCAweGJkZThhZTI0LA0KCTB4NTU0NjQyOTksIDB4YmY1ODJlNjEsIDB4NGU1OGY0OGYsIDB4ZjJkZGZkYTIsIDB4ZjQ3NGVmMzgsIDB4ODc4OWJkYzIsDQoJMHg1MzY2ZjljMywgMHhjOGIzOGU3NCwgMHhiNDc1ZjI1NSwgMHg0NmZjZDliOSwgMHg3YWViMjY2MSwgMHg4YjFkZGY4NCwNCgkweDg0NmEwZTc5LCAweDkxNWY5NWUyLCAweDQ2NmU1OThlLCAweDIwYjQ1NzcwLCAweDhjZDU1NTkxLCAweGM5MDJkZTRjLA0KCTB4YjkwYmFjZTEsIDB4YmI4MjA1ZDAsIDB4MTFhODYyNDgsIDB4NzU3NGE5OWUsIDB4Yjc3ZjE5YjYsIDB4ZTBhOWRjMDksDQoJMHg2NjJkMDlhMSwgMHhjNDMyNDYzMywgMHhlODVhMWYwMiwgMHgwOWYwYmU4YywgMHg0YTk5YTAyNSwgMHgxZDZlZmUxMCwNCgkweDFhYjkzZDFkLCAweDBiYTVhNGRmLCAweGExODZmMjBmLCAweDI4NjhmMTY5LCAweGRjYjdkYTgzLCAweDU3MzkwNmZlLA0KCTB4YTFlMmNlOWIsIDB4NGZjZDdmNTIsIDB4NTAxMTVlMDEsIDB4YTcwNjgzZmEsIDB4YTAwMmI1YzQsIDB4MGRlNmQwMjcsDQoJMHg5YWY4OGMyNywgMHg3NzNmODY0MSwgMHhjMzYwNGMwNiwgMHg2MWE4MDZiNSwgMHhmMDE3N2EyOCwgMHhjMGY1ODZlMCwNCgkweDAwNjA1OGFhLCAweDMwZGM3ZDYyLCAweDExZTY5ZWQ3LCAweDIzMzhlYTYzLCAweDUzYzJkZDk0LCAweGMyYzIxNjM0LA0KCTB4YmJjYmVlNTYsIDB4OTBiY2I2ZGUsIDB4ZWJmYzdkYTEsIDB4Y2U1OTFkNzYsIDB4NmYwNWU0MDksIDB4NGI3YzAxODgsDQoJMHgzOTcyMGEzZCwgMHg3YzkyN2MyNCwgMHg4NmUzNzI1ZiwgMHg3MjRkOWRiOSwgMHgxYWMxNWJiNCwgMHhkMzllYjhmYywNCgkweGVkNTQ1NTc4LCAweDA4ZmNhNWI1LCAweGQ4M2Q3Y2QzLCAweDRkYWQwZmM0LCAweDFlNTBlZjVlLCAweGIxNjFlNmY4LA0KCTB4YTI4NTE0ZDksIDB4NmM1MTEzM2MsIDB4NmZkNWM3ZTcsIDB4NTZlMTRlYzQsIDB4MzYyYWJmY2UsIDB4ZGRjNmM4MzcsDQoJMHhkNzlhMzIzNCwgMHg5MjYzODIxMiwgMHg2NzBlZmE4ZSwgMHg0MDYwMDBlMA0KICAgIF0sIFsNCgkweDNhMzljZTM3LCAweGQzZmFmNWNmLCAweGFiYzI3NzM3LCAweDVhYzUyZDFiLCAweDVjYjA2NzllLCAweDRmYTMzNzQyLA0KCTB4ZDM4MjI3NDAsIDB4OTliYzliYmUsIDB4ZDUxMThlOWQsIDB4YmYwZjczMTUsIDB4ZDYyZDFjN2UsIDB4YzcwMGM0N2IsDQoJMHhiNzhjMWI2YiwgMHgyMWExOTA0NSwgMHhiMjZlYjFiZSwgMHg2YTM2NmViNCwgMHg1NzQ4YWIyZiwgMHhiYzk0NmU3OSwNCgkweGM2YTM3NmQyLCAweDY1NDljMmM4LCAweDUzMGZmOGVlLCAweDQ2OGRkZTdkLCAweGQ1NzMwYTFkLCAweDRjZDA0ZGM2LA0KCTB4MjkzOWJiZGIsIDB4YTliYTQ2NTAsIDB4YWM5NTI2ZTgsIDB4YmU1ZWUzMDQsIDB4YTFmYWQ1ZjAsIDB4NmEyZDUxOWEsDQoJMHg2M2VmOGNlMiwgMHg5YTg2ZWUyMiwgMHhjMDg5YzJiOCwgMHg0MzI0MmVmNiwgMHhhNTFlMDNhYSwgMHg5Y2YyZDBhNCwNCgkweDgzYzA2MWJhLCAweDliZTk2YTRkLCAweDhmZTUxNTUwLCAweGJhNjQ1YmQ2LCAweDI4MjZhMmY5LCAweGE3M2EzYWUxLA0KCTB4NGJhOTk1ODYsIDB4ZWY1NTYyZTksIDB4YzcyZmVmZDMsIDB4Zjc1MmY3ZGEsIDB4M2YwNDZmNjksIDB4NzdmYTBhNTksDQoJMHg4MGU0YTkxNSwgMHg4N2IwODYwMSwgMHg5YjA5ZTZhZCwgMHgzYjNlZTU5MywgMHhlOTkwZmQ1YSwgMHg5ZTM0ZDc5NywNCgkweDJjZjBiN2Q5LCAweDAyMmI4YjUxLCAweDk2ZDVhYzNhLCAweDAxN2RhNjdkLCAweGQxY2YzZWQ2LCAweDdjN2QyZDI4LA0KCTB4MWY5ZjI1Y2YsIDB4YWRmMmI4OWIsIDB4NWFkNmI0NzIsIDB4NWE4OGY1NGMsIDB4ZTAyOWFjNzEsIDB4ZTAxOWE1ZTYsDQoJMHg0N2IwYWNmZCwgMHhlZDkzZmE5YiwgMHhlOGQzYzQ4ZCwgMHgyODNiNTdjYywgMHhmOGQ1NjYyOSwgMHg3OTEzMmUyOCwNCgkweDc4NWYwMTkxLCAweGVkNzU2MDU1LCAweGY3OTYwZTQ0LCAweGUzZDM1ZThjLCAweDE1MDU2ZGQ0LCAweDg4ZjQ2ZGJhLA0KCTB4MDNhMTYxMjUsIDB4MDU2NGYwYmQsIDB4YzNlYjllMTUsIDB4M2M5MDU3YTIsIDB4OTcyNzFhZWMsIDB4YTkzYTA3MmEsDQoJMHgxYjNmNmQ5YiwgMHgxZTYzMjFmNSwgMHhmNTljNjZmYiwgMHgyNmRjZjMxOSwgMHg3NTMzZDkyOCwgMHhiMTU1ZmRmNSwNCgkweDAzNTYzNDgyLCAweDhhYmEzY2JiLCAweDI4NTE3NzExLCAweGMyMGFkOWY4LCAweGFiY2M1MTY3LCAweGNjYWQ5MjVmLA0KCTB4NGRlODE3NTEsIDB4MzgzMGRjOGUsIDB4Mzc5ZDU4NjIsIDB4OTMyMGY5OTEsIDB4ZWE3YTkwYzIsIDB4ZmIzZTdiY2UsDQoJMHg1MTIxY2U2NCwgMHg3NzRmYmUzMiwgMHhhOGI2ZTM3ZSwgMHhjMzI5M2Q0NiwgMHg0OGRlNTM2OSwgMHg2NDEzZTY4MCwNCgkweGEyYWUwODEwLCAweGRkNmRiMjI0LCAweDY5ODUyZGZkLCAweDA5MDcyMTY2LCAweGIzOWE0NjBhLCAweDY0NDVjMGRkLA0KCTB4NTg2Y2RlY2YsIDB4MWMyMGM4YWUsIDB4NWJiZWY3ZGQsIDB4MWI1ODhkNDAsIDB4Y2NkMjAxN2YsIDB4NmJiNGUzYmIsDQoJMHhkZGEyNmE3ZSwgMHgzYTU5ZmY0NSwgMHgzZTM1MGE0NCwgMHhiY2I0Y2RkNSwgMHg3MmVhY2VhOCwgMHhmYTY0ODRiYiwNCgkweDhkNjYxMmFlLCAweGJmM2M2ZjQ3LCAweGQyOWJlNDYzLCAweDU0MmY1ZDllLCAweGFlYzI3NzFiLCAweGY2NGU2MzcwLA0KCTB4NzQwZTBkOGQsIDB4ZTc1YjEzNTcsIDB4Zjg3MjE2NzEsIDB4YWY1MzdkNWQsIDB4NDA0MGNiMDgsIDB4NGViNGUyY2MsDQoJMHgzNGQyNDY2YSwgMHgwMTE1YWY4NCwgMHhlMWIwMDQyOCwgMHg5NTk4M2ExZCwgMHgwNmI4OWZiNCwgMHhjZTZlYTA0OCwNCgkweDZmM2YzYjgyLCAweDM1MjBhYjgyLCAweDAxMWExZDRiLCAweDI3NzIyN2Y4LCAweDYxMTU2MGIxLCAweGU3OTMzZmRjLA0KCTB4YmIzYTc5MmIsIDB4MzQ0NTI1YmQsIDB4YTA4ODM5ZTEsIDB4NTFjZTc5NGIsIDB4MmYzMmM5YjcsIDB4YTAxZmJhYzksDQoJMHhlMDFjYzg3ZSwgMHhiY2M3ZDFmNiwgMHhjZjAxMTFjMywgMHhhMWU4YWFjNywgMHgxYTkwODc0OSwgMHhkNDRmYmQ5YSwNCgkweGQwZGFkZWNiLCAweGQ1MGFkYTM4LCAweDAzMzljMzJhLCAweGM2OTEzNjY3LCAweDhkZjkzMTdjLCAweGUwYjEyYjRmLA0KCTB4Zjc5ZTU5YjcsIDB4NDNmNWJiM2EsIDB4ZjJkNTE5ZmYsIDB4MjdkOTQ1OWMsIDB4YmY5NzIyMmMsIDB4MTVlNmZjMmEsDQoJMHgwZjkxZmM3MSwgMHg5Yjk0MTUyNSwgMHhmYWU1OTM2MSwgMHhjZWI2OWNlYiwgMHhjMmE4NjQ1OSwgMHgxMmJhYThkMSwNCgkweGI2YzEwNzVlLCAweGUzMDU2YTBjLCAweDEwZDI1MDY1LCAweGNiMDNhNDQyLCAweGUwZWM2ZTBlLCAweDE2OThkYjNiLA0KCTB4NGM5OGEwYmUsIDB4MzI3OGU5NjQsIDB4OWYxZjk1MzIsIDB4ZTBkMzkyZGYsIDB4ZDNhMDM0MmIsIDB4ODk3MWYyMWUsDQoJMHgxYjBhNzQ0MSwgMHg0YmEzMzQ4YywgMHhjNWJlNzEyMCwgMHhjMzc2MzJkOCwgMHhkZjM1OWY4ZCwgMHg5Yjk5MmYyZSwNCgkweGU2MGI2ZjQ3LCAweDBmZTNmMTFkLCAweGU1NGNkYTU0LCAweDFlZGFkODkxLCAweGNlNjI3OWNmLCAweGNkM2U3ZTZmLA0KCTB4MTYxOGIxNjYsIDB4ZmQyYzFkMDUsIDB4ODQ4ZmQyYzUsIDB4ZjZmYjIyOTksIDB4ZjUyM2YzNTcsIDB4YTYzMjc2MjMsDQoJMHg5M2E4MzUzMSwgMHg1NmNjY2QwMiwgMHhhY2YwODE2MiwgMHg1YTc1ZWJiNSwgMHg2ZTE2MzY5NywgMHg4OGQyNzNjYywNCgkweGRlOTY2MjkyLCAweDgxYjk0OWQwLCAweDRjNTA5MDFiLCAweDcxYzY1NjE0LCAweGU2YzZjN2JkLCAweDMyN2ExNDBhLA0KCTB4NDVlMWQwMDYsIDB4YzNmMjdiOWEsIDB4YzlhYTUzZmQsIDB4NjJhODBmMDAsIDB4YmIyNWJmZTIsIDB4MzViZGQyZjYsDQoJMHg3MTEyNjkwNSwgMHhiMjA0MDIyMiwgMHhiNmNiY2Y3YywgMHhjZDc2OWMyYiwgMHg1MzExM2VjMCwgMHgxNjQwZTNkMywNCgkweDM4YWJiZDYwLCAweDI1NDdhZGYwLCAweGJhMzgyMDljLCAweGY3NDZjZTc2LCAweDc3YWZhMWM1LCAweDIwNzU2MDYwLA0KCTB4ODVjYmZlNGUsIDB4OGFlODhkZDgsIDB4N2FhYWY5YjAsIDB4NGNmOWFhN2UsIDB4MTk0OGMyNWMsIDB4MDJmYjhhOGMsDQoJMHgwMWMzNmFlNCwgMHhkNmViZTFmOSwgMHg5MGQ0Zjg2OSwgMHhhNjVjZGVhMCwgMHgzZjA5MjUyZCwgMHhjMjA4ZTY5ZiwNCgkweGI3NGU2MTMyLCAweGNlNzdlMjViLCAweDU3OGZkZmUzLCAweDNhYzM3MmU2DQogICAgXQ0KXTsNCg0KLy8qDQovLyogVGhpcyBpcyB0aGUgZGVmYXVsdCBQQVJSQVkNCi8vKg0KQmxvd2Zpc2gucHJvdG90eXBlLlBBUlJBWSA9IFsNCiAgICAweDI0M2Y2YTg4LCAweDg1YTMwOGQzLCAweDEzMTk4YTJlLCAweDAzNzA3MzQ0LCAweGE0MDkzODIyLCAweDI5OWYzMWQwLA0KICAgIDB4MDgyZWZhOTgsIDB4ZWM0ZTZjODksIDB4NDUyODIxZTYsIDB4MzhkMDEzNzcsIDB4YmU1NDY2Y2YsIDB4MzRlOTBjNmMsDQogICAgMHhjMGFjMjliNywgMHhjOTdjNTBkZCwgMHgzZjg0ZDViNSwgMHhiNTQ3MDkxNywgMHg5MjE2ZDVkOSwgMHg4OTc5ZmIxYg0KXTsNCg0KLy8qDQovLyogVGhpcyBpcyB0aGUgbnVtYmVyIG9mIHJvdW5kcyB0aGUgY2lwaGVyIHdpbGwgZ28NCi8vKg0KQmxvd2Zpc2gucHJvdG90eXBlLk5OID0gMTY7DQoNCi8vKg0KLy8qIFRoaXMgZnVuY3Rpb24gaXMgbmVlZGVkIHRvIGdldCByaWQgb2YgcHJvYmxlbXMNCi8vKiB3aXRoIHRoZSBoaWdoLWJpdCBnZXR0aW5nIHNldC4gIElmIHdlIGRvbid0IGRvDQovLyogdGhpcywgdGhlbiBzb21ldGltZXMgKCBhYSAmIDB4MDBGRkZGRkZGRiApIGlzIG5vdA0KLy8qIGVxdWFsIHRvICggYmIgJiAweDAwRkZGRkZGRkYgKSBldmVuIHdoZW4gdGhleQ0KLy8qIGFncmVlIGJpdC1mb3ItYml0IGZvciB0aGUgZmlyc3QgMzIgYml0cy4NCi8vKg0KQmxvd2Zpc2gucHJvdG90eXBlLl9jbGVhbiA9IGZ1bmN0aW9uKCB4eCApIHsNCiAgICBpZiAoIHh4IDwgMCApIHsNCgl2YXIgeXkgPSB4eCAmIDB4N0ZGRkZGRkY7DQoJeHggPSB5eSArIDB4ODAwMDAwMDA7DQogICAgfQ0KICAgIHJldHVybiB4eDsNCn07DQoNCi8vKg0KLy8qIFRoaXMgaXMgdGhlIG1peGluZyBmdW5jdGlvbiB0aGF0IHVzZXMgdGhlIHNib3hlcw0KLy8qDQpCbG93ZmlzaC5wcm90b3R5cGUuX0YgPSBmdW5jdGlvbiAoIHh4ICkgew0KICAgIHZhciBhYTsNCiAgICB2YXIgYmI7DQogICAgdmFyIGNjOw0KICAgIHZhciBkZDsNCiAgICB2YXIgeXk7DQoNCiAgICBkZCA9IHh4ICYgMHgwMEZGOw0KICAgIHh4ID4+Pj0gODsNCiAgICBjYyA9IHh4ICYgMHgwMEZGOw0KICAgIHh4ID4+Pj0gODsNCiAgICBiYiA9IHh4ICYgMHgwMEZGOw0KICAgIHh4ID4+Pj0gODsNCiAgICBhYSA9IHh4ICYgMHgwMEZGOw0KDQogICAgeXkgPSB0aGlzLnNib3hlc1sgMCBdWyBhYSBdICsgdGhpcy5zYm94ZXNbIDEgXVsgYmIgXTsNCiAgICB5eSA9IHl5IF4gdGhpcy5zYm94ZXNbIDIgXVsgY2MgXTsNCiAgICB5eSA9IHl5ICsgdGhpcy5zYm94ZXNbIDMgXVsgZGQgXTsNCg0KICAgIHJldHVybiB5eTsNCn07DQoNCi8vKg0KLy8qIFRoaXMgbWV0aG9kIHRha2VzIGFuIGFycmF5IHdpdGggdHdvIHZhbHVlcywgbGVmdCBhbmQgcmlnaHQNCi8vKiBhbmQgZG9lcyBOTiByb3VuZHMgb2YgQmxvd2Zpc2ggb24gdGhlbS4NCi8vKg0KQmxvd2Zpc2gucHJvdG90eXBlLl9lbmNyeXB0X2Jsb2NrID0gZnVuY3Rpb24gKCB2YWxzICkgew0KICAgIHZhciBkYXRhTCA9IHZhbHNbIDAgXTsNCiAgICB2YXIgZGF0YVIgPSB2YWxzWyAxIF07DQoNCiAgICB2YXIgaWk7DQoNCiAgICBmb3IgKCBpaT0wOyBpaSA8IHRoaXMuTk47ICsraWkgKSB7DQoJZGF0YUwgPSBkYXRhTCBeIHRoaXMucGFycmF5WyBpaSBdOw0KCWRhdGFSID0gdGhpcy5fRiggZGF0YUwgKSBeIGRhdGFSOw0KDQoJdmFyIHRtcCA9IGRhdGFMOw0KCWRhdGFMID0gZGF0YVI7DQoJZGF0YVIgPSB0bXA7DQogICAgfQ0KDQogICAgZGF0YUwgPSBkYXRhTCBeIHRoaXMucGFycmF5WyB0aGlzLk5OICsgMCBdOw0KICAgIGRhdGFSID0gZGF0YVIgXiB0aGlzLnBhcnJheVsgdGhpcy5OTiArIDEgXTsNCg0KICAgIHZhbHNbIDAgXSA9IHRoaXMuX2NsZWFuKCBkYXRhUiApOw0KICAgIHZhbHNbIDEgXSA9IHRoaXMuX2NsZWFuKCBkYXRhTCApOw0KfTsNCg0KLy8qDQovLyogVGhpcyBtZXRob2QgdGFrZXMgYSB2ZWN0b3Igb2YgbnVtYmVycyBhbmQgdHVybnMgdGhlbQ0KLy8qIGludG8gbG9uZyB3b3JkcyBzbyB0aGF0IHRoZXkgY2FuIGJlIHByb2Nlc3NlZCBieSB0aGUNCi8vKiByZWFsIGFsZ29yaXRobS4NCi8vKg0KLy8qIE1heWJlIEkgc2hvdWxkIG1ha2UgdGhlIHJlYWwgYWxnb3JpdGhtIGFib3ZlIHRha2UgYSB2ZWN0b3INCi8vKiBpbnN0ZWFkLiAgVGhhdCB3aWxsIGludm9sdmUgbW9yZSBsb29waW5nLCBidXQgaXQgd29uJ3QgcmVxdWlyZQ0KLy8qIHRoZSBGKCkgbWV0aG9kIHRvIGRlY29uc3RydWN0IHRoZSB2ZWN0b3IuDQovLyoNCkJsb3dmaXNoLnByb3RvdHlwZS5lbmNyeXB0X2Jsb2NrID0gZnVuY3Rpb24gKCB2ZWN0b3IgKSB7DQogICAgdmFyIGlpOw0KICAgIHZhciB2YWxzID0gWyAwLCAwIF07DQogICAgdmFyIG9mZiAgPSB0aGlzLkJMT0NLU0laRS8yOw0KICAgIGZvciAoIGlpID0gMDsgaWkgPCB0aGlzLkJMT0NLU0laRS8yOyArK2lpICkgew0KCXZhbHNbMF0gPSAoIHZhbHNbMF0gPDwgOCApIHwgKCB2ZWN0b3JbIGlpICsgMCAgIF0gJiAweDAwRkYgKTsNCgl2YWxzWzFdID0gKCB2YWxzWzFdIDw8IDggKSB8ICggdmVjdG9yWyBpaSArIG9mZiBdICYgMHgwMEZGICk7DQogICAgfQ0KDQogICAgdGhpcy5fZW5jcnlwdF9ibG9jayggdmFscyApOw0KDQogICAgdmFyIHJldCA9IFsgXTsNCiAgICBmb3IgKCBpaSA9IDA7IGlpIDwgdGhpcy5CTE9DS1NJWkUvMjsgKytpaSApIHsNCglyZXRbIGlpICsgMCAgIF0gPSAoIHZhbHNbIDAgXSA+Pj4gKDI0IC0gOCooaWkpKSAmIDB4MDBGRiApOw0KCXJldFsgaWkgKyBvZmYgXSA9ICggdmFsc1sgMSBdID4+PiAoMjQgLSA4KihpaSkpICYgMHgwMEZGICk7DQoJLy8gdmFsc1sgMCBdID0gKCB2YWxzWyAwIF0gPj4+IDggKTsNCgkvLyB2YWxzWyAxIF0gPSAoIHZhbHNbIDEgXSA+Pj4gOCApOw0KICAgIH0NCg0KICAgIHJldHVybiByZXQ7DQp9Ow0KDQovLyoNCi8vKiBUaGlzIG1ldGhvZCB0YWtlcyBhbiBhcnJheSB3aXRoIHR3byB2YWx1ZXMsIGxlZnQgYW5kIHJpZ2h0DQovLyogYW5kIHVuZG9lcyBOTiByb3VuZHMgb2YgQmxvd2Zpc2ggb24gdGhlbS4NCi8vKg0KQmxvd2Zpc2gucHJvdG90eXBlLl9kZWNyeXB0X2Jsb2NrID0gZnVuY3Rpb24gKCB2YWxzICkgew0KICAgIHZhciBkYXRhTCA9IHZhbHNbIDAgXTsNCiAgICB2YXIgZGF0YVIgPSB2YWxzWyAxIF07DQoNCiAgICB2YXIgaWk7DQoNCiAgICBmb3IgKCBpaT10aGlzLk5OKzE7IGlpID4gMTsgLS1paSApIHsNCglkYXRhTCA9IGRhdGFMIF4gdGhpcy5wYXJyYXlbIGlpIF07DQoJZGF0YVIgPSB0aGlzLl9GKCBkYXRhTCApIF4gZGF0YVI7DQoNCgl2YXIgdG1wID0gZGF0YUw7DQoJZGF0YUwgPSBkYXRhUjsNCglkYXRhUiA9IHRtcDsNCiAgICB9DQoNCiAgICBkYXRhTCA9IGRhdGFMIF4gdGhpcy5wYXJyYXlbIDEgXTsNCiAgICBkYXRhUiA9IGRhdGFSIF4gdGhpcy5wYXJyYXlbIDAgXTsNCg0KICAgIHZhbHNbIDAgXSA9IHRoaXMuX2NsZWFuKCBkYXRhUiApOw0KICAgIHZhbHNbIDEgXSA9IHRoaXMuX2NsZWFuKCBkYXRhTCApOw0KfTsNCg0KLy8qDQovLyogVGhpcyBtZXRob2QgdGFrZXMgYSBrZXkgYXJyYXkgYW5kIGluaXRpYWxpemVzIHRoZQ0KLy8qIHNib3hlcyBhbmQgcGFycmF5IGZvciB0aGlzIGVuY3J5cHRpb24uDQovLyoNCkJsb3dmaXNoLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCBrZXkgKSB7DQogICAgdmFyIGlpOw0KICAgIHZhciBqaiA9IDA7DQoNCiAgICB0aGlzLnBhcnJheSA9IFtdOw0KICAgIGZvciAoIGlpPTA7IGlpIDwgdGhpcy5OTiArIDI7ICsraWkgKSB7DQoJdmFyIGRhdGEgPSAweDAwMDAwMDAwOw0KCXZhciBrazsNCglmb3IgKCBraz0wOyBrayA8IDQ7ICsra2sgKSB7DQoJICAgIGRhdGEgPSAoIGRhdGEgPDwgOCApIHwgKCBrZXlbIGpqIF0gJiAweDAwRkYgKTsNCgkgICAgaWYgKCArK2pqID49IGtleS5sZW5ndGggKSB7DQoJCWpqID0gMDsNCgkgICAgfQ0KCX0NCgl0aGlzLnBhcnJheVsgaWkgXSA9IHRoaXMuUEFSUkFZWyBpaSBdIF4gZGF0YTsNCiAgICB9DQoNCiAgICB0aGlzLnNib3hlcyA9IFtdOw0KICAgIGZvciAoIGlpPTA7IGlpIDwgNDsgKytpaSApIHsNCgl0aGlzLnNib3hlc1sgaWkgXSA9IFtdOw0KCWZvciAoIGpqPTA7IGpqIDwgMjU2OyArK2pqICkgew0KCSAgICB0aGlzLnNib3hlc1sgaWkgXVsgamogXSA9IHRoaXMuU0JPWEVTWyBpaSBdWyBqaiBdOw0KCX0NCiAgICB9DQoNCiAgICB2YXIgdmFscyA9IFsgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCBdOw0KDQogICAgZm9yICggaWk9MDsgaWkgPCB0aGlzLk5OKzI7IGlpICs9IDIgKSB7DQoJdGhpcy5fZW5jcnlwdF9ibG9jayggdmFscyApOw0KCXRoaXMucGFycmF5WyBpaSArIDAgXSA9IHZhbHNbIDAgXTsNCgl0aGlzLnBhcnJheVsgaWkgKyAxIF0gPSB2YWxzWyAxIF07DQogICAgfQ0KDQogICAgZm9yICggaWk9MDsgaWkgPCA0OyArK2lpICkgew0KCWZvciAoIGpqPTA7IGpqIDwgMjU2OyBqaiArPSAyICkgew0KCSAgICB0aGlzLl9lbmNyeXB0X2Jsb2NrKCB2YWxzICk7DQoJICAgIHRoaXMuc2JveGVzWyBpaSBdWyBqaiArIDAgXSA9IHZhbHNbIDAgXTsNCgkgICAgdGhpcy5zYm94ZXNbIGlpIF1bIGpqICsgMSBdID0gdmFsc1sgMSBdOw0KCX0NCiAgICB9DQp9Ow0KDQovLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzDQpmdW5jdGlvbiBCRmVuY3J5cHQoYmxvY2ssa2V5KSB7DQoJdmFyIGJmID0gbmV3IEJsb3dmaXNoKCk7DQoJYmYuaW5pdCh1dGlsLnN0cjJiaW4oa2V5KSk7DQoJcmV0dXJuIGJmLmVuY3J5cHRfYmxvY2soYmxvY2spOw0KfQ0KDQovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZQ0KLy8gbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KDQovLyBDb3B5cmlnaHQgMjAxMCBwamFjb2JzQHhlZWtyLmNvbSAuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQoNCi8vIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSA0KDQovLyBmaXhlZC9tb2RpZmllZCBieSBIZXJiZXJ0IEhhbmV3aW5rZWwsIHd3dy5oYW5lV0lOLmRlDQovLyBjaGVjayB3d3cuaGFuZVdJTi5kZSBmb3IgdGhlIGxhdGVzdCB2ZXJzaW9uDQoNCi8vIGNhc3Q1LmpzIGlzIGEgSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBDQVNULTEyOCwgYXMgZGVmaW5lZCBpbiBSRkMgMjE0NC4NCi8vIENBU1QtMTI4IGlzIGEgY29tbW9uIE9wZW5QR1AgY2lwaGVyLg0KDQoNCi8vIENBU1Q1IGNvbnN0cnVjdG9yDQoNCmZ1bmN0aW9uIGNhc3Q1X2VuY3J5cHQoYmxvY2ssIGtleSkgew0KCXZhciBjYXN0NSA9IG5ldyBvcGVucGdwX3N5bWVuY19jYXN0NSgpOw0KCWNhc3Q1LnNldEtleSh1dGlsLnN0cjJiaW4oa2V5KSk7DQoJcmV0dXJuIGNhc3Q1LmVuY3J5cHQoYmxvY2spOw0KfQ0KDQpmdW5jdGlvbiBvcGVucGdwX3N5bWVuY19jYXN0NSgpIHsNCgl0aGlzLkJsb2NrU2l6ZT0gODsNCgl0aGlzLktleVNpemUgPSAxNjsNCg0KCXRoaXMuc2V0S2V5ID0gZnVuY3Rpb24gKGtleSkgew0KCQkgdGhpcy5tYXNraW5nID0gbmV3IEFycmF5KDE2KTsNCgkJIHRoaXMucm90YXRlID0gbmV3IEFycmF5KDE2KTsNCg0KCQkgdGhpcy5yZXNldCgpOw0KDQoJCSBpZiAoa2V5Lmxlbmd0aCA9PSB0aGlzLktleVNpemUpDQoJCSB7DQoJCSAgIHRoaXMua2V5U2NoZWR1bGUoa2V5KTsNCgkJIH0NCgkJIGVsc2UNCgkJIHsNCgkJICAgdXRpbC5wcmludF9lcnJvcignY2FzdDUuanM6IENBU1QtMTI4OiBrZXlzIG11c3QgYmUgMTYgYnl0ZXMnKTsNCgkJICAgcmV0dXJuIGZhbHNlOw0KCQkgfQ0KCQkgcmV0dXJuIHRydWU7DQoJfTsNCgkNCgl0aGlzLnJlc2V0ID0gZnVuY3Rpb24oKSB7DQoJCSBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspDQoJCSB7DQoJCSAgdGhpcy5tYXNraW5nW2ldID0gMDsNCgkJICB0aGlzLnJvdGF0ZVtpXSA9IDA7DQoJCSB9DQoJfTsNCg0KCXRoaXMuZ2V0QmxvY2tTaXplID0gZnVuY3Rpb24oKSB7DQoJCSByZXR1cm4gQmxvY2tTaXplOw0KCX07DQoNCgl0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihzcmMpIHsNCgkJIHZhciBkc3QgPSBuZXcgQXJyYXkoc3JjLmxlbmd0aCk7DQoNCgkJIGZvcih2YXIgaSA9IDA7IGkgPCBzcmMubGVuZ3RoOyBpKz04KQ0KCQkgew0KCQkgIHZhciBsID0gc3JjW2ldPDwyNCB8IHNyY1tpKzFdPDwxNiB8IHNyY1tpKzJdPDw4IHwgc3JjW2krM107DQoJCSAgdmFyIHIgPSBzcmNbaSs0XTw8MjQgfCBzcmNbaSs1XTw8MTYgfCBzcmNbaSs2XTw8OCB8IHNyY1tpKzddOw0KCQkgIHZhciB0Ow0KDQoJCSAgdCA9IHI7IHIgPSBsXmYxKHIsIHRoaXMubWFza2luZ1swXSwgdGhpcy5yb3RhdGVbMF0pOyBsID0gdDsNCgkJICB0ID0gcjsgciA9IGxeZjIociwgdGhpcy5tYXNraW5nWzFdLCB0aGlzLnJvdGF0ZVsxXSk7IGwgPSB0Ow0KCQkgIHQgPSByOyByID0gbF5mMyhyLCB0aGlzLm1hc2tpbmdbMl0sIHRoaXMucm90YXRlWzJdKTsgbCA9IHQ7DQoJCSAgdCA9IHI7IHIgPSBsXmYxKHIsIHRoaXMubWFza2luZ1szXSwgdGhpcy5yb3RhdGVbM10pOyBsID0gdDsNCg0KCQkgIHQgPSByOyByID0gbF5mMihyLCB0aGlzLm1hc2tpbmdbNF0sIHRoaXMucm90YXRlWzRdKTsgbCA9IHQ7DQoJCSAgdCA9IHI7IHIgPSBsXmYzKHIsIHRoaXMubWFza2luZ1s1XSwgdGhpcy5yb3RhdGVbNV0pOyBsID0gdDsNCgkJICB0ID0gcjsgciA9IGxeZjEociwgdGhpcy5tYXNraW5nWzZdLCB0aGlzLnJvdGF0ZVs2XSk7IGwgPSB0Ow0KCQkgIHQgPSByOyByID0gbF5mMihyLCB0aGlzLm1hc2tpbmdbN10sIHRoaXMucm90YXRlWzddKTsgbCA9IHQ7DQoNCgkJICB0ID0gcjsgciA9IGxeZjMociwgdGhpcy5tYXNraW5nWzhdLCB0aGlzLnJvdGF0ZVs4XSk7IGwgPSB0Ow0KCQkgIHQgPSByOyByID0gbF5mMShyLCB0aGlzLm1hc2tpbmdbOV0sIHRoaXMucm90YXRlWzldKTsgbCA9IHQ7DQoJCSAgdCA9IHI7IHIgPSBsXmYyKHIsIHRoaXMubWFza2luZ1sxMF0sIHRoaXMucm90YXRlWzEwXSk7IGwgPSB0Ow0KCQkgIHQgPSByOyByID0gbF5mMyhyLCB0aGlzLm1hc2tpbmdbMTFdLCB0aGlzLnJvdGF0ZVsxMV0pOyBsID0gdDsNCg0KCQkgIHQgPSByOyByID0gbF5mMShyLCB0aGlzLm1hc2tpbmdbMTJdLCB0aGlzLnJvdGF0ZVsxMl0pOyBsID0gdDsNCgkJICB0ID0gcjsgciA9IGxeZjIociwgdGhpcy5tYXNraW5nWzEzXSwgdGhpcy5yb3RhdGVbMTNdKTsgbCA9IHQ7DQoJCSAgdCA9IHI7IHIgPSBsXmYzKHIsIHRoaXMubWFza2luZ1sxNF0sIHRoaXMucm90YXRlWzE0XSk7IGwgPSB0Ow0KCQkgIHQgPSByOyByID0gbF5mMShyLCB0aGlzLm1hc2tpbmdbMTVdLCB0aGlzLnJvdGF0ZVsxNV0pOyBsID0gdDsNCg0KCQkgIGRzdFtpXSAgID0gKHIgPj4+IDI0KSYyNTU7DQoJCSAgZHN0W2krMV0gPSAociA+Pj4gMTYpJjI1NTsNCgkJICBkc3RbaSsyXSA9IChyID4+PiA4KSYyNTU7DQoJCSAgZHN0W2krM10gPSByJjI1NTsNCgkJICBkc3RbaSs0XSA9IChsID4+PiAyNCkmMjU1Ow0KCQkgIGRzdFtpKzVdID0gKGwgPj4+IDE2KSYyNTU7DQoJCSAgZHN0W2krNl0gPSAobCA+Pj4gOCkmMjU1Ow0KCQkgIGRzdFtpKzddID0gbCYyNTU7DQoJCSB9DQoNCgkJIHJldHVybiBkc3Q7DQoJfTsNCgkNCgl0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihzcmMpIHsNCgkJIHZhciBkc3QgPSBuZXcgQXJyYXkoc3JjLmxlbmd0aCk7DQoNCgkJIGZvcih2YXIgaSA9IDA7IGkgPCBzcmMubGVuZ3RoOyBpKz04KQ0KCQkgew0KCQkgIHZhciBsID0gc3JjW2ldPDwyNCB8IHNyY1tpKzFdPDwxNiB8IHNyY1tpKzJdPDw4IHwgc3JjW2krM107DQoJCSAgdmFyIHIgPSBzcmNbaSs0XTw8MjQgfCBzcmNbaSs1XTw8MTYgfCBzcmNbaSs2XTw8OCB8IHNyY1tpKzddOw0KCQkgIHZhciB0Ow0KDQoJCSAgdCA9IHI7IHIgPSBsXmYxKHIsIHRoaXMubWFza2luZ1sxNV0sIHRoaXMucm90YXRlWzE1XSk7IGwgPSB0Ow0KCQkgIHQgPSByOyByID0gbF5mMyhyLCB0aGlzLm1hc2tpbmdbMTRdLCB0aGlzLnJvdGF0ZVsxNF0pOyBsID0gdDsNCgkJICB0ID0gcjsgciA9IGxeZjIociwgdGhpcy5tYXNraW5nWzEzXSwgdGhpcy5yb3RhdGVbMTNdKTsgbCA9IHQ7DQoJCSAgdCA9IHI7IHIgPSBsXmYxKHIsIHRoaXMubWFza2luZ1sxMl0sIHRoaXMucm90YXRlWzEyXSk7IGwgPSB0Ow0KDQoJCSAgdCA9IHI7IHIgPSBsXmYzKHIsIHRoaXMubWFza2luZ1sxMV0sIHRoaXMucm90YXRlWzExXSk7IGwgPSB0Ow0KCQkgIHQgPSByOyByID0gbF5mMihyLCB0aGlzLm1hc2tpbmdbMTBdLCB0aGlzLnJvdGF0ZVsxMF0pOyBsID0gdDsNCgkJICB0ID0gcjsgciA9IGxeZjEociwgdGhpcy5tYXNraW5nWzldLCB0aGlzLnJvdGF0ZVs5XSk7IGwgPSB0Ow0KCQkgIHQgPSByOyByID0gbF5mMyhyLCB0aGlzLm1hc2tpbmdbOF0sIHRoaXMucm90YXRlWzhdKTsgbCA9IHQ7DQoNCgkJICB0ID0gcjsgciA9IGxeZjIociwgdGhpcy5tYXNraW5nWzddLCB0aGlzLnJvdGF0ZVs3XSk7IGwgPSB0Ow0KCQkgIHQgPSByOyByID0gbF5mMShyLCB0aGlzLm1hc2tpbmdbNl0sIHRoaXMucm90YXRlWzZdKTsgbCA9IHQ7DQoJCSAgdCA9IHI7IHIgPSBsXmYzKHIsIHRoaXMubWFza2luZ1s1XSwgdGhpcy5yb3RhdGVbNV0pOyBsID0gdDsNCgkJICB0ID0gcjsgciA9IGxeZjIociwgdGhpcy5tYXNraW5nWzRdLCB0aGlzLnJvdGF0ZVs0XSk7IGwgPSB0Ow0KDQoJCSAgdCA9IHI7IHIgPSBsXmYxKHIsIHRoaXMubWFza2luZ1szXSwgdGhpcy5yb3RhdGVbM10pOyBsID0gdDsNCgkJICB0ID0gcjsgciA9IGxeZjMociwgdGhpcy5tYXNraW5nWzJdLCB0aGlzLnJvdGF0ZVsyXSk7IGwgPSB0Ow0KCQkgIHQgPSByOyByID0gbF5mMihyLCB0aGlzLm1hc2tpbmdbMV0sIHRoaXMucm90YXRlWzFdKTsgbCA9IHQ7DQoJCSAgdCA9IHI7IHIgPSBsXmYxKHIsIHRoaXMubWFza2luZ1swXSwgdGhpcy5yb3RhdGVbMF0pOyBsID0gdDsNCg0KCQkgIGRzdFtpXSAgID0gKHIgPj4+IDI0KSYyNTU7DQoJCSAgZHN0W2krMV0gPSAociA+Pj4gMTYpJjI1NTsNCgkJICBkc3RbaSsyXSA9IChyID4+PiA4KSYyNTU7DQoJCSAgZHN0W2krM10gPSByJjI1NTsNCgkJICBkc3RbaSs0XSA9IChsID4+PiAyNCkmMjU1Ow0KCQkgIGRzdFtpKzVdID0gKGwgPj4gMTYpJjI1NTsNCgkJICBkc3RbaSs2XSA9IChsID4+IDgpJjI1NTsNCgkJICBkc3RbaSs3XSA9IGwmMjU1Ow0KCQkgfQ0KDQoJCSByZXR1cm4gZHN0Ow0KCQl9Ow0KCQl2YXIgc2NoZWR1bGVBID0gbmV3IEFycmF5KDQpOw0KDQoJCXNjaGVkdWxlQVswXSA9IG5ldyBBcnJheSg0KTsNCgkJc2NoZWR1bGVBWzBdWzBdID0gbmV3IEFycmF5KDQsIDAsIDB4ZCwgMHhmLCAweGMsIDB4ZSwgMHg4KTsNCgkJc2NoZWR1bGVBWzBdWzFdID0gbmV3IEFycmF5KDUsIDIsIDE2ICsgMCwgMTYgKyAyLCAxNiArIDEsIDE2ICsgMywgMHhhKTsNCgkJc2NoZWR1bGVBWzBdWzJdID0gbmV3IEFycmF5KDYsIDMsIDE2ICsgNywgMTYgKyA2LCAxNiArIDUsIDE2ICsgNCwgOSk7DQoJCXNjaGVkdWxlQVswXVszXSA9IG5ldyBBcnJheSg3LCAxLCAxNiArIDB4YSwgMTYgKyA5LCAxNiArIDB4YiwgMTYgKyA4LCAweGIpOw0KDQoJCXNjaGVkdWxlQVsxXSA9IG5ldyBBcnJheSg0KTsNCgkJc2NoZWR1bGVBWzFdWzBdID0gbmV3IEFycmF5KDAsIDYsIDE2ICsgNSwgMTYgKyA3LCAxNiArIDQsIDE2ICsgNiwgMTYgKyAwKTsNCgkJc2NoZWR1bGVBWzFdWzFdID0gbmV3IEFycmF5KDEsIDQsIDAsIDIsIDEsIDMsIDE2ICsgMik7DQoJCXNjaGVkdWxlQVsxXVsyXSA9IG5ldyBBcnJheSgyLCA1LCA3LCA2LCA1LCA0LCAxNiArIDEpOw0KCQlzY2hlZHVsZUFbMV1bM10gPSBuZXcgQXJyYXkoMywgNywgMHhhLCA5LCAweGIsIDgsIDE2ICsgMyk7DQoNCgkJc2NoZWR1bGVBWzJdID0gbmV3IEFycmF5KDQpOw0KCQlzY2hlZHVsZUFbMl1bMF0gPSBuZXcgQXJyYXkoNCwgMCwgMHhkLCAweGYsIDB4YywgMHhlLCA4KTsNCgkJc2NoZWR1bGVBWzJdWzFdID0gbmV3IEFycmF5KDUsIDIsIDE2ICsgMCwgMTYgKyAyLCAxNiArIDEsIDE2ICsgMywgMHhhKTsNCgkJc2NoZWR1bGVBWzJdWzJdID0gbmV3IEFycmF5KDYsIDMsIDE2ICsgNywgMTYgKyA2LCAxNiArIDUsIDE2ICsgNCwgOSk7DQoJCXNjaGVkdWxlQVsyXVszXSA9IG5ldyBBcnJheSg3LCAxLCAxNiArIDB4YSwgMTYgKyA5LCAxNiArIDB4YiwgMTYgKyA4LCAweGIpOw0KDQoNCgkJc2NoZWR1bGVBWzNdID0gbmV3IEFycmF5KDQpOw0KCQlzY2hlZHVsZUFbM11bMF0gPSBuZXcgQXJyYXkoMCwgNiwgMTYgKyA1LCAxNiArIDcsIDE2ICsgNCwgMTYgKyA2LCAxNiArIDApOw0KCQlzY2hlZHVsZUFbM11bMV0gPSBuZXcgQXJyYXkoMSwgNCwgMCwgMiwgMSwgMywgMTYgKyAyKTsNCgkJc2NoZWR1bGVBWzNdWzJdID0gbmV3IEFycmF5KDIsIDUsIDcsIDYsIDUsIDQsIDE2ICsgMSk7DQoJCXNjaGVkdWxlQVszXVszXSA9IG5ldyBBcnJheSgzLCA3LCAweGEsIDksIDB4YiwgOCwgMTYgKyAzKTsNCg0KCQl2YXIgc2NoZWR1bGVCID0gbmV3IEFycmF5KDQpOw0KDQoJCXNjaGVkdWxlQlswXSA9IG5ldyBBcnJheSg0KTsNCgkJc2NoZWR1bGVCWzBdWzBdID0gbmV3IEFycmF5KDE2ICsgOCwgMTYgKyA5LCAxNiArIDcsIDE2ICsgNiwgMTYgKyAyKTsNCgkJc2NoZWR1bGVCWzBdWzFdID0gbmV3IEFycmF5KDE2ICsgMHhhLCAxNiArIDB4YiwgMTYgKyA1LCAxNiArIDQsIDE2ICsgNik7DQoJCXNjaGVkdWxlQlswXVsyXSA9IG5ldyBBcnJheSgxNiArIDB4YywgMTYgKyAweGQsIDE2ICsgMywgMTYgKyAyLCAxNiArIDkpOw0KCQlzY2hlZHVsZUJbMF1bM10gPSBuZXcgQXJyYXkoMTYgKyAweGUsIDE2ICsgMHhmLCAxNiArIDEsIDE2ICsgMCwgMTYgKyAweGMpOw0KDQoJCXNjaGVkdWxlQlsxXSA9IG5ldyBBcnJheSg0KTsNCgkJc2NoZWR1bGVCWzFdWzBdID0gbmV3IEFycmF5KDMsIDIsIDB4YywgMHhkLCA4KTsNCgkJc2NoZWR1bGVCWzFdWzFdID0gbmV3IEFycmF5KDEsIDAsIDB4ZSwgMHhmLCAweGQpOw0KCQlzY2hlZHVsZUJbMV1bMl0gPSBuZXcgQXJyYXkoNywgNiwgOCwgOSwgMyk7DQoJCXNjaGVkdWxlQlsxXVszXSA9IG5ldyBBcnJheSg1LCA0LCAweGEsIDB4YiwgNyk7DQoNCg0KCQlzY2hlZHVsZUJbMl0gPSBuZXcgQXJyYXkoNCk7DQoJCXNjaGVkdWxlQlsyXVswXSA9IG5ldyBBcnJheSgxNiArIDMsIDE2ICsgMiwgMTYgKyAweGMsIDE2ICsgMHhkLCAxNiArIDkpOw0KCQlzY2hlZHVsZUJbMl1bMV0gPSBuZXcgQXJyYXkoMTYgKyAxLCAxNiArIDAsIDE2ICsgMHhlLCAxNiArIDB4ZiwgMTYgKyAweGMpOw0KCQlzY2hlZHVsZUJbMl1bMl0gPSBuZXcgQXJyYXkoMTYgKyA3LCAxNiArIDYsIDE2ICsgOCwgMTYgKyA5LCAxNiArIDIpOw0KCQlzY2hlZHVsZUJbMl1bM10gPSBuZXcgQXJyYXkoMTYgKyA1LCAxNiArIDQsIDE2ICsgMHhhLCAxNiArIDB4YiwgMTYgKyA2KTsNCg0KDQoJCXNjaGVkdWxlQlszXSA9IG5ldyBBcnJheSg0KTsNCgkJc2NoZWR1bGVCWzNdWzBdID0gbmV3IEFycmF5KDgsIDksIDcsIDYsIDMpOw0KCQlzY2hlZHVsZUJbM11bMV0gPSBuZXcgQXJyYXkoMHhhLCAweGIsIDUsIDQsIDcpOw0KCQlzY2hlZHVsZUJbM11bMl0gPSBuZXcgQXJyYXkoMHhjLCAweGQsIDMsIDIsIDgpOw0KCQlzY2hlZHVsZUJbM11bM10gPSBuZXcgQXJyYXkoMHhlLCAweGYsIDEsIDAsIDB4ZCk7DQoNCgkJLy8gY2hhbmdlZCAnaW4nIHRvICdpbm4nIChpbiBqYXZhc2NyaXB0ICdpbicgaXMgYSByZXNlcnZlZCB3b3JkKQ0KCQl0aGlzLmtleVNjaGVkdWxlID0gZnVuY3Rpb24oaW5uKQ0KCQl7DQoJCSB2YXIgdCA9IG5ldyBBcnJheSg4KTsNCgkJIHZhciBrID0gbmV3IEFycmF5KDMyKTsNCg0KCQkgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspDQoJCSB7DQoJCSAgdmFyIGogPSBpICogNDsNCgkJICB0W2ldID0gaW5uW2pdPDwyNCB8IGlubltqKzFdPDwxNiB8IGlubltqKzJdPDw4IHwgaW5uW2orM107DQoJCSB9DQoNCgkJIHZhciB4ID0gWzYsIDcsIDQsIDVdOw0KCQkgdmFyIGtpID0gMDsNCg0KCQkgZm9yICh2YXIgaGFsZiA9IDA7IGhhbGYgPCAyOyBoYWxmKyspDQoJCSB7DQoJCSAgZm9yICh2YXIgcm91bmQgPSAwOyByb3VuZCA8IDQ7IHJvdW5kKyspDQoJCSAgew0KCQkgICBmb3IgKHZhciBqID0gMDsgaiA8IDQ7IGorKykNCgkJICAgew0KCQkgICAgdmFyIGEgPSBzY2hlZHVsZUFbcm91bmRdW2pdOw0KCQkgICAgdmFyIHcgPSB0W2FbMV1dOw0KDQoJCSAgICB3IF49IHNCb3hbNF1bKHRbYVsyXT4+PjJdPj4+KDI0LTgqKGFbMl0mMykpKSYweGZmXTsNCgkJICAgIHcgXj0gc0JveFs1XVsodFthWzNdPj4+Ml0+Pj4oMjQtOCooYVszXSYzKSkpJjB4ZmZdOw0KCQkgICAgdyBePSBzQm94WzZdWyh0W2FbNF0+Pj4yXT4+PigyNC04KihhWzRdJjMpKSkmMHhmZl07DQoJCSAgICB3IF49IHNCb3hbN11bKHRbYVs1XT4+PjJdPj4+KDI0LTgqKGFbNV0mMykpKSYweGZmXTsNCgkJICAgIHcgXj0gc0JveFt4W2pdXVsodFthWzZdPj4+Ml0+Pj4oMjQtOCooYVs2XSYzKSkpJjB4ZmZdOw0KCQkgICAgdFthWzBdXSA9IHc7DQoJCSAgIH0NCg0KCQkgICBmb3IgKHZhciBqID0gMDsgaiA8IDQ7IGorKykNCgkJICAgew0KCQkgICAgdmFyIGIgPSBzY2hlZHVsZUJbcm91bmRdW2pdOw0KCQkgICAgdmFyIHcgPSBzQm94WzRdWyh0W2JbMF0+Pj4yXT4+PigyNC04KihiWzBdJjMpKSkmMHhmZl07DQoNCgkJICAgIHcgXj0gc0JveFs1XVsodFtiWzFdPj4+Ml0+Pj4oMjQtOCooYlsxXSYzKSkpJjB4ZmZdOw0KCQkgICAgdyBePSBzQm94WzZdWyh0W2JbMl0+Pj4yXT4+PigyNC04KihiWzJdJjMpKSkmMHhmZl07DQoJCSAgICB3IF49IHNCb3hbN11bKHRbYlszXT4+PjJdPj4+KDI0LTgqKGJbM10mMykpKSYweGZmXTsNCgkJICAgIHcgXj0gc0JveFs0K2pdWyh0W2JbNF0+Pj4yXT4+PigyNC04KihiWzRdJjMpKSkmMHhmZl07DQoJCSAgICBrW2tpXSA9IHc7DQoJCSAgICBraSsrOw0KCQkgICB9DQoJCSAgfQ0KCQkgfQ0KDQoJCSBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspDQoJCSB7DQoJCSAgdGhpcy5tYXNraW5nW2ldID0ga1tpXTsNCgkJICB0aGlzLnJvdGF0ZVtpXSAgPSBrWzE2K2ldICYgMHgxZjsNCgkJIH0NCgkJfTsNCg0KCQkvLyBUaGVzZSBhcmUgdGhlIHRocmVlICdmJyBmdW5jdGlvbnMuIFNlZSBSRkMgMjE0NCwgc2VjdGlvbiAyLjIuDQoNCgkJZnVuY3Rpb24gZjEoZCwgbSwgcikNCgkJew0KCQkgdmFyIHQgPSBtICsgZDsNCgkJIHZhciBJID0gKHQgPDwgcikgfCAodCA+Pj4gKDMyIC0gcikpOw0KCQkgcmV0dXJuICgoc0JveFswXVtJPj4+MjRdIF4gc0JveFsxXVsoST4+PjE2KSYyNTVdKSAtIHNCb3hbMl1bKEk+Pj44KSYyNTVdKSArIHNCb3hbM11bSSYyNTVdOw0KCQl9DQoNCgkJZnVuY3Rpb24gZjIoZCwgbSwgcikNCgkJew0KCQkgdmFyIHQgPSBtIF4gZDsNCgkJIHZhciBJID0gKHQgPDwgcikgfCAodCA+Pj4gKDMyIC0gcikpOw0KCQkgcmV0dXJuICgoc0JveFswXVtJPj4+MjRdIC0gc0JveFsxXVsoST4+PjE2KSYyNTVdKSArIHNCb3hbMl1bKEk+Pj44KSYyNTVdKSBeIHNCb3hbM11bSSYyNTVdOw0KCQl9DQoNCgkJZnVuY3Rpb24gZjMoZCwgbSwgcikNCgkJew0KCQkgdmFyIHQgPSBtIC0gZDsNCgkJIHZhciBJID0gKHQgPDwgcikgfCAodCA+Pj4gKDMyIC0gcikpOw0KCQkgcmV0dXJuICgoc0JveFswXVtJPj4+MjRdICsgc0JveFsxXVsoST4+PjE2KSYyNTVdKSBeIHNCb3hbMl1bKEk+Pj44KSYyNTVdKSAtIHNCb3hbM11bSSYyNTVdOw0KCQl9DQoNCgkJdmFyIHNCb3ggPSBuZXcgQXJyYXkoOCk7DQoJCXNCb3hbMF0gPSBuZXcgQXJyYXkoDQoJCSAgMHgzMGZiNDBkNCwgMHg5ZmEwZmYwYiwgMHg2YmVjY2QyZiwgMHgzZjI1OGM3YSwgMHgxZTIxM2YyZiwgMHg5YzAwNGRkMywgMHg2MDAzZTU0MCwgMHhjZjlmYzk0OSwNCgkJICAweGJmZDRhZjI3LCAweDg4YmJiZGI1LCAweGUyMDM0MDkwLCAweDk4ZDA5Njc1LCAweDZlNjNhMGUwLCAweDE1YzM2MWQyLCAweGMyZTc2NjFkLCAweDIyZDRmZjhlLA0KCQkgIDB4Mjg2ODNiNmYsIDB4YzA3ZmQwNTksIDB4ZmYyMzc5YzgsIDB4Nzc1ZjUwZTIsIDB4NDNjMzQwZDMsIDB4ZGYyZjg2NTYsIDB4ODg3Y2E0MWEsIDB4YTJkMmJkMmQsDQoJCSAgMHhhMWM5ZTBkNiwgMHgzNDZjNDgxOSwgMHg2MWI3NmQ4NywgMHgyMjU0MGYyZiwgMHgyYWJlMzJlMSwgMHhhYTU0MTY2YiwgMHgyMjU2OGUzYSwgMHhhMmQzNDFkMCwNCgkJICAweDY2ZGI0MGM4LCAweGE3ODQzOTJmLCAweDAwNGRmZjJmLCAweDJkYjlkMmRlLCAweDk3OTQzZmFjLCAweDRhOTdjMWQ4LCAweDUyNzY0NGI3LCAweGI1ZjQzN2E3LA0KCQkgIDB4YjgyY2JhZWYsIDB4ZDc1MWQxNTksIDB4NmZmN2YwZWQsIDB4NWEwOTdhMWYsIDB4ODI3YjY4ZDAsIDB4OTBlY2Y1MmUsIDB4MjJiMGMwNTQsIDB4YmM4ZTU5MzUsDQoJCSAgMHg0YjZkMmY3ZiwgMHg1MGJiNjRhMiwgMHhkMjY2NDkxMCwgMHhiZWU1ODEyZCwgMHhiNzMzMjI5MCwgMHhlOTNiMTU5ZiwgMHhiNDhlZTQxMSwgMHg0YmZmMzQ1ZCwNCgkJICAweGZkNDVjMjQwLCAweGFkMzE5NzNmLCAweGM0ZjZkMDJlLCAweDU1ZmM4MTY1LCAweGQ1YjFjYWFkLCAweGExYWMyZGFlLCAweGEyZDRiNzZkLCAweGMxOWIwYzUwLA0KCQkgIDB4ODgyMjQwZjIsIDB4MGM2ZTRmMzgsIDB4YTRlNGJmZDcsIDB4NGY1YmEyNzIsIDB4NTY0YzFkMmYsIDB4YzU5YzUzMTksIDB4Yjk0OWUzNTQsIDB4YjA0NjY5ZmUsDQoJCSAgMHhiMWI2YWI4YSwgMHhjNzEzNThkZCwgMHg2Mzg1YzU0NSwgMHgxMTBmOTM1ZCwgMHg1NzUzOGFkNSwgMHg2YTM5MDQ5MywgMHhlNjNkMzdlMCwgMHgyYTU0ZjZiMywNCgkJICAweDNhNzg3ZDVmLCAweDYyNzZhMGI1LCAweDE5YTZmY2RmLCAweDdhNDIyMDZhLCAweDI5ZjlkNGQ1LCAweGY2MWIxODkxLCAweGJiNzIyNzVlLCAweGFhNTA4MTY3LA0KCQkgIDB4Mzg5MDEwOTEsIDB4YzZiNTA1ZWIsIDB4ODRjN2NiOGMsIDB4MmFkNzVhMGYsIDB4ODc0YTE0MjcsIDB4YTJkMTkzNmIsIDB4MmFkMjg2YWYsIDB4YWE1NmQyOTEsDQoJCSAgMHhkNzg5NDM2MCwgMHg0MjVjNzUwZCwgMHg5M2IzOWUyNiwgMHgxODcxODRjOSwgMHg2YzAwYjMyZCwgMHg3M2UyYmIxNCwgMHhhMGJlYmMzYywgMHg1NDYyMzc3OSwNCgkJICAweDY0NDU5ZWFiLCAweDNmMzI4YjgyLCAweDc3MThjZjgyLCAweDU5YTJjZWE2LCAweDA0ZWUwMDJlLCAweDg5ZmU3OGU2LCAweDNmYWIwOTUwLCAweDMyNWZmNmMyLA0KCQkgIDB4ODEzODNmMDUsIDB4Njk2M2M1YzgsIDB4NzZjYjVhZDYsIDB4ZDQ5OTc0YzksIDB4Y2ExODBkY2YsIDB4MzgwNzgyZDUsIDB4YzdmYTVjZjYsIDB4OGFjMzE1MTEsDQoJCSAgMHgzNWU3OWUxMywgMHg0N2RhOTFkMCwgMHhmNDBmOTA4NiwgMHhhN2UyNDE5ZSwgMHgzMTM2NjI0MSwgMHgwNTFlZjQ5NSwgMHhhYTU3M2IwNCwgMHg0YTgwNWQ4ZCwNCgkJICAweDU0ODMwMGQwLCAweDAwMzIyYTNjLCAweGJmNjRjZGRmLCAweGJhNTdhNjhlLCAweDc1YzYzNzJiLCAweDUwYWZkMzQxLCAweGE3YzEzMjc1LCAweDkxNWEwYmY1LA0KCQkgIDB4NmI1NGJmYWIsIDB4MmIwYjE0MjYsIDB4YWI0Y2M5ZDcsIDB4NDQ5Y2NkODIsIDB4ZjdmYmYyNjUsIDB4YWI4NWM1ZjMsIDB4MWI1NWRiOTQsIDB4YWFkNGUzMjQsDQoJCSAgMHhjZmE0YmQzZiwgMHgyZGVhYTNlMiwgMHg5ZTIwNGQwMiwgMHhjOGJkMjVhYywgMHhlYWRmNTViMywgMHhkNWJkOWU5OCwgMHhlMzEyMzFiMiwgMHgyYWQ1YWQ2YywNCgkJICAweDk1NDMyOWRlLCAweGFkYmU0NTI4LCAweGQ4NzEwZjY5LCAweGFhNTFjOTBmLCAweGFhNzg2YmY2LCAweDIyNTEzZjFlLCAweGFhNTFhNzliLCAweDJhZDM0NGNjLA0KCQkgIDB4N2I1YTQxZjAsIDB4ZDM3Y2ZiYWQsIDB4MWIwNjk1MDUsIDB4NDFlY2U0OTEsIDB4YjRjMzMyZTYsIDB4MDMyMjY4ZDQsIDB4Yzk2MDBhY2MsIDB4Y2UzODdlNmQsDQoJCSAgMHhiZjZiYjE2YywgMHg2YTcwZmI3OCwgMHgwZDAzZDljOSwgMHhkNGRmMzlkZSwgMHhlMDEwNjNkYSwgMHg0NzM2ZjQ2NCwgMHg1YWQzMjhkOCwgMHhiMzQ3Y2M5NiwNCgkJICAweDc1YmIwZmMzLCAweDk4NTExYmZiLCAweDRmZmJjYzM1LCAweGI1OGJjZjZhLCAweGUxMWYwYWJjLCAweGJmYzVmZTRhLCAweGE3MGFlYzEwLCAweGFjMzk1NzBhLA0KCQkgIDB4M2YwNDQ0MmYsIDB4NjE4OGIxNTMsIDB4ZTAzOTdhMmUsIDB4NTcyN2NiNzksIDB4OWNlYjQxOGYsIDB4MWNhY2Q2OGQsIDB4MmFkMzdjOTYsIDB4MDE3NWNiOWQsDQoJCSAgMHhjNjlkZmYwOSwgMHhjNzViNjVmMCwgMHhkOWRiNDBkOCwgMHhlYzBlNzc3OSwgMHg0NzQ0ZWFkNCwgMHhiMTFjMzI3NCwgMHhkZDI0Y2I5ZSwgMHg3ZTFjNTRiZCwNCgkJICAweGYwMTE0NGY5LCAweGQyMjQwZWIxLCAweDk2NzViM2ZkLCAweGEzYWMzNzU1LCAweGQ0N2MyN2FmLCAweDUxYzg1ZjRkLCAweDU2OTA3NTk2LCAweGE1YmIxNWU2LA0KCQkgIDB4NTgwMzA0ZjAsIDB4Y2EwNDJjZjEsIDB4MDExYTM3ZWEsIDB4OGRiZmFhZGIsIDB4MzViYTNlNGEsIDB4MzUyNmZmYTAsIDB4YzM3YjRkMDksIDB4YmMzMDZlZDksDQoJCSAgMHg5OGE1MjY2NiwgMHg1NjQ4ZjcyNSwgMHhmZjVlNTY5ZCwgMHgwY2VkNjNkMCwgMHg3YzYzYjJjZiwgMHg3MDBiNDVlMSwgMHhkNWVhNTBmMSwgMHg4NWE5Mjg3MiwNCgkJICAweGFmMWZiZGE3LCAweGQ0MjM0ODcwLCAweGE3ODcwYmYzLCAweDJkM2I0ZDc5LCAweDQyZTA0MTk4LCAweDBjZDBlZGU3LCAweDI2NDcwZGI4LCAweGY4ODE4MTRjLA0KCQkgIDB4NDc0ZDZhZDcsIDB4N2MwYzVlNWMsIDB4ZDEyMzE5NTksIDB4MzgxYjcyOTgsIDB4ZjVkMmY0ZGIsIDB4YWI4Mzg2NTMsIDB4NmUyZjFlMjMsIDB4ODM3MTljOWUsDQoJCSAgMHhiZDkxZTA0NiwgMHg5YTU2NDU2ZSwgMHhkYzM5MjAwYywgMHgyMGM4YzU3MSwgMHg5NjJiZGExYywgMHhlMWU2OTZmZiwgMHhiMTQxYWIwOCwgMHg3Y2NhODliOSwNCgkJICAweDFhNjllNzgzLCAweDAyY2M0ODQzLCAweGEyZjdjNTc5LCAweDQyOWVmNDdkLCAweDQyN2IxNjljLCAweDVhYzlmMDQ5LCAweGRkOGYwZjAwLCAweDVjODE2NWJmKTsNCg0KCQlzQm94WzFdID0gbmV3IEFycmF5KA0KCQkgIDB4MWYyMDEwOTQsIDB4ZWYwYmE3NWIsIDB4NjllM2NmN2UsIDB4MzkzZjQzODAsIDB4ZmU2MWNmN2EsIDB4ZWVjNTIwN2EsIDB4NTU4ODljOTQsIDB4NzJmYzA2NTEsDQoJCSAgMHhhZGE3ZWY3OSwgMHg0ZTFkNzIzNSwgMHhkNTVhNjNjZSwgMHhkZTA0MzZiYSwgMHg5OWM0MzBlZiwgMHg1ZjBjMDc5NCwgMHgxOGRjZGI3ZCwgMHhhMWQ2ZWZmMywNCgkJICAweGEwYjUyZjdiLCAweDU5ZTgzNjA1LCAweGVlMTViMDk0LCAweGU5ZmZkOTA5LCAweGRjNDQwMDg2LCAweGVmOTQ0NDU5LCAweGJhODNjY2IzLCAweGUwYzNjZGZiLA0KCQkgIDB4ZDFkYTQxODEsIDB4M2IwOTJhYjEsIDB4Zjk5N2YxYzEsIDB4YTVlNmNmN2IsIDB4MDE0MjBkZGIsIDB4ZTRlN2VmNWIsIDB4MjVhMWZmNDEsIDB4ZTE4MGY4MDYsDQoJCSAgMHgxZmM0MTA4MCwgMHgxNzliZWU3YSwgMHhkMzdhYzZhOSwgMHhmZTU4MzBhNCwgMHg5OGRlOGI3ZiwgMHg3N2U4M2Y0ZSwgMHg3OTkyOTI2OSwgMHgyNGZhOWY3YiwNCgkJICAweGUxMTNjODViLCAweGFjYzQwMDgzLCAweGQ3NTAzNTI1LCAweGY3ZWE2MTVmLCAweDYyMTQzMTU0LCAweDBkNTU0YjYzLCAweDVkNjgxMTIxLCAweGM4NjZjMzU5LA0KCQkgIDB4M2Q2M2NmNzMsIDB4Y2VlMjM0YzAsIDB4ZDRkODdlODcsIDB4NWM2NzJiMjEsIDB4MDcxZjYxODEsIDB4MzlmNzYyN2YsIDB4MzYxZTMwODQsIDB4ZTRlYjU3M2IsDQoJCSAgMHg2MDJmNjRhNCwgMHhkNjNhY2Q5YywgMHgxYmJjNDYzNSwgMHg5ZTgxMDMyZCwgMHgyNzAxZjUwYywgMHg5OTg0N2FiNCwgMHhhMGUzZGY3OSwgMHhiYTZjZjM4YywNCgkJICAweDEwODQzMDk0LCAweDI1MzdhOTVlLCAweGY0NmY2ZmZlLCAweGExZmYzYjFmLCAweDIwOGNmYjZhLCAweDhmNDU4Yzc0LCAweGQ5ZTBhMjI3LCAweDRlYzczYTM0LA0KCQkgIDB4ZmM4ODRmNjksIDB4M2U0ZGU4ZGYsIDB4ZWYwZTAwODgsIDB4MzU1OTY0OGQsIDB4OGE0NTM4OGMsIDB4MWQ4MDQzNjYsIDB4NzIxZDliZmQsIDB4YTU4Njg0YmIsDQoJCSAgMHhlODI1NjMzMywgMHg4NDRlODIxMiwgMHgxMjhkODA5OCwgMHhmZWQzM2ZiNCwgMHhjZTI4MGFlMSwgMHgyN2UxOWJhNSwgMHhkNWE2YzI1MiwgMHhlNDk3NTRiZCwNCgkJICAweGM1ZDY1NWRkLCAweGViNjY3MDY0LCAweDc3ODQwYjRkLCAweGExYjZhODAxLCAweDg0ZGIyNmE5LCAweGUwYjU2NzE0LCAweDIxZjA0M2I3LCAweGU1ZDA1ODYwLA0KCQkgIDB4NTRmMDMwODQsIDB4MDY2ZmY0NzIsIDB4YTMxYWExNTMsIDB4ZGFkYzQ3NTUsIDB4YjU2MjVkYmYsIDB4Njg1NjFiZTYsIDB4ODNjYTZiOTQsIDB4MmQ2ZWQyM2IsDQoJCSAgMHhlY2NmMDFkYiwgMHhhNmQzZDBiYSwgMHhiNjgwM2Q1YywgMHhhZjc3YTcwOSwgMHgzM2I0YTM0YywgMHgzOTdiYzhkNiwgMHg1ZWUyMmI5NSwgMHg1ZjBlNTMwNCwNCgkJICAweDgxZWQ2ZjYxLCAweDIwZTc0MzY0LCAweGI0NWUxMzc4LCAweGRlMTg2MzliLCAweDg4MWNhMTIyLCAweGI5NjcyNmQxLCAweDgwNDlhN2U4LCAweDIyYjdkYTdiLA0KCQkgIDB4NWU1NTJkMjUsIDB4NTI3MmQyMzcsIDB4NzlkMjk1MWMsIDB4YzYwZDg5NGMsIDB4NDg4Y2I0MDIsIDB4MWJhNGZlNWIsIDB4YTRiMDlmNmIsIDB4MWNhODE1Y2YsDQoJCSAgMHhhMjBjMzAwNSwgMHg4ODcxZGY2MywgMHhiOWRlMmZjYiwgMHgwY2M2YzllOSwgMHgwYmVlZmY1MywgMHhlMzIxNDUxNywgMHhiNDU0MjgzNSwgMHg5ZjYzMjkzYywNCgkJICAweGVlNDFlNzI5LCAweDZlMWQyZDdjLCAweDUwMDQ1Mjg2LCAweDFlNjY4NWYzLCAweGYzMzQwMWM2LCAweDMwYTIyYzk1LCAweDMxYTcwODUwLCAweDYwOTMwZjEzLA0KCQkgIDB4NzNmOTg0MTcsIDB4YTEyNjk4NTksIDB4ZWM2NDVjNDQsIDB4NTJjODc3YTksIDB4Y2RmZjMzYTYsIDB4YTAyYjE3NDEsIDB4N2NiYWQ5YTIsIDB4MjE4MDAzNmYsDQoJCSAgMHg1MGQ5OWMwOCwgMHhjYjNmNDg2MSwgMHhjMjZiZDc2NSwgMHg2NGEzZjZhYiwgMHg4MDM0MjY3NiwgMHgyNWE3NWU3YiwgMHhlNGU2ZDFmYywgMHgyMGM3MTBlNiwNCgkJICAweGNkZjBiNjgwLCAweDE3ODQ0ZDNiLCAweDMxZWVmODRkLCAweDdlMDgyNGU0LCAweDJjY2I0OWViLCAweDg0NmEzYmFlLCAweDhmZjc3ODg4LCAweGVlNWQ2MGY2LA0KCQkgIDB4N2FmNzU2NzMsIDB4MmZkZDVjZGIsIDB4YTExNjMxYzEsIDB4MzBmNjZmNDMsIDB4YjNmYWVjNTQsIDB4MTU3ZmQ3ZmEsIDB4ZWY4NTc5Y2MsIDB4ZDE1MmRlNTgsDQoJCSAgMHhkYjJmZmQ1ZSwgMHg4ZjMyY2UxOSwgMHgzMDZhZjk3YSwgMHgwMmYwM2VmOCwgMHg5OTMxOWFkNSwgMHhjMjQyZmEwZiwgMHhhN2UzZWJiMCwgMHhjNjhlNDkwNiwNCgkJICAweGI4ZGEyMzBjLCAweDgwODIzMDI4LCAweGRjZGVmM2M4LCAweGQzNWZiMTcxLCAweDA4OGExYmM4LCAweGJlYzBjNTYwLCAweDYxYTNjOWU4LCAweGJjYThmNTRkLA0KCQkgIDB4YzcyZmVmZmEsIDB4MjI4MjJlOTksIDB4ODJjNTcwYjQsIDB4ZDhkOTRlODksIDB4OGIxYzM0YmMsIDB4MzAxZTE2ZTYsIDB4MjczYmU5NzksIDB4YjBmZmVhYTYsDQoJCSAgMHg2MWQ5YjhjNiwgMHgwMGIyNDg2OSwgMHhiN2ZmY2UzZiwgMHgwOGRjMjgzYiwgMHg0M2RhZjY1YSwgMHhmN2UxOTc5OCwgMHg3NjE5YjcyZiwgMHg4ZjFjOWJhNCwNCgkJICAweGRjODYzN2EwLCAweDE2YTdkM2IxLCAweDlmYzM5M2I3LCAweGE3MTM2ZWViLCAweGM2YmNjNjNlLCAweDFhNTEzNzQyLCAweGVmNjgyOGJjLCAweDUyMDM2NWQ2LA0KCQkgIDB4MmQ2YTc3YWIsIDB4MzUyN2VkNGIsIDB4ODIxZmQyMTYsIDB4MDk1YzZlMmUsIDB4ZGI5MmYyZmIsIDB4NWVlYTI5Y2IsIDB4MTQ1ODkyZjUsIDB4OTE1ODRmN2YsDQoJCSAgMHg1NDgzNjk3YiwgMHgyNjY3YThjYywgMHg4NTE5NjA0OCwgMHg4YzRiYWNlYSwgMHg4MzM4NjBkNCwgMHgwZDIzZTBmOSwgMHg2YzM4N2U4YSwgMHgwYWU2ZDI0OSwNCgkJICAweGIyODQ2MDBjLCAweGQ4MzU3MzFkLCAweGRjYjFjNjQ3LCAweGFjNGM1NmVhLCAweDNlYmQ4MWIzLCAweDIzMGVhYmIwLCAweDY0MzhiYzg3LCAweGYwYjViMWZhLA0KCQkgIDB4OGY1ZWEyYjMsIDB4ZmMxODQ2NDIsIDB4MGEwMzZiN2EsIDB4NGZiMDg5YmQsIDB4NjQ5ZGE1ODksIDB4YTM0NTQxNWUsIDB4NWMwMzgzMjMsIDB4M2U1ZDNiYjksDQoJCSAgMHg0M2Q3OTU3MiwgMHg3ZTZkZDA3YywgMHgwNmRmZGYxZSwgMHg2YzZjYzRlZiwgMHg3MTYwYTUzOSwgMHg3M2JmYmU3MCwgMHg4Mzg3NzYwNSwgMHg0NTIzZWNmMSk7DQoNCgkJc0JveFsyXSA9IG5ldyBBcnJheSgNCgkJICAweDhkZWZjMjQwLCAweDI1ZmE1ZDlmLCAweGViOTAzZGJmLCAweGU4MTBjOTA3LCAweDQ3NjA3ZmZmLCAweDM2OWZlNDRiLCAweDhjMWZjNjQ0LCAweGFlY2VjYTkwLA0KCQkgIDB4YmViMWY5YmYsIDB4ZWVmYmNhZWEsIDB4ZThjZjE5NTAsIDB4NTFkZjA3YWUsIDB4OTIwZTg4MDYsIDB4ZjBhZDA1NDgsIDB4ZTEzYzhkODMsIDB4OTI3MDEwZDUsDQoJCSAgMHgxMTEwN2Q5ZiwgMHgwNzY0N2RiOSwgMHhiMmUzZTRkNCwgMHgzZDRmMjg1ZSwgMHhiOWFmYTgyMCwgMHhmYWRlODJlMCwgMHhhMDY3MjY4YiwgMHg4MjcyNzkyZSwNCgkJICAweDU1M2ZiMmMwLCAweDQ4OWFlMjJiLCAweGQ0ZWY5Nzk0LCAweDEyNWUzZmJjLCAweDIxZmZmY2VlLCAweDgyNWIxYmZkLCAweDkyNTVjNWVkLCAweDEyNTdhMjQwLA0KCQkgIDB4NGUxYTgzMDIsIDB4YmFlMDdmZmYsIDB4NTI4MjQ2ZTcsIDB4OGU1NzE0MGUsIDB4MzM3M2Y3YmYsIDB4OGM5ZjgxODgsIDB4YTZmYzRlZTgsIDB4Yzk4MmI1YTUsDQoJCSAgMHhhOGMwMWRiNywgMHg1NzlmYzI2NCwgMHg2NzA5NGYzMSwgMHhmMmJkM2Y1ZiwgMHg0MGZmZjdjMSwgMHgxZmI3OGRmYywgMHg4ZTZiZDJjMSwgMHg0MzdiZTU5YiwNCgkJICAweDk5YjAzZGJmLCAweGI1ZGJjNjRiLCAweDYzOGRjMGU2LCAweDU1ODE5ZDk5LCAweGExOTdjODFjLCAweDRhMDEyZDZlLCAweGM1ODg0YTI4LCAweGNjYzM2ZjcxLA0KCQkgIDB4Yjg0M2MyMTMsIDB4NmMwNzQzZjEsIDB4ODMwOTg5M2MsIDB4MGZlZGRkNWYsIDB4MmY3ZmU4NTAsIDB4ZDdjMDdmN2UsIDB4MDI1MDdmYmYsIDB4NWFmYjlhMDQsDQoJCSAgMHhhNzQ3ZDJkMCwgMHgxNjUxMTkyZSwgMHhhZjcwYmYzZSwgMHg1OGMzMTM4MCwgMHg1Zjk4MzAyZSwgMHg3MjdjYzNjNCwgMHgwYTBmYjQwMiwgMHgwZjdmZWY4MiwNCgkJICAweDhjOTZmZGFkLCAweDVkMmMyYWFlLCAweDhlZTk5YTQ5LCAweDUwZGE4OGI4LCAweDg0MjdmNGEwLCAweDFlYWM1NzkwLCAweDc5NmZiNDQ5LCAweDgyNTJkYzE1LA0KCQkgIDB4ZWZiZDdkOWIsIDB4YTY3MjU5N2QsIDB4YWRhODQwZDgsIDB4NDVmNTQ1MDQsIDB4ZmE1ZDc0MDMsIDB4ZTgzZWMzMDUsIDB4NGY5MTc1MWEsIDB4OTI1NjY5YzIsDQoJCSAgMHgyM2VmZTk0MSwgMHhhOTAzZjEyZSwgMHg2MDI3MGRmMiwgMHgwMjc2ZTRiNiwgMHg5NGZkNjU3NCwgMHg5Mjc5ODViMiwgMHg4Mjc2ZGJjYiwgMHgwMjc3ODE3NiwNCgkJICAweGY4YWY5MThkLCAweDRlNDhmNzllLCAweDhmNjE2ZGRmLCAweGUyOWQ4NDBlLCAweDg0MmY3ZDgzLCAweDM0MGNlNWM4LCAweDk2YmJiNjgyLCAweDkzYjRiMTQ4LA0KCQkgIDB4ZWYzMDNjYWIsIDB4OTg0ZmFmMjgsIDB4Nzc5ZmFmOWIsIDB4OTJkYzU2MGQsIDB4MjI0ZDFlMjAsIDB4ODQzN2FhODgsIDB4N2QyOWRjOTYsIDB4Mjc1NmQzZGMsDQoJCSAgMHg4YjkwN2NlZSwgMHhiNTFmZDI0MCwgMHhlN2MwN2NlMywgMHhlNTY2YjRhMSwgMHhjM2U5NjE1ZSwgMHgzY2Y4MjA5ZCwgMHg2MDk0ZDFlMywgMHhjZDljYTM0MSwNCgkJICAweDVjNzY0NjBlLCAweDAwZWE5ODNiLCAweGQ0ZDY3ODgxLCAweGZkNDc1NzJjLCAweGY3NmNlZGQ5LCAweGJkYTgyMjljLCAweDEyN2RhZGFhLCAweDQzOGEwNzRlLA0KCQkgIDB4MWY5N2MwOTAsIDB4MDgxYmRiOGEsIDB4OTNhMDdlYmUsIDB4YjkzOGNhMTUsIDB4OTdiMDNjZmYsIDB4M2RjMmMwZjgsIDB4OGQxYWIyZWMsIDB4NjQzODBlNTEsDQoJCSAgMHg2OGNjN2JmYiwgMHhkOTBmMjc4OCwgMHgxMjQ5MDE4MSwgMHg1ZGU1ZmZkNCwgMHhkZDdlZjg2YSwgMHg3NmEyZTIxNCwgMHhiOWE0MDM2OCwgMHg5MjVkOTU4ZiwNCgkJICAweDRiMzlmZmZhLCAweGJhMzlhZWU5LCAweGE0ZmZkMzBiLCAweGZhZjc5MzNiLCAweDZkNDk4NjIzLCAweDE5M2NiY2ZhLCAweDI3NjI3NTQ1LCAweDgyNWNmNDdhLA0KCQkgIDB4NjFiZDhiYTAsIDB4ZDExZTQyZDEsIDB4Y2VhZDA0ZjQsIDB4MTI3ZWEzOTIsIDB4MTA0MjhkYjcsIDB4ODI3MmE5NzIsIDB4OTI3MGM0YTgsIDB4MTI3ZGU1MGIsDQoJCSAgMHgyODViYTFjOCwgMHgzYzYyZjQ0ZiwgMHgzNWMwZWFhNSwgMHhlODA1ZDIzMSwgMHg0Mjg5MjlmYiwgMHhiNGZjZGY4MiwgMHg0ZmI2NmE1MywgMHgwZTdkYzE1YiwNCgkJICAweDFmMDgxZmFiLCAweDEwODYxOGFlLCAweGZjZmQwODZkLCAweGY5ZmYyODg5LCAweDY5NGJjYzExLCAweDIzNmE1Y2FlLCAweDEyZGVjYTRkLCAweDJjM2Y4Y2M1LA0KCQkgIDB4ZDJkMDJkZmUsIDB4ZjhlZjU4OTYsIDB4ZTRjZjUyZGEsIDB4OTUxNTViNjcsIDB4NDk0YTQ4OGMsIDB4YjliNmE4MGMsIDB4NWM4ZjgyYmMsIDB4ODlkMzZiNDUsDQoJCSAgMHgzYTYwOTQzNywgMHhlYzAwYzlhOSwgMHg0NDcxNTI1MywgMHgwYTg3NGI0OSwgMHhkNzczYmM0MCwgMHg3YzM0NjcxYywgMHgwMjcxN2VmNiwgMHg0ZmViNTUzNiwNCgkJICAweGEyZDAyZmZmLCAweGQyYmY2MGM0LCAweGQ0M2YwM2MwLCAweDUwYjRlZjZkLCAweDA3NDc4Y2QxLCAweDAwNmUxODg4LCAweGEyZTUzZjU1LCAweGI5ZTZkNGJjLA0KCQkgIDB4YTIwNDgwMTYsIDB4OTc1NzM4MzMsIDB4ZDcyMDdkNjcsIDB4ZGUwZjhmM2QsIDB4NzJmODdiMzMsIDB4YWJjYzRmMzMsIDB4NzY4OGM1NWQsIDB4N2IwMGE2YjAsDQoJCSAgMHg5NDdiMDAwMSwgMHg1NzAwNzVkMiwgMHhmOWJiODhmOCwgMHg4OTQyMDE5ZSwgMHg0MjY0YTVmZiwgMHg4NTYzMDJlMCwgMHg3MmRiZDkyYiwgMHhlZTk3MWI2OSwNCgkJICAweDZlYTIyZmRlLCAweDVmMDhhZTJiLCAweGFmN2E2MTZkLCAweGU1Yzk4NzY3LCAweGNmMWZlYmQyLCAweDYxZWZjOGMyLCAweGYxYWMyNTcxLCAweGNjODIzOWMyLA0KCQkgIDB4NjcyMTRjYjgsIDB4YjFlNTgzZDEsIDB4YjdkYzNlNjIsIDB4N2YxMGJkY2UsIDB4ZjkwYTVjMzgsIDB4MGZmMDQ0M2QsIDB4NjA2ZTZkYzYsIDB4NjA1NDNhNDksDQoJCSAgMHg1NzI3YzE0OCwgMHgyYmU5OGExZCwgMHg4YWI0MTczOCwgMHgyMGUxYmUyNCwgMHhhZjk2ZGEwZiwgMHg2ODQ1ODQyNSwgMHg5OTgzM2JlNSwgMHg2MDBkNDU3ZCwNCgkJICAweDI4MmY5MzUwLCAweDgzMzRiMzYyLCAweGQ5MWQxMTIwLCAweDJiNmQ4ZGEwLCAweDY0MmIxZTMxLCAweDljMzA1YTAwLCAweDUyYmNlNjg4LCAweDFiMDM1ODhhLA0KCQkgIDB4ZjdiYWVmZDUsIDB4NDE0MmVkOWMsIDB4YTQzMTVjMTEsIDB4ODMzMjNlYzUsIDB4ZGZlZjQ2MzYsIDB4YTEzM2M1MDEsIDB4ZTlkMzUzMWMsIDB4ZWUzNTM3ODMpOw0KDQoJCXNCb3hbM10gPSBuZXcgQXJyYXkoDQoJCSAgMHg5ZGIzMDQyMCwgMHgxZmI2ZTlkZSwgMHhhN2JlN2JlZiwgMHhkMjczYTI5OCwgMHg0YTRmN2JkYiwgMHg2NGFkOGM1NywgMHg4NTUxMDQ0MywgMHhmYTAyMGVkMSwNCgkJICAweDdlMjg3YWZmLCAweGU2MGZiNjYzLCAweDA5NWYzNWExLCAweDc5ZWJmMTIwLCAweGZkMDU5ZDQzLCAweDY0OTdiN2IxLCAweGYzNjQxZjYzLCAweDI0MWU0YWRmLA0KCQkgIDB4MjgxNDdmNWYsIDB4NGZhMmI4Y2QsIDB4Yzk0MzAwNDAsIDB4MGNjMzIyMjAsIDB4ZmRkMzBiMzAsIDB4YzBhNTM3NGYsIDB4MWQyZDAwZDksIDB4MjQxNDdiMTUsDQoJCSAgMHhlZTRkMTExYSwgMHgwZmNhNTE2NywgMHg3MWZmOTA0YywgMHgyZDE5NWZmZSwgMHgxYTA1NjQ1ZiwgMHgwYzEzZmVmZSwgMHgwODFiMDhjYSwgMHgwNTE3MDEyMSwNCgkJICAweDgwNTMwMTAwLCAweGU4M2U1ZWZlLCAweGFjOWFmNGY4LCAweDdmZTcyNzAxLCAweGQyYjhlZTVmLCAweDA2ZGY0MjYxLCAweGJiOWU5YjhhLCAweDcyOTNlYTI1LA0KCQkgIDB4Y2U4NGZmZGYsIDB4ZjU3MTg4MDEsIDB4M2RkNjRiMDQsIDB4YTI2ZjI2M2IsIDB4N2VkNDg0MDAsIDB4NTQ3ZWViZTYsIDB4NDQ2ZDRjYTAsIDB4NmNmM2Q2ZjUsDQoJCSAgMHgyNjQ5YWJkZiwgMHhhZWEwYzdmNSwgMHgzNjMzOGNjMSwgMHg1MDNmN2U5MywgMHhkMzc3MjA2MSwgMHgxMWI2MzhlMSwgMHg3MjUwMGUwMywgMHhmODBlYjJiYiwNCgkJICAweGFiZTA1MDJlLCAweGVjOGQ3N2RlLCAweDU3OTcxZTgxLCAweGUxNGY2NzQ2LCAweGM5MzM1NDAwLCAweDY5MjAzMThmLCAweDA4MWRiYjk5LCAweGZmYzMwNGE1LA0KCQkgIDB4NGQzNTE4MDUsIDB4N2YzZDVjZTMsIDB4YTZjODY2YzYsIDB4NWQ1YmNjYTksIDB4ZGFlYzZmZWEsIDB4OWY5MjZmOTEsIDB4OWY0NjIyMmYsIDB4Mzk5MTQ2N2QsDQoJCSAgMHhhNWJmNmQ4ZSwgMHgxMTQzYzQ0ZiwgMHg0Mzk1ODMwMiwgMHhkMDIxNGVlYiwgMHgwMjIwODNiOCwgMHgzZmI2MTgwYywgMHgxOGY4OTMxZSwgMHgyODE2NThlNiwNCgkJICAweDI2NDg2ZTNlLCAweDhiZDc4YTcwLCAweDc0NzdlNGMxLCAweGI1MDZlMDdjLCAweGYzMmQwYTI1LCAweDc5MDk4YjAyLCAweGU0ZWFiYjgxLCAweDI4MTIzYjIzLA0KCQkgIDB4NjlkZWFkMzgsIDB4MTU3NGNhMTYsIDB4ZGY4NzFiNjIsIDB4MjExYzQwYjcsIDB4YTUxYTllZjksIDB4MDAxNDM3N2IsIDB4MDQxZThhYzgsIDB4MDkxMTQwMDMsDQoJCSAgMHhiZDU5ZTRkMiwgMHhlM2QxNTZkNSwgMHg0ZmU4NzZkNSwgMHgyZjkxYTM0MCwgMHg1NTdiZThkZSwgMHgwMGVhZTRhNywgMHgwY2U1YzJlYywgMHg0ZGI0YmJhNiwNCgkJICAweGU3NTZiZGZmLCAweGRkMzM2OWFjLCAweGVjMTdiMDM1LCAweDA2NTcyMzI3LCAweDk5YWZjOGIwLCAweDU2YzhjMzkxLCAweDZiNjU4MTFjLCAweDVlMTQ2MTE5LA0KCQkgIDB4NmU4NWNiNzUsIDB4YmUwN2MwMDIsIDB4YzIzMjU1NzcsIDB4ODkzZmY0ZWMsIDB4NWJiZmM5MmQsIDB4ZDBlYzNiMjUsIDB4Yjc4MDFhYjcsIDB4OGQ2ZDNiMjQsDQoJCSAgMHgyMGM3NjNlZiwgMHhjMzY2YTVmYywgMHg5YzM4Mjg4MCwgMHgwYWNlMzIwNSwgMHhhYWM5NTQ4YSwgMHhlY2ExZDdjNywgMHgwNDFhZmEzMiwgMHgxZDE2NjI1YSwNCgkJICAweDY3MDE5MDJjLCAweDliNzU3YTU0LCAweDMxZDQ3N2Y3LCAweDkxMjZiMDMxLCAweDM2Y2M2ZmRiLCAweGM3MGI4YjQ2LCAweGQ5ZTY2YTQ4LCAweDU2ZTU1YTc5LA0KCQkgIDB4MDI2YTRjZWIsIDB4NTI0MzdlZmYsIDB4MmY4Zjc2YjQsIDB4MGRmOTgwYTUsIDB4ODY3NGNkZTMsIDB4ZWRkYTA0ZWIsIDB4MTdhOWJlMDQsIDB4MmMxOGY0ZGYsDQoJCSAgMHhiNzc0N2Y5ZCwgMHhhYjJhZjdiNCwgMHhlZmMzNGQyMCwgMHgyZTA5NmI3YywgMHgxNzQxYTI1NCwgMHhlNWI2YTAzNSwgMHgyMTNkNDJmNiwgMHgyYzFjN2MyNiwNCgkJICAweDYxYzJmNTBmLCAweDY1NTJkYWY5LCAweGQyYzIzMWY4LCAweDI1MTMwZjY5LCAweGQ4MTY3ZmEyLCAweDA0MThmMmM4LCAweDAwMWE5NmE2LCAweDBkMTUyNmFiLA0KCQkgIDB4NjMzMTVjMjEsIDB4NWUwYTcyZWMsIDB4NDliYWZlZmQsIDB4MTg3OTA4ZDksIDB4OGQwZGJkODYsIDB4MzExMTcwYTcsIDB4M2U5YjY0MGMsIDB4Y2MzZTEwZDcsDQoJCSAgMHhkNWNhZDNiNiwgMHgwY2FlYzM4OCwgMHhmNzMwMDFlMSwgMHg2YzcyOGFmZiwgMHg3MWVhZTJhMSwgMHgxZjlhZjM2ZSwgMHhjZmNiZDEyZiwgMHhjMWRlODQxNywNCgkJICAweGFjMDdiZTZiLCAweGNiNDRhMWQ4LCAweDhiOWIwZjU2LCAweDAxMzk4OGMzLCAweGIxYzUyZmNhLCAweGI0YmUzMWNkLCAweGQ4NzgyODA2LCAweDEyYTNhNGUyLA0KCQkgIDB4NmY3ZGU1MzIsIDB4NThmZDdlYjYsIDB4ZDAxZWU5MDAsIDB4MjRhZGZmYzIsIDB4ZjQ5OTBmYzUsIDB4OTcxMWFhYzUsIDB4MDAxZDdiOTUsIDB4ODJlNWU3ZDIsDQoJCSAgMHgxMDk4NzNmNiwgMHgwMDYxMzA5NiwgMHhjMzJkOTUyMSwgMHhhZGExMjFmZiwgMHgyOTkwODQxNSwgMHg3ZmJiOTc3ZiwgMHhhZjllYjNkYiwgMHgyOWM5ZWQyYSwNCgkJICAweDVjZTJhNDY1LCAweGE3MzBmMzJjLCAweGQwYWEzZmU4LCAweDhhNWNjMDkxLCAweGQ0OWUyY2U3LCAweDBjZTQ1NGE5LCAweGQ2MGFjZDg2LCAweDAxNWYxOTE5LA0KCQkgIDB4NzcwNzkxMDMsIDB4ZGVhMDNhZjYsIDB4NzhhODU2NWUsIDB4ZGVlMzU2ZGYsIDB4MjFmMDVjYmUsIDB4OGI3NWUzODcsIDB4YjNjNTA2NTEsIDB4YjhhNWMzZWYsDQoJCSAgMHhkOGVlYjZkMiwgMHhlNTIzYmU3NywgMHhjMjE1NDUyOSwgMHgyZjY5ZWZkZiwgMHhhZmU2N2FmYiwgMHhmNDcwYzRiMiwgMHhmM2UwZWI1YiwgMHhkNmNjOTg3NiwNCgkJICAweDM5ZTQ0NjBjLCAweDFmZGE4NTM4LCAweDE5ODc4MzJmLCAweGNhMDA3MzY3LCAweGE5OTE0NGY4LCAweDI5NmIyOTllLCAweDQ5MmZjMjk1LCAweDkyNjZiZWFiLA0KCQkgIDB4YjU2NzZlNjksIDB4OWJkM2RkZGEsIDB4ZGY3ZTA1MmYsIDB4ZGIyNTcwMWMsIDB4MWI1ZTUxZWUsIDB4ZjY1MzI0ZTYsIDB4NmFmY2UzNmMsIDB4MDMxNmNjMDQsDQoJCSAgMHg4NjQ0MjEzZSwgMHhiN2RjNTlkMCwgMHg3OTY1MjkxZiwgMHhjY2Q2ZmQ0MywgMHg0MTgyMzk3OSwgMHg5MzJiY2RmNiwgMHhiNjU3YzM0ZCwgMHg0ZWRmZDI4MiwNCgkJICAweDdhZTUyOTBjLCAweDNjYjk1MzZiLCAweDg1MWUyMGZlLCAweDk4MzM1NTdlLCAweDEzZWNmMGIwLCAweGQzZmZiMzcyLCAweDNmODVjNWMxLCAweDBhZWY3ZWQyKTsNCg0KCQlzQm94WzRdID0gbmV3IEFycmF5KA0KCQkgIDB4N2VjOTBjMDQsIDB4MmM2ZTc0YjksIDB4OWIwZTY2ZGYsIDB4YTYzMzc5MTEsIDB4Yjg2YTdmZmYsIDB4MWRkMzU4ZjUsIDB4NDRkZDlkNDQsIDB4MTczMTE2N2YsDQoJCSAgMHgwOGZiZjFmYSwgMHhlN2Y1MTFjYywgMHhkMjA1MWIwMCwgMHg3MzVhYmEwMCwgMHgyYWI3MjJkOCwgMHgzODYzODFjYiwgMHhhY2Y2MjQzYSwgMHg2OWJlZmQ3YSwNCgkJICAweGU2YTJlNzdmLCAweGYwYzcyMGNkLCAweGM0NDk0ODE2LCAweGNjZjVjMTgwLCAweDM4ODUxNjQwLCAweDE1YjBhODQ4LCAweGU2OGIxOGNiLCAweDRjYWFkZWZmLA0KCQkgIDB4NWY0ODBhMDEsIDB4MDQxMmIyYWEsIDB4MjU5ODE0ZmMsIDB4NDFkMGVmZTIsIDB4NGU0MGI0OGQsIDB4MjQ4ZWI2ZmIsIDB4OGRiYTFjZmUsIDB4NDFhOTliMDIsDQoJCSAgMHgxYTU1MGEwNCwgMHhiYThmNjVjYiwgMHg3MjUxZjRlNywgMHg5NWE1MTcyNSwgMHhjMTA2ZWNkNywgMHg5N2E1OTgwYSwgMHhjNTM5YjlhYSwgMHg0ZDc5ZmU2YSwNCgkJICAweGYyZjNmNzYzLCAweDY4YWY4MDQwLCAweGVkMGM5ZTU2LCAweDExYjQ5NThiLCAweGUxZWI1YTg4LCAweDg3MDllNmIwLCAweGQ3ZTA3MTU2LCAweDRlMjlmZWE3LA0KCQkgIDB4NjM2NmU1MmQsIDB4MDJkMWMwMDAsIDB4YzRhYzhlMDUsIDB4OTM3N2Y1NzEsIDB4MGMwNTM3MmEsIDB4NTc4NTM1ZjIsIDB4MjI2MWJlMDIsIDB4ZDY0MmEwYzksDQoJCSAgMHhkZjEzYTI4MCwgMHg3NGI1NWJkMiwgMHg2ODIxOTljMCwgMHhkNDIxZTVlYywgMHg1M2ZiM2NlOCwgMHhjOGFkZWRiMywgMHgyOGE4N2ZjOSwgMHgzZDk1OTk4MSwNCgkJICAweDVjMWZmOTAwLCAweGZlMzhkMzk5LCAweDBjNGVmZjBiLCAweDA2MjQwN2VhLCAweGFhMmY0ZmIxLCAweDRmYjk2OTc2LCAweDkwYzc5NTA1LCAweGIwYThhNzc0LA0KCQkgIDB4ZWY1NWExZmYsIDB4ZTU5Y2EyYzIsIDB4YTZiNjJkMjcsIDB4ZTY2YTQyNjMsIDB4ZGY2NTAwMWYsIDB4MGVjNTA5NjYsIDB4ZGZkZDU1YmMsIDB4MjlkZTA2NTUsDQoJCSAgMHg5MTFlNzM5YSwgMHgxN2FmODk3NSwgMHgzMmM3OTExYywgMHg4OWY4OTQ2OCwgMHgwZDAxZTk4MCwgMHg1MjQ3NTVmNCwgMHgwM2I2M2NjOSwgMHgwY2M4NDRiMiwNCgkJICAweGJjZjNmMGFhLCAweDg3YWMzNmU5LCAweGU1M2E3NDI2LCAweDAxYjNkODJiLCAweDFhOWU3NDQ5LCAweDY0ZWUyZDdlLCAweGNkZGJiMWRhLCAweDAxYzk0OTEwLA0KCQkgIDB4Yjg2OGJmODAsIDB4MGQyNmYzZmQsIDB4OTM0MmVkZTcsIDB4MDRhNWMyODQsIDB4NjM2NzM3YjYsIDB4NTBmNWI2MTYsIDB4ZjI0NzY2ZTMsIDB4OGVjYTM2YzEsDQoJCSAgMHgxMzZlMDVkYiwgMHhmZWYxODM5MSwgMHhmYjg4N2EzNywgMHhkNmU3ZjdkNCwgMHhjN2ZiN2RjOSwgMHgzMDYzZmNkZiwgMHhiNmY1ODlkZSwgMHhlYzI5NDFkYSwNCgkJICAweDI2ZTQ2Njk1LCAweGI3NTY2NDE5LCAweGY2NTRlZmM1LCAweGQwOGQ1OGI3LCAweDQ4OTI1NDAxLCAweGMxYmFjYjdmLCAweGU1ZmY1NTBmLCAweGI2MDgzMDQ5LA0KCQkgIDB4NWJiNWQwZTgsIDB4ODdkNzJlNWEsIDB4YWI2YTZlZTEsIDB4MjIzYTY2Y2UsIDB4YzYyYmYzY2QsIDB4OWUwODg1ZjksIDB4NjhjYjNlNDcsIDB4MDg2YzAxMGYsDQoJCSAgMHhhMjFkZTgyMCwgMHhkMThiNjlkZSwgMHhmM2Y2NTc3NywgMHhmYTAyYzNmNiwgMHg0MDdlZGFjMywgMHhjYmIzZDU1MCwgMHgxNzkzMDg0ZCwgMHhiMGQ3MGViYSwNCgkJICAweDBhYjM3OGQ1LCAweGQ5NTFmYjBjLCAweGRlZDdkYTU2LCAweDQxMjRiYmU0LCAweDk0Y2EwYjU2LCAweDBmNTc1NWQxLCAweGUwZTFlNTZlLCAweDYxODRiNWJlLA0KCQkgIDB4NTgwYTI0OWYsIDB4OTRmNzRiYzAsIDB4ZTMyNzg4OGUsIDB4OWY3YjU1NjEsIDB4YzNkYzAyODAsIDB4MDU2ODc3MTUsIDB4NjQ2YzZiZDcsIDB4NDQ5MDRkYjMsDQoJCSAgMHg2NmI0ZjBhMywgMHhjMGYxNjQ4YSwgMHg2OTdlZDVhZiwgMHg0OWU5MmZmNiwgMHgzMDllMzc0ZiwgMHgyY2I2MzU2YSwgMHg4NTgwODU3MywgMHg0OTkxZjg0MCwNCgkJICAweDc2ZjBhZTAyLCAweDA4M2JlODRkLCAweDI4NDIxYzlhLCAweDQ0NDg5NDA2LCAweDczNmU0Y2I4LCAweGMxMDkyOTEwLCAweDhiYzk1ZmM2LCAweDdkODY5Y2Y0LA0KCQkgIDB4MTM0ZjYxNmYsIDB4MmU3NzExOGQsIDB4YjMxYjJiZTEsIDB4YWE5MGI0NzIsIDB4M2NhNWQ3MTcsIDB4N2QxNjFiYmEsIDB4OWNhZDkwMTAsIDB4YWY0NjJiYTIsDQoJCSAgMHg5ZmU0NTlkMiwgMHg0NWQzNDU1OSwgMHhkOWYyZGExMywgMHhkYmM2NTQ4NywgMHhmM2U0Zjk0ZSwgMHgxNzZkNDg2ZiwgMHgwOTdjMTNlYSwgMHg2MzFkYTVjNywNCgkJICAweDQ0NWY3MzgyLCAweDE3NTY4M2Y0LCAweGNkYzY2YTk3LCAweDcwYmUwMjg4LCAweGIzY2RjZjcyLCAweDZlNWRkMmYzLCAweDIwOTM2MDc5LCAweDQ1OWI4MGE1LA0KCQkgIDB4YmU2MGUyZGIsIDB4YTljMjMxMDEsIDB4ZWJhNTMxNWMsIDB4MjI0ZTQyZjIsIDB4MWM1YzE1NzIsIDB4ZjY3MjFiMmMsIDB4MWFkMmZmZjMsIDB4OGMyNTQwNGUsDQoJCSAgMHgzMjRlZDcyZiwgMHg0MDY3YjdmZCwgMHgwNTIzMTM4ZSwgMHg1Y2EzYmM3OCwgMHhkYzBmZDY2ZSwgMHg3NTkyMjI4MywgMHg3ODRkNmIxNywgMHg1OGViYjE2ZSwNCgkJICAweDQ0MDk0Zjg1LCAweDNmNDgxZDg3LCAweGZjZmVhZTdiLCAweDc3YjVmZjc2LCAweDhjMjMwMmJmLCAweGFhZjQ3NTU2LCAweDVmNDZiMDJhLCAweDJiMDkyODAxLA0KCQkgIDB4M2QzOGY1ZjcsIDB4MGNhODFmMzYsIDB4NTJhZjRhOGEsIDB4NjZkNWU3YzAsIDB4ZGYzYjA4NzQsIDB4OTUwNTUxMTAsIDB4MWI1YWQ3YTgsIDB4ZjYxZWQ1YWQsDQoJCSAgMHg2Y2Y2ZTQ3OSwgMHgyMDc1ODE4NCwgMHhkMGNlZmE2NSwgMHg4OGY3YmU1OCwgMHg0YTA0NjgyNiwgMHgwZmY2ZjhmMywgMHhhMDljN2Y3MCwgMHg1MzQ2YWJhMCwNCgkJICAweDVjZTk2YzI4LCAweGUxNzZlZGEzLCAweDZiYWMzMDdmLCAweDM3NjgyOWQyLCAweDg1MzYwZmE5LCAweDE3ZTNmZTJhLCAweDI0Yjc5NzY3LCAweGY1YTk2YjIwLA0KCQkgIDB4ZDZjZDI1OTUsIDB4NjhmZjFlYmYsIDB4NzU1NTQ0MmMsIDB4ZjE5ZjA2YmUsIDB4ZjllMDY1OWEsIDB4ZWViOTQ5MWQsIDB4MzQwMTA3MTgsIDB4YmIzMGNhYjgsDQoJCSAgMHhlODIyZmUxNSwgMHg4ODU3MDk4MywgMHg3NTBlNjI0OSwgMHhkYTYyN2U1NSwgMHg1ZTc2ZmZhOCwgMHhiMTUzNDU0NiwgMHg2ZDQ3ZGUwOCwgMHhlZmU5ZTdkNCk7DQoNCgkJc0JveFs1XSA9IG5ldyBBcnJheSgNCgkJICAweGY2ZmE4ZjlkLCAweDJjYWM2Y2UxLCAweDRjYTM0ODY3LCAweGUyMzM3ZjdjLCAweDk1ZGIwOGU3LCAweDAxNjg0M2I0LCAweGVjZWQ1Y2JjLCAweDMyNTU1M2FjLA0KCQkgIDB4YmY5ZjA5NjAsIDB4ZGZhMWUyZWQsIDB4ODNmMDU3OWQsIDB4NjNlZDg2YjksIDB4MWFiNmE2YjgsIDB4ZGU1ZWJlMzksIDB4ZjM4ZmY3MzIsIDB4ODk4OWIxMzgsDQoJCSAgMHgzM2YxNDk2MSwgMHhjMDE5MzdiZCwgMHhmNTA2YzZkYSwgMHhlNDYyNWU3ZSwgMHhhMzA4ZWE5OSwgMHg0ZTIzZTMzYywgMHg3OWNiZDdjYywgMHg0OGExNDM2NywNCgkJICAweGEzMTQ5NjE5LCAweGZlYzk0YmQ1LCAweGExMTQxNzRhLCAweGVhYTAxODY2LCAweGEwODRkYjJkLCAweDA5YTg0ODZmLCAweGE4ODg2MTRhLCAweDI5MDBhZjk4LA0KCQkgIDB4MDE2NjU5OTEsIDB4ZTE5OTI4NjMsIDB4YzhmMzBjNjAsIDB4MmU3OGVmM2MsIDB4ZDBkNTE5MzIsIDB4Y2YwZmVjMTQsIDB4ZjdjYTA3ZDIsIDB4ZDBhODIwNzIsDQoJCSAgMHhmZDQxMTk3ZSwgMHg5MzA1YTZiMCwgMHhlODZiZTNkYSwgMHg3NGJlZDNjZCwgMHgzNzJkYTUzYywgMHg0YzdmNDQ0OCwgMHhkYWI1ZDQ0MCwgMHg2ZGJhMGVjMywNCgkJICAweDA4MzkxOWE3LCAweDlmYmFlZWQ5LCAweDQ5ZGJjZmIwLCAweDRlNjcwYzUzLCAweDVjM2Q5YzAxLCAweDY0YmRiOTQxLCAweDJjMGU2MzZhLCAweGJhN2RkOWNkLA0KCQkgIDB4ZWE2ZjczODgsIDB4ZTcwYmM3NjIsIDB4MzVmMjlhZGIsIDB4NWM0Y2RkOGQsIDB4ZjBkNDhkOGMsIDB4Yjg4MTUzZTIsIDB4MDhhMTk4NjYsIDB4MWFlMmVhYzgsDQoJCSAgMHgyODRjYWY4OSwgMHhhYTkyODIyMywgMHg5MzM0YmU1MywgMHgzYjNhMjFiZiwgMHgxNjQzNGJlMywgMHg5YWVhMzkwNiwgMHhlZmU4YzM2ZSwgMHhmODkwY2RkOSwNCgkJICAweDgwMjI2ZGFlLCAweGMzNDBhNGEzLCAweGRmN2U5YzA5LCAweGE2OTRhODA3LCAweDViN2M1ZWNjLCAweDIyMWRiM2E2LCAweDlhNjlhMDJmLCAweDY4ODE4YTU0LA0KCQkgIDB4Y2ViMjI5NmYsIDB4NTNjMDg0M2EsIDB4ZmU4OTM2NTUsIDB4MjViZmU2OGEsIDB4YjQ2MjhhYmMsIDB4Y2YyMjJlYmYsIDB4MjVhYzZmNDgsIDB4YTlhOTkzODcsDQoJCSAgMHg1M2JkZGI2NSwgMHhlNzZmZmJlNywgMHhlOTY3ZmQ3OCwgMHgwYmE5MzU2MywgMHg4ZTM0MmJjMSwgMHhlOGExMWJlOSwgMHg0OTgwNzQwZCwgMHhjODA4N2RmYywNCgkJICAweDhkZTRiZjk5LCAweGExMTEwMWEwLCAweDdmZDM3OTc1LCAweGRhNWEyNmMwLCAweGU4MWY5OTRmLCAweDk1MjhjZDg5LCAweGZkMzM5ZmVkLCAweGI4NzgzNGJmLA0KCQkgIDB4NWYwNDQ1NmQsIDB4MjIyNTg2OTgsIDB4YzljNGM4M2IsIDB4MmRjMTU2YmUsIDB4NGY2MjhkYWEsIDB4NTdmNTVlYzUsIDB4ZTIyMjBhYmUsIDB4ZDI5MTZlYmYsDQoJCSAgMHg0ZWM3NWI5NSwgMHgyNGYyYzNjMCwgMHg0MmQxNWQ5OSwgMHhjZDBkN2ZhMCwgMHg3YjZlMjdmZiwgMHhhOGRjOGFmMCwgMHg3MzQ1YzEwNiwgMHhmNDFlMjMyZiwNCgkJICAweDM1MTYyMzg2LCAweGU2ZWE4OTI2LCAweDMzMzNiMDk0LCAweDE1N2VjNmYyLCAweDM3MmI3NGFmLCAweDY5MjU3M2U0LCAweGU5YTlkODQ4LCAweGYzMTYwMjg5LA0KCQkgIDB4M2E2MmVmMWQsIDB4YTc4N2UyMzgsIDB4ZjNhNWY2NzYsIDB4NzQzNjQ4NTMsIDB4MjA5NTEwNjMsIDB4NDU3NjY5OGQsIDB4YjZmYWQ0MDcsIDB4NTkyYWY5NTAsDQoJCSAgMHgzNmY3MzUyMywgMHg0Y2ZiNmU4NywgMHg3ZGE0Y2VjMCwgMHg2YzE1MmRhYSwgMHhjYjAzOTZhOCwgMHhjNTBkZmU1ZCwgMHhmY2Q3MDdhYiwgMHgwOTIxYzQyZiwNCgkJICAweDg5ZGZmMGJiLCAweDVmZTJiZTc4LCAweDQ0OGY0ZjMzLCAweDc1NDYxM2M5LCAweDJiMDVkMDhkLCAweDQ4YjlkNTg1LCAweGRjMDQ5NDQxLCAweGM4MDk4ZjliLA0KCQkgIDB4N2RlZGU3ODYsIDB4YzM5YTMzNzMsIDB4NDI0MTAwMDUsIDB4NmEwOTE3NTEsIDB4MGVmM2M4YTYsIDB4ODkwMDcyZDYsIDB4MjgyMDc2ODIsIDB4YTlhOWY3YmUsDQoJCSAgMHhiZjMyNjc5ZCwgMHhkNDViNWI3NSwgMHhiMzUzZmQwMCwgMHhjYmIwZTM1OCwgMHg4MzBmMjIwYSwgMHgxZjhmYjIxNCwgMHhkMzcyY2YwOCwgMHhjYzNjNGExMywNCgkJICAweDhjZjYzMTY2LCAweDA2MWM4N2JlLCAweDg4Yzk4Zjg4LCAweDYwNjJlMzk3LCAweDQ3Y2Y4ZTdhLCAweGI2Yzg1MjgzLCAweDNjYzJhY2ZiLCAweDNmYzA2OTc2LA0KCQkgIDB4NGU4ZjAyNTIsIDB4NjRkODMxNGQsIDB4ZGEzODcwZTMsIDB4MWU2NjU0NTksIDB4YzEwOTA4ZjAsIDB4NTEzMDIxYTUsIDB4NmM1YjY4YjcsIDB4ODIyZjhhYTAsDQoJCSAgMHgzMDA3Y2QzZSwgMHg3NDcxOWVlZiwgMHhkYzg3MjY4MSwgMHgwNzMzNDBkNCwgMHg3ZTQzMmZkOSwgMHgwYzVlYzI0MSwgMHg4ODA5Mjg2YywgMHhmNTkyZDg5MSwNCgkJICAweDA4YTkzMGY2LCAweDk1N2VmMzA1LCAweGI3ZmJmZmJkLCAweGMyNjZlOTZmLCAweDZmZTRhYzk4LCAweGIxNzNlY2MwLCAweGJjNjBiNDJhLCAweDk1MzQ5OGRhLA0KCQkgIDB4ZmJhMWFlMTIsIDB4MmQ0YmQ3MzYsIDB4MGYyNWZhYWIsIDB4YTRmM2ZjZWIsIDB4ZTI5NjkxMjMsIDB4MjU3ZjBjM2QsIDB4OTM0OGFmNDksIDB4MzYxNDAwYmMsDQoJCSAgMHhlODgxNmY0YSwgMHgzODE0ZjIwMCwgMHhhM2Y5NDA0MywgMHg5YzdhNTRjMiwgMHhiYzcwNGY1NywgMHhkYTQxZTdmOSwgMHhjMjVhZDMzYSwgMHg1NGY0YTA4NCwNCgkJICAweGIxN2Y1NTA1LCAweDU5MzU3Y2JlLCAweGVkYmQxNWM4LCAweDdmOTdjNWFiLCAweGJhNWFjN2I1LCAweGI2ZjZkZWFmLCAweDNhNDc5YzNhLCAweDUzMDJkYTI1LA0KCQkgIDB4NjUzZDdlNmEsIDB4NTQyNjhkNDksIDB4NTFhNDc3ZWEsIDB4NTAxN2Q1NWIsIDB4ZDdkMjVkODgsIDB4NDQxMzZjNzYsIDB4MDQwNGE4YzgsIDB4YjhlNWExMjEsDQoJCSAgMHhiODFhOTI4YSwgMHg2MGVkNTg2OSwgMHg5N2M1NWI5NiwgMHhlYWVjOTkxYiwgMHgyOTkzNTkxMywgMHgwMWZkYjdmMSwgMHgwODhlOGRmYSwgMHg5YWI2ZjZmNSwNCgkJICAweDNiNGNiZjlmLCAweDRhNWRlM2FiLCAweGU2MDUxZDM1LCAweGEwZTFkODU1LCAweGQzNmI0Y2YxLCAweGY1NDRlZGViLCAweGIwZTkzNTI0LCAweGJlYmI4ZmJkLA0KCQkgIDB4YTJkNzYyY2YsIDB4NDljOTJmNTQsIDB4MzhiNWYzMzEsIDB4NzEyOGE0NTQsIDB4NDgzOTI5MDUsIDB4YTY1YjFkYjgsIDB4ODUxYzk3YmQsIDB4ZDY3NWNmMmYpOw0KDQoJCXNCb3hbNl0gPSBuZXcgQXJyYXkoDQoJCSAgMHg4NWUwNDAxOSwgMHgzMzJiZjU2NywgMHg2NjJkYmZmZiwgMHhjZmM2NTY5MywgMHgyYThkN2Y2ZiwgMHhhYjliYzkxMiwgMHhkZTYwMDhhMSwgMHgyMDI4ZGExZiwNCgkJICAweDAyMjdiY2U3LCAweDRkNjQyOTE2LCAweDE4ZmFjMzAwLCAweDUwZjE4YjgyLCAweDJjYjJjYjExLCAweGIyMzJlNzVjLCAweDRiMzY5NWYyLCAweGIyODcwN2RlLA0KCQkgIDB4YTA1ZmJjZjYsIDB4Y2Q0MTgxZTksIDB4ZTE1MDIxMGMsIDB4ZTI0ZWYxYmQsIDB4YjE2OGMzODEsIDB4ZmRlNGU3ODksIDB4NWM3OWIwZDgsIDB4MWU4YmZkNDMsDQoJCSAgMHg0ZDQ5NTAwMSwgMHgzOGJlNDM0MSwgMHg5MTNjZWUxZCwgMHg5MmE3OWMzZiwgMHgwODk3NjZiZSwgMHhiYWVlYWRmNCwgMHgxMjg2YmVjZiwgMHhiNmVhY2IxOSwNCgkJICAweDI2NjBjMjAwLCAweDc1NjViZGU0LCAweDY0MjQxZjdhLCAweDgyNDhkY2E5LCAweGMzYjNhZDY2LCAweDI4MTM2MDg2LCAweDBiZDhkZmE4LCAweDM1NmQxY2YyLA0KCQkgIDB4MTA3Nzg5YmUsIDB4YjNiMmU5Y2UsIDB4MDUwMmFhOGYsIDB4MGJjMDM1MWUsIDB4MTY2YmY1MmEsIDB4ZWIxMmZmODIsIDB4ZTM0ODY5MTEsIDB4ZDM0ZDc1MTYsDQoJCSAgMHg0ZTdiM2FmZiwgMHg1ZjQzNjcxYiwgMHg5Y2Y2ZTAzNywgMHg0OTgxYWM4MywgMHgzMzQyNjZjZSwgMHg4YzkzNDFiNywgMHhkMGQ4NTRjMCwgMHhjYjNhNmM4OCwNCgkJICAweDQ3YmMyODI5LCAweDQ3MjViYTM3LCAweGE2NmFkMjJiLCAweDdhZDYxZjFlLCAweDBjNWNiYWZhLCAweDQ0MzdmMTA3LCAweGI2ZTc5OTYyLCAweDQyZDJkODE2LA0KCQkgIDB4MGE5NjEyODgsIDB4ZTFhNWMwNmUsIDB4MTM3NDllNjcsIDB4NzJmYzA4MWEsIDB4YjFkMTM5ZjcsIDB4Zjk1ODM3NDUsIDB4Y2YxOWRmNTgsIDB4YmVjM2Y3NTYsDQoJCSAgMHhjMDZlYmEzMCwgMHgwNzIxMWIyNCwgMHg0NWMyODgyOSwgMHhjOTVlMzE3ZiwgMHhiYzhlYzUxMSwgMHgzOGJjNDZlOSwgMHhjNmU2ZmExNCwgMHhiYWU4NTg0YSwNCgkJICAweGFkNGViYzQ2LCAweDQ2OGY1MDhiLCAweDc4Mjk0MzVmLCAweGYxMjQxODNiLCAweDgyMWRiYTlmLCAweGFmZjYwZmY0LCAweGVhMmM0ZTZkLCAweDE2ZTM5MjY0LA0KCQkgIDB4OTI1NDRhOGIsIDB4MDA5YjRmYzMsIDB4YWJhNjhjZWQsIDB4OWFjOTZmNzgsIDB4MDZhNWI3OWEsIDB4YjI4NTZlNmUsIDB4MWFlYzNjYTksIDB4YmU4Mzg2ODgsDQoJCSAgMHgwZTA4MDRlOSwgMHg1NWYxYmU1NiwgMHhlN2U1MzYzYiwgMHhiM2ExZjI1ZCwgMHhmN2RlYmI4NSwgMHg2MWZlMDMzYywgMHgxNjc0NjIzMywgMHgzYzAzNGMyOCwNCgkJICAweGRhNmQwYzc0LCAweDc5YWFjNTZjLCAweDNjZTRlMWFkLCAweDUxZjBjODAyLCAweDk4ZjhmMzVhLCAweDE2MjZhNDlmLCAweGVlZDgyYjI5LCAweDFkMzgyZmUzLA0KCQkgIDB4MGM0ZmI5OWEsIDB4YmIzMjU3NzgsIDB4M2VjNmQ5N2IsIDB4NmU3N2E2YTksIDB4Y2I2NThiNWMsIDB4ZDQ1MjMwYzcsIDB4MmJkMTQwOGIsIDB4NjBjMDNlYjcsDQoJCSAgMHhiOTA2OGQ3OCwgMHhhMzM3NTRmNCwgMHhmNDMwYzg3ZCwgMHhjOGE3MTMwMiwgMHhiOTZkOGMzMiwgMHhlYmQ0ZTdiZSwgMHhiZThiOWQyZCwgMHg3OTc5ZmIwNiwNCgkJICAweGU3MjI1MzA4LCAweDhiNzVjZjc3LCAweDExZWY4ZGE0LCAweGUwODNjODU4LCAweDhkNmI3ODZmLCAweDVhNjMxN2E2LCAweGZhNWNmN2EwLCAweDVkZGEwMDMzLA0KCQkgIDB4ZjI4ZWJmYjAsIDB4ZjViOWMzMTAsIDB4YTBlYWMyODAsIDB4MDhiOTc2N2EsIDB4YTNkOWQyYjAsIDB4NzlkMzQyMTcsIDB4MDIxYTcxOGQsIDB4OWFjNjMzNmEsDQoJCSAgMHgyNzExZmQ2MCwgMHg0MzgwNTBlMywgMHgwNjk5MDhhOCwgMHgzZDdmZWRjNCwgMHg4MjZkMmJlZiwgMHg0ZWViODQ3NiwgMHg0ODhkY2YyNSwgMHgzNmM5ZDU2NiwNCgkJICAweDI4ZTc0ZTQxLCAweGMyNjEwYWNhLCAweDNkNDlhOWNmLCAweGJhZTNiOWRmLCAweGI2NWY4ZGU2LCAweDkyYWVhZjY0LCAweDNhYzdkNWU2LCAweDllYTgwNTA5LA0KCQkgIDB4ZjIyYjAxN2QsIDB4YTQxNzNmNzAsIDB4ZGQxZTE2YzMsIDB4MTVlMGQ3ZjksIDB4NTBiMWI4ODcsIDB4MmI5ZjRmZDUsIDB4NjI1YWJhODIsIDB4NmEwMTc5NjIsDQoJCSAgMHgyZWMwMWI5YywgMHgxNTQ4OGFhOSwgMHhkNzE2ZTc0MCwgMHg0MDA1NWEyYywgMHg5M2QyOWEyMiwgMHhlMzJkYmY5YSwgMHgwNTg3NDViOSwgMHgzNDUzZGMxZSwNCgkJICAweGQ2OTkyOTZlLCAweDQ5NmNmZjZmLCAweDFjOWY0OTg2LCAweGRmZTJlZDA3LCAweGI4NzI0MmQxLCAweDE5ZGU3ZWFlLCAweDA1M2U1NjFhLCAweDE1YWQ2ZjhjLA0KCQkgIDB4NjY2MjZjMWMsIDB4NzE1NGMyNGMsIDB4ZWEwODJiMmEsIDB4OTNlYjI5MzksIDB4MTdkY2IwZjAsIDB4NThkNGYyYWUsIDB4OWVhMjk0ZmIsIDB4NTJjZjU2NGMsDQoJCSAgMHg5ODgzZmU2NiwgMHgyZWM0MDU4MSwgMHg3NjM5NTNjMywgMHgwMWQ2NjkyZSwgMHhkM2EwYzEwOCwgMHhhMWU3MTYwZSwgMHhlNGYyZGZhNiwgMHg2OTNlZDI4NSwNCgkJICAweDc0OTA0Njk4LCAweDRjMmIwZWRkLCAweDRmNzU3NjU2LCAweDVkMzkzMzc4LCAweGExMzIyMzRmLCAweDNkMzIxYzVkLCAweGMzZjVlMTk0LCAweDRiMjY5MzAxLA0KCQkgIDB4Yzc5ZjAyMmYsIDB4M2M5OTdlN2UsIDB4NWU0Zjk1MDQsIDB4M2ZmYWZiYmQsIDB4NzZmN2FkMGUsIDB4Mjk2NjkzZjQsIDB4M2QxZmNlNmYsIDB4YzYxZTQ1YmUsDQoJCSAgMHhkM2I1YWIzNCwgMHhmNzJiZjliNywgMHgxYjA0MzRjMCwgMHg0ZTcyYjU2NywgMHg1NTkyYTMzZCwgMHhiNTIyOTMwMSwgMHhjZmQyYTg3ZiwgMHg2MGFlYjc2NywNCgkJICAweDE4MTQzODZiLCAweDMwYmNjMzNkLCAweDM4YTBjMDdkLCAweGZkMTYwNmYyLCAweGMzNjM1MTliLCAweDU4OWRkMzkwLCAweDU0NzlmOGU2LCAweDFjYjhkNjQ3LA0KCQkgIDB4OTdmZDYxYTksIDB4ZWE3NzU5ZjQsIDB4MmQ1NzUzOWQsIDB4NTY5YTU4Y2YsIDB4ZTg0ZTYzYWQsIDB4NDYyZTFiNzgsIDB4NjU4MGY4N2UsIDB4ZjM4MTc5MTQsDQoJCSAgMHg5MWRhNTVmNCwgMHg0MGEyMzBmMywgMHhkMTk4OGYzNSwgMHhiNmUzMThkMiwgMHgzZmZhNTBiYywgMHgzZDQwZjAyMSwgMHhjM2MwYmRhZSwgMHg0OTU4YzI0YywNCgkJICAweDUxOGYzNmIyLCAweDg0YjFkMzcwLCAweDBmZWRjZTgzLCAweDg3OGRkYWRhLCAweGYyYTI3OWM3LCAweDk0ZTAxYmU4LCAweDkwNzE2ZjRiLCAweDk1NGI4YWEzKTsNCg0KCQlzQm94WzddID0gbmV3IEFycmF5KA0KCQkgIDB4ZTIxNjMwMGQsIDB4YmJkZGZmZmMsIDB4YTdlYmRhYmQsIDB4MzU2NDgwOTUsIDB4Nzc4OWY4YjcsIDB4ZTZjMTEyMWIsIDB4MGUyNDE2MDAsIDB4MDUyY2U4YjUsDQoJCSAgMHgxMWE5Y2ZiMCwgMHhlNTk1MmYxMSwgMHhlY2U3OTkwYSwgMHg5Mzg2ZDE3NCwgMHgyYTQyOTMxYywgMHg3NmUzODExMSwgMHhiMTJkZWYzYSwgMHgzN2RkZGRmYywNCgkJICAweGRlOWFkZWIxLCAweDBhMGNjMzJjLCAweGJlMTk3MDI5LCAweDg0YTAwOTQwLCAweGJiMjQzYTBmLCAweGI0ZDEzN2NmLCAweGI0NGU3OWYwLCAweDA0OWVlZGZkLA0KCQkgIDB4MGIxNWExNWQsIDB4NDgwZDMxNjgsIDB4OGJiYmRlNWEsIDB4NjY5ZGVkNDIsIDB4YzdlY2U4MzEsIDB4M2Y4Zjk1ZTcsIDB4NzJkZjE5MWIsIDB4NzU4MDMzMGQsDQoJCSAgMHg5NDA3NDI1MSwgMHg1YzdkY2RmYSwgMHhhYmJlNmQ2MywgMHhhYTQwMjE2NCwgMHhiMzAxZDQwYSwgMHgwMmU3ZDFjYSwgMHg1MzU3MWRhZSwgMHg3YTMxODJhMiwNCgkJICAweDEyYThkZGVjLCAweGZkYWEzMzVkLCAweDE3NmY0M2U4LCAweDcxZmI0NmQ0LCAweDM4MTI5MDIyLCAweGNlOTQ5YWQ0LCAweGI4NDc2OWFkLCAweDk2NWJkODYyLA0KCQkgIDB4ODJmM2QwNTUsIDB4NjZmYjk3NjcsIDB4MTViODBiNGUsIDB4MWQ1YjQ3YTAsIDB4NGNmZGUwNmYsIDB4YzI4ZWM0YjgsIDB4NTdlODcyNmUsIDB4NjQ3YTc4ZmMsDQoJCSAgMHg5OTg2NWQ0NCwgMHg2MDhiZDU5MywgMHg2YzIwMGUwMywgMHgzOWRjNWZmNiwgMHg1ZDBiMDBhMywgMHhhZTYzYWZmMiwgMHg3ZThiZDYzMiwgMHg3MDEwOGMwYywNCgkJICAweGJiZDM1MDQ5LCAweDI5OThkZjA0LCAweDk4MGNmNDJhLCAweDliNmRmNDkxLCAweDllN2VkZDUzLCAweDA2OTE4NTQ4LCAweDU4Y2I3ZTA3LCAweDNiNzRlZjJlLA0KCQkgIDB4NTIyZmZmYjEsIDB4ZDI0NzA4Y2MsIDB4MWM3ZTI3Y2QsIDB4YTRlYjIxNWIsIDB4M2NmMWQyZTIsIDB4MTliNDdhMzgsIDB4NDI0Zjc2MTgsIDB4MzU4NTYwMzksDQoJCSAgMHg5ZDE3ZGVlNywgMHgyN2ViMzVlNiwgMHhjOWFmZjY3YiwgMHgzNmJhZjViOCwgMHgwOWM0NjdjZCwgMHhjMTg5MTBiMSwgMHhlMTFkYmY3YiwgMHgwNmNkMWFmOCwNCgkJICAweDcxNzBjNjA4LCAweDJkNWUzMzU0LCAweGQ0ZGU0OTVhLCAweDY0YzZkMDA2LCAweGJjYzBjNjJjLCAweDNkZDAwZGIzLCAweDcwOGY4ZjM0LCAweDc3ZDUxYjQyLA0KCQkgIDB4MjY0ZjYyMGYsIDB4MjRiOGQyYmYsIDB4MTVjMWI3OWUsIDB4NDZhNTI1NjQsIDB4ZjhkN2U1NGUsIDB4M2UzNzgxNjAsIDB4Nzg5NWNkYTUsIDB4ODU5YzE1YTUsDQoJCSAgMHhlNjQ1OTc4OCwgMHhjMzdiYzc1ZiwgMHhkYjA3YmEwYywgMHgwNjc2YTNhYiwgMHg3ZjIyOWIxZSwgMHgzMTg0MmU3YiwgMHgyNDI1OWZkNywgMHhmOGJlZjQ3MiwNCgkJICAweDgzNWZmY2I4LCAweDZkZjRjMWYyLCAweDk2ZjViMTk1LCAweGZkMGFmMGZjLCAweGIwZmUxMzRjLCAweGUyNTA2ZDNkLCAweDRmOWIxMmVhLCAweGYyMTVmMjI1LA0KCQkgIDB4YTIyMzczNmYsIDB4OWZiNGM0MjgsIDB4MjVkMDQ5NzksIDB4MzRjNzEzZjgsIDB4YzQ2MTgxODcsIDB4ZWE3YTZlOTgsIDB4N2NkMTZlZmMsIDB4MTQzNjg3NmMsDQoJCSAgMHhmMTU0NDEwNywgMHhiZWRlZWUxNCwgMHg1NmU5YWYyNywgMHhhMDRhYTQ0MSwgMHgzY2Y3Yzg5OSwgMHg5MmVjYmFlNiwgMHhkZDY3MDE2ZCwgMHgxNTE2ODJlYiwNCgkJICAweGE4NDJlZWRmLCAweGZkYmE2MGI0LCAweGYxOTA3Yjc1LCAweDIwZTMwMzBmLCAweDI0ZDhjMjllLCAweGUxMzk2NzNiLCAweGVmYTYzZmI4LCAweDcxODczMDU0LA0KCQkgIDB4YjZmMmNmM2IsIDB4OWYzMjY0NDIsIDB4Y2IxNWE0Y2MsIDB4YjAxYTQ1MDQsIDB4ZjFlNDdkOGQsIDB4ODQ0YTFiZTUsIDB4YmFlN2RmZGMsIDB4NDJjYmRhNzAsDQoJCSAgMHhjZDdkYWUwYSwgMHg1N2U4NWI3YSwgMHhkNTNmNWFmNiwgMHgyMGNmNGQ4YywgMHhjZWE0ZDQyOCwgMHg3OWQxMzBhNCwgMHgzNDg2ZWJmYiwgMHgzM2QzY2RkYywNCgkJICAweDc3ODUzYjUzLCAweDM3ZWZmY2I1LCAweGM1MDY4Nzc4LCAweGU1ODBiM2U2LCAweDRlNjhiOGY0LCAweGM1YzhiMzdlLCAweDBkODA5ZWEyLCAweDM5OGZlYjdjLA0KCQkgIDB4MTMyYTRmOTQsIDB4NDNiNzk1MGUsIDB4MmZlZTdkMWMsIDB4MjIzNjEzYmQsIDB4ZGQwNmNhYTIsIDB4MzdkZjkzMmIsIDB4YzQyNDgyODksIDB4YWNmM2ViYzMsDQoJCSAgMHg1NzE1ZjZiNywgMHhlZjM0NzhkZCwgMHhmMjY3NjE2ZiwgMHhjMTQ4Y2JlNCwgMHg5MDUyODE1ZSwgMHg1ZTQxMGZhYiwgMHhiNDhhMjQ2NSwgMHgyZWRhN2ZhNCwNCgkJICAweGU4N2I0MGU0LCAweGU5OGVhMDg0LCAweDU4ODllOWUxLCAweGVmZDM5MGZjLCAweGRkMDdkMzViLCAweGRiNDg1Njk0LCAweDM4ZDdlNWIyLCAweDU3NzIwMTAxLA0KCQkgIDB4NzMwZWRlYmMsIDB4NWI2NDMxMTMsIDB4OTQ5MTdlNGYsIDB4NTAzYzJmYmEsIDB4NjQ2ZjEyODIsIDB4NzUyM2QyNGEsIDB4ZTA3Nzk2OTUsIDB4ZjljMTdhOGYsDQoJCSAgMHg3YTViMjEyMSwgMHhkMTg3Yjg5NiwgMHgyOTI2M2E0ZCwgMHhiYTUxMGNkZiwgMHg4MWY0N2M5ZiwgMHhhZDExNjNlZCwgMHhlYTdiNTk2NSwgMHgxYTAwNzI2ZSwNCgkJICAweDExNDAzMDkyLCAweDAwZGE2ZDc3LCAweDRhMGNkZDYxLCAweGFkMWY0NjAzLCAweDYwNWJkZmIwLCAweDllZWRjMzY0LCAweDIyZWJlNmE4LCAweGNlZTdkMjhhLA0KCQkgIDB4YTBlNzM2YTAsIDB4NTU2NGE2YjksIDB4MTA4NTMyMDksIDB4YzdlYjhmMzcsIDB4MmRlNzA1Y2EsIDB4ODk1MTU3MGYsIDB4ZGYwOTgyMmIsIDB4YmQ2OTFhNmMsDQoJCSAgMHhhYTEyZTRmMiwgMHg4NzQ1MWMwZiwgMHhlMGY2YTI3YSwgMHgzYWRhNDgxOSwgMHg0Y2YxNzY0ZiwgMHgwZDc3MWMyYiwgMHg2N2NkYjE1NiwgMHgzNTBkODM4NCwNCgkJICAweDU5MzhmYTBmLCAweDQyMzk5ZWYzLCAweDM2OTk3YjA3LCAweDBlODQwOTNkLCAweDRhYTkzZTYxLCAweDgzNjBkODdiLCAweDFmYTk4YjBjLCAweDExNDkzODJjLA0KCQkgIDB4ZTk3NjI1YTUsIDB4MDYxNGQxYjcsIDB4MGUyNTI0NGIsIDB4MGM3NjgzNDcsIDB4NTg5ZThkODIsIDB4MGQyMDU5ZDEsIDB4YTQ2NmJiMWUsIDB4ZjhkYTBhODIsDQoJCSAgMHgwNGYxOTEzMCwgMHhiYTZlNGVjMCwgMHg5OTI2NTE2NCwgMHgxZWU3MjMwZCwgMHg1MGIyYWQ4MCwgMHhlYWVlNjgwMSwgMHg4ZGIyYTI4MywgMHhlYThiZjU5ZSk7DQoNCn07DQoNCi8vUGF1bCBUZXJvLCBKdWx5IDIwMDENCi8vaHR0cDovL3d3dy50ZXJvLmNvLnVrL2Rlcy8NCi8vDQovL09wdGltaXNlZCBmb3IgcGVyZm9ybWFuY2Ugd2l0aCBsYXJnZSBibG9ja3MgYnkgTWljaGFlbCBIYXl3b3J0aCwgTm92ZW1iZXIgMjAwMQ0KLy9odHRwOi8vd3d3Lm5ldGRlYWxpbmcuY29tDQovLw0KLy8gTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIDQoNCi8vVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiIEFORA0KLy9BTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUNCi8vSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UNCi8vQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUNCi8vRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwNCi8vREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMNCi8vT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pDQovL0hPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUDQovL0xJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkNCi8vT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRg0KLy9TVUNIIERBTUFHRS4NCg0KLy9kZXMNCi8vdGhpcyB0YWtlcyB0aGUga2V5LCB0aGUgbWVzc2FnZSwgYW5kIHdoZXRoZXIgdG8gZW5jcnlwdCBvciBkZWNyeXB0DQoNCi8vIGFkZGVkIGJ5IFJlY3VyaXR5IExhYnMNCmZ1bmN0aW9uIGRlc2VkZShibG9jayxrZXkpIHsNCgl2YXIga2V5MSA9IGtleS5zdWJzdHJpbmcoMCw4KTsNCgl2YXIga2V5MiA9IGtleS5zdWJzdHJpbmcoOCwxNik7DQoJdmFyIGtleTMgPSBrZXkuc3Vic3RyaW5nKDE2LDI0KTsNCglyZXR1cm4gdXRpbC5zdHIyYmluKGRlcyhkZXNfY3JlYXRlS2V5cyhrZXkzKSxkZXMoZGVzX2NyZWF0ZUtleXMoa2V5MiksZGVzKGRlc19jcmVhdGVLZXlzKGtleTEpLHV0aWwuYmluMnN0cihibG9jayksIHRydWUsIDAsbnVsbCxudWxsKSwgZmFsc2UsIDAsbnVsbCxudWxsKSwgdHJ1ZSwgMCxudWxsLG51bGwpKTsNCn0NCg0KDQpmdW5jdGlvbiBkZXMgKGtleXMsIG1lc3NhZ2UsIGVuY3J5cHQsIG1vZGUsIGl2LCBwYWRkaW5nKSB7DQogIC8vZGVjbGFyaW5nIHRoaXMgbG9jYWxseSBzcGVlZHMgdGhpbmdzIHVwIGEgYml0DQogIHZhciBzcGZ1bmN0aW9uMSA9IG5ldyBBcnJheSAoMHgxMDEwNDAwLDAsMHgxMDAwMCwweDEwMTA0MDQsMHgxMDEwMDA0LDB4MTA0MDQsMHg0LDB4MTAwMDAsMHg0MDAsMHgxMDEwNDAwLDB4MTAxMDQwNCwweDQwMCwweDEwMDA0MDQsMHgxMDEwMDA0LDB4MTAwMDAwMCwweDQsMHg0MDQsMHgxMDAwNDAwLDB4MTAwMDQwMCwweDEwNDAwLDB4MTA0MDAsMHgxMDEwMDAwLDB4MTAxMDAwMCwweDEwMDA0MDQsMHgxMDAwNCwweDEwMDAwMDQsMHgxMDAwMDA0LDB4MTAwMDQsMCwweDQwNCwweDEwNDA0LDB4MTAwMDAwMCwweDEwMDAwLDB4MTAxMDQwNCwweDQsMHgxMDEwMDAwLDB4MTAxMDQwMCwweDEwMDAwMDAsMHgxMDAwMDAwLDB4NDAwLDB4MTAxMDAwNCwweDEwMDAwLDB4MTA0MDAsMHgxMDAwMDA0LDB4NDAwLDB4NCwweDEwMDA0MDQsMHgxMDQwNCwweDEwMTA0MDQsMHgxMDAwNCwweDEwMTAwMDAsMHgxMDAwNDA0LDB4MTAwMDAwNCwweDQwNCwweDEwNDA0LDB4MTAxMDQwMCwweDQwNCwweDEwMDA0MDAsMHgxMDAwNDAwLDAsMHgxMDAwNCwweDEwNDAwLDAsMHgxMDEwMDA0KTsNCiAgdmFyIHNwZnVuY3Rpb24yID0gbmV3IEFycmF5ICgtMHg3ZmVmN2ZlMCwtMHg3ZmZmODAwMCwweDgwMDAsMHgxMDgwMjAsMHgxMDAwMDAsMHgyMCwtMHg3ZmVmZmZlMCwtMHg3ZmZmN2ZlMCwtMHg3ZmZmZmZlMCwtMHg3ZmVmN2ZlMCwtMHg3ZmVmODAwMCwtMHg4MDAwMDAwMCwtMHg3ZmZmODAwMCwweDEwMDAwMCwweDIwLC0weDdmZWZmZmUwLDB4MTA4MDAwLDB4MTAwMDIwLC0weDdmZmY3ZmUwLDAsLTB4ODAwMDAwMDAsMHg4MDAwLDB4MTA4MDIwLC0weDdmZjAwMDAwLDB4MTAwMDIwLC0weDdmZmZmZmUwLDAsMHgxMDgwMDAsMHg4MDIwLC0weDdmZWY4MDAwLC0weDdmZjAwMDAwLDB4ODAyMCwwLDB4MTA4MDIwLC0weDdmZWZmZmUwLDB4MTAwMDAwLC0weDdmZmY3ZmUwLC0weDdmZjAwMDAwLC0weDdmZWY4MDAwLDB4ODAwMCwtMHg3ZmYwMDAwMCwtMHg3ZmZmODAwMCwweDIwLC0weDdmZWY3ZmUwLDB4MTA4MDIwLDB4MjAsMHg4MDAwLC0weDgwMDAwMDAwLDB4ODAyMCwtMHg3ZmVmODAwMCwweDEwMDAwMCwtMHg3ZmZmZmZlMCwweDEwMDAyMCwtMHg3ZmZmN2ZlMCwtMHg3ZmZmZmZlMCwweDEwMDAyMCwweDEwODAwMCwwLC0weDdmZmY4MDAwLDB4ODAyMCwtMHg4MDAwMDAwMCwtMHg3ZmVmZmZlMCwtMHg3ZmVmN2ZlMCwweDEwODAwMCk7DQogIHZhciBzcGZ1bmN0aW9uMyA9IG5ldyBBcnJheSAoMHgyMDgsMHg4MDIwMjAwLDAsMHg4MDIwMDA4LDB4ODAwMDIwMCwwLDB4MjAyMDgsMHg4MDAwMjAwLDB4MjAwMDgsMHg4MDAwMDA4LDB4ODAwMDAwOCwweDIwMDAwLDB4ODAyMDIwOCwweDIwMDA4LDB4ODAyMDAwMCwweDIwOCwweDgwMDAwMDAsMHg4LDB4ODAyMDIwMCwweDIwMCwweDIwMjAwLDB4ODAyMDAwMCwweDgwMjAwMDgsMHgyMDIwOCwweDgwMDAyMDgsMHgyMDIwMCwweDIwMDAwLDB4ODAwMDIwOCwweDgsMHg4MDIwMjA4LDB4MjAwLDB4ODAwMDAwMCwweDgwMjAyMDAsMHg4MDAwMDAwLDB4MjAwMDgsMHgyMDgsMHgyMDAwMCwweDgwMjAyMDAsMHg4MDAwMjAwLDAsMHgyMDAsMHgyMDAwOCwweDgwMjAyMDgsMHg4MDAwMjAwLDB4ODAwMDAwOCwweDIwMCwwLDB4ODAyMDAwOCwweDgwMDAyMDgsMHgyMDAwMCwweDgwMDAwMDAsMHg4MDIwMjA4LDB4OCwweDIwMjA4LDB4MjAyMDAsMHg4MDAwMDA4LDB4ODAyMDAwMCwweDgwMDAyMDgsMHgyMDgsMHg4MDIwMDAwLDB4MjAyMDgsMHg4LDB4ODAyMDAwOCwweDIwMjAwKTsNCiAgdmFyIHNwZnVuY3Rpb240ID0gbmV3IEFycmF5ICgweDgwMjAwMSwweDIwODEsMHgyMDgxLDB4ODAsMHg4MDIwODAsMHg4MDAwODEsMHg4MDAwMDEsMHgyMDAxLDAsMHg4MDIwMDAsMHg4MDIwMDAsMHg4MDIwODEsMHg4MSwwLDB4ODAwMDgwLDB4ODAwMDAxLDB4MSwweDIwMDAsMHg4MDAwMDAsMHg4MDIwMDEsMHg4MCwweDgwMDAwMCwweDIwMDEsMHgyMDgwLDB4ODAwMDgxLDB4MSwweDIwODAsMHg4MDAwODAsMHgyMDAwLDB4ODAyMDgwLDB4ODAyMDgxLDB4ODEsMHg4MDAwODAsMHg4MDAwMDEsMHg4MDIwMDAsMHg4MDIwODEsMHg4MSwwLDAsMHg4MDIwMDAsMHgyMDgwLDB4ODAwMDgwLDB4ODAwMDgxLDB4MSwweDgwMjAwMSwweDIwODEsMHgyMDgxLDB4ODAsMHg4MDIwODEsMHg4MSwweDEsMHgyMDAwLDB4ODAwMDAxLDB4MjAwMSwweDgwMjA4MCwweDgwMDA4MSwweDIwMDEsMHgyMDgwLDB4ODAwMDAwLDB4ODAyMDAxLDB4ODAsMHg4MDAwMDAsMHgyMDAwLDB4ODAyMDgwKTsNCiAgdmFyIHNwZnVuY3Rpb241ID0gbmV3IEFycmF5ICgweDEwMCwweDIwODAxMDAsMHgyMDgwMDAwLDB4NDIwMDAxMDAsMHg4MDAwMCwweDEwMCwweDQwMDAwMDAwLDB4MjA4MDAwMCwweDQwMDgwMTAwLDB4ODAwMDAsMHgyMDAwMTAwLDB4NDAwODAxMDAsMHg0MjAwMDEwMCwweDQyMDgwMDAwLDB4ODAxMDAsMHg0MDAwMDAwMCwweDIwMDAwMDAsMHg0MDA4MDAwMCwweDQwMDgwMDAwLDAsMHg0MDAwMDEwMCwweDQyMDgwMTAwLDB4NDIwODAxMDAsMHgyMDAwMTAwLDB4NDIwODAwMDAsMHg0MDAwMDEwMCwwLDB4NDIwMDAwMDAsMHgyMDgwMTAwLDB4MjAwMDAwMCwweDQyMDAwMDAwLDB4ODAxMDAsMHg4MDAwMCwweDQyMDAwMTAwLDB4MTAwLDB4MjAwMDAwMCwweDQwMDAwMDAwLDB4MjA4MDAwMCwweDQyMDAwMTAwLDB4NDAwODAxMDAsMHgyMDAwMTAwLDB4NDAwMDAwMDAsMHg0MjA4MDAwMCwweDIwODAxMDAsMHg0MDA4MDEwMCwweDEwMCwweDIwMDAwMDAsMHg0MjA4MDAwMCwweDQyMDgwMTAwLDB4ODAxMDAsMHg0MjAwMDAwMCwweDQyMDgwMTAwLDB4MjA4MDAwMCwwLDB4NDAwODAwMDAsMHg0MjAwMDAwMCwweDgwMTAwLDB4MjAwMDEwMCwweDQwMDAwMTAwLDB4ODAwMDAsMCwweDQwMDgwMDAwLDB4MjA4MDEwMCwweDQwMDAwMTAwKTsNCiAgdmFyIHNwZnVuY3Rpb242ID0gbmV3IEFycmF5ICgweDIwMDAwMDEwLDB4MjA0MDAwMDAsMHg0MDAwLDB4MjA0MDQwMTAsMHgyMDQwMDAwMCwweDEwLDB4MjA0MDQwMTAsMHg0MDAwMDAsMHgyMDAwNDAwMCwweDQwNDAxMCwweDQwMDAwMCwweDIwMDAwMDEwLDB4NDAwMDEwLDB4MjAwMDQwMDAsMHgyMDAwMDAwMCwweDQwMTAsMCwweDQwMDAxMCwweDIwMDA0MDEwLDB4NDAwMCwweDQwNDAwMCwweDIwMDA0MDEwLDB4MTAsMHgyMDQwMDAxMCwweDIwNDAwMDEwLDAsMHg0MDQwMTAsMHgyMDQwNDAwMCwweDQwMTAsMHg0MDQwMDAsMHgyMDQwNDAwMCwweDIwMDAwMDAwLDB4MjAwMDQwMDAsMHgxMCwweDIwNDAwMDEwLDB4NDA0MDAwLDB4MjA0MDQwMTAsMHg0MDAwMDAsMHg0MDEwLDB4MjAwMDAwMTAsMHg0MDAwMDAsMHgyMDAwNDAwMCwweDIwMDAwMDAwLDB4NDAxMCwweDIwMDAwMDEwLDB4MjA0MDQwMTAsMHg0MDQwMDAsMHgyMDQwMDAwMCwweDQwNDAxMCwweDIwNDA0MDAwLDAsMHgyMDQwMDAxMCwweDEwLDB4NDAwMCwweDIwNDAwMDAwLDB4NDA0MDEwLDB4NDAwMCwweDQwMDAxMCwweDIwMDA0MDEwLDAsMHgyMDQwNDAwMCwweDIwMDAwMDAwLDB4NDAwMDEwLDB4MjAwMDQwMTApOw0KICB2YXIgc3BmdW5jdGlvbjcgPSBuZXcgQXJyYXkgKDB4MjAwMDAwLDB4NDIwMDAwMiwweDQwMDA4MDIsMCwweDgwMCwweDQwMDA4MDIsMHgyMDA4MDIsMHg0MjAwODAwLDB4NDIwMDgwMiwweDIwMDAwMCwwLDB4NDAwMDAwMiwweDIsMHg0MDAwMDAwLDB4NDIwMDAwMiwweDgwMiwweDQwMDA4MDAsMHgyMDA4MDIsMHgyMDAwMDIsMHg0MDAwODAwLDB4NDAwMDAwMiwweDQyMDAwMDAsMHg0MjAwODAwLDB4MjAwMDAyLDB4NDIwMDAwMCwweDgwMCwweDgwMiwweDQyMDA4MDIsMHgyMDA4MDAsMHgyLDB4NDAwMDAwMCwweDIwMDgwMCwweDQwMDAwMDAsMHgyMDA4MDAsMHgyMDAwMDAsMHg0MDAwODAyLDB4NDAwMDgwMiwweDQyMDAwMDIsMHg0MjAwMDAyLDB4MiwweDIwMDAwMiwweDQwMDAwMDAsMHg0MDAwODAwLDB4MjAwMDAwLDB4NDIwMDgwMCwweDgwMiwweDIwMDgwMiwweDQyMDA4MDAsMHg4MDIsMHg0MDAwMDAyLDB4NDIwMDgwMiwweDQyMDAwMDAsMHgyMDA4MDAsMCwweDIsMHg0MjAwODAyLDAsMHgyMDA4MDIsMHg0MjAwMDAwLDB4ODAwLDB4NDAwMDAwMiwweDQwMDA4MDAsMHg4MDAsMHgyMDAwMDIpOw0KICB2YXIgc3BmdW5jdGlvbjggPSBuZXcgQXJyYXkgKDB4MTAwMDEwNDAsMHgxMDAwLDB4NDAwMDAsMHgxMDA0MTA0MCwweDEwMDAwMDAwLDB4MTAwMDEwNDAsMHg0MCwweDEwMDAwMDAwLDB4NDAwNDAsMHgxMDA0MDAwMCwweDEwMDQxMDQwLDB4NDEwMDAsMHgxMDA0MTAwMCwweDQxMDQwLDB4MTAwMCwweDQwLDB4MTAwNDAwMDAsMHgxMDAwMDA0MCwweDEwMDAxMDAwLDB4MTA0MCwweDQxMDAwLDB4NDAwNDAsMHgxMDA0MDA0MCwweDEwMDQxMDAwLDB4MTA0MCwwLDAsMHgxMDA0MDA0MCwweDEwMDAwMDQwLDB4MTAwMDEwMDAsMHg0MTA0MCwweDQwMDAwLDB4NDEwNDAsMHg0MDAwMCwweDEwMDQxMDAwLDB4MTAwMCwweDQwLDB4MTAwNDAwNDAsMHgxMDAwLDB4NDEwNDAsMHgxMDAwMTAwMCwweDQwLDB4MTAwMDAwNDAsMHgxMDA0MDAwMCwweDEwMDQwMDQwLDB4MTAwMDAwMDAsMHg0MDAwMCwweDEwMDAxMDQwLDAsMHgxMDA0MTA0MCwweDQwMDQwLDB4MTAwMDAwNDAsMHgxMDA0MDAwMCwweDEwMDAxMDAwLDB4MTAwMDEwNDAsMCwweDEwMDQxMDQwLDB4NDEwMDAsMHg0MTAwMCwweDEwNDAsMHgxMDQwLDB4NDAwNDAsMHgxMDAwMDAwMCwweDEwMDQxMDAwKTsNCg0KICAvL2NyZWF0ZSB0aGUgMTYgb3IgNDggc3Via2V5cyB3ZSB3aWxsIG5lZWQNCiAgdmFyIG09MCwgaSwgaiwgdGVtcCwgdGVtcDIsIHJpZ2h0MSwgcmlnaHQyLCBsZWZ0LCByaWdodCwgbG9vcGluZzsNCiAgdmFyIGNiY2xlZnQsIGNiY2xlZnQyLCBjYmNyaWdodCwgY2JjcmlnaHQyDQogIHZhciBlbmRsb29wLCBsb29waW5jOw0KICB2YXIgbGVuID0gbWVzc2FnZS5sZW5ndGg7DQogIHZhciBjaHVuayA9IDA7DQogIC8vc2V0IHVwIHRoZSBsb29wcyBmb3Igc2luZ2xlIGFuZCB0cmlwbGUgZGVzDQogIHZhciBpdGVyYXRpb25zID0ga2V5cy5sZW5ndGggPT0gMzIgPyAzIDogOTsgLy9zaW5nbGUgb3IgdHJpcGxlIGRlcw0KICBpZiAoaXRlcmF0aW9ucyA9PSAzKSB7bG9vcGluZyA9IGVuY3J5cHQgPyBuZXcgQXJyYXkgKDAsIDMyLCAyKSA6IG5ldyBBcnJheSAoMzAsIC0yLCAtMik7fQ0KICBlbHNlIHtsb29waW5nID0gZW5jcnlwdCA/IG5ldyBBcnJheSAoMCwgMzIsIDIsIDYyLCAzMCwgLTIsIDY0LCA5NiwgMikgOiBuZXcgQXJyYXkgKDk0LCA2MiwgLTIsIDMyLCA2NCwgMiwgMzAsIC0yLCAtMik7fQ0KDQogIC8vcGFkIHRoZSBtZXNzYWdlIGRlcGVuZGluZyBvbiB0aGUgcGFkZGluZyBwYXJhbWV0ZXINCiAgaWYgKHBhZGRpbmcgPT0gMikgbWVzc2FnZSArPSAiICAgICAgICAiOyAvL3BhZCB0aGUgbWVzc2FnZSB3aXRoIHNwYWNlcw0KICBlbHNlIGlmIChwYWRkaW5nID09IDEpIHt0ZW1wID0gOC0obGVuJTgpOyBtZXNzYWdlICs9IFN0cmluZy5mcm9tQ2hhckNvZGUgKHRlbXAsdGVtcCx0ZW1wLHRlbXAsdGVtcCx0ZW1wLHRlbXAsdGVtcCk7IGlmICh0ZW1wPT04KSBsZW4rPTg7fSAvL1BLQ1M3IHBhZGRpbmcNCiAgZWxzZSBpZiAoIXBhZGRpbmcpIG1lc3NhZ2UgKz0gIlwwXDBcMFwwXDBcMFwwXDAiOyAvL3BhZCB0aGUgbWVzc2FnZSBvdXQgd2l0aCBudWxsIGJ5dGVzDQoNCiAgLy9zdG9yZSB0aGUgcmVzdWx0IGhlcmUNCiAgcmVzdWx0ID0gIiI7DQogIHRlbXByZXN1bHQgPSAiIjsNCg0KICBpZiAobW9kZSA9PSAxKSB7IC8vQ0JDIG1vZGUNCiAgICBjYmNsZWZ0ID0gKGl2LmNoYXJDb2RlQXQobSsrKSA8PCAyNCkgfCAoaXYuY2hhckNvZGVBdChtKyspIDw8IDE2KSB8IChpdi5jaGFyQ29kZUF0KG0rKykgPDwgOCkgfCBpdi5jaGFyQ29kZUF0KG0rKyk7DQogICAgY2JjcmlnaHQgPSAoaXYuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChpdi5jaGFyQ29kZUF0KG0rKykgPDwgMTYpIHwgKGl2LmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8IGl2LmNoYXJDb2RlQXQobSsrKTsNCiAgICBtPTA7DQogIH0NCg0KICAvL2xvb3AgdGhyb3VnaCBlYWNoIDY0IGJpdCBjaHVuayBvZiB0aGUgbWVzc2FnZQ0KICB3aGlsZSAobSA8IGxlbikgew0KICAgIGxlZnQgPSAobWVzc2FnZS5jaGFyQ29kZUF0KG0rKykgPDwgMjQpIHwgKG1lc3NhZ2UuY2hhckNvZGVBdChtKyspIDw8IDE2KSB8IChtZXNzYWdlLmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8IG1lc3NhZ2UuY2hhckNvZGVBdChtKyspOw0KICAgIHJpZ2h0ID0gKG1lc3NhZ2UuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChtZXNzYWdlLmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAobWVzc2FnZS5jaGFyQ29kZUF0KG0rKykgPDwgOCkgfCBtZXNzYWdlLmNoYXJDb2RlQXQobSsrKTsNCg0KICAgIC8vZm9yIENpcGhlciBCbG9jayBDaGFpbmluZyBtb2RlLCB4b3IgdGhlIG1lc3NhZ2Ugd2l0aCB0aGUgcHJldmlvdXMgcmVzdWx0DQogICAgaWYgKG1vZGUgPT0gMSkge2lmIChlbmNyeXB0KSB7bGVmdCBePSBjYmNsZWZ0OyByaWdodCBePSBjYmNyaWdodDt9IGVsc2Uge2NiY2xlZnQyID0gY2JjbGVmdDsgY2JjcmlnaHQyID0gY2JjcmlnaHQ7IGNiY2xlZnQgPSBsZWZ0OyBjYmNyaWdodCA9IHJpZ2h0O319DQoNCiAgICAvL2ZpcnN0IGVhY2ggNjQgYnV0IGNodW5rIG9mIHRoZSBtZXNzYWdlIG11c3QgYmUgcGVybXV0ZWQgYWNjb3JkaW5nIHRvIElQDQogICAgdGVtcCA9ICgobGVmdCA+Pj4gNCkgXiByaWdodCkgJiAweDBmMGYwZjBmOyByaWdodCBePSB0ZW1wOyBsZWZ0IF49ICh0ZW1wIDw8IDQpOw0KICAgIHRlbXAgPSAoKGxlZnQgPj4+IDE2KSBeIHJpZ2h0KSAmIDB4MDAwMGZmZmY7IHJpZ2h0IF49IHRlbXA7IGxlZnQgXj0gKHRlbXAgPDwgMTYpOw0KICAgIHRlbXAgPSAoKHJpZ2h0ID4+PiAyKSBeIGxlZnQpICYgMHgzMzMzMzMzMzsgbGVmdCBePSB0ZW1wOyByaWdodCBePSAodGVtcCA8PCAyKTsNCiAgICB0ZW1wID0gKChyaWdodCA+Pj4gOCkgXiBsZWZ0KSAmIDB4MDBmZjAwZmY7IGxlZnQgXj0gdGVtcDsgcmlnaHQgXj0gKHRlbXAgPDwgOCk7DQogICAgdGVtcCA9ICgobGVmdCA+Pj4gMSkgXiByaWdodCkgJiAweDU1NTU1NTU1OyByaWdodCBePSB0ZW1wOyBsZWZ0IF49ICh0ZW1wIDw8IDEpOw0KDQogICAgbGVmdCA9ICgobGVmdCA8PCAxKSB8IChsZWZ0ID4+PiAzMSkpOyANCiAgICByaWdodCA9ICgocmlnaHQgPDwgMSkgfCAocmlnaHQgPj4+IDMxKSk7IA0KDQogICAgLy9kbyB0aGlzIGVpdGhlciAxIG9yIDMgdGltZXMgZm9yIGVhY2ggY2h1bmsgb2YgdGhlIG1lc3NhZ2UNCiAgICBmb3IgKGo9MDsgajxpdGVyYXRpb25zOyBqKz0zKSB7DQogICAgICBlbmRsb29wID0gbG9vcGluZ1tqKzFdOw0KICAgICAgbG9vcGluYyA9IGxvb3BpbmdbaisyXTsNCiAgICAgIC8vbm93IGdvIHRocm91Z2ggYW5kIHBlcmZvcm0gdGhlIGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbiAgDQogICAgICBmb3IgKGk9bG9vcGluZ1tqXTsgaSE9ZW5kbG9vcDsgaSs9bG9vcGluYykgeyAvL2ZvciBlZmZpY2llbmN5DQogICAgICAgIHJpZ2h0MSA9IHJpZ2h0IF4ga2V5c1tpXTsgDQogICAgICAgIHJpZ2h0MiA9ICgocmlnaHQgPj4+IDQpIHwgKHJpZ2h0IDw8IDI4KSkgXiBrZXlzW2krMV07DQogICAgICAgIC8vdGhlIHJlc3VsdCBpcyBhdHRhaW5lZCBieSBwYXNzaW5nIHRoZXNlIGJ5dGVzIHRocm91Z2ggdGhlIFMgc2VsZWN0aW9uIGZ1bmN0aW9ucw0KICAgICAgICB0ZW1wID0gbGVmdDsNCiAgICAgICAgbGVmdCA9IHJpZ2h0Ow0KICAgICAgICByaWdodCA9IHRlbXAgXiAoc3BmdW5jdGlvbjJbKHJpZ2h0MSA+Pj4gMjQpICYgMHgzZl0gfCBzcGZ1bmN0aW9uNFsocmlnaHQxID4+PiAxNikgJiAweDNmXQ0KICAgICAgICAgICAgICB8IHNwZnVuY3Rpb242WyhyaWdodDEgPj4+ICA4KSAmIDB4M2ZdIHwgc3BmdW5jdGlvbjhbcmlnaHQxICYgMHgzZl0NCiAgICAgICAgICAgICAgfCBzcGZ1bmN0aW9uMVsocmlnaHQyID4+PiAyNCkgJiAweDNmXSB8IHNwZnVuY3Rpb24zWyhyaWdodDIgPj4+IDE2KSAmIDB4M2ZdDQogICAgICAgICAgICAgIHwgc3BmdW5jdGlvbjVbKHJpZ2h0MiA+Pj4gIDgpICYgMHgzZl0gfCBzcGZ1bmN0aW9uN1tyaWdodDIgJiAweDNmXSk7DQogICAgICB9DQogICAgICB0ZW1wID0gbGVmdDsgbGVmdCA9IHJpZ2h0OyByaWdodCA9IHRlbXA7IC8vdW5yZXZlcnNlIGxlZnQgYW5kIHJpZ2h0DQogICAgfSAvL2ZvciBlaXRoZXIgMSBvciAzIGl0ZXJhdGlvbnMNCg0KICAgIC8vbW92ZSB0aGVuIGVhY2ggb25lIGJpdCB0byB0aGUgcmlnaHQNCiAgICBsZWZ0ID0gKChsZWZ0ID4+PiAxKSB8IChsZWZ0IDw8IDMxKSk7IA0KICAgIHJpZ2h0ID0gKChyaWdodCA+Pj4gMSkgfCAocmlnaHQgPDwgMzEpKTsgDQoNCiAgICAvL25vdyBwZXJmb3JtIElQLTEsIHdoaWNoIGlzIElQIGluIHRoZSBvcHBvc2l0ZSBkaXJlY3Rpb24NCiAgICB0ZW1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7IHJpZ2h0IF49IHRlbXA7IGxlZnQgXj0gKHRlbXAgPDwgMSk7DQogICAgdGVtcCA9ICgocmlnaHQgPj4+IDgpIF4gbGVmdCkgJiAweDAwZmYwMGZmOyBsZWZ0IF49IHRlbXA7IHJpZ2h0IF49ICh0ZW1wIDw8IDgpOw0KICAgIHRlbXAgPSAoKHJpZ2h0ID4+PiAyKSBeIGxlZnQpICYgMHgzMzMzMzMzMzsgbGVmdCBePSB0ZW1wOyByaWdodCBePSAodGVtcCA8PCAyKTsNCiAgICB0ZW1wID0gKChsZWZ0ID4+PiAxNikgXiByaWdodCkgJiAweDAwMDBmZmZmOyByaWdodCBePSB0ZW1wOyBsZWZ0IF49ICh0ZW1wIDw8IDE2KTsNCiAgICB0ZW1wID0gKChsZWZ0ID4+PiA0KSBeIHJpZ2h0KSAmIDB4MGYwZjBmMGY7IHJpZ2h0IF49IHRlbXA7IGxlZnQgXj0gKHRlbXAgPDwgNCk7DQoNCiAgICAvL2ZvciBDaXBoZXIgQmxvY2sgQ2hhaW5pbmcgbW9kZSwgeG9yIHRoZSBtZXNzYWdlIHdpdGggdGhlIHByZXZpb3VzIHJlc3VsdA0KICAgIGlmIChtb2RlID09IDEpIHtpZiAoZW5jcnlwdCkge2NiY2xlZnQgPSBsZWZ0OyBjYmNyaWdodCA9IHJpZ2h0O30gZWxzZSB7bGVmdCBePSBjYmNsZWZ0MjsgcmlnaHQgXj0gY2JjcmlnaHQyO319DQogICAgdGVtcHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlICgobGVmdD4+PjI0KSwgKChsZWZ0Pj4+MTYpICYgMHhmZiksICgobGVmdD4+PjgpICYgMHhmZiksIChsZWZ0ICYgMHhmZiksIChyaWdodD4+PjI0KSwgKChyaWdodD4+PjE2KSAmIDB4ZmYpLCAoKHJpZ2h0Pj4+OCkgJiAweGZmKSwgKHJpZ2h0ICYgMHhmZikpOw0KDQogICAgY2h1bmsgKz0gODsNCiAgICBpZiAoY2h1bmsgPT0gNTEyKSB7cmVzdWx0ICs9IHRlbXByZXN1bHQ7IHRlbXByZXN1bHQgPSAiIjsgY2h1bmsgPSAwO30NCiAgfSAvL2ZvciBldmVyeSA4IGNoYXJhY3RlcnMsIG9yIDY0IGJpdHMgaW4gdGhlIG1lc3NhZ2UNCg0KICAvL3JldHVybiB0aGUgcmVzdWx0IGFzIGFuIGFycmF5DQogIHJlc3VsdCArPSB0ZW1wcmVzdWx0Ow0KICByZXN1bHQgPSByZXN1bHQucmVwbGFjZSgvXDAqJC9nLCAiIik7DQogIHJldHVybiByZXN1bHQ7DQp9IC8vZW5kIG9mIGRlcw0KDQoNCg0KLy9kZXNfY3JlYXRlS2V5cw0KLy90aGlzIHRha2VzIGFzIGlucHV0IGEgNjQgYml0IGtleSAoZXZlbiB0aG91Z2ggb25seSA1NiBiaXRzIGFyZSB1c2VkKQ0KLy9hcyBhbiBhcnJheSBvZiAyIGludGVnZXJzLCBhbmQgcmV0dXJucyAxNiA0OCBiaXQga2V5cw0KZnVuY3Rpb24gZGVzX2NyZWF0ZUtleXMgKGtleSkgew0KICAvL2RlY2xhcmluZyB0aGlzIGxvY2FsbHkgc3BlZWRzIHRoaW5ncyB1cCBhIGJpdA0KICBwYzJieXRlczAgID0gbmV3IEFycmF5ICgwLDB4NCwweDIwMDAwMDAwLDB4MjAwMDAwMDQsMHgxMDAwMCwweDEwMDA0LDB4MjAwMTAwMDAsMHgyMDAxMDAwNCwweDIwMCwweDIwNCwweDIwMDAwMjAwLDB4MjAwMDAyMDQsMHgxMDIwMCwweDEwMjA0LDB4MjAwMTAyMDAsMHgyMDAxMDIwNCk7DQogIHBjMmJ5dGVzMSAgPSBuZXcgQXJyYXkgKDAsMHgxLDB4MTAwMDAwLDB4MTAwMDAxLDB4NDAwMDAwMCwweDQwMDAwMDEsMHg0MTAwMDAwLDB4NDEwMDAwMSwweDEwMCwweDEwMSwweDEwMDEwMCwweDEwMDEwMSwweDQwMDAxMDAsMHg0MDAwMTAxLDB4NDEwMDEwMCwweDQxMDAxMDEpOw0KICBwYzJieXRlczIgID0gbmV3IEFycmF5ICgwLDB4OCwweDgwMCwweDgwOCwweDEwMDAwMDAsMHgxMDAwMDA4LDB4MTAwMDgwMCwweDEwMDA4MDgsMCwweDgsMHg4MDAsMHg4MDgsMHgxMDAwMDAwLDB4MTAwMDAwOCwweDEwMDA4MDAsMHgxMDAwODA4KTsNCiAgcGMyYnl0ZXMzICA9IG5ldyBBcnJheSAoMCwweDIwMDAwMCwweDgwMDAwMDAsMHg4MjAwMDAwLDB4MjAwMCwweDIwMjAwMCwweDgwMDIwMDAsMHg4MjAyMDAwLDB4MjAwMDAsMHgyMjAwMDAsMHg4MDIwMDAwLDB4ODIyMDAwMCwweDIyMDAwLDB4MjIyMDAwLDB4ODAyMjAwMCwweDgyMjIwMDApOw0KICBwYzJieXRlczQgID0gbmV3IEFycmF5ICgwLDB4NDAwMDAsMHgxMCwweDQwMDEwLDAsMHg0MDAwMCwweDEwLDB4NDAwMTAsMHgxMDAwLDB4NDEwMDAsMHgxMDEwLDB4NDEwMTAsMHgxMDAwLDB4NDEwMDAsMHgxMDEwLDB4NDEwMTApOw0KICBwYzJieXRlczUgID0gbmV3IEFycmF5ICgwLDB4NDAwLDB4MjAsMHg0MjAsMCwweDQwMCwweDIwLDB4NDIwLDB4MjAwMDAwMCwweDIwMDA0MDAsMHgyMDAwMDIwLDB4MjAwMDQyMCwweDIwMDAwMDAsMHgyMDAwNDAwLDB4MjAwMDAyMCwweDIwMDA0MjApOw0KICBwYzJieXRlczYgID0gbmV3IEFycmF5ICgwLDB4MTAwMDAwMDAsMHg4MDAwMCwweDEwMDgwMDAwLDB4MiwweDEwMDAwMDAyLDB4ODAwMDIsMHgxMDA4MDAwMiwwLDB4MTAwMDAwMDAsMHg4MDAwMCwweDEwMDgwMDAwLDB4MiwweDEwMDAwMDAyLDB4ODAwMDIsMHgxMDA4MDAwMik7DQogIHBjMmJ5dGVzNyAgPSBuZXcgQXJyYXkgKDAsMHgxMDAwMCwweDgwMCwweDEwODAwLDB4MjAwMDAwMDAsMHgyMDAxMDAwMCwweDIwMDAwODAwLDB4MjAwMTA4MDAsMHgyMDAwMCwweDMwMDAwLDB4MjA4MDAsMHgzMDgwMCwweDIwMDIwMDAwLDB4MjAwMzAwMDAsMHgyMDAyMDgwMCwweDIwMDMwODAwKTsNCiAgcGMyYnl0ZXM4ICA9IG5ldyBBcnJheSAoMCwweDQwMDAwLDAsMHg0MDAwMCwweDIsMHg0MDAwMiwweDIsMHg0MDAwMiwweDIwMDAwMDAsMHgyMDQwMDAwLDB4MjAwMDAwMCwweDIwNDAwMDAsMHgyMDAwMDAyLDB4MjA0MDAwMiwweDIwMDAwMDIsMHgyMDQwMDAyKTsNCiAgcGMyYnl0ZXM5ICA9IG5ldyBBcnJheSAoMCwweDEwMDAwMDAwLDB4OCwweDEwMDAwMDA4LDAsMHgxMDAwMDAwMCwweDgsMHgxMDAwMDAwOCwweDQwMCwweDEwMDAwNDAwLDB4NDA4LDB4MTAwMDA0MDgsMHg0MDAsMHgxMDAwMDQwMCwweDQwOCwweDEwMDAwNDA4KTsNCiAgcGMyYnl0ZXMxMCA9IG5ldyBBcnJheSAoMCwweDIwLDAsMHgyMCwweDEwMDAwMCwweDEwMDAyMCwweDEwMDAwMCwweDEwMDAyMCwweDIwMDAsMHgyMDIwLDB4MjAwMCwweDIwMjAsMHgxMDIwMDAsMHgxMDIwMjAsMHgxMDIwMDAsMHgxMDIwMjApOw0KICBwYzJieXRlczExID0gbmV3IEFycmF5ICgwLDB4MTAwMDAwMCwweDIwMCwweDEwMDAyMDAsMHgyMDAwMDAsMHgxMjAwMDAwLDB4MjAwMjAwLDB4MTIwMDIwMCwweDQwMDAwMDAsMHg1MDAwMDAwLDB4NDAwMDIwMCwweDUwMDAyMDAsMHg0MjAwMDAwLDB4NTIwMDAwMCwweDQyMDAyMDAsMHg1MjAwMjAwKTsNCiAgcGMyYnl0ZXMxMiA9IG5ldyBBcnJheSAoMCwweDEwMDAsMHg4MDAwMDAwLDB4ODAwMTAwMCwweDgwMDAwLDB4ODEwMDAsMHg4MDgwMDAwLDB4ODA4MTAwMCwweDEwLDB4MTAxMCwweDgwMDAwMTAsMHg4MDAxMDEwLDB4ODAwMTAsMHg4MTAxMCwweDgwODAwMTAsMHg4MDgxMDEwKTsNCiAgcGMyYnl0ZXMxMyA9IG5ldyBBcnJheSAoMCwweDQsMHgxMDAsMHgxMDQsMCwweDQsMHgxMDAsMHgxMDQsMHgxLDB4NSwweDEwMSwweDEwNSwweDEsMHg1LDB4MTAxLDB4MTA1KTsNCg0KICAvL2hvdyBtYW55IGl0ZXJhdGlvbnMgKDEgZm9yIGRlcywgMyBmb3IgdHJpcGxlIGRlcykNCiAgdmFyIGl0ZXJhdGlvbnMgPSBrZXkubGVuZ3RoID4gOCA/IDMgOiAxOyAvL2NoYW5nZWQgYnkgUGF1bCAxNi82LzIwMDcgdG8gdXNlIFRyaXBsZSBERVMgZm9yIDkrIGJ5dGUga2V5cw0KICAvL3N0b3JlcyB0aGUgcmV0dXJuIGtleXMNCiAgdmFyIGtleXMgPSBuZXcgQXJyYXkgKDMyICogaXRlcmF0aW9ucyk7DQogIC8vbm93IGRlZmluZSB0aGUgbGVmdCBzaGlmdHMgd2hpY2ggbmVlZCB0byBiZSBkb25lDQogIHZhciBzaGlmdHMgPSBuZXcgQXJyYXkgKDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDApOw0KICAvL290aGVyIHZhcmlhYmxlcw0KICB2YXIgbGVmdHRlbXAsIHJpZ2h0dGVtcCwgbT0wLCBuPTAsIHRlbXA7DQoNCiAgZm9yICh2YXIgaj0wOyBqPGl0ZXJhdGlvbnM7IGorKykgeyAvL2VpdGhlciAxIG9yIDMgaXRlcmF0aW9ucw0KICAgIGxlZnQgPSAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCAyNCkgfCAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8IGtleS5jaGFyQ29kZUF0KG0rKyk7DQogICAgcmlnaHQgPSAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCAyNCkgfCAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8IGtleS5jaGFyQ29kZUF0KG0rKyk7DQoNCiAgICB0ZW1wID0gKChsZWZ0ID4+PiA0KSBeIHJpZ2h0KSAmIDB4MGYwZjBmMGY7IHJpZ2h0IF49IHRlbXA7IGxlZnQgXj0gKHRlbXAgPDwgNCk7DQogICAgdGVtcCA9ICgocmlnaHQgPj4+IC0xNikgXiBsZWZ0KSAmIDB4MDAwMGZmZmY7IGxlZnQgXj0gdGVtcDsgcmlnaHQgXj0gKHRlbXAgPDwgLTE2KTsNCiAgICB0ZW1wID0gKChsZWZ0ID4+PiAyKSBeIHJpZ2h0KSAmIDB4MzMzMzMzMzM7IHJpZ2h0IF49IHRlbXA7IGxlZnQgXj0gKHRlbXAgPDwgMik7DQogICAgdGVtcCA9ICgocmlnaHQgPj4+IC0xNikgXiBsZWZ0KSAmIDB4MDAwMGZmZmY7IGxlZnQgXj0gdGVtcDsgcmlnaHQgXj0gKHRlbXAgPDwgLTE2KTsNCiAgICB0ZW1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7IHJpZ2h0IF49IHRlbXA7IGxlZnQgXj0gKHRlbXAgPDwgMSk7DQogICAgdGVtcCA9ICgocmlnaHQgPj4+IDgpIF4gbGVmdCkgJiAweDAwZmYwMGZmOyBsZWZ0IF49IHRlbXA7IHJpZ2h0IF49ICh0ZW1wIDw8IDgpOw0KICAgIHRlbXAgPSAoKGxlZnQgPj4+IDEpIF4gcmlnaHQpICYgMHg1NTU1NTU1NTsgcmlnaHQgXj0gdGVtcDsgbGVmdCBePSAodGVtcCA8PCAxKTsNCg0KICAgIC8vdGhlIHJpZ2h0IHNpZGUgbmVlZHMgdG8gYmUgc2hpZnRlZCBhbmQgdG8gZ2V0IHRoZSBsYXN0IGZvdXIgYml0cyBvZiB0aGUgbGVmdCBzaWRlDQogICAgdGVtcCA9IChsZWZ0IDw8IDgpIHwgKChyaWdodCA+Pj4gMjApICYgMHgwMDAwMDBmMCk7DQogICAgLy9sZWZ0IG5lZWRzIHRvIGJlIHB1dCB1cHNpZGUgZG93bg0KICAgIGxlZnQgPSAocmlnaHQgPDwgMjQpIHwgKChyaWdodCA8PCA4KSAmIDB4ZmYwMDAwKSB8ICgocmlnaHQgPj4+IDgpICYgMHhmZjAwKSB8ICgocmlnaHQgPj4+IDI0KSAmIDB4ZjApOw0KICAgIHJpZ2h0ID0gdGVtcDsNCg0KICAgIC8vbm93IGdvIHRocm91Z2ggYW5kIHBlcmZvcm0gdGhlc2Ugc2hpZnRzIG9uIHRoZSBsZWZ0IGFuZCByaWdodCBrZXlzDQogICAgZm9yIChpPTA7IGkgPCBzaGlmdHMubGVuZ3RoOyBpKyspIHsNCiAgICAgIC8vc2hpZnQgdGhlIGtleXMgZWl0aGVyIG9uZSBvciB0d28gYml0cyB0byB0aGUgbGVmdA0KICAgICAgaWYgKHNoaWZ0c1tpXSkge2xlZnQgPSAobGVmdCA8PCAyKSB8IChsZWZ0ID4+PiAyNik7IHJpZ2h0ID0gKHJpZ2h0IDw8IDIpIHwgKHJpZ2h0ID4+PiAyNik7fQ0KICAgICAgZWxzZSB7bGVmdCA9IChsZWZ0IDw8IDEpIHwgKGxlZnQgPj4+IDI3KTsgcmlnaHQgPSAocmlnaHQgPDwgMSkgfCAocmlnaHQgPj4+IDI3KTt9DQogICAgICBsZWZ0ICY9IC0weGY7IHJpZ2h0ICY9IC0weGY7DQoNCiAgICAgIC8vbm93IGFwcGx5IFBDLTIsIGluIHN1Y2ggYSB3YXkgdGhhdCBFIGlzIGVhc2llciB3aGVuIGVuY3J5cHRpbmcgb3IgZGVjcnlwdGluZw0KICAgICAgLy90aGlzIGNvbnZlcnNpb24gd2lsbCBsb29rIGxpa2UgUEMtMiBleGNlcHQgb25seSB0aGUgbGFzdCA2IGJpdHMgb2YgZWFjaCBieXRlIGFyZSB1c2VkDQogICAgICAvL3JhdGhlciB0aGFuIDQ4IGNvbnNlY3V0aXZlIGJpdHMgYW5kIHRoZSBvcmRlciBvZiBsaW5lcyB3aWxsIGJlIGFjY29yZGluZyB0byANCiAgICAgIC8vaG93IHRoZSBTIHNlbGVjdGlvbiBmdW5jdGlvbnMgd2lsbCBiZSBhcHBsaWVkOiBTMiwgUzQsIFM2LCBTOCwgUzEsIFMzLCBTNSwgUzcNCiAgICAgIGxlZnR0ZW1wID0gcGMyYnl0ZXMwW2xlZnQgPj4+IDI4XSB8IHBjMmJ5dGVzMVsobGVmdCA+Pj4gMjQpICYgMHhmXQ0KICAgICAgICAgICAgICB8IHBjMmJ5dGVzMlsobGVmdCA+Pj4gMjApICYgMHhmXSB8IHBjMmJ5dGVzM1sobGVmdCA+Pj4gMTYpICYgMHhmXQ0KICAgICAgICAgICAgICB8IHBjMmJ5dGVzNFsobGVmdCA+Pj4gMTIpICYgMHhmXSB8IHBjMmJ5dGVzNVsobGVmdCA+Pj4gOCkgJiAweGZdDQogICAgICAgICAgICAgIHwgcGMyYnl0ZXM2WyhsZWZ0ID4+PiA0KSAmIDB4Zl07DQogICAgICByaWdodHRlbXAgPSBwYzJieXRlczdbcmlnaHQgPj4+IDI4XSB8IHBjMmJ5dGVzOFsocmlnaHQgPj4+IDI0KSAmIDB4Zl0NCiAgICAgICAgICAgICAgICB8IHBjMmJ5dGVzOVsocmlnaHQgPj4+IDIwKSAmIDB4Zl0gfCBwYzJieXRlczEwWyhyaWdodCA+Pj4gMTYpICYgMHhmXQ0KICAgICAgICAgICAgICAgIHwgcGMyYnl0ZXMxMVsocmlnaHQgPj4+IDEyKSAmIDB4Zl0gfCBwYzJieXRlczEyWyhyaWdodCA+Pj4gOCkgJiAweGZdDQogICAgICAgICAgICAgICAgfCBwYzJieXRlczEzWyhyaWdodCA+Pj4gNCkgJiAweGZdOw0KICAgICAgdGVtcCA9ICgocmlnaHR0ZW1wID4+PiAxNikgXiBsZWZ0dGVtcCkgJiAweDAwMDBmZmZmOyANCiAgICAgIGtleXNbbisrXSA9IGxlZnR0ZW1wIF4gdGVtcDsga2V5c1tuKytdID0gcmlnaHR0ZW1wIF4gKHRlbXAgPDwgMTYpOw0KICAgIH0NCiAgfSAvL2ZvciBlYWNoIGl0ZXJhdGlvbnMNCiAgLy9yZXR1cm4gdGhlIGtleXMgd2UndmUgY3JlYXRlZA0KICByZXR1cm4ga2V5czsNCn0gLy9lbmQgb2YgZGVzX2NyZWF0ZUtleXMNCg0KDQovKiBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkggDQogKiANCiAqIENpcGhlci5qcw0KICogQSBibG9jay1jaXBoZXIgYWxnb3JpdGhtIGltcGxlbWVudGF0aW9uIG9uIEphdmFTY3JpcHQNCiAqIFNlZSBDaXBoZXIucmVhZG1lLnR4dCBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi4NCiAqDQogKiBDb3B5cmlnaHQoYykgMjAwOSBBdHN1c2hpIE9rYSBbIGh0dHA6Ly9va2EubnUvIF0NCiAqIFRoaXMgc2NyaXB0IGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExHUEwNCiAqDQogKiBBQ0tOT1dMRURHTUVOVA0KICoNCiAqICAgICBUaGUgbWFpbiBzdWJyb3V0aW5lcyBhcmUgd3JpdHRlbiBieSBNaWNoaWVsIHZhbiBFdmVyZGluZ2VuLg0KICogDQogKiAgICAgTWljaGllbCB2YW4gRXZlcmRpbmdlbg0KICogICAgIGh0dHA6Ly9ob21lLnZlcnNhdGVsLm5sL01BdmFuRXZlcmRpbmdlbi9pbmRleC5odG1sDQogKiANCiAqICAgICBBbGwgcmlnaHRzIGZvciB0aGVzZSByb3V0aW5lcyBhcmUgcmVzZXJ2ZWQgdG8gTWljaGllbCB2YW4gRXZlcmRpbmdlbi4NCiAqDQogKi8NCg0KLy8gYWRkZWQgYnkgUmVjdXJpdHkgTGFicw0KZnVuY3Rpb24gVEZlbmNyeXB0KGJsb2NrLCBrZXkpIHsNCgl2YXIgYmxvY2tfY29weSA9IFtdLmNvbmNhdChibG9jayk7DQoJdmFyIHRmID0gY3JlYXRlVHdvZmlzaCgpOw0KCXRmLm9wZW4odXRpbC5zdHIyYmluKGtleSksMCk7DQoJdmFyIHJlc3VsdCA9IHRmLmVuY3J5cHQoYmxvY2tfY29weSwgMCk7DQoJdGYuY2xvc2UoKTsNCglyZXR1cm4gcmVzdWx0Ow0KfQ0KDQovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCi8vTWF0aA0KLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQoNCnZhciBNQVhJTlQgPSAweEZGRkZGRkZGOw0KDQpmdW5jdGlvbiByb3RiKGIsbil7IHJldHVybiAoIGI8PG4gfCBiPj4+KCA4LW4pICkgJiAweEZGOyB9DQpmdW5jdGlvbiByb3R3KHcsbil7IHJldHVybiAoIHc8PG4gfCB3Pj4+KDMyLW4pICkgJiBNQVhJTlQ7IH0NCmZ1bmN0aW9uIGdldFcoYSxpKXsgcmV0dXJuIGFbaV18YVtpKzFdPDw4fGFbaSsyXTw8MTZ8YVtpKzNdPDwyNDsgfQ0KZnVuY3Rpb24gc2V0VyhhLGksdyl7IGEuc3BsaWNlKGksNCx3JjB4RkYsKHc+Pj44KSYweEZGLCh3Pj4+MTYpJjB4RkYsKHc+Pj4yNCkmMHhGRik7IH0NCmZ1bmN0aW9uIHNldFdJbnYoYSxpLHcpeyBhLnNwbGljZShpLDQsKHc+Pj4yNCkmMHhGRiwodz4+PjE2KSYweEZGLCh3Pj4+OCkmMHhGRix3JjB4RkYpOyB9DQpmdW5jdGlvbiBnZXRCKHgsbil7IHJldHVybiAoeD4+PihuKjgpKSYweEZGOyB9DQoNCmZ1bmN0aW9uIGdldE5yQml0cyhpKXsgdmFyIG49MDsgd2hpbGUgKGk+MCl7IG4rKzsgaT4+Pj0xOyB9IHJldHVybiBuOyB9DQpmdW5jdGlvbiBnZXRNYXNrKG4peyByZXR1cm4gKDE8PG4pLTE7IH0NCg0KLy9hZGRlZCAyMDA4LzExLzEzIFhYWCBNVVNUIFVTRSBPTkUtV0FZIEhBU0ggRlVOQ1RJT04gRk9SIFNFQ1VSSVRZIFJFQVNPTg0KZnVuY3Rpb24gcmFuZEJ5dGUoKSB7DQogcmV0dXJuIE1hdGguZmxvb3IoIE1hdGgucmFuZG9tKCkgKiAyNTYgKTsNCn0NCi8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCi8vIFR3b2Zpc2gNCi8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCg0KZnVuY3Rpb24gY3JlYXRlVHdvZmlzaCgpIHsNCgkvLw0KCXZhciBrZXlCeXRlcyA9IG51bGw7DQoJdmFyIGRhdGFCeXRlcyA9IG51bGw7DQoJdmFyIGRhdGFPZmZzZXQgPSAtMTsNCgkvLyB2YXIgZGF0YUxlbmd0aCA9IC0xOw0KCXZhciBhbGdvcml0aG1OYW1lID0gbnVsbDsNCgkvLyB2YXIgaWR4MiA9IC0xOw0KCS8vDQoNCglhbGdvcml0aG1OYW1lID0gInR3b2Zpc2giOw0KDQoJdmFyIHRmc0tleSA9IFtdOw0KCXZhciB0ZnNNID0gWyBbXSwgW10sIFtdLCBbXSBdOw0KDQoJZnVuY3Rpb24gdGZzSW5pdChrZXkpIHsNCgkJa2V5Qnl0ZXMgPSBrZXk7DQoJCXZhciBpLCBhLCBiLCBjLCBkLCBtZUtleSA9IFtdLCBtb0tleSA9IFtdLCBpbktleSA9IFtdOw0KCQl2YXIga0xlbjsNCgkJdmFyIHNLZXkgPSBbXTsNCgkJdmFyIGYwMSwgZjViLCBmZWY7DQoNCgkJdmFyIHEwID0gWyBbIDgsIDEsIDcsIDEzLCA2LCAxNSwgMywgMiwgMCwgMTEsIDUsIDksIDE0LCAxMiwgMTAsIDQgXSwNCgkJCQlbIDIsIDgsIDExLCAxMywgMTUsIDcsIDYsIDE0LCAzLCAxLCA5LCA0LCAwLCAxMCwgMTIsIDUgXSBdOw0KCQl2YXIgcTEgPSBbIFsgMTQsIDEyLCAxMSwgOCwgMSwgMiwgMywgNSwgMTUsIDQsIDEwLCA2LCA3LCAwLCA5LCAxMyBdLA0KCQkJCVsgMSwgMTQsIDIsIDExLCA0LCAxMiwgMywgNywgNiwgMTMsIDEwLCA1LCAxNSwgOSwgMCwgOCBdIF07DQoJCXZhciBxMiA9IFsgWyAxMSwgMTAsIDUsIDE0LCA2LCAxMywgOSwgMCwgMTIsIDgsIDE1LCAzLCAyLCA0LCA3LCAxIF0sDQoJCQkJWyA0LCAxMiwgNywgNSwgMSwgNiwgOSwgMTAsIDAsIDE0LCAxMywgOCwgMiwgMTEsIDMsIDE1IF0gXTsNCgkJdmFyIHEzID0gWyBbIDEzLCA3LCAxNSwgNCwgMSwgMiwgNiwgMTQsIDksIDExLCAzLCAwLCA4LCA1LCAxMiwgMTAgXSwNCgkJCQlbIDExLCA5LCA1LCAxLCAxMiwgMywgMTMsIDE0LCA2LCA0LCA3LCAxNSwgMiwgMCwgOCwgMTAgXSBdOw0KCQl2YXIgcm9yNCA9IFsgMCwgOCwgMSwgOSwgMiwgMTAsIDMsIDExLCA0LCAxMiwgNSwgMTMsIDYsIDE0LCA3LCAxNSBdOw0KCQl2YXIgYXNoeCA9IFsgMCwgOSwgMiwgMTEsIDQsIDEzLCA2LCAxNSwgOCwgMSwgMTAsIDMsIDEyLCA1LCAxNCwgNyBdOw0KCQl2YXIgcSA9IFsgW10sIFtdIF07DQoJCXZhciBtID0gWyBbXSwgW10sIFtdLCBbXSBdOw0KDQoJCWZ1bmN0aW9uIGZmbTViKHgpIHsNCgkJCXJldHVybiB4IF4gKHggPj4gMikgXiBbIDAsIDkwLCAxODAsIDIzOCBdW3ggJiAzXTsNCgkJfQ0KCQlmdW5jdGlvbiBmZm1FZih4KSB7DQoJCQlyZXR1cm4geCBeICh4ID4+IDEpIF4gKHggPj4gMikgXiBbIDAsIDIzOCwgMTgwLCA5MCBdW3ggJiAzXTsNCgkJfQ0KDQoJCWZ1bmN0aW9uIG1kc1JlbShwLCBxKSB7DQoJCQl2YXIgaSwgdCwgdTsNCgkJCWZvciAoaSA9IDA7IGkgPCA4OyBpKyspIHsNCgkJCQl0ID0gcSA+Pj4gMjQ7DQoJCQkJcSA9ICgocSA8PCA4KSAmIE1BWElOVCkgfCBwID4+PiAyNDsNCgkJCQlwID0gKHAgPDwgOCkgJiBNQVhJTlQ7DQoJCQkJdSA9IHQgPDwgMTsNCgkJCQlpZiAodCAmIDEyOCkgew0KCQkJCQl1IF49IDMzMzsNCgkJCQl9DQoJCQkJcSBePSB0IF4gKHUgPDwgMTYpOw0KCQkJCXUgXj0gdCA+Pj4gMTsNCgkJCQlpZiAodCAmIDEpIHsNCgkJCQkJdSBePSAxNjY7DQoJCQkJfQ0KCQkJCXEgXj0gdSA8PCAyNCB8IHUgPDwgODsNCgkJCX0NCgkJCXJldHVybiBxOw0KCQl9DQoNCgkJZnVuY3Rpb24gcXAobiwgeCkgew0KCQkJdmFyIGEsIGIsIGMsIGQ7DQoJCQlhID0geCA+PiA0Ow0KCQkJYiA9IHggJiAxNTsNCgkJCWMgPSBxMFtuXVthIF4gYl07DQoJCQlkID0gcTFbbl1bcm9yNFtiXSBeIGFzaHhbYV1dOw0KCQkJcmV0dXJuIHEzW25dW3JvcjRbZF0gXiBhc2h4W2NdXSA8PCA0IHwgcTJbbl1bYyBeIGRdOw0KCQl9DQoNCgkJZnVuY3Rpb24gaEZ1bih4LCBrZXkpIHsNCgkJCXZhciBhID0gZ2V0Qih4LCAwKSwgYiA9IGdldEIoeCwgMSksIGMgPSBnZXRCKHgsIDIpLCBkID0gZ2V0Qih4LCAzKTsNCgkJCXN3aXRjaCAoa0xlbikgew0KCQkJY2FzZSA0Og0KCQkJCWEgPSBxWzFdW2FdIF4gZ2V0QihrZXlbM10sIDApOw0KCQkJCWIgPSBxWzBdW2JdIF4gZ2V0QihrZXlbM10sIDEpOw0KCQkJCWMgPSBxWzBdW2NdIF4gZ2V0QihrZXlbM10sIDIpOw0KCQkJCWQgPSBxWzFdW2RdIF4gZ2V0QihrZXlbM10sIDMpOw0KCQkJY2FzZSAzOg0KCQkJCWEgPSBxWzFdW2FdIF4gZ2V0QihrZXlbMl0sIDApOw0KCQkJCWIgPSBxWzFdW2JdIF4gZ2V0QihrZXlbMl0sIDEpOw0KCQkJCWMgPSBxWzBdW2NdIF4gZ2V0QihrZXlbMl0sIDIpOw0KCQkJCWQgPSBxWzBdW2RdIF4gZ2V0QihrZXlbMl0sIDMpOw0KCQkJY2FzZSAyOg0KCQkJCWEgPSBxWzBdW3FbMF1bYV0gXiBnZXRCKGtleVsxXSwgMCldIF4gZ2V0QihrZXlbMF0sIDApOw0KCQkJCWIgPSBxWzBdW3FbMV1bYl0gXiBnZXRCKGtleVsxXSwgMSldIF4gZ2V0QihrZXlbMF0sIDEpOw0KCQkJCWMgPSBxWzFdW3FbMF1bY10gXiBnZXRCKGtleVsxXSwgMildIF4gZ2V0QihrZXlbMF0sIDIpOw0KCQkJCWQgPSBxWzFdW3FbMV1bZF0gXiBnZXRCKGtleVsxXSwgMyldIF4gZ2V0QihrZXlbMF0sIDMpOw0KCQkJfQ0KCQkJcmV0dXJuIG1bMF1bYV0gXiBtWzFdW2JdIF4gbVsyXVtjXSBeIG1bM11bZF07DQoJCX0NCg0KCQlrZXlCeXRlcyA9IGtleUJ5dGVzLnNsaWNlKDAsIDMyKTsNCgkJaSA9IGtleUJ5dGVzLmxlbmd0aDsNCgkJd2hpbGUgKGkgIT0gMTYgJiYgaSAhPSAyNCAmJiBpICE9IDMyKQ0KCQkJa2V5Qnl0ZXNbaSsrXSA9IDA7DQoNCgkJZm9yIChpID0gMDsgaSA8IGtleUJ5dGVzLmxlbmd0aDsgaSArPSA0KSB7DQoJCQlpbktleVtpID4+IDJdID0gZ2V0VyhrZXlCeXRlcywgaSk7DQoJCX0NCgkJZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7DQoJCQlxWzBdW2ldID0gcXAoMCwgaSk7DQoJCQlxWzFdW2ldID0gcXAoMSwgaSk7DQoJCX0NCgkJZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7DQoJCQlmMDEgPSBxWzFdW2ldOw0KCQkJZjViID0gZmZtNWIoZjAxKTsNCgkJCWZlZiA9IGZmbUVmKGYwMSk7DQoJCQltWzBdW2ldID0gZjAxICsgKGY1YiA8PCA4KSArIChmZWYgPDwgMTYpICsgKGZlZiA8PCAyNCk7DQoJCQltWzJdW2ldID0gZjViICsgKGZlZiA8PCA4KSArIChmMDEgPDwgMTYpICsgKGZlZiA8PCAyNCk7DQoJCQlmMDEgPSBxWzBdW2ldOw0KCQkJZjViID0gZmZtNWIoZjAxKTsNCgkJCWZlZiA9IGZmbUVmKGYwMSk7DQoJCQltWzFdW2ldID0gZmVmICsgKGZlZiA8PCA4KSArIChmNWIgPDwgMTYpICsgKGYwMSA8PCAyNCk7DQoJCQltWzNdW2ldID0gZjViICsgKGYwMSA8PCA4KSArIChmZWYgPDwgMTYpICsgKGY1YiA8PCAyNCk7DQoJCX0NCg0KCQlrTGVuID0gaW5LZXkubGVuZ3RoIC8gMjsNCgkJZm9yIChpID0gMDsgaSA8IGtMZW47IGkrKykgew0KCQkJYSA9IGluS2V5W2kgKyBpXTsNCgkJCW1lS2V5W2ldID0gYTsNCgkJCWIgPSBpbktleVtpICsgaSArIDFdOw0KCQkJbW9LZXlbaV0gPSBiOw0KCQkJc0tleVtrTGVuIC0gaSAtIDFdID0gbWRzUmVtKGEsIGIpOw0KCQl9DQoJCWZvciAoaSA9IDA7IGkgPCA0MDsgaSArPSAyKSB7DQoJCQlhID0gMHgxMDEwMTAxICogaTsNCgkJCWIgPSBhICsgMHgxMDEwMTAxOw0KCQkJYSA9IGhGdW4oYSwgbWVLZXkpOw0KCQkJYiA9IHJvdHcoaEZ1bihiLCBtb0tleSksIDgpOw0KCQkJdGZzS2V5W2ldID0gKGEgKyBiKSAmIE1BWElOVDsNCgkJCXRmc0tleVtpICsgMV0gPSByb3R3KGEgKyAyICogYiwgOSk7DQoJCX0NCgkJZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7DQoJCQlhID0gYiA9IGMgPSBkID0gaTsNCgkJCXN3aXRjaCAoa0xlbikgew0KCQkJY2FzZSA0Og0KCQkJCWEgPSBxWzFdW2FdIF4gZ2V0QihzS2V5WzNdLCAwKTsNCgkJCQliID0gcVswXVtiXSBeIGdldEIoc0tleVszXSwgMSk7DQoJCQkJYyA9IHFbMF1bY10gXiBnZXRCKHNLZXlbM10sIDIpOw0KCQkJCWQgPSBxWzFdW2RdIF4gZ2V0QihzS2V5WzNdLCAzKTsNCgkJCWNhc2UgMzoNCgkJCQlhID0gcVsxXVthXSBeIGdldEIoc0tleVsyXSwgMCk7DQoJCQkJYiA9IHFbMV1bYl0gXiBnZXRCKHNLZXlbMl0sIDEpOw0KCQkJCWMgPSBxWzBdW2NdIF4gZ2V0QihzS2V5WzJdLCAyKTsNCgkJCQlkID0gcVswXVtkXSBeIGdldEIoc0tleVsyXSwgMyk7DQoJCQljYXNlIDI6DQoJCQkJdGZzTVswXVtpXSA9IG1bMF1bcVswXVtxWzBdW2FdIF4gZ2V0QihzS2V5WzFdLCAwKV0NCgkJCQkJCV4gZ2V0QihzS2V5WzBdLCAwKV07DQoJCQkJdGZzTVsxXVtpXSA9IG1bMV1bcVswXVtxWzFdW2JdIF4gZ2V0QihzS2V5WzFdLCAxKV0NCgkJCQkJCV4gZ2V0QihzS2V5WzBdLCAxKV07DQoJCQkJdGZzTVsyXVtpXSA9IG1bMl1bcVsxXVtxWzBdW2NdIF4gZ2V0QihzS2V5WzFdLCAyKV0NCgkJCQkJCV4gZ2V0QihzS2V5WzBdLCAyKV07DQoJCQkJdGZzTVszXVtpXSA9IG1bM11bcVsxXVtxWzFdW2RdIF4gZ2V0QihzS2V5WzFdLCAzKV0NCgkJCQkJCV4gZ2V0QihzS2V5WzBdLCAzKV07DQoJCQl9DQoJCX0NCgl9DQoNCglmdW5jdGlvbiB0ZnNHMCh4KSB7DQoJCXJldHVybiB0ZnNNWzBdW2dldEIoeCwgMCldIF4gdGZzTVsxXVtnZXRCKHgsIDEpXSBeIHRmc01bMl1bZ2V0Qih4LCAyKV0NCgkJCQleIHRmc01bM11bZ2V0Qih4LCAzKV07DQoJfQ0KCWZ1bmN0aW9uIHRmc0cxKHgpIHsNCgkJcmV0dXJuIHRmc01bMF1bZ2V0Qih4LCAzKV0gXiB0ZnNNWzFdW2dldEIoeCwgMCldIF4gdGZzTVsyXVtnZXRCKHgsIDEpXQ0KCQkJCV4gdGZzTVszXVtnZXRCKHgsIDIpXTsNCgl9DQoNCglmdW5jdGlvbiB0ZnNGcm5kKHIsIGJsaykgew0KCQl2YXIgYSA9IHRmc0cwKGJsa1swXSk7DQoJCXZhciBiID0gdGZzRzEoYmxrWzFdKTsNCgkJYmxrWzJdID0gcm90dyhibGtbMl0gXiAoYSArIGIgKyB0ZnNLZXlbNCAqIHIgKyA4XSkgJiBNQVhJTlQsIDMxKTsNCgkJYmxrWzNdID0gcm90dyhibGtbM10sIDEpIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogciArIDldKSAmIE1BWElOVDsNCgkJYSA9IHRmc0cwKGJsa1syXSk7DQoJCWIgPSB0ZnNHMShibGtbM10pOw0KCQlibGtbMF0gPSByb3R3KGJsa1swXSBeIChhICsgYiArIHRmc0tleVs0ICogciArIDEwXSkgJiBNQVhJTlQsIDMxKTsNCgkJYmxrWzFdID0gcm90dyhibGtbMV0sIDEpIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogciArIDExXSkgJiBNQVhJTlQ7DQoJfQ0KDQoJZnVuY3Rpb24gdGZzSXJuZChpLCBibGspIHsNCgkJdmFyIGEgPSB0ZnNHMChibGtbMF0pOw0KCQl2YXIgYiA9IHRmc0cxKGJsa1sxXSk7DQoJCWJsa1syXSA9IHJvdHcoYmxrWzJdLCAxKSBeIChhICsgYiArIHRmc0tleVs0ICogaSArIDEwXSkgJiBNQVhJTlQ7DQoJCWJsa1szXSA9IHJvdHcoYmxrWzNdIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogaSArIDExXSkgJiBNQVhJTlQsIDMxKTsNCgkJYSA9IHRmc0cwKGJsa1syXSk7DQoJCWIgPSB0ZnNHMShibGtbM10pOw0KCQlibGtbMF0gPSByb3R3KGJsa1swXSwgMSkgXiAoYSArIGIgKyB0ZnNLZXlbNCAqIGkgKyA4XSkgJiBNQVhJTlQ7DQoJCWJsa1sxXSA9IHJvdHcoYmxrWzFdIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogaSArIDldKSAmIE1BWElOVCwgMzEpOw0KCX0NCg0KCWZ1bmN0aW9uIHRmc0Nsb3NlKCkgew0KCQl0ZnNLZXkgPSBbXTsNCgkJdGZzTSA9IFsgW10sIFtdLCBbXSwgW10gXTsNCgl9DQoNCglmdW5jdGlvbiB0ZnNFbmNyeXB0KGRhdGEsIG9mZnNldCkgew0KCQlkYXRhQnl0ZXMgPSBkYXRhOw0KCQlkYXRhT2Zmc2V0ID0gb2Zmc2V0Ow0KCQl2YXIgYmxrID0gWyBnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCkgXiB0ZnNLZXlbMF0sDQoJCQkJZ2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyA0KSBeIHRmc0tleVsxXSwNCgkJCQlnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDgpIF4gdGZzS2V5WzJdLA0KCQkJCWdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIpIF4gdGZzS2V5WzNdIF07DQoJCWZvciAoIHZhciBqID0gMDsgaiA8IDg7IGorKykgew0KCQkJdGZzRnJuZChqLCBibGspOw0KCQl9DQoJCXNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0LCBibGtbMl0gXiB0ZnNLZXlbNF0pOw0KCQlzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDQsIGJsa1szXSBeIHRmc0tleVs1XSk7DQoJCXNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgOCwgYmxrWzBdIF4gdGZzS2V5WzZdKTsNCgkJc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyAxMiwgYmxrWzFdIF4gdGZzS2V5WzddKTsNCgkJZGF0YU9mZnNldCArPSAxNjsNCgkJcmV0dXJuIGRhdGFCeXRlczsNCgl9DQoNCglmdW5jdGlvbiB0ZnNEZWNyeXB0KGRhdGEsIG9mZnNldCkgew0KCQlkYXRhQnl0ZXMgPSBkYXRhOw0KCQlkYXRhT2Zmc2V0ID0gb2Zmc2V0Ow0KCQl2YXIgYmxrID0gWyBnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCkgXiB0ZnNLZXlbNF0sDQoJCQkJZ2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyA0KSBeIHRmc0tleVs1XSwNCgkJCQlnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDgpIF4gdGZzS2V5WzZdLA0KCQkJCWdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIpIF4gdGZzS2V5WzddIF07DQoJCWZvciAoIHZhciBqID0gNzsgaiA+PSAwOyBqLS0pIHsNCgkJCXRmc0lybmQoaiwgYmxrKTsNCgkJfQ0KCQlzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCwgYmxrWzJdIF4gdGZzS2V5WzBdKTsNCgkJc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyA0LCBibGtbM10gXiB0ZnNLZXlbMV0pOw0KCQlzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDgsIGJsa1swXSBeIHRmc0tleVsyXSk7DQoJCXNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIsIGJsa1sxXSBeIHRmc0tleVszXSk7DQoJCWRhdGFPZmZzZXQgKz0gMTY7DQoJfQ0KCQ0KCS8vIGFkZGVkIGJ5IFJlY3VyaXR5IExhYnMNCglmdW5jdGlvbiB0ZnNGaW5hbCgpIHsNCgkJcmV0dXJuIGRhdGFCeXRlczsNCgl9DQoNCglyZXR1cm4gew0KCQluYW1lIDogInR3b2Zpc2giLA0KCQlibG9ja3NpemUgOiAxMjggLyA4LA0KCQlvcGVuIDogdGZzSW5pdCwNCgkJY2xvc2UgOiB0ZnNDbG9zZSwNCgkJZW5jcnlwdCA6IHRmc0VuY3J5cHQsDQoJCWRlY3J5cHQgOiB0ZnNEZWNyeXB0LA0KCQkvLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzDQoJCWZpbmFsaXplOiB0ZnNGaW5hbA0KCX07DQp9DQoNCkpYRyA9IHtleGlzdHM6IChmdW5jdGlvbih1bmRlZmluZWQpe3JldHVybiBmdW5jdGlvbih2KXtyZXR1cm4gISh2PT09dW5kZWZpbmVkIHx8IHY9PT1udWxsKTt9fSkoKX07DQpKWEcuZGVjb21wcmVzcyA9IGZ1bmN0aW9uKHN0cikge3JldHVybiB1bmVzY2FwZSgobmV3IEpYRy5VdGlsLlVuemlwKEpYRy5VdGlsLkJhc2U2NC5kZWNvZGVBc0FycmF5KHN0cikpKS51bnppcCgpWzBdWzBdKTt9Ow0KLyoNCiAgICBDb3B5cmlnaHQgMjAwOC0yMDEyDQogICAgICAgIE1hdHRoaWFzIEVobWFubiwNCiAgICAgICAgTWljaGFlbCBHZXJoYWV1c2VyLA0KICAgICAgICBDYXJzdGVuIE1pbGxlciwNCiAgICAgICAgQmlhbmNhIFZhbGVudGluLA0KICAgICAgICBBbGZyZWQgV2Fzc2VybWFubiwNCiAgICAgICAgUGV0ZXIgV2lsZmFocnQNCg0KICAgIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIEpTWEdyYXBoLg0KICAgIA0KICAgIER1YWwgbGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlIFZlcnNpb24gMi4wLCBvciBMR1BMIFZlcnNpb24gMyBsaWNlbnNlcy4NCg0KICAgIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQ0KICAgIGFsb25nIHdpdGggSlNYQ29tcHJlc3Nvci4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4NCiAgICANCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBBcGFjaGUgTGljZW5zZSBhbG9uZyB3aXRoIEpTWENvbXByZXNzb3IuICANCiAgICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLz4uDQoNCiovDQoNCi8qKg0KICAqIEBjbGFzcyBVdGlsIGNsYXNzDQogICogQGNsYXNzZGVzYyBVdGlsaXRpZXMgZm9yIHVuY29tcHJlc3NpbmcgYW5kIGJhc2U2NCBkZWNvZGluZw0KICAqIENsYXNzIGZvciBndW56aXBwaW5nLCB1bnppcHBpbmcgYW5kIGJhc2U2NCBkZWNvZGluZyBvZiBmaWxlcy4NCiAgKiBJdCBpcyB1c2VkIGZvciByZWFkaW5nIEdFT05FeFQsIEdlb2dlYnJhIGFuZCBJbnRlcmdlbyBmaWxlcy4NCiAgKg0KICAqIE9ubHkgSHVmZm1hbiBjb2RlcyBhcmUgZGVjb2RlZCBpbiBndW56aXAuDQogICogVGhlIGNvZGUgaXMgYmFzZWQgb24gdGhlIHNvdXJjZSBjb2RlIGZvciBndW56aXAuYyBieSBQYXNpIE9qYWxhIA0KICAqIHtAbGluayBodHRwOi8vd3d3LmNzLnR1dC5maS9+YWxiZXJ0L0Rldi9ndW56aXAvZ3VuemlwLmN9DQogICoge0BsaW5rIGh0dHA6Ly93d3cuY3MudHV0LmZpL35hbGJlcnR9DQogICovDQpKWEcuVXRpbCA9IHt9Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQovKioNCiAqIFVuemlwIHppcCBmaWxlcw0KICovDQpKWEcuVXRpbC5VbnppcCA9IGZ1bmN0aW9uIChiYXJyYXkpew0KICAgIHZhciBvdXRwdXRBcnIgPSBbXSwNCiAgICAgICAgb3V0cHV0ID0gIiIsDQogICAgICAgIGRlYnVnID0gZmFsc2UsDQogICAgICAgIGdwZmxhZ3MsDQogICAgICAgIGZpbGVzID0gMCwNCiAgICAgICAgdW56aXBwZWQgPSBbXSwNCiAgICAgICAgY3JjLA0KICAgICAgICBidWYzMmsgPSBuZXcgQXJyYXkoMzI3NjgpLA0KICAgICAgICBiSWR4ID0gMCwNCiAgICAgICAgbW9kZVpJUD1mYWxzZSwNCg0KICAgICAgICBDUkMsIFNJWkUsDQogICAgDQogICAgICAgIGJpdFJldmVyc2UgPSBbDQogICAgICAgIDB4MDAsIDB4ODAsIDB4NDAsIDB4YzAsIDB4MjAsIDB4YTAsIDB4NjAsIDB4ZTAsDQogICAgICAgIDB4MTAsIDB4OTAsIDB4NTAsIDB4ZDAsIDB4MzAsIDB4YjAsIDB4NzAsIDB4ZjAsDQogICAgICAgIDB4MDgsIDB4ODgsIDB4NDgsIDB4YzgsIDB4MjgsIDB4YTgsIDB4NjgsIDB4ZTgsDQogICAgICAgIDB4MTgsIDB4OTgsIDB4NTgsIDB4ZDgsIDB4MzgsIDB4YjgsIDB4NzgsIDB4ZjgsDQogICAgICAgIDB4MDQsIDB4ODQsIDB4NDQsIDB4YzQsIDB4MjQsIDB4YTQsIDB4NjQsIDB4ZTQsDQogICAgICAgIDB4MTQsIDB4OTQsIDB4NTQsIDB4ZDQsIDB4MzQsIDB4YjQsIDB4NzQsIDB4ZjQsDQogICAgICAgIDB4MGMsIDB4OGMsIDB4NGMsIDB4Y2MsIDB4MmMsIDB4YWMsIDB4NmMsIDB4ZWMsDQogICAgICAgIDB4MWMsIDB4OWMsIDB4NWMsIDB4ZGMsIDB4M2MsIDB4YmMsIDB4N2MsIDB4ZmMsDQogICAgICAgIDB4MDIsIDB4ODIsIDB4NDIsIDB4YzIsIDB4MjIsIDB4YTIsIDB4NjIsIDB4ZTIsDQogICAgICAgIDB4MTIsIDB4OTIsIDB4NTIsIDB4ZDIsIDB4MzIsIDB4YjIsIDB4NzIsIDB4ZjIsDQogICAgICAgIDB4MGEsIDB4OGEsIDB4NGEsIDB4Y2EsIDB4MmEsIDB4YWEsIDB4NmEsIDB4ZWEsDQogICAgICAgIDB4MWEsIDB4OWEsIDB4NWEsIDB4ZGEsIDB4M2EsIDB4YmEsIDB4N2EsIDB4ZmEsDQogICAgICAgIDB4MDYsIDB4ODYsIDB4NDYsIDB4YzYsIDB4MjYsIDB4YTYsIDB4NjYsIDB4ZTYsDQogICAgICAgIDB4MTYsIDB4OTYsIDB4NTYsIDB4ZDYsIDB4MzYsIDB4YjYsIDB4NzYsIDB4ZjYsDQogICAgICAgIDB4MGUsIDB4OGUsIDB4NGUsIDB4Y2UsIDB4MmUsIDB4YWUsIDB4NmUsIDB4ZWUsDQogICAgICAgIDB4MWUsIDB4OWUsIDB4NWUsIDB4ZGUsIDB4M2UsIDB4YmUsIDB4N2UsIDB4ZmUsDQogICAgICAgIDB4MDEsIDB4ODEsIDB4NDEsIDB4YzEsIDB4MjEsIDB4YTEsIDB4NjEsIDB4ZTEsDQogICAgICAgIDB4MTEsIDB4OTEsIDB4NTEsIDB4ZDEsIDB4MzEsIDB4YjEsIDB4NzEsIDB4ZjEsDQogICAgICAgIDB4MDksIDB4ODksIDB4NDksIDB4YzksIDB4MjksIDB4YTksIDB4NjksIDB4ZTksDQogICAgICAgIDB4MTksIDB4OTksIDB4NTksIDB4ZDksIDB4MzksIDB4YjksIDB4NzksIDB4ZjksDQogICAgICAgIDB4MDUsIDB4ODUsIDB4NDUsIDB4YzUsIDB4MjUsIDB4YTUsIDB4NjUsIDB4ZTUsDQogICAgICAgIDB4MTUsIDB4OTUsIDB4NTUsIDB4ZDUsIDB4MzUsIDB4YjUsIDB4NzUsIDB4ZjUsDQogICAgICAgIDB4MGQsIDB4OGQsIDB4NGQsIDB4Y2QsIDB4MmQsIDB4YWQsIDB4NmQsIDB4ZWQsDQogICAgICAgIDB4MWQsIDB4OWQsIDB4NWQsIDB4ZGQsIDB4M2QsIDB4YmQsIDB4N2QsIDB4ZmQsDQogICAgICAgIDB4MDMsIDB4ODMsIDB4NDMsIDB4YzMsIDB4MjMsIDB4YTMsIDB4NjMsIDB4ZTMsDQogICAgICAgIDB4MTMsIDB4OTMsIDB4NTMsIDB4ZDMsIDB4MzMsIDB4YjMsIDB4NzMsIDB4ZjMsDQogICAgICAgIDB4MGIsIDB4OGIsIDB4NGIsIDB4Y2IsIDB4MmIsIDB4YWIsIDB4NmIsIDB4ZWIsDQogICAgICAgIDB4MWIsIDB4OWIsIDB4NWIsIDB4ZGIsIDB4M2IsIDB4YmIsIDB4N2IsIDB4ZmIsDQogICAgICAgIDB4MDcsIDB4ODcsIDB4NDcsIDB4YzcsIDB4MjcsIDB4YTcsIDB4NjcsIDB4ZTcsDQogICAgICAgIDB4MTcsIDB4OTcsIDB4NTcsIDB4ZDcsIDB4MzcsIDB4YjcsIDB4NzcsIDB4ZjcsDQogICAgICAgIDB4MGYsIDB4OGYsIDB4NGYsIDB4Y2YsIDB4MmYsIDB4YWYsIDB4NmYsIDB4ZWYsDQogICAgICAgIDB4MWYsIDB4OWYsIDB4NWYsIDB4ZGYsIDB4M2YsIDB4YmYsIDB4N2YsIDB4ZmYNCiAgICBdLA0KICAgIA0KICAgIGNwbGVucyA9IFsNCiAgICAgICAgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMywgMTUsIDE3LCAxOSwgMjMsIDI3LCAzMSwNCiAgICAgICAgMzUsIDQzLCA1MSwgNTksIDY3LCA4MywgOTksIDExNSwgMTMxLCAxNjMsIDE5NSwgMjI3LCAyNTgsIDAsIDANCiAgICBdLA0KDQogICAgY3BsZXh0ID0gWw0KICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAyLCAyLCAyLCAyLA0KICAgICAgICAzLCAzLCAzLCAzLCA0LCA0LCA0LCA0LCA1LCA1LCA1LCA1LCAwLCA5OSwgOTkNCiAgICBdLCAvKiA5OT09aW52YWxpZCAqLw0KDQogICAgY3BkaXN0ID0gWw0KICAgICAgICAweDAwMDEsIDB4MDAwMiwgMHgwMDAzLCAweDAwMDQsIDB4MDAwNSwgMHgwMDA3LCAweDAwMDksIDB4MDAwZCwNCiAgICAgICAgMHgwMDExLCAweDAwMTksIDB4MDAyMSwgMHgwMDMxLCAweDAwNDEsIDB4MDA2MSwgMHgwMDgxLCAweDAwYzEsDQogICAgICAgIDB4MDEwMSwgMHgwMTgxLCAweDAyMDEsIDB4MDMwMSwgMHgwNDAxLCAweDA2MDEsIDB4MDgwMSwgMHgwYzAxLA0KICAgICAgICAweDEwMDEsIDB4MTgwMSwgMHgyMDAxLCAweDMwMDEsIDB4NDAwMSwgMHg2MDAxDQogICAgXSwNCg0KICAgIGNwZGV4dCA9IFsNCiAgICAgICAgMCwgIDAsICAwLCAgMCwgIDEsICAxLCAgMiwgIDIsDQogICAgICAgIDMsICAzLCAgNCwgIDQsICA1LCAgNSwgIDYsICA2LA0KICAgICAgICA3LCAgNywgIDgsICA4LCAgOSwgIDksIDEwLCAxMCwNCiAgICAgICAgMTEsIDExLCAxMiwgMTIsIDEzLCAxMw0KICAgIF0sDQogICAgDQogICAgYm9yZGVyID0gWzE2LCAxNywgMTgsIDAsIDgsIDcsIDksIDYsIDEwLCA1LCAxMSwgNCwgMTIsIDMsIDEzLCAyLCAxNCwgMSwgMTVdLA0KICAgIA0KICAgIGJBID0gYmFycmF5LA0KDQogICAgYnl0ZXBvcz0wLA0KICAgIGJpdHBvcz0wLA0KICAgIGJiID0gMSwNCiAgICBiaXRzPTAsDQogICAgDQogICAgTkFNRU1BWCA9IDI1NiwNCiAgICANCiAgICBuYW1lQnVmID0gW10sDQogICAgDQogICAgZmlsZW91dDsNCiAgICANCiAgICBmdW5jdGlvbiByZWFkQnl0ZSgpew0KICAgICAgICBiaXRzKz04Ow0KICAgICAgICBpZiAoYnl0ZXBvczxiQS5sZW5ndGgpew0KICAgICAgICAgICAgLy9pZiAoZGVidWcpDQogICAgICAgICAgICAvLyAgICBkb2N1bWVudC53cml0ZShieXRlcG9zKyI6ICIrYkFbYnl0ZXBvc10rIjxicj4iKTsNCiAgICAgICAgICAgIHJldHVybiBiQVtieXRlcG9zKytdOw0KICAgICAgICB9IGVsc2UNCiAgICAgICAgICAgIHJldHVybiAtMTsNCiAgICB9Ow0KDQogICAgZnVuY3Rpb24gYnl0ZUFsaWduKCl7DQogICAgICAgIGJiID0gMTsNCiAgICB9Ow0KICAgIA0KICAgIGZ1bmN0aW9uIHJlYWRCaXQoKXsNCiAgICAgICAgdmFyIGNhcnJ5Ow0KICAgICAgICBiaXRzKys7DQogICAgICAgIGNhcnJ5ID0gKGJiICYgMSk7DQogICAgICAgIGJiID4+PSAxOw0KICAgICAgICBpZiAoYmI9PTApew0KICAgICAgICAgICAgYmIgPSByZWFkQnl0ZSgpOw0KICAgICAgICAgICAgY2FycnkgPSAoYmIgJiAxKTsNCiAgICAgICAgICAgIGJiID0gKGJiPj4xKSB8IDB4ODA7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIGNhcnJ5Ow0KICAgIH07DQoNCiAgICBmdW5jdGlvbiByZWFkQml0cyhhKSB7DQogICAgICAgIHZhciByZXMgPSAwLA0KICAgICAgICAgICAgaSA9IGE7DQogICAgDQogICAgICAgIHdoaWxlKGktLSkgew0KICAgICAgICAgICAgcmVzID0gKHJlczw8MSkgfCByZWFkQml0KCk7DQogICAgICAgIH0NCiAgICAgICAgaWYoYSkgew0KICAgICAgICAgICAgcmVzID0gYml0UmV2ZXJzZVtyZXNdPj4oOC1hKTsNCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gcmVzOw0KICAgIH07DQogICAgICAgIA0KICAgIGZ1bmN0aW9uIGZsdXNoQnVmZmVyKCl7DQogICAgICAgIC8vZG9jdW1lbnQud3JpdGUoJ0ZMVVNIQlVGRkVSOicrYnVmMzJrKTsNCiAgICAgICAgYklkeCA9IDA7DQogICAgfTsNCiAgICBmdW5jdGlvbiBhZGRCdWZmZXIoYSl7DQogICAgICAgIFNJWkUrKzsNCiAgICAgICAgLy9DUkM9dXBkY3JjKGEsY3JjKTsNCiAgICAgICAgYnVmMzJrW2JJZHgrK10gPSBhOw0KICAgICAgICBvdXRwdXRBcnIucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGEpKTsNCiAgICAgICAgLy9vdXRwdXQrPVN0cmluZy5mcm9tQ2hhckNvZGUoYSk7DQogICAgICAgIGlmKGJJZHg9PTB4ODAwMCl7DQogICAgICAgICAgICAvL2RvY3VtZW50LndyaXRlKCdBRERCVUZGRVI6JytidWYzMmspOw0KICAgICAgICAgICAgYklkeD0wOw0KICAgICAgICB9DQogICAgfTsNCiAgICANCiAgICBmdW5jdGlvbiBIdWZOb2RlKCkgew0KICAgICAgICB0aGlzLmIwPTA7DQogICAgICAgIHRoaXMuYjE9MDsNCiAgICAgICAgdGhpcy5qdW1wID0gbnVsbDsNCiAgICAgICAgdGhpcy5qdW1wcG9zID0gLTE7DQogICAgfTsNCg0KICAgIHZhciBMSVRFUkFMUyA9IDI4ODsNCiAgICANCiAgICB2YXIgbGl0ZXJhbFRyZWUgPSBuZXcgQXJyYXkoTElURVJBTFMpOw0KICAgIHZhciBkaXN0YW5jZVRyZWUgPSBuZXcgQXJyYXkoMzIpOw0KICAgIHZhciB0cmVlcG9zPTA7DQogICAgdmFyIFBsYWNlcyA9IG51bGw7DQogICAgdmFyIFBsYWNlczIgPSBudWxsOw0KICAgIA0KICAgIHZhciBpbXBEaXN0YW5jZVRyZWUgPSBuZXcgQXJyYXkoNjQpOw0KICAgIHZhciBpbXBMZW5ndGhUcmVlID0gbmV3IEFycmF5KDY0KTsNCiAgICANCiAgICB2YXIgbGVuID0gMDsNCiAgICB2YXIgZnBvcyA9IG5ldyBBcnJheSgxNyk7DQogICAgZnBvc1swXT0wOw0KICAgIHZhciBmbGVuczsNCiAgICB2YXIgZm1heDsNCiAgICANCiAgICBmdW5jdGlvbiBJc1BhdCgpIHsNCiAgICAgICAgd2hpbGUgKDEpIHsNCiAgICAgICAgICAgIGlmIChmcG9zW2xlbl0gPj0gZm1heCkNCiAgICAgICAgICAgICAgICByZXR1cm4gLTE7DQogICAgICAgICAgICBpZiAoZmxlbnNbZnBvc1tsZW5dXSA9PSBsZW4pDQogICAgICAgICAgICAgICAgcmV0dXJuIGZwb3NbbGVuXSsrOw0KICAgICAgICAgICAgZnBvc1tsZW5dKys7DQogICAgICAgIH0NCiAgICB9Ow0KDQogICAgZnVuY3Rpb24gUmVjKCkgew0KICAgICAgICB2YXIgY3VycGxhY2UgPSBQbGFjZXNbdHJlZXBvc107DQogICAgICAgIHZhciB0bXA7DQogICAgICAgIGlmIChkZWJ1ZykNCiAgICAJCWRvY3VtZW50LndyaXRlKCI8YnI+bGVuOiIrbGVuKyIgdHJlZXBvczoiK3RyZWVwb3MpOw0KICAgICAgICBpZihsZW49PTE3KSB7IC8vd2FyIDE3DQogICAgICAgICAgICByZXR1cm4gLTE7DQogICAgICAgIH0NCiAgICAgICAgdHJlZXBvcysrOw0KICAgICAgICBsZW4rKzsNCiAgICAJDQogICAgICAgIHRtcCA9IElzUGF0KCk7DQogICAgICAgIGlmIChkZWJ1ZykNCiAgICAgICAgCWRvY3VtZW50LndyaXRlKCI8YnI+SXNQYXQgIit0bXApOw0KICAgICAgICBpZih0bXAgPj0gMCkgew0KICAgICAgICAgICAgY3VycGxhY2UuYjAgPSB0bXA7ICAgIC8qIGxlYWYgY2VsbCBmb3IgMC1iaXQgKi8NCiAgICAgICAgICAgIGlmIChkZWJ1ZykNCiAgICAgICAgICAgIAlkb2N1bWVudC53cml0ZSgiPGJyPmIwICIrY3VycGxhY2UuYjApOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAvKiBOb3QgYSBMZWFmIGNlbGwgKi8NCiAgICAgICAgY3VycGxhY2UuYjAgPSAweDgwMDA7DQogICAgICAgIGlmIChkZWJ1ZykNCiAgICAgICAgCWRvY3VtZW50LndyaXRlKCI8YnI+YjAgIitjdXJwbGFjZS5iMCk7DQogICAgICAgIGlmKFJlYygpKQ0KICAgICAgICAgICAgcmV0dXJuIC0xOw0KICAgICAgICB9DQogICAgICAgIHRtcCA9IElzUGF0KCk7DQogICAgICAgIGlmKHRtcCA+PSAwKSB7DQogICAgICAgICAgICBjdXJwbGFjZS5iMSA9IHRtcDsgICAgLyogbGVhZiBjZWxsIGZvciAxLWJpdCAqLw0KICAgICAgICAgICAgaWYgKGRlYnVnKQ0KICAgICAgICAgICAgCWRvY3VtZW50LndyaXRlKCI8YnI+YjEgIitjdXJwbGFjZS5iMSk7DQogICAgICAgICAgICBjdXJwbGFjZS5qdW1wID0gbnVsbDsgICAgLyogSnVzdCBmb3IgdGhlIGRpc3BsYXkgcm91dGluZSAqLw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgLyogTm90IGEgTGVhZiBjZWxsICovDQogICAgICAgICAgICBjdXJwbGFjZS5iMSA9IDB4ODAwMDsNCiAgICAgICAgICAgIGlmIChkZWJ1ZykNCiAgICAgICAgICAgIAlkb2N1bWVudC53cml0ZSgiPGJyPmIxICIrY3VycGxhY2UuYjEpOw0KICAgICAgICAgICAgY3VycGxhY2UuanVtcCA9IFBsYWNlc1t0cmVlcG9zXTsNCiAgICAgICAgICAgIGN1cnBsYWNlLmp1bXBwb3MgPSB0cmVlcG9zOw0KICAgICAgICAgICAgaWYoUmVjKCkpDQogICAgICAgICAgICAgICAgcmV0dXJuIC0xOw0KICAgICAgICB9DQogICAgICAgIGxlbi0tOw0KICAgICAgICByZXR1cm4gMDsNCiAgICB9Ow0KDQogICAgZnVuY3Rpb24gQ3JlYXRlVHJlZShjdXJyZW50VHJlZSwgbnVtdmFsLCBsZW5ndGhzLCBzaG93KSB7DQogICAgICAgIHZhciBpOw0KICAgICAgICAvKiBDcmVhdGUgdGhlIEh1ZmZtYW4gZGVjb2RlIHRyZWUvdGFibGUgKi8NCiAgICAgICAgLy9kb2N1bWVudC53cml0ZSgiPGJyPmNyZWF0ZXRyZWU8YnI+Iik7DQogICAgICAgIGlmIChkZWJ1ZykNCiAgICAgICAgCWRvY3VtZW50LndyaXRlKCJjdXJyZW50VHJlZSAiK2N1cnJlbnRUcmVlKyIgbnVtdmFsICIrbnVtdmFsKyIgbGVuZ3RocyAiK2xlbmd0aHMrIiBzaG93ICIrc2hvdyk7DQogICAgICAgIFBsYWNlcyA9IGN1cnJlbnRUcmVlOw0KICAgICAgICB0cmVlcG9zPTA7DQogICAgICAgIGZsZW5zID0gbGVuZ3RoczsNCiAgICAgICAgZm1heCAgPSBudW12YWw7DQogICAgICAgIGZvciAoaT0wO2k8MTc7aSsrKQ0KICAgICAgICAgICAgZnBvc1tpXSA9IDA7DQogICAgICAgIGxlbiA9IDA7DQogICAgICAgIGlmKFJlYygpKSB7DQogICAgICAgICAgICAvL2ZwcmludGYoc3RkZXJyLCAiaW52YWxpZCBodWZmbWFuIHRyZWVcbiIpOw0KICAgICAgICAgICAgaWYgKGRlYnVnKQ0KICAgICAgICAgICAgCWFsZXJ0KCJpbnZhbGlkIGh1ZmZtYW4gdHJlZVxuIik7DQogICAgICAgICAgICByZXR1cm4gLTE7DQogICAgICAgIH0NCiAgICAgICAgaWYgKGRlYnVnKXsNCiAgICAgICAgCWRvY3VtZW50LndyaXRlKCc8YnI+VHJlZTogJytQbGFjZXMubGVuZ3RoKTsNCiAgICAgICAgCWZvciAodmFyIGE9MDthPDMyO2ErKyl7DQogICAgICAgICAgICAJZG9jdW1lbnQud3JpdGUoIlBsYWNlc1siK2ErIl0uYjA9IitQbGFjZXNbYV0uYjArIjxicj4iKTsNCiAgICAgICAgICAgIAlkb2N1bWVudC53cml0ZSgiUGxhY2VzWyIrYSsiXS5iMT0iK1BsYWNlc1thXS5iMSsiPGJyPiIpOw0KICAgICAgICAJfQ0KICAgICAgICB9DQogICAgDQogICAgICAgIC8qaWYoc2hvdykgew0KICAgICAgICAgICAgdmFyIHRtcDsNCiAgICAgICAgICAgIGZvcih0bXA9Y3VycmVudFRyZWU7dG1wPFBsYWNlczt0bXArKykgew0KICAgICAgICAgICAgICAgIGZwcmludGYoc3Rkb3V0LCAiMHglMDN4ICAweCUwM3ggKDB4JTA0eCkiLHRtcC1jdXJyZW50VHJlZSwgdG1wLT5qdW1wP3RtcC0+anVtcC1jdXJyZW50VHJlZTowLCh0bXAtPmp1bXA/dG1wLT5qdW1wLWN1cnJlbnRUcmVlOjApKjYrMHhjZjApOw0KICAgICAgICAgICAgICAgIGlmKCEodG1wLmIwICYgMHg4MDAwKSkgew0KICAgICAgICAgICAgICAgICAgICAvL2ZwcmludGYoc3Rkb3V0LCAiICAweCUwM3ggKCVjKSIsIHRtcC0+YjAsKHRtcC0+YjA8MjU2ICYmIGlzcHJpbnQodG1wLT5iMCkpP3RtcC0+YjA6JxoaGicpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZighKHRtcC5iMSAmIDB4ODAwMCkpIHsNCiAgICAgICAgICAgICAgICAgICAgaWYoKHRtcC5iMCAmIDB4ODAwMCkpDQogICAgICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZG91dCwgIiAgICAgICAgICAgIik7DQogICAgICAgICAgICAgICAgICAgIGZwcmludGYoc3Rkb3V0LCAiICAweCUwM3ggKCVjKSIsIHRtcC0+YjEsKHRtcC0+YjE8MjU2ICYmIGlzcHJpbnQodG1wLT5iMSkpP3RtcC0+YjE6JxoaGicpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZG91dCwgIlxuIik7DQogICAgICAgICAgICB9DQogICAgICAgIH0qLw0KICAgICAgICByZXR1cm4gMDsNCiAgICB9Ow0KICAgIA0KICAgIGZ1bmN0aW9uIERlY29kZVZhbHVlKGN1cnJlbnRUcmVlKSB7DQogICAgICAgIHZhciBsZW4sIGksDQogICAgICAgICAgICB4dHJlZXBvcz0wLA0KICAgICAgICAgICAgWCA9IGN1cnJlbnRUcmVlW3h0cmVlcG9zXSwNCiAgICAgICAgICAgIGI7DQoNCiAgICAgICAgLyogZGVjb2RlIG9uZSBzeW1ib2wgb2YgdGhlIGRhdGEgKi8NCiAgICAgICAgd2hpbGUoMSkgew0KICAgICAgICAgICAgYj1yZWFkQml0KCk7DQogICAgICAgICAgICBpZiAoZGVidWcpDQogICAgICAgICAgICAJZG9jdW1lbnQud3JpdGUoImI9IitiKTsNCiAgICAgICAgICAgIGlmKGIpIHsNCiAgICAgICAgICAgICAgICBpZighKFguYjEgJiAweDgwMDApKXsNCiAgICAgICAgICAgICAgICAJaWYgKGRlYnVnKQ0KICAgICAgICAgICAgICAgICAgICAJZG9jdW1lbnQud3JpdGUoInJldDEiKTsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFguYjE7ICAgIC8qIElmIGxlYWYgbm9kZSwgcmV0dXJuIGRhdGEgKi8NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgWCA9IFguanVtcDsNCiAgICAgICAgICAgICAgICBsZW4gPSBjdXJyZW50VHJlZS5sZW5ndGg7DQogICAgICAgICAgICAgICAgZm9yIChpPTA7aTxsZW47aSsrKXsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRUcmVlW2ldPT09WCl7DQogICAgICAgICAgICAgICAgICAgICAgICB4dHJlZXBvcz1pOw0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgLy94dHJlZXBvcysrOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBpZighKFguYjAgJiAweDgwMDApKXsNCiAgICAgICAgICAgICAgICAJaWYgKGRlYnVnKQ0KICAgICAgICAgICAgICAgICAgICAJZG9jdW1lbnQud3JpdGUoInJldDIiKTsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFguYjA7ICAgIC8qIElmIGxlYWYgbm9kZSwgcmV0dXJuIGRhdGEgKi8NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgLy9YKys7IC8vPz8/Pz8/Pz8/Pz8/Pz8/Pz8/DQogICAgICAgICAgICAgICAgeHRyZWVwb3MrKzsNCiAgICAgICAgICAgICAgICBYID0gY3VycmVudFRyZWVbeHRyZWVwb3NdOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChkZWJ1ZykNCiAgICAgICAgCWRvY3VtZW50LndyaXRlKCJyZXQzIik7DQogICAgICAgIHJldHVybiAtMTsNCiAgICB9Ow0KICAgIA0KICAgIGZ1bmN0aW9uIERlZmxhdGVMb29wKCkgew0KICAgIHZhciBsYXN0LCBjLCB0eXBlLCBpLCBsZW47DQoNCiAgICBkbyB7DQogICAgICAgIC8qaWYoKGxhc3QgPSByZWFkQml0KCkpKXsNCiAgICAgICAgICAgIGZwcmludGYoZXJyZnAsICJMYXN0IEJsb2NrOiAiKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGZwcmludGYoZXJyZnAsICJOb3QgTGFzdCBCbG9jazogIik7DQogICAgICAgIH0qLw0KICAgICAgICBsYXN0ID0gcmVhZEJpdCgpOw0KICAgICAgICB0eXBlID0gcmVhZEJpdHMoMik7DQogICAgICAgIHN3aXRjaCh0eXBlKSB7DQogICAgICAgICAgICBjYXNlIDA6DQogICAgICAgICAgICAJaWYgKGRlYnVnKQ0KICAgICAgICAgICAgICAgIAlhbGVydCgiU3RvcmVkXG4iKTsNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIGNhc2UgMToNCiAgICAgICAgICAgIAlpZiAoZGVidWcpDQogICAgICAgICAgICAgICAgCWFsZXJ0KCJGaXhlZCBIdWZmbWFuIGNvZGVzXG4iKTsNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIGNhc2UgMjoNCiAgICAgICAgICAgIAlpZiAoZGVidWcpDQogICAgICAgICAgICAgICAgCWFsZXJ0KCJEeW5hbWljIEh1ZmZtYW4gY29kZXNcbiIpOw0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgY2FzZSAzOg0KICAgICAgICAgICAgCWlmIChkZWJ1ZykNCiAgICAgICAgICAgICAgICAJYWxlcnQoIlJlc2VydmVkIGJsb2NrIHR5cGUhIVxuIik7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICBkZWZhdWx0Og0KICAgICAgICAgICAgCWlmIChkZWJ1ZykNCiAgICAgICAgICAgICAgICAJYWxlcnQoIlVuZXhwZWN0ZWQgdmFsdWUgJWQhXG4iLCB0eXBlKTsNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KDQogICAgICAgIGlmKHR5cGU9PTApIHsNCiAgICAgICAgICAgIHZhciBibG9ja0xlbiwgY1N1bTsNCg0KICAgICAgICAgICAgLy8gU3RvcmVkIA0KICAgICAgICAgICAgYnl0ZUFsaWduKCk7DQogICAgICAgICAgICBibG9ja0xlbiA9IHJlYWRCeXRlKCk7DQogICAgICAgICAgICBibG9ja0xlbiB8PSAocmVhZEJ5dGUoKTw8OCk7DQoNCiAgICAgICAgICAgIGNTdW0gPSByZWFkQnl0ZSgpOw0KICAgICAgICAgICAgY1N1bSB8PSAocmVhZEJ5dGUoKTw8OCk7DQoNCiAgICAgICAgICAgIGlmKCgoYmxvY2tMZW4gXiB+Y1N1bSkgJiAweGZmZmYpKSB7DQogICAgICAgICAgICAgICAgZG9jdW1lbnQud3JpdGUoIkJsb2NrTGVuIGNoZWNrc3VtIG1pc21hdGNoXG4iKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHdoaWxlKGJsb2NrTGVuLS0pIHsNCiAgICAgICAgICAgICAgICBjID0gcmVhZEJ5dGUoKTsNCiAgICAgICAgICAgICAgICBhZGRCdWZmZXIoYyk7DQogICAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSBpZih0eXBlPT0xKSB7DQogICAgICAgICAgICB2YXIgajsNCg0KICAgICAgICAgICAgLyogRml4ZWQgSHVmZm1hbiB0YWJsZXMgLS0gZml4ZWQgZGVjb2RlIHJvdXRpbmUgKi8NCiAgICAgICAgICAgIHdoaWxlKDEpIHsNCiAgICAgICAgICAgIC8qDQogICAgICAgICAgICAgICAgMjU2ICAgIDAwMDAwMDAgICAgICAgIDANCiAgICAgICAgICAgICAgICA6ICAgOiAgICAgOg0KICAgICAgICAgICAgICAgIDI3OSAgICAwMDEwMTExICAgICAgICAyMw0KICAgICAgICAgICAgICAgIDAgICAwMDExMDAwMCAgICA0OA0KICAgICAgICAgICAgICAgIDogICAgOiAgICAgIDoNCiAgICAgICAgICAgICAgICAxNDMgICAgMTAxMTExMTEgICAgMTkxDQogICAgICAgICAgICAgICAgMjgwIDExMDAwMDAwICAgIDE5Mg0KICAgICAgICAgICAgICAgIDogICAgOiAgICAgIDoNCiAgICAgICAgICAgICAgICAyODcgMTEwMDAxMTEgICAgMTk5DQogICAgICAgICAgICAgICAgMTQ0ICAgIDExMDAxMDAwMCAgICA0MDANCiAgICAgICAgICAgICAgICA6ICAgIDogICAgICAgOg0KICAgICAgICAgICAgICAgIDI1NSAgICAxMTExMTExMTEgICAgNTExDQogICAgDQogICAgICAgICAgICAgICAgTm90ZSB0aGUgYml0IG9yZGVyIQ0KICAgICAgICAgICAgICAgICovDQoNCiAgICAgICAgICAgIGogPSAoYml0UmV2ZXJzZVtyZWFkQml0cyg3KV0+PjEpOw0KICAgICAgICAgICAgaWYoaiA+IDIzKSB7DQogICAgICAgICAgICAgICAgaiA9IChqPDwxKSB8IHJlYWRCaXQoKTsgICAgLyogNDguLjI1NSAqLw0KDQogICAgICAgICAgICAgICAgaWYoaiA+IDE5OSkgeyAgICAvKiAyMDAuLjI1NSAqLw0KICAgICAgICAgICAgICAgICAgICBqIC09IDEyODsgICAgLyogIDcyLi4xMjcgKi8NCiAgICAgICAgICAgICAgICAgICAgaiA9IChqPDwxKSB8IHJlYWRCaXQoKTsgICAgICAgIC8qIDE0NC4uMjU1IDw8ICovDQogICAgICAgICAgICAgICAgfSBlbHNlIHsgICAgICAgIC8qICA0OC4uMTk5ICovDQogICAgICAgICAgICAgICAgICAgIGogLT0gNDg7ICAgIC8qICAgMC4uMTUxICovDQogICAgICAgICAgICAgICAgICAgIGlmKGogPiAxNDMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGogPSBqKzEzNjsgICAgLyogMjgwLi4yODcgPDwgKi8NCiAgICAgICAgICAgICAgICAgICAgICAgIC8qICAgMC4uMTQzIDw8ICovDQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9IGVsc2UgeyAgICAvKiAgIDAuLjIzICovDQogICAgICAgICAgICAgICAgaiArPSAyNTY7ICAgIC8qIDI1Ni4uMjc5IDw8ICovDQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZihqIDwgMjU2KSB7DQogICAgICAgICAgICAgICAgYWRkQnVmZmVyKGopOw0KICAgICAgICAgICAgICAgIC8vZG9jdW1lbnQud3JpdGUoIm91dDoiK1N0cmluZy5mcm9tQ2hhckNvZGUoaikpOw0KICAgICAgICAgICAgICAgIC8qZnByaW50ZihlcnJmcCwgIkAlZCAlMDJ4XG4iLCBTSVpFLCBqKTsqLw0KICAgICAgICAgICAgfSBlbHNlIGlmKGogPT0gMjU2KSB7DQogICAgICAgICAgICAgICAgLyogRU9GICovDQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHZhciBsZW4sIGRpc3Q7DQoNCiAgICAgICAgICAgICAgICBqIC09IDI1NiArIDE7ICAgIC8qIGJ5dGVzICsgRU9GICovDQogICAgICAgICAgICAgICAgbGVuID0gcmVhZEJpdHMoY3BsZXh0W2pdKSArIGNwbGVuc1tqXTsNCg0KICAgICAgICAgICAgICAgIGogPSBiaXRSZXZlcnNlW3JlYWRCaXRzKDUpXT4+MzsNCiAgICAgICAgICAgICAgICBpZihjcGRleHRbal0gPiA4KSB7DQogICAgICAgICAgICAgICAgICAgIGRpc3QgPSByZWFkQml0cyg4KTsNCiAgICAgICAgICAgICAgICAgICAgZGlzdCB8PSAocmVhZEJpdHMoY3BkZXh0W2pdLTgpPDw4KTsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBkaXN0ID0gcmVhZEJpdHMoY3BkZXh0W2pdKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgZGlzdCArPSBjcGRpc3Rbal07DQoNCiAgICAgICAgICAgICAgICAvKmZwcmludGYoZXJyZnAsICJAJWQgKGwlMDJ4LGQlMDR4KVxuIiwgU0laRSwgbGVuLCBkaXN0KTsqLw0KICAgICAgICAgICAgICAgIGZvcihqPTA7ajxsZW47aisrKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBjID0gYnVmMzJrWyhiSWR4IC0gZGlzdCkgJiAweDdmZmZdOw0KICAgICAgICAgICAgICAgICAgICBhZGRCdWZmZXIoYyk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSAvLyB3aGlsZQ0KICAgICAgICB9IGVsc2UgaWYodHlwZT09Mikgew0KICAgICAgICAgICAgdmFyIGosIG4sIGxpdGVyYWxDb2RlcywgZGlzdENvZGVzLCBsZW5Db2RlczsNCiAgICAgICAgICAgIHZhciBsbCA9IG5ldyBBcnJheSgyODgrMzIpOyAgICAvLyAic3RhdGljIiBqdXN0IHRvIHByZXNlcnZlIHN0YWNrDQogICAgDQogICAgICAgICAgICAvLyBEeW5hbWljIEh1ZmZtYW4gdGFibGVzIA0KICAgIA0KICAgICAgICAgICAgbGl0ZXJhbENvZGVzID0gMjU3ICsgcmVhZEJpdHMoNSk7DQogICAgICAgICAgICBkaXN0Q29kZXMgPSAxICsgcmVhZEJpdHMoNSk7DQogICAgICAgICAgICBsZW5Db2RlcyA9IDQgKyByZWFkQml0cyg0KTsNCiAgICAgICAgICAgIC8vZG9jdW1lbnQud3JpdGUoIjxicj5wYXJhbTogIitsaXRlcmFsQ29kZXMrIiAiK2Rpc3RDb2RlcysiICIrbGVuQ29kZXMrIjxicj4iKTsNCiAgICAgICAgICAgIGZvcihqPTA7IGo8MTk7IGorKykgew0KICAgICAgICAgICAgICAgIGxsW2pdID0gMDsNCiAgICAgICAgICAgIH0NCiAgICANCiAgICAgICAgICAgIC8vIEdldCB0aGUgZGVjb2RlIHRyZWUgY29kZSBsZW5ndGhzDQogICAgDQogICAgICAgICAgICAvL2RvY3VtZW50LndyaXRlKCI8YnI+Iik7DQogICAgICAgICAgICBmb3Ioaj0wOyBqPGxlbkNvZGVzOyBqKyspIHsNCiAgICAgICAgICAgICAgICBsbFtib3JkZXJbal1dID0gcmVhZEJpdHMoMyk7DQogICAgICAgICAgICAgICAgLy9kb2N1bWVudC53cml0ZShsbFtib3JkZXJbal1dKyIgIik7DQogICAgICAgICAgICB9DQogICAgICAgICAgICAvL2ZwcmludGYoZXJyZnAsICJcbiIpOw0KICAgICAgICAgICAgLy9kb2N1bWVudC53cml0ZSgnPGJyPmxsOicrbGwpOw0KICAgICAgICAgICAgbGVuID0gZGlzdGFuY2VUcmVlLmxlbmd0aDsNCiAgICAgICAgICAgIGZvciAoaT0wOyBpPGxlbjsgaSsrKQ0KICAgICAgICAgICAgICAgIGRpc3RhbmNlVHJlZVtpXT1uZXcgSHVmTm9kZSgpOw0KICAgICAgICAgICAgaWYoQ3JlYXRlVHJlZShkaXN0YW5jZVRyZWUsIDE5LCBsbCwgMCkpIHsNCiAgICAgICAgICAgICAgICBmbHVzaEJ1ZmZlcigpOw0KICAgICAgICAgICAgICAgIHJldHVybiAxOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYgKGRlYnVnKXsNCiAgICAgICAgICAgIAlkb2N1bWVudC53cml0ZSgiPGJyPmRpc3RhbmNlVHJlZSIpOw0KICAgICAgICAgICAgCWZvcih2YXIgYT0wO2E8ZGlzdGFuY2VUcmVlLmxlbmd0aDthKyspew0KICAgICAgICAgICAgICAgIAlkb2N1bWVudC53cml0ZSgiPGJyPiIrZGlzdGFuY2VUcmVlW2FdLmIwKyIgIitkaXN0YW5jZVRyZWVbYV0uYjErIiAiK2Rpc3RhbmNlVHJlZVthXS5qdW1wKyIgIitkaXN0YW5jZVRyZWVbYV0uanVtcHBvcyk7DQogICAgICAgICAgICAgICAgCS8qaWYgKGRpc3RhbmNlVHJlZVthXS5qdW1wcG9zIT0tMSkNCiAgICAgICAgICAgICAgICAgICAgCWRvY3VtZW50LndyaXRlKCIgIitkaXN0YW5jZVRyZWVbYV0uanVtcC5iMCsiICIrZGlzdGFuY2VUcmVlW2FdLmp1bXAuYjEpOw0KICAgICAgICAgICAgICAgIAkqLw0KICAgICAgICAgICAgCX0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIC8vZG9jdW1lbnQud3JpdGUoJzxCUj50cmVlIGNyZWF0ZWQnKTsNCiAgICANCiAgICAgICAgICAgIC8vcmVhZCBpbiBsaXRlcmFsIGFuZCBkaXN0YW5jZSBjb2RlIGxlbmd0aHMNCiAgICAgICAgICAgIG4gPSBsaXRlcmFsQ29kZXMgKyBkaXN0Q29kZXM7DQogICAgICAgICAgICBpID0gMDsNCiAgICAgICAgICAgIHZhciB6PS0xOw0KICAgICAgICAgICAgaWYgKGRlYnVnKQ0KICAgICAgICAgICAgCWRvY3VtZW50LndyaXRlKCI8YnI+bj0iK24rIiBiaXRzOiAiK2JpdHMrIjxicj4iKTsNCiAgICAgICAgICAgIHdoaWxlKGkgPCBuKSB7DQogICAgICAgICAgICAgICAgeisrOw0KICAgICAgICAgICAgICAgIGogPSBEZWNvZGVWYWx1ZShkaXN0YW5jZVRyZWUpOw0KICAgICAgICAgICAgICAgIGlmIChkZWJ1ZykNCiAgICAgICAgICAgICAgICAJZG9jdW1lbnQud3JpdGUoIjxicj4iK3orIiBpOiIraSsiIGRlY29kZTogIitqKyIgICAgYml0cyAiK2JpdHMrIjxicj4iKTsNCiAgICAgICAgICAgICAgICBpZihqPDE2KSB7ICAgIC8vIGxlbmd0aCBvZiBjb2RlIGluIGJpdHMgKDAuLjE1KQ0KICAgICAgICAgICAgICAgICAgICAgICBsbFtpKytdID0gajsNCiAgICAgICAgICAgICAgICB9IGVsc2UgaWYoaj09MTYpIHsgICAgLy8gcmVwZWF0IGxhc3QgbGVuZ3RoIDMgdG8gNiB0aW1lcyANCiAgICAgICAgICAgICAgICAgICAgICAgdmFyIGw7DQogICAgICAgICAgICAgICAgICAgIGogPSAzICsgcmVhZEJpdHMoMik7DQogICAgICAgICAgICAgICAgICAgIGlmKGkraiA+IG4pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGZsdXNoQnVmZmVyKCk7DQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICBsID0gaSA/IGxsW2ktMV0gOiAwOw0KICAgICAgICAgICAgICAgICAgICB3aGlsZShqLS0pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGxsW2krK10gPSBsOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgaWYoaj09MTcpIHsgICAgICAgIC8vIDMgdG8gMTAgemVybyBsZW5ndGggY29kZXMNCiAgICAgICAgICAgICAgICAgICAgICAgIGogPSAzICsgcmVhZEJpdHMoMyk7DQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7ICAgICAgICAvLyBqID09IDE4OiAxMSB0byAxMzggemVybyBsZW5ndGggY29kZXMgDQogICAgICAgICAgICAgICAgICAgICAgICBqID0gMTEgKyByZWFkQml0cyg3KTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICBpZihpK2ogPiBuKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBmbHVzaEJ1ZmZlcigpOw0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgd2hpbGUoai0tKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBsbFtpKytdID0gMDsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIC8qZm9yKGo9MDsgajxsaXRlcmFsQ29kZXMrZGlzdENvZGVzOyBqKyspIHsNCiAgICAgICAgICAgICAgICAvL2ZwcmludGYoZXJyZnAsICIlZCAiLCBsbFtqXSk7DQogICAgICAgICAgICAgICAgaWYgKChqJjcpPT03KQ0KICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKGVycmZwLCAiXG4iKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGZwcmludGYoZXJyZnAsICJcbiIpOyovDQogICAgICAgICAgICAvLyBDYW4gb3ZlcndyaXRlIHRyZWUgZGVjb2RlIHRyZWUgYXMgaXQgaXMgbm90IHVzZWQgYW55bW9yZQ0KICAgICAgICAgICAgbGVuID0gbGl0ZXJhbFRyZWUubGVuZ3RoOw0KICAgICAgICAgICAgZm9yIChpPTA7IGk8bGVuOyBpKyspDQogICAgICAgICAgICAgICAgbGl0ZXJhbFRyZWVbaV09bmV3IEh1Zk5vZGUoKTsNCiAgICAgICAgICAgIGlmKENyZWF0ZVRyZWUobGl0ZXJhbFRyZWUsIGxpdGVyYWxDb2RlcywgbGwsIDApKSB7DQogICAgICAgICAgICAgICAgZmx1c2hCdWZmZXIoKTsNCiAgICAgICAgICAgICAgICByZXR1cm4gMTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGxlbiA9IGxpdGVyYWxUcmVlLmxlbmd0aDsNCiAgICAgICAgICAgIGZvciAoaT0wOyBpPGxlbjsgaSsrKQ0KICAgICAgICAgICAgICAgIGRpc3RhbmNlVHJlZVtpXT1uZXcgSHVmTm9kZSgpOw0KICAgICAgICAgICAgdmFyIGxsMiA9IG5ldyBBcnJheSgpOw0KICAgICAgICAgICAgZm9yIChpPWxpdGVyYWxDb2RlczsgaSA8bGwubGVuZ3RoOyBpKyspew0KICAgICAgICAgICAgICAgIGxsMltpLWxpdGVyYWxDb2Rlc109bGxbaV07DQogICAgICAgICAgICB9ICAgIA0KICAgICAgICAgICAgaWYoQ3JlYXRlVHJlZShkaXN0YW5jZVRyZWUsIGRpc3RDb2RlcywgbGwyLCAwKSkgew0KICAgICAgICAgICAgICAgIGZsdXNoQnVmZmVyKCk7DQogICAgICAgICAgICAgICAgcmV0dXJuIDE7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAoZGVidWcpDQogICAgICAgICAgIAkJZG9jdW1lbnQud3JpdGUoIjxicj5saXRlcmFsVHJlZSIpOw0KICAgICAgICAgICAgb3V0ZXI6DQogICAgICAgICAgICB3aGlsZSgxKSB7DQogICAgICAgICAgICAgICAgaiA9IERlY29kZVZhbHVlKGxpdGVyYWxUcmVlKTsNCiAgICAgICAgICAgICAgICBpZihqID49IDI1NikgeyAgICAgICAgLy8gSW4gQzY0OiBpZiBjYXJyeSBzZXQNCiAgICAgICAgICAgICAgICAgICAgdmFyIGxlbiwgZGlzdDsNCiAgICAgICAgICAgICAgICAgICAgaiAtPSAyNTY7DQogICAgICAgICAgICAgICAgICAgIGlmKGogPT0gMCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gRU9GDQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICBqLS07DQogICAgICAgICAgICAgICAgICAgIGxlbiA9IHJlYWRCaXRzKGNwbGV4dFtqXSkgKyBjcGxlbnNbal07DQogICAgDQogICAgICAgICAgICAgICAgICAgIGogPSBEZWNvZGVWYWx1ZShkaXN0YW5jZVRyZWUpOw0KICAgICAgICAgICAgICAgICAgICBpZihjcGRleHRbal0gPiA4KSB7DQogICAgICAgICAgICAgICAgICAgICAgICBkaXN0ID0gcmVhZEJpdHMoOCk7DQogICAgICAgICAgICAgICAgICAgICAgICBkaXN0IHw9IChyZWFkQml0cyhjcGRleHRbal0tOCk8PDgpOw0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgZGlzdCA9IHJlYWRCaXRzKGNwZGV4dFtqXSk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgZGlzdCArPSBjcGRpc3Rbal07DQogICAgICAgICAgICAgICAgICAgIHdoaWxlKGxlbi0tKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBpZihiSWR4IC0gZGlzdCA8IDApIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjID0gYnVmMzJrWyhiSWR4IC0gZGlzdCkgJiAweDdmZmZdOw0KICAgICAgICAgICAgICAgICAgICAgICAgYWRkQnVmZmVyKGMpOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgYWRkQnVmZmVyKGopOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0gd2hpbGUoIWxhc3QpOw0KICAgIGZsdXNoQnVmZmVyKCk7DQoNCiAgICBieXRlQWxpZ24oKTsNCiAgICByZXR1cm4gMDsNCn07DQoNCkpYRy5VdGlsLlVuemlwLnByb3RvdHlwZS51bnppcEZpbGUgPSBmdW5jdGlvbihuYW1lKSB7DQogICAgdmFyIGk7DQoJdGhpcy51bnppcCgpOw0KCS8vYWxlcnQodW56aXBwZWRbMF1bMV0pOw0KCWZvciAoaT0wO2k8dW56aXBwZWQubGVuZ3RoO2krKyl7DQoJCWlmKHVuemlwcGVkW2ldWzFdPT1uYW1lKSB7DQoJCQlyZXR1cm4gdW56aXBwZWRbaV1bMF07DQoJCX0NCgl9DQoJDQogIH07DQoNCkpYRy5VdGlsLlVuemlwLnByb3RvdHlwZS5kZWZsYXRlID0gZnVuY3Rpb24oKSB7DQogICAgb3V0cHV0QXJyID0gW107DQogICAgdmFyIHRtcCA9IFtdOw0KICAgIG1vZGVaSVAgPSBmYWxzZTsNCiAgICBEZWZsYXRlTG9vcCgpOw0KICAgIGlmIChkZWJ1ZykNCiAgICAgICAgYWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTsNCiAgICB1bnppcHBlZFtmaWxlc10gPSBuZXcgQXJyYXkoMik7DQogICAgdW56aXBwZWRbZmlsZXNdWzBdID0gb3V0cHV0QXJyLmpvaW4oJycpOw0KICAgIHVuemlwcGVkW2ZpbGVzXVsxXSA9ICJERUZMQVRFIjsNCiAgICBmaWxlcysrOw0KICAgIHJldHVybiB1bnppcHBlZDsNCn0gICAgDQogICAgDQpKWEcuVXRpbC5VbnppcC5wcm90b3R5cGUudW56aXAgPSBmdW5jdGlvbigpIHsNCgkvL2NvbnZlcnRUb0J5dGVBcnJheShpbnB1dCk7DQoJaWYgKGRlYnVnKQ0KCQlhbGVydChiQSk7DQoJLypmb3IgKGk9MDtpPGJBLmxlbmd0aCo4O2krKyl7DQoJCWRvY3VtZW50LndyaXRlKHJlYWRCaXQoKSk7DQoJCWlmICgoaSsxKSU4PT0wKQ0KCQkJZG9jdW1lbnQud3JpdGUoIiAiKTsNCgl9Ki8NCgkvKmZvciAoaT0wO2k8YkEubGVuZ3RoO2krKyl7DQoJCWRvY3VtZW50LndyaXRlKHJlYWRCeXRlKCkrIiAiKTsNCgkJaWYgKChpKzEpJTg9PTApDQoJCQlkb2N1bWVudC53cml0ZSgiICIpOw0KCX0NCglmb3IgKGk9MDtpPGJBLmxlbmd0aDtpKyspew0KCQlkb2N1bWVudC53cml0ZShiQVtpXSsiICIpOw0KCQlpZiAoKGkrMSklMTY9PTApDQoJCQlkb2N1bWVudC53cml0ZSgiPGJyPiIpOw0KCX0JDQoJKi8NCgkvL2FsZXJ0KGJBKTsNCgluZXh0RmlsZSgpOw0KCXJldHVybiB1bnppcHBlZDsNCiAgfTsNCiAgICANCiBmdW5jdGlvbiBuZXh0RmlsZSgpew0KIAlpZiAoZGVidWcpDQogCQlhbGVydCgiTkVYVEZJTEUiKTsNCiAJb3V0cHV0QXJyID0gW107DQogCXZhciB0bXAgPSBbXTsNCiAJbW9kZVpJUCA9IGZhbHNlOw0KCXRtcFswXSA9IHJlYWRCeXRlKCk7DQoJdG1wWzFdID0gcmVhZEJ5dGUoKTsNCglpZiAoZGVidWcpDQoJCWFsZXJ0KCJ0eXBlOiAiK3RtcFswXSsiICIrdG1wWzFdKTsNCglpZiAodG1wWzBdID09IHBhcnNlSW50KCI3OCIsMTYpICYmIHRtcFsxXSA9PSBwYXJzZUludCgiZGEiLDE2KSl7IC8vR1pJUA0KCQlpZiAoZGVidWcpDQoJCQlhbGVydCgiR0VPTkV4VC1HWklQIik7DQoJCURlZmxhdGVMb29wKCk7DQoJCWlmIChkZWJ1ZykNCgkJCWFsZXJ0KG91dHB1dEFyci5qb2luKCcnKSk7DQoJCXVuemlwcGVkW2ZpbGVzXSA9IG5ldyBBcnJheSgyKTsNCiAgICAJdW56aXBwZWRbZmlsZXNdWzBdID0gb3V0cHV0QXJyLmpvaW4oJycpOw0KICAgIAl1bnppcHBlZFtmaWxlc11bMV0gPSAiZ2VvbmV4dC5neHQiOw0KICAgIAlmaWxlcysrOw0KCX0NCglpZiAodG1wWzBdID09IHBhcnNlSW50KCI3OCIsMTYpICYmIHRtcFsxXSA9PSBwYXJzZUludCgiOWMiLDE2KSl7IC8vWkxJQg0KCQlpZiAoZGVidWcpDQoJCQlhbGVydCgiWkxJQiIpOw0KCQlEZWZsYXRlTG9vcCgpOw0KCQlpZiAoZGVidWcpDQoJCQlhbGVydChvdXRwdXRBcnIuam9pbignJykpOw0KCQl1bnppcHBlZFtmaWxlc10gPSBuZXcgQXJyYXkoMik7DQogICAgCXVuemlwcGVkW2ZpbGVzXVswXSA9IG91dHB1dEFyci5qb2luKCcnKTsNCiAgICAJdW56aXBwZWRbZmlsZXNdWzFdID0gIlpMSUIiOw0KICAgIAlmaWxlcysrOw0KCX0NCglpZiAodG1wWzBdID09IHBhcnNlSW50KCIxZiIsMTYpICYmIHRtcFsxXSA9PSBwYXJzZUludCgiOGIiLDE2KSl7IC8vR1pJUA0KCQlpZiAoZGVidWcpDQoJCQlhbGVydCgiR1pJUCIpOw0KCQkvL0RlZmxhdGVMb29wKCk7DQoJCXNraXBkaXIoKTsNCgkJaWYgKGRlYnVnKQ0KCQkJYWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTsNCgkJdW56aXBwZWRbZmlsZXNdID0gbmV3IEFycmF5KDIpOw0KICAgIAl1bnppcHBlZFtmaWxlc11bMF0gPSBvdXRwdXRBcnIuam9pbignJyk7DQogICAgCXVuemlwcGVkW2ZpbGVzXVsxXSA9ICJmaWxlIjsNCiAgICAJZmlsZXMrKzsNCgl9DQoJaWYgKHRtcFswXSA9PSBwYXJzZUludCgiNTAiLDE2KSAmJiB0bXBbMV0gPT0gcGFyc2VJbnQoIjRiIiwxNikpeyAvL1pJUA0KCQltb2RlWklQID0gdHJ1ZTsNCgkJdG1wWzJdID0gcmVhZEJ5dGUoKTsNCgkJdG1wWzNdID0gcmVhZEJ5dGUoKTsNCgkJaWYgKHRtcFsyXSA9PSBwYXJzZUludCgiMyIsMTYpICYmIHRtcFszXSA9PSBwYXJzZUludCgiNCIsMTYpKXsNCgkJCS8vTU9ERV9aSVANCgkJCXRtcFswXSA9IHJlYWRCeXRlKCk7DQoJCQl0bXBbMV0gPSByZWFkQnl0ZSgpOw0KCQkJaWYgKGRlYnVnKQ0KCQkJCWFsZXJ0KCJaSVAtVmVyc2lvbjogIit0bXBbMV0rIiAiK3RtcFswXS8xMCsiLiIrdG1wWzBdJTEwKTsNCgkJCQ0KCQkJZ3BmbGFncyA9IHJlYWRCeXRlKCk7DQoJCQlncGZsYWdzIHw9IChyZWFkQnl0ZSgpPDw4KTsNCgkJCWlmIChkZWJ1ZykNCgkJCQlhbGVydCgiZ3BmbGFnczogIitncGZsYWdzKTsNCgkJCQ0KCQkJdmFyIG1ldGhvZCA9IHJlYWRCeXRlKCk7DQoJCQltZXRob2QgfD0gKHJlYWRCeXRlKCk8PDgpOw0KCQkJaWYgKGRlYnVnKQ0KCQkJCWFsZXJ0KCJtZXRob2Q6ICIrbWV0aG9kKTsNCgkJCQ0KCQkJcmVhZEJ5dGUoKTsNCgkJCXJlYWRCeXRlKCk7DQoJCQlyZWFkQnl0ZSgpOw0KCQkJcmVhZEJ5dGUoKTsNCgkJCQ0KCQkJdmFyIGNyYyA9IHJlYWRCeXRlKCk7DQoJCQljcmMgfD0gKHJlYWRCeXRlKCk8PDgpOw0KCQkJY3JjIHw9IChyZWFkQnl0ZSgpPDwxNik7DQoJCQljcmMgfD0gKHJlYWRCeXRlKCk8PDI0KTsNCgkJCQ0KCQkJdmFyIGNvbXBTaXplID0gcmVhZEJ5dGUoKTsNCgkJCWNvbXBTaXplIHw9IChyZWFkQnl0ZSgpPDw4KTsNCgkJCWNvbXBTaXplIHw9IChyZWFkQnl0ZSgpPDwxNik7DQoJCQljb21wU2l6ZSB8PSAocmVhZEJ5dGUoKTw8MjQpOw0KCQkJDQoJCQl2YXIgc2l6ZSA9IHJlYWRCeXRlKCk7DQoJCQlzaXplIHw9IChyZWFkQnl0ZSgpPDw4KTsNCgkJCXNpemUgfD0gKHJlYWRCeXRlKCk8PDE2KTsNCgkJCXNpemUgfD0gKHJlYWRCeXRlKCk8PDI0KTsNCgkJCQ0KCQkJaWYgKGRlYnVnKQ0KCQkJCWFsZXJ0KCJsb2NhbCBDUkM6ICIrY3JjKyJcbmxvY2FsIFNpemU6ICIrc2l6ZSsiXG5sb2NhbCBDb21wU2l6ZTogIitjb21wU2l6ZSk7DQoJCQkNCgkJCXZhciBmaWxlbGVuID0gcmVhZEJ5dGUoKTsNCgkJCWZpbGVsZW4gfD0gKHJlYWRCeXRlKCk8PDgpOw0KCQkJDQoJCQl2YXIgZXh0cmFsZW4gPSByZWFkQnl0ZSgpOw0KCQkJZXh0cmFsZW4gfD0gKHJlYWRCeXRlKCk8PDgpOw0KCQkJDQoJCQlpZiAoZGVidWcpDQoJCQkJYWxlcnQoImZpbGVsZW4gIitmaWxlbGVuKTsNCgkJCWkgPSAwOw0KCQkJbmFtZUJ1ZiA9IFtdOw0KCQkJd2hpbGUgKGZpbGVsZW4tLSl7IA0KCQkJCXZhciBjID0gcmVhZEJ5dGUoKTsNCgkJCQlpZiAoYyA9PSAiLyIgfCBjID09IjoiKXsNCgkJCQkJaSA9IDA7DQoJCQkJfSBlbHNlIGlmIChpIDwgTkFNRU1BWC0xKQ0KCQkJCQluYW1lQnVmW2krK10gPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpOw0KCQkJfQ0KCQkJaWYgKGRlYnVnKQ0KCQkJCWFsZXJ0KCJuYW1lQnVmOiAiK25hbWVCdWYpOw0KCQkJDQoJCQkvL25hbWVCdWZbaV0gPSAiXDAiOw0KCQkJaWYgKCFmaWxlb3V0KQ0KCQkJCWZpbGVvdXQgPSBuYW1lQnVmOw0KCQkJDQoJCQl2YXIgaSA9IDA7DQoJCQl3aGlsZSAoaSA8IGV4dHJhbGVuKXsNCgkJCQljID0gcmVhZEJ5dGUoKTsNCgkJCQlpKys7DQoJCQl9DQoJCQkJDQoJCQlDUkMgPSAweGZmZmZmZmZmOw0KCQkJU0laRSA9IDA7DQoJCQkNCgkJCWlmIChzaXplID0gMCAmJiBmaWxlT3V0LmNoYXJBdChmaWxlb3V0Lmxlbmd0aC0xKT09Ii8iKXsNCgkJCQkvL3NraXBkaXINCgkJCQlpZiAoZGVidWcpDQoJCQkJCWFsZXJ0KCJza2lwZGlyIik7DQoJCQl9DQoJCQlpZiAobWV0aG9kID09IDgpew0KCQkJCURlZmxhdGVMb29wKCk7DQoJCQkJaWYgKGRlYnVnKQ0KCQkJCQlhbGVydChvdXRwdXRBcnIuam9pbignJykpOw0KCQkJCXVuemlwcGVkW2ZpbGVzXSA9IG5ldyBBcnJheSgyKTsNCgkJCQl1bnppcHBlZFtmaWxlc11bMF0gPSBvdXRwdXRBcnIuam9pbignJyk7DQogICAgCQkJdW56aXBwZWRbZmlsZXNdWzFdID0gbmFtZUJ1Zi5qb2luKCcnKTsNCiAgICAJCQlmaWxlcysrOw0KCQkJCS8vcmV0dXJuIG91dHB1dEFyci5qb2luKCcnKTsNCgkJCX0NCgkJCXNraXBkaXIoKTsNCgkJfQ0KCX0NCiB9Ow0KCQ0KZnVuY3Rpb24gc2tpcGRpcigpew0KICAgIHZhciBjcmMsIA0KICAgICAgICB0bXAgPSBbXSwNCiAgICAgICAgY29tcFNpemUsIHNpemUsIG9zLCBpLCBjOw0KICAgIA0KCWlmICgoZ3BmbGFncyAmIDgpKSB7DQoJCXRtcFswXSA9IHJlYWRCeXRlKCk7DQoJCXRtcFsxXSA9IHJlYWRCeXRlKCk7DQoJCXRtcFsyXSA9IHJlYWRCeXRlKCk7DQoJCXRtcFszXSA9IHJlYWRCeXRlKCk7DQoJCQ0KCQlpZiAodG1wWzBdID09IHBhcnNlSW50KCI1MCIsMTYpICYmIA0KICAgICAgICAgICAgdG1wWzFdID09IHBhcnNlSW50KCI0YiIsMTYpICYmIA0KICAgICAgICAgICAgdG1wWzJdID09IHBhcnNlSW50KCIwNyIsMTYpICYmIA0KICAgICAgICAgICAgdG1wWzNdID09IHBhcnNlSW50KCIwOCIsMTYpKQ0KICAgICAgICB7DQogICAgICAgICAgICBjcmMgPSByZWFkQnl0ZSgpOw0KICAgICAgICAgICAgY3JjIHw9IChyZWFkQnl0ZSgpPDw4KTsNCiAgICAgICAgICAgIGNyYyB8PSAocmVhZEJ5dGUoKTw8MTYpOw0KICAgICAgICAgICAgY3JjIHw9IChyZWFkQnl0ZSgpPDwyNCk7DQoJCX0gZWxzZSB7DQoJCQljcmMgPSB0bXBbMF0gfCAodG1wWzFdPDw4KSB8ICh0bXBbMl08PDE2KSB8ICh0bXBbM108PDI0KTsNCgkJfQ0KCQkNCgkJY29tcFNpemUgPSByZWFkQnl0ZSgpOw0KCQljb21wU2l6ZSB8PSAocmVhZEJ5dGUoKTw8OCk7DQoJCWNvbXBTaXplIHw9IChyZWFkQnl0ZSgpPDwxNik7DQoJCWNvbXBTaXplIHw9IChyZWFkQnl0ZSgpPDwyNCk7DQoJCQ0KCQlzaXplID0gcmVhZEJ5dGUoKTsNCgkJc2l6ZSB8PSAocmVhZEJ5dGUoKTw8OCk7DQoJCXNpemUgfD0gKHJlYWRCeXRlKCk8PDE2KTsNCgkJc2l6ZSB8PSAocmVhZEJ5dGUoKTw8MjQpOw0KCQkNCgkJaWYgKGRlYnVnKQ0KCQkJYWxlcnQoIkNSQzoiKTsNCgl9DQoNCglpZiAobW9kZVpJUCkNCgkJbmV4dEZpbGUoKTsNCgkNCgl0bXBbMF0gPSByZWFkQnl0ZSgpOw0KCWlmICh0bXBbMF0gIT0gOCkgew0KCQlpZiAoZGVidWcpDQoJCQlhbGVydCgiVW5rbm93biBjb21wcmVzc2lvbiBtZXRob2QhIik7DQogICAgICAgIHJldHVybiAwOwkNCgl9DQoJDQoJZ3BmbGFncyA9IHJlYWRCeXRlKCk7DQoJaWYgKGRlYnVnKXsNCgkJaWYgKChncGZsYWdzICYgfihwYXJzZUludCgiMWYiLDE2KSkpKQ0KCQkJYWxlcnQoIlVua25vd24gZmxhZ3Mgc2V0ISIpOw0KCX0NCgkNCglyZWFkQnl0ZSgpOw0KCXJlYWRCeXRlKCk7DQoJcmVhZEJ5dGUoKTsNCglyZWFkQnl0ZSgpOw0KCQ0KCXJlYWRCeXRlKCk7DQoJb3MgPSByZWFkQnl0ZSgpOw0KCQ0KCWlmICgoZ3BmbGFncyAmIDQpKXsNCgkJdG1wWzBdID0gcmVhZEJ5dGUoKTsNCgkJdG1wWzJdID0gcmVhZEJ5dGUoKTsNCgkJbGVuID0gdG1wWzBdICsgMjU2KnRtcFsxXTsNCgkJaWYgKGRlYnVnKQ0KCQkJYWxlcnQoIkV4dHJhIGZpZWxkIHNpemU6ICIrbGVuKTsNCgkJZm9yIChpPTA7aTxsZW47aSsrKQ0KCQkJcmVhZEJ5dGUoKTsNCgl9DQoJDQoJaWYgKChncGZsYWdzICYgOCkpew0KCQlpPTA7DQoJCW5hbWVCdWY9W107DQoJCXdoaWxlIChjPXJlYWRCeXRlKCkpew0KCQkJaWYoYyA9PSAiNyIgfHwgYyA9PSAiOiIpDQoJCQkJaT0wOw0KCQkJaWYgKGk8TkFNRU1BWC0xKQ0KCQkJCW5hbWVCdWZbaSsrXSA9IGM7DQoJCX0NCgkJLy9uYW1lQnVmW2ldID0gIlwwIjsNCgkJaWYgKGRlYnVnKQ0KCQkJYWxlcnQoIm9yaWdpbmFsIGZpbGUgbmFtZTogIituYW1lQnVmKTsNCgl9DQoJCQ0KCWlmICgoZ3BmbGFncyAmIDE2KSl7DQoJCXdoaWxlIChjPXJlYWRCeXRlKCkpew0KCQkJLy9GSUxFIENPTU1FTlQNCgkJfQ0KCX0NCgkNCglpZiAoKGdwZmxhZ3MgJiAyKSl7DQoJCXJlYWRCeXRlKCk7DQoJCXJlYWRCeXRlKCk7DQoJfQ0KCQ0KCURlZmxhdGVMb29wKCk7DQoJDQoJY3JjID0gcmVhZEJ5dGUoKTsNCgljcmMgfD0gKHJlYWRCeXRlKCk8PDgpOw0KCWNyYyB8PSAocmVhZEJ5dGUoKTw8MTYpOw0KCWNyYyB8PSAocmVhZEJ5dGUoKTw8MjQpOw0KCQ0KCXNpemUgPSByZWFkQnl0ZSgpOw0KCXNpemUgfD0gKHJlYWRCeXRlKCk8PDgpOw0KCXNpemUgfD0gKHJlYWRCeXRlKCk8PDE2KTsNCglzaXplIHw9IChyZWFkQnl0ZSgpPDwyNCk7DQoJDQoJaWYgKG1vZGVaSVApDQoJCW5leHRGaWxlKCk7DQoJDQp9Ow0KDQp9Ow0KDQovKioNCiogIEJhc2U2NCBlbmNvZGluZyAvIGRlY29kaW5nDQoqICB7QGxpbmsgaHR0cDovL3d3dy53ZWJ0b29sa2l0LmluZm8vfQ0KKi8NCkpYRy5VdGlsLkJhc2U2NCA9IHsNCg0KICAgIC8vIHByaXZhdGUgcHJvcGVydHkNCiAgICBfa2V5U3RyIDogIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89IiwNCg0KICAgIC8vIHB1YmxpYyBtZXRob2QgZm9yIGVuY29kaW5nDQogICAgZW5jb2RlIDogZnVuY3Rpb24gKGlucHV0KSB7DQogICAgICAgIHZhciBvdXRwdXQgPSBbXSwNCiAgICAgICAgICAgIGNocjEsIGNocjIsIGNocjMsIGVuYzEsIGVuYzIsIGVuYzMsIGVuYzQsDQogICAgICAgICAgICBpID0gMDsNCg0KICAgICAgICBpbnB1dCA9IEpYRy5VdGlsLkJhc2U2NC5fdXRmOF9lbmNvZGUoaW5wdXQpOw0KDQogICAgICAgIHdoaWxlIChpIDwgaW5wdXQubGVuZ3RoKSB7DQoNCiAgICAgICAgICAgIGNocjEgPSBpbnB1dC5jaGFyQ29kZUF0KGkrKyk7DQogICAgICAgICAgICBjaHIyID0gaW5wdXQuY2hhckNvZGVBdChpKyspOw0KICAgICAgICAgICAgY2hyMyA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTsNCg0KICAgICAgICAgICAgZW5jMSA9IGNocjEgPj4gMjsNCiAgICAgICAgICAgIGVuYzIgPSAoKGNocjEgJiAzKSA8PCA0KSB8IChjaHIyID4+IDQpOw0KICAgICAgICAgICAgZW5jMyA9ICgoY2hyMiAmIDE1KSA8PCAyKSB8IChjaHIzID4+IDYpOw0KICAgICAgICAgICAgZW5jNCA9IGNocjMgJiA2MzsNCg0KICAgICAgICAgICAgaWYgKGlzTmFOKGNocjIpKSB7DQogICAgICAgICAgICAgICAgZW5jMyA9IGVuYzQgPSA2NDsNCiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNOYU4oY2hyMykpIHsNCiAgICAgICAgICAgICAgICBlbmM0ID0gNjQ7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIG91dHB1dC5wdXNoKFt0aGlzLl9rZXlTdHIuY2hhckF0KGVuYzEpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleVN0ci5jaGFyQXQoZW5jMiksDQogICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5U3RyLmNoYXJBdChlbmMzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlTdHIuY2hhckF0KGVuYzQpXS5qb2luKCcnKSk7DQogICAgICAgIH0NCg0KICAgICAgICByZXR1cm4gb3V0cHV0LmpvaW4oJycpOw0KICAgIH0sDQoNCiAgICAvLyBwdWJsaWMgbWV0aG9kIGZvciBkZWNvZGluZw0KICAgIGRlY29kZSA6IGZ1bmN0aW9uIChpbnB1dCwgdXRmOCkgew0KICAgICAgICB2YXIgb3V0cHV0ID0gW10sDQogICAgICAgICAgICBjaHIxLCBjaHIyLCBjaHIzLA0KICAgICAgICAgICAgZW5jMSwgZW5jMiwgZW5jMywgZW5jNCwNCiAgICAgICAgICAgIGkgPSAwOw0KDQogICAgICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZSgvW15BLVphLXowLTlcK1wvXD1dL2csICIiKTsNCg0KICAgICAgICB3aGlsZSAoaSA8IGlucHV0Lmxlbmd0aCkgew0KDQogICAgICAgICAgICBlbmMxID0gdGhpcy5fa2V5U3RyLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpOw0KICAgICAgICAgICAgZW5jMiA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTsNCiAgICAgICAgICAgIGVuYzMgPSB0aGlzLl9rZXlTdHIuaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7DQogICAgICAgICAgICBlbmM0ID0gdGhpcy5fa2V5U3RyLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpOw0KDQogICAgICAgICAgICBjaHIxID0gKGVuYzEgPDwgMikgfCAoZW5jMiA+PiA0KTsNCiAgICAgICAgICAgIGNocjIgPSAoKGVuYzIgJiAxNSkgPDwgNCkgfCAoZW5jMyA+PiAyKTsNCiAgICAgICAgICAgIGNocjMgPSAoKGVuYzMgJiAzKSA8PCA2KSB8IGVuYzQ7DQoNCiAgICAgICAgICAgIG91dHB1dC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMSkpOw0KDQogICAgICAgICAgICBpZiAoZW5jMyAhPSA2NCkgew0KICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMikpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYgKGVuYzQgIT0gNjQpIHsNCiAgICAgICAgICAgICAgICBvdXRwdXQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGNocjMpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICANCiAgICAgICAgb3V0cHV0ID0gb3V0cHV0LmpvaW4oJycpOyANCiAgICAgICAgDQogICAgICAgIGlmICh1dGY4KSB7DQogICAgICAgICAgICBvdXRwdXQgPSBKWEcuVXRpbC5CYXNlNjQuX3V0ZjhfZGVjb2RlKG91dHB1dCk7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIG91dHB1dDsNCg0KICAgIH0sDQoNCiAgICAvLyBwcml2YXRlIG1ldGhvZCBmb3IgVVRGLTggZW5jb2RpbmcNCiAgICBfdXRmOF9lbmNvZGUgOiBmdW5jdGlvbiAoc3RyaW5nKSB7DQogICAgICAgIHN0cmluZyA9IHN0cmluZy5yZXBsYWNlKC9cclxuL2csIlxuIik7DQogICAgICAgIHZhciB1dGZ0ZXh0ID0gIiI7DQoNCiAgICAgICAgZm9yICh2YXIgbiA9IDA7IG4gPCBzdHJpbmcubGVuZ3RoOyBuKyspIHsNCg0KICAgICAgICAgICAgdmFyIGMgPSBzdHJpbmcuY2hhckNvZGVBdChuKTsNCg0KICAgICAgICAgICAgaWYgKGMgPCAxMjgpIHsNCiAgICAgICAgICAgICAgICB1dGZ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYyk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlIGlmKChjID4gMTI3KSAmJiAoYyA8IDIwNDgpKSB7DQogICAgICAgICAgICAgICAgdXRmdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChjID4+IDYpIHwgMTkyKTsNCiAgICAgICAgICAgICAgICB1dGZ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGMgJiA2MykgfCAxMjgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZWxzZSB7DQogICAgICAgICAgICAgICAgdXRmdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChjID4+IDEyKSB8IDIyNCk7DQogICAgICAgICAgICAgICAgdXRmdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyA+PiA2KSAmIDYzKSB8IDEyOCk7DQogICAgICAgICAgICAgICAgdXRmdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChjICYgNjMpIHwgMTI4KTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICB9DQoNCiAgICAgICAgcmV0dXJuIHV0ZnRleHQ7DQogICAgfSwNCg0KICAgIC8vIHByaXZhdGUgbWV0aG9kIGZvciBVVEYtOCBkZWNvZGluZw0KICAgIF91dGY4X2RlY29kZSA6IGZ1bmN0aW9uICh1dGZ0ZXh0KSB7DQogICAgICAgIHZhciBzdHJpbmcgPSBbXSwNCiAgICAgICAgICAgIGkgPSAwLA0KICAgICAgICAgICAgYyA9IDAsIGMyID0gMCwgYzMgPSAwOw0KDQogICAgICAgIHdoaWxlICggaSA8IHV0ZnRleHQubGVuZ3RoICkgew0KICAgICAgICAgICAgYyA9IHV0ZnRleHQuY2hhckNvZGVBdChpKTsNCiAgICAgICAgICAgIGlmIChjIDwgMTI4KSB7DQogICAgICAgICAgICAgICAgc3RyaW5nLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShjKSk7DQogICAgICAgICAgICAgICAgaSsrOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZWxzZSBpZigoYyA+IDE5MSkgJiYgKGMgPCAyMjQpKSB7DQogICAgICAgICAgICAgICAgYzIgPSB1dGZ0ZXh0LmNoYXJDb2RlQXQoaSsxKTsNCiAgICAgICAgICAgICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyAmIDMxKSA8PCA2KSB8IChjMiAmIDYzKSkpOw0KICAgICAgICAgICAgICAgIGkgKz0gMjsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVsc2Ugew0KICAgICAgICAgICAgICAgIGMyID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkrMSk7DQogICAgICAgICAgICAgICAgYzMgPSB1dGZ0ZXh0LmNoYXJDb2RlQXQoaSsyKTsNCiAgICAgICAgICAgICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyAmIDE1KSA8PCAxMikgfCAoKGMyICYgNjMpIDw8IDYpIHwgKGMzICYgNjMpKSk7DQogICAgICAgICAgICAgICAgaSArPSAzOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIHJldHVybiBzdHJpbmcuam9pbignJyk7DQogICAgfSwNCiAgICANCiAgICBfZGVzdHJpcDogZnVuY3Rpb24gKHN0cmlwcGVkLCB3cmFwKXsNCiAgICAgICAgdmFyIGxpbmVzID0gW10sIGxpbmVubywgaSwNCiAgICAgICAgICAgIGRlc3RyaXBwZWQgPSBbXTsNCiAgICAgICAgDQogICAgICAgIGlmICh3cmFwPT1udWxsKSANCiAgICAgICAgICAgIHdyYXAgPSA3NjsNCiAgICAgICAgICAgIA0KICAgICAgICBzdHJpcHBlZC5yZXBsYWNlKC8gL2csICIiKTsNCiAgICAgICAgbGluZW5vID0gc3RyaXBwZWQubGVuZ3RoIC8gd3JhcDsNCiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpbmVubzsgaSsrKQ0KICAgICAgICAgICAgbGluZXNbaV09c3RyaXBwZWQuc3Vic3RyKGkgKiB3cmFwLCB3cmFwKTsNCiAgICAgICAgaWYgKGxpbmVubyAhPSBzdHJpcHBlZC5sZW5ndGggLyB3cmFwKQ0KICAgICAgICAgICAgbGluZXNbbGluZXMubGVuZ3RoXT1zdHJpcHBlZC5zdWJzdHIobGluZW5vICogd3JhcCwgc3RyaXBwZWQubGVuZ3RoLShsaW5lbm8gKiB3cmFwKSk7DQogICAgICAgICAgICANCiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKQ0KICAgICAgICAgICAgZGVzdHJpcHBlZC5wdXNoKGxpbmVzW2ldKTsNCiAgICAgICAgcmV0dXJuIGRlc3RyaXBwZWQuam9pbignXG4nKTsNCiAgICB9LA0KICAgIA0KICAgIGRlY29kZUFzQXJyYXk6IGZ1bmN0aW9uIChpbnB1dCl7DQogICAgICAgIHZhciBkZWMgPSB0aGlzLmRlY29kZShpbnB1dCksDQogICAgICAgICAgICBhciA9IFtdLCBpOw0KICAgICAgICBmb3IgKGk9MDtpPGRlYy5sZW5ndGg7aSsrKXsNCiAgICAgICAgICAgIGFyW2ldPWRlYy5jaGFyQ29kZUF0KGkpOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiBhcjsNCiAgICB9LA0KICAgIA0KICAgIGRlY29kZUdFT05FeFQgOiBmdW5jdGlvbiAoaW5wdXQpIHsNCiAgICAgICAgcmV0dXJuIGRlY29kZUFzQXJyYXkoZGVzdHJpcChpbnB1dCksZmFsc2UpOw0KICAgIH0NCn07DQoNCi8qKg0KICogQHByaXZhdGUNCiAqLw0KSlhHLlV0aWwuYXNjaWlDaGFyQ29kZUF0ID0gZnVuY3Rpb24oc3RyLGkpew0KCXZhciBjID0gc3RyLmNoYXJDb2RlQXQoaSk7DQoJaWYgKGM+MjU1KXsNCiAgICAJc3dpdGNoIChjKSB7DQoJCQljYXNlIDgzNjQ6IGM9MTI4Ow0KCSAgICAJYnJlYWs7DQoJICAgIAljYXNlIDgyMTg6IGM9MTMwOw0KCSAgICAJYnJlYWs7DQoJICAgIAljYXNlIDQwMjogYz0xMzE7DQoJICAgIAlicmVhazsNCgkgICAgCWNhc2UgODIyMjogYz0xMzI7DQoJICAgIAlicmVhazsNCgkgICAgCWNhc2UgODIzMDogYz0xMzM7DQoJICAgIAlicmVhazsNCgkgICAgCWNhc2UgODIyNDogYz0xMzQ7DQoJICAgIAlicmVhazsNCgkgICAgCWNhc2UgODIyNTogYz0xMzU7DQoJICAgIAlicmVhazsNCgkgICAgCWNhc2UgNzEwOiBjPTEzNjsNCgkgICAgCWJyZWFrOw0KCSAgICAJY2FzZSA4MjQwOiBjPTEzNzsNCgkgICAgCWJyZWFrOw0KCSAgICAJY2FzZSAzNTI6IGM9MTM4Ow0KCSAgICAJYnJlYWs7DQoJICAgIAljYXNlIDgyNDk6IGM9MTM5Ow0KCSAgICAJYnJlYWs7DQoJICAgIAljYXNlIDMzODogYz0xNDA7DQoJICAgIAlicmVhazsNCgkgICAgCWNhc2UgMzgxOiBjPTE0MjsNCgkgICAgCWJyZWFrOw0KCSAgICAJY2FzZSA4MjE2OiBjPTE0NTsNCgkgICAgCWJyZWFrOw0KCSAgICAJY2FzZSA4MjE3OiBjPTE0NjsNCgkgICAgCWJyZWFrOw0KCSAgICAJY2FzZSA4MjIwOiBjPTE0NzsNCgkgICAgCWJyZWFrOw0KCSAgICAJY2FzZSA4MjIxOiBjPTE0ODsNCgkgICAgCWJyZWFrOw0KCSAgICAJY2FzZSA4MjI2OiBjPTE0OTsNCgkgICAgCWJyZWFrOw0KCSAgICAJY2FzZSA4MjExOiBjPTE1MDsNCgkgICAgCWJyZWFrOw0KCSAgICAJY2FzZSA4MjEyOiBjPTE1MTsNCgkgICAgCWJyZWFrOw0KCSAgICAJY2FzZSA3MzI6IGM9MTUyOw0KCSAgICAJYnJlYWs7DQoJICAgIAljYXNlIDg0ODI6IGM9MTUzOw0KCSAgICAJYnJlYWs7DQoJICAgIAljYXNlIDM1MzogYz0xNTQ7DQoJICAgIAlicmVhazsNCgkgICAgCWNhc2UgODI1MDogYz0xNTU7DQoJICAgIAlicmVhazsNCgkgICAgCWNhc2UgMzM5OiBjPTE1NjsNCgkgICAgCWJyZWFrOw0KCSAgICAJY2FzZSAzODI6IGM9MTU4Ow0KCSAgICAJYnJlYWs7DQoJICAgIAljYXNlIDM3NjogYz0xNTk7DQoJICAgIAlicmVhazsNCgkgICAgCWRlZmF1bHQ6DQoJICAgIAlicmVhazsNCgkgICAgfQ0KCX0NCglyZXR1cm4gYzsNCn07DQoNCi8qKg0KICogRGVjb2Rpbmcgc3RyaW5nIGludG8gdXRmLTgNCiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJpbmcgdG8gZGVjb2RlDQogKiBAcmV0dXJuIHtTdHJpbmd9IHV0ZjggZGVjb2RlZCBzdHJpbmcNCiAqLw0KSlhHLlV0aWwudXRmOERlY29kZSA9IGZ1bmN0aW9uKHV0ZnRleHQpIHsNCiAgdmFyIHN0cmluZyA9IFtdOw0KICB2YXIgaSA9IDA7DQogIHZhciBjID0gMCwgYzEgPSAwLCBjMiA9IDAsIGMzOw0KICBpZiAoIUpYRy5leGlzdHModXRmdGV4dCkpIHJldHVybiAnJzsNCiAgDQogIHdoaWxlICggaSA8IHV0ZnRleHQubGVuZ3RoICkgew0KICAgIGMgPSB1dGZ0ZXh0LmNoYXJDb2RlQXQoaSk7DQoNCiAgICBpZiAoYyA8IDEyOCkgew0KICAgICAgc3RyaW5nLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShjKSk7DQogICAgICBpKys7DQogICAgfSBlbHNlIGlmKChjID4gMTkxKSAmJiAoYyA8IDIyNCkpIHsNCiAgICAgIGMyID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkrMSk7DQogICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyAmIDMxKSA8PCA2KSB8IChjMiAmIDYzKSkpOw0KICAgICAgaSArPSAyOw0KICAgIH0gZWxzZSB7DQogICAgICBjMiA9IHV0ZnRleHQuY2hhckNvZGVBdChpKzEpOw0KICAgICAgYzMgPSB1dGZ0ZXh0LmNoYXJDb2RlQXQoaSsyKTsNCiAgICAgIHN0cmluZy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoKChjICYgMTUpIDw8IDEyKSB8ICgoYzIgJiA2MykgPDwgNikgfCAoYzMgJiA2MykpKTsNCiAgICAgIGkgKz0gMzsNCiAgICB9DQogIH07DQogIHJldHVybiBzdHJpbmcuam9pbignJyk7DQp9Ow0KDQovKioNCiAqIEdlbmVyYXRlIGEgcmFuZG9tIHV1aWQuDQogKiBodHRwOi8vd3d3LmJyb29mYS5jb20NCiAqIG1haWx0bzpyb2JlcnRAYnJvb2ZhLmNvbQ0KICoNCiAqIENvcHlyaWdodCAoYykgMjAxMCBSb2JlcnQgS2llZmZlcg0KICogRHVhbCBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGFuZCBHUEwgbGljZW5zZXMuDQogKg0KICogRVhBTVBMRVM6DQogKiAgID4+PiBNYXRoLnV1aWQoKQ0KICogICAiOTIzMjlEMzktNkY1Qy00NTIwLUFCRkMtQUFCNjQ1NDRFMTcyIg0KICovDQpKWEcuVXRpbC5nZW5VVUlEID0gZnVuY3Rpb24oKSB7DQogICAgLy8gUHJpdmF0ZSBhcnJheSBvZiBjaGFycyB0byB1c2UNCiAgICB2YXIgY2hhcnMgPSAnMDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXonLnNwbGl0KCcnKSwNCiAgICAgICAgdXVpZCA9IG5ldyBBcnJheSgzNiksIHJuZD0wLCByOw0KDQogICAgZm9yICh2YXIgaSA9IDA7IGkgPCAzNjsgaSsrKSB7DQogICAgICBpZiAoaT09OCB8fCBpPT0xMyB8fCAgaT09MTggfHwgaT09MjMpIHsNCiAgICAgICAgdXVpZFtpXSA9ICctJzsNCiAgICAgIH0gZWxzZSBpZiAoaT09MTQpIHsNCiAgICAgICAgdXVpZFtpXSA9ICc0JzsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGlmIChybmQgPD0gMHgwMikgcm5kID0gMHgyMDAwMDAwICsgKE1hdGgucmFuZG9tKCkqMHgxMDAwMDAwKXwwOw0KICAgICAgICByID0gcm5kICYgMHhmOw0KICAgICAgICBybmQgPSBybmQgPj4gNDsNCiAgICAgICAgdXVpZFtpXSA9IGNoYXJzWyhpID09IDE5KSA/IChyICYgMHgzKSB8IDB4OCA6IHJdOw0KICAgICAgfQ0KICAgIH0NCg0KICAgIHJldHVybiB1dWlkLmpvaW4oJycpOw0KfTsNCg0KLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0DQovLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIDQovLw0KLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcg0KLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyDQovLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4NCi8vDQovLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwNCi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mDQovLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQ0KLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4NCi8vDQovLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlDQovLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0ENCg0KLyoqDQogKg0KICogVGhpcyBvYmplY3QgY29udGFpbnMgY29uZmlndXJhdGlvbiB2YWx1ZXMgYW5kIGltcGxlbWVudHMNCiAqIHN0b3JpbmcgYW5kIHJldHJpZXZpbmcgY29uZmlndXJhdGlvbiB0aGVtIGZyb20gSFRNTDUgbG9jYWwgc3RvcmFnZS4NCiAqDQogKiBUaGlzIG9iamVjdCBjYW4gYmUgYWNjZXNzZWQgYWZ0ZXIgY2FsbGluZyBvcGVucGdwLmluaXQoKQ0KICogdXNpbmcgb3BlbnBncC5jb25maWcNCiAqIFN0b3JlZCBjb25maWcgcGFyYW1ldGVycyBjYW4gYmUgYWNjZXNzZWQgdXNpbmcNCiAqIG9wZW5wZ3AuY29uZmlnLmNvbmZpZw0KICogQGNsYXNzDQogKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBHUEc0QnJvd3NlcnMgY29uZmlnIG9iamVjdA0KICovDQpmdW5jdGlvbiBvcGVucGdwX2NvbmZpZygpIHsNCgkvKioNCgkgKiBUaGUgdmFyaWFibGUgd2l0aCB0aGUgYWN0dWFsIGNvbmZpZ3VyYXRpb24NCgkgKiBAcHJvcGVydHkge0ludGVnZXJ9IHByZWZlcl9oYXNoX2FsZ29yaXRobQ0KCSAqIEBwcm9wZXJ0eSB7SW50ZWdlcn0gZW5jcnlwdGlvbl9jaXBoZXINCgkgKiBAcHJvcGVydHkge0ludGVnZXJ9IGNvbXByZXNzaW9uDQoJICogQHByb3BlcnR5IHtCb29sZWFufSBzaG93X3ZlcnNpb24NCgkgKiBAcHJvcGVydHkge0Jvb2xlYW59IHNob3dfY29tbWVudA0KCSAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gaW50ZWdyaXR5X3Byb3RlY3QNCgkgKiBAcHJvcGVydHkge0ludGVnZXJ9IGNvbXBvc2l0aW9uX2JlaGF2aW9yDQoJICogQHByb3BlcnR5IHtTdHJpbmd9IGtleXNlcnZlcg0KCSAqLw0KCXRoaXMuY29uZmlnID0gbnVsbDsNCg0KCS8qKg0KCSAqIFRoZSBkZWZhdWx0IGNvbmZpZyBvYmplY3Qgd2hpY2ggaXMgdXNlZCBpZiBubw0KCSAqIGNvbmZpZ3VyYXRpb24gd2FzIGluIHBsYWNlDQoJICovDQoJdGhpcy5kZWZhdWx0X2NvbmZpZyA9IHsNCgkJCXByZWZlcl9oYXNoX2FsZ29yaXRobTogOCwNCgkJCWVuY3J5cHRpb25fY2lwaGVyOiA5LA0KCQkJY29tcHJlc3Npb246IDEsDQoJCQlzaG93X3ZlcnNpb246IHRydWUsDQoJCQlzaG93X2NvbW1lbnQ6IHRydWUsDQoJCQlpbnRlZ3JpdHlfcHJvdGVjdDogdHJ1ZSwNCgkJCWNvbXBvc2l0aW9uX2JlaGF2aW9yOiAwLA0KCQkJa2V5c2VydmVyOiAia2V5c2VydmVyLmxpbnV4Lml0IiAvLyAicGdwLm1pdC5lZHU6MTEzNzEiDQoJfTsNCg0KCXRoaXMudmVyc2lvbnN0cmluZyA9Ik9wZW5QR1AuanMgdi4xLjIwMTMwNDIwIjsNCgl0aGlzLmNvbW1lbnRzdHJpbmcgPSJodHRwOi8vb3BlbnBncGpzLm9yZyI7DQoJLyoqDQoJICogUmVhZHMgdGhlIGNvbmZpZyBvdXQgb2YgdGhlIEhUTUw1IGxvY2FsIHN0b3JhZ2UNCgkgKiBhbmQgaW5pdGlhbGl6ZXMgdGhlIG9iamVjdCBjb25maWcuDQoJICogaWYgY29uZmlnIGlzIG51bGwgdGhlIGRlZmF1bHQgY29uZmlnIHdpbGwgYmUgdXNlZA0KCSAqLw0KCWZ1bmN0aW9uIHJlYWQoKSB7DQoJCXZhciBjZiA9IEpTT04ucGFyc2Uod2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKCJjb25maWciKSk7DQoJCWlmIChjZiA9PSBudWxsKSB7DQoJCQl0aGlzLmNvbmZpZyA9IHRoaXMuZGVmYXVsdF9jb25maWc7DQoJCQl0aGlzLndyaXRlKCk7DQoJCX0NCgkJZWxzZQ0KCQkJdGhpcy5jb25maWcgPSBjZjsNCgl9DQoNCgkvKioNCgkgKiBJZiBlbmFibGVkLCBkZWJ1ZyBtZXNzYWdlcyB3aWxsIGJlIHByaW50ZWQNCgkgKi8NCgl0aGlzLmRlYnVnID0gZmFsc2U7DQoNCgkvKioNCgkgKiBXcml0ZXMgdGhlIGNvbmZpZyB0byBIVE1MNSBsb2NhbCBzdG9yYWdlDQoJICovDQoJZnVuY3Rpb24gd3JpdGUoKSB7DQoJCXdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbSgiY29uZmlnIixKU09OLnN0cmluZ2lmeSh0aGlzLmNvbmZpZykpOw0KCX0NCg0KCXRoaXMucmVhZCA9IHJlYWQ7DQoJdGhpcy53cml0ZSA9IHdyaXRlOw0KfQ0KLyogT3BlblBHUCByYWRpeC02NC9iYXNlNjQgc3RyaW5nIGVuY29kaW5nL2RlY29kaW5nDQogKiBDb3B5cmlnaHQgMjAwNSBIZXJiZXJ0IEhhbmV3aW5rZWwsIHd3dy5oYW5lV0lOLmRlDQogKiB2ZXJzaW9uIDEuMCwgY2hlY2sgd3d3LmhhbmVXSU4uZGUgZm9yIHRoZSBsYXRlc3QgdmVyc2lvbg0KICoNCiAqIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYXMtaXMsIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LiAgDQogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlIG9yIHNlbGwgdGhpcyBzb2Z0d2FyZSwgd2l0aCBvcg0KICogd2l0aG91dCBmZWUsIGZvciBhbnkgcHVycG9zZSBhbmQgYnkgYW55IGluZGl2aWR1YWwgb3Igb3JnYW5pemF0aW9uLCBpcyBoZXJlYnkNCiAqIGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGFyYWdyYXBoIGFwcGVhciANCiAqIGluIGFsbCBjb3BpZXMuIERpc3RyaWJ1dGlvbiBhcyBhIHBhcnQgb2YgYW4gYXBwbGljYXRpb24gb3IgYmluYXJ5IG11c3QNCiAqIGluY2x1ZGUgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscw0KICogcHJvdmlkZWQgd2l0aCB0aGUgYXBwbGljYXRpb24gb3IgZGlzdHJpYnV0aW9uLg0KICovDQoNCnZhciBiNjRzID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nOw0KDQpmdW5jdGlvbiBzMnIodCkgew0KCXZhciBhLCBjLCBuOw0KCXZhciByID0gJycsIGwgPSAwLCBzID0gMDsNCgl2YXIgdGwgPSB0Lmxlbmd0aDsNCg0KCWZvciAobiA9IDA7IG4gPCB0bDsgbisrKSB7DQoJCWMgPSB0LmNoYXJDb2RlQXQobik7DQoJCWlmIChzID09IDApIHsNCgkJCXIgKz0gYjY0cy5jaGFyQXQoKGMgPj4gMikgJiA2Myk7DQoJCQlhID0gKGMgJiAzKSA8PCA0Ow0KCQl9IGVsc2UgaWYgKHMgPT0gMSkgew0KCQkJciArPSBiNjRzLmNoYXJBdCgoYSB8IChjID4+IDQpICYgMTUpKTsNCgkJCWEgPSAoYyAmIDE1KSA8PCAyOw0KCQl9IGVsc2UgaWYgKHMgPT0gMikgew0KCQkJciArPSBiNjRzLmNoYXJBdChhIHwgKChjID4+IDYpICYgMykpOw0KCQkJbCArPSAxOw0KCQkJaWYgKChsICUgNjApID09IDApDQoJCQkJciArPSAiXG4iOw0KCQkJciArPSBiNjRzLmNoYXJBdChjICYgNjMpOw0KCQl9DQoJCWwgKz0gMTsNCgkJaWYgKChsICUgNjApID09IDApDQoJCQlyICs9ICJcbiI7DQoNCgkJcyArPSAxOw0KCQlpZiAocyA9PSAzKQ0KCQkJcyA9IDA7DQoJfQ0KCWlmIChzID4gMCkgew0KCQlyICs9IGI2NHMuY2hhckF0KGEpOw0KCQlsICs9IDE7DQoJCWlmICgobCAlIDYwKSA9PSAwKQ0KCQkJciArPSAiXG4iOw0KCQlyICs9ICc9JzsNCgkJbCArPSAxOw0KCX0NCglpZiAocyA9PSAxKSB7DQoJCWlmICgobCAlIDYwKSA9PSAwKQ0KCQkJciArPSAiXG4iOw0KCQlyICs9ICc9JzsNCgl9DQoNCglyZXR1cm4gcjsNCn0NCg0KZnVuY3Rpb24gcjJzKHQpIHsNCgl2YXIgYywgbjsNCgl2YXIgciA9ICcnLCBzID0gMCwgYSA9IDA7DQoJdmFyIHRsID0gdC5sZW5ndGg7DQoNCglmb3IgKG4gPSAwOyBuIDwgdGw7IG4rKykgew0KCQljID0gYjY0cy5pbmRleE9mKHQuY2hhckF0KG4pKTsNCgkJaWYgKGMgPj0gMCkgew0KCQkJaWYgKHMpDQoJCQkJciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGEgfCAoYyA+PiAoNiAtIHMpKSAmIDI1NSk7DQoJCQlzID0gKHMgKyAyKSAmIDc7DQoJCQlhID0gKGMgPDwgcykgJiAyNTU7DQoJCX0NCgl9DQoJcmV0dXJuIHI7DQp9DQovLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHQNCi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkgNCi8vDQovLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yDQovLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXINCi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLg0KLy8NCi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLA0KLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YNCi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VDQovLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLg0KLy8NCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUNCi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQ0KDQovKioNCiAqIERlQXJtb3IgYW4gT3BlblBHUCBhcm1vcmVkIG1lc3NhZ2U7IHZlcmlmeSB0aGUgY2hlY2tzdW0gYW5kIHJldHVybiANCiAqIHRoZSBlbmNvZGVkIGJ5dGVzDQogKiBAcGFyYW0ge1N0cmluZ30gdGV4dCBPcGVuUEdQIGFybW9yZWQgbWVzc2FnZQ0KICogQHJldHVybnMgeyhCb29sZWFufE9iamVjdCl9IEVpdGhlciBmYWxzZSBpbiBjYXNlIG9mIGFuIGVycm9yIA0KICogb3IgYW4gb2JqZWN0IHdpdGggYXR0cmlidXRlICJ0ZXh0IiBjb250YWluaW5nIHRoZSBtZXNzYWdlIHRleHQNCiAqIGFuZCBhbiBhdHRyaWJ1dGUgIm9wZW5wZ3AiIGNvbnRhaW5pbmcgdGhlIGJ5dGVzLg0KICovDQpmdW5jdGlvbiBvcGVucGdwX2VuY29kaW5nX2RlQXJtb3IodGV4dCkgew0KCXRleHQgPSB0ZXh0LnJlcGxhY2UoL1xyL2csICcnKQ0KDQoJdmFyIHR5cGUgPSBvcGVucGdwX2VuY29kaW5nX2dldF90eXBlKHRleHQpOw0KDQoJaWYgKHR5cGUgIT0gMikgew0KCQl2YXIgc3BsaXR0ZWR0ZXh0ID0gdGV4dC5zcGxpdCgnLS0tLS0nKTsNCg0KCQl2YXIgZGF0YSA9IHsgDQoJCQlvcGVucGdwOiBvcGVucGdwX2VuY29kaW5nX2Jhc2U2NF9kZWNvZGUoDQoJCQkJc3BsaXR0ZWR0ZXh0WzJdDQoJCQkJCS5zcGxpdCgnXG5cbicpWzFdDQoJCQkJCS5zcGxpdCgiXG49IilbMF0NCgkJCQkJLnJlcGxhY2UoL1xuLSAvZywiXG4iKSksDQoJCQl0eXBlOiB0eXBlDQoJCX07DQoNCgkJaWYgKHZlcmlmeUNoZWNrU3VtKGRhdGEub3BlbnBncCwgDQoJCQlzcGxpdHRlZHRleHRbMl0NCgkJCQkuc3BsaXQoJ1xuXG4nKVsxXQ0KCQkJCS5zcGxpdCgiXG49IilbMV0NCgkJCQkuc3BsaXQoJ1xuJylbMF0pKQ0KDQoJCQlyZXR1cm4gZGF0YTsNCgkJZWxzZSB7DQoJCQl1dGlsLnByaW50X2Vycm9yKCJBc2NpaSBhcm1vciBpbnRlZ3JpdHkgY2hlY2sgb24gbWVzc2FnZSBmYWlsZWQ6ICciDQoJCQkJKyBzcGxpdHRlZHRleHRbMl0NCgkJCQkJLnNwbGl0KCdcblxuJylbMV0NCgkJCQkJLnNwbGl0KCJcbj0iKVsxXQ0KCQkJCQkuc3BsaXQoJ1xuJylbMF0gDQoJCQkJKyAiJyBzaG91bGQgYmUgJyINCgkJCQkrIGdldENoZWNrU3VtKGRhdGEpKSArICInIjsNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KCX0gZWxzZSB7DQoJCXZhciBzcGxpdHRlZHRleHQgPSB0ZXh0LnNwbGl0KCctLS0tLScpOw0KDQoJCXZhciByZXN1bHQgPSB7DQoJCQl0ZXh0OiBzcGxpdHRlZHRleHRbMl0NCgkJCQkucmVwbGFjZSgvXG4tIC9nLCJcbiIpDQoJCQkJLnNwbGl0KCJcblxuIilbMV0sDQoJCQlvcGVucGdwOiBvcGVucGdwX2VuY29kaW5nX2Jhc2U2NF9kZWNvZGUoc3BsaXR0ZWR0ZXh0WzRdDQoJCQkJLnNwbGl0KCJcblxuIilbMV0NCgkJCQkuc3BsaXQoIlxuPSIpWzBdKSwNCgkJCXR5cGU6IHR5cGUNCgkJfTsNCg0KCQlpZiAodmVyaWZ5Q2hlY2tTdW0ocmVzdWx0Lm9wZW5wZ3AsIHNwbGl0dGVkdGV4dFs0XQ0KCQkJLnNwbGl0KCJcblxuIilbMV0NCgkJCS5zcGxpdCgiXG49IilbMV0pKQ0KDQoJCQkJcmV0dXJuIHJlc3VsdDsNCgkJZWxzZSB7DQoJCQl1dGlsLnByaW50X2Vycm9yKCJBc2NpaSBhcm1vciBpbnRlZ3JpdHkgY2hlY2sgb24gbWVzc2FnZSBmYWlsZWQiKTsNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KCX0NCn0NCg0KLyoqDQogKiBGaW5kcyBvdXQgd2hpY2ggQXNjaWkgQXJtb3JpbmcgdHlwZSBpcyB1c2VkLiBUaGlzIGlzIGFuIGludGVybmFsIGZ1bmN0aW9uDQogKiBAcGFyYW0ge1N0cmluZ30gdGV4dCBbU3RyaW5nXSBhc2NpaSBhcm1vcmVkIHRleHQNCiAqIEByZXR1cm5zIHtJbnRlZ2VyfSAwID0gTUVTU0FHRSBQQVJUIG4gb2YgbQ0KICogICAgICAgICAxID0gTUVTU0FHRSBQQVJUIG4NCiAqICAgICAgICAgMiA9IFNJR05FRCBNRVNTQUdFDQogKiAgICAgICAgIDMgPSBQR1AgTUVTU0FHRQ0KICogICAgICAgICA0ID0gUFVCTElDIEtFWSBCTE9DSw0KICogICAgICAgICA1ID0gUFJJVkFURSBLRVkgQkxPQ0sNCiAqICAgICAgICAgbnVsbCA9IHVua25vd24NCiAqLw0KZnVuY3Rpb24gb3BlbnBncF9lbmNvZGluZ19nZXRfdHlwZSh0ZXh0KSB7DQoJdmFyIHNwbGl0dGVkdGV4dCA9IHRleHQuc3BsaXQoJy0tLS0tJyk7DQoJLy8gQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgWC9ZDQoJLy8gVXNlZCBmb3IgbXVsdGktcGFydCBtZXNzYWdlcywgd2hlcmUgdGhlIGFybW9yIGlzIHNwbGl0IGFtb25nc3QgWQ0KCS8vIHBhcnRzLCBhbmQgdGhpcyBpcyB0aGUgWHRoIHBhcnQgb3V0IG9mIFkuDQoJaWYgKHNwbGl0dGVkdGV4dFsxXS5tYXRjaCgvQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgXGQrXC9cZCsvKSkgew0KCQlyZXR1cm4gMDsNCgl9IGVsc2UNCgkJLy8gQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgWA0KCQkvLyBVc2VkIGZvciBtdWx0aS1wYXJ0IG1lc3NhZ2VzLCB3aGVyZSB0aGlzIGlzIHRoZSBYdGggcGFydCBvZiBhbg0KCQkvLyB1bnNwZWNpZmllZCBudW1iZXIgb2YgcGFydHMuIFJlcXVpcmVzIHRoZSBNRVNTQUdFLUlEIEFybW9yDQoJCS8vIEhlYWRlciB0byBiZSB1c2VkLg0KCWlmIChzcGxpdHRlZHRleHRbMV0ubWF0Y2goL0JFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFxkKy8pKSB7DQoJCXJldHVybiAxOw0KDQoJfSBlbHNlDQoJCS8vIEJFR0lOIFBHUCBTSUdOQVRVUkUNCgkJLy8gVXNlZCBmb3IgZGV0YWNoZWQgc2lnbmF0dXJlcywgT3BlblBHUC9NSU1FIHNpZ25hdHVyZXMsIGFuZA0KCQkvLyBjbGVhcnRleHQgc2lnbmF0dXJlcy4gTm90ZSB0aGF0IFBHUCAyLnggdXNlcyBCRUdJTiBQR1AgTUVTU0FHRQ0KCQkvLyBmb3IgZGV0YWNoZWQgc2lnbmF0dXJlcy4NCglpZiAoc3BsaXR0ZWR0ZXh0WzFdLm1hdGNoKC9CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UvKSkgew0KCQlyZXR1cm4gMjsNCg0KCX0gZWxzZQ0KICAJICAgIC8vIEJFR0lOIFBHUCBNRVNTQUdFDQoJICAgIC8vIFVzZWQgZm9yIHNpZ25lZCwgZW5jcnlwdGVkLCBvciBjb21wcmVzc2VkIGZpbGVzLg0KCWlmIChzcGxpdHRlZHRleHRbMV0ubWF0Y2goL0JFR0lOIFBHUCBNRVNTQUdFLykpIHsNCgkJcmV0dXJuIDM7DQoNCgl9IGVsc2UNCgkJLy8gQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0sNCgkJLy8gVXNlZCBmb3IgYXJtb3JpbmcgcHVibGljIGtleXMuDQoJaWYgKHNwbGl0dGVkdGV4dFsxXS5tYXRjaCgvQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0svKSkgew0KCQlyZXR1cm4gNDsNCg0KCX0gZWxzZQ0KCQkvLyBCRUdJTiBQR1AgUFJJVkFURSBLRVkgQkxPQ0sNCgkJLy8gVXNlZCBmb3IgYXJtb3JpbmcgcHJpdmF0ZSBrZXlzLg0KCWlmIChzcGxpdHRlZHRleHRbMV0ubWF0Y2goL0JFR0lOIFBHUCBQUklWQVRFIEtFWSBCTE9DSy8pKSB7DQoJCXJldHVybiA1Ow0KCX0NCn0NCg0KLyoqDQogKiBBZGQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0byB0aGUgYXJtb3IgdmVyc2lvbiBvZiBhbiBPcGVuUEdQIGJpbmFyeQ0KICogcGFja2V0IGJsb2NrLg0KICogQGF1dGhvciAgQWxleA0KICogQHZlcnNpb24gMjAxMS0xMi0xNg0KICogQHJldHVybnMge1N0cmluZ30gVGhlIGhlYWRlciBpbmZvcm1hdGlvbg0KICovDQpmdW5jdGlvbiBvcGVucGdwX2VuY29kaW5nX2FybW9yX2FkZGhlYWRlcigpIHsNCiAgICB2YXIgcmVzdWx0ID0gIiI7DQoJaWYgKG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5zaG93X3ZlcnNpb24pIHsNCiAgICAgICAgcmVzdWx0ICs9ICJWZXJzaW9uOiAiK29wZW5wZ3AuY29uZmlnLnZlcnNpb25zdHJpbmcrJ1xyXG4nOw0KICAgIH0NCglpZiAob3BlbnBncC5jb25maWcuY29uZmlnLnNob3dfY29tbWVudCkgew0KICAgICAgICByZXN1bHQgKz0gIkNvbW1lbnQ6ICIrb3BlbnBncC5jb25maWcuY29tbWVudHN0cmluZysnXHJcbic7DQogICAgfQ0KICAgIHJlc3VsdCArPSAnXHJcbic7DQogICAgcmV0dXJuIHJlc3VsdDsNCn0NCg0KLyoqDQogKiBBcm1vciBhbiBPcGVuUEdQIGJpbmFyeSBwYWNrZXQgYmxvY2sNCiAqIEBwYXJhbSB7SW50ZWdlcn0gbWVzc2FnZXR5cGUgdHlwZSBvZiB0aGUgbWVzc2FnZQ0KICogQHBhcmFtIGRhdGENCiAqIEBwYXJhbSB7SW50ZWdlcn0gcGFydGluZGV4DQogKiBAcGFyYW0ge0ludGVnZXJ9IHBhcnR0b3RhbA0KICogQHJldHVybnMge1N0cmluZ30gQXJtb3JlZCB0ZXh0DQogKi8NCmZ1bmN0aW9uIG9wZW5wZ3BfZW5jb2RpbmdfYXJtb3IobWVzc2FnZXR5cGUsIGRhdGEsIHBhcnRpbmRleCwgcGFydHRvdGFsKSB7DQoJdmFyIHJlc3VsdCA9ICIiOw0KCXN3aXRjaChtZXNzYWdldHlwZSkgew0KCWNhc2UgMDoNCgkJcmVzdWx0ICs9ICItLS0tLUJFR0lOIFBHUCBNRVNTQUdFLCBQQVJUICIrcGFydGluZGV4KyIvIitwYXJ0dG90YWwrIi0tLS0tXHJcbiI7DQoJCXJlc3VsdCArPSBvcGVucGdwX2VuY29kaW5nX2FybW9yX2FkZGhlYWRlcigpOw0KCQlyZXN1bHQgKz0gb3BlbnBncF9lbmNvZGluZ19iYXNlNjRfZW5jb2RlKGRhdGEpOw0KCQlyZXN1bHQgKz0gIlxyXG49IitnZXRDaGVja1N1bShkYXRhKSsiXHJcbiI7DQoJCXJlc3VsdCArPSAiLS0tLS1FTkQgUEdQIE1FU1NBR0UsIFBBUlQgIitwYXJ0aW5kZXgrIi8iK3BhcnR0b3RhbCsiLS0tLS1cclxuIjsNCgkJYnJlYWs7DQoJY2FzZSAxOg0KCQlyZXN1bHQgKz0gIi0tLS0tQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgIitwYXJ0aW5kZXgrIi0tLS0tXHJcbiI7DQoJCXJlc3VsdCArPSBvcGVucGdwX2VuY29kaW5nX2FybW9yX2FkZGhlYWRlcigpOw0KCQlyZXN1bHQgKz0gb3BlbnBncF9lbmNvZGluZ19iYXNlNjRfZW5jb2RlKGRhdGEpOw0KCQlyZXN1bHQgKz0gIlxyXG49IitnZXRDaGVja1N1bShkYXRhKSsiXHJcbiI7DQoJCXJlc3VsdCArPSAiLS0tLS1FTkQgUEdQIE1FU1NBR0UsIFBBUlQgIitwYXJ0aW5kZXgrIi0tLS0tXHJcbiI7DQoJCWJyZWFrOw0KCWNhc2UgMjoNCgkJcmVzdWx0ICs9ICJcclxuLS0tLS1CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UtLS0tLVxyXG5IYXNoOiAiK2RhdGEuaGFzaCsiXHJcblxyXG4iOw0KCQlyZXN1bHQgKz0gZGF0YS50ZXh0LnJlcGxhY2UoL1xuLS9nLCJcbi0gLSIpOw0KCQlyZXN1bHQgKz0gIlxyXG4tLS0tLUJFR0lOIFBHUCBTSUdOQVRVUkUtLS0tLVxyXG4iOw0KCQlyZXN1bHQgKz0gb3BlbnBncF9lbmNvZGluZ19hcm1vcl9hZGRoZWFkZXIoKTsNCgkJcmVzdWx0ICs9IG9wZW5wZ3BfZW5jb2RpbmdfYmFzZTY0X2VuY29kZShkYXRhLm9wZW5wZ3ApOw0KCQlyZXN1bHQgKz0gIlxyXG49IitnZXRDaGVja1N1bShkYXRhLm9wZW5wZ3ApKyJcclxuIjsNCgkJcmVzdWx0ICs9ICItLS0tLUVORCBQR1AgU0lHTkFUVVJFLS0tLS1cclxuIjsNCgkJYnJlYWs7DQoJY2FzZSAzOg0KCQlyZXN1bHQgKz0gIi0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLVxyXG4iOw0KCQlyZXN1bHQgKz0gb3BlbnBncF9lbmNvZGluZ19hcm1vcl9hZGRoZWFkZXIoKTsNCgkJcmVzdWx0ICs9IG9wZW5wZ3BfZW5jb2RpbmdfYmFzZTY0X2VuY29kZShkYXRhKTsNCgkJcmVzdWx0ICs9ICJcclxuPSIrZ2V0Q2hlY2tTdW0oZGF0YSkrIlxyXG4iOw0KCQlyZXN1bHQgKz0gIi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS1cclxuIjsNCgkJYnJlYWs7DQoJY2FzZSA0Og0KCQlyZXN1bHQgKz0gIi0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxyXG4iOw0KCQlyZXN1bHQgKz0gb3BlbnBncF9lbmNvZGluZ19hcm1vcl9hZGRoZWFkZXIoKTsNCgkJcmVzdWx0ICs9IG9wZW5wZ3BfZW5jb2RpbmdfYmFzZTY0X2VuY29kZShkYXRhKTsNCgkJcmVzdWx0ICs9ICJcclxuPSIrZ2V0Q2hlY2tTdW0oZGF0YSkrIlxyXG4iOw0KCQlyZXN1bHQgKz0gIi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cclxuXHJcbiI7DQoJCWJyZWFrOw0KCWNhc2UgNToNCgkJcmVzdWx0ICs9ICItLS0tLUJFR0lOIFBHUCBQUklWQVRFIEtFWSBCTE9DSy0tLS0tXHJcbiI7DQoJCXJlc3VsdCArPSBvcGVucGdwX2VuY29kaW5nX2FybW9yX2FkZGhlYWRlcigpOw0KCQlyZXN1bHQgKz0gb3BlbnBncF9lbmNvZGluZ19iYXNlNjRfZW5jb2RlKGRhdGEpOw0KCQlyZXN1bHQgKz0gIlxyXG49IitnZXRDaGVja1N1bShkYXRhKSsiXHJcbiI7DQoJCXJlc3VsdCArPSAiLS0tLS1FTkQgUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS1cclxuIjsNCgkJYnJlYWs7DQoJfQ0KDQoJcmV0dXJuIHJlc3VsdDsNCn0NCg0KLyoqDQogKiBDYWxjdWxhdGVzIGEgY2hlY2tzdW0gb3ZlciB0aGUgZ2l2ZW4gZGF0YSBhbmQgcmV0dXJucyBpdCBiYXNlNjQgZW5jb2RlZA0KICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBjcmVhdGUgYSBDUkMtMjQgY2hlY2tzdW0gZm9yDQogKiBAcmV0dXJuIHtTdHJpbmd9IEJhc2U2NCBlbmNvZGVkIGNoZWNrc3VtDQogKi8NCmZ1bmN0aW9uIGdldENoZWNrU3VtKGRhdGEpIHsNCgl2YXIgYyA9IGNyZWF0ZWNyYzI0KGRhdGEpOw0KCXZhciBzdHIgPSAiIiArIFN0cmluZy5mcm9tQ2hhckNvZGUoYyA+PiAxNikrDQoJCQkJICAgU3RyaW5nLmZyb21DaGFyQ29kZSgoYyA+PiA4KSAmIDB4RkYpKw0KCQkJCSAgIFN0cmluZy5mcm9tQ2hhckNvZGUoYyAmIDB4RkYpOw0KCXJldHVybiBvcGVucGdwX2VuY29kaW5nX2Jhc2U2NF9lbmNvZGUoc3RyKTsNCn0NCg0KLyoqDQogKiBDYWxjdWxhdGVzIHRoZSBjaGVja3N1bSBvdmVyIHRoZSBnaXZlbiBkYXRhIGFuZCBjb21wYXJlcyBpdCB3aXRoIHRoZSANCiAqIGdpdmVuIGJhc2U2NCBlbmNvZGVkIGNoZWNrc3VtDQogKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGNyZWF0ZSBhIENSQy0yNCBjaGVja3N1bSBmb3INCiAqIEBwYXJhbSB7U3RyaW5nfSBjaGVja3N1bSBCYXNlNjQgZW5jb2RlZCBjaGVja3N1bQ0KICogQHJldHVybiB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgZ2l2ZW4gY2hlY2tzdW0gaXMgY29ycmVjdDsgb3RoZXJ3aXNlIGZhbHNlDQogKi8NCmZ1bmN0aW9uIHZlcmlmeUNoZWNrU3VtKGRhdGEsIGNoZWNrc3VtKSB7DQoJdmFyIGMgPSBnZXRDaGVja1N1bShkYXRhKTsNCgl2YXIgZCA9IGNoZWNrc3VtOw0KCXJldHVybiBjWzBdID09IGRbMF0gJiYgY1sxXSA9PSBkWzFdICYmIGNbMl0gPT0gZFsyXTsNCn0NCi8qKg0KICogSW50ZXJuYWwgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIGEgQ1JDLTI0IGNoZWNrc3VtIG92ZXIgYSBnaXZlbiBzdHJpbmcgKGRhdGEpDQogKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGNyZWF0ZSBhIENSQy0yNCBjaGVja3N1bSBmb3INCiAqIEByZXR1cm4ge0ludGVnZXJ9IFRoZSBDUkMtMjQgY2hlY2tzdW0gYXMgbnVtYmVyDQogKi8NCnZhciBjcmNfdGFibGUgPSBbDQoweDAwMDAwMDAwLCAweDAwODY0Y2ZiLCAweDAxOGFkNTBkLCAweDAxMGM5OWY2LCAweDAzOTNlNmUxLCAweDAzMTVhYTFhLCAweDAyMTkzM2VjLCAweDAyOWY3ZjE3LCAweDA3YTE4MTM5LCAweDA3MjdjZGMyLCAweDA2MmI1NDM0LCAweDA2YWQxOGNmLCAweDA0MzI2N2Q4LCAweDA0YjQyYjIzLCAweDA1YjhiMmQ1LCAweDA1M2VmZTJlLCAweDBmYzU0ZTg5LCAweDBmNDMwMjcyLCAweDBlNGY5Yjg0LCAweDBlYzlkNzdmLCAweDBjNTZhODY4LCAweDBjZDBlNDkzLCAweDBkZGM3ZDY1LCAweDBkNWEzMTllLCAweDA4NjRjZmIwLCAweDA4ZTI4MzRiLCAweDA5ZWUxYWJkLCAweDA5Njg1NjQ2LCAweDBiZjcyOTUxLCAweDBiNzE2NWFhLCAweDBhN2RmYzVjLCAweDBhZmJiMGE3LCAweDFmMGNkMWU5LCAweDFmOGE5ZDEyLCAweDFlODYwNGU0LCAweDFlMDA0ODFmLCAweDFjOWYzNzA4LCAweDFjMTk3YmYzLCAweDFkMTVlMjA1LCAweDFkOTNhZWZlLCAweDE4YWQ1MGQwLCAweDE4MmIxYzJiLCAweDE5Mjc4NWRkLCAweDE5YTFjOTI2LCAweDFiM2ViNjMxLCAweDFiYjhmYWNhLCAweDFhYjQ2MzNjLCAweDFhMzIyZmM3LCAweDEwYzk5ZjYwLCAweDEwNGZkMzliLCAweDExNDM0YTZkLCAweDExYzUwNjk2LCAweDEzNWE3OTgxLCAweDEzZGMzNTdhLCAweDEyZDBhYzhjLCAweDEyNTZlMDc3LCAweDE3NjgxZTU5LCAweDE3ZWU1MmEyLCAweDE2ZTJjYjU0LCAweDE2NjQ4N2FmLCAweDE0ZmJmOGI4LCAweDE0N2RiNDQzLCAweDE1NzEyZGI1LCAweDE1Zjc2MTRlLCAweDNlMTlhM2QyLCAweDNlOWZlZjI5LCAweDNmOTM3NmRmLCAweDNmMTUzYTI0LCAweDNkOGE0NTMzLCAweDNkMGMwOWM4LCAweDNjMDA5MDNlLCAweDNjODZkY2M1LCAweDM5YjgyMmViLCAweDM5M2U2ZTEwLCAweDM4MzJmN2U2LCAweDM4YjRiYjFkLCAweDNhMmJjNDBhLCAweDNhYWQ4OGYxLCAweDNiYTExMTA3LCAweDNiMjc1ZGZjLCAweDMxZGNlZDViLCAweDMxNWFhMWEwLA0KMHgzMDU2Mzg1NiwgMHgzMGQwNzRhZCwgMHgzMjRmMGJiYSwgMHgzMmM5NDc0MSwgMHgzM2M1ZGViNywgMHgzMzQzOTI0YywgMHgzNjdkNmM2MiwgMHgzNmZiMjA5OSwgMHgzN2Y3Yjk2ZiwgMHgzNzcxZjU5NCwgMHgzNWVlOGE4MywgMHgzNTY4YzY3OCwgMHgzNDY0NWY4ZSwgMHgzNGUyMTM3NSwgMHgyMTE1NzIzYiwgMHgyMTkzM2VjMCwgMHgyMDlmYTczNiwgMHgyMDE5ZWJjZCwgMHgyMjg2OTRkYSwgMHgyMjAwZDgyMSwgMHgyMzBjNDFkNywgMHgyMzhhMGQyYywgMHgyNmI0ZjMwMiwgMHgyNjMyYmZmOSwgMHgyNzNlMjYwZiwgMHgyN2I4NmFmNCwgMHgyNTI3MTVlMywgMHgyNWExNTkxOCwgMHgyNGFkYzBlZSwgMHgyNDJiOGMxNSwgMHgyZWQwM2NiMiwgMHgyZTU2NzA0OSwgMHgyZjVhZTliZiwgMHgyZmRjYTU0NCwgMHgyZDQzZGE1MywgMHgyZGM1OTZhOCwgMHgyY2M5MGY1ZSwgMHgyYzRmNDNhNSwgMHgyOTcxYmQ4YiwgMHgyOWY3ZjE3MCwgMHgyOGZiNjg4NiwgMHgyODdkMjQ3ZCwgMHgyYWUyNWI2YSwgMHgyYTY0MTc5MSwgMHgyYjY4OGU2NywgMHgyYmVlYzI5YywgMHg3YzMzNDdhNCwgMHg3Y2I1MGI1ZiwgMHg3ZGI5OTJhOSwgMHg3ZDNmZGU1MiwgMHg3ZmEwYTE0NSwgMHg3ZjI2ZWRiZSwgMHg3ZTJhNzQ0OCwgMHg3ZWFjMzhiMywgMHg3YjkyYzY5ZCwgMHg3YjE0OGE2NiwgMHg3YTE4MTM5MCwgMHg3YTllNWY2YiwgMHg3ODAxMjA3YywgMHg3ODg3NmM4NywgMHg3OThiZjU3MSwgMHg3OTBkYjk4YSwgMHg3M2Y2MDkyZCwgMHg3MzcwNDVkNiwgMHg3MjdjZGMyMCwgMHg3MmZhOTBkYiwgMHg3MDY1ZWZjYywgMHg3MGUzYTMzNywgMHg3MWVmM2FjMSwgMHg3MTY5NzYzYSwgMHg3NDU3ODgxNCwgMHg3NGQxYzRlZiwgMHg3NWRkNWQxOSwgMHg3NTViMTFlMiwgMHg3N2M0NmVmNSwgMHg3NzQyMjIwZSwgMHg3NjRlYmJmOCwgMHg3NmM4ZjcwMywgMHg2MzNmOTY0ZCwgMHg2M2I5ZGFiNiwgMHg2MmI1NDM0MCwgMHg2MjMzMGZiYiwNCjB4NjBhYzcwYWMsIDB4NjAyYTNjNTcsIDB4NjEyNmE1YTEsIDB4NjFhMGU5NWEsIDB4NjQ5ZTE3NzQsIDB4NjQxODViOGYsIDB4NjUxNGMyNzksIDB4NjU5MjhlODIsIDB4NjcwZGYxOTUsIDB4Njc4YmJkNmUsIDB4NjY4NzI0OTgsIDB4NjYwMTY4NjMsIDB4NmNmYWQ4YzQsIDB4NmM3Yzk0M2YsIDB4NmQ3MDBkYzksIDB4NmRmNjQxMzIsIDB4NmY2OTNlMjUsIDB4NmZlZjcyZGUsIDB4NmVlM2ViMjgsIDB4NmU2NWE3ZDMsIDB4NmI1YjU5ZmQsIDB4NmJkZDE1MDYsIDB4NmFkMThjZjAsIDB4NmE1N2MwMGIsIDB4NjhjOGJmMWMsIDB4Njg0ZWYzZTcsIDB4Njk0MjZhMTEsIDB4NjljNDI2ZWEsIDB4NDIyYWU0NzYsIDB4NDJhY2E4OGQsIDB4NDNhMDMxN2IsIDB4NDMyNjdkODAsIDB4NDFiOTAyOTcsIDB4NDEzZjRlNmMsIDB4NDAzM2Q3OWEsIDB4NDBiNTliNjEsIDB4NDU4YjY1NGYsIDB4NDUwZDI5YjQsIDB4NDQwMWIwNDIsIDB4NDQ4N2ZjYjksIDB4NDYxODgzYWUsIDB4NDY5ZWNmNTUsIDB4NDc5MjU2YTMsIDB4NDcxNDFhNTgsIDB4NGRlZmFhZmYsIDB4NGQ2OWU2MDQsIDB4NGM2NTdmZjIsIDB4NGNlMzMzMDksIDB4NGU3YzRjMWUsIDB4NGVmYTAwZTUsIDB4NGZmNjk5MTMsIDB4NGY3MGQ1ZTgsIDB4NGE0ZTJiYzYsIDB4NGFjODY3M2QsIDB4NGJjNGZlY2IsIDB4NGI0MmIyMzAsIDB4NDlkZGNkMjcsIDB4NDk1YjgxZGMsIDB4NDg1NzE4MmEsIDB4NDhkMTU0ZDEsIDB4NWQyNjM1OWYsIDB4NWRhMDc5NjQsIDB4NWNhY2UwOTIsIDB4NWMyYWFjNjksIDB4NWViNWQzN2UsIDB4NWUzMzlmODUsIDB4NWYzZjA2NzMsIDB4NWZiOTRhODgsIDB4NWE4N2I0YTYsIDB4NWEwMWY4NWQsIDB4NWIwZDYxYWIsIDB4NWI4YjJkNTAsIDB4NTkxNDUyNDcsIDB4NTk5MjFlYmMsIDB4NTg5ZTg3NGEsIDB4NTgxOGNiYjEsIDB4NTJlMzdiMTYsIDB4NTI2NTM3ZWQsIDB4NTM2OWFlMWIsIDB4NTNlZmUyZTAsIDB4NTE3MDlkZjcsIDB4NTFmNmQxMGMsDQoweDUwZmE0OGZhLCAweDUwN2MwNDAxLCAweDU1NDJmYTJmLCAweDU1YzRiNmQ0LCAweDU0YzgyZjIyLCAweDU0NGU2M2Q5LCAweDU2ZDExY2NlLCAweDU2NTc1MDM1LCAweDU3NWJjOWMzLCAweDU3ZGQ4NTM4XTsNCg0KZnVuY3Rpb24gY3JlYXRlY3JjMjQoaW5wdXQpIHsNCiAgdmFyIGNyYyA9IDB4QjcwNENFOw0KICB2YXIgaW5kZXggPSAwOw0KDQogIHdoaWxlKChpbnB1dC5sZW5ndGggLSBpbmRleCkgPiAxNikgIHsNCiAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCkpICYgMHhmZl07DQogICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrMSkpICYgMHhmZl07DQogICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrMikpICYgMHhmZl07DQogICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrMykpICYgMHhmZl07DQogICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrNCkpICYgMHhmZl07DQogICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrNSkpICYgMHhmZl07DQogICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrNikpICYgMHhmZl07DQogICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrNykpICYgMHhmZl07DQogICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrOCkpICYgMHhmZl07DQogICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrOSkpICYgMHhmZl07DQogICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrMTApKSAmIDB4ZmZdOw0KICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4KzExKSkgJiAweGZmXTsNCiAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCsxMikpICYgMHhmZl07DQogICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrMTMpKSAmIDB4ZmZdOw0KICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4KzE0KSkgJiAweGZmXTsNCiAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCsxNSkpICYgMHhmZl07DQogICBpbmRleCArPSAxNjsNCiAgfQ0KDQogIGZvcih2YXIgaiA9IGluZGV4OyBqIDwgaW5wdXQubGVuZ3RoOyBqKyspIHsNCiAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCsrKSkgJiAweGZmXQ0KICB9DQogIHJldHVybiBjcmMgJiAweGZmZmZmZjsNCn0NCg0KLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0DQovLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3INCi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcg0KLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLA0KLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YNCi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VDQovLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLg0KLy8gDQovLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlDQovLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0ENCg0KLyoqDQogKiBXcmFwcGVyIGZ1bmN0aW9uIGZvciB0aGUgYmFzZTY0IGNvZGVjLiANCiAqIFRoaXMgZnVuY3Rpb24gZW5jb2RlcyBhIFN0cmluZyAobWVzc2FnZSkgaW4gYmFzZTY0IChyYWRpeC02NCkNCiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGVuY29kZQ0KICogQHJldHVybiB7U3RyaW5nfSBUaGUgYmFzZTY0IGVuY29kZWQgZGF0YQ0KICovDQpmdW5jdGlvbiBvcGVucGdwX2VuY29kaW5nX2Jhc2U2NF9lbmNvZGUobWVzc2FnZSkgew0KCXJldHVybiBzMnIobWVzc2FnZSk7DQp9DQoNCg0KLyoqDQogKiBXcmFwcGVyIGZ1bmN0aW9uIGZvciB0aGUgYmFzZTY0IGNvZGVjLg0KICogVGhpcyBmdW5jdGlvbiBkZWNvZGVzIGEgU3RyaW5nKG1lc3NhZ2UpIGluIGJhc2U2NCAocmFkaXgtNjQpDQogKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBCYXNlNjQgZW5jb2RlZCBkYXRhDQogKiBAcmV0dXJuIHtTdHJpbmd9IFJhdyBkYXRhIGFmdGVyIGRlY29kaW5nDQogKi8NCmZ1bmN0aW9uIG9wZW5wZ3BfZW5jb2RpbmdfYmFzZTY0X2RlY29kZShtZXNzYWdlKSB7DQoJcmV0dXJuIHIycyhtZXNzYWdlKTsNCn0NCg0KLyoqDQogKiBXcmFwcGVyIGZ1bmN0aW9uIGZvciBqcXVlcnkgbGlicmFyeS4NCiAqIFRoaXMgZnVuY3Rpb24gZXNjYXBlcyBIVE1MIGNoYXJhY3RlcnMgd2l0aGluIGEgc3RyaW5nLiBUaGlzIGlzIHVzZWQgDQogKiB0byBwcmV2ZW50IFhTUy4NCiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIE1lc3NhZ2UgdG8gZXNjYXBlDQogKiBAcmV0dXJuIHtTdHJpbmd9IEh0bWwgZW5jb2RlZCBzdHJpbmcNCiAqLw0KZnVuY3Rpb24gb3BlbnBncF9lbmNvZGluZ19odG1sX2VuY29kZShtZXNzYWdlKSB7DQoJaWYgKG1lc3NhZ2UgPT0gbnVsbCkNCgkJcmV0dXJuICIiOw0KCXJldHVybiAkKCc8ZGl2Lz4nKS50ZXh0KG1lc3NhZ2UpLmh0bWwoKTsNCn0NCg0KLyoqDQogKiBjcmVhdGUgYSBFTUUtUEtDUzEtdjFfNSBwYWRkaW5nIChTZWUgUkZDNDg4MCAxMy4xLjEpDQogKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBtZXNzYWdlIHRvIGJlIHBhZGRlZA0KICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggTGVuZ3RoIHRvIHRoZSByZXN1bHRpbmcgbWVzc2FnZQ0KICogQHJldHVybiB7U3RyaW5nfSBFTUUtUEtDUzEgcGFkZGVkIG1lc3NhZ2UNCiAqLw0KZnVuY3Rpb24gb3BlbnBncF9lbmNvZGluZ19lbWVfcGtjczFfZW5jb2RlKG1lc3NhZ2UsIGxlbmd0aCkgew0KCWlmIChtZXNzYWdlLmxlbmd0aCA+IGxlbmd0aC0xMSkNCgkJcmV0dXJuIC0xOw0KCXZhciByZXN1bHQgPSAiIjsNCglyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTsNCglyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgyKTsNCglmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aCAtIG1lc3NhZ2UubGVuZ3RoIC0gMzsgaSsrKSB7DQoJCXJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKG9wZW5wZ3BfY3J5cHRvX2dldFBzZXVkb1JhbmRvbSgxLDI1NSkpOw0KCX0NCglyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTsNCglyZXN1bHQgKz0gbWVzc2FnZTsNCglyZXR1cm4gcmVzdWx0Ow0KfQ0KDQovKioNCiAqIGRlY29kZXMgYSBFTUUtUEtDUzEtdjFfNSBwYWRkaW5nIChTZWUgUkZDNDg4MCAxMy4xLjIpDQogKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBFTUUtUEtDUzEgcGFkZGVkIG1lc3NhZ2UNCiAqIEByZXR1cm4ge1N0cmluZ30gZGVjb2RlZCBtZXNzYWdlIA0KICovDQpmdW5jdGlvbiBvcGVucGdwX2VuY29kaW5nX2VtZV9wa2NzMV9kZWNvZGUobWVzc2FnZSwgbGVuKSB7DQoJaWYgKG1lc3NhZ2UubGVuZ3RoIDwgbGVuKQ0KCSAgICBtZXNzYWdlID0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKSttZXNzYWdlOw0KCWlmIChtZXNzYWdlLmxlbmd0aCA8IDEyIHx8IG1lc3NhZ2UuY2hhckNvZGVBdCgwKSAhPSAwIHx8IG1lc3NhZ2UuY2hhckNvZGVBdCgxKSAhPSAyKQ0KCQlyZXR1cm4gLTE7DQoJdmFyIGkgPSAyOw0KCXdoaWxlIChtZXNzYWdlLmNoYXJDb2RlQXQoaSkgIT0gMCAmJiBtZXNzYWdlLmxlbmd0aCA+IGkpDQoJICAgIGkrKzsNCglyZXR1cm4gbWVzc2FnZS5zdWJzdHJpbmcoaSsxLCBtZXNzYWdlLmxlbmd0aCk7DQp9DQovKioNCiAqIEFTTjEgb2JqZWN0IGlkZW50aWZpZXJzIGZvciBoYXNoZXMgKFNlZSBSRkM0ODgwIDUuMi4yKQ0KICovDQpoYXNoX2hlYWRlcnMgPSBuZXcgQXJyYXkoKTsNCmhhc2hfaGVhZGVyc1sxXSAgPSBbMHgzMCwweDIwLDB4MzAsMHgwYywweDA2LDB4MDgsMHgyYSwweDg2LDB4NDgsMHg4NiwweGY3LDB4MGQsMHgwMiwweDA1LDB4MDUsMHgwMCwweDA0LDB4MTBdOw0KaGFzaF9oZWFkZXJzWzNdICA9IFsweDMwLDB4MjEsMHgzMCwweDA5LDB4MDYsMHgwNSwweDJCLDB4MjQsMHgwMywweDAyLDB4MDEsMHgwNSwweDAwLDB4MDQsMHgxNF07DQpoYXNoX2hlYWRlcnNbMl0gID0gWzB4MzAsMHgyMSwweDMwLDB4MDksMHgwNiwweDA1LDB4MmIsMHgwZSwweDAzLDB4MDIsMHgxYSwweDA1LDB4MDAsMHgwNCwweDE0XTsNCmhhc2hfaGVhZGVyc1s4XSAgPSBbMHgzMCwweDMxLDB4MzAsMHgwZCwweDA2LDB4MDksMHg2MCwweDg2LDB4NDgsMHgwMSwweDY1LDB4MDMsMHgwNCwweDAyLDB4MDEsMHgwNSwweDAwLDB4MDQsMHgyMF07DQpoYXNoX2hlYWRlcnNbOV0gID0gWzB4MzAsMHg0MSwweDMwLDB4MGQsMHgwNiwweDA5LDB4NjAsMHg4NiwweDQ4LDB4MDEsMHg2NSwweDAzLDB4MDQsMHgwMiwweDAyLDB4MDUsMHgwMCwweDA0LDB4MzBdOw0KaGFzaF9oZWFkZXJzWzEwXSA9IFsweDMwLDB4NTEsMHgzMCwweDBkLDB4MDYsMHgwOSwweDYwLDB4ODYsMHg0OCwweDAxLDB4NjUsMHgwMywweDA0LDB4MDIsMHgwMywweDA1LDB4MDAsMHgwNCwweDQwXTsNCmhhc2hfaGVhZGVyc1sxMV0gPSBbMHgzMCwweDMxLDB4MzAsMHgwZCwweDA2LDB4MDksMHg2MCwweDg2LDB4NDgsMHgwMSwweDY1LDB4MDMsMHgwNCwweDAyLDB4MDQsMHgwNSwweDAwLDB4MDQsMHgxQ107DQoNCi8qKg0KICogY3JlYXRlIGEgRU1TQS1QS0NTMS12MV81IHBhZGRpbmcgKFNlZSBSRkM0ODgwIDEzLjEuMykNCiAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBIYXNoIGFsZ29yaXRobSB0eXBlIHVzZWQNCiAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgdG8gYmUgaGFzaGVkDQogKiBAcGFyYW0ge0ludGVnZXJ9IGtleWxlbmd0aCBLZXkgc2l6ZSBvZiB0aGUgcHVibGljIG1waSBpbiBieXRlcw0KICogQHJldHVybnMge1N0cmluZ30gSGFzaGNvZGUgd2l0aCBwa2NzMXBhZGRpbmcgYXMgc3RyaW5nDQogKi8NCmZ1bmN0aW9uIG9wZW5wZ3BfZW5jb2RpbmdfZW1zYV9wa2NzMV9lbmNvZGUoYWxnbywgZGF0YSwga2V5bGVuZ3RoKSB7DQoJdmFyIGRhdGEyID0gIiI7DQoJZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKTsNCglkYXRhMiArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDEpOw0KCWZvciAodmFyIGkgPSAwOyBpIDwgKGtleWxlbmd0aCAtIGhhc2hfaGVhZGVyc1thbGdvXS5sZW5ndGggLSAzIC0gb3BlbnBncF9jcnlwdG9fZ2V0SGFzaEJ5dGVMZW5ndGgoYWxnbykpOyBpKyspDQoJCWRhdGEyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHhmZik7DQoJZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKTsNCgkNCglmb3IgKHZhciBpID0gMDsgaSA8IGhhc2hfaGVhZGVyc1thbGdvXS5sZW5ndGg7IGkrKykNCgkJZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShoYXNoX2hlYWRlcnNbYWxnb11baV0pOw0KCQ0KCWRhdGEyICs9IG9wZW5wZ3BfY3J5cHRvX2hhc2hEYXRhKGFsZ28sIGRhdGEpOw0KCXJldHVybiBuZXcgQmlnSW50ZWdlcih1dGlsLmhleHN0cmR1bXAoZGF0YTIpLDE2KTsNCn0NCg0KLyoqDQogKiBleHRyYWN0IHRoZSBoYXNoIG91dCBvZiBhbiBFTVNBLVBLQ1MxLXYxLjUgcGFkZGluZyAoU2VlIFJGQzQ4ODAgMTMuMS4zKSANCiAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIEhhc2ggaW4gcGtjczEgZW5jb2RpbmcNCiAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBoYXNoIGFzIHN0cmluZw0KICovDQpmdW5jdGlvbiBvcGVucGdwX2VuY29kaW5nX2Vtc2FfcGtjczFfZGVjb2RlKGFsZ28sIGRhdGEpIHsgDQoJdmFyIGkgPSAwOw0KCWlmIChkYXRhLmNoYXJDb2RlQXQoMCkgPT0gMCkgaSsrOw0KCWVsc2UgaWYgKGRhdGEuY2hhckNvZGVBdCgwKSAhPSAxKSByZXR1cm4gLTE7DQoJZWxzZSBpKys7DQoNCgl3aGlsZSAoZGF0YS5jaGFyQ29kZUF0KGkpID09IDB4RkYpIGkrKzsNCglpZiAoZGF0YS5jaGFyQ29kZUF0KGkrKykgIT0gMCkgcmV0dXJuIC0xOw0KCXZhciBqID0gMDsNCglmb3IgKGogPSAwOyBqIDwgaGFzaF9oZWFkZXJzW2FsZ29dLmxlbmd0aCAmJiBqK2kgPCBkYXRhLmxlbmd0aDsgaisrKSB7DQoJCWlmIChkYXRhLmNoYXJDb2RlQXQoaitpKSAhPSBoYXNoX2hlYWRlcnNbYWxnb11bal0pIHJldHVybiAtMTsNCgl9DQoJaSs9IGo7CQ0KCWlmIChkYXRhLnN1YnN0cmluZyhpKS5sZW5ndGggPCBvcGVucGdwX2NyeXB0b19nZXRIYXNoQnl0ZUxlbmd0aChhbGdvKSkgcmV0dXJuIC0xOw0KCXJldHVybiBkYXRhLnN1YnN0cmluZyhpKTsNCn0NCi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdA0KLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSA0KLy8gDQovLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yDQovLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXINCi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLg0KLy8gDQovLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwNCi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mDQovLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQ0KLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4NCi8vIA0KLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQ0KLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBDQoNCi8qKg0KICogQGZpbGVvdmVydmlldyBUaGUgb3BlbnBncCBiYXNlIGNsYXNzIHNob3VsZCBwcm92aWRlIGFsbCBvZiB0aGUgZnVuY3Rpb25hbGl0eSANCiAqIHRvIGNvbnN1bWUgdGhlIG9wZW5wZ3AuanMgbGlicmFyeS4gQWxsIGFkZGl0aW9uYWwgY2xhc3NlcyBhcmUgZG9jdW1lbnRlZCANCiAqIGZvciBleHRlbmRpbmcgYW5kIGRldmVsb3Bpbmcgb24gdG9wIG9mIHRoZSBiYXNlIGxpYnJhcnkuDQogKi8NCg0KLyoqDQogKiBHUEc0QnJvd3NlcnMgQ29yZSBpbnRlcmZhY2UuIEEgc2luZ2xlIGluc3RhbmNlIGlzIGhvbGQNCiAqIGZyb20gdGhlIGJlZ2lubmluZy4gVG8gdXNlIHRoaXMgbGlicmFyeSBjYWxsICJvcGVucGdwLmluaXQoKSINCiAqIEBhbGlhcyBvcGVucGdwDQogKiBAY2xhc3MNCiAqIEBjbGFzc2Rlc2MgTWFpbiBPcGVucGdwLmpzIGNsYXNzLiBVc2UgdGhpcyB0byBpbml0aWF0ZSBhbmQgbWFrZSBhbGwgY2FsbHMgdG8gdGhpcyBsaWJyYXJ5Lg0KICovDQpmdW5jdGlvbiBfb3BlbnBncCAoKSB7DQoJdGhpcy50b3N0cmluZyA9ICIiOw0KCQ0KCS8qKg0KCSAqIGluaXRpYWxpemVzIHRoZSBsaWJyYXJ5Og0KCSAqIC0gcmVhZGluZyB0aGUga2V5cmluZyBmcm9tIGxvY2FsIHN0b3JhZ2UNCgkgKiAtIHJlYWRpbmcgdGhlIGNvbmZpZyBmcm9tIGxvY2FsIHN0b3JhZ2UNCgkgKi8NCglmdW5jdGlvbiBpbml0KCkgew0KCQl0aGlzLmNvbmZpZyA9IG5ldyBvcGVucGdwX2NvbmZpZygpOw0KCQl0aGlzLmNvbmZpZy5yZWFkKCk7DQoJCXRoaXMua2V5cmluZyA9IG5ldyBvcGVucGdwX2tleXJpbmcoKTsNCgkJdGhpcy5rZXlyaW5nLmluaXQoKTsNCgl9DQoJDQoJLyoqDQoJICogcmVhZHMgc2V2ZXJhbCBwdWJsaWNLZXkgb2JqZWN0cyBmcm9tIGEgYXNjaWkgYXJtb3JlZA0KCSAqIHJlcHJlc2VudGF0aW9uIGFuIHJldHVybnMgb3BlbnBncF9tc2dfcHVibGlja2V5IHBhY2tldHMNCgkgKiBAcGFyYW0ge1N0cmluZ30gYXJtb3JlZFRleHQgT3BlblBHUCBhcm1vcmVkIHRleHQgY29udGFpbmluZw0KCSAqIHRoZSBwdWJsaWMga2V5KHMpDQoJICogQHJldHVybiB7b3BlbnBncF9tc2dfcHVibGlja2V5W119IG9uIGVycm9yIHRoZSBmdW5jdGlvbg0KCSAqIHJldHVybnMgbnVsbA0KCSAqLw0KCWZ1bmN0aW9uIHJlYWRfcHVibGljS2V5KGFybW9yZWRUZXh0KSB7DQoJCXZhciBteXBvcyA9IDA7DQoJCXZhciBwdWJsaWNLZXlzID0gbmV3IEFycmF5KCk7DQoJCXZhciBwdWJsaWNLZXlDb3VudCA9IDA7DQoJCXZhciBpbnB1dCA9IG9wZW5wZ3BfZW5jb2RpbmdfZGVBcm1vcihhcm1vcmVkVGV4dC5yZXBsYWNlKC9cci9nLCcnKSkub3BlbnBncDsNCgkJdmFyIGwgPSBpbnB1dC5sZW5ndGg7DQoJCXdoaWxlIChteXBvcyAhPSBpbnB1dC5sZW5ndGgpIHsNCgkJCXZhciBmaXJzdF9wYWNrZXQgPSBvcGVucGdwX3BhY2tldC5yZWFkX3BhY2tldChpbnB1dCwgbXlwb3MsIGwpOw0KCQkJLy8gcHVibGljIGtleSBwYXJzZXINCgkJCWlmIChpbnB1dFtteXBvc10uY2hhckNvZGVBdCgpID09IDB4OTkgfHwgZmlyc3RfcGFja2V0LnRhZ1R5cGUgPT0gNikgew0KCQkJCXB1YmxpY0tleXNbcHVibGljS2V5Q291bnRdID0gbmV3IG9wZW5wZ3BfbXNnX3B1YmxpY2tleSgpOwkJCQkNCgkJCQlwdWJsaWNLZXlzW3B1YmxpY0tleUNvdW50XS5oZWFkZXIgPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MsbXlwb3MrMyk7DQoJCQkJaWYgKGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgPT0gMHg5OSkgew0KCQkJCQkvLyBwYXJzZSB0aGUgbGVuZ3RoIGFuZCByZWFkIGEgdGFnNiBwYWNrZXQNCgkJCQkJbXlwb3MrKzsNCgkJCQkJdmFyIGwgPSAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDgpDQoJCQkJCQkJfCBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoJCQkJCXB1YmxpY0tleXNbcHVibGljS2V5Q291bnRdLnB1YmxpY0tleVBhY2tldCA9IG5ldyBvcGVucGdwX3BhY2tldF9rZXltYXRlcmlhbCgpOw0KCQkJCQlwdWJsaWNLZXlzW3B1YmxpY0tleUNvdW50XS5wdWJsaWNLZXlQYWNrZXQuaGVhZGVyID0gcHVibGljS2V5c1twdWJsaWNLZXlDb3VudF0uaGVhZGVyOw0KCQkJCQlwdWJsaWNLZXlzW3B1YmxpY0tleUNvdW50XS5wdWJsaWNLZXlQYWNrZXQucmVhZF90YWc2KGlucHV0LCBteXBvcywgbCk7DQoJCQkJCW15cG9zICs9IHB1YmxpY0tleXNbcHVibGljS2V5Q291bnRdLnB1YmxpY0tleVBhY2tldC5wYWNrZXRMZW5ndGg7DQoJCQkJCW15cG9zICs9IHB1YmxpY0tleXNbcHVibGljS2V5Q291bnRdLnJlYWRfbm9kZXMocHVibGljS2V5c1twdWJsaWNLZXlDb3VudF0ucHVibGljS2V5UGFja2V0LCBpbnB1dCwgbXlwb3MsIChpbnB1dC5sZW5ndGggLSBteXBvcykpOw0KCQkJCX0gZWxzZSB7DQoJCQkJCXB1YmxpY0tleXNbcHVibGljS2V5Q291bnRdID0gbmV3IG9wZW5wZ3BfbXNnX3B1YmxpY2tleSgpOw0KCQkJCQlwdWJsaWNLZXlzW3B1YmxpY0tleUNvdW50XS5wdWJsaWNLZXlQYWNrZXQgPSBmaXJzdF9wYWNrZXQ7DQoJCQkJCW15cG9zICs9IGZpcnN0X3BhY2tldC5oZWFkZXJMZW5ndGgrZmlyc3RfcGFja2V0LnBhY2tldExlbmd0aDsNCgkJCQkJbXlwb3MgKz0gcHVibGljS2V5c1twdWJsaWNLZXlDb3VudF0ucmVhZF9ub2RlcyhmaXJzdF9wYWNrZXQsIGlucHV0LCBteXBvcywgaW5wdXQubGVuZ3RoIC1teXBvcyk7DQoJCQkJfQ0KCQkJfSBlbHNlIHsNCgkJCQl1dGlsLnByaW50X2Vycm9yKCJubyBwdWJsaWMga2V5IGZvdW5kISIpOw0KCQkJCXJldHVybiBudWxsOw0KCQkJfQ0KCQkJcHVibGljS2V5c1twdWJsaWNLZXlDb3VudF0uZGF0YSA9IGlucHV0LnN1YnN0cmluZygwLG15cG9zKTsNCgkJCXB1YmxpY0tleUNvdW50Kys7DQoJCX0NCgkJcmV0dXJuIHB1YmxpY0tleXM7DQoJfQ0KCQ0KCS8qKg0KCSAqIHJlYWRzIHNldmVyYWwgcHJpdmF0ZUtleSBvYmplY3RzIGZyb20gYSBhc2NpaSBhcm1vcmVkDQoJICogcmVwcmVzZW50YXRpb24gYW4gcmV0dXJucyBvcGVucGdwX21zZ19wcml2YXRla2V5IG9iamVjdHMNCgkgKiBAcGFyYW0ge1N0cmluZ30gYXJtb3JlZFRleHQgT3BlblBHUCBhcm1vcmVkIHRleHQgY29udGFpbmluZw0KCSAqIHRoZSBwcml2YXRlIGtleShzKQ0KCSAqIEByZXR1cm4ge29wZW5wZ3BfbXNnX3ByaXZhdGVrZXlbXX0gb24gZXJyb3IgdGhlIGZ1bmN0aW9uDQoJICogcmV0dXJucyBudWxsDQoJICovDQoJZnVuY3Rpb24gcmVhZF9wcml2YXRlS2V5KGFybW9yZWRUZXh0KSB7DQoJCXZhciBwcml2YXRlS2V5cyA9IG5ldyBBcnJheSgpOw0KCQl2YXIgcHJpdmF0ZUtleUNvdW50ID0gMDsNCgkJdmFyIG15cG9zID0gMDsNCgkJdmFyIGlucHV0ID0gb3BlbnBncF9lbmNvZGluZ19kZUFybW9yKGFybW9yZWRUZXh0LnJlcGxhY2UoL1xyL2csJycpKS5vcGVucGdwOw0KCQl2YXIgbCA9IGlucHV0Lmxlbmd0aDsNCgkJd2hpbGUgKG15cG9zICE9IGlucHV0Lmxlbmd0aCkgew0KCQkJdmFyIGZpcnN0X3BhY2tldCA9IG9wZW5wZ3BfcGFja2V0LnJlYWRfcGFja2V0KGlucHV0LCBteXBvcywgbCk7DQoJCQlpZiAoZmlyc3RfcGFja2V0LnRhZ1R5cGUgPT0gNSkgew0KCQkJCXByaXZhdGVLZXlzW3ByaXZhdGVLZXlzLmxlbmd0aF0gPSBuZXcgb3BlbnBncF9tc2dfcHJpdmF0ZWtleSgpOw0KCQkJCW15cG9zICs9IGZpcnN0X3BhY2tldC5oZWFkZXJMZW5ndGgrZmlyc3RfcGFja2V0LnBhY2tldExlbmd0aDsNCgkJCQlteXBvcyArPSBwcml2YXRlS2V5c1twcml2YXRlS2V5Q291bnRdLnJlYWRfbm9kZXMoZmlyc3RfcGFja2V0LCBpbnB1dCwgbXlwb3MsIGwpOw0KCQkJLy8gb3RoZXIgYmxvY2tzCSAgICAgICAgICAgIA0KCQkJfSBlbHNlIHsNCgkJCQl1dGlsLnByaW50X2Vycm9yKCdubyBibG9jayBwYWNrZXQgZm91bmQhJyk7DQoJCQkJcmV0dXJuIG51bGw7DQoJCQl9DQoJCQlwcml2YXRlS2V5c1twcml2YXRlS2V5Q291bnRdLmRhdGEgPSBpbnB1dC5zdWJzdHJpbmcoMCxteXBvcyk7DQoJCQlwcml2YXRlS2V5Q291bnQrKzsNCgkJfQ0KCQlyZXR1cm4gcHJpdmF0ZUtleXM7CQkNCgl9DQoNCgkvKioNCgkgKiByZWFkcyBtZXNzYWdlIHBhY2tldHMgb3V0IG9mIGFuIE9wZW5QR1AgYXJtb3JlZCB0ZXh0IGFuZA0KCSAqIHJldHVybnMgYW4gYXJyYXkgb2YgbWVzc2FnZSBvYmplY3RzDQoJICogQHBhcmFtIHtTdHJpbmd9IGFybW9yZWRUZXh0IHRleHQgdG8gYmUgcGFyc2VkDQoJICogQHJldHVybiB7b3BlbnBncF9tc2dfbWVzc2FnZVtdfSBvbiBlcnJvciB0aGUgZnVuY3Rpb24NCgkgKiByZXR1cm5zIG51bGwNCgkgKi8NCglmdW5jdGlvbiByZWFkX21lc3NhZ2UoYXJtb3JlZFRleHQpIHsNCgkJdmFyIGRlYXJtb3JlZDsNCgkJdHJ5ew0KICAgIAkJZGVhcm1vcmVkID0gb3BlbnBncF9lbmNvZGluZ19kZUFybW9yKGFybW9yZWRUZXh0LnJlcGxhY2UoL1xyL2csJycpKTsNCgkJfQ0KCQljYXRjaChlKXsNCiAgICAJCXV0aWwucHJpbnRfZXJyb3IoJ25vIG1lc3NhZ2UgZm91bmQhJyk7DQogICAgCQlyZXR1cm4gbnVsbDsNCgkJfQ0KCQlyZXR1cm4gcmVhZF9tZXNzYWdlc19kZWFybW9yZWQoZGVhcm1vcmVkKTsNCgkJfQ0KCQkNCgkvKioNCgkgKiByZWFkcyBtZXNzYWdlIHBhY2tldHMgb3V0IG9mIGFuIE9wZW5QR1AgYXJtb3JlZCB0ZXh0IGFuZA0KCSAqIHJldHVybnMgYW4gYXJyYXkgb2YgbWVzc2FnZSBvYmplY3RzLiBDYW4gYmUgY2FsbGVkIGV4dGVybmFsbHkgb3IgaW50ZXJuYWxseS4NCgkgKiBFeHRlcm5hbCBjYWxsIHdpbGwgcGFyc2UgYSBkZS1hcm1vcmVkIG1lc3NhZ2VkIGFuZCByZXR1cm4gbWVzc2FnZXMgZm91bmQuDQoJICogSW50ZXJuYWwgd2lsbCBiZSBjYWxsZWQgdG8gcmVhZCBwYWNrZXRzIHdyYXBwZWQgaW4gb3RoZXIgcGFja2V0cyAoaS5lLiBjb21wcmVzc2VkKQ0KCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBkZWFybW9yZWQgdGV4dCBvZiBPcGVuUEdQIHBhY2tldHMsIHRvIGJlIHBhcnNlZA0KCSAqIEByZXR1cm4ge29wZW5wZ3BfbXNnX21lc3NhZ2VbXX0gb24gZXJyb3IgdGhlIGZ1bmN0aW9uDQoJICogcmV0dXJucyBudWxsDQoJICovDQoJZnVuY3Rpb24gcmVhZF9tZXNzYWdlc19kZWFybW9yZWQoaW5wdXQpew0KCQl2YXIgbWVzc2FnZVN0cmluZyA9IGlucHV0Lm9wZW5wZ3A7DQoJCXZhciBzaWduYXR1cmVUZXh0ID0gaW5wdXQudGV4dDsgLy90ZXh0IHRvIHZlcmlmeSBzaWduYXR1cmVzIGFnYWluc3QuIE1vZGlmaWVkIGJ5IFRhZzExLg0KCQl2YXIgbWVzc2FnZXMgPSBuZXcgQXJyYXkoKTsNCgkJdmFyIG1lc3NhZ2VDb3VudCA9IDA7DQoJCXZhciBteXBvcyA9IDA7DQoJCXZhciBsID0gbWVzc2FnZVN0cmluZy5sZW5ndGg7DQoJCXdoaWxlIChteXBvcyA8IG1lc3NhZ2VTdHJpbmcubGVuZ3RoKSB7DQoJCQl2YXIgZmlyc3RfcGFja2V0ID0gb3BlbnBncF9wYWNrZXQucmVhZF9wYWNrZXQobWVzc2FnZVN0cmluZywgbXlwb3MsIGwpOw0KCQkJaWYgKCFmaXJzdF9wYWNrZXQpIHsNCgkJCQlicmVhazsNCgkJCX0NCgkJCS8vIHB1YmxpYyBrZXkgcGFyc2VyIChkZWZpbml0aW9uIGZyb20gdGhlIHN0YW5kYXJkOikNCgkJCS8vIE9wZW5QR1AgTWVzc2FnZSAgICAgIDotIEVuY3J5cHRlZCBNZXNzYWdlIHwgU2lnbmVkIE1lc3NhZ2UgfA0KCQkJLy8gICAgICAgICAgICAgICAgICAgICAgICAgQ29tcHJlc3NlZCBNZXNzYWdlIHwgTGl0ZXJhbCBNZXNzYWdlLg0KCQkJLy8gQ29tcHJlc3NlZCBNZXNzYWdlICAgOi0gQ29tcHJlc3NlZCBEYXRhIFBhY2tldC4NCgkJCS8vIA0KCQkJLy8gTGl0ZXJhbCBNZXNzYWdlICAgICAgOi0gTGl0ZXJhbCBEYXRhIFBhY2tldC4NCgkJCS8vIA0KCQkJLy8gRVNLICAgICAgICAgICAgICAgICAgOi0gUHVibGljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgUGFja2V0IHwNCgkJCS8vICAgICAgICAgICAgICAgICAgICAgICAgIFN5bW1ldHJpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IFBhY2tldC4NCgkJCS8vIA0KCQkJLy8gRVNLIFNlcXVlbmNlICAgICAgICAgOi0gRVNLIHwgRVNLIFNlcXVlbmNlLCBFU0suDQoJCQkvLyANCgkJCS8vIEVuY3J5cHRlZCBEYXRhICAgICAgIDotIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgUGFja2V0IHwNCgkJCS8vICAgICAgICAgICAgICAgICAgICAgICAgIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIEludGVncml0eSBQcm90ZWN0ZWQgRGF0YSBQYWNrZXQNCgkJCS8vIA0KCQkJLy8gRW5jcnlwdGVkIE1lc3NhZ2UgICAgOi0gRW5jcnlwdGVkIERhdGEgfCBFU0sgU2VxdWVuY2UsIEVuY3J5cHRlZCBEYXRhLg0KCQkJLy8gDQoJCQkvLyBPbmUtUGFzcyBTaWduZWQgTWVzc2FnZSA6LSBPbmUtUGFzcyBTaWduYXR1cmUgUGFja2V0LA0KCQkJLy8gICAgICAgICAgICAgICAgICAgICAgICAgT3BlblBHUCBNZXNzYWdlLCBDb3JyZXNwb25kaW5nIFNpZ25hdHVyZSBQYWNrZXQuDQoNCgkJCS8vIFNpZ25lZCBNZXNzYWdlICAgICAgIDotIFNpZ25hdHVyZSBQYWNrZXQsIE9wZW5QR1AgTWVzc2FnZSB8DQoJCQkvLyAgICAgICAgICAgICAgICAgICAgICAgICBPbmUtUGFzcyBTaWduZWQgTWVzc2FnZS4NCgkJCWlmIChmaXJzdF9wYWNrZXQudGFnVHlwZSA9PSAgMSB8fA0KCQkJICAgIChmaXJzdF9wYWNrZXQudGFnVHlwZSA9PSAyICYmIGZpcnN0X3BhY2tldC5zaWduYXR1cmVUeXBlIDwgMTYpIHx8DQoJCQkgICAgIGZpcnN0X3BhY2tldC50YWdUeXBlID09ICAzIHx8DQoJCQkgICAgIGZpcnN0X3BhY2tldC50YWdUeXBlID09ICA0IHx8DQoJCQkJIGZpcnN0X3BhY2tldC50YWdUeXBlID09ICA4IHx8DQoJCQkJIGZpcnN0X3BhY2tldC50YWdUeXBlID09ICA5IHx8DQoJCQkJIGZpcnN0X3BhY2tldC50YWdUeXBlID09IDEwIHx8DQoJCQkJIGZpcnN0X3BhY2tldC50YWdUeXBlID09IDExIHx8DQoJCQkJIGZpcnN0X3BhY2tldC50YWdUeXBlID09IDE4IHx8DQoJCQkJIGZpcnN0X3BhY2tldC50YWdUeXBlID09IDE5KSB7DQoJCQkJbWVzc2FnZXNbbWVzc2FnZXMubGVuZ3RoXSA9IG5ldyBvcGVucGdwX21zZ19tZXNzYWdlKCk7DQoJCQkJbWVzc2FnZXNbbWVzc2FnZUNvdW50XS5tZXNzYWdlUGFja2V0ID0gZmlyc3RfcGFja2V0Ow0KCQkJCW1lc3NhZ2VzW21lc3NhZ2VDb3VudF0udHlwZSA9IGlucHV0LnR5cGU7DQoJCQkJLy8gRW5jcnlwdGVkIE1lc3NhZ2UNCgkJCQlpZiAoZmlyc3RfcGFja2V0LnRhZ1R5cGUgPT0gOSB8fA0KCQkJCSAgICBmaXJzdF9wYWNrZXQudGFnVHlwZSA9PSAxIHx8DQoJCQkJICAgIGZpcnN0X3BhY2tldC50YWdUeXBlID09IDMgfHwNCgkJCQkgICAgZmlyc3RfcGFja2V0LnRhZ1R5cGUgPT0gMTgpIHsNCgkJCQkJaWYgKGZpcnN0X3BhY2tldC50YWdUeXBlID09IDkpIHsNCgkJCQkJCXV0aWwucHJpbnRfZXJyb3IoInVuZXhwZWN0ZWQgb3BlbnBncCBwYWNrZXQiKTsNCgkJCQkJCWJyZWFrOw0KCQkJCQl9IGVsc2UgaWYgKGZpcnN0X3BhY2tldC50YWdUeXBlID09IDEpIHsNCgkJCQkJCXV0aWwucHJpbnRfZGVidWcoInNlc3Npb24ga2V5IGZvdW5kOlxuICIrZmlyc3RfcGFja2V0LnRvU3RyaW5nKCkpOw0KCQkJCQkJdmFyIGlzc2Vzc2lvbmtleSA9IHRydWU7DQoJCQkJCQltZXNzYWdlc1ttZXNzYWdlQ291bnRdLnNlc3Npb25LZXlzID0gbmV3IEFycmF5KCk7DQoJCQkJCQl2YXIgc2Vzc2lvbktleUNvdW50ID0gMDsNCgkJCQkJCXdoaWxlIChpc3Nlc3Npb25rZXkpIHsNCgkJCQkJCQltZXNzYWdlc1ttZXNzYWdlQ291bnRdLnNlc3Npb25LZXlzW3Nlc3Npb25LZXlDb3VudF0gPSBmaXJzdF9wYWNrZXQ7DQoJCQkJCQkJbXlwb3MgKz0gZmlyc3RfcGFja2V0LnBhY2tldExlbmd0aCArIGZpcnN0X3BhY2tldC5oZWFkZXJMZW5ndGg7DQoJCQkJCQkJbCAtPSAoZmlyc3RfcGFja2V0LnBhY2tldExlbmd0aCArIGZpcnN0X3BhY2tldC5oZWFkZXJMZW5ndGgpOw0KCQkJCQkJCWZpcnN0X3BhY2tldCA9IG9wZW5wZ3BfcGFja2V0LnJlYWRfcGFja2V0KG1lc3NhZ2VTdHJpbmcsIG15cG9zLCBsKTsNCgkJCQkJCQkNCgkJCQkJCQlpZiAoZmlyc3RfcGFja2V0LnRhZ1R5cGUgIT0gMSAmJiBmaXJzdF9wYWNrZXQudGFnVHlwZSAhPSAzKQ0KCQkJCQkJCQlpc3Nlc3Npb25rZXkgPSBmYWxzZTsNCgkJCQkJCQlzZXNzaW9uS2V5Q291bnQrKzsNCgkJCQkJCX0NCgkJCQkJCWlmIChmaXJzdF9wYWNrZXQudGFnVHlwZSA9PSAxOCB8fCBmaXJzdF9wYWNrZXQudGFnVHlwZSA9PSA5KSB7DQoJCQkJCQkJdXRpbC5wcmludF9kZWJ1ZygiZW5jcnlwdGVkIGRhdGEgZm91bmQ6XG4gIitmaXJzdF9wYWNrZXQudG9TdHJpbmcoKSk7DQoJCQkJCQkJbWVzc2FnZXNbbWVzc2FnZUNvdW50XS5lbmNyeXB0ZWREYXRhID0gZmlyc3RfcGFja2V0Ow0KCQkJCQkJCW15cG9zICs9IGZpcnN0X3BhY2tldC5wYWNrZXRMZW5ndGgrZmlyc3RfcGFja2V0LmhlYWRlckxlbmd0aDsNCgkJCQkJCQlsIC09IChmaXJzdF9wYWNrZXQucGFja2V0TGVuZ3RoK2ZpcnN0X3BhY2tldC5oZWFkZXJMZW5ndGgpOw0KCQkJCQkJCW1lc3NhZ2VDb3VudCsrOw0KCQkJCQkJCQ0KCQkJCQkJfSBlbHNlIHsNCgkJCQkJCQl1dGlsLnByaW50X2RlYnVnKCJzb21ldGhpbmcgaXMgd3Jvbmc6ICIrZmlyc3RfcGFja2V0LnRhZ1R5cGUpOw0KCQkJCQkJfQ0KCQkJCQkJDQoJCQkJCX0gZWxzZSBpZiAoZmlyc3RfcGFja2V0LnRhZ1R5cGUgPT0gMTgpIHsNCgkJCQkJCXV0aWwucHJpbnRfZGVidWcoInN5bW1ldHJpYyBlbmNyeXB0ZWQgZGF0YSIpOw0KCQkJCQkJYnJlYWs7DQoJCQkJCX0NCgkJCQl9IGVsc2UgDQoJCQkJCWlmIChmaXJzdF9wYWNrZXQudGFnVHlwZSA9PSAyICYmIGZpcnN0X3BhY2tldC5zaWduYXR1cmVUeXBlIDwgMykgew0KCQkJCQkvLyBTaWduZWQgTWVzc2FnZQ0KCQkJCQkJbXlwb3MgKz0gZmlyc3RfcGFja2V0LnBhY2tldExlbmd0aCArIGZpcnN0X3BhY2tldC5oZWFkZXJMZW5ndGg7DQoJCQkJCQlsIC09IChmaXJzdF9wYWNrZXQucGFja2V0TGVuZ3RoICsgZmlyc3RfcGFja2V0LmhlYWRlckxlbmd0aCk7DQoJCQkJCQltZXNzYWdlc1ttZXNzYWdlQ291bnRdLnRleHQgPSBzaWduYXR1cmVUZXh0Ow0KCQkJCQkJbWVzc2FnZXNbbWVzc2FnZUNvdW50XS5zaWduYXR1cmUgPSBmaXJzdF9wYWNrZXQ7DQoJCQkJICAgICAgICBtZXNzYWdlQ291bnQrKzsNCgkJCQl9IGVsc2UgDQoJCQkJCS8vIFNpZ25lZCBNZXNzYWdlDQoJCQkJCWlmIChmaXJzdF9wYWNrZXQudGFnVHlwZSA9PSA0KSB7DQoJCQkJCQkvL1RPRE86IEltcGxlbWVudCBjaGVjaw0KCQkJCQkJbXlwb3MgKz0gZmlyc3RfcGFja2V0LnBhY2tldExlbmd0aCArIGZpcnN0X3BhY2tldC5oZWFkZXJMZW5ndGg7DQoJCQkJCQlsIC09IChmaXJzdF9wYWNrZXQucGFja2V0TGVuZ3RoICsgZmlyc3RfcGFja2V0LmhlYWRlckxlbmd0aCk7DQoJCQkJfSBlbHNlIA0KCQkJCQlpZiAoZmlyc3RfcGFja2V0LnRhZ1R5cGUgPT0gOCkgew0KCQkJCQkvLyBDb21wcmVzc2VkIE1lc3NhZ2UNCgkJCQkJCW15cG9zICs9IGZpcnN0X3BhY2tldC5wYWNrZXRMZW5ndGggKyBmaXJzdF9wYWNrZXQuaGVhZGVyTGVuZ3RoOw0KCQkJCQkJbCAtPSAoZmlyc3RfcGFja2V0LnBhY2tldExlbmd0aCArIGZpcnN0X3BhY2tldC5oZWFkZXJMZW5ndGgpOw0KCQkJCSAgICAgICAgdmFyIGRlY29tcHJlc3NlZFRleHQgPSBmaXJzdF9wYWNrZXQuZGVjb21wcmVzcygpOw0KCQkJCSAgICAgICAgbWVzc2FnZXMgPSBtZXNzYWdlcy5jb25jYXQob3BlbnBncC5yZWFkX21lc3NhZ2VzX2RlYXJtb3JlZCh7dGV4dDogZGVjb21wcmVzc2VkVGV4dCwgb3BlbnBncDogZGVjb21wcmVzc2VkVGV4dH0pKTsNCgkJCQl9IGVsc2UNCgkJCQkJLy8gTWFya2VyIFBhY2tldCAoT2Jzb2xldGUgTGl0ZXJhbCBQYWNrZXQpIChUYWcgMTApDQoJCQkJCS8vICJTdWNoIGEgcGFja2V0IE1VU1QgYmUgaWdub3JlZCB3aGVuIHJlY2VpdmVkLiIgc2VlIGh0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzQ4ODAjc2VjdGlvbi01LjgNCgkJCQkJaWYgKGZpcnN0X3BhY2tldC50YWdUeXBlID09IDEwKSB7DQoJCQkJCQkvLyByZXNldCBtZXNzYWdlcw0KCQkJCQkJbWVzc2FnZXMubGVuZ3RoID0gMDsNCgkJCQkJCS8vIGNvbnRpbnVlIHdpdGggbmV4dCBwYWNrZXQNCgkJCQkJCW15cG9zICs9IGZpcnN0X3BhY2tldC5wYWNrZXRMZW5ndGggKyBmaXJzdF9wYWNrZXQuaGVhZGVyTGVuZ3RoOw0KCQkJCQkJbCAtPSAoZmlyc3RfcGFja2V0LnBhY2tldExlbmd0aCArIGZpcnN0X3BhY2tldC5oZWFkZXJMZW5ndGgpOw0KCQkJCX0gZWxzZSANCgkJCQkJaWYgKGZpcnN0X3BhY2tldC50YWdUeXBlID09IDExKSB7DQoJCQkJCS8vIExpdGVyYWwgTWVzc2FnZSAtLSB3b3JrIGlzIGFscmVhZHkgZG9uZSBpbiByZWFkX3BhY2tldA0KCQkJCQlteXBvcyArPSBmaXJzdF9wYWNrZXQucGFja2V0TGVuZ3RoICsgZmlyc3RfcGFja2V0LmhlYWRlckxlbmd0aDsNCgkJCQkJbCAtPSAoZmlyc3RfcGFja2V0LnBhY2tldExlbmd0aCArIGZpcnN0X3BhY2tldC5oZWFkZXJMZW5ndGgpOw0KCQkJCQlzaWduYXR1cmVUZXh0ID0gZmlyc3RfcGFja2V0LmRhdGE7DQoJCQkJCW1lc3NhZ2VzW21lc3NhZ2VDb3VudF0uZGF0YSA9IGZpcnN0X3BhY2tldC5kYXRhOw0KCQkJCQltZXNzYWdlQ291bnQrKzsNCgkJCQl9IGVsc2UgDQoJCQkJCWlmIChmaXJzdF9wYWNrZXQudGFnVHlwZSA9PSAxOSkgew0KCQkJCQkvLyBNb2RpZmljYXRpb24gRGV0ZWN0IENvZGUNCgkJCQkJCW15cG9zICs9IGZpcnN0X3BhY2tldC5wYWNrZXRMZW5ndGggKyBmaXJzdF9wYWNrZXQuaGVhZGVyTGVuZ3RoOw0KCQkJCQkJbCAtPSAoZmlyc3RfcGFja2V0LnBhY2tldExlbmd0aCArIGZpcnN0X3BhY2tldC5oZWFkZXJMZW5ndGgpOw0KCQkJCX0NCgkJCX0gZWxzZSB7DQoJCQkJdXRpbC5wcmludF9lcnJvcignbm8gbWVzc2FnZSBmb3VuZCEnKTsNCgkJCQlyZXR1cm4gbnVsbDsNCgkJCX0NCgkJfQ0KCQkNCgkJcmV0dXJuIG1lc3NhZ2VzOw0KCX0NCgkNCgkvKioNCgkgKiBjcmVhdGVzIGEgYmluYXJ5IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhbiBlbmNyeXB0ZWQgYW5kIHNpZ25lZCBtZXNzYWdlLg0KCSAqIFRoZSBtZXNzYWdlIHdpbGwgYmUgZW5jcnlwdGVkIHdpdGggdGhlIHB1YmxpYyBrZXlzIHNwZWNpZmllZCBhbmQgc2lnbmVkDQoJICogd2l0aCB0aGUgc3BlY2lmaWVkIHByaXZhdGUga2V5Lg0KCSAqIEBwYXJhbSB7T2JqZWN0fSBwcml2YXRla2V5IHtvYmo6IFtvcGVucGdwX21zZ19wcml2YXRla2V5XX0gUHJpdmF0ZSBrZXkgDQoJICogdG8gYmUgdXNlZCB0byBzaWduIHRoZSBtZXNzYWdlDQoJICogQHBhcmFtIHtPYmplY3RbXX0gcHVibGlja2V5cyBBbiBhcnJhZiBvZiB7b2JqOiBbb3BlbnBncF9tc2dfcHVibGlja2V5XX0NCgkgKiAtIHB1YmxpYyBrZXlzIHRvIGJlIHVzZWQgdG8gZW5jcnlwdCB0aGUgbWVzc2FnZSANCgkgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZXRleHQgbWVzc2FnZSB0ZXh0IHRvIGVuY3J5cHQgYW5kIHNpZ24NCgkgKiBAcmV0dXJuIHtTdHJpbmd9IGEgYmluYXJ5IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgbWVzc2FnZSB3aGljaCANCgkgKiBjYW4gYmUgT3BlblBHUCBhcm1vcmVkDQoJICovDQoJZnVuY3Rpb24gd3JpdGVfc2lnbmVkX2FuZF9lbmNyeXB0ZWRfbWVzc2FnZShwcml2YXRla2V5LCBwdWJsaWNrZXlzLCBtZXNzYWdldGV4dCkgew0KCQl2YXIgcmVzdWx0ID0gIiI7DQoJCXZhciBsaXRlcmFsID0gbmV3IG9wZW5wZ3BfcGFja2V0X2xpdGVyYWxkYXRhKCkud3JpdGVfcGFja2V0KG1lc3NhZ2V0ZXh0LnJlcGxhY2UoL1xyXG4vZywiXG4iKS5yZXBsYWNlKC9cbi9nLCJcclxuIikpOw0KCQl1dGlsLnByaW50X2RlYnVnX2hleHN0cl9kdW1wKCJsaXRlcmFsX3BhY2tldDogfCIrbGl0ZXJhbCsifFxuIixsaXRlcmFsKTsNCgkJZm9yICh2YXIgaSA9IDA7IGkgPCBwdWJsaWNrZXlzLmxlbmd0aDsgaSsrKSB7DQoJCQl2YXIgb25lcGFzc3NpZ25hdHVyZSA9IG5ldyBvcGVucGdwX3BhY2tldF9vbmVwYXNzc2lnbmF0dXJlKCk7DQoJCQl2YXIgb25lcGFzc3NpZ3N0ciA9ICIiOw0KCQkJaWYgKGkgPT0gMCkNCgkJCQlvbmVwYXNzc2lnc3RyID0gb25lcGFzc3NpZ25hdHVyZS53cml0ZV9wYWNrZXQoMSwgb3BlbnBncC5jb25maWcuY29uZmlnLnByZWZlcl9oYXNoX2FsZ29yaXRobSwgIHByaXZhdGVrZXksIGZhbHNlKTsNCgkJCWVsc2UNCgkJCQlvbmVwYXNzc2lnc3RyID0gb25lcGFzc3NpZ25hdHVyZS53cml0ZV9wYWNrZXQoMSwgb3BlbnBncC5jb25maWcuY29uZmlnLnByZWZlcl9oYXNoX2FsZ29yaXRobSwgIHByaXZhdGVrZXksIGZhbHNlKTsNCgkJCXV0aWwucHJpbnRfZGVidWdfaGV4c3RyX2R1bXAoIm9uZXBhc3NzaWdzdHI6IHwiK29uZXBhc3NzaWdzdHIrInxcbiIsb25lcGFzc3NpZ3N0cik7DQoJCQl2YXIgZGF0YXNpZ25hdHVyZSA9IG5ldyBvcGVucGdwX3BhY2tldF9zaWduYXR1cmUoKS53cml0ZV9tZXNzYWdlX3NpZ25hdHVyZSgxLCBtZXNzYWdldGV4dC5yZXBsYWNlKC9cclxuL2csIlxuIikucmVwbGFjZSgvXG4vZywiXHJcbiIpLCBwcml2YXRla2V5KTsNCgkJCXV0aWwucHJpbnRfZGVidWdfaGV4c3RyX2R1bXAoImRhdGFzaWduYXR1cmU6IHwiK2RhdGFzaWduYXR1cmUub3BlbnBncCsifFxuIixkYXRhc2lnbmF0dXJlLm9wZW5wZ3ApOw0KCQkJaWYgKGkgPT0gMCkgew0KCQkJCXJlc3VsdCA9IG9uZXBhc3NzaWdzdHIrbGl0ZXJhbCtkYXRhc2lnbmF0dXJlLm9wZW5wZ3A7DQoJCQl9IGVsc2Ugew0KCQkJCXJlc3VsdCA9IG9uZXBhc3NzaWdzdHIrcmVzdWx0K2RhdGFzaWduYXR1cmUub3BlbnBncDsNCgkJCX0NCgkJfQ0KCQkNCgkJdXRpbC5wcmludF9kZWJ1Z19oZXhzdHJfZHVtcCgic2lnbmVkIHBhY2tldDogfCIrcmVzdWx0KyJ8XG4iLHJlc3VsdCk7DQoJCS8vIHNpZ25hdHVyZXMgZG9uZS4uIG5vdyBlbmNyeXB0aW9uDQoJCXZhciBzZXNzaW9ua2V5ID0gb3BlbnBncF9jcnlwdG9fZ2VuZXJhdGVTZXNzaW9uS2V5KG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlcik7IA0KCQl2YXIgcmVzdWx0MiA9ICIiOw0KCQkNCgkJLy8gY3JlYXRpbmcgc2Vzc2lvbiBrZXlzIGZvciBlYWNoIHJlY2lwaWVudA0KCQlmb3IgKHZhciBpID0gMDsgaSA8IHB1YmxpY2tleXMubGVuZ3RoOyBpKyspIHsNCgkJCXZhciBwa2V5ID0gcHVibGlja2V5c1tpXS5nZXRFbmNyeXB0aW9uS2V5KCk7DQoJCQlpZiAocGtleSA9PSBudWxsKSB7DQoJCQkJdXRpbC5wcmludF9lcnJvcigibm8gZW5jcnlwdGlvbiBrZXkgZm91bmQhIEtleSBpcyBmb3Igc2lnbmluZyBvbmx5LiIpOw0KCQkJCXJldHVybiBudWxsOw0KCQkJfQ0KCQkJcmVzdWx0MiArPSBuZXcgb3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkc2Vzc2lvbmtleSgpLg0KCQkJCQl3cml0ZV9wdWJfa2V5X3BhY2tldCgNCgkJCQkJCXBrZXkuZ2V0S2V5SWQoKSwNCgkJCQkJCXBrZXkuTVBJcywNCgkJCQkJCXBrZXkucHVibGljS2V5QWxnb3JpdGhtLA0KCQkJCQkJb3BlbnBncC5jb25maWcuY29uZmlnLmVuY3J5cHRpb25fY2lwaGVyLA0KCQkJCQkJc2Vzc2lvbmtleSk7DQoJCX0NCgkJaWYgKG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5pbnRlZ3JpdHlfcHJvdGVjdCkgew0KCQkJcmVzdWx0MiArPSBuZXcgb3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkaW50ZWdyaXR5cHJvdGVjdGVkZGF0YSgpLndyaXRlX3BhY2tldChvcGVucGdwLmNvbmZpZy5jb25maWcuZW5jcnlwdGlvbl9jaXBoZXIsIHNlc3Npb25rZXksIHJlc3VsdCk7DQoJCX0gZWxzZSB7DQoJCQlyZXN1bHQyICs9IG5ldyBvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhKCkud3JpdGVfcGFja2V0KG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlciwgc2Vzc2lvbmtleSwgcmVzdWx0KTsNCgkJfQ0KCQlyZXR1cm4gb3BlbnBncF9lbmNvZGluZ19hcm1vcigzLHJlc3VsdDIsbnVsbCxudWxsKTsNCgl9DQoJLyoqDQoJICogY3JlYXRlcyBhIGJpbmFyeSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYW4gZW5jcnlwdGVkIG1lc3NhZ2UuDQoJICogVGhlIG1lc3NhZ2Ugd2lsbCBiZSBlbmNyeXB0ZWQgd2l0aCB0aGUgcHVibGljIGtleXMgc3BlY2lmaWVkIA0KCSAqIEBwYXJhbSB7T2JqZWN0W119IHB1YmxpY2tleXMgQW4gYXJyYXkgb2Yge29iajogW29wZW5wZ3BfbXNnX3B1YmxpY2tleV19DQoJICogLXB1YmxpYyBrZXlzIHRvIGJlIHVzZWQgdG8gZW5jcnlwdCB0aGUgbWVzc2FnZSANCgkgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZXRleHQgbWVzc2FnZSB0ZXh0IHRvIGVuY3J5cHQNCgkgKiBAcmV0dXJuIHtTdHJpbmd9IGEgYmluYXJ5IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgbWVzc2FnZQ0KCSAqIHdoaWNoIGNhbiBiZSBPcGVuUEdQIGFybW9yZWQNCgkgKi8NCglmdW5jdGlvbiB3cml0ZV9lbmNyeXB0ZWRfbWVzc2FnZShwdWJsaWNrZXlzLCBtZXNzYWdldGV4dCkgew0KCQl2YXIgcmVzdWx0ID0gIiI7DQoJCXZhciBsaXRlcmFsID0gbmV3IG9wZW5wZ3BfcGFja2V0X2xpdGVyYWxkYXRhKCkud3JpdGVfcGFja2V0KG1lc3NhZ2V0ZXh0LnJlcGxhY2UoL1xyXG4vZywiXG4iKS5yZXBsYWNlKC9cbi9nLCJcclxuIikpOw0KCQl1dGlsLnByaW50X2RlYnVnX2hleHN0cl9kdW1wKCJsaXRlcmFsX3BhY2tldDogfCIrbGl0ZXJhbCsifFxuIixsaXRlcmFsKTsNCgkJcmVzdWx0ID0gbGl0ZXJhbDsNCgkJDQoJCS8vIHNpZ25hdHVyZXMgZG9uZS4uIG5vdyBlbmNyeXB0aW9uDQoJCXZhciBzZXNzaW9ua2V5ID0gb3BlbnBncF9jcnlwdG9fZ2VuZXJhdGVTZXNzaW9uS2V5KG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlcik7IA0KCQl2YXIgcmVzdWx0MiA9ICIiOw0KCQkNCgkJLy8gY3JlYXRpbmcgc2Vzc2lvbiBrZXlzIGZvciBlYWNoIHJlY2lwaWVudA0KCQlmb3IgKHZhciBpID0gMDsgaSA8IHB1YmxpY2tleXMubGVuZ3RoOyBpKyspIHsNCgkJCXZhciBwa2V5ID0gcHVibGlja2V5c1tpXS5nZXRFbmNyeXB0aW9uS2V5KCk7DQoJCQlpZiAocGtleSA9PSBudWxsKSB7DQoJCQkJdXRpbC5wcmludF9lcnJvcigibm8gZW5jcnlwdGlvbiBrZXkgZm91bmQhIEtleSBpcyBmb3Igc2lnbmluZyBvbmx5LiIpOw0KCQkJCXJldHVybiBudWxsOw0KCQkJfQ0KCQkJcmVzdWx0MiArPSBuZXcgb3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkc2Vzc2lvbmtleSgpLg0KCQkJCQl3cml0ZV9wdWJfa2V5X3BhY2tldCgNCgkJCQkJCXBrZXkuZ2V0S2V5SWQoKSwNCgkJCQkJCXBrZXkuTVBJcywNCgkJCQkJCXBrZXkucHVibGljS2V5QWxnb3JpdGhtLA0KCQkJCQkJb3BlbnBncC5jb25maWcuY29uZmlnLmVuY3J5cHRpb25fY2lwaGVyLA0KCQkJCQkJc2Vzc2lvbmtleSk7DQoJCX0NCgkJaWYgKG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5pbnRlZ3JpdHlfcHJvdGVjdCkgew0KCQkJcmVzdWx0MiArPSBuZXcgb3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkaW50ZWdyaXR5cHJvdGVjdGVkZGF0YSgpLndyaXRlX3BhY2tldChvcGVucGdwLmNvbmZpZy5jb25maWcuZW5jcnlwdGlvbl9jaXBoZXIsIHNlc3Npb25rZXksIHJlc3VsdCk7DQoJCX0gZWxzZSB7DQoJCQlyZXN1bHQyICs9IG5ldyBvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhKCkud3JpdGVfcGFja2V0KG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlciwgc2Vzc2lvbmtleSwgcmVzdWx0KTsNCgkJfQ0KCQlyZXR1cm4gb3BlbnBncF9lbmNvZGluZ19hcm1vcigzLHJlc3VsdDIsbnVsbCxudWxsKTsNCgl9DQoJDQoJLyoqDQoJICogY3JlYXRlcyBhIGJpbmFyeSBzdHJpbmcgcmVwcmVzZW50YXRpb24gYSBzaWduZWQgbWVzc2FnZS4NCgkgKiBUaGUgbWVzc2FnZSB3aWxsIGJlIHNpZ25lZCB3aXRoIHRoZSBzcGVjaWZpZWQgcHJpdmF0ZSBrZXkuDQoJICogQHBhcmFtIHtPYmplY3R9IHByaXZhdGVrZXkge29iajogW29wZW5wZ3BfbXNnX3ByaXZhdGVrZXldfQ0KCSAqIC0gdGhlIHByaXZhdGUga2V5IHRvIGJlIHVzZWQgdG8gc2lnbiB0aGUgbWVzc2FnZSANCgkgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZXRleHQgbWVzc2FnZSB0ZXh0IHRvIHNpZ24NCgkgKiBAcmV0dXJuIHtPYmplY3R9IHtPYmplY3Q6IHRleHQgW1N0cmluZ119LCBvcGVucGdwOiB7U3RyaW5nfSBhIGJpbmFyeQ0KCSAqICBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG1lc3NhZ2Ugd2hpY2ggY2FuIGJlIE9wZW5QR1ANCgkgKiAgIGFybW9yZWQob3BlbnBncCkgYW5kIGEgdGV4dCByZXByZXNlbnRhdGlvbiBvZiB0aGUgbWVzc2FnZSAodGV4dCkuIA0KCSAqIFRoaXMgY2FuIGJlIGRpcmVjdGx5IHVzZWQgdG8gT3BlblBHUCBhcm1vciB0aGUgbWVzc2FnZQ0KCSAqLw0KCWZ1bmN0aW9uIHdyaXRlX3NpZ25lZF9tZXNzYWdlKHByaXZhdGVrZXksIG1lc3NhZ2V0ZXh0KSB7DQoJCXZhciBzaWcgPSBuZXcgb3BlbnBncF9wYWNrZXRfc2lnbmF0dXJlKCkud3JpdGVfbWVzc2FnZV9zaWduYXR1cmUoMSwgbWVzc2FnZXRleHQucmVwbGFjZSgvXHJcbi9nLCJcbiIpLnJlcGxhY2UoL1xuLywiXHJcbiIpLCBwcml2YXRla2V5KTsNCgkJdmFyIHJlc3VsdCA9IHt0ZXh0OiBtZXNzYWdldGV4dC5yZXBsYWNlKC9cclxuL2csIlxuIikucmVwbGFjZSgvXG4vLCJcclxuIiksIG9wZW5wZ3A6IHNpZy5vcGVucGdwLCBoYXNoOiBzaWcuaGFzaH07DQoJCXJldHVybiBvcGVucGdwX2VuY29kaW5nX2FybW9yKDIscmVzdWx0LCBudWxsLCBudWxsKQ0KCX0NCgkNCgkvKioNCgkgKiBnZW5lcmF0ZXMgYSBuZXcga2V5IHBhaXIgZm9yIG9wZW5wZ3AuIEJldGEgc3RhZ2UuIEN1cnJlbnRseSBvbmx5IA0KCSAqIHN1cHBvcnRzIFJTQSBrZXlzLCBhbmQgbm8gc3Via2V5cy4NCgkgKiBAcGFyYW0ge0ludGVnZXJ9IGtleVR5cGUgdG8gaW5kaWNhdGUgd2hhdCB0eXBlIG9mIGtleSB0byBtYWtlLiANCgkgKiBSU0EgaXMgMS4gRm9sbG93cyBhbGdvcml0aG1zIG91dGxpbmVkIGluIE9wZW5QR1AuDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBudW1CaXRzIG51bWJlciBvZiBiaXRzIGZvciB0aGUga2V5IGNyZWF0aW9uLiAoc2hvdWxkIA0KCSAqIGJlIDEwMjQrLCBnZW5lcmFsbHkpDQoJICogQHBhcmFtIHtTdHJpbmd9IHVzZXJJZCBhc3N1bWVzIGFscmVhZHkgaW4gZm9ybSBvZiAiVXNlciBOYW1lIA0KCSAqIDx1c2VybmFtZUBlbWFpbC5jb20+Ig0KCSAqIEBwYXJhbSB7U3RyaW5nfSBwYXNzcGhyYXNlIFRoZSBwYXNzcGhyYXNlIHVzZWQgdG8gZW5jcnlwdCB0aGUgcmVzdWx0aW5nIHByaXZhdGUga2V5DQoJICogQHJldHVybiB7T2JqZWN0fSB7cHJpdmF0ZUtleTogW29wZW5wZ3BfbXNnX3ByaXZhdGVrZXldLCANCgkgKiBwcml2YXRlS2V5QXJtb3JlZDogW3N0cmluZ10sIHB1YmxpY0tleUFybW9yZWQ6IFtzdHJpbmddfQ0KCSAqLw0KCWZ1bmN0aW9uIGdlbmVyYXRlX2tleV9wYWlyKGtleVR5cGUsIG51bUJpdHMsIHVzZXJJZCwgcGFzc3BocmFzZSl7DQoJCXZhciB1c2VySWRQYWNrZXQgPSBuZXcgb3BlbnBncF9wYWNrZXRfdXNlcmlkKCk7DQoJCXZhciB1c2VySWRTdHJpbmcgPSB1c2VySWRQYWNrZXQud3JpdGVfcGFja2V0KHVzZXJJZCk7DQoJCQ0KCQl2YXIga2V5UGFpciA9IG9wZW5wZ3BfY3J5cHRvX2dlbmVyYXRlS2V5UGFpcihrZXlUeXBlLG51bUJpdHMsIHBhc3NwaHJhc2UsIG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG0sIDMpOw0KCQl2YXIgcHJpdktleVN0cmluZyA9IGtleVBhaXIucHJpdmF0ZUtleTsNCgkJdmFyIHByaXZLZXlQYWNrZXQgPSBuZXcgb3BlbnBncF9wYWNrZXRfa2V5bWF0ZXJpYWwoKS5yZWFkX3ByaXZfa2V5KHByaXZLZXlTdHJpbmcuc3RyaW5nLDMscHJpdktleVN0cmluZy5zdHJpbmcubGVuZ3RoKTsNCgkJaWYoIXByaXZLZXlQYWNrZXQuZGVjcnlwdFNlY3JldE1QSXMocGFzc3BocmFzZSkpDQoJCSAgICB1dGlsLnByaW50X2Vycm9yKCdJc3N1ZSBjcmVhdGluZyBrZXkuIFVuYWJsZSB0byByZWFkIHJlc3VsdGluZyBwcml2YXRlIGtleScpOw0KCQl2YXIgcHJpdktleSA9IG5ldyBvcGVucGdwX21zZ19wcml2YXRla2V5KCk7DQoJCXByaXZLZXkucHJpdmF0ZUtleVBhY2tldCA9IHByaXZLZXlQYWNrZXQ7DQoJCXByaXZLZXkuZ2V0UHJlZmVycmVkU2lnbmF0dXJlSGFzaEFsZ29yaXRobSA9IGZ1bmN0aW9uKCl7cmV0dXJuIG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG19Oy8vbmVlZCB0byBvdmVycmlkZSB0aGlzIHRvIHNvbHZlIGNhdGNoIDIyIHRvIGdlbmVyYXRlIHNpZ25hdHVyZS4gOCBpcyB2YWx1ZSBmb3IgU0hBMjU2DQoJCQ0KCQl2YXIgcHVibGljS2V5U3RyaW5nID0gcHJpdktleS5wcml2YXRlS2V5UGFja2V0LnB1YmxpY0tleS5kYXRhOw0KCQl2YXIgaGFzaERhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4OTkpKyBTdHJpbmcuZnJvbUNoYXJDb2RlKCgocHVibGljS2V5U3RyaW5nLmxlbmd0aCkgPj4gOCkgJiAweEZGKSANCgkJCSsgU3RyaW5nLmZyb21DaGFyQ29kZSgocHVibGljS2V5U3RyaW5nLmxlbmd0aCkgJiAweEZGKSArcHVibGljS2V5U3RyaW5nK1N0cmluZy5mcm9tQ2hhckNvZGUoMHhCNCkgKw0KCQkJU3RyaW5nLmZyb21DaGFyQ29kZSgodXNlcklkLmxlbmd0aCkgPj4gMjQpICtTdHJpbmcuZnJvbUNoYXJDb2RlKCgodXNlcklkLmxlbmd0aCkgPj4gMTYpICYgMHhGRikgDQoJCQkrIFN0cmluZy5mcm9tQ2hhckNvZGUoKCh1c2VySWQubGVuZ3RoKSA+PiA4KSAmIDB4RkYpICsgU3RyaW5nLmZyb21DaGFyQ29kZSgodXNlcklkLmxlbmd0aCkgJiAweEZGKSArIHVzZXJJZA0KCQl2YXIgc2lnbmF0dXJlID0gbmV3IG9wZW5wZ3BfcGFja2V0X3NpZ25hdHVyZSgpOw0KCQlzaWduYXR1cmUgPSBzaWduYXR1cmUud3JpdGVfbWVzc2FnZV9zaWduYXR1cmUoMTYsaGFzaERhdGEsIHByaXZLZXkpOw0KCQl2YXIgcHVibGljQXJtb3JlZCA9IG9wZW5wZ3BfZW5jb2RpbmdfYXJtb3IoNCwga2V5UGFpci5wdWJsaWNLZXkuc3RyaW5nICsgdXNlcklkU3RyaW5nICsgc2lnbmF0dXJlLm9wZW5wZ3AgKTsNCg0KCQl2YXIgcHJpdkFybW9yZWQgPSBvcGVucGdwX2VuY29kaW5nX2FybW9yKDUscHJpdktleVN0cmluZy5zdHJpbmcrdXNlcklkU3RyaW5nK3NpZ25hdHVyZS5vcGVucGdwKTsNCgkJDQoJCXJldHVybiB7cHJpdmF0ZUtleSA6IHByaXZLZXksIHByaXZhdGVLZXlBcm1vcmVkOiBwcml2QXJtb3JlZCwgcHVibGljS2V5QXJtb3JlZDogcHVibGljQXJtb3JlZH0NCgl9DQoJDQoJdGhpcy5nZW5lcmF0ZV9rZXlfcGFpciA9IGdlbmVyYXRlX2tleV9wYWlyOw0KCXRoaXMud3JpdGVfc2lnbmVkX21lc3NhZ2UgPSB3cml0ZV9zaWduZWRfbWVzc2FnZTsgDQoJdGhpcy53cml0ZV9zaWduZWRfYW5kX2VuY3J5cHRlZF9tZXNzYWdlID0gd3JpdGVfc2lnbmVkX2FuZF9lbmNyeXB0ZWRfbWVzc2FnZTsNCgl0aGlzLndyaXRlX2VuY3J5cHRlZF9tZXNzYWdlID0gd3JpdGVfZW5jcnlwdGVkX21lc3NhZ2U7DQoJdGhpcy5yZWFkX21lc3NhZ2UgPSByZWFkX21lc3NhZ2U7DQoJdGhpcy5yZWFkX21lc3NhZ2VzX2RlYXJtb3JlZCA9IHJlYWRfbWVzc2FnZXNfZGVhcm1vcmVkOw0KCXRoaXMucmVhZF9wdWJsaWNLZXkgPSByZWFkX3B1YmxpY0tleTsNCgl0aGlzLnJlYWRfcHJpdmF0ZUtleSA9IHJlYWRfcHJpdmF0ZUtleTsNCgl0aGlzLmluaXQgPSBpbml0Ow0KfQ0KDQp2YXIgb3BlbnBncCA9IG5ldyBfb3BlbnBncCgpOw0KDQoNCi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdA0KLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSA0KLy8gDQovLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yDQovLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXINCi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLg0KLy8gDQovLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwNCi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mDQovLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQ0KLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4NCi8vIA0KLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQ0KLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBDQoNCi8qKg0KICogQGNsYXNzDQogKiBAY2xhc3NkZXNjIFRoZSBjbGFzcyB0aGF0IGRlYWxzIHdpdGggc3RvcmFnZSBvZiB0aGUga2V5cmluZy4gQ3VycmVudGx5IHRoZSBvbmx5IG9wdGlvbiBpcyB0byB1c2UgSFRNTDUgbG9jYWwgc3RvcmFnZS4NCiAqLw0KZnVuY3Rpb24gb3BlbnBncF9rZXlyaW5nKCkgew0KCQkNCgkvKioNCgkgKiBJbml0aWFsaXphdGlvbiByb3V0aW5lIGZvciB0aGUga2V5cmluZy4gVGhpcyBtZXRob2QgcmVhZHMgdGhlIA0KCSAqIGtleXJpbmcgZnJvbSBIVE1MNSBsb2NhbCBzdG9yYWdlIGFuZCBpbml0aWFsaXplcyB0aGlzIGluc3RhbmNlLg0KCSAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSBvcGVucGdwLmluaXQoKS4NCgkgKi8NCglmdW5jdGlvbiBpbml0KCkgew0KCQl2YXIgc3ByaXZhdGVrZXlzID0gSlNPTi5wYXJzZSh3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oInByaXZhdGVrZXlzIikpOw0KCQl2YXIgc3B1YmxpY2tleXMgPSBKU09OLnBhcnNlKHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbSgicHVibGlja2V5cyIpKTsNCgkJaWYgKHNwcml2YXRla2V5cyA9PSBudWxsIHx8IHNwcml2YXRla2V5cy5sZW5ndGggPT0gMCkgew0KCQkJc3ByaXZhdGVrZXlzID0gbmV3IEFycmF5KCk7DQoJCX0NCg0KCQlpZiAoc3B1YmxpY2tleXMgPT0gbnVsbCB8fCBzcHVibGlja2V5cy5sZW5ndGggPT0gMCkgew0KCQkJc3B1YmxpY2tleXMgPSBuZXcgQXJyYXkoKTsNCgkJfQ0KCQl0aGlzLnB1YmxpY0tleXMgPSBuZXcgQXJyYXkoKTsNCgkJdGhpcy5wcml2YXRlS2V5cyA9IG5ldyBBcnJheSgpOw0KCQl2YXIgayA9IDA7DQoJCWZvciAodmFyIGkgPTA7IGkgPCBzcHJpdmF0ZWtleXMubGVuZ3RoOyBpKyspIHsNCgkJCXZhciByID0gb3BlbnBncC5yZWFkX3ByaXZhdGVLZXkoc3ByaXZhdGVrZXlzW2ldKTsNCgkJCXRoaXMucHJpdmF0ZUtleXNba10gPSB7IGFybW9yZWQ6IHNwcml2YXRla2V5c1tpXSwgb2JqOiByWzBdLCBrZXlJZDogclswXS5nZXRLZXlJZCgpfTsNCgkJCWsrKzsNCgkJfQ0KCQlrID0gMDsNCgkJZm9yICh2YXIgaSA9MDsgaSA8IHNwdWJsaWNrZXlzLmxlbmd0aDsgaSsrKSB7DQoJCQl2YXIgciA9IG9wZW5wZ3AucmVhZF9wdWJsaWNLZXkoc3B1YmxpY2tleXNbaV0pOw0KCQkJaWYgKHJbMF0gIT0gbnVsbCkgew0KCQkJCXRoaXMucHVibGljS2V5c1trXSA9IHsgYXJtb3JlZDogc3B1YmxpY2tleXNbaV0sIG9iajogclswXSwga2V5SWQ6IHJbMF0uZ2V0S2V5SWQoKX07DQoJCQkJaysrOw0KCQkJfQ0KCQl9DQoJfQ0KCXRoaXMuaW5pdCA9IGluaXQ7DQoNCgkvKioNCgkgKiBDaGVja3MgaWYgYXQgbGVhc3Qgb25lIHByaXZhdGUga2V5IGlzIGluIHRoZSBrZXlyaW5nDQoJICogQHJldHVybiB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGVyZSBhcmUgcHJpdmF0ZSBrZXlzLCBlbHNlIGZhbHNlLg0KCSAqLw0KCWZ1bmN0aW9uIGhhc1ByaXZhdGVLZXkoKSB7DQoJCXJldHVybiB0aGlzLnByaXZhdGVLZXlzLmxlbmd0aCA+IDA7DQoJfQ0KCXRoaXMuaGFzUHJpdmF0ZUtleSA9IGhhc1ByaXZhdGVLZXk7DQoNCgkvKioNCgkgKiBTYXZlcyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUga2V5cmluZyB0byBIVE1MNSBsb2NhbCBzdG9yYWdlLg0KCSAqIFRoZSBwcml2YXRlS2V5cyBhcnJheSBhbmQgcHVibGljS2V5cyBhcnJheSBnZXRzIFN0cmluZ2lmaWVkIHVzaW5nIEpTT04NCgkgKi8NCglmdW5jdGlvbiBzdG9yZSgpIHsgDQoJCXZhciBwcml2ID0gbmV3IEFycmF5KCk7DQoJCWZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wcml2YXRlS2V5cy5sZW5ndGg7IGkrKykgew0KCQkJcHJpdltpXSA9IHRoaXMucHJpdmF0ZUtleXNbaV0uYXJtb3JlZDsNCgkJfQ0KCQl2YXIgcHViID0gbmV3IEFycmF5KCk7DQoJCWZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wdWJsaWNLZXlzLmxlbmd0aDsgaSsrKSB7DQoJCQlwdWJbaV0gPSB0aGlzLnB1YmxpY0tleXNbaV0uYXJtb3JlZDsNCgkJfQ0KCQl3aW5kb3cubG9jYWxTdG9yYWdlLnNldEl0ZW0oInByaXZhdGVrZXlzIixKU09OLnN0cmluZ2lmeShwcml2KSk7DQoJCXdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbSgicHVibGlja2V5cyIsSlNPTi5zdHJpbmdpZnkocHViKSk7DQoJfQ0KCXRoaXMuc3RvcmUgPSBzdG9yZTsNCgkvKioNCgkgKiBzZWFyY2hlcyBhbGwgcHVibGljIGtleXMgaW4gdGhlIGtleXJpbmcgbWF0Y2hpbmcgdGhlIGFkZHJlc3Mgb3IgYWRkcmVzcyBwYXJ0IG9mIHRoZSB1c2VyIGlkcw0KCSAqIEBwYXJhbSB7U3RyaW5nfSBlbWFpbF9hZGRyZXNzDQoJICogQHJldHVybiB7b3BlbnBncF9tc2dfcHVibGlja2V5W119IFRoZSBwdWJsaWMga2V5cyBhc3NvY2lhdGVkIHdpdGggcHJvdmlkZWQgZW1haWwgYWRkcmVzcy4NCgkgKi8NCglmdW5jdGlvbiBnZXRQdWJsaWNLZXlGb3JBZGRyZXNzKGVtYWlsX2FkZHJlc3MpIHsNCgkJdmFyIHJlc3VsdHMgPSBuZXcgQXJyYXkoKTsNCgkJdmFyIHNwbCA9IGVtYWlsX2FkZHJlc3Muc3BsaXQoIjwiKTsNCgkJdmFyIGVtYWlsID0gIiI7DQoJCWlmIChzcGwubGVuZ3RoID4gMSkgew0KCQkJZW1haWwgPSBzcGxbMV0uc3BsaXQoIj4iKVswXTsNCgkJfSBlbHNlIHsNCgkJCWVtYWlsID0gZW1haWxfYWRkcmVzcy50cmltKCk7DQoJCX0NCgkJZW1haWwgPSBlbWFpbC50b0xvd2VyQ2FzZSgpOw0KCQlpZighdXRpbC5lbWFpbFJlZ0V4LnRlc3QoZW1haWwpKXsNCgkJICAgIHJldHVybiByZXN1bHRzOw0KCQl9DQoJCWZvciAodmFyIGkgPTA7IGkgPCB0aGlzLnB1YmxpY0tleXMubGVuZ3RoOyBpKyspIHsNCgkJCWZvciAodmFyIGogPSAwOyBqIDwgdGhpcy5wdWJsaWNLZXlzW2ldLm9iai51c2VySWRzLmxlbmd0aDsgaisrKSB7DQoJCQkJaWYgKHRoaXMucHVibGljS2V5c1tpXS5vYmoudXNlcklkc1tqXS50ZXh0LnRvTG93ZXJDYXNlKCkuaW5kZXhPZihlbWFpbCkgPj0gMCkNCgkJCQkJcmVzdWx0c1tyZXN1bHRzLmxlbmd0aF0gPSB0aGlzLnB1YmxpY0tleXNbaV07DQoJCQl9DQoJCX0NCgkJcmV0dXJuIHJlc3VsdHM7DQoJfQ0KCXRoaXMuZ2V0UHVibGljS2V5Rm9yQWRkcmVzcyA9IGdldFB1YmxpY0tleUZvckFkZHJlc3M7DQoNCgkvKioNCgkgKiBTZWFyY2hlcyB0aGUga2V5cmluZyBmb3IgYSBwcml2YXRlIGtleSBjb250YWluaW5nIHRoZSBzcGVjaWZpZWQgZW1haWwgYWRkcmVzcw0KCSAqIEBwYXJhbSB7U3RyaW5nfSBlbWFpbF9hZGRyZXNzIGVtYWlsIGFkZHJlc3MgdG8gc2VhcmNoIGZvcg0KCSAqIEByZXR1cm4ge29wZW5wZ3BfbXNnX3ByaXZhdGVrZXlbXX0gcHJpdmF0ZSBrZXlzIGZvdW5kDQoJICovDQoJZnVuY3Rpb24gZ2V0UHJpdmF0ZUtleUZvckFkZHJlc3MoZW1haWxfYWRkcmVzcykgew0KCQl2YXIgcmVzdWx0cyA9IG5ldyBBcnJheSgpOw0KCQl2YXIgc3BsID0gZW1haWxfYWRkcmVzcy5zcGxpdCgiPCIpOw0KCQl2YXIgZW1haWwgPSAiIjsNCgkJaWYgKHNwbC5sZW5ndGggPiAxKSB7DQoJCQllbWFpbCA9IHNwbFsxXS5zcGxpdCgiPiIpWzBdOw0KCQl9IGVsc2Ugew0KCQkJZW1haWwgPSBlbWFpbF9hZGRyZXNzLnRyaW0oKTsNCgkJfQ0KCQllbWFpbCA9IGVtYWlsLnRvTG93ZXJDYXNlKCk7DQoJCWlmKCF1dGlsLmVtYWlsUmVnRXgudGVzdChlbWFpbCkpew0KCQkgICAgcmV0dXJuIHJlc3VsdHM7DQoJCX0NCgkJZm9yICh2YXIgaSA9MDsgaSA8IHRoaXMucHJpdmF0ZUtleXMubGVuZ3RoOyBpKyspIHsNCgkJCWZvciAodmFyIGogPSAwOyBqIDwgdGhpcy5wcml2YXRlS2V5c1tpXS5vYmoudXNlcklkcy5sZW5ndGg7IGorKykgew0KCQkJCWlmICh0aGlzLnByaXZhdGVLZXlzW2ldLm9iai51c2VySWRzW2pdLnRleHQudG9Mb3dlckNhc2UoKS5pbmRleE9mKGVtYWlsKSA+PSAwKQ0KCQkJCQlyZXN1bHRzW3Jlc3VsdHMubGVuZ3RoXSA9IHRoaXMucHJpdmF0ZUtleXNbaV07DQoJCQl9DQoJCX0NCgkJcmV0dXJuIHJlc3VsdHM7DQoJfQ0KDQoJdGhpcy5nZXRQcml2YXRlS2V5Rm9yQWRkcmVzcyA9IGdldFByaXZhdGVLZXlGb3JBZGRyZXNzOw0KCS8qKg0KCSAqIFNlYXJjaGVzIHRoZSBrZXlyaW5nIGZvciBwdWJsaWMga2V5cyBoYXZpbmcgdGhlIHNwZWNpZmllZCBrZXkgaWQNCgkgKiBAcGFyYW0ge1N0cmluZ30ga2V5SWQgcHJvdmlkZWQgYXMgc3RyaW5nIG9mIGhleCBudW1iZXIgKGxvd2VyY2FzZSkNCgkgKiBAcmV0dXJuIHtvcGVucGdwX21zZ19wcml2YXRla2V5W119IHB1YmxpYyBrZXlzIGZvdW5kDQoJICovDQoJZnVuY3Rpb24gZ2V0UHVibGljS2V5c0ZvcktleUlkKGtleUlkKSB7DQoJCXZhciByZXN1bHQgPSBuZXcgQXJyYXkoKTsNCgkJZm9yICh2YXIgaT0wOyBpIDwgdGhpcy5wdWJsaWNLZXlzLmxlbmd0aDsgaSsrKSB7DQoJCQl2YXIga2V5ID0gdGhpcy5wdWJsaWNLZXlzW2ldOw0KCQkJaWYgKGtleUlkID09IGtleS5vYmouZ2V0S2V5SWQoKSkNCgkJCQlyZXN1bHRbcmVzdWx0Lmxlbmd0aF0gPSBrZXk7DQoJCQllbHNlIGlmIChrZXkub2JqLnN1YktleXMgIT0gbnVsbCkgew0KCQkJCWZvciAodmFyIGo9MDsgaiA8IGtleS5vYmouc3ViS2V5cy5sZW5ndGg7IGorKykgew0KCQkJCQl2YXIgc3Via2V5ID0ga2V5Lm9iai5zdWJLZXlzW2pdOw0KCQkJCQlpZiAoa2V5SWQgPT0gc3Via2V5LmdldEtleUlkKCkpIHsNCgkJCQkJCXJlc3VsdFtyZXN1bHQubGVuZ3RoXSA9IHsNCgkJCQkJCQkJb2JqOiBrZXkub2JqLmdldFN1YktleUFzS2V5KGopLA0KCQkJCQkJCQlrZXlJZDogc3Via2V5LmdldEtleUlkKCkNCgkJCQkJCX0NCgkJCQkJfQ0KCQkJCX0NCgkJCX0NCgkJfQ0KCQlyZXR1cm4gcmVzdWx0Ow0KCX0NCgl0aGlzLmdldFB1YmxpY0tleXNGb3JLZXlJZCA9IGdldFB1YmxpY0tleXNGb3JLZXlJZDsNCgkNCgkvKioNCgkgKiBTZWFyY2hlcyB0aGUga2V5cmluZyBmb3IgcHJpdmF0ZSBrZXlzIGhhdmluZyB0aGUgc3BlY2lmaWVkIGtleSBpZA0KCSAqIEBwYXJhbSB7U3RyaW5nfSBrZXlJZCA4IGJ5dGVzIGFzIHN0cmluZyBjb250YWluaW5nIHRoZSBrZXkgaWQgdG8gbG9vayBmb3INCgkgKiBAcmV0dXJuIHtvcGVucGdwX21zZ19wcml2YXRla2V5W119IHByaXZhdGUga2V5cyBmb3VuZA0KCSAqLw0KCWZ1bmN0aW9uIGdldFByaXZhdGVLZXlGb3JLZXlJZChrZXlJZCkgew0KCQl2YXIgcmVzdWx0ID0gbmV3IEFycmF5KCk7DQoJCWZvciAodmFyIGk9MDsgaSA8IHRoaXMucHJpdmF0ZUtleXMubGVuZ3RoOyBpKyspIHsNCgkJCWlmIChrZXlJZCA9PSB0aGlzLnByaXZhdGVLZXlzW2ldLm9iai5nZXRLZXlJZCgpKSB7DQoJCQkJcmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0geyBrZXk6IHRoaXMucHJpdmF0ZUtleXNbaV0sIGtleW1hdGVyaWFsOiB0aGlzLnByaXZhdGVLZXlzW2ldLm9iai5wcml2YXRlS2V5UGFja2V0fTsNCgkJCX0NCgkJCWlmICh0aGlzLnByaXZhdGVLZXlzW2ldLm9iai5zdWJLZXlzICE9IG51bGwpIHsNCgkJCQl2YXIgc3Via2V5aWRzID0gdGhpcy5wcml2YXRlS2V5c1tpXS5vYmouZ2V0U3ViS2V5SWRzKCk7DQoJCQkJZm9yICh2YXIgaj0wOyBqIDwgc3Via2V5aWRzLmxlbmd0aDsgaisrKQ0KCQkJCQlpZiAoa2V5SWQgPT0gdXRpbC5oZXhzdHJkdW1wKHN1YmtleWlkc1tqXSkpIHsNCgkJCQkJCXJlc3VsdFtyZXN1bHQubGVuZ3RoXSA9IHsga2V5OiB0aGlzLnByaXZhdGVLZXlzW2ldLCBrZXltYXRlcmlhbDogdGhpcy5wcml2YXRlS2V5c1tpXS5vYmouc3ViS2V5c1tqXX07DQoJCQkJCX0NCgkJCX0NCgkJfQ0KCQlyZXR1cm4gcmVzdWx0Ow0KCX0NCgl0aGlzLmdldFByaXZhdGVLZXlGb3JLZXlJZCA9IGdldFByaXZhdGVLZXlGb3JLZXlJZDsNCgkNCgkvKioNCgkgKiBJbXBvcnRzIGEgcHVibGljIGtleSBmcm9tIGFuIGV4cG9ydGVkIGFzY2lpIGFybW9yZWQgbWVzc2FnZSANCgkgKiBAcGFyYW0ge1N0cmluZ30gYXJtb3JlZF90ZXh0IFBVQkxJQyBLRVkgQkxPQ0sgbWVzc2FnZSB0byByZWFkIHRoZSBwdWJsaWMga2V5IGZyb20NCgkgKi8NCglmdW5jdGlvbiBpbXBvcnRQdWJsaWNLZXkgKGFybW9yZWRfdGV4dCkgew0KCQl2YXIgcmVzdWx0ID0gb3BlbnBncC5yZWFkX3B1YmxpY0tleShhcm1vcmVkX3RleHQpOw0KCQlmb3IgKHZhciBpID0gMDsgaSA8IHJlc3VsdC5sZW5ndGg7IGkrKykgew0KCQkJdGhpcy5wdWJsaWNLZXlzW3RoaXMucHVibGljS2V5cy5sZW5ndGhdID0ge2FybW9yZWQ6IGFybW9yZWRfdGV4dCwgb2JqOiByZXN1bHRbaV0sIGtleUlkOiByZXN1bHRbaV0uZ2V0S2V5SWQoKX07DQoJCX0NCgkJcmV0dXJuIHRydWU7DQoJfQ0KDQoJLyoqDQoJICogSW1wb3J0cyBhIHByaXZhdGUga2V5IGZyb20gYW4gZXhwb3J0ZWQgYXNjaWkgYXJtb3JlZCBtZXNzYWdlIA0KCSAqIEBwYXJhbSB7U3RyaW5nfSBhcm1vcmVkX3RleHQgUFJJVkFURSBLRVkgQkxPQ0sgbWVzc2FnZSB0byByZWFkIHRoZSBwcml2YXRlIGtleSBmcm9tDQoJICovDQoJZnVuY3Rpb24gaW1wb3J0UHJpdmF0ZUtleSAoYXJtb3JlZF90ZXh0LCBwYXNzd29yZCkgew0KCQl2YXIgcmVzdWx0ID0gb3BlbnBncC5yZWFkX3ByaXZhdGVLZXkoYXJtb3JlZF90ZXh0KTsNCgkJaWYoIXJlc3VsdFswXS5kZWNyeXB0U2VjcmV0TVBJcyhwYXNzd29yZCkpDQoJCSAgICByZXR1cm4gZmFsc2U7DQoJCWZvciAodmFyIGkgPSAwOyBpIDwgcmVzdWx0Lmxlbmd0aDsgaSsrKSB7DQoJCQl0aGlzLnByaXZhdGVLZXlzW3RoaXMucHJpdmF0ZUtleXMubGVuZ3RoXSA9IHthcm1vcmVkOiBhcm1vcmVkX3RleHQsIG9iajogcmVzdWx0W2ldLCBrZXlJZDogcmVzdWx0W2ldLmdldEtleUlkKCl9Ow0KCQl9DQoJCXJldHVybiB0cnVlOw0KCX0NCg0KCXRoaXMuaW1wb3J0UHVibGljS2V5ID0gaW1wb3J0UHVibGljS2V5Ow0KCXRoaXMuaW1wb3J0UHJpdmF0ZUtleSA9IGltcG9ydFByaXZhdGVLZXk7DQoJDQoJLyoqDQoJICogcmV0dXJucyB0aGUgb3BlbnBncF9tc2dfcHJpdmF0ZWtleSByZXByZXNlbnRhdGlvbiBvZiB0aGUgcHVibGljIGtleSBhdCBwdWJsaWMga2V5IHJpbmcgaW5kZXggIA0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBwdWJsaWMga2V5IHdpdGhpbiB0aGUgcHVibGljS2V5cyBhcnJheQ0KCSAqIEByZXR1cm4ge29wZW5wZ3BfbXNnX3ByaXZhdGVrZXl9IHRoZSBwdWJsaWMga2V5IG9iamVjdA0KCSAqLw0KCWZ1bmN0aW9uIGV4cG9ydFB1YmxpY0tleShpbmRleCkgew0KCQlyZXR1cm4gdGhpcy5wdWJsaWNLZXlbaW5kZXhdOw0KCX0NCgl0aGlzLmV4cG9ydFB1YmxpY0tleSA9IGV4cG9ydFB1YmxpY0tleTsNCgkJDQoJDQoJLyoqDQoJICogUmVtb3ZlcyBhIHB1YmxpYyBrZXkgZnJvbSB0aGUgcHVibGljIGtleSBrZXlyaW5nIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBpbmRleCB0aGUgaW5kZXggb2YgdGhlIHB1YmxpYyBrZXkgd2l0aGluIHRoZSBwdWJsaWNLZXlzIGFycmF5DQoJICogQHJldHVybiB7b3BlbnBncF9tc2dfcHJpdmF0ZWtleX0gVGhlIHB1YmxpYyBrZXkgb2JqZWN0IHdoaWNoIGhhcyBiZWVuIHJlbW92ZWQNCgkgKi8NCglmdW5jdGlvbiByZW1vdmVQdWJsaWNLZXkoaW5kZXgpIHsNCgkJdmFyIHJlbW92ZWQgPSB0aGlzLnB1YmxpY0tleXMuc3BsaWNlKGluZGV4LDEpOw0KCQl0aGlzLnN0b3JlKCk7DQoJCXJldHVybiByZW1vdmVkOw0KCX0NCgl0aGlzLnJlbW92ZVB1YmxpY0tleSA9IHJlbW92ZVB1YmxpY0tleTsNCg0KCS8qKg0KCSAqIHJldHVybnMgdGhlIG9wZW5wZ3BfbXNnX3ByaXZhdGVrZXkgcmVwcmVzZW50YXRpb24gb2YgdGhlIHByaXZhdGUga2V5IGF0IHByaXZhdGUga2V5IHJpbmcgaW5kZXggIA0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBwcml2YXRlIGtleSB3aXRoaW4gdGhlIHByaXZhdGVLZXlzIGFycmF5DQoJICogQHJldHVybiB7b3BlbnBncF9tc2dfcHJpdmF0ZWtleX0gdGhlIHByaXZhdGUga2V5IG9iamVjdA0KCSAqLwkNCglmdW5jdGlvbiBleHBvcnRQcml2YXRlS2V5KGluZGV4KSB7DQoJCXJldHVybiB0aGlzLnByaXZhdGVLZXlzW2luZGV4XTsNCgl9DQoJdGhpcy5leHBvcnRQcml2YXRlS2V5ID0gZXhwb3J0UHJpdmF0ZUtleTsNCg0KCS8qKg0KCSAqIFJlbW92ZXMgYSBwcml2YXRlIGtleSBmcm9tIHRoZSBwcml2YXRlIGtleSBrZXlyaW5nIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBpbmRleCB0aGUgaW5kZXggb2YgdGhlIHByaXZhdGUga2V5IHdpdGhpbiB0aGUgcHJpdmF0ZUtleXMgYXJyYXkNCgkgKiBAcmV0dXJuIHtvcGVucGdwX21zZ19wcml2YXRla2V5fSBUaGUgcHJpdmF0ZSBrZXkgb2JqZWN0IHdoaWNoIGhhcyBiZWVuIHJlbW92ZWQNCgkgKi8NCglmdW5jdGlvbiByZW1vdmVQcml2YXRlS2V5KGluZGV4KSB7DQoJCXZhciByZW1vdmVkID0gdGhpcy5wcml2YXRlS2V5cy5zcGxpY2UoaW5kZXgsMSk7DQoJCXRoaXMuc3RvcmUoKTsNCgkJcmV0dXJuIHJlbW92ZWQ7DQoJfQ0KCXRoaXMucmVtb3ZlUHJpdmF0ZUtleSA9IHJlbW92ZVByaXZhdGVLZXk7DQoNCn0NCi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdA0KLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSA0KLy8gDQovLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yDQovLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXINCi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLg0KLy8gDQovLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwNCi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mDQovLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQ0KLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4NCi8vIA0KLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQ0KLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBDQoNCi8qKg0KICogQHByb3RlY3RlZA0KICogQGNsYXNzDQogKiBAY2xhc3NkZXNjIFRvcC1sZXZlbCBtZXNzYWdlIG9iamVjdC4gQ29udGFpbnMgaW5mb3JtYXRpb24gZnJvbSBvbmUgb3IgbW9yZSBwYWNrZXRzDQogKi8NCg0KZnVuY3Rpb24gb3BlbnBncF9tc2dfbWVzc2FnZSgpIHsNCgkNCgkvLyAtMSA9IG5vIHZhbGlkIHBhc3NwaHJhc2Ugc3VibWl0dGVkDQoJLy8gLTIgPSBubyBwcml2YXRlIGtleSBmb3VuZA0KCS8vIC0zID0gZGVjcnlwdGlvbiBlcnJvcg0KCS8vIHRleHQgPSB2YWxpZCBkZWNyeXB0aW9uDQoJdGhpcy50ZXh0ID0gIiI7DQoJdGhpcy5tZXNzYWdlUGFja2V0ID0gbnVsbDsNCgl0aGlzLnR5cGUgPSBudWxsOw0KCQ0KCS8qKg0KCSAqIERlY3J5cHRzIGEgbWVzc2FnZSBhbmQgZ2VuZXJhdGVzIHVzZXIgaW50ZXJmYWNlIG1lc3NhZ2Ugb3V0IG9mIHRoZSBmb3VuZC4NCgkgKiBNREMgd2lsbCBiZSB2ZXJpZmllZCBhcyB3ZWxsIGFzIG1lc3NhZ2Ugc2lnbmF0dXJlcw0KCSAqIEBwYXJhbSB7b3BlbnBncF9tc2dfcHJpdmF0ZWtleX0gcHJpdmF0ZV9rZXkgdGhlIHByaXZhdGUgdGhlIG1lc3NhZ2UgaXMgZW5jcnlwdGVkIHdpdGggKGNvcnJlc3BvbmRpbmcgdG8gdGhlIHNlc3Npb24ga2V5KQ0KCSAqIEBwYXJhbSB7b3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkc2Vzc2lvbmtleX0gc2Vzc2lvbmtleSB0aGUgc2Vzc2lvbiBrZXkgdG8gYmUgdXNlZCB0byBkZWNyeXB0IHRoZSBtZXNzYWdlDQoJICogQHJldHVybiB7U3RyaW5nfSBwbGFpbnRleHQgb2YgdGhlIG1lc3NhZ2Ugb3IgbnVsbCBvbiBlcnJvcg0KCSAqLw0KCWZ1bmN0aW9uIGRlY3J5cHQocHJpdmF0ZV9rZXksIHNlc3Npb25rZXkpIHsNCiAgICAgICAgcmV0dXJuIHRoaXMuZGVjcnlwdEFuZFZlcmlmeVNpZ25hdHVyZShwcml2YXRlX2tleSwgc2Vzc2lvbmtleSkudGV4dDsNCgl9DQoNCgkvKioNCgkgKiBEZWNyeXB0cyBhIG1lc3NhZ2UgYW5kIGdlbmVyYXRlcyB1c2VyIGludGVyZmFjZSBtZXNzYWdlIG91dCBvZiB0aGUgZm91bmQuDQoJICogTURDIHdpbGwgYmUgdmVyaWZpZWQgYXMgd2VsbCBhcyBtZXNzYWdlIHNpZ25hdHVyZXMNCgkgKiBAcGFyYW0ge29wZW5wZ3BfbXNnX3ByaXZhdGVrZXl9IHByaXZhdGVfa2V5IHRoZSBwcml2YXRlIHRoZSBtZXNzYWdlIGlzIGVuY3J5cHRlZCB3aXRoIChjb3JyZXNwb25kaW5nIHRvIHRoZSBzZXNzaW9uIGtleSkNCgkgKiBAcGFyYW0ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZHNlc3Npb25rZXl9IHNlc3Npb25rZXkgdGhlIHNlc3Npb24ga2V5IHRvIGJlIHVzZWQgdG8gZGVjcnlwdCB0aGUgbWVzc2FnZQ0KCSAqIEBwYXJhbSB7b3BlbnBncF9tc2dfcHVibGlja2V5fSBwdWJrZXkgQXJyYXkgb2YgcHVibGljIGtleXMgdG8gY2hlY2sgc2lnbmF0dXJlIGFnYWluc3QuIElmIG5vdCBwcm92aWRlZCwgY2hlY2tzIGxvY2FsIGtleXN0b3JlLg0KCSAqIEByZXR1cm4ge1N0cmluZ30gcGxhaW50ZXh0IG9mIHRoZSBtZXNzYWdlIG9yIG51bGwgb24gZXJyb3INCgkgKi8NCglmdW5jdGlvbiBkZWNyeXB0QW5kVmVyaWZ5U2lnbmF0dXJlKHByaXZhdGVfa2V5LCBzZXNzaW9ua2V5LCBwdWJrZXkpIHsNCgkJaWYgKHByaXZhdGVfa2V5ID09IG51bGwgfHwgc2Vzc2lvbmtleSA9PSBudWxsIHx8IHNlc3Npb25rZXkgPT0gIiIpDQoJCQlyZXR1cm4gbnVsbDsNCgkJdmFyIGRlY3J5cHRlZCA9IHNlc3Npb25rZXkuZGVjcnlwdCh0aGlzLCBwcml2YXRlX2tleS5rZXltYXRlcmlhbCk7DQoJCWlmIChkZWNyeXB0ZWQgPT0gbnVsbCkNCgkJCXJldHVybiBudWxsOw0KCQl2YXIgcGFja2V0Ow0KCQl2YXIgcG9zaXRpb24gPSAwOw0KCQl2YXIgbGVuID0gZGVjcnlwdGVkLmxlbmd0aDsNCgkJdmFyIHZhbGlkU2lnbmF0dXJlcyA9IG5ldyBBcnJheSgpOw0KCQl1dGlsLnByaW50X2RlYnVnX2hleHN0cl9kdW1wKCJvcGVucGdwLm1zZy5tZXNzZ2UgZGVjcnlwdDpcbiIsZGVjcnlwdGVkKTsNCgkJDQoJCXZhciBtZXNzYWdlcyA9IG9wZW5wZ3AucmVhZF9tZXNzYWdlc19kZWFybW9yZWQoe3RleHQ6IGRlY3J5cHRlZCwgb3BlbnBncDogZGVjcnlwdGVkfSk7DQoJCWZvcih2YXIgbSBpbiBtZXNzYWdlcyl7DQoJCQlpZihtZXNzYWdlc1ttXS5kYXRhKXsNCgkJCQl0aGlzLnRleHQgPSBtZXNzYWdlc1ttXS5kYXRhOw0KCQkJfQ0KCQkJaWYobWVzc2FnZXNbbV0uc2lnbmF0dXJlKXsNCgkJCSAgICB2YWxpZFNpZ25hdHVyZXMucHVzaChtZXNzYWdlc1ttXS52ZXJpZnlTaWduYXR1cmUocHVia2V5KSk7DQoJCQl9DQoJCX0NCgkJcmV0dXJuIHt0ZXh0OnRoaXMudGV4dCwgdmFsaWRTaWduYXR1cmVzOnZhbGlkU2lnbmF0dXJlc307DQoJfQ0KCQ0KCS8qKg0KCSAqIFZlcmlmaWVzIGEgbWVzc2FnZSBzaWduYXR1cmUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCBhZnRlciByZWFkX21lc3NhZ2UgaWYgdGhlIG1lc3NhZ2Ugd2FzIHNpZ25lZCBvbmx5Lg0KCSAqIEBwYXJhbSB7b3BlbnBncF9tc2dfcHVibGlja2V5fSBwdWJrZXkgQXJyYXkgb2YgcHVibGljIGtleXMgdG8gY2hlY2sgc2lnbmF0dXJlIGFnYWluc3QuIElmIG5vdCBwcm92aWRlZCwgY2hlY2tzIGxvY2FsIGtleXN0b3JlLg0KCSAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgdGhlIHNpZ25hdHVyZSB3YXMgY29ycmVjdDsgb3RoZXJ3aXNlIGZhbHNlDQoJICovDQoJZnVuY3Rpb24gdmVyaWZ5U2lnbmF0dXJlKHB1YmtleSkgew0KCQl2YXIgcmVzdWx0ID0gZmFsc2U7DQoJCWlmICh0aGlzLnNpZ25hdHVyZS50YWdUeXBlID09IDIpIHsNCgkJICAgIGlmKCFwdWJrZXkgfHwgcHVia2V5Lmxlbmd0aCA9PSAwKXsNCgkJCSAgICB2YXIgcHVia2V5Ow0KCQkJICAgIGlmICh0aGlzLnNpZ25hdHVyZS52ZXJzaW9uID09IDQpIHsNCgkJCQkgICAgcHVia2V5ID0gb3BlbnBncC5rZXlyaW5nLmdldFB1YmxpY0tleXNGb3JLZXlJZCh0aGlzLnNpZ25hdHVyZS5pc3N1ZXJLZXlJZCk7DQoJCQkgICAgfSBlbHNlIGlmICh0aGlzLnNpZ25hdHVyZS52ZXJzaW9uID09IDMpIHsNCgkJCQkgICAgcHVia2V5ID0gb3BlbnBncC5rZXlyaW5nLmdldFB1YmxpY0tleXNGb3JLZXlJZCh0aGlzLnNpZ25hdHVyZS5rZXlJZCk7DQoJCQkgICAgfSBlbHNlIHsNCgkJCQkgICAgdXRpbC5wcmludF9lcnJvcigidW5rbm93biBzaWduYXR1cmUgdHlwZSBvbiBtZXNzYWdlISIpOw0KCQkJCSAgICByZXR1cm4gZmFsc2U7DQoJCQkgICAgfQ0KCQkJfQ0KCQkJaWYgKHB1YmtleS5sZW5ndGggPT0gMCkNCgkJCQl1dGlsLnByaW50X3dhcm5pbmcoIlVuYWJsZSB0byB2ZXJpZnkgc2lnbmF0dXJlIG9mIGlzc3VlcjogIit1dGlsLmhleHN0cmR1bXAodGhpcy5zaWduYXR1cmUuaXNzdWVyS2V5SWQpKyIuIFB1YmxpYyBrZXkgbm90IGZvdW5kIGluIGtleXJpbmcuIik7DQoJCQllbHNlIHsNCgkJCQlmb3IgKHZhciBpID0gMCA7IGkgPCBwdWJrZXkubGVuZ3RoOyBpKyspIHsNCgkJCQkJdmFyIHRvaGFzaCA9IHRoaXMudGV4dC5yZXBsYWNlKC9cclxuL2csIlxuIikucmVwbGFjZSgvXG4vZywiXHJcbiIpOw0KCQkJCQlpZiAodGhpcy5zaWduYXR1cmUudmVyaWZ5KHRvaGFzaCwgcHVia2V5W2ldKSkgew0KCQkJCQkJdXRpbC5wcmludF9pbmZvKCJGb3VuZCBHb29kIFNpZ25hdHVyZSBmcm9tICIrcHVia2V5W2ldLm9iai51c2VySWRzWzBdLnRleHQrIiAoMHgiK3V0aWwuaGV4c3RyZHVtcChwdWJrZXlbaV0ub2JqLmdldEtleUlkKCkpLnN1YnN0cmluZyg4KSsiKSIpOw0KCQkJCQkJcmVzdWx0ID0gdHJ1ZTsNCgkJCQkJfSBlbHNlIHsNCgkJCQkJCXV0aWwucHJpbnRfZXJyb3IoIlNpZ25hdHVyZSB2ZXJpZmljYXRpb24gZmFpbGVkOiBCYWQgU2lnbmF0dXJlIGZyb20gIitwdWJrZXlbaV0ub2JqLnVzZXJJZHNbMF0udGV4dCsiICgweCIrdXRpbC5oZXhzdHJkdW1wKHB1YmtleVswXS5vYmouZ2V0S2V5SWQoKSkuc3Vic3RyaW5nKDgpKyIpIik7DQoJCQkJCX0NCgkJCQl9DQoJCQl9DQoJCX0NCgkJcmV0dXJuIHJlc3VsdDsNCgl9DQoJDQoJZnVuY3Rpb24gdG9TdHJpbmcoKSB7DQoJCXZhciByZXN1bHQgPSAiU2Vzc2lvbiBLZXlzOlxuIjsNCgkJaWYgKHRoaXMuc2Vzc2lvbktleXMgIT1udWxsKQ0KCQlmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuc2Vzc2lvbktleXMubGVuZ3RoOyBpKyspIHsNCgkJCXJlc3VsdCArPSB0aGlzLnNlc3Npb25LZXlzW2ldLnRvU3RyaW5nKCk7DQoJCX0NCgkJcmVzdWx0ICs9ICJcblxuIEVuY3J5cHRlZERhdGE6XG4iOw0KCQlpZih0aGlzLmVuY3J5cHRlZERhdGEgIT0gbnVsbCkNCgkJcmVzdWx0ICs9IHRoaXMuZW5jcnlwdGVkRGF0YS50b1N0cmluZygpOw0KCQkNCgkJcmVzdWx0ICs9ICJcblxuIFNpZ25hdHVyZTpcbiI7DQoJCWlmKHRoaXMuc2lnbmF0dXJlICE9IG51bGwpDQoJCXJlc3VsdCArPSB0aGlzLnNpZ25hdHVyZS50b1N0cmluZygpOw0KCQkNCgkJcmVzdWx0ICs9ICJcblxuIFRleHQ6XG4iDQoJCWlmKHRoaXMuc2lnbmF0dXJlICE9IG51bGwpDQoJCQlyZXN1bHQgKz0gdGhpcy50ZXh0Ow0KCQlyZXR1cm4gcmVzdWx0Ow0KCX0NCgl0aGlzLmRlY3J5cHQgPSBkZWNyeXB0Ow0KCXRoaXMuZGVjcnlwdEFuZFZlcmlmeVNpZ25hdHVyZSA9IGRlY3J5cHRBbmRWZXJpZnlTaWduYXR1cmU7DQoJdGhpcy52ZXJpZnlTaWduYXR1cmUgPSB2ZXJpZnlTaWduYXR1cmU7DQoJdGhpcy50b1N0cmluZyA9IHRvU3RyaW5nOw0KfQ0KLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0DQovLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3INCi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcg0KLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLA0KLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YNCi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VDQovLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLg0KLy8gDQovLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlDQovLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0ENCg0KLyoqDQogKiBAY2xhc3MNCiAqIEBjbGFzc2Rlc2MgQ2xhc3MgdGhhdCByZXByZXNlbnRzIGEgZGVjb2RlZCBwcml2YXRlIGtleSBmb3IgaW50ZXJuYWwgb3BlbnBncC5qcyB1c2UNCiAqLw0KDQpmdW5jdGlvbiBvcGVucGdwX21zZ19wcml2YXRla2V5KCkgew0KCXRoaXMuc3ViS2V5cyA9IG5ldyBBcnJheSgpOw0KCXRoaXMucHJpdmF0ZUtleVBhY2tldCA9IG51bGw7DQoJdGhpcy51c2VySWRzID0gbmV3IEFycmF5KCk7DQoJdGhpcy51c2VyQXR0cmlidXRlcyA9IG5ldyBBcnJheSgpOw0KCXRoaXMucmV2b2NhdGlvblNpZ25hdHVyZXMgPSBuZXcgQXJyYXkoKTsNCgl0aGlzLnN1YktleXMgPSBuZXcgQXJyYXkoKTsNCg0KCS8qKg0KCSAqIA0KCSAqIEByZXR1cm4gbGFzdCBwb3NpdGlvbg0KCSAqLw0KCWZ1bmN0aW9uIHJlYWRfbm9kZXMocGFyZW50X25vZGUsIGlucHV0LCBwb3NpdGlvbiwgbGVuKSB7DQoJCXRoaXMucHJpdmF0ZUtleVBhY2tldCA9IHBhcmVudF9ub2RlOw0KCQkNCgkJdmFyIHBvcyA9IHBvc2l0aW9uOw0KCQl3aGlsZSAoaW5wdXQubGVuZ3RoID4gcG9zKSB7DQoJCQl2YXIgcmVzdWx0ID0gb3BlbnBncF9wYWNrZXQucmVhZF9wYWNrZXQoaW5wdXQsIHBvcywgaW5wdXQubGVuZ3RoIC0gcG9zKTsNCgkJCWlmIChyZXN1bHQgPT0gbnVsbCkgew0KCQkJCXV0aWwucHJpbnRfZXJyb3IoIm9wZW5wZ3AubXNnLm1lc3NnZSBkZWNyeXB0OlxuIisnW3B1Yi9wcml2X2tleV1wYXJzaW5nIGVuZHMgaGVyZSBAOicgKyBwb3MgKyAiIGw6IiArIGxlbik7DQoJCQkJYnJlYWs7DQoJCQl9IGVsc2Ugew0KCQkJCXN3aXRjaCAocmVzdWx0LnRhZ1R5cGUpIHsNCgkJCQljYXNlIDI6IC8vIHB1YmxpYyBrZXkgcmV2b2NhdGlvbiBzaWduYXR1cmUNCgkJCQkJaWYgKHJlc3VsdC5zaWduYXR1cmVUeXBlID09IDMyKQ0KCQkJCQkJdGhpcy5yZXZvY2F0aW9uU2lnbmF0dXJlc1t0aGlzLnJldm9jYXRpb25TaWduYXR1cmVzLmxlbmd0aF0gPSByZXN1bHQ7DQoJCQkJCWVsc2UgaWYgKHJlc3VsdC5zaWduYXR1cmVUeXBlID4gMTUgJiYgcmVzdWx0LnNpZ25hdHVyZVR5cGUgPCAyMCkgew0KCQkJCQkJaWYgKHRoaXMuY2VydGlmaWNhdGlvbnNpZ25hdHVyZXMgPT0gbnVsbCkNCgkJCQkJCQl0aGlzLmNlcnRpZmljYXRpb25TaWduYXR1cmVzID0gbmV3IEFycmF5KCk7DQoJCQkJCQl0aGlzLmNlcnRpZmljYXRpb25TaWduYXR1cmVzW3RoaXMuY2VydGlmaWNhdGlvblNpZ25hdHVyZXMubGVuZ3RoXSA9IHJlc3VsdDsNCgkJCQkJfSBlbHNlDQoJCQkJCQl1dGlsLnByaW50X2Vycm9yKCJvcGVucGdwLm1zZy5tZXNzZ2UgZGVjcnlwdDpcbiIrInVua25vd24gc2lnbmF0dXJlIHR5cGUgZGlyZWN0bHkgb24ga2V5ICIrcmVzdWx0LnNpZ25hdHVyZVR5cGUrIiBAIitwb3MpOw0KCQkJCQlwb3MgKz0gcmVzdWx0LnBhY2tldExlbmd0aCArIHJlc3VsdC5oZWFkZXJMZW5ndGg7DQoJCQkJCWJyZWFrOw0KCQkJCWNhc2UgNzogLy8gUHJpdmF0ZVN1YmtleSBQYWNrZXQNCgkJCQkJdGhpcy5zdWJLZXlzW3RoaXMuc3ViS2V5cy5sZW5ndGhdID0gcmVzdWx0Ow0KCQkJCQlwb3MgKz0gcmVzdWx0LnBhY2tldExlbmd0aCArIHJlc3VsdC5oZWFkZXJMZW5ndGg7DQoJCQkJCXBvcyArPSByZXN1bHQucmVhZF9ub2Rlcyh0aGlzLnByaXZhdGVLZXlQYWNrZXQsaW5wdXQsIHBvcywgaW5wdXQubGVuZ3RoIC0gcG9zKTsNCgkJCQkJYnJlYWs7DQoJCQkJY2FzZSAxNzogLy8gVXNlciBBdHRyaWJ1dGUgUGFja2V0DQoJCQkJCXRoaXMudXNlckF0dHJpYnV0ZXNbdGhpcy51c2VyQXR0cmlidXRlcy5sZW5ndGhdID0gcmVzdWx0Ow0KCQkJCQlwb3MgKz0gcmVzdWx0LnBhY2tldExlbmd0aCArIHJlc3VsdC5oZWFkZXJMZW5ndGg7DQoJCQkJCXBvcyArPSByZXN1bHQucmVhZF9ub2Rlcyh0aGlzLnByaXZhdGVLZXlQYWNrZXQsaW5wdXQsIHBvcywgaW5wdXQubGVuZ3RoIC0gcG9zKTsNCgkJCQkJYnJlYWs7DQoJCQkJY2FzZSAxMzogLy8gVXNlciBJRCBQYWNrZXQNCgkJCQkJdGhpcy51c2VySWRzW3RoaXMudXNlcklkcy5sZW5ndGhdID0gcmVzdWx0Ow0KCQkJCQlwb3MgKz0gcmVzdWx0LnBhY2tldExlbmd0aCArIHJlc3VsdC5oZWFkZXJMZW5ndGg7DQoJCQkJCXBvcyArPSByZXN1bHQucmVhZF9ub2Rlcyh0aGlzLnByaXZhdGVLZXlQYWNrZXQsIGlucHV0LCBwb3MsIGlucHV0Lmxlbmd0aCAtIHBvcyk7DQoJCQkJCWJyZWFrOw0KCQkJCWRlZmF1bHQ6DQoJCQkJCXRoaXMucG9zaXRpb24gPSBwb3NpdGlvbiAtIHRoaXMucHJpdmF0ZUtleVBhY2tldC5wYWNrZXRMZW5ndGggLSB0aGlzLnByaXZhdGVLZXlQYWNrZXQuaGVhZGVyTGVuZ3RoOw0KCQkJCQl0aGlzLmxlbiA9IHBvcyAtIHBvc2l0aW9uOw0KCQkJCQlyZXR1cm4gdGhpcy5sZW47DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJCXRoaXMucG9zaXRpb24gPSBwb3NpdGlvbiAtIHRoaXMucHJpdmF0ZUtleVBhY2tldC5wYWNrZXRMZW5ndGggLSB0aGlzLnByaXZhdGVLZXlQYWNrZXQuaGVhZGVyTGVuZ3RoOw0KCQl0aGlzLmxlbiA9IHBvcyAtIHBvc2l0aW9uOw0KCQkNCgkJcmV0dXJuIHRoaXMubGVuOw0KCX0NCgkNCglmdW5jdGlvbiBnZXRLZXlJZCgpIHsNCgkJcmV0dXJuIHRoaXMucHJpdmF0ZUtleVBhY2tldC5wdWJsaWNLZXkuZ2V0S2V5SWQoKTsNCgl9DQoJDQoJDQoJZnVuY3Rpb24gZ2V0U3ViS2V5SWRzKCkgew0KCQlpZiAodGhpcy5wcml2YXRlS2V5UGFja2V0LnB1YmxpY0tleS52ZXJzaW9uID09IDQpIC8vIFYzIGtleXMgTVVTVCBOT1QgaGF2ZSBzdWJrZXlzLg0KCQl2YXIgcmVzdWx0ID0gbmV3IEFycmF5KCk7DQoJCWZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zdWJLZXlzLmxlbmd0aDsgaSsrKSB7DQoJCQlyZXN1bHRbaV0gPSBzdHJfc2hhMSh0aGlzLnN1YktleXNbaV0ucHVibGljS2V5LmhlYWRlcit0aGlzLnN1YktleXNbaV0ucHVibGljS2V5LmRhdGEpLnN1YnN0cmluZygxMiwyMCk7DQoJCX0NCgkJcmV0dXJuIHJlc3VsdDsNCgl9DQoJDQoJDQoJZnVuY3Rpb24gZ2V0U2lnbmluZ0tleSgpIHsNCgkJaWYgKCh0aGlzLnByaXZhdGVLZXlQYWNrZXQucHVibGljS2V5LnB1YmxpY0tleUFsZ29yaXRobSA9PSAxNyB8fA0KCQkJIHRoaXMucHJpdmF0ZUtleVBhY2tldC5wdWJsaWNLZXkucHVibGljS2V5QWxnb3JpdGhtICE9IDIpDQoJCQkmJiB0aGlzLnByaXZhdGVLZXlQYWNrZXQucHVibGljS2V5LnZlcmlmeUtleSgpID09IDMpDQoJCQlyZXR1cm4gdGhpcy5wcml2YXRlS2V5UGFja2V0Ow0KCQllbHNlIGlmICh0aGlzLnByaXZhdGVLZXlQYWNrZXQucHVibGljS2V5LnZlcnNpb24gPT0gNCkgLy8gVjMga2V5cyBNVVNUIE5PVCBoYXZlIHN1YmtleXMuDQoJCQlmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMucHJpdmF0ZUtleVBhY2tldC5zdWJLZXlzLmxlbmd0aDsgaisrKSB7DQoJCQkJaWYgKCh0aGlzLnByaXZhdGVLZXlQYWNrZXQuc3ViS2V5c1tqXS5wdWJsaWNLZXkucHVibGljS2V5QWxnb3JpdGhtID09IDE3IHx8DQoJCQkJCSB0aGlzLnByaXZhdGVLZXlQYWNrZXQuc3ViS2V5c1tqXS5wdWJsaWNLZXkucHVibGljS2V5QWxnb3JpdGhtICE9IDIpICYmDQoJCQkJCSB0aGlzLnByaXZhdGVLZXlQYWNrZXQuc3ViS2V5c1tqXS5wdWJsaWNLZXkudmVyaWZ5S2V5KCkgPT0gMykNCgkJCQkJcmV0dXJuIHRoaXMucHJpdmF0ZUtleVBhY2tldC5zdWJLZXlzW2pdOw0KCQkJfQ0KCQlyZXR1cm4gbnVsbDsNCgl9DQoJDQoJZnVuY3Rpb24gZ2V0UHJlZmVycmVkU2lnbmF0dXJlSGFzaEFsZ29yaXRobSgpIHsNCgkJdmFyIHBrZXkgPSB0aGlzLmdldFNpZ25pbmdLZXkoKTsNCgkJaWYgKHBrZXkgPT0gbnVsbCkgew0KCQkJdXRpbC5wcmludF9lcnJvcigicHJpdmF0ZSBrZXkgaXMgZm9yIGVuY3J5cHRpb24gb25seSEgQ2Fubm90IGNyZWF0ZSBhIHNpZ25hdHVyZS4iKQ0KCQkJcmV0dXJuIG51bGw7DQoJCX0NCgkJaWYgKHBrZXkucHVibGljS2V5LnB1YmxpY0tleUFsZ29yaXRobSA9PSAxNykgew0KCQkJdmFyIGRzYSA9IG5ldyBEU0EoKTsNCgkJCXJldHVybiBkc2Euc2VsZWN0X2hhc2hfYWxnb3JpdGhtKHBrZXkucHVibGljS2V5Lk1QSXNbMV0udG9CaWdJbnRlZ2VyKCkpOyAvLyBxDQoJCX0NCgkJLy9UT0RPIGltcGxlbWVudDogaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzQ4ODAjc2VjdGlvbi01LjIuMy44DQoJCS8vc2VwYXJhdGUgcHJpdmF0ZSBrZXkgcHJlZmVyZW5jZSBmcm9tIGRpZ2VzdCBwcmVmZXJlbmNlcw0KCQlyZXR1cm4gb3BlbnBncC5jb25maWcuY29uZmlnLnByZWZlcl9oYXNoX2FsZ29yaXRobTsNCgkJCQ0KCX0NCg0KCWZ1bmN0aW9uIGRlY3J5cHRTZWNyZXRNUElzKHN0cl9wYXNzcGhyYXNlKSB7DQoJCXJldHVybiB0aGlzLnByaXZhdGVLZXlQYWNrZXQuZGVjcnlwdFNlY3JldE1QSXMoc3RyX3Bhc3NwaHJhc2UpOw0KCX0NCgkNCglmdW5jdGlvbiBnZXRGaW5nZXJwcmludCgpIHsNCgkJcmV0dXJuIHRoaXMucHJpdmF0ZUtleVBhY2tldC5wdWJsaWNLZXkuZ2V0RmluZ2VycHJpbnQoKTsNCgl9DQoNCgkvLyBUT0RPIG5lZWQgdG8gaW1wbGVtZW50IHRoaXMNCglmdW5jdGlvbiByZXZva2UoKSB7DQoJCQ0KCX0NCg0KCS8qKg0KCSAqIGV4dHJhY3RzIHRoZSBwdWJsaWMga2V5IHBhcnQNCgkgKiBAcmV0dXJuIHtTdHJpbmd9IE9wZW5QR1AgYXJtb3JlZCB0ZXh0IGNvbnRhaW5pbmcgdGhlIHB1YmxpYyBrZXkNCgkgKiAgICAgICAgICAgICAgICAgIHJldHVybnMgbnVsbCBpZiBubyBzdWZmaWNpZW50IGRhdGEgdG8gZXh0cmFjdCBwdWJsaWMga2V5DQoJICovDQoJZnVuY3Rpb24gZXh0cmFjdFB1YmxpY0tleSgpIHsNCgkJLy8gYWRkIHB1YmxpYyBrZXkNCgkJdmFyIGtleSA9IHRoaXMucHJpdmF0ZUtleVBhY2tldC5wdWJsaWNLZXkuaGVhZGVyICsgdGhpcy5wcml2YXRlS2V5UGFja2V0LnB1YmxpY0tleS5kYXRhOw0KCQlmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudXNlcklkcy5sZW5ndGg7IGkrKykgew0KCQkJLy8gdmVyaWZ5IHVzZXJpZHMNCgkJCWlmICh0aGlzLnVzZXJJZHNbaV0uY2VydGlmaWNhdGlvblNpZ25hdHVyZXMubGVuZ3RoID09PSAwKSB7DQoJCQkJdXRpbC5wcmludF9lcnJvcigiZXh0cmFjdFB1YmxpY0tleSAtIG1pc3NpbmcgY2VydGlmaWNhdGlvbiBzaWduYXR1cmVzIik7DQoJCQkJcmV0dXJuIG51bGw7DQoJCQl9DQoJCQl2YXIgdXNlcklkUGFja2V0ID0gbmV3IG9wZW5wZ3BfcGFja2V0X3VzZXJpZCgpOw0KCQkJLy8gYWRkIHVzZXJpZHMNCgkJCWtleSArPSB1c2VySWRQYWNrZXQud3JpdGVfcGFja2V0KHRoaXMudXNlcklkc1tpXS50ZXh0KTsNCgkJCWZvciAodmFyIGogPSAwOyBqIDwgdGhpcy51c2VySWRzW2ldLmNlcnRpZmljYXRpb25TaWduYXR1cmVzLmxlbmd0aDsgaisrKSB7DQoJCQkJdmFyIGNlcnRTaWcgPSB0aGlzLnVzZXJJZHNbaV0uY2VydGlmaWNhdGlvblNpZ25hdHVyZXNbal07DQoJCQkJLy8gYWRkIHNpZ25hdHVyZXMNCgkJCQlrZXkgKz0gb3BlbnBncF9wYWNrZXQud3JpdGVfcGFja2V0X2hlYWRlcigyLCBjZXJ0U2lnLmRhdGEubGVuZ3RoKSArIGNlcnRTaWcuZGF0YTsNCgkJCX0NCgkJfQ0KCQlmb3IgKHZhciBrID0gMDsgayA8IHRoaXMuc3ViS2V5cy5sZW5ndGg7IGsrKykgew0KCQkJdmFyIHB1YlN1YktleSA9IHRoaXMuc3ViS2V5c1trXS5wdWJsaWNLZXk7DQoJCQkvLyBhZGQgcHVibGljIHN1YmtleSBwYWNrYWdlDQoJCQlrZXkgKz0gb3BlbnBncF9wYWNrZXQud3JpdGVfb2xkX3BhY2tldF9oZWFkZXIoMTQsIHB1YlN1YktleS5kYXRhLmxlbmd0aCkgKyBwdWJTdWJLZXkuZGF0YTsNCgkJCXZhciBzdWJLZXlTaWcgPSB0aGlzLnN1YktleXNba10uc3ViS2V5U2lnbmF0dXJlOw0KCQkJaWYgKHN1YktleVNpZyAhPT0gbnVsbCkgew0KCQkJCS8vIGFkZCBzdWJrZXkgc2lnbmF0dXJlDQoJCQkJa2V5ICs9IG9wZW5wZ3BfcGFja2V0LndyaXRlX3BhY2tldF9oZWFkZXIoMiwgc3ViS2V5U2lnLmRhdGEubGVuZ3RoKSArIHN1YktleVNpZy5kYXRhOw0KCQkJfSBlbHNlIHsNCgkJCQl1dGlsLnByaW50X2Vycm9yKCJleHRyYWN0UHVibGljS2V5IC0gbWlzc2luZyBzdWJrZXkgc2lnbmF0dXJlIik7DQoJCQkJcmV0dXJuIG51bGw7DQoJCQl9DQoJCX0NCgkJdmFyIHB1YmxpY0FybW9yZWQgPSBvcGVucGdwX2VuY29kaW5nX2FybW9yKDQsIGtleSk7DQoJCXJldHVybiBwdWJsaWNBcm1vcmVkOw0KCX0NCg0KCXRoaXMuZXh0cmFjdFB1YmxpY0tleSA9IGV4dHJhY3RQdWJsaWNLZXk7DQoJdGhpcy5nZXRTaWduaW5nS2V5ID0gZ2V0U2lnbmluZ0tleTsNCgl0aGlzLmdldEZpbmdlcnByaW50ID0gZ2V0RmluZ2VycHJpbnQ7DQoJdGhpcy5nZXRQcmVmZXJyZWRTaWduYXR1cmVIYXNoQWxnb3JpdGhtID0gZ2V0UHJlZmVycmVkU2lnbmF0dXJlSGFzaEFsZ29yaXRobTsNCgl0aGlzLnJlYWRfbm9kZXMgPSByZWFkX25vZGVzOw0KCXRoaXMuZGVjcnlwdFNlY3JldE1QSXMgPSBkZWNyeXB0U2VjcmV0TVBJczsNCgl0aGlzLmdldFN1YktleUlkcyA9IGdldFN1YktleUlkczsNCgl0aGlzLmdldEtleUlkID0gZ2V0S2V5SWQ7DQoJDQp9DQovLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHQNCi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkgNCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcg0KLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyDQovLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4NCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsDQovLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0KLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUNCi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuDQovLyANCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUNCi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQ0KDQovKioNCiAqIEBjbGFzcw0KICogQGNsYXNzZGVzYyBEZWNvZGVkIHB1YmxpYyBrZXkgb2JqZWN0IGZvciBpbnRlcm5hbCBvcGVucGdwLmpzIHVzZQ0KICovDQpmdW5jdGlvbiBvcGVucGdwX21zZ19wdWJsaWNrZXkoKSB7DQoJdGhpcy5kYXRhOw0KCXRoaXMucG9zaXRpb247DQoJdGhpcy5sZW47DQoJdGhpcy50b3N0cmluZyA9ICJPUEVOUEdQIFBVQkxJQyBLRVlcbiI7DQoJdGhpcy5iaW5kaW5nU2lnbmF0dXJlID0gbnVsbDsNCgl0aGlzLnB1YmxpY0tleVBhY2tldCA9IG51bGw7DQoJdGhpcy51c2VySWRzID0gbmV3IEFycmF5KCk7DQoJdGhpcy51c2VyQXR0cmlidXRlcyA9IG5ldyBBcnJheSgpOw0KCXRoaXMucmV2b2NhdGlvblNpZ25hdHVyZXMgPSBuZXcgQXJyYXkoKTsNCgl0aGlzLnN1YktleXMgPSBuZXcgQXJyYXkoKTsNCgl0aGlzLmFyYml0cmFyeVBhY2tldCA9IG5ldyBBcnJheSgpOw0KCXRoaXMuZGlyZWN0U2lnbmF0dXJlcyA9IG5ldyBBcnJheSgpOw0KCS8qKg0KCSAqIA0KCSAqIEByZXR1cm4gbGFzdCBwb3NpdGlvbg0KCSAqLw0KCWZ1bmN0aW9uIHJlYWRfbm9kZXMocGFyZW50X25vZGUsIGlucHV0LCBwb3NpdGlvbiwgbGVuKSB7DQoJCXRoaXMucHVibGljS2V5UGFja2V0ID0gcGFyZW50X25vZGU7DQoJCXZhciBleGl0ID0gZmFsc2U7DQoJCXZhciBwb3MgPSBwb3NpdGlvbjsNCgkJdmFyIGwgPSBsZW47DQoJCXdoaWxlIChpbnB1dC5sZW5ndGggIT0gcG9zKSB7DQoJCQl2YXIgcmVzdWx0ID0gb3BlbnBncF9wYWNrZXQucmVhZF9wYWNrZXQoaW5wdXQsIHBvcywgaW5wdXQubGVuZ3RoIC0gcG9zKTsNCgkJCWlmIChyZXN1bHQgPT0gbnVsbCkgew0KCQkJCXV0aWwucHJpbnRfZXJyb3IoIm9wZW5wZ3AubXNnLnB1YmxpY2tleSByZWFkX25vZGVzOlxuIisnW3B1Yl9rZXldcGFyc2luZyBlbmRzIGhlcmUgQDonICsgcG9zICsgIiBsOiIgKyBsKTsNCgkJCQlicmVhazsNCgkJCX0gZWxzZSB7DQoJCQkJc3dpdGNoIChyZXN1bHQudGFnVHlwZSkgew0KCQkJCWNhc2UgMjogLy8gcHVibGljIGtleSByZXZvY2F0aW9uIHNpZ25hdHVyZQ0KCQkJCQlpZiAocmVzdWx0LnNpZ25hdHVyZVR5cGUgPT0gMzIpDQoJCQkJCQl0aGlzLnJldm9jYXRpb25TaWduYXR1cmVzW3RoaXMucmV2b2NhdGlvblNpZ25hdHVyZXMubGVuZ3RoXSA9IHJlc3VsdDsNCgkJCQkJZWxzZSBpZiAocmVzdWx0LnNpZ25hdHVyZVR5cGUgPT0gMTYgfHwgcmVzdWx0LnNpZ25hdHVyZVR5cGUgPT0gMTcgfHwgcmVzdWx0LnNpZ25hdHVyZVR5cGUgPT0gMTggIHx8IHJlc3VsdC5zaWduYXR1cmVUeXBlID09IDE5KQ0KCQkJCQkJdGhpcy5jZXJ0aWZpY2F0aW9uU2lnbmF0dXJlID0gcmVzdWx0Ow0KCQkJCQllbHNlIGlmIChyZXN1bHQuc2lnbmF0dXJlVHlwZSA9PSAyNSkgew0KCQkJCQkJdGhpcy5iaW5kaW5nU2lnbmF0dXJlID0gcmVzdWx0Ow0KCQkJCQl9IGVsc2UgaWYgKHJlc3VsdC5zaWduYXR1cmVUeXBlID09IDMxKSB7DQoJCQkJCQl0aGlzLmRpcmVjdFNpZ25hdHVyZXNbdGhpcy5kaXJlY3RTaWduYXR1cmVzLmxlbmd0aF0gPSByZXN1bHQ7DQoJCQkJCX0gZWxzZQ0KCQkJCQkJdXRpbC5wcmludF9lcnJvcigib3BlbnBncC5tc2cucHVibGlja2V5IHJlYWRfbm9kZXM6XG4iKyJ1bmtub3duIHNpZ25hdHVyZSB0eXBlIGRpcmVjdGx5IG9uIGtleSAiK3Jlc3VsdC5zaWduYXR1cmVUeXBlKTsNCgkJCQkJcG9zICs9IHJlc3VsdC5wYWNrZXRMZW5ndGggKyByZXN1bHQuaGVhZGVyTGVuZ3RoOw0KCQkJCQlicmVhazsNCgkJCQljYXNlIDE0OiAvLyBQdWJsaWMtU3Via2V5IFBhY2tldA0KCQkJCQl0aGlzLnN1YktleXNbdGhpcy5zdWJLZXlzLmxlbmd0aF0gPSByZXN1bHQ7DQoJCQkJCXBvcyArPSByZXN1bHQucGFja2V0TGVuZ3RoICsgcmVzdWx0LmhlYWRlckxlbmd0aDsNCgkJCQkJcG9zICs9IHJlc3VsdC5yZWFkX25vZGVzKHRoaXMucHVibGljS2V5UGFja2V0LGlucHV0LCBwb3MsIGlucHV0Lmxlbmd0aCAtIHBvcyk7DQoJCQkJCWJyZWFrOw0KCQkJCWNhc2UgMTc6IC8vIFVzZXIgQXR0cmlidXRlIFBhY2tldA0KCQkJCQl0aGlzLnVzZXJBdHRyaWJ1dGVzW3RoaXMudXNlckF0dHJpYnV0ZXMubGVuZ3RoXSA9IHJlc3VsdDsNCgkJCQkJcG9zICs9IHJlc3VsdC5wYWNrZXRMZW5ndGggKyByZXN1bHQuaGVhZGVyTGVuZ3RoOw0KCQkJCQlwb3MgKz0gcmVzdWx0LnJlYWRfbm9kZXModGhpcy5wdWJsaWNLZXlQYWNrZXQsaW5wdXQsIHBvcywgaW5wdXQubGVuZ3RoIC0gcG9zKTsNCgkJCQkJYnJlYWs7DQoJCQkJY2FzZSAxMzogLy8gVXNlciBJRCBQYWNrZXQNCgkJCQkJdGhpcy51c2VySWRzW3RoaXMudXNlcklkcy5sZW5ndGhdID0gcmVzdWx0Ow0KCQkJCQlwb3MgKz0gcmVzdWx0LnBhY2tldExlbmd0aCArIHJlc3VsdC5oZWFkZXJMZW5ndGg7DQoJCQkJCXBvcyArPSByZXN1bHQucmVhZF9ub2Rlcyh0aGlzLnB1YmxpY0tleVBhY2tldCwgaW5wdXQsIHBvcywgaW5wdXQubGVuZ3RoIC0gcG9zKTsNCgkJCQkJYnJlYWs7DQoJCQkJZGVmYXVsdDoNCgkJCQkJdGhpcy5kYXRhID0gaW5wdXQ7DQoJCQkJCXRoaXMucG9zaXRpb24gPSBwb3NpdGlvbiAtIHRoaXMucHVibGljS2V5UGFja2V0LnBhY2tldExlbmd0aCAtIHRoaXMucHVibGljS2V5UGFja2V0LmhlYWRlckxlbmd0aDsNCgkJCQkJdGhpcy5sZW4gPSBwb3MgLSBwb3NpdGlvbjsNCgkJCQkJcmV0dXJuIHRoaXMubGVuOw0KCQkJCX0NCgkJCX0NCgkJfQ0KCQl0aGlzLmRhdGEgPSBpbnB1dDsNCgkJdGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uIC0gKHRoaXMucHVibGljS2V5UGFja2V0LnBhY2tldExlbmd0aCAtIHRoaXMucHVibGljS2V5UGFja2V0LmhlYWRlckxlbmd0aCk7DQoJCXRoaXMubGVuID0gcG9zIC0gcG9zaXRpb247DQoJCXJldHVybiB0aGlzLmxlbjsNCgl9DQoNCglmdW5jdGlvbiB3cml0ZSgpIHsNCg0KCX0NCg0KCWZ1bmN0aW9uIGdldEtleUlkKCkgew0KCQlyZXR1cm4gdGhpcy5wdWJsaWNLZXlQYWNrZXQuZ2V0S2V5SWQoKTsNCgl9DQoJDQoJZnVuY3Rpb24gZ2V0RmluZ2VycHJpbnQoKSB7DQoJCXJldHVybiB0aGlzLnB1YmxpY0tleVBhY2tldC5nZXRGaW5nZXJwcmludCgpOw0KCX0NCg0KDQoJDQoJZnVuY3Rpb24gdmFsaWRhdGUoKSB7DQoJCS8vIGNoZWNrIHJldm9jYXRpb24ga2V5cw0KCQlmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucmV2b2NhdGlvblNpZ25hdHVyZXMubGVuZ3RoOyBpKyspIHsNCgkJCXZhciB0b2hhc2ggPSB0aGlzLnB1YmxpY0tleVBhY2tldC5oZWFkZXIrdGhpcy5wdWJsaWNLZXlQYWNrZXQuZGF0YTsNCgkJCWlmICh0aGlzLnJldm9jYXRpb25TaWduYXR1cmVzW2ldLnZlcmlmeSh0b2hhc2gsIHRoaXMucHVibGljS2V5UGFja2V0KSkNCgkJCQlyZXR1cm4gZmFsc2U7DQoJCX0NCgkJDQoJCWlmICh0aGlzLnN1YktleXMubGVuZ3RoICE9IDApIHsNCgkJCS8vIHNlYXJjaCBmb3IgYSB2YWxpZCBzdWJrZXkNCgkJCXZhciBmb3VuZCA9IGZhbHNlOw0KCQkJZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YktleXMubGVuZ3RoOyBpKyspDQoJCQkJaWYgKHRoaXMuc3ViS2V5c1tpXS52ZXJpZnlLZXkoKSA9PSAzKSB7DQoJCQkJCWZvdW5kID0gdHJ1ZTsNCgkJCQkJYnJlYWs7DQoJCQkJfQ0KCQkJaWYgKCFmb3VuZCkNCgkJCQlyZXR1cm4gZmFsc2U7DQoJCX0NCgkJLy8gc2VhcmNoIGZvciBvbmUgdmFsaWQgdXNlcmlkDQoJCWZvdW5kID0gZmFsc2U7DQoJCWZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy51c2VySWRzLmxlbmd0aDsgaSsrKQ0KCQkJaWYgKHRoaXMudXNlcklkc1tpXS52ZXJpZnkodGhpcy5wdWJsaWNLZXlQYWNrZXQpID09IDApIHsNCgkJCQlmb3VuZCA9IHRydWU7DQoJCQkJYnJlYWs7DQoJCQl9DQoJCWlmICghZm91bmQpDQoJCQlyZXR1cm4gZmFsc2U7DQoJCXJldHVybiB0cnVlOw0KCX0NCgkNCgkvKioNCgkgKiB2ZXJpZmllcyBhbGwgc2lnbmF0dXJlcw0KCSAqIEByZXR1cm4gYSAyIGRpbWVuc2lvbmFsIGFycmF5LiB0aGUgZmlyc3QgZGltZW5zaW9uIGNvcnJlc3BvbmRzIHRvIHRoZSB1c2VyaWRzIGF2YWlsYWJsZQ0KCSAqLw0KCWZ1bmN0aW9uIHZlcmlmeUNlcnRpZmljYXRpb25TaWduYXR1cmVzKCkgew0KCQl2YXIgcmVzdWx0ID0gbmV3IEFycmF5KCk7DQoJCWZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy51c2VySWRzLmxlbmd0aDsgaSsrKSB7DQoJCQlyZXN1bHRbaV0gPSB0aGlzLnVzZXJJZHNbaV0udmVyaWZ5Q2VydGlmaWNhdGlvblNpZ25hdHVyZXModGhpcy5wdWJsaWNLZXlQYWNrZXQpOw0KCQl9DQoJCXJldHVybiByZXN1bHQ7DQoJfQ0KCXRoaXMudmVyaWZ5Q2VydGlmaWNhdGlvblNpZ25hdHVyZXMgPSB2ZXJpZnlDZXJ0aWZpY2F0aW9uU2lnbmF0dXJlczsNCgkNCgkvKioNCgkgKiB2ZXJpZmllczoNCgkgKiAgLSByZXZvY2F0aW9uIGNlcnRpZmljYXRlcyBkaXJlY3RseSBvbiBrZXkNCgkgKiAgLSBzZWxmIHNpZ25hdHVyZXMNCgkgKiAgLSBzdWJrZXkgYmluZGluZyBhbmQgcmV2b2NhdGlvbiBjZXJ0aWZpY2F0ZXMNCgkgKiAgDQoJICogIFRoaXMgaXMgdXNlZnVsIGZvciB2YWxpZGF0aW5nIHRoZSBrZXkNCgkgKiAgQHJldHVybnMge0Jvb2xlYW59IHRydWUgaWYgdGhlIGJhc2ljIHNpZ25hdHVyZXMgYXJlIGFsbCB2YWxpZA0KCSAqLw0KCWZ1bmN0aW9uIHZlcmlmeUJhc2ljU2lnbmF0dXJlcygpIHsNCgkJZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnJldm9jYXRpb25TaWduYXR1cmVzLmxlbmd0aDsgaSsrKSB7DQoJCQl2YXIgdG9oYXNoID0gdGhpcy5wdWJsaWNLZXlQYWNrZXQuaGVhZGVyK3RoaXMucHVibGljS2V5UGFja2V0LmRhdGE7DQoJCQlpZiAodGhpcy5yZXZvY2F0aW9uU2lnbmF0dXJlc1tpXS52ZXJpZnkodG9oYXNoLCB0aGlzLnB1YmxpY0tleVBhY2tldCkpDQoJCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoJCQ0KCQlpZiAodGhpcy5zdWJLZXlzLmxlbmd0aCAhPSAwKSB7DQoJCQkvLyBzZWFyY2ggZm9yIGEgdmFsaWQgc3Via2V5DQoJCQl2YXIgZm91bmQgPSBmYWxzZTsNCgkJCWZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zdWJLZXlzLmxlbmd0aDsgaSsrKSB7DQoJCQkJaWYgKHRoaXMuc3ViS2V5c1tpXSA9PSBudWxsKQ0KCQkJCQljb250aW51ZTsNCgkJCQl2YXIgcmVzdWx0ID0gdGhpcy5zdWJLZXlzW2ldLnZlcmlmeUtleSgpOw0KCQkJCWlmIChyZXN1bHQgPT0gMykgew0KCQkJCQlmb3VuZCA9IHRydWU7DQoJCQkJCWJyZWFrOw0KCQkJCX0gDQoJCQl9DQoJCQlpZiAoIWZvdW5kKQ0KCQkJCXJldHVybiBmYWxzZTsNCgkJfQ0KCQl2YXIga2V5SWQgPSB0aGlzLmdldEtleUlkKCk7DQoJCWZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy51c2VySWRzLmxlbmd0aDsgaSsrKSB7DQoJCQlmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMudXNlcklkc1tpXS5jZXJ0aWZpY2F0aW9uUmV2b2NhdGlvblNpZ25hdHVyZXMubGVuZ3RoOyBqKyspIHsNCgkJCQlpZiAodGhpcy51c2VySWRzW2ldLmNlcnRpZmljYXRpb25TaWduYXR1cmVzW2pdLmdldElzc3VlciA9PSBrZXlJZCAmJg0KCQkJCQl0aGlzLnVzZXJJZHNbaV0uY2VydGlmaWNhdGlvblNpZ25hdHVyZXNbal0udmVyaWZ5QmFzaWModGhpcy5wdWJsaWNLZXlQYWNrZXQpICE9IDQpDQoJCQkJCXJldHVybiBmYWxzZTsNCgkJCX0NCgkJfQ0KCQlyZXR1cm4gdHJ1ZTsNCgl9DQoJDQoJZnVuY3Rpb24gdG9TdHJpbmcoKSB7DQoJCXZhciByZXN1bHQgPSAiIE9QRU5QR1AgUHVibGljIEtleVxuICAgIGxlbmd0aDogIit0aGlzLmxlbisiXG4iOw0KCQlyZXN1bHQgKz0gIiAgICBSZXZvY2F0aW9uIFNpZ25hdHVyZXM6XG4iDQoJCWZvciAodmFyIGk9MDsgaSA8IHRoaXMucmV2b2NhdGlvblNpZ25hdHVyZXMubGVuZ3RoOyBpKyspIHsNCgkJCXJlc3VsdCArPSAiICAgICIrdGhpcy5yZXZvY2F0aW9uU2lnbmF0dXJlc1tpXS50b1N0cmluZygpOyANCgkJfQ0KCQlyZXN1bHQgKz0gIiAgICBVc2VyIElkczpcbiI7DQoJCWZvciAodmFyIGk9MDsgaSA8IHRoaXMudXNlcklkcy5sZW5ndGg7IGkrKykgew0KCQkJcmVzdWx0ICs9ICIgICAgIit0aGlzLnVzZXJJZHNbaV0udG9TdHJpbmcoKTsgDQoJCX0NCgkJcmVzdWx0ICs9ICIgICAgVXNlciBBdHRyaWJ1dGVzOlxuIjsNCgkJZm9yICh2YXIgaT0wOyBpIDwgdGhpcy51c2VyQXR0cmlidXRlcy5sZW5ndGg7IGkrKykgew0KCQkJcmVzdWx0ICs9ICIgICAgIit0aGlzLnVzZXJBdHRyaWJ1dGVzW2ldLnRvU3RyaW5nKCk7IA0KCQl9DQoJCXJlc3VsdCArPSAiICAgIFB1YmxpYyBLZXkgU3ViS2V5czpcbiI7DQoJCWZvciAodmFyIGk9MDsgaSA8IHRoaXMuc3ViS2V5cy5sZW5ndGg7IGkrKykgew0KCQkJcmVzdWx0ICs9ICIgICAgIit0aGlzLnN1YktleXNbaV0udG9TdHJpbmcoKTsgDQoJCX0NCgkJcmV0dXJuIHJlc3VsdDsNCgl9DQoJDQoJLyoqDQoJICogZmluZHMgYW4gZW5jcnlwdGlvbiBrZXkgZm9yIHRoaXMgcHVibGljIGtleQ0KCSAqIEByZXR1cm5zIG51bGwgaWYgbm8gZW5jcnlwdGlvbiBrZXkgaGFzIGJlZW4gZm91bmQNCgkgKi8NCglmdW5jdGlvbiBnZXRFbmNyeXB0aW9uS2V5KCkgew0KCQkvLyBWNDogYnkgY29udmVudGlvbiBzdWJrZXlzIGFyZSBwcmVmZXJlZCBmb3IgZW5jcnlwdGlvbiBzZXJ2aWNlDQoJCS8vIFYzOiBrZXlzIE1VU1QgTk9UIGhhdmUgc3Via2V5cw0KCQlmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMuc3ViS2V5cy5sZW5ndGg7IGorKykNCgkJCQlpZiAodGhpcy5zdWJLZXlzW2pdLnB1YmxpY0tleUFsZ29yaXRobSAhPSAxNyAmJg0KCQkJCQkJdGhpcy5zdWJLZXlzW2pdLnB1YmxpY0tleUFsZ29yaXRobSAhPSAzICYmDQoJCQkJCQl0aGlzLnN1YktleXNbal0udmVyaWZ5S2V5KCkpIHsNCgkJCQkJcmV0dXJuIHRoaXMuc3ViS2V5c1tqXTsNCgkJCQl9DQoJCS8vIGlmIG5vIHZhbGlkIHN1YmtleSBmb3IgZW5jcnlwdGlvbiwgdXNlIHByaW1hcnkga2V5DQoJCWlmICh0aGlzLnB1YmxpY0tleVBhY2tldC5wdWJsaWNLZXlBbGdvcml0aG0gIT0gMTcgJiYgdGhpcy5wdWJsaWNLZXlQYWNrZXQucHVibGljS2V5QWxnb3JpdGhtICE9IDMNCgkJCSYmIHRoaXMucHVibGljS2V5UGFja2V0LnZlcmlmeUtleSgpKSB7DQoJCQlyZXR1cm4gdGhpcy5wdWJsaWNLZXlQYWNrZXQ7CQ0KCQl9DQoJCXJldHVybiBudWxsOw0KCX0NCgkNCglmdW5jdGlvbiBnZXRTaWduaW5nS2V5KCkgew0KCQlpZiAoKHRoaXMucHVibGljS2V5UGFja2V0LnB1YmxpY0tleUFsZ29yaXRobSA9PSAxNyB8fA0KCQkJIHRoaXMucHVibGljS2V5UGFja2V0LnB1YmxpY0tleUFsZ29yaXRobSAhPSAyKSkNCgkJCXJldHVybiB0aGlzLnB1YmxpY0tleVBhY2tldDsNCgkJZWxzZSBpZiAodGhpcy5wdWJsaWNLZXlQYWNrZXQudmVyc2lvbiA9PSA0KSAvLyBWMyBrZXlzIE1VU1QgTk9UIGhhdmUgc3Via2V5cy4NCgkJCWZvciAodmFyIGogPSAwOyBqIDwgdGhpcy5zdWJLZXlzLmxlbmd0aDsgaisrKSB7DQoJCQkJaWYgKCh0aGlzLnN1YktleXNbal0ucHVibGljS2V5QWxnb3JpdGhtID09IDE3IHx8DQoJCQkJCSB0aGlzLnN1YktleXNbal0ucHVibGljS2V5QWxnb3JpdGhtICE9IDIpICYmDQoJCQkJCSB0aGlzLnN1YktleXNbal0udmVyaWZ5S2V5KCkpDQoJCQkJCXJldHVybiB0aGlzLnN1YktleXNbal07DQoJCQl9DQoJCXJldHVybiBudWxsOw0KCX0NCg0KICAgICAgICAvKiBSZXR1cm5zIHRoZSBpLXRoIHN1YktleSBhcyBhIG9wZW5wZ3BfbXNnX3B1YmxpY2tleSBvYmplY3QgKi8NCglmdW5jdGlvbiBnZXRTdWJLZXlBc0tleShpKSB7DQoJCXZhciByZXQgPSBuZXcgb3BlbnBncF9tc2dfcHVibGlja2V5KCk7DQoJCXJldC51c2VySWRzID0gdGhpcy51c2VySWRzOw0KCQlyZXQudXNlckF0dHJpYnV0ZXMgPSB0aGlzLnVzZXJBdHRyaWJ1dGVzOw0KCQlyZXQucHVibGljS2V5UGFja2V0ID0gdGhpcy5zdWJLZXlzW2ldOw0KCQlyZXR1cm4gcmV0Ow0KCX0NCg0KCXRoaXMuZ2V0RW5jcnlwdGlvbktleSA9IGdldEVuY3J5cHRpb25LZXk7DQoJdGhpcy5nZXRTaWduaW5nS2V5ID0gZ2V0U2lnbmluZ0tleTsNCgl0aGlzLnJlYWRfbm9kZXMgPSByZWFkX25vZGVzOw0KCXRoaXMud3JpdGUgPSB3cml0ZTsNCgl0aGlzLnRvU3RyaW5nID0gdG9TdHJpbmc7DQoJdGhpcy52YWxpZGF0ZSA9IHZhbGlkYXRlOw0KCXRoaXMuZ2V0RmluZ2VycHJpbnQgPSBnZXRGaW5nZXJwcmludDsNCgl0aGlzLmdldEtleUlkID0gZ2V0S2V5SWQ7DQoJdGhpcy52ZXJpZnlCYXNpY1NpZ25hdHVyZXMgPSB2ZXJpZnlCYXNpY1NpZ25hdHVyZXM7DQoJdGhpcy5nZXRTdWJLZXlBc0tleSA9IGdldFN1YktleUFzS2V5Ow0KfQ0KLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0DQovLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3INCi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcg0KLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLA0KLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YNCi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VDQovLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLg0KLy8gDQovLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlDQovLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0ENCg0KLyoqDQogKiBAY2xhc3MNCiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIENvbXByZXNzZWQgRGF0YSBQYWNrZXQgKFRhZyA4KQ0KICogDQogKiBSRkM0ODgwIDUuNjoNCiAqIFRoZSBDb21wcmVzc2VkIERhdGEgcGFja2V0IGNvbnRhaW5zIGNvbXByZXNzZWQgZGF0YS4gIFR5cGljYWxseSwgdGhpcw0KICogcGFja2V0IGlzIGZvdW5kIGFzIHRoZSBjb250ZW50cyBvZiBhbiBlbmNyeXB0ZWQgcGFja2V0LCBvciBmb2xsb3dpbmcNCiAqIGEgU2lnbmF0dXJlIG9yIE9uZS1QYXNzIFNpZ25hdHVyZSBwYWNrZXQsIGFuZCBjb250YWlucyBhIGxpdGVyYWwgZGF0YQ0KICogcGFja2V0Lg0KICovICAgDQpmdW5jdGlvbiBvcGVucGdwX3BhY2tldF9jb21wcmVzc2VkKCkgew0KCXRoaXMudGFnVHlwZSA9IDg7DQoJdGhpcy5kZWNvbXByZXNzZWREYXRhID0gbnVsbDsNCgkNCgkvKioNCgkgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciB0aGUgcGFja2V0Lg0KCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDggcGFja2V0DQoJICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBQb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZw0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuIExlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mIA0KCSAqIGlucHV0IGF0IHBvc2l0aW9uDQoJICogQHJldHVybiB7b3BlbnBncF9wYWNrZXRfY29tcHJlc3NlZH0gT2JqZWN0IHJlcHJlc2VudGF0aW9uDQoJICovDQoJZnVuY3Rpb24gcmVhZF9wYWNrZXQgKGlucHV0LCBwb3NpdGlvbiwgbGVuKSB7DQoJCXRoaXMucGFja2V0TGVuZ3RoID0gbGVuOw0KCQl2YXIgbXlwb3MgPSBwb3NpdGlvbjsNCgkJLy8gT25lIG9jdGV0IHRoYXQgZ2l2ZXMgdGhlIGFsZ29yaXRobSB1c2VkIHRvIGNvbXByZXNzIHRoZSBwYWNrZXQuDQoJCXRoaXMudHlwZSA9IGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKyk7DQoJCS8vIENvbXByZXNzZWQgZGF0YSwgd2hpY2ggbWFrZXMgdXAgdGhlIHJlbWFpbmRlciBvZiB0aGUgcGFja2V0Lg0KCQl0aGlzLmNvbXByZXNzZWREYXRhID0gaW5wdXQuc3Vic3RyaW5nKHBvc2l0aW9uKzEsIHBvc2l0aW9uK2xlbik7DQoJCXJldHVybiB0aGlzOw0KCX0NCgkvKioNCgkgKiBEZWNvbXByZXNzaW9uIG1ldGhvZCBmb3IgZGVjb21wcmVzc2luZyB0aGUgY29tcHJlc3NlZCBkYXRhDQoJICogcmVhZCBieSByZWFkX3BhY2tldA0KCSAqIEByZXR1cm4ge1N0cmluZ30gVGhlIGRlY29tcHJlc3NlZCBkYXRhDQoJICovDQoJZnVuY3Rpb24gZGVjb21wcmVzcygpIHsNCgkJaWYgKHRoaXMuZGVjb21wcmVzc2VkRGF0YSAhPSBudWxsKQ0KCQkJcmV0dXJuIHRoaXMuZGVjb21wcmVzc2VkRGF0YTsNCg0KCQlpZiAodGhpcy50eXBlID09IG51bGwpDQoJCQlyZXR1cm4gbnVsbDsNCg0KCQlzd2l0Y2ggKHRoaXMudHlwZSkgew0KCQljYXNlIDA6IC8vIC0gVW5jb21wcmVzc2VkDQoJCQl0aGlzLmRlY29tcHJlc3NlZERhdGEgPSB0aGlzLmNvbXByZXNzZWREYXRhOw0KCQkJYnJlYWs7DQoJCWNhc2UgMTogLy8gLSBaSVAgW1JGQzE5NTFdDQoJCQl1dGlsLnByaW50X2luZm8oJ0RlY29tcHJlc3NlZCBwYWNrZXQgW1R5cGUgMS1aSVBdOiAnICsgdGhpcy50b1N0cmluZygpKTsNCgkJCXZhciBjb21wRGF0YSA9IHRoaXMuY29tcHJlc3NlZERhdGE7DQoJCQl2YXIgcmFkaXggPSBzMnIoY29tcERhdGEpLnJlcGxhY2UoL1xuL2csIiIpOw0KCQkJLy8gbm8gaGVhZGVyIGluIHRoaXMgY2FzZSwgZGlyZWN0bHkgY2FsbCBkZWZsYXRlDQoJCQl2YXIganhnX29iaiA9IG5ldyBKWEcuVXRpbC5VbnppcChKWEcuVXRpbC5CYXNlNjQuZGVjb2RlQXNBcnJheShyYWRpeCkpOw0KCQkJdGhpcy5kZWNvbXByZXNzZWREYXRhID0gdW5lc2NhcGUoanhnX29iai5kZWZsYXRlKClbMF1bMF0pOw0KCQkJYnJlYWs7DQoJCWNhc2UgMjogLy8gLSBaTElCIFtSRkMxOTUwXQ0KCQkJdXRpbC5wcmludF9pbmZvKCdEZWNvbXByZXNzZWQgcGFja2V0IFtUeXBlIDItWkxJQl06ICcgKyB0aGlzLnRvU3RyaW5nKCkpOw0KCQkJdmFyIGNvbXByZXNzaW9uTWV0aG9kID0gdGhpcy5jb21wcmVzc2VkRGF0YS5jaGFyQ29kZUF0KDApICUgMHgxMDsgLy9SRkMgMTk1MC4gQml0cyAwLTMgQ29tcHJlc3Npb24gTWV0aG9kDQoJCQkvL0JpdHMgNC03IFJGQyAxOTUwIGFyZSBMWjc3IFdpbmRvdy4gR2VuZXJhbGx5IHRoaXMgdmFsdWUgaXMgNyA9PSAzMmsgd2luZG93IHNpemUuDQoJCQkvLzJuZCBCeXRlIGluIFJGQyAxOTUwIGlzIGZvciAiRkxBR3MiIEFsbG93cyBmb3IgYSBEaWN0aW9uYXJ5IChob3cgaXMgdGhpcyBkZWZpbmVkKS4gQmFzaWMgY2hlY2tzdW0sIGFuZCBjb21wcmVzc2lvbiBsZXZlbC4NCgkJCWlmIChjb21wcmVzc2lvbk1ldGhvZCA9PSA4KSB7IC8vQ00gOCBpcyBmb3IgREVGTEFURSwgUkZDIDE5NTENCgkJCQkvLyByZW1vdmUgNCBieXRlcyBBRExFUjMyIGNoZWNrc3VtIGZyb20gdGhlIGVuZA0KCQkJCXZhciBjb21wRGF0YSA9IHRoaXMuY29tcHJlc3NlZERhdGEuc3Vic3RyaW5nKDAsIHRoaXMuY29tcHJlc3NlZERhdGEubGVuZ3RoIC0gNCk7DQoJCQkJdmFyIHJhZGl4ID0gczJyKGNvbXBEYXRhKS5yZXBsYWNlKC9cbi9nLCIiKTsNCgkJCQkvL1RPRE8gY2hlY2sgQURMRVIzMiBjaGVja3N1bQ0KCQkJCXRoaXMuZGVjb21wcmVzc2VkRGF0YSA9IEpYRy5kZWNvbXByZXNzKHJhZGl4KTsNCgkJCQlicmVhazsNCgkJCX0gZWxzZSB7DQoJCQkJdXRpbC5wcmludF9lcnJvcigiQ29tcHJlc3Npb24gYWxnb3JpdGhtIFpMSUIgb25seSBzdXBwb3J0cyBERUZMQVRFIGNvbXByZXNzaW9uIG1ldGhvZC4iKTsNCgkJCX0NCgkJCWJyZWFrOw0KCQljYXNlIDM6IC8vICAtIEJaaXAyIFtCWjJdDQoJCQkvLyBUT0RPOiBuZWVkIHRvIGltcGxlbWVudCB0aGlzDQoJCQl1dGlsLnByaW50X2Vycm9yKCJDb21wcmVzc2lvbiBhbGdvcml0aG0gQlppcDIgW0JaMl0gaXMgbm90IGltcGxlbWVudGVkLiIpOw0KCQkJYnJlYWs7DQoJCWRlZmF1bHQ6DQoJCQl1dGlsLnByaW50X2Vycm9yKCJDb21wcmVzc2lvbiBhbGdvcml0aG0gdW5rbm93biA6Iit0aGlzLnR5cGUpOw0KCQkJYnJlYWs7DQoJCX0NCgkJdXRpbC5wcmludF9kZWJ1ZygiZGVjb21wcmVzc2VkOiIrdXRpbC5oZXhzdHJkdW1wKHRoaXMuZGVjb21wcmVzc2VkRGF0YSkpOw0KCQlyZXR1cm4gdGhpcy5kZWNvbXByZXNzZWREYXRhOyANCgl9DQoNCgkvKioNCgkgKiBDb21wcmVzcyB0aGUgcGFja2V0IGRhdGEgKG1lbWJlciBkZWNvbXByZXNzZWREYXRhKQ0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gdHlwZSBBbGdvcml0aG0gdG8gYmUgdXNlZCAvLyBTZWUgUkZDIDQ4ODAgOS4zDQoJICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBiZSBjb21wcmVzc2VkDQoJICogQHJldHVybiB7U3RyaW5nfSBUaGUgY29tcHJlc3NlZCBkYXRhIHN0b3JlZCBpbiBhdHRyaWJ1dGUgY29tcHJlc3NlZERhdGENCgkgKi8NCglmdW5jdGlvbiBjb21wcmVzcyh0eXBlLCBkYXRhKSB7DQoJCXRoaXMudHlwZSA9IHR5cGU7DQoJCXRoaXMuZGVjb21wcmVzc2VkRGF0YSA9IGRhdGE7DQoJCXN3aXRjaCAodGhpcy50eXBlKSB7DQoJCWNhc2UgMDogLy8gLSBVbmNvbXByZXNzZWQNCgkJCXRoaXMuY29tcHJlc3NlZERhdGEgPSB0aGlzLmRlY29tcHJlc3NlZERhdGE7DQoJCQlicmVhazsNCgkJY2FzZSAxOiAvLyAtIFpJUCBbUkZDMTk1MV0NCgkJCXV0aWwucHJpbnRfZXJyb3IoIkNvbXByZXNzaW9uIGFsZ29yaXRobSBaSVAgW1JGQzE5NTFdIGlzIG5vdCBpbXBsZW1lbnRlZC4iKTsNCgkJCWJyZWFrOw0KCQljYXNlIDI6IC8vIC0gWkxJQiBbUkZDMTk1MF0NCgkJCS8vIFRPRE86IG5lZWQgdG8gaW1wbGVtZW50IHRoaXMNCgkJCXV0aWwucHJpbnRfZXJyb3IoIkNvbXByZXNzaW9uIGFsZ29yaXRobSBaTElCIFtSRkMxOTUwXSBpcyBub3QgaW1wbGVtZW50ZWQuIik7DQoJCQlicmVhazsNCgkJY2FzZSAzOiAvLyAgLSBCWmlwMiBbQloyXQ0KCQkJLy8gVE9ETzogbmVlZCB0byBpbXBsZW1lbnQgdGhpcw0KCQkJdXRpbC5wcmludF9lcnJvcigiQ29tcHJlc3Npb24gYWxnb3JpdGhtIEJaaXAyIFtCWjJdIGlzIG5vdCBpbXBsZW1lbnRlZC4iKTsNCgkJCWJyZWFrOw0KCQlkZWZhdWx0Og0KCQkJdXRpbC5wcmludF9lcnJvcigiQ29tcHJlc3Npb24gYWxnb3JpdGhtIHVua25vd24gOiIrdGhpcy50eXBlKTsNCgkJCWJyZWFrOw0KCQl9DQoJCXRoaXMucGFja2V0TGVuZ3RoID0gdGhpcy5jb21wcmVzc2VkRGF0YS5sZW5ndGggKzE7DQoJCXJldHVybiB0aGlzLmNvbXByZXNzZWREYXRhOyANCgl9DQoJDQoJLyoqDQoJICogQ3JlYXRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFja2V0DQoJICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvcml0aG0gQWxnb3JpdGhtIHRvIGJlIHVzZWQgLy8gU2VlIFJGQyA0ODgwIDkuMw0KCSAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgdG8gYmUgY29tcHJlc3NlZA0KCSAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nLXJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYWNrZXQNCgkgKi8NCglmdW5jdGlvbiB3cml0ZV9wYWNrZXQoYWxnb3JpdGhtLCBkYXRhKSB7DQoJCXRoaXMuZGVjb21wcmVzc2VkRGF0YSA9IGRhdGE7DQoJCWlmIChhbGdvcml0aG0gPT0gbnVsbCkgew0KCQkJdGhpcy50eXBlID0gMTsNCgkJfQ0KCQl2YXIgcmVzdWx0ID0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnR5cGUpK3RoaXMuY29tcHJlc3ModGhpcy50eXBlKTsNCgkJcmV0dXJuIG9wZW5wZ3BfcGFja2V0LndyaXRlX3BhY2tldF9oZWFkZXIoOCwgcmVzdWx0Lmxlbmd0aCkrcmVzdWx0Ow0KCX0NCgkNCgkvKioNCgkgKiBQcmV0dHkgcHJpbnRpbmcgdGhlIHBhY2tldCAodXNlZnVsIGZvciBkZWJ1ZyBwdXJwb3NlcykNCgkgKiBAcmV0dXJuIHtTdHJpbmd9DQoJICovDQoJZnVuY3Rpb24gdG9TdHJpbmcoKSB7DQoJCXJldHVybiAnNS42LiAgQ29tcHJlc3NlZCBEYXRhIFBhY2tldCAoVGFnIDgpXG4nKw0KCQkgICAnICAgIGxlbmd0aDogICcrdGhpcy5wYWNrZXRMZW5ndGgrJ1xuJysNCgkJCSAgICcgICAgQ29tcHJlc3Npb24gQWxnb3JpdGhtID0gJyt0aGlzLnR5cGUrJ1xuJysNCgkJICAgICAgICcgICAgQ29tcHJlc3NlZCBEYXRhOiBCeXRlIFsnK3V0aWwuaGV4c3RyZHVtcCh0aGlzLmNvbXByZXNzZWREYXRhKSsnXVxuJzsNCgl9DQoJDQoJdGhpcy5yZWFkX3BhY2tldCA9IHJlYWRfcGFja2V0Ow0KCXRoaXMudG9TdHJpbmcgPSB0b1N0cmluZzsNCgl0aGlzLmNvbXByZXNzID0gY29tcHJlc3M7DQoJdGhpcy5kZWNvbXByZXNzID0gZGVjb21wcmVzczsNCgl0aGlzLndyaXRlX3BhY2tldCA9IHdyaXRlX3BhY2tldDsNCn07DQovLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHQNCi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkgNCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcg0KLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyDQovLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4NCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsDQovLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0KLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUNCi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuDQovLyANCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUNCi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQ0KDQovKioNCiAqIEBjbGFzcw0KICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQgKFRhZyA5KQ0KICogDQogKiBSRkM0ODgwIDUuNzogVGhlIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgcGFja2V0IGNvbnRhaW5zIGRhdGEgZW5jcnlwdGVkDQogKiB3aXRoIGEgc3ltbWV0cmljLWtleSBhbGdvcml0aG0uIFdoZW4gaXQgaGFzIGJlZW4gZGVjcnlwdGVkLCBpdCBjb250YWlucyBvdGhlcg0KICogcGFja2V0cyAodXN1YWxseSBhIGxpdGVyYWwgZGF0YSBwYWNrZXQgb3IgY29tcHJlc3NlZCBkYXRhIHBhY2tldCwgYnV0IGluDQogKiB0aGVvcnkgb3RoZXIgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBwYWNrZXRzIG9yIHNlcXVlbmNlcyBvZiBwYWNrZXRzDQogKiB0aGF0IGZvcm0gd2hvbGUgT3BlblBHUCBtZXNzYWdlcykuDQogKi8NCg0KZnVuY3Rpb24gb3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkZGF0YSgpIHsNCgl0aGlzLnRhZ1R5cGUgPSA5Ow0KCXRoaXMucGFja2V0TGVuZ3RoID0gbnVsbDsNCgl0aGlzLmVuY3J5cHRlZERhdGEgPSBudWxsOw0KCXRoaXMuZGVjcnlwdGVkRGF0YSA9IG51bGw7DQoNCgkvKioNCgkgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciB0aGUgcGFja2V0Lg0KCSAqIA0KCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDkgcGFja2V0DQoJICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBQb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZw0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuIExlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mDQoJICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvbg0KCSAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGF9IE9iamVjdCByZXByZXNlbnRhdGlvbg0KCSAqLw0KCWZ1bmN0aW9uIHJlYWRfcGFja2V0KGlucHV0LCBwb3NpdGlvbiwgbGVuKSB7DQoJCXZhciBteXBvcyA9IHBvc2l0aW9uOw0KCQl0aGlzLnBhY2tldExlbmd0aCA9IGxlbjsNCgkJLy8gLSBFbmNyeXB0ZWQgZGF0YSwgdGhlIG91dHB1dCBvZiB0aGUgc2VsZWN0ZWQgc3ltbWV0cmljLWtleSBjaXBoZXINCgkJLy8gb3BlcmF0aW5nIGluIE9wZW5QR1AncyB2YXJpYW50IG9mIENpcGhlciBGZWVkYmFjayAoQ0ZCKSBtb2RlLg0KCQl0aGlzLmVuY3J5cHRlZERhdGEgPSBpbnB1dC5zdWJzdHJpbmcocG9zaXRpb24sIHBvc2l0aW9uICsgbGVuKTsNCgkJcmV0dXJuIHRoaXM7DQoJfQ0KDQoJLyoqDQoJICogU3ltbWV0cmljYWxseSBkZWNyeXB0IHRoZSBwYWNrZXQgZGF0YQ0KCSAqIA0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gc3ltbWV0cmljX2FsZ29yaXRobV90eXBlDQoJICogICAgICAgICAgICAgU3ltbWV0cmljIGtleSBhbGdvcml0aG0gdG8gdXNlIC8vIFNlZSBSRkM0ODgwIDkuMg0KCSAqIEBwYXJhbSB7U3RyaW5nfSBrZXkNCgkgKiAgICAgICAgICAgICBLZXkgYXMgc3RyaW5nIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgbGVuZ3RoIHRvIHRoZQ0KCSAqICAgICAgICAgICAgYWxnb3JpdGhtDQoJICogQHJldHVybiBUaGUgZGVjcnlwdGVkIGRhdGE7DQoJICovDQoJZnVuY3Rpb24gZGVjcnlwdF9zeW0oc3ltbWV0cmljX2FsZ29yaXRobV90eXBlLCBrZXkpIHsNCgkJdGhpcy5kZWNyeXB0ZWREYXRhID0gb3BlbnBncF9jcnlwdG9fc3ltbWV0cmljRGVjcnlwdCgNCgkJCQlzeW1tZXRyaWNfYWxnb3JpdGhtX3R5cGUsIGtleSwgdGhpcy5lbmNyeXB0ZWREYXRhLCB0cnVlKTsNCgkJdXRpbC5wcmludF9kZWJ1Zygib3BlbnBncC5wYWNrZXQuZW5jcnlwdGVkaW50ZWdyaXR5cHJvdGVjdGVkZGF0YS5qc1xuIisNCgkJCQkiZGF0YTogIit1dGlsLmhleHN0cmR1bXAodGhpcy5kZWNyeXB0ZWREYXRhKSk7DQoJCXJldHVybiB0aGlzLmRlY3J5cHRlZERhdGE7DQoJfQ0KDQoJLyoqDQoJICogQ3JlYXRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFja2V0DQoJICogDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIFN5bW1ldHJpYyBrZXkgYWxnb3JpdGhtIHRvIHVzZSAvLyBTZWUgUkZDNDg4MCA5LjINCgkgKiBAcGFyYW0ge1N0cmluZ30ga2V5IEtleSBhcyBzdHJpbmcgd2l0aCB0aGUgY29ycmVzcG9uZGluZyBsZW5ndGggdG8gdGhlDQoJICogICAgICAgICAgICBhbGdvcml0aG0NCgkgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGJlDQoJICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmctcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhY2tldA0KCSAqLw0KCWZ1bmN0aW9uIHdyaXRlX3BhY2tldChhbGdvLCBrZXksIGRhdGEpIHsNCgkJdmFyIHJlc3VsdCA9ICIiOw0KCQlyZXN1bHQgKz0gb3BlbnBncF9jcnlwdG9fc3ltbWV0cmljRW5jcnlwdCgNCgkJCQlvcGVucGdwX2NyeXB0b19nZXRQcmVmaXhSYW5kb20oYWxnbyksIGFsZ28sIGtleSwgZGF0YSwgdHJ1ZSk7DQoJCXJlc3VsdCA9IG9wZW5wZ3BfcGFja2V0LndyaXRlX3BhY2tldF9oZWFkZXIoOSwgcmVzdWx0Lmxlbmd0aCkgKyByZXN1bHQ7DQoJCXJldHVybiByZXN1bHQ7DQoJfQ0KDQoJZnVuY3Rpb24gdG9TdHJpbmcoKSB7DQoJCXJldHVybiAnNS43LiAgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQgKFRhZyA5KVxuJw0KCQkJCSsgJyAgICBsZW5ndGg6ICAnICsgdGhpcy5wYWNrZXRMZW5ndGggKyAnXG4nDQoJCQkJKyAnICAgIFVzZWQgc3ltbWV0cmljIGFsZ29yaXRobTogJyArIHRoaXMuYWxnb3JpdGhtVHlwZSArICdcbicNCgkJCQkrICcgICAgZW5jcnlwdGVkIGRhdGE6IEJ5dGVzIFsnDQoJCQkJKyB1dGlsLmhleHN0cmR1bXAodGhpcy5lbmNyeXB0ZWREYXRhKSArICddXG4nOw0KCX0NCgl0aGlzLmRlY3J5cHRfc3ltID0gZGVjcnlwdF9zeW07DQoJdGhpcy50b1N0cmluZyA9IHRvU3RyaW5nOw0KCXRoaXMucmVhZF9wYWNrZXQgPSByZWFkX3BhY2tldDsNCgl0aGlzLndyaXRlX3BhY2tldCA9IHdyaXRlX3BhY2tldDsNCn07DQovLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHQNCi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkgNCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcg0KLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyDQovLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4NCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsDQovLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0KLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUNCi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuDQovLyANCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUNCi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQ0KDQovKioNCiAqIEBjbGFzcw0KICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3ltLiBFbmNyeXB0ZWQgSW50ZWdyaXR5IFByb3RlY3RlZCBEYXRhIA0KICogUGFja2V0IChUYWcgMTgpDQogKiANCiAqIFJGQzQ4ODAgNS4xMzogVGhlIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIEludGVncml0eSBQcm90ZWN0ZWQgRGF0YSBwYWNrZXQgaXMNCiAqIGEgdmFyaWFudCBvZiB0aGUgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBwYWNrZXQuIEl0IGlzIGEgbmV3IGZlYXR1cmUNCiAqIGNyZWF0ZWQgZm9yIE9wZW5QR1AgdGhhdCBhZGRyZXNzZXMgdGhlIHByb2JsZW0gb2YgZGV0ZWN0aW5nIGEgbW9kaWZpY2F0aW9uIHRvDQogKiBlbmNyeXB0ZWQgZGF0YS4gSXQgaXMgdXNlZCBpbiBjb21iaW5hdGlvbiB3aXRoIGEgTW9kaWZpY2F0aW9uIERldGVjdGlvbiBDb2RlDQogKiBwYWNrZXQuDQogKi8NCg0KZnVuY3Rpb24gb3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkaW50ZWdyaXR5cHJvdGVjdGVkZGF0YSgpIHsNCgl0aGlzLnRhZ1R5cGUgPSAxODsNCgl0aGlzLnZlcnNpb24gPSBudWxsOyAvLyBpbnRlZ2VyID09IDENCgl0aGlzLnBhY2tldExlbmd0aCA9IG51bGw7IC8vIGludGVnZXINCgl0aGlzLmVuY3J5cHRlZERhdGEgPSBudWxsOyAvLyBzdHJpbmcNCgl0aGlzLmRlY3J5dHBlZERhdGEgPSBudWxsOyAvLyBzdHJpbmcNCgl0aGlzLmhhc2ggPSBudWxsOyAvLyBzdHJpbmcNCgkvKioNCgkgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciB0aGUgcGFja2V0Lg0KCSAqIA0KCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDE4IHBhY2tldA0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24NCgkgKiAgICAgICAgICAgICBwb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZw0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuIExlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mDQoJICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvbg0KCSAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGludGVncml0eXByb3RlY3RlZGRhdGF9IG9iamVjdA0KCSAqICAgICAgICAgcmVwcmVzZW50YXRpb24NCgkgKi8NCglmdW5jdGlvbiByZWFkX3BhY2tldChpbnB1dCwgcG9zaXRpb24sIGxlbikgew0KCQl0aGlzLnBhY2tldExlbmd0aCA9IGxlbjsNCgkJLy8gLSBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlci4gVGhlIG9ubHkgY3VycmVudGx5IGRlZmluZWQgdmFsdWUgaXMNCgkJLy8gMS4NCgkJdGhpcy52ZXJzaW9uID0gaW5wdXRbcG9zaXRpb25dLmNoYXJDb2RlQXQoKTsNCgkJaWYgKHRoaXMudmVyc2lvbiAhPSAxKSB7DQoJCQl1dGlsDQoJCQkJCS5wcmludF9lcnJvcignb3BlbnBncC5wYWNrZXQuZW5jcnlwdGVkaW50ZWdyaXR5cHJvdGVjdGVkZGF0YS5qc1xudW5rbm93biBlbmNyeXB0ZWQgaW50ZWdyaXR5IHByb3RlY3RlZCBkYXRhIHBhY2tldCB2ZXJzaW9uOiAnDQoJCQkJCQkJKyB0aGlzLnZlcnNpb24NCgkJCQkJCQkrICIgLCBAICINCgkJCQkJCQkrIHBvc2l0aW9uDQoJCQkJCQkJKyAiaGV4OiINCgkJCQkJCQkrIHV0aWwuaGV4c3RyZHVtcChpbnB1dCkpOw0KCQkJcmV0dXJuIG51bGw7DQoJCX0NCgkJLy8gLSBFbmNyeXB0ZWQgZGF0YSwgdGhlIG91dHB1dCBvZiB0aGUgc2VsZWN0ZWQgc3ltbWV0cmljLWtleSBjaXBoZXINCgkJLy8gICBvcGVyYXRpbmcgaW4gQ2lwaGVyIEZlZWRiYWNrIG1vZGUgd2l0aCBzaGlmdCBhbW91bnQgZXF1YWwgdG8gdGhlDQoJCS8vICAgYmxvY2sgc2l6ZSBvZiB0aGUgY2lwaGVyIChDRkItbiB3aGVyZSBuIGlzIHRoZSBibG9jayBzaXplKS4NCgkJdGhpcy5lbmNyeXB0ZWREYXRhID0gaW5wdXQuc3Vic3RyaW5nKHBvc2l0aW9uICsgMSwgcG9zaXRpb24gKyAxICsgbGVuKTsNCgkJdXRpbC5wcmludF9kZWJ1Zygib3BlbnBncC5wYWNrZXQuZW5jcnlwdGVkaW50ZWdyaXR5cHJvdGVjdGVkZGF0YS5qc1xuIg0KCQkJCSsgdGhpcy50b1N0cmluZygpKTsNCgkJcmV0dXJuIHRoaXM7DQoJfQ0KDQoJLyoqDQoJICogQ3JlYXRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIFN5bS4gRW5jcnlwdGVkIEludGVncml0eSBQcm90ZWN0ZWQNCgkgKiBEYXRhIFBhY2tldCAodGFnIDE4KSAoc2VlIFJGQzQ4ODAgNS4xMykNCgkgKiANCgkgKiBAcGFyYW0ge0ludGVnZXJ9IHN5bW1ldHJpY19hbGdvcml0aG0NCgkgKiAgICAgICAgICAgIFRoZSBzZWxlY3RlZCBzeW1tZXRyaWMgZW5jcnlwdGlvbiBhbGdvcml0aG0gdG8gYmUgdXNlZA0KCSAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgVGhlIGtleSBvZiBjaXBoZXIgYmxvY2tzaXplIGxlbmd0aCB0byBiZSB1c2VkDQoJICogQHBhcmFtIHtTdHJpbmd9IGRhdGENCgkgKiAgICAgICAgICAgIFBsYWludGV4dCBkYXRhIHRvIGJlIGVuY3J5cHRlZCB3aXRoaW4gdGhlIHBhY2tldA0KCSAqIEByZXR1cm4ge1N0cmluZ30gQSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhY2tldA0KCSAqLw0KCWZ1bmN0aW9uIHdyaXRlX3BhY2tldChzeW1tZXRyaWNfYWxnb3JpdGhtLCBrZXksIGRhdGEpIHsNCg0KCQl2YXIgcHJlZml4cmFuZG9tID0gb3BlbnBncF9jcnlwdG9fZ2V0UHJlZml4UmFuZG9tKHN5bW1ldHJpY19hbGdvcml0aG0pOw0KCQl2YXIgcHJlZml4ID0gcHJlZml4cmFuZG9tDQoJCQkJKyBwcmVmaXhyYW5kb20uY2hhckF0KHByZWZpeHJhbmRvbS5sZW5ndGggLSAyKQ0KCQkJCSsgcHJlZml4cmFuZG9tLmNoYXJBdChwcmVmaXhyYW5kb20ubGVuZ3RoIC0gMSk7DQoJCXZhciB0b2hhc2ggPSBkYXRhOw0KCQl0b2hhc2ggKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweEQzKTsNCgkJdG9oYXNoICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHgxNCk7DQoJCXV0aWwucHJpbnRfZGVidWdfaGV4c3RyX2R1bXAoImRhdGEgdG8gYmUgaGFzaGVkOiINCgkJCQksIHByZWZpeCArIHRvaGFzaCk7DQoJCXRvaGFzaCArPSBzdHJfc2hhMShwcmVmaXggKyB0b2hhc2gpOw0KCQl1dGlsLnByaW50X2RlYnVnX2hleHN0cl9kdW1wKCJoYXNoOiINCgkJCQksIHRvaGFzaC5zdWJzdHJpbmcodG9oYXNoLmxlbmd0aCAtIDIwLA0KCQkJCQkJdG9oYXNoLmxlbmd0aCkpOw0KCQl2YXIgcmVzdWx0ID0gb3BlbnBncF9jcnlwdG9fc3ltbWV0cmljRW5jcnlwdChwcmVmaXhyYW5kb20sDQoJCQkJc3ltbWV0cmljX2FsZ29yaXRobSwga2V5LCB0b2hhc2gsIGZhbHNlKS5zdWJzdHJpbmcoMCwNCgkJCQlwcmVmaXgubGVuZ3RoICsgdG9oYXNoLmxlbmd0aCk7DQoJCXZhciBoZWFkZXIgPSBvcGVucGdwX3BhY2tldC53cml0ZV9wYWNrZXRfaGVhZGVyKDE4LCByZXN1bHQubGVuZ3RoICsgMSkNCgkJCQkrIFN0cmluZy5mcm9tQ2hhckNvZGUoMSk7DQoJCXRoaXMuZW5jcnlwdGVkRGF0YSA9IHJlc3VsdDsNCgkJcmV0dXJuIGhlYWRlciArIHJlc3VsdDsNCgl9DQoNCgkvKioNCgkgKiBEZWNyeXB0cyB0aGUgZW5jcnlwdGVkIGRhdGEgY29udGFpbmVkIGluIHRoaXMgb2JqZWN0IHJlYWRfcGFja2V0IG11c3QNCgkgKiBoYXZlIGJlZW4gY2FsbGVkIGJlZm9yZQ0KCSAqIA0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gc3ltbWV0cmljX2FsZ29yaXRobV90eXBlDQoJICogICAgICAgICAgICBUaGUgc2VsZWN0ZWQgc3ltbWV0cmljIGVuY3J5cHRpb24gYWxnb3JpdGhtIHRvIGJlIHVzZWQNCgkgKiBAcGFyYW0ge1N0cmluZ30ga2V5IFRoZSBrZXkgb2YgY2lwaGVyIGJsb2Nrc2l6ZSBsZW5ndGggdG8gYmUgdXNlZA0KCSAqIEByZXR1cm4ge1N0cmluZ30gVGhlIGRlY3J5cHRlZCBkYXRhIG9mIHRoaXMgcGFja2V0DQoJICovDQoJZnVuY3Rpb24gZGVjcnlwdChzeW1tZXRyaWNfYWxnb3JpdGhtX3R5cGUsIGtleSkgew0KCQl0aGlzLmRlY3J5cHRlZERhdGEgPSBvcGVucGdwX2NyeXB0b19zeW1tZXRyaWNEZWNyeXB0KA0KCQkJCXN5bW1ldHJpY19hbGdvcml0aG1fdHlwZSwga2V5LCB0aGlzLmVuY3J5cHRlZERhdGEsIGZhbHNlKTsNCgkJLy8gdGhlcmUgbXVzdCBiZSBhIG1vZGlmaWNhdGlvbiBkZXRlY3Rpb24gY29kZSBwYWNrZXQgYXMgdGhlDQoJCS8vIGxhc3QgcGFja2V0IGFuZCBldmVyeXRoaW5nIGdldHMgaGFzaGVkIGV4Y2VwdCB0aGUgaGFzaCBpdHNlbGYNCgkJdGhpcy5oYXNoID0gc3RyX3NoYTEob3BlbnBncF9jcnlwdG9fTURDU3lzdGVtQnl0ZXMoDQoJCQkJc3ltbWV0cmljX2FsZ29yaXRobV90eXBlLCBrZXksIHRoaXMuZW5jcnlwdGVkRGF0YSkNCgkJCQkrIHRoaXMuZGVjcnlwdGVkRGF0YS5zdWJzdHJpbmcoMCwNCgkJCQkJCXRoaXMuZGVjcnlwdGVkRGF0YS5sZW5ndGggLSAyMCkpOw0KCQl1dGlsLnByaW50X2RlYnVnX2hleHN0cl9kdW1wKCJjYWxjIGhhc2ggPSAiLCB0aGlzLmhhc2gpOw0KCQlpZiAodGhpcy5oYXNoID09IHRoaXMuZGVjcnlwdGVkRGF0YS5zdWJzdHJpbmcoDQoJCQkJdGhpcy5kZWNyeXB0ZWREYXRhLmxlbmd0aCAtIDIwLCB0aGlzLmRlY3J5cHRlZERhdGEubGVuZ3RoKSkNCgkJCXJldHVybiB0aGlzLmRlY3J5cHRlZERhdGE7DQoJCWVsc2UNCgkJCXV0aWwNCgkJCQkJLnByaW50X2Vycm9yKCJEZWNyeXB0aW9uIHN0b3BwZWQ6IGRpc2NvdmVyZWQgYSBtb2RpZmljYXRpb24gb2YgZW5jcnlwdGVkIGRhdGEuIik7DQoJCXJldHVybiBudWxsOw0KCX0NCg0KCWZ1bmN0aW9uIHRvU3RyaW5nKCkgew0KCSAgICB2YXIgZGF0YSA9ICcnOw0KCSAgICBpZihvcGVucGdwLmNvbmZpZy5kZWJ1ZykNCgkgICAgICAgIGRhdGEgPSAnICAgIGRhdGE6IEJ5dGVzIFsnDQoJCQkJKyB1dGlsLmhleHN0cmR1bXAodGhpcy5lbmNyeXB0ZWREYXRhKSArICddJzsNCgkgICAgDQoJCXJldHVybiAnNS4xMy4gIFN5bS4gRW5jcnlwdGVkIEludGVncml0eSBQcm90ZWN0ZWQgRGF0YSBQYWNrZXQgKFRhZyAxOClcbicNCgkJCQkrICcgICAgbGVuZ3RoOiAgJw0KCQkJCSsgdGhpcy5wYWNrZXRMZW5ndGgNCgkJCQkrICdcbicNCgkJCQkrICcgICAgdmVyc2lvbjogJw0KCQkJCSsgdGhpcy52ZXJzaW9uDQoJCQkJKyAnXG4nDQoJCQkJKyBkYXRhOw0KCX0NCg0KCXRoaXMud3JpdGVfcGFja2V0ID0gd3JpdGVfcGFja2V0Ow0KCXRoaXMucmVhZF9wYWNrZXQgPSByZWFkX3BhY2tldDsNCgl0aGlzLnRvU3RyaW5nID0gdG9TdHJpbmc7DQoJdGhpcy5kZWNyeXB0ID0gZGVjcnlwdDsNCn07DQovLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHQNCi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkgNCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcg0KLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyDQovLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4NCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsDQovLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0KLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUNCi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuDQovLyANCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUNCi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQ0KDQovKioNCiAqIEBjbGFzcw0KICogQGNsYXNzZGVzYyBQdWJsaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleSBQYWNrZXRzIChUYWcgMSkNCiAqIA0KICogUkZDNDg4MCA1LjE6IEEgUHVibGljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgcGFja2V0IGhvbGRzIHRoZSBzZXNzaW9uIGtleQ0KICogdXNlZCB0byBlbmNyeXB0IGEgbWVzc2FnZS4gWmVybyBvciBtb3JlIFB1YmxpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5DQogKiBwYWNrZXRzIGFuZC9vciBTeW1tZXRyaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleSBwYWNrZXRzIG1heSBwcmVjZWRlIGENCiAqIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgUGFja2V0LCB3aGljaCBob2xkcyBhbiBlbmNyeXB0ZWQgbWVzc2FnZS4gVGhlDQogKiBtZXNzYWdlIGlzIGVuY3J5cHRlZCB3aXRoIHRoZSBzZXNzaW9uIGtleSwgYW5kIHRoZSBzZXNzaW9uIGtleSBpcyBpdHNlbGYNCiAqIGVuY3J5cHRlZCBhbmQgc3RvcmVkIGluIHRoZSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgcGFja2V0KHMpLiBUaGUNCiAqIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgUGFja2V0IGlzIHByZWNlZGVkIGJ5IG9uZSBQdWJsaWMtS2V5IEVuY3J5cHRlZA0KICogU2Vzc2lvbiBLZXkgcGFja2V0IGZvciBlYWNoIE9wZW5QR1Aga2V5IHRvIHdoaWNoIHRoZSBtZXNzYWdlIGlzIGVuY3J5cHRlZC4NCiAqIFRoZSByZWNpcGllbnQgb2YgdGhlIG1lc3NhZ2UgZmluZHMgYSBzZXNzaW9uIGtleSB0aGF0IGlzIGVuY3J5cHRlZCB0byB0aGVpcg0KICogcHVibGljIGtleSwgZGVjcnlwdHMgdGhlIHNlc3Npb24ga2V5LCBhbmQgdGhlbiB1c2VzIHRoZSBzZXNzaW9uIGtleSB0bw0KICogZGVjcnlwdCB0aGUgbWVzc2FnZS4NCiAqLw0KZnVuY3Rpb24gb3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkc2Vzc2lvbmtleSgpIHsNCg0KCS8qKg0KCSAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgcHVibGlja2V5IGVuY3J5cHRlZCBzZXNzaW9uIGtleSBwYWNrZXQgKHRhZyAxKS4NCgkgKiANCgkgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyAxIHBhY2tldA0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBzdHJpbmcNCgkgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBMZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZg0KCSAqICAgICAgICAgICAgaW5wdXQgYXQgcG9zaXRpb24NCgkgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhfSBPYmplY3QgcmVwcmVzZW50YXRpb24NCgkgKi8NCglmdW5jdGlvbiByZWFkX3B1Yl9rZXlfcGFja2V0KGlucHV0LCBwb3NpdGlvbiwgbGVuKSB7DQoJCXRoaXMudGFnVHlwZSA9IDE7DQoJCXRoaXMucGFja2V0TGVuZ3RoID0gbGVuOw0KCQl2YXIgbXlwb3MgPSBwb3NpdGlvbjsNCgkJaWYgKGxlbiA8IDEwKSB7DQoJCQl1dGlsDQoJCQkJCS5wcmludF9lcnJvcigib3BlbnBncC5wYWNrZXQuZW5jcnlwdGVkc2Vzc2lvbmtleS5qc1xuIiArICdpbnZhbGlkIGxlbmd0aCcpOw0KCQkJcmV0dXJuIG51bGw7DQoJCX0NCg0KCQl0aGlzLnZlcnNpb24gPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoJCXRoaXMua2V5SWQgPSBuZXcgb3BlbnBncF90eXBlX2tleWlkKCk7DQoJCXRoaXMua2V5SWQucmVhZF9wYWNrZXQoaW5wdXQsIG15cG9zKTsNCgkJbXlwb3MgKz0gODsNCgkJdGhpcy5wdWJsaWNLZXlBbGdvcml0aG1Vc2VkID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KDQoJCXN3aXRjaCAodGhpcy5wdWJsaWNLZXlBbGdvcml0aG1Vc2VkKSB7DQoJCWNhc2UgMToNCgkJY2FzZSAyOiAvLyBSU0ENCgkJCXRoaXMuTVBJcyA9IG5ldyBBcnJheSgpOw0KCQkJdGhpcy5NUElzWzBdID0gbmV3IG9wZW5wZ3BfdHlwZV9tcGkoKTsNCgkJCXRoaXMuTVBJc1swXS5yZWFkKGlucHV0LCBteXBvcywgbXlwb3MgLSBwb3NpdGlvbik7DQoJCQlicmVhazsNCgkJY2FzZSAxNjogLy8gRWxnYW1hbA0KCQkJdGhpcy5NUElzID0gbmV3IEFycmF5KCk7DQoJCQl0aGlzLk1QSXNbMF0gPSBuZXcgb3BlbnBncF90eXBlX21waSgpOw0KCQkJdGhpcy5NUElzWzBdLnJlYWQoaW5wdXQsIG15cG9zLCBteXBvcyAtIHBvc2l0aW9uKTsNCgkJCW15cG9zICs9IHRoaXMuTVBJc1swXS5wYWNrZXRMZW5ndGg7DQoJCQl0aGlzLk1QSXNbMV0gPSBuZXcgb3BlbnBncF90eXBlX21waSgpOw0KCQkJdGhpcy5NUElzWzFdLnJlYWQoaW5wdXQsIG15cG9zLCBteXBvcyAtIHBvc2l0aW9uKTsNCgkJCWJyZWFrOw0KCQlkZWZhdWx0Og0KCQkJdXRpbC5wcmludF9lcnJvcigib3BlbnBncC5wYWNrZXQuZW5jcnlwdGVkc2Vzc2lvbmtleS5qc1xuIg0KCQkJCQkrICJ1bmtub3duIHB1YmxpYyBrZXkgcGFja2V0IGFsZ29yaXRobSB0eXBlICINCgkJCQkJKyB0aGlzLnB1YmxpY0tleUFsZ29yaXRobVR5cGUpOw0KCQkJYnJlYWs7DQoJCX0NCgkJcmV0dXJuIHRoaXM7DQoJfQ0KDQoJLyoqDQoJICogQ3JlYXRlIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgdGFnIDEgcGFja2V0DQoJICogDQoJICogQHBhcmFtIHtTdHJpbmd9IHB1YmxpY0tleUlkDQoJICogICAgICAgICAgICAgVGhlIHB1YmxpYyBrZXkgaWQgY29ycmVzcG9uZGluZyB0byBwdWJsaWNNUElzIGtleSBhcyBzdHJpbmcNCgkgKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGlbXX0gcHVibGljTVBJcw0KCSAqICAgICAgICAgICAgTXVsdGlwcmVjaXNpb24gaW50ZWdlciBvYmplY3RzIGRlc2NyaWJpbmcgdGhlIHB1YmxpYyBrZXkNCgkgKiBAcGFyYW0ge0ludGVnZXJ9IHB1YmFsZ28NCgkgKiAgICAgICAgICAgIFRoZSBjb3JyZXNwb25kaW5nIHB1YmxpYyBrZXkgYWxnb3JpdGhtIC8vIFNlZSBSRkM0ODgwIDkuMQ0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gc3ltbWFsZ28NCgkgKiAgICAgICAgICAgIFRoZSBzeW1tZXRyaWMgY2lwaGVyIGFsZ29yaXRobSB1c2VkIHRvIGVuY3J5cHQgdGhlIGRhdGEgDQoJICogICAgICAgICAgICB3aXRoaW4gYW4gZW5jcnlwdGVkZGF0YXBhY2tldCBvciBlbmNyeXB0ZWRpbnRlZ3JpdHktDQoJICogICAgICAgICAgICBwcm90ZWN0ZWRkYXRhcGFja2V0IA0KCSAqICAgICAgICAgICAgZm9sbG93aW5nIHRoaXMgcGFja2V0IC8vU2VlIFJGQzQ4ODAgOS4yDQoJICogQHBhcmFtIHtTdHJpbmd9IHNlc3Npb25rZXkNCgkgKiAgICAgICAgICAgIEEgc3RyaW5nIG9mIHJhbmRvbWJ5dGVzIHJlcHJlc2VudGluZyB0aGUgc2Vzc2lvbiBrZXkNCgkgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24NCgkgKi8NCglmdW5jdGlvbiB3cml0ZV9wdWJfa2V5X3BhY2tldChwdWJsaWNLZXlJZCwgcHVibGljTVBJcywgcHViYWxnbywgc3ltbWFsZ28sDQoJCQlzZXNzaW9ua2V5KSB7DQoJCXZhciByZXN1bHQgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDMpOw0KCQl2YXIgZGF0YSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoc3ltbWFsZ28pOw0KCQlkYXRhICs9IHNlc3Npb25rZXk7DQoJCXZhciBjaGVja3N1bSA9IHV0aWwuY2FsY19jaGVja3N1bShzZXNzaW9ua2V5KTsNCgkJZGF0YSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChjaGVja3N1bSA+PiA4KSAmIDB4RkYpOw0KCQlkYXRhICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGNoZWNrc3VtKSAmIDB4RkYpOw0KCQlyZXN1bHQgKz0gcHVibGljS2V5SWQ7DQoJCXJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHB1YmFsZ28pOw0KCQl2YXIgbXBpID0gbmV3IG9wZW5wZ3BfdHlwZV9tcGkoKTsNCgkJdmFyIG1waXJlc3VsdCA9IG9wZW5wZ3BfY3J5cHRvX2FzeW1ldHJpY0VuY3J5cHQocHViYWxnbywgcHVibGljTVBJcywNCgkJCQltcGkuY3JlYXRlKG9wZW5wZ3BfZW5jb2RpbmdfZW1lX3BrY3MxX2VuY29kZShkYXRhLA0KCQkJCQkJcHVibGljTVBJc1swXS5tcGlCeXRlTGVuZ3RoKSkpOw0KCQlmb3IgKCB2YXIgaSA9IDA7IGkgPCBtcGlyZXN1bHQubGVuZ3RoOyBpKyspIHsNCgkJCXJlc3VsdCArPSBtcGlyZXN1bHRbaV07DQoJCX0NCgkJcmVzdWx0ID0gb3BlbnBncF9wYWNrZXQud3JpdGVfcGFja2V0X2hlYWRlcigxLCByZXN1bHQubGVuZ3RoKSArIHJlc3VsdDsNCgkJcmV0dXJuIHJlc3VsdDsNCgl9DQoNCgkvKioNCgkgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIHN5bW1ldHJpYyBlbmNyeXB0ZWQgc2Vzc2lvbiBrZXkgcGFja2V0ICh0YWcgMykuDQoJICogDQoJICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFBheWxvYWQgb2YgYSB0YWcgMSBwYWNrZXQNCgkgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4NCgkgKiAgICAgICAgICAgIExlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mDQoJICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvbg0KCSAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGF9IE9iamVjdCByZXByZXNlbnRhdGlvbg0KCSAqLw0KCWZ1bmN0aW9uIHJlYWRfc3ltbWV0cmljX2tleV9wYWNrZXQoaW5wdXQsIHBvc2l0aW9uLCBsZW4pIHsNCgkJdGhpcy50YWdUeXBlID0gMzsNCgkJdmFyIG15cG9zID0gcG9zaXRpb247DQoJCS8vIEEgb25lLW9jdGV0IHZlcnNpb24gbnVtYmVyLiBUaGUgb25seSBjdXJyZW50bHkgZGVmaW5lZCB2ZXJzaW9uIGlzIDQuDQoJCXRoaXMudmVyc2lvbiA9IGlucHV0W215cG9zKytdOw0KDQoJCS8vIEEgb25lLW9jdGV0IG51bWJlciBkZXNjcmliaW5nIHRoZSBzeW1tZXRyaWMgYWxnb3JpdGhtIHVzZWQuDQoJCXRoaXMuc3ltbWV0cmljS2V5QWxnb3JpdGhtVXNlZCA9IGlucHV0W215cG9zKytdOw0KCQkvLyBBIHN0cmluZy10by1rZXkgKFMySykgc3BlY2lmaWVyLCBsZW5ndGggYXMgZGVmaW5lZCBhYm92ZS4NCgkJdGhpcy5zMmsgPSBuZXcgb3BlbnBncF90eXBlX3MyaygpOw0KCQl0aGlzLnMyay5yZWFkKGlucHV0LCBteXBvcyk7DQoNCgkJLy8gT3B0aW9uYWxseSwgdGhlIGVuY3J5cHRlZCBzZXNzaW9uIGtleSBpdHNlbGYsIHdoaWNoIGlzIGRlY3J5cHRlZA0KCQkvLyB3aXRoIHRoZSBzdHJpbmctdG8ta2V5IG9iamVjdC4NCgkJaWYgKChzMmsuczJrTGVuZ3RoICsgbXlwb3MpIDwgbGVuKSB7DQoJCQl0aGlzLmVuY3J5cHRlZFNlc3Npb25LZXkgPSBuZXcgQXJyYXkoKTsNCgkJCWZvciAoIHZhciBpID0gKG15cG9zIC0gcG9zaXRpb24pOyBpIDwgbGVuOyBpKyspIHsNCgkJCQl0aGlzLmVuY3J5cHRlZFNlc3Npb25LZXlbaV0gPSBpbnB1dFtteXBvcysrXTsNCgkJCX0NCgkJfQ0KCQlyZXR1cm4gdGhpczsNCgl9DQoJLyoqDQoJICogRGVjcnlwdHMgdGhlIHNlc3Npb24ga2V5IChvbmx5IGZvciBwdWJsaWMga2V5IGVuY3J5cHRlZCBzZXNzaW9uIGtleQ0KCSAqIHBhY2tldHMgKHRhZyAxKQ0KCSAqIA0KCSAqIEBwYXJhbSB7b3BlbnBncF9tc2dfbWVzc2FnZX0gbXNnDQoJICogICAgICAgICAgICBUaGUgbWVzc2FnZSBvYmplY3QgKHdpdGggbWVtYmVyIGVuY3J5cHRlZERhdGENCgkgKiBAcGFyYW0ge29wZW5wZ3BfbXNnX3ByaXZhdGVrZXl9IGtleQ0KCSAqICAgICAgICAgICAgUHJpdmF0ZSBrZXkgd2l0aCBzZWNNUElzIHVubG9ja2VkDQoJICogQHJldHVybiB7U3RyaW5nfSBUaGUgdW5lbmNyeXB0ZWQgc2Vzc2lvbiBrZXkNCgkgKi8NCglmdW5jdGlvbiBkZWNyeXB0KG1zZywga2V5KSB7DQoJCWlmICh0aGlzLnRhZ1R5cGUgPT0gMSkgew0KCQkJdmFyIHJlc3VsdCA9IG9wZW5wZ3BfY3J5cHRvX2FzeW1ldHJpY0RlY3J5cHQoDQoJCQkJCXRoaXMucHVibGljS2V5QWxnb3JpdGhtVXNlZCwga2V5LnB1YmxpY0tleS5NUElzLA0KCQkJCQlrZXkuc2VjTVBJcywgdGhpcy5NUElzKS50b01QSSgpOw0KCQkJdmFyIGNoZWNrc3VtID0gKChyZXN1bHQuY2hhckNvZGVBdChyZXN1bHQubGVuZ3RoIC0gMikgPDwgOCkgKyByZXN1bHQNCgkJCQkJLmNoYXJDb2RlQXQocmVzdWx0Lmxlbmd0aCAtIDEpKTsNCgkJCXZhciBkZWNvZGVkID0gb3BlbnBncF9lbmNvZGluZ19lbWVfcGtjczFfZGVjb2RlKHJlc3VsdC5zdWJzdHJpbmcoMiwgcmVzdWx0Lmxlbmd0aCAtIDIpLCBrZXkucHVibGljS2V5Lk1QSXNbMF0uZ2V0Qnl0ZUxlbmd0aCgpKTsNCgkJCXZhciBzZXNza2V5ID0gZGVjb2RlZC5zdWJzdHJpbmcoMSk7DQoJCQl2YXIgYWxnbyA9IGRlY29kZWQuY2hhckNvZGVBdCgwKTsNCgkJCWlmIChtc2cuZW5jcnlwdGVkRGF0YS50YWdUeXBlID09IDE4KQ0KCQkJCXJldHVybiBtc2cuZW5jcnlwdGVkRGF0YS5kZWNyeXB0KGFsZ28sIHNlc3NrZXkpOw0KCQkJZWxzZQ0KCQkJCXJldHVybiBtc2cuZW5jcnlwdGVkRGF0YS5kZWNyeXB0X3N5bShhbGdvLCBzZXNza2V5KTsNCgkJfSBlbHNlIGlmICh0aGlzLnRhZ1R5cGUgPT0gMykgew0KCQkJdXRpbA0KCQkJCQkucHJpbnRfZXJyb3IoIlN5bW1ldHJpYyBlbmNyeXB0ZWQgc2Vzc2lvbmtleSBpcyBub3Qgc3VwcG9ydGVkISIpOw0KCQkJcmV0dXJuIG51bGw7DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBDcmVhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgb2JqZWN0ICh1c2VmdWwgZm9yIGRlYnVnDQoJICogcHVycG9zZXMpDQoJICogDQoJICogQHJldHVybiB7U3RyaW5nfSBUaGUgc3RyaW5nIGNvbnRhaW5pbmcgYSBvcGVucGdwIGRlc2NyaXB0aW9uDQoJICovDQoJZnVuY3Rpb24gdG9TdHJpbmcoKSB7DQoJCWlmICh0aGlzLnRhZ1R5cGUgPT0gMSkgew0KCQkJdmFyIHJlc3VsdCA9ICc1LjEuICBQdWJsaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleSBQYWNrZXRzIChUYWcgMSlcbicNCgkJCQkJKyAnICAgIEtleUlkOiAgJw0KCQkJCQkrIHRoaXMua2V5SWQudG9TdHJpbmcoKQ0KCQkJCQkrICdcbicNCgkJCQkJKyAnICAgIGxlbmd0aDogJw0KCQkJCQkrIHRoaXMucGFja2V0TGVuZ3RoDQoJCQkJCSsgJ1xuJw0KCQkJCQkrICcgICAgdmVyc2lvbjonDQoJCQkJCSsgdGhpcy52ZXJzaW9uDQoJCQkJCSsgJ1xuJw0KCQkJCQkrICcgICAgcHViQWxnVXM6Jw0KCQkJCQkrIHRoaXMucHVibGljS2V5QWxnb3JpdGhtVXNlZCArICdcbic7DQoJCQlmb3IgKCB2YXIgaSA9IDA7IGkgPCB0aGlzLk1QSXMubGVuZ3RoOyBpKyspIHsNCgkJCQlyZXN1bHQgKz0gdGhpcy5NUElzW2ldLnRvU3RyaW5nKCk7DQoJCQl9DQoJCQlyZXR1cm4gcmVzdWx0Ow0KCQl9IGVsc2UNCgkJCXJldHVybiAnNS4zIFN5bW1ldHJpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IFBhY2tldHMgKFRhZyAzKVxuJw0KCQkJCQkrICcgICAgS2V5SWQ6ICAnICsgdGhpcy5rZXlJZC50b1N0cmluZygpICsgJ1xuJw0KCQkJCQkrICcgICAgbGVuZ3RoOiAnICsgdGhpcy5wYWNrZXRMZW5ndGggKyAnXG4nDQoJCQkJCSsgJyAgICB2ZXJzaW9uOicgKyB0aGlzLnZlcnNpb24gKyAnXG4nICsgJyAgICBzeW1LZXlBOicNCgkJCQkJKyB0aGlzLnN5bW1ldHJpY0tleUFsZ29yaXRobVVzZWQgKyAnXG4nICsgJyAgICBzMms6ICAgICcNCgkJCQkJKyB0aGlzLnMyayArICdcbic7DQoJfQ0KDQoJdGhpcy5yZWFkX3B1Yl9rZXlfcGFja2V0ID0gcmVhZF9wdWJfa2V5X3BhY2tldDsNCgl0aGlzLnJlYWRfc3ltbWV0cmljX2tleV9wYWNrZXQgPSByZWFkX3N5bW1ldHJpY19rZXlfcGFja2V0Ow0KCXRoaXMud3JpdGVfcHViX2tleV9wYWNrZXQgPSB3cml0ZV9wdWJfa2V5X3BhY2tldDsNCgl0aGlzLnRvU3RyaW5nID0gdG9TdHJpbmc7DQoJdGhpcy5kZWNyeXB0ID0gZGVjcnlwdDsNCn07DQoNCi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdA0KLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSA0KLy8gDQovLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yDQovLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXINCi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLg0KLy8gDQovLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwNCi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mDQovLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQ0KLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4NCi8vIA0KLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQ0KLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBDQoNCi8qKg0KICogQGNsYXNzDQogKiBAY2xhc3NkZXNjIFBhcmVudCBvcGVucGdwIHBhY2tldCBjbGFzcy4gT3BlcmF0aW9ucyBmb2N1cyBvbiBkZXRlcm1pbmluZyANCiAqIHBhY2tldCB0eXBlcyBhbmQgcGFja2V0IGhlYWRlci4NCiAqLw0KZnVuY3Rpb24gX29wZW5wZ3BfcGFja2V0KCkgew0KCS8qKg0KCSAqIEVuY29kZXMgYSBnaXZlbiBpbnRlZ2VyIG9mIGxlbmd0aCB0byB0aGUgb3BlbnBncCBsZW5ndGggc3BlY2lmaWVyIHRvIGENCgkgKiBzdHJpbmcNCgkgKiANCgkgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbmd0aCBUaGUgbGVuZ3RoIHRvIGVuY29kZQ0KCSAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIHdpdGggb3BlbnBncCBsZW5ndGggcmVwcmVzZW50YXRpb24NCgkgKi8NCglmdW5jdGlvbiBlbmNvZGVfbGVuZ3RoKGxlbmd0aCkgew0KCQlyZXN1bHQgPSAiIjsNCgkJaWYgKGxlbmd0aCA8IDE5Mikgew0KCQkJcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUobGVuZ3RoKTsNCgkJfSBlbHNlIGlmIChsZW5ndGggPiAxOTEgJiYgbGVuZ3RoIDwgODM4NCkgew0KCQkJLyoNCgkJCSAqIGxldCBhID0gKHRvdGFsIGRhdGEgcGFja2V0IGxlbmd0aCkgLSAxOTIgbGV0IGJjID0gdHdvIG9jdGV0DQoJCQkgKiByZXByZXNlbnRhdGlvbiBvZiBhIGxldCBkID0gYiArIDE5Mg0KCQkJICovDQoJCQlyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGxlbmd0aCAtIDE5MikgPj4gOCkgKyAxOTIpOw0KCQkJcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGxlbmd0aCAtIDE5MikgJiAweEZGKTsNCgkJfSBlbHNlIHsNCgkJCXJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDI1NSk7DQoJCQlyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgobGVuZ3RoID4+IDI0KSAmIDB4RkYpOw0KCQkJcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGxlbmd0aCA+PiAxNikgJiAweEZGKTsNCgkJCXJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChsZW5ndGggPj4gOCkgJiAweEZGKTsNCgkJCXJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGxlbmd0aCAmIDB4RkYpOw0KCQl9DQoJCXJldHVybiByZXN1bHQ7DQoJfQ0KCXRoaXMuZW5jb2RlX2xlbmd0aCA9IGVuY29kZV9sZW5ndGg7DQoNCgkvKioNCgkgKiBXcml0ZXMgYSBwYWNrZXQgaGVhZGVyIHZlcnNpb24gNCB3aXRoIHRoZSBnaXZlbiB0YWdfdHlwZSBhbmQgbGVuZ3RoIHRvIGENCgkgKiBzdHJpbmcNCgkgKiANCgkgKiBAcGFyYW0ge0ludGVnZXJ9IHRhZ190eXBlIFRhZyB0eXBlDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggTGVuZ3RoIG9mIHRoZSBwYXlsb2FkDQoJICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmcgb2YgdGhlIGhlYWRlcg0KCSAqLw0KCWZ1bmN0aW9uIHdyaXRlX3BhY2tldF9oZWFkZXIodGFnX3R5cGUsIGxlbmd0aCkgew0KCQkvKiB3ZSdyZSBvbmx5IGdlbmVyYXRpbmcgdjQgcGFja2V0IGhlYWRlcnMgaGVyZSAqLw0KCQl2YXIgcmVzdWx0ID0gIiI7DQoJCXJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4QzAgfCB0YWdfdHlwZSk7DQoJCXJlc3VsdCArPSBlbmNvZGVfbGVuZ3RoKGxlbmd0aCk7DQoJCXJldHVybiByZXN1bHQ7DQoJfQ0KDQoJLyoqDQoJICogV3JpdGVzIGEgcGFja2V0IGhlYWRlciBWZXJzaW9uIDMgd2l0aCB0aGUgZ2l2ZW4gdGFnX3R5cGUgYW5kIGxlbmd0aCB0byBhDQoJICogc3RyaW5nDQoJICogDQoJICogQHBhcmFtIHtJbnRlZ2VyfSB0YWdfdHlwZSBUYWcgdHlwZQ0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuZ3RoIExlbmd0aCBvZiB0aGUgcGF5bG9hZA0KCSAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIG9mIHRoZSBoZWFkZXINCgkgKi8NCglmdW5jdGlvbiB3cml0ZV9vbGRfcGFja2V0X2hlYWRlcih0YWdfdHlwZSwgbGVuZ3RoKSB7DQoJCXZhciByZXN1bHQgPSAiIjsNCgkJaWYgKGxlbmd0aCA8IDI1Nikgew0KCQkJcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHg4MCB8ICh0YWdfdHlwZSA8PCAyKSk7DQoJCQlyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShsZW5ndGgpOw0KCQl9IGVsc2UgaWYgKGxlbmd0aCA8IDY1NTM2KSB7DQoJCQlyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDgwIHwgKHRhZ190eXBlIDw8IDIpIHwgMSk7DQoJCQlyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShsZW5ndGggPj4gOCk7DQoJCQlyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShsZW5ndGggJiAweEZGKTsNCgkJfSBlbHNlIHsNCgkJCXJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ODAgfCAodGFnX3R5cGUgPDwgMikgfCAyKTsNCgkJCXJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChsZW5ndGggPj4gMjQpICYgMHhGRik7DQoJCQlyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgobGVuZ3RoID4+IDE2KSAmIDB4RkYpOw0KCQkJcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGxlbmd0aCA+PiA4KSAmIDB4RkYpOw0KCQkJcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUobGVuZ3RoICYgMHhGRik7DQoJCX0NCgkJcmV0dXJuIHJlc3VsdDsNCgl9DQoJdGhpcy53cml0ZV9vbGRfcGFja2V0X2hlYWRlciA9IHdyaXRlX29sZF9wYWNrZXRfaGVhZGVyOw0KCXRoaXMud3JpdGVfcGFja2V0X2hlYWRlciA9IHdyaXRlX3BhY2tldF9oZWFkZXI7DQoJLyoqDQoJICogR2VuZXJpYyBzdGF0aWMgUGFja2V0IFBhcnNlciBmdW5jdGlvbg0KCSAqIA0KCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBJbnB1dCBzdHJlYW0gYXMgc3RyaW5nDQoJICogQHBhcmFtIHtpbnRlZ2VyfSBwb3NpdGlvbiBQb3NpdGlvbiB0byBzdGFydCBwYXJzaW5nDQoJICogQHBhcmFtIHtpbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBpbnB1dCBmcm9tIHBvc2l0aW9uIG9uDQoJICogQHJldHVybiB7T2JqZWN0fSBSZXR1cm5zIGEgcGFyc2VkIG9wZW5wZ3BfcGFja2V0DQoJICovDQoJZnVuY3Rpb24gcmVhZF9wYWNrZXQoaW5wdXQsIHBvc2l0aW9uLCBsZW4pIHsNCgkJLy8gc29tZSBzYW5pdHkgY2hlY2tzDQoJCWlmIChpbnB1dCA9PSBudWxsIHx8IGlucHV0Lmxlbmd0aCA8PSBwb3NpdGlvbg0KCQkJCXx8IGlucHV0LnN1YnN0cmluZyhwb3NpdGlvbikubGVuZ3RoIDwgMg0KCQkJCXx8IChpbnB1dFtwb3NpdGlvbl0uY2hhckNvZGVBdCgpICYgMHg4MCkgPT0gMCkgew0KCQkJdXRpbA0KCQkJCQkucHJpbnRfZXJyb3IoIkVycm9yIGR1cmluZyBwYXJzaW5nLiBUaGlzIG1lc3NhZ2UgLyBrZXkgaXMgcHJvYmFibHkgbm90IGNvbnRhaW5pbmcgYSB2YWxpZCBPcGVuUEdQIGZvcm1hdC4iKTsNCgkJCXJldHVybiBudWxsOw0KCQl9DQoJCXZhciBteXBvcyA9IHBvc2l0aW9uOw0KCQl2YXIgdGFnID0gLTE7DQoJCXZhciBmb3JtYXQgPSAtMTsNCg0KCQlmb3JtYXQgPSAwOyAvLyAwID0gb2xkIGZvcm1hdDsgMSA9IG5ldyBmb3JtYXQNCgkJaWYgKChpbnB1dFtteXBvc10uY2hhckNvZGVBdCgpICYgMHg0MCkgIT0gMCkgew0KCQkJZm9ybWF0ID0gMTsNCgkJfQ0KDQoJCXZhciBwYWNrZXRfbGVuZ3RoX3R5cGU7DQoJCWlmIChmb3JtYXQpIHsNCgkJCS8vIG5ldyBmb3JtYXQgaGVhZGVyDQoJCQl0YWcgPSBpbnB1dFtteXBvc10uY2hhckNvZGVBdCgpICYgMHgzRjsgLy8gYml0IDUtMA0KCQl9IGVsc2Ugew0KCQkJLy8gb2xkIGZvcm1hdCBoZWFkZXINCgkJCXRhZyA9IChpbnB1dFtteXBvc10uY2hhckNvZGVBdCgpICYgMHgzRikgPj4gMjsgLy8gYml0IDUtMg0KCQkJcGFja2V0X2xlbmd0aF90eXBlID0gaW5wdXRbbXlwb3NdLmNoYXJDb2RlQXQoKSAmIDB4MDM7IC8vIGJpdCAxLTANCgkJfQ0KDQoJCS8vIGhlYWRlciBvY3RldCBwYXJzaW5nIGRvbmUNCgkJbXlwb3MrKzsNCg0KCQkvLyBwYXJzZWQgbGVuZ3RoIGZyb20gbGVuZ3RoIGZpZWxkDQoJCXZhciBib2R5ZGF0YSA9IG51bGw7DQoNCgkJLy8gdXNlZCBmb3IgcGFydGlhbCBib2R5IGxlbmd0aHMNCgkJdmFyIHJlYWxfcGFja2V0X2xlbmd0aCA9IC0xOw0KCQlpZiAoIWZvcm1hdCkgew0KCQkJLy8gNC4yLjEuIE9sZCBGb3JtYXQgUGFja2V0IExlbmd0aHMNCgkJCXN3aXRjaCAocGFja2V0X2xlbmd0aF90eXBlKSB7DQoJCQljYXNlIDA6IC8vIFRoZSBwYWNrZXQgaGFzIGEgb25lLW9jdGV0IGxlbmd0aC4gVGhlIGhlYWRlciBpcyAyIG9jdGV0cw0KCQkJCS8vIGxvbmcuDQoJCQkJcGFja2V0X2xlbmd0aCA9IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJCQlicmVhazsNCgkJCWNhc2UgMTogLy8gVGhlIHBhY2tldCBoYXMgYSB0d28tb2N0ZXQgbGVuZ3RoLiBUaGUgaGVhZGVyIGlzIDMgb2N0ZXRzDQoJCQkJLy8gbG9uZy4NCgkJCQlwYWNrZXRfbGVuZ3RoID0gKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCA4KQ0KCQkJCQkJfCBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoJCQkJYnJlYWs7DQoJCQljYXNlIDI6IC8vIFRoZSBwYWNrZXQgaGFzIGEgZm91ci1vY3RldCBsZW5ndGguIFRoZSBoZWFkZXIgaXMgNQ0KCQkJCS8vIG9jdGV0cyBsb25nLg0KCQkJCXBhY2tldF9sZW5ndGggPSAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDI0KQ0KCQkJCQkJfCAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDE2KQ0KCQkJCQkJfCAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDgpDQoJCQkJCQl8IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJCQlicmVhazsNCgkJCWRlZmF1bHQ6DQoJCQkJLy8gMyAtIFRoZSBwYWNrZXQgaXMgb2YgaW5kZXRlcm1pbmF0ZSBsZW5ndGguIFRoZSBoZWFkZXIgaXMgMQ0KCQkJCS8vIG9jdGV0IGxvbmcsIGFuZCB0aGUgaW1wbGVtZW50YXRpb24gbXVzdCBkZXRlcm1pbmUgaG93IGxvbmcNCgkJCQkvLyB0aGUgcGFja2V0IGlzLiBJZiB0aGUgcGFja2V0IGlzIGluIGEgZmlsZSwgdGhpcyBtZWFucyB0aGF0DQoJCQkJLy8gdGhlIHBhY2tldCBleHRlbmRzIHVudGlsIHRoZSBlbmQgb2YgdGhlIGZpbGUuIEluIGdlbmVyYWwsIA0KCQkJCS8vIGFuIGltcGxlbWVudGF0aW9uIFNIT1VMRCBOT1QgdXNlIGluZGV0ZXJtaW5hdGUtbGVuZ3RoIA0KCQkJCS8vIHBhY2tldHMgZXhjZXB0IHdoZXJlIHRoZSBlbmQgb2YgdGhlIGRhdGEgd2lsbCBiZSBjbGVhciANCgkJCQkvLyBmcm9tIHRoZSBjb250ZXh0LCBhbmQgZXZlbiB0aGVuIGl0IGlzIGJldHRlciB0byB1c2UgYSANCgkJCQkvLyBkZWZpbml0ZSBsZW5ndGgsIG9yIGEgbmV3IGZvcm1hdCBoZWFkZXIuIFRoZSBuZXcgZm9ybWF0IA0KCQkJCS8vIGhlYWRlcnMgZGVzY3JpYmVkIGJlbG93IGhhdmUgYSBtZWNoYW5pc20gZm9yIHByZWNpc2VseQ0KCQkJCS8vIGVuY29kaW5nIGRhdGEgb2YgaW5kZXRlcm1pbmF0ZSBsZW5ndGguDQoJCQkJcGFja2V0X2xlbmd0aCA9IGxlbjsNCgkJCQlicmVhazsNCgkJCX0NCg0KCQl9IGVsc2UgLy8gNC4yLjIuIE5ldyBGb3JtYXQgUGFja2V0IExlbmd0aHMNCgkJew0KDQoJCQkvLyA0LjIuMi4xLiBPbmUtT2N0ZXQgTGVuZ3Rocw0KCQkJaWYgKGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgPCAxOTIpIHsNCgkJCQlwYWNrZXRfbGVuZ3RoID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KCQkJCXV0aWwucHJpbnRfZGVidWcoIjEgYnl0ZSBsZW5ndGg6IiArIHBhY2tldF9sZW5ndGgpOw0KCQkJCS8vIDQuMi4yLjIuIFR3by1PY3RldCBMZW5ndGhzDQoJCQl9IGVsc2UgaWYgKGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgPj0gMTkyDQoJCQkJCSYmIGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgPCAyMjQpIHsNCgkJCQlwYWNrZXRfbGVuZ3RoID0gKChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgLSAxOTIpIDw8IDgpDQoJCQkJCQkrIChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkpICsgMTkyOw0KCQkJCXV0aWwucHJpbnRfZGVidWcoIjIgYnl0ZSBsZW5ndGg6IiArIHBhY2tldF9sZW5ndGgpOw0KCQkJCS8vIDQuMi4yLjQuIFBhcnRpYWwgQm9keSBMZW5ndGhzDQoJCQl9IGVsc2UgaWYgKGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgPiAyMjMNCgkJCQkJJiYgaW5wdXRbbXlwb3NdLmNoYXJDb2RlQXQoKSA8IDI1NSkgew0KCQkJCXBhY2tldF9sZW5ndGggPSAxIDw8IChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgJiAweDFGKTsNCgkJCQl1dGlsLnByaW50X2RlYnVnKCI0IGJ5dGUgbGVuZ3RoOiIgKyBwYWNrZXRfbGVuZ3RoKTsNCgkJCQkvLyBFRUVLLCB3ZSdyZSByZWFkaW5nIHRoZSBmdWxsIGRhdGEgaGVyZS4uLg0KCQkJCXZhciBteXBvczIgPSBteXBvcyArIHBhY2tldF9sZW5ndGg7DQoJCQkJYm9keWRhdGEgPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MsIG15cG9zICsgcGFja2V0X2xlbmd0aCk7DQoJCQkJd2hpbGUgKHRydWUpIHsNCgkJCQkJaWYgKGlucHV0W215cG9zMl0uY2hhckNvZGVBdCgpIDwgMTkyKSB7DQoJCQkJCQl2YXIgdG1wbGVuID0gaW5wdXRbbXlwb3MyKytdLmNoYXJDb2RlQXQoKTsNCgkJCQkJCXBhY2tldF9sZW5ndGggKz0gdG1wbGVuOw0KCQkJCQkJYm9keWRhdGEgKz0gaW5wdXQuc3Vic3RyaW5nKG15cG9zMiwgbXlwb3MyICsgdG1wbGVuKTsNCgkJCQkJCW15cG9zMiArPSB0bXBsZW47DQoJCQkJCQlicmVhazsNCgkJCQkJfSBlbHNlIGlmIChpbnB1dFtteXBvczJdLmNoYXJDb2RlQXQoKSA+PSAxOTINCgkJCQkJCQkmJiBpbnB1dFtteXBvczJdLmNoYXJDb2RlQXQoKSA8IDIyNCkgew0KCQkJCQkJdmFyIHRtcGxlbiA9ICgoaW5wdXRbbXlwb3MyKytdLmNoYXJDb2RlQXQoKSAtIDE5MikgPDwgOCkNCgkJCQkJCQkJKyAoaW5wdXRbbXlwb3MyKytdLmNoYXJDb2RlQXQoKSkgKyAxOTI7DQoJCQkJCQlwYWNrZXRfbGVuZ3RoICs9IHRtcGxlbjsNCgkJCQkJCWJvZHlkYXRhICs9IGlucHV0LnN1YnN0cmluZyhteXBvczIsIG15cG9zMiArIHRtcGxlbik7DQoJCQkJCQlteXBvczIgKz0gdG1wbGVuOw0KCQkJCQkJYnJlYWs7DQoJCQkJCX0gZWxzZSBpZiAoaW5wdXRbbXlwb3MyXS5jaGFyQ29kZUF0KCkgPiAyMjMNCgkJCQkJCQkmJiBpbnB1dFtteXBvczJdLmNoYXJDb2RlQXQoKSA8IDI1NSkgew0KCQkJCQkJdmFyIHRtcGxlbiA9IDEgPDwgKGlucHV0W215cG9zMisrXS5jaGFyQ29kZUF0KCkgJiAweDFGKTsNCgkJCQkJCXBhY2tldF9sZW5ndGggKz0gdG1wbGVuOw0KCQkJCQkJYm9keWRhdGEgKz0gaW5wdXQuc3Vic3RyaW5nKG15cG9zMiwgbXlwb3MyICsgdG1wbGVuKTsNCgkJCQkJCW15cG9zMiArPSB0bXBsZW47DQoJCQkJCX0gZWxzZSB7DQoJCQkJCQlteXBvczIrKzsNCgkJCQkJCXZhciB0bXBsZW4gPSAoaW5wdXRbbXlwb3MyKytdLmNoYXJDb2RlQXQoKSA8PCAyNCkNCgkJCQkJCQkJfCAoaW5wdXRbbXlwb3MyKytdLmNoYXJDb2RlQXQoKSA8PCAxNikNCgkJCQkJCQkJfCAoaW5wdXRbbXlwb3MyKytdLmNoYXJDb2RlQXQoKSA8PCA4KQ0KCQkJCQkJCQl8IGlucHV0W215cG9zMisrXS5jaGFyQ29kZUF0KCk7DQoJCQkJCQlib2R5ZGF0YSArPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MyLCBteXBvczIgKyB0bXBsZW4pOw0KCQkJCQkJcGFja2V0X2xlbmd0aCArPSB0bXBsZW47DQoJCQkJCQlteXBvczIgKz0gdG1wbGVuOw0KCQkJCQkJYnJlYWs7DQoJCQkJCX0NCgkJCQl9DQoJCQkJcmVhbF9wYWNrZXRfbGVuZ3RoID0gbXlwb3MyOw0KCQkJCS8vIDQuMi4yLjMuIEZpdmUtT2N0ZXQgTGVuZ3Rocw0KCQkJfSBlbHNlIHsNCgkJCQlteXBvcysrOw0KCQkJCXBhY2tldF9sZW5ndGggPSAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDI0KQ0KCQkJCQkJfCAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDE2KQ0KCQkJCQkJfCAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDgpDQoJCQkJCQl8IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJCX0NCgkJfQ0KDQoJCS8vIGlmIHRoZXJlIHdhcydudCBhIHBhcnRpYWwgYm9keSBsZW5ndGg6IHVzZSB0aGUgc3BlY2lmaWVkDQoJCS8vIHBhY2tldF9sZW5ndGgNCgkJaWYgKHJlYWxfcGFja2V0X2xlbmd0aCA9PSAtMSkgew0KCQkJcmVhbF9wYWNrZXRfbGVuZ3RoID0gcGFja2V0X2xlbmd0aDsNCgkJfQ0KDQoJCWlmIChib2R5ZGF0YSA9PSBudWxsKSB7DQoJCQlib2R5ZGF0YSA9IGlucHV0LnN1YnN0cmluZyhteXBvcywgbXlwb3MgKyByZWFsX3BhY2tldF9sZW5ndGgpOw0KCQl9DQoNCgkJLy8gYWxlcnQoJ3RhZyB0eXBlOiAnK3RoaXMudGFnKycgbGVuZ3RoOiAnK3BhY2tldF9sZW5ndGgpOw0KCQl2YXIgdmVyc2lvbiA9IDE7IC8vIChvbGQgZm9ybWF0OyAyPSBuZXcgZm9ybWF0KQ0KCQkvLyBpZiAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpID4gMTUpDQoJCS8vIHZlcnNpb24gPSAyOw0KDQoJCXN3aXRjaCAodGFnKSB7DQoJCWNhc2UgMDogLy8gUmVzZXJ2ZWQgLSBhIHBhY2tldCB0YWcgTVVTVCBOT1QgaGF2ZSB0aGlzIHZhbHVlDQoJCQlicmVhazsNCgkJY2FzZSAxOiAvLyBQdWJsaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleSBQYWNrZXQNCgkJCXZhciByZXN1bHQgPSBuZXcgb3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkc2Vzc2lvbmtleSgpOw0KCQkJaWYgKHJlc3VsdC5yZWFkX3B1Yl9rZXlfcGFja2V0KGJvZHlkYXRhLCAwLCBwYWNrZXRfbGVuZ3RoKSAhPSBudWxsKSB7DQoJCQkJcmVzdWx0LmhlYWRlckxlbmd0aCA9IG15cG9zIC0gcG9zaXRpb247DQoJCQkJcmVzdWx0LnBhY2tldExlbmd0aCA9IHJlYWxfcGFja2V0X2xlbmd0aDsNCgkJCQlyZXR1cm4gcmVzdWx0Ow0KCQkJfQ0KCQkJYnJlYWs7DQoJCWNhc2UgMjogLy8gU2lnbmF0dXJlIFBhY2tldA0KCQkJdmFyIHJlc3VsdCA9IG5ldyBvcGVucGdwX3BhY2tldF9zaWduYXR1cmUoKTsNCgkJCWlmIChyZXN1bHQucmVhZF9wYWNrZXQoYm9keWRhdGEsIDAsIHBhY2tldF9sZW5ndGgpICE9IG51bGwpIHsNCgkJCQlyZXN1bHQuaGVhZGVyTGVuZ3RoID0gbXlwb3MgLSBwb3NpdGlvbjsNCgkJCQlyZXN1bHQucGFja2V0TGVuZ3RoID0gcmVhbF9wYWNrZXRfbGVuZ3RoOw0KCQkJCXJldHVybiByZXN1bHQ7DQoJCQl9DQoJCQlicmVhazsNCgkJY2FzZSAzOiAvLyBTeW1tZXRyaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleSBQYWNrZXQNCgkJCXZhciByZXN1bHQgPSBuZXcgb3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkc2Vzc2lvbmtleSgpOw0KCQkJaWYgKHJlc3VsdC5yZWFkX3N5bW1ldHJpY19rZXlfcGFja2V0KGJvZHlkYXRhLCAwLCBwYWNrZXRfbGVuZ3RoKSAhPSBudWxsKSB7DQoJCQkJcmVzdWx0LmhlYWRlckxlbmd0aCA9IG15cG9zIC0gcG9zaXRpb247DQoJCQkJcmVzdWx0LnBhY2tldExlbmd0aCA9IHJlYWxfcGFja2V0X2xlbmd0aDsNCgkJCQlyZXR1cm4gcmVzdWx0Ow0KCQkJfQ0KCQkJYnJlYWs7DQoJCWNhc2UgNDogLy8gT25lLVBhc3MgU2lnbmF0dXJlIFBhY2tldA0KCQkJdmFyIHJlc3VsdCA9IG5ldyBvcGVucGdwX3BhY2tldF9vbmVwYXNzc2lnbmF0dXJlKCk7DQoJCQlpZiAocmVzdWx0LnJlYWRfcGFja2V0KGJvZHlkYXRhLCAwLCBwYWNrZXRfbGVuZ3RoKSkgew0KCQkJCXJlc3VsdC5oZWFkZXJMZW5ndGggPSBteXBvcyAtIHBvc2l0aW9uOw0KCQkJCXJlc3VsdC5wYWNrZXRMZW5ndGggPSByZWFsX3BhY2tldF9sZW5ndGg7DQoJCQkJcmV0dXJuIHJlc3VsdDsNCgkJCX0NCgkJCWJyZWFrOw0KCQljYXNlIDU6IC8vIFNlY3JldC1LZXkgUGFja2V0DQoJCQl2YXIgcmVzdWx0ID0gbmV3IG9wZW5wZ3BfcGFja2V0X2tleW1hdGVyaWFsKCk7DQoJCQlyZXN1bHQuaGVhZGVyID0gaW5wdXQuc3Vic3RyaW5nKHBvc2l0aW9uLCBteXBvcyk7DQoJCQlpZiAocmVzdWx0LnJlYWRfdGFnNShib2R5ZGF0YSwgMCwgcGFja2V0X2xlbmd0aCkgIT0gbnVsbCkgew0KCQkJCXJlc3VsdC5oZWFkZXJMZW5ndGggPSBteXBvcyAtIHBvc2l0aW9uOw0KCQkJCXJlc3VsdC5wYWNrZXRMZW5ndGggPSByZWFsX3BhY2tldF9sZW5ndGg7DQoJCQkJcmV0dXJuIHJlc3VsdDsNCgkJCX0NCgkJCWJyZWFrOw0KCQljYXNlIDY6IC8vIFB1YmxpYy1LZXkgUGFja2V0DQoJCQl2YXIgcmVzdWx0ID0gbmV3IG9wZW5wZ3BfcGFja2V0X2tleW1hdGVyaWFsKCk7DQoJCQlyZXN1bHQuaGVhZGVyID0gaW5wdXQuc3Vic3RyaW5nKHBvc2l0aW9uLCBteXBvcyk7DQoJCQlpZiAocmVzdWx0LnJlYWRfdGFnNihib2R5ZGF0YSwgMCwgcGFja2V0X2xlbmd0aCkgIT0gbnVsbCkgew0KCQkJCXJlc3VsdC5oZWFkZXJMZW5ndGggPSBteXBvcyAtIHBvc2l0aW9uOw0KCQkJCXJlc3VsdC5wYWNrZXRMZW5ndGggPSByZWFsX3BhY2tldF9sZW5ndGg7DQoJCQkJcmV0dXJuIHJlc3VsdDsNCgkJCX0NCgkJCWJyZWFrOw0KCQljYXNlIDc6IC8vIFNlY3JldC1TdWJrZXkgUGFja2V0DQoJCQl2YXIgcmVzdWx0ID0gbmV3IG9wZW5wZ3BfcGFja2V0X2tleW1hdGVyaWFsKCk7DQoJCQlpZiAocmVzdWx0LnJlYWRfdGFnNyhib2R5ZGF0YSwgMCwgcGFja2V0X2xlbmd0aCkgIT0gbnVsbCkgew0KCQkJCXJlc3VsdC5oZWFkZXJMZW5ndGggPSBteXBvcyAtIHBvc2l0aW9uOw0KCQkJCXJlc3VsdC5wYWNrZXRMZW5ndGggPSByZWFsX3BhY2tldF9sZW5ndGg7DQoJCQkJcmV0dXJuIHJlc3VsdDsNCgkJCX0NCgkJCWJyZWFrOw0KCQljYXNlIDg6IC8vIENvbXByZXNzZWQgRGF0YSBQYWNrZXQNCgkJCXZhciByZXN1bHQgPSBuZXcgb3BlbnBncF9wYWNrZXRfY29tcHJlc3NlZCgpOw0KCQkJaWYgKHJlc3VsdC5yZWFkX3BhY2tldChib2R5ZGF0YSwgMCwgcGFja2V0X2xlbmd0aCkgIT0gbnVsbCkgew0KCQkJCXJlc3VsdC5oZWFkZXJMZW5ndGggPSBteXBvcyAtIHBvc2l0aW9uOw0KCQkJCXJlc3VsdC5wYWNrZXRMZW5ndGggPSByZWFsX3BhY2tldF9sZW5ndGg7DQoJCQkJcmV0dXJuIHJlc3VsdDsNCgkJCX0NCgkJCWJyZWFrOw0KCQljYXNlIDk6IC8vIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgUGFja2V0DQoJCQl2YXIgcmVzdWx0ID0gbmV3IG9wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGEoKTsNCgkJCWlmIChyZXN1bHQucmVhZF9wYWNrZXQoYm9keWRhdGEsIDAsIHBhY2tldF9sZW5ndGgpICE9IG51bGwpIHsNCgkJCQlyZXN1bHQuaGVhZGVyTGVuZ3RoID0gbXlwb3MgLSBwb3NpdGlvbjsNCgkJCQlyZXN1bHQucGFja2V0TGVuZ3RoID0gcmVhbF9wYWNrZXRfbGVuZ3RoOw0KCQkJCXJldHVybiByZXN1bHQ7DQoJCQl9DQoJCQlicmVhazsNCgkJY2FzZSAxMDogLy8gTWFya2VyIFBhY2tldCA9IFBHUCAoMHg1MCwgMHg0NywgMHg1MCkNCgkJCXZhciByZXN1bHQgPSBuZXcgb3BlbnBncF9wYWNrZXRfbWFya2VyKCk7DQoJCQlpZiAocmVzdWx0LnJlYWRfcGFja2V0KGJvZHlkYXRhLCAwLCBwYWNrZXRfbGVuZ3RoKSAhPSBudWxsKSB7DQoJCQkJcmVzdWx0LmhlYWRlckxlbmd0aCA9IG15cG9zIC0gcG9zaXRpb247DQoJCQkJcmVzdWx0LnBhY2tldExlbmd0aCA9IHJlYWxfcGFja2V0X2xlbmd0aDsNCgkJCQlyZXR1cm4gcmVzdWx0Ow0KCQkJfQ0KCQkJYnJlYWs7DQoJCWNhc2UgMTE6IC8vIExpdGVyYWwgRGF0YSBQYWNrZXQNCgkJCXZhciByZXN1bHQgPSBuZXcgb3BlbnBncF9wYWNrZXRfbGl0ZXJhbGRhdGEoKTsNCgkJCWlmIChyZXN1bHQucmVhZF9wYWNrZXQoYm9keWRhdGEsIDAsIHBhY2tldF9sZW5ndGgpICE9IG51bGwpIHsNCgkJCQlyZXN1bHQuaGVhZGVyTGVuZ3RoID0gbXlwb3MgLSBwb3NpdGlvbjsNCgkJCQlyZXN1bHQuaGVhZGVyID0gaW5wdXQuc3Vic3RyaW5nKHBvc2l0aW9uLCBteXBvcyk7DQoJCQkJcmVzdWx0LnBhY2tldExlbmd0aCA9IHJlYWxfcGFja2V0X2xlbmd0aDsNCgkJCQlyZXR1cm4gcmVzdWx0Ow0KCQkJfQ0KCQkJYnJlYWs7DQoJCWNhc2UgMTI6IC8vIFRydXN0IFBhY2tldA0KCQkJLy8gVE9ETzogdG8gYmUgaW1wbGVtZW50ZWQNCgkJCWJyZWFrOw0KCQljYXNlIDEzOiAvLyBVc2VyIElEIFBhY2tldA0KCQkJdmFyIHJlc3VsdCA9IG5ldyBvcGVucGdwX3BhY2tldF91c2VyaWQoKTsNCgkJCWlmIChyZXN1bHQucmVhZF9wYWNrZXQoYm9keWRhdGEsIDAsIHBhY2tldF9sZW5ndGgpICE9IG51bGwpIHsNCgkJCQlyZXN1bHQuaGVhZGVyTGVuZ3RoID0gbXlwb3MgLSBwb3NpdGlvbjsNCgkJCQlyZXN1bHQucGFja2V0TGVuZ3RoID0gcmVhbF9wYWNrZXRfbGVuZ3RoOw0KCQkJCXJldHVybiByZXN1bHQ7DQoJCQl9DQoJCQlicmVhazsNCgkJY2FzZSAxNDogLy8gUHVibGljLVN1YmtleSBQYWNrZXQNCgkJCXZhciByZXN1bHQgPSBuZXcgb3BlbnBncF9wYWNrZXRfa2V5bWF0ZXJpYWwoKTsNCgkJCXJlc3VsdC5oZWFkZXIgPSBpbnB1dC5zdWJzdHJpbmcocG9zaXRpb24sIG15cG9zKTsNCgkJCWlmIChyZXN1bHQucmVhZF90YWcxNChib2R5ZGF0YSwgMCwgcGFja2V0X2xlbmd0aCkgIT0gbnVsbCkgew0KCQkJCXJlc3VsdC5oZWFkZXJMZW5ndGggPSBteXBvcyAtIHBvc2l0aW9uOw0KCQkJCXJlc3VsdC5wYWNrZXRMZW5ndGggPSByZWFsX3BhY2tldF9sZW5ndGg7DQoJCQkJcmV0dXJuIHJlc3VsdDsNCgkJCX0NCgkJCWJyZWFrOw0KCQljYXNlIDE3OiAvLyBVc2VyIEF0dHJpYnV0ZSBQYWNrZXQNCgkJCXZhciByZXN1bHQgPSBuZXcgb3BlbnBncF9wYWNrZXRfdXNlcmF0dHJpYnV0ZSgpOw0KCQkJaWYgKHJlc3VsdC5yZWFkX3BhY2tldChib2R5ZGF0YSwgMCwgcGFja2V0X2xlbmd0aCkgIT0gbnVsbCkgew0KCQkJCXJlc3VsdC5oZWFkZXJMZW5ndGggPSBteXBvcyAtIHBvc2l0aW9uOw0KCQkJCXJlc3VsdC5wYWNrZXRMZW5ndGggPSByZWFsX3BhY2tldF9sZW5ndGg7DQoJCQkJcmV0dXJuIHJlc3VsdDsNCgkJCX0NCgkJCWJyZWFrOw0KCQljYXNlIDE4OiAvLyBTeW0uIEVuY3J5cHRlZCBhbmQgSW50ZWdyaXR5IFByb3RlY3RlZCBEYXRhIFBhY2tldA0KCQkJdmFyIHJlc3VsdCA9IG5ldyBvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRpbnRlZ3JpdHlwcm90ZWN0ZWRkYXRhKCk7DQoJCQlpZiAocmVzdWx0LnJlYWRfcGFja2V0KGJvZHlkYXRhLCAwLCBwYWNrZXRfbGVuZ3RoKSAhPSBudWxsKSB7DQoJCQkJcmVzdWx0LmhlYWRlckxlbmd0aCA9IG15cG9zIC0gcG9zaXRpb247DQoJCQkJcmVzdWx0LnBhY2tldExlbmd0aCA9IHJlYWxfcGFja2V0X2xlbmd0aDsNCgkJCQlyZXR1cm4gcmVzdWx0Ow0KCQkJfQ0KCQkJYnJlYWs7DQoJCWNhc2UgMTk6IC8vIE1vZGlmaWNhdGlvbiBEZXRlY3Rpb24gQ29kZSBQYWNrZXQNCgkJCXZhciByZXN1bHQgPSBuZXcgb3BlbnBncF9wYWNrZXRfbW9kaWZpY2F0aW9uZGV0ZWN0aW9uY29kZSgpOw0KCQkJaWYgKHJlc3VsdC5yZWFkX3BhY2tldChib2R5ZGF0YSwgMCwgcGFja2V0X2xlbmd0aCkgIT0gbnVsbCkgew0KCQkJCXJlc3VsdC5oZWFkZXJMZW5ndGggPSBteXBvcyAtIHBvc2l0aW9uOw0KCQkJCXJlc3VsdC5wYWNrZXRMZW5ndGggPSByZWFsX3BhY2tldF9sZW5ndGg7DQoJCQkJcmV0dXJuIHJlc3VsdDsNCgkJCX0NCgkJCWJyZWFrOw0KCQlkZWZhdWx0Og0KCQkJdXRpbC5wcmludF9lcnJvcigib3BlbnBncC5wYWNrZXQuanNcbiINCgkJCQkJKyAiW0VSUk9SXSBvcGVucGdwX3BhY2tldDogZmFpbGVkIHRvIHBhcnNlIHBhY2tldCBAOiINCgkJCQkJKyBteXBvcyArICJcbmNoYXI6JyINCgkJCQkJKyB1dGlsLmhleHN0cmR1bXAoaW5wdXQuc3Vic3RyaW5nKG15cG9zKSkgKyAiJ1xuaW5wdXQ6Ig0KCQkJCQkrIHV0aWwuaGV4c3RyZHVtcChpbnB1dCkpOw0KCQkJcmV0dXJuIG51bGw7DQoJCQlicmVhazsNCgkJfQ0KCX0NCg0KCXRoaXMucmVhZF9wYWNrZXQgPSByZWFkX3BhY2tldDsNCn0NCg0KdmFyIG9wZW5wZ3BfcGFja2V0ID0gbmV3IF9vcGVucGdwX3BhY2tldCgpOw0KLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0DQovLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3INCi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcg0KLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLA0KLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YNCi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VDQovLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLg0KLy8gDQovLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlDQovLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0ENCg0KLyoqDQogKiBAY2xhc3MNCiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIEtleSBNYXRlcmlhbCBQYWNrZXQgKFRhZyA1LDYsNywxNCkNCiAqICAgDQogKiBSRkM0NDgwIDUuNToNCiAqIEEga2V5IG1hdGVyaWFsIHBhY2tldCBjb250YWlucyBhbGwgdGhlIGluZm9ybWF0aW9uIGFib3V0IGEgcHVibGljIG9yDQogKiBwcml2YXRlIGtleS4gIFRoZXJlIGFyZSBmb3VyIHZhcmlhbnRzIG9mIHRoaXMgcGFja2V0IHR5cGUsIGFuZCB0d28NCiAqIG1ham9yIHZlcnNpb25zLiAgQ29uc2VxdWVudGx5LCB0aGlzIHNlY3Rpb24gaXMgY29tcGxleC4NCiAqLw0KZnVuY3Rpb24gb3BlbnBncF9wYWNrZXRfa2V5bWF0ZXJpYWwoKSB7DQoJLy8gbWVtYmVyczoNCgl0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9IG51bGw7DQoJdGhpcy50YWdUeXBlID0gbnVsbDsNCgl0aGlzLmNyZWF0aW9uVGltZSA9IG51bGw7DQoJdGhpcy52ZXJzaW9uID0gbnVsbDsNCgl0aGlzLmV4cGlyYXRpb24gID0gbnVsbDsvLyBWMw0KCXRoaXMuTVBJcyA9IG51bGw7DQoJdGhpcy5zZWNNUElzID0gbnVsbDsNCgl0aGlzLnB1YmxpY0tleSA9IG51bGw7DQoJdGhpcy5zeW1tZXRyaWNFbmNyeXB0aW9uQWxnb3JpdGhtID0gbnVsbDsNCgl0aGlzLnMya1VzYWdlQ29udmVudGlvbnMgPSBudWxsOw0KCXRoaXMuSVZMZW5ndGggID0gbnVsbDsNCiAgICB0aGlzLmVuY3J5cHRlZE1QSURhdGEgPSBudWxsOw0KICAgIHRoaXMuaGFzVW5lbmNyeXB0ZWRTZWNyZXRLZXlEYXRhID0gbnVsbDsNCiAgICB0aGlzLmNoZWNrc3VtID0gbnVsbDsNCiAgICB0aGlzLnBhcmVudE5vZGUgPSBudWxsOw0KCXRoaXMuc3ViS2V5U2lnbmF0dXJlID0gbnVsbDsNCgl0aGlzLnN1YktleVJldm9jYXRpb25TaWduYXR1cmUgPSBudWxsOw0KDQoJLy8gNS41LjEuIEtleSBQYWNrZXQgVmFyaWFudHMNCgkNCgkvLyA1LjUuMS4zLiBTZWNyZXQtS2V5IFBhY2tldCAoVGFnIDUpDQoJLyoqDQoJICogVGhpcyBmdW5jdGlvbiByZWFkcyB0aGUgcGF5bG9hZCBvZiBhIHNlY3JldCBrZXkgcGFja2V0IChUYWcgNSkNCgkgKiBhbmQgaW5pdGlhbGl6ZXMgdGhlIG9wZW5wZ3BfcGFja2V0X2tleW1hdGVyaWFsDQoJICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IElucHV0IHN0cmluZyB0byByZWFkIHRoZSBwYWNrZXQgZnJvbQ0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gU3RhcnQgcG9zaXRpb24gZm9yIHRoZSBwYXJzZXINCgkgKiBAcGFyYW0ge0ludGVmZXJ9IGxlbiBMZW5ndGggb2YgdGhlIHBhY2tldCBvciByZW1haW5pbmcgbGVuZ3RoIG9mIGlucHV0DQoJICogQHJldHVybiB7b3BlbnBncF9wYWNrZXRfa2V5bWF0ZXJpYWx9DQoJICovDQoJZnVuY3Rpb24gcmVhZF90YWc1KGlucHV0LCBwb3NpdGlvbiwgbGVuKSB7DQoJCXRoaXMudGFnVHlwZSA9IDU7DQoJCXRoaXMucmVhZF9wcml2X2tleShpbnB1dCwgcG9zaXRpb24sIGxlbik7DQoJCXJldHVybiB0aGlzOw0KCX0NCg0KCS8vIDUuNS4xLjEuIFB1YmxpYy1LZXkgUGFja2V0IChUYWcgNikNCgkvKioNCgkgKiBUaGlzIGZ1bmN0aW9uIHJlYWRzIHRoZSBwYXlsb2FkIG9mIGEgcHVibGljIGtleSBwYWNrZXQgKFRhZyA2KQ0KCSAqIGFuZCBpbml0aWFsaXplcyB0aGUgb3BlbnBncF9wYWNrZXRfa2V5bWF0ZXJpYWwNCgkgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgSW5wdXQgc3RyaW5nIHRvIHJlYWQgdGhlIHBhY2tldCBmcm9tDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBTdGFydCBwb3NpdGlvbiBmb3IgdGhlIHBhcnNlcg0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuIExlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHJlbWFpbmluZyBsZW5ndGggb2YgaW5wdXQNCgkgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9rZXltYXRlcmlhbH0NCgkgKi8NCglmdW5jdGlvbiByZWFkX3RhZzYoaW5wdXQsIHBvc2l0aW9uLCBsZW4pIHsNCgkJLy8gQSBQdWJsaWMtS2V5IHBhY2tldCBzdGFydHMgYSBzZXJpZXMgb2YgcGFja2V0cyB0aGF0IGZvcm1zIGFuIE9wZW5QR1ANCgkJLy8ga2V5IChzb21ldGltZXMgY2FsbGVkIGFuIE9wZW5QR1AgY2VydGlmaWNhdGUpLg0KCQl0aGlzLnRhZ1R5cGUgPSA2Ow0KCQl0aGlzLnBhY2tldExlbmd0aCA9IGxlbjsNCgkJdGhpcy5yZWFkX3B1Yl9rZXkoaW5wdXQsIHBvc2l0aW9uLGxlbik7DQoJCQ0KCQlyZXR1cm4gdGhpczsNCgl9DQoNCgkvLyA1LjUuMS40LiBTZWNyZXQtU3Via2V5IFBhY2tldCAoVGFnIDcpDQoJLyoqDQoJICogVGhpcyBmdW5jdGlvbiByZWFkcyB0aGUgcGF5bG9hZCBvZiBhIHNlY3JldCBrZXkgc3ViIHBhY2tldCAoVGFnIDcpDQoJICogYW5kIGluaXRpYWxpemVzIHRoZSBvcGVucGdwX3BhY2tldF9rZXltYXRlcmlhbA0KCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBJbnB1dCBzdHJpbmcgdG8gcmVhZCB0aGUgcGFja2V0IGZyb20NCgkgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIFN0YXJ0IHBvc2l0aW9uIGZvciB0aGUgcGFyc2VyDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgcmVtYWluaW5nIGxlbmd0aCBvZiBpbnB1dA0KCSAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2tleW1hdGVyaWFsfQ0KCSAqLw0KCWZ1bmN0aW9uIHJlYWRfdGFnNyhpbnB1dCwgcG9zaXRpb24sIGxlbikgew0KCQl0aGlzLnRhZ1R5cGUgPSA3Ow0KCQl0aGlzLnBhY2tldExlbmd0aCA9IGxlbjsNCgkJcmV0dXJuIHRoaXMucmVhZF9wcml2X2tleShpbnB1dCwgcG9zaXRpb24sIGxlbik7DQoJfQ0KDQoJLy8gNS41LjEuMi4gUHVibGljLVN1YmtleSBQYWNrZXQgKFRhZyAxNCkNCgkvKioNCgkgKiBUaGlzIGZ1bmN0aW9uIHJlYWRzIHRoZSBwYXlsb2FkIG9mIGEgcHVibGljIGtleSBzdWIgcGFja2V0IChUYWcgMTQpDQoJICogYW5kIGluaXRpYWxpemVzIHRoZSBvcGVucGdwX3BhY2tldF9rZXltYXRlcmlhbA0KCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBJbnB1dCBzdHJpbmcgdG8gcmVhZCB0aGUgcGFja2V0IGZyb20NCgkgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIFN0YXJ0IHBvc2l0aW9uIGZvciB0aGUgcGFyc2VyDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgcmVtYWluaW5nIGxlbmd0aCBvZiBpbnB1dA0KCSAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2tleW1hdGVyaWFsfQ0KCSAqLw0KCWZ1bmN0aW9uIHJlYWRfdGFnMTQoaW5wdXQsIHBvc2l0aW9uLCBsZW4pIHsNCgkJdGhpcy5zdWJLZXlTaWduYXR1cmUgPSBudWxsOw0KCQl0aGlzLnN1YktleVJldm9jYXRpb25TaWduYXR1cmUgPSBuZXcgQXJyYXkoKTsNCgkJdGhpcy50YWdUeXBlID0gMTQ7DQoJCXRoaXMucGFja2V0TGVuZ3RoID0gbGVuOw0KCQl0aGlzLnJlYWRfcHViX2tleShpbnB1dCwgcG9zaXRpb24sbGVuKTsNCgkJcmV0dXJuIHRoaXM7DQoJfQ0KCQ0KCS8qKg0KCSAqIEludGVybmFsIFBhcnNlciBmb3IgcHVibGljIGtleXMgYXMgc3BlY2lmaWVkIGluIFJGQyA0ODgwIHNlY3Rpb24gDQoJICogNS41LjIgUHVibGljLUtleSBQYWNrZXQgRm9ybWF0cw0KCSAqIGNhbGxlZCBieSByZWFkX3RhZyZsdDtudW0mZ3Q7DQoJICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IElucHV0IHN0cmluZyB0byByZWFkIHRoZSBwYWNrZXQgZnJvbQ0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gU3RhcnQgcG9zaXRpb24gZm9yIHRoZSBwYXJzZXINCgkgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBMZW5ndGggb2YgdGhlIHBhY2tldCBvciByZW1haW5pbmcgbGVuZ3RoIG9mIGlucHV0DQoJICogQHJldHVybiB7T2JqZWN0fSBUaGlzIG9iamVjdCB3aXRoIGF0dHJpYnV0ZXMgc2V0IGJ5IHRoZSBwYXJzZXINCgkgKi8gIA0KCWZ1bmN0aW9uIHJlYWRfcHViX2tleShpbnB1dCwgcG9zaXRpb24sIGxlbikgew0KCQl2YXIgbXlwb3MgPSBwb3NpdGlvbjsNCgkJLy8gQSBvbmUtb2N0ZXQgdmVyc2lvbiBudW1iZXIgKDMgb3IgNCkuDQoJCXRoaXMudmVyc2lvbiA9IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJaWYgKHRoaXMudmVyc2lvbiA9PSAzKSB7DQoJCQkvLyBBIGZvdXItb2N0ZXQgbnVtYmVyIGRlbm90aW5nIHRoZSB0aW1lIHRoYXQgdGhlIGtleSB3YXMgY3JlYXRlZC4NCgkJCXRoaXMuY3JlYXRpb25UaW1lID0gbmV3IERhdGUoKChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPDwgMjQpIHwNCgkJCQkoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDE2KSB8DQoJCQkJKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCAgOCkgfA0KCQkJCShpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkpKSoxMDAwKTsNCgkJCQ0KCQkgICAgLy8gLSBBIHR3by1vY3RldCBudW1iZXIgZGVub3RpbmcgdGhlIHRpbWUgaW4gZGF5cyB0aGF0IHRoaXMga2V5IGlzDQoJCSAgICAvLyAgIHZhbGlkLiAgSWYgdGhpcyBudW1iZXIgaXMgemVybywgdGhlbiBpdCBkb2VzIG5vdCBleHBpcmUuDQoJCQl0aGlzLmV4cGlyYXRpb24gPSAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDgpICYgaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KCQ0KCQkgICAgLy8gLSBBIG9uZS1vY3RldCBudW1iZXIgZGVub3RpbmcgdGhlIHB1YmxpYy1rZXkgYWxnb3JpdGhtIG9mIHRoaXMga2V5Lg0KCQkJdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoJCQl2YXIgbXBpY291bnQgPSAwOw0KCQkgICAgLy8gLSBBIHNlcmllcyBvZiBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyBjb21wcmlzaW5nIHRoZSBrZXkgbWF0ZXJpYWw6DQoJCQkvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIFJTQSBwdWJsaWMga2V5czoNCgkJICAgIC8vICAgICAgIC0gYSBtdWx0aXByZWNpc2lvbiBpbnRlZ2VyIChNUEkpIG9mIFJTQSBwdWJsaWMgbW9kdWx1cyBuOw0KCQkgICAgLy8gICAgICAgLSBhbiBNUEkgb2YgUlNBIHB1YmxpYyBlbmNyeXB0aW9uIGV4cG9uZW50IGUuDQoJCQlpZiAodGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPiAwICYmIHRoaXMucHVibGljS2V5QWxnb3JpdGhtIDwgNCkNCgkJCQltcGljb3VudCA9IDI7DQoJCQkvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIEVsZ2FtYWwgcHVibGljIGtleXM6DQoJCQkvLyAgICAgLSBNUEkgb2YgRWxnYW1hbCBwcmltZSBwOw0KCQkJLy8gICAgIC0gTVBJIG9mIEVsZ2FtYWwgZ3JvdXAgZ2VuZXJhdG9yIGc7DQoJCQkvLyAgICAgLSBNUEkgb2YgRWxnYW1hbCBwdWJsaWMga2V5IHZhbHVlIHkgKD0gZyoqeCBtb2QgcCB3aGVyZSB4ICBpcyBzZWNyZXQpLg0KDQoJCQllbHNlIGlmICh0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9PSAxNikNCgkJCQltcGljb3VudCA9IDM7DQoJCQkvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIERTQSBwdWJsaWMga2V5czoNCgkJCS8vICAgICAgIC0gTVBJIG9mIERTQSBwcmltZSBwOw0KCQkJLy8gICAgICAgLSBNUEkgb2YgRFNBIGdyb3VwIG9yZGVyIHEgKHEgaXMgYSBwcmltZSBkaXZpc29yIG9mIHAtMSk7DQoJCQkvLyAgICAgICAtIE1QSSBvZiBEU0EgZ3JvdXAgZ2VuZXJhdG9yIGc7DQoJCQkvLyAgICAgICAtIE1QSSBvZiBEU0EgcHVibGljLWtleSB2YWx1ZSB5ICg9IGcqKnggbW9kIHAgd2hlcmUgeCAgaXMgc2VjcmV0KS4NCgkJCWVsc2UgaWYgKHRoaXMucHVibGljS2V5QWxnb3JpdGhtID09IDE3KQ0KCQkJCW1waWNvdW50ID0gNDsNCg0KCQkJdGhpcy5NUElzID0gbmV3IEFycmF5KCk7DQoJCQlmb3IgKHZhciBpID0gMDsgaSA8IG1waWNvdW50OyBpKyspIHsNCgkJCQl0aGlzLk1QSXNbaV0gPSBuZXcgb3BlbnBncF90eXBlX21waSgpOw0KCQkJCWlmICh0aGlzLk1QSXNbaV0ucmVhZChpbnB1dCwgbXlwb3MsIChteXBvcy1wb3NpdGlvbikpICE9IG51bGwgJiYgDQoJCQkJCQkhdGhpcy5wYWNrZXRMZW5ndGggPCAobXlwb3MtcG9zaXRpb24pKSB7DQoJCQkJCW15cG9zICs9IHRoaXMuTVBJc1tpXS5wYWNrZXRMZW5ndGg7DQoJCQkJfSBlbHNlIHsNCgkJCQkJdXRpbC5wcmludF9lcnJvcigib3BlbnBncC5wYWNrZXQua2V5bWF0ZXJpYWwuanNcbiIrJ2Vycm9yIHJlYWRpbmcgTVBJIEA6JytteXBvcyk7DQoJCQkJfQ0KCQkJfQ0KCQkJdGhpcy5wYWNrZXRMZW5ndGggPSBteXBvcy1wb3NpdGlvbjsNCgkJfSBlbHNlIGlmICh0aGlzLnZlcnNpb24gPT0gNCkgew0KCQkJLy8gLSBBIGZvdXItb2N0ZXQgbnVtYmVyIGRlbm90aW5nIHRoZSB0aW1lIHRoYXQgdGhlIGtleSB3YXMgY3JlYXRlZC4NCgkJCXRoaXMuY3JlYXRpb25UaW1lID0gbmV3IERhdGUoKChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPDwgMjQpIHwNCgkJCShpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPDwgMTYpIHwNCgkJCShpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPDwgIDgpIHwNCgkJCShpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkpKSoxMDAwKTsNCgkJCQ0KCQkJLy8gLSBBIG9uZS1vY3RldCBudW1iZXIgZGVub3RpbmcgdGhlIHB1YmxpYy1rZXkgYWxnb3JpdGhtIG9mIHRoaXMga2V5Lg0KCQkJdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoJCQl2YXIgbXBpY291bnQgPSAwOw0KCQkgICAgLy8gLSBBIHNlcmllcyBvZiBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyBjb21wcmlzaW5nIHRoZSBrZXkgbWF0ZXJpYWw6DQoJCQkvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIFJTQSBwdWJsaWMga2V5czoNCgkJICAgIC8vICAgICAgIC0gYSBtdWx0aXByZWNpc2lvbiBpbnRlZ2VyIChNUEkpIG9mIFJTQSBwdWJsaWMgbW9kdWx1cyBuOw0KCQkgICAgLy8gICAgICAgLSBhbiBNUEkgb2YgUlNBIHB1YmxpYyBlbmNyeXB0aW9uIGV4cG9uZW50IGUuDQoJCQlpZiAodGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPiAwICYmIHRoaXMucHVibGljS2V5QWxnb3JpdGhtIDwgNCkNCgkJCQkJbXBpY291bnQgPSAyOw0KCQkJLy8gICBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBFbGdhbWFsIHB1YmxpYyBrZXlzOg0KCQkJLy8gICAgIC0gTVBJIG9mIEVsZ2FtYWwgcHJpbWUgcDsNCgkJCS8vICAgICAtIE1QSSBvZiBFbGdhbWFsIGdyb3VwIGdlbmVyYXRvciBnOw0KCQkJLy8gICAgIC0gTVBJIG9mIEVsZ2FtYWwgcHVibGljIGtleSB2YWx1ZSB5ICg9IGcqKnggbW9kIHAgd2hlcmUgeCAgaXMgc2VjcmV0KS4NCgkJCWVsc2UgaWYgKHRoaXMucHVibGljS2V5QWxnb3JpdGhtID09IDE2KQ0KCQkJCW1waWNvdW50ID0gMzsNCg0KCQkJLy8gICBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBEU0EgcHVibGljIGtleXM6DQoJCQkvLyAgICAgICAtIE1QSSBvZiBEU0EgcHJpbWUgcDsNCgkJCS8vICAgICAgIC0gTVBJIG9mIERTQSBncm91cCBvcmRlciBxIChxIGlzIGEgcHJpbWUgZGl2aXNvciBvZiBwLTEpOw0KCQkJLy8gICAgICAgLSBNUEkgb2YgRFNBIGdyb3VwIGdlbmVyYXRvciBnOw0KCQkJLy8gICAgICAgLSBNUEkgb2YgRFNBIHB1YmxpYy1rZXkgdmFsdWUgeSAoPSBnKip4IG1vZCBwIHdoZXJlIHggIGlzIHNlY3JldCkuDQoJCQllbHNlIGlmICh0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9PSAxNykNCgkJCQltcGljb3VudCA9IDQ7DQoNCgkJCXRoaXMuTVBJcyA9IG5ldyBBcnJheSgpOw0KCQkJdmFyIGkgPSAwOw0KCQkJZm9yICh2YXIgaSA9IDA7IGkgPCBtcGljb3VudDsgaSsrKSB7DQoJCQkJdGhpcy5NUElzW2ldID0gbmV3IG9wZW5wZ3BfdHlwZV9tcGkoKTsNCgkJCQlpZiAodGhpcy5NUElzW2ldLnJlYWQoaW5wdXQsIG15cG9zLCAobXlwb3MtcG9zaXRpb24pKSAhPSBudWxsICYmDQoJCQkJCQkhdGhpcy5wYWNrZXRMZW5ndGggPCAobXlwb3MtcG9zaXRpb24pKSB7DQoJCQkJCW15cG9zICs9IHRoaXMuTVBJc1tpXS5wYWNrZXRMZW5ndGg7DQoJCQkJfSBlbHNlIHsNCgkJCQkJdXRpbC5wcmludF9lcnJvcigib3BlbnBncC5wYWNrZXQua2V5bWF0ZXJpYWwuanNcbiIrJ2Vycm9yIHJlYWRpbmcgTVBJIEA6JytteXBvcyk7DQoJCQkJfQ0KCQkJfQ0KCQkJdGhpcy5wYWNrZXRMZW5ndGggPSBteXBvcy1wb3NpdGlvbjsNCgkJfSBlbHNlIHsNCgkJCXJldHVybiBudWxsOw0KCQl9DQoJCXRoaXMuZGF0YSA9IGlucHV0LnN1YnN0cmluZyhwb3NpdGlvbiwgbXlwb3MpOw0KCQl0aGlzLnBhY2tldGRhdGEgPSBpbnB1dC5zdWJzdHJpbmcocG9zaXRpb24sIG15cG9zKTsNCgkJcmV0dXJuIHRoaXM7DQoJfQ0KCQ0KCS8vIDUuNS4zLiAgU2VjcmV0LUtleSBQYWNrZXQgRm9ybWF0cw0KCQ0KCS8qKg0KCSAqIEludGVybmFsIHBhcnNlciBmb3IgcHJpdmF0ZSBrZXlzIGFzIHNwZWNpZmllZCBpbiBSRkMgNDg4MCBzZWN0aW9uIDUuNS4zDQoJICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IElucHV0IHN0cmluZyB0byByZWFkIHRoZSBwYWNrZXQgZnJvbQ0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gU3RhcnQgcG9zaXRpb24gZm9yIHRoZSBwYXJzZXINCgkgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBMZW5ndGggb2YgdGhlIHBhY2tldCBvciByZW1haW5pbmcgbGVuZ3RoIG9mIGlucHV0DQoJICogQHJldHVybiB7T2JqZWN0fSBUaGlzIG9iamVjdCB3aXRoIGF0dHJpYnV0ZXMgc2V0IGJ5IHRoZSBwYXJzZXINCgkgKi8NCglmdW5jdGlvbiByZWFkX3ByaXZfa2V5KGlucHV0LHBvc2l0aW9uLCBsZW4pIHsNCgkgICAgLy8gLSBBIFB1YmxpYy1LZXkgb3IgUHVibGljLVN1YmtleSBwYWNrZXQsIGFzIGRlc2NyaWJlZCBhYm92ZS4NCgkgICAgdGhpcy5wdWJsaWNLZXkgPSBuZXcgb3BlbnBncF9wYWNrZXRfa2V5bWF0ZXJpYWwoKTsNCgkJaWYgKHRoaXMucHVibGljS2V5LnJlYWRfcHViX2tleShpbnB1dCxwb3NpdGlvbiwgbGVuKSA9PSBudWxsKSB7DQoJCQl1dGlsLnByaW50X2Vycm9yKCJvcGVucGdwLnBhY2tldC5rZXltYXRlcmlhbC5qc1xuIisiRmFpbGVkIHJlYWRpbmcgcHVibGljIGtleSBwb3J0aW9uIG9mIGEgcHJpdmF0ZSBrZXk6ICIraW5wdXRbcG9zaXRpb25dLmNoYXJDb2RlQXQoKSsiICIrcG9zaXRpb24rIiAiK2xlbisiXG4gQWJvcnRpbmcgaGVyZS4uLiIpOw0KCQkJcmV0dXJuIG51bGw7DQoJCX0NCgkJdGhpcy5wdWJsaWNLZXkuaGVhZGVyID0gb3BlbnBncF9wYWNrZXQud3JpdGVfb2xkX3BhY2tldF9oZWFkZXIoNix0aGlzLnB1YmxpY0tleS5wYWNrZXRMZW5ndGgpOw0KCQkvLyB0aGlzLnB1YmxpY0tleS5oZWFkZXIgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4OTkpICsgU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnB1YmxpY0tleS5wYWNrZXRMZW5ndGggPj4gOCAmIDB4RkYpK1N0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5wdWJsaWNLZXkucGFja2V0TGVuZ3RoICYgMHhGRik7DQoJCXZhciBteXBvcyA9IHBvc2l0aW9uICsgdGhpcy5wdWJsaWNLZXkuZGF0YS5sZW5ndGg7DQoJCXRoaXMucGFja2V0TGVuZ3RoID0gbGVuOw0KCQkNCgkgICAgLy8gLSBPbmUgb2N0ZXQgaW5kaWNhdGluZyBzdHJpbmctdG8ta2V5IHVzYWdlIGNvbnZlbnRpb25zLiAgWmVybw0KCSAgICAvLyAgIGluZGljYXRlcyB0aGF0IHRoZSBzZWNyZXQta2V5IGRhdGEgaXMgbm90IGVuY3J5cHRlZC4gIDI1NSBvciAyNTQNCgkgICAgLy8gICBpbmRpY2F0ZXMgdGhhdCBhIHN0cmluZy10by1rZXkgc3BlY2lmaWVyIGlzIGJlaW5nIGdpdmVuLiAgQW55DQoJICAgIC8vICAgb3RoZXIgdmFsdWUgaXMgYSBzeW1tZXRyaWMta2V5IGVuY3J5cHRpb24gYWxnb3JpdGhtIGlkZW50aWZpZXIuDQoJICAgIHRoaXMuczJrVXNhZ2VDb252ZW50aW9ucyA9IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkgICAgDQoJICAgIGlmICh0aGlzLnMya1VzYWdlQ29udmVudGlvbnMgPT0gMCkNCgkgICAgCXRoaXMuaGFzVW5lbmNyeXB0ZWRTZWNyZXRLZXlEYXRhID0gdHJ1ZTsNCgkgICANCgkgICAgLy8gLSBbT3B0aW9uYWxdIElmIHN0cmluZy10by1rZXkgdXNhZ2Ugb2N0ZXQgd2FzIDI1NSBvciAyNTQsIGEgb25lLQ0KCSAgICAvLyAgIG9jdGV0IHN5bW1ldHJpYyBlbmNyeXB0aW9uIGFsZ29yaXRobS4NCgkgICAgaWYgKHRoaXMuczJrVXNhZ2VDb252ZW50aW9ucyA9PSAyNTUgfHwgdGhpcy5zMmtVc2FnZUNvbnZlbnRpb25zID09IDI1NCkgew0KCSAgICAJdGhpcy5zeW1tZXRyaWNFbmNyeXB0aW9uQWxnb3JpdGhtID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KCSAgICB9DQoJICAgICANCgkgICAgLy8gLSBbT3B0aW9uYWxdIElmIHN0cmluZy10by1rZXkgdXNhZ2Ugb2N0ZXQgd2FzIDI1NSBvciAyNTQsIGENCgkgICAgLy8gICBzdHJpbmctdG8ta2V5IHNwZWNpZmllci4gIFRoZSBsZW5ndGggb2YgdGhlIHN0cmluZy10by1rZXkNCgkgICAgLy8gICBzcGVjaWZpZXIgaXMgaW1wbGllZCBieSBpdHMgdHlwZSwgYXMgZGVzY3JpYmVkIGFib3ZlLg0KCSAgICBpZiAodGhpcy5zMmtVc2FnZUNvbnZlbnRpb25zID09IDI1NSB8fCB0aGlzLnMya1VzYWdlQ29udmVudGlvbnMgPT0gMjU0KSB7DQoJICAgIAl0aGlzLnMyayA9IG5ldyBvcGVucGdwX3R5cGVfczJrKCk7DQoJICAgIAl0aGlzLnMyay5yZWFkKGlucHV0LCBteXBvcyk7DQoJICAgIAlteXBvcyArPXRoaXMuczJrLnMya0xlbmd0aDsNCgkgICAgfQ0KCSAgICANCgkgICAgLy8gLSBbT3B0aW9uYWxdIElmIHNlY3JldCBkYXRhIGlzIGVuY3J5cHRlZCAoc3RyaW5nLXRvLWtleSB1c2FnZSBvY3RldA0KCSAgICAvLyAgIG5vdCB6ZXJvKSwgYW4gSW5pdGlhbCBWZWN0b3IgKElWKSBvZiB0aGUgc2FtZSBsZW5ndGggYXMgdGhlDQoJICAgIC8vICAgY2lwaGVyJ3MgYmxvY2sgc2l6ZS4NCgkgICAgdGhpcy5zeW1rZXlsZW5ndGggPSAwOw0KCSAgICBpZiAodGhpcy5zMmtVc2FnZUNvbnZlbnRpb25zICE9IDAgJiYgdGhpcy5zMmtVc2FnZUNvbnZlbnRpb25zICE9IDI1NSAmJg0KCSAgICAJCXRoaXMuczJrVXNhZ2VDb252ZW50aW9ucyAhPSAyNTQpIHsNCgkgICAgCXRoaXMuc3ltbWV0cmljRW5jcnlwdGlvbkFsZ29yaXRobSA9IHRoaXMuczJrVXNhZ2VDb252ZW50aW9uczsNCgkgICAgfQ0KCSAgICBpZiAodGhpcy5zMmtVc2FnZUNvbnZlbnRpb25zICE9IDAgJiYgdGhpcy5zMmsudHlwZSAhPSAxMDAxKSB7DQoJICAgIAl0aGlzLmhhc0lWID0gdHJ1ZTsNCgkgICAgCXN3aXRjaCAodGhpcy5zeW1tZXRyaWNFbmNyeXB0aW9uQWxnb3JpdGhtKSB7DQoJCSAgICBjYXNlICAxOiAvLyAtIElERUEgW0lERUFdDQoJCSAgICAJdXRpbC5wcmludF9lcnJvcigib3BlbnBncC5wYWNrZXQua2V5bWF0ZXJpYWwuanNcbiIrInN5bW1ldHJpYyBlbmNyeXRyeXB0aW9uIGFsZ29yaXRoaW06IElERUEgaXMgbm90IGltcGxlbWVudGVkIik7DQoJCSAgICAJcmV0dXJuIG51bGw7DQoJICAgIAljYXNlICAyOiAvLyAtIFRyaXBsZURFUyAoREVTLUVERSwgW1NDSE5FSUVSXSBbSEFDXSAtIDE2OCBiaXQga2V5IGRlcml2ZWQgZnJvbSAxOTIpDQoJICAgIAljYXNlICAzOiAvLyAtIENBU1Q1ICgxMjggYml0IGtleSwgYXMgcGVyIFtSRkMyMTQ0XSkNCgkgICAgCQl0aGlzLklWTGVuZ3RoID0gODsNCgkJICAgIAlicmVhazsNCgkJICAgIGNhc2UgIDQ6IC8vIC0gQmxvd2Zpc2ggKDEyOCBiaXQga2V5LCAxNiByb3VuZHMpIFtCTE9XRklTSF0NCgkJICAgIGNhc2UgIDc6IC8vIC0gQUVTIHdpdGggMTI4LWJpdCBrZXkgW0FFU10NCgkgICAgCWNhc2UgIDg6IC8vIC0gQUVTIHdpdGggMTkyLWJpdCBrZXkNCgkgICAgCWNhc2UgIDk6IC8vIC0gQUVTIHdpdGggMjU2LWJpdCBrZXkNCgkgICAgCQl0aGlzLklWTGVuZ3RoID0gMTY7DQoJCSAgICAJYnJlYWs7DQoJICAgIAljYXNlIDEwOiAvLyAtIFR3b2Zpc2ggd2l0aCAyNTYtYml0IGtleSBbVFdPRklTSF0NCgkgICAgCQl0aGlzLklWTGVuZ3RoID0gMzI7CSAgICAJCQ0KCQkgICAgCWJyZWFrOw0KCSAgICAJY2FzZSAgNTogLy8gLSBSZXNlcnZlZA0KCSAgICAJY2FzZSAgNjogLy8gLSBSZXNlcnZlZA0KCSAgICAJZGVmYXVsdDoNCgkgICAgCQl1dGlsLnByaW50X2Vycm9yKCJvcGVucGdwLnBhY2tldC5rZXltYXRlcmlhbC5qc1xuIisidW5rbm93biBlbmNyeXB0aW9uIGFsZ29yaXRobSBmb3Igc2VjcmV0IGtleSA6Iit0aGlzLnN5bW1ldHJpY0VuY3J5cHRpb25BbGdvcml0aG0pOw0KCSAgICAJCXJldHVybiBudWxsOw0KCSAgICAJfQ0KCSAgICAJbXlwb3MrKzsgDQoJICAgIAl0aGlzLklWID0gaW5wdXQuc3Vic3RyaW5nKG15cG9zLCBteXBvcyt0aGlzLklWTGVuZ3RoKTsNCgkgICAgCW15cG9zICs9IHRoaXMuSVZMZW5ndGg7DQoJICAgIH0NCgkgICAgLy8gLSBQbGFpbiBvciBlbmNyeXB0ZWQgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgY29tcHJpc2luZyB0aGUgc2VjcmV0DQoJICAgIC8vICAga2V5IGRhdGEuICBUaGVzZSBhbGdvcml0aG0tc3BlY2lmaWMgZmllbGRzIGFyZSBhcyBkZXNjcmliZWQNCgkgICAgLy8gICBiZWxvdy4NCg0KICAgICAgLy8gczJrIHR5cGUgMTAwMSBjb3JyZXNwb25kcyB0byBHUEcgc3BlY2lmaWMgZXh0ZW5zaW9uIHdpdGhvdXQgcHJpbWFyeSBrZXkgc2VjcmV0cw0KICAgICAgLy8gaHR0cDovL3d3dy5nbnVwZy5vcmcvZmFxL0dudVBHLUZBUS5odG1sI2hvdy1jYW4taS11c2UtZ251cGctaW4tYW4tYXV0b21hdGVkLWVudmlyb25tZW50DQoJICAgIGlmICh0aGlzLnMya1VzYWdlQ29udmVudGlvbnMgIT0gMCAmJiB0aGlzLnMyay50eXBlID09IDEwMDEpIHsNCgkgICAgCXRoaXMuc2VjTVBJcyA9IG51bGw7DQoJICAgIAl0aGlzLmVuY3J5cHRlZE1QSURhdGEgPSBudWxsOw0KCSAgICB9IGVsc2UgaWYgKCF0aGlzLmhhc1VuZW5jcnlwdGVkU2VjcmV0S2V5RGF0YSkgew0KCSAgICAJdGhpcy5lbmNyeXB0ZWRNUElEYXRhID0gaW5wdXQuc3Vic3RyaW5nKG15cG9zLCBsZW4pOw0KCSAgICAJbXlwb3MgKz0gdGhpcy5lbmNyeXB0ZWRNUElEYXRhLmxlbmd0aDsNCgkgICAgfSBlbHNlIHsNCgkgICAgCWlmICh0aGlzLnB1YmxpY0tleS5wdWJsaWNLZXlBbGdvcml0aG0gPiAwICYmIHRoaXMucHVibGljS2V5LnB1YmxpY0tleUFsZ29yaXRobSA8IDQpIHsNCgkgICAgCQkvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIFJTQSBzZWNyZXQga2V5czoNCgkgICAgCQkvLyAgIC0gbXVsdGlwcmVjaXNpb24gaW50ZWdlciAoTVBJKSBvZiBSU0Egc2VjcmV0IGV4cG9uZW50IGQuDQoJICAgIAkJLy8gICAtIE1QSSBvZiBSU0Egc2VjcmV0IHByaW1lIHZhbHVlIHAuDQoJICAgIAkJLy8gICAtIE1QSSBvZiBSU0Egc2VjcmV0IHByaW1lIHZhbHVlIHEgKHAgPCBxKS4NCgkgICAgCQkvLyAgIC0gTVBJIG9mIHUsIHRoZSBtdWx0aXBsaWNhdGl2ZSBpbnZlcnNlIG9mIHAsIG1vZCBxLg0KCSAgICAJCXRoaXMuc2VjTVBJcyA9IG5ldyBBcnJheSgpOw0KCSAgICAJCXRoaXMuc2VjTVBJc1swXSA9IG5ldyBvcGVucGdwX3R5cGVfbXBpKCk7DQoJICAgIAkJdGhpcy5zZWNNUElzWzBdLnJlYWQoaW5wdXQsIG15cG9zLCBsZW4tMi0gKG15cG9zIC0gcG9zaXRpb24pKTsNCgkgICAgCQlteXBvcyArPSB0aGlzLnNlY01QSXNbMF0ucGFja2V0TGVuZ3RoOw0KCSAgICAJCXRoaXMuc2VjTVBJc1sxXSA9IG5ldyBvcGVucGdwX3R5cGVfbXBpKCk7DQoJICAgIAkJdGhpcy5zZWNNUElzWzFdLnJlYWQoaW5wdXQsIG15cG9zLCBsZW4tMi0gKG15cG9zIC0gcG9zaXRpb24pKTsNCgkgICAgCQlteXBvcyArPSB0aGlzLnNlY01QSXNbMV0ucGFja2V0TGVuZ3RoOw0KCSAgICAJCXRoaXMuc2VjTVBJc1syXSA9IG5ldyBvcGVucGdwX3R5cGVfbXBpKCk7DQoJICAgIAkJdGhpcy5zZWNNUElzWzJdLnJlYWQoaW5wdXQsIG15cG9zLCBsZW4tMi0gKG15cG9zIC0gcG9zaXRpb24pKTsNCgkgICAgCQlteXBvcyArPSB0aGlzLnNlY01QSXNbMl0ucGFja2V0TGVuZ3RoOw0KCSAgICAJCXRoaXMuc2VjTVBJc1szXSA9IG5ldyBvcGVucGdwX3R5cGVfbXBpKCk7DQoJICAgIAkJdGhpcy5zZWNNUElzWzNdLnJlYWQoaW5wdXQsIG15cG9zLCBsZW4tMi0gKG15cG9zIC0gcG9zaXRpb24pKTsNCgkgICAgCQlteXBvcyArPSB0aGlzLnNlY01QSXNbM10ucGFja2V0TGVuZ3RoOw0KCSAgICAJfSBlbHNlIGlmICh0aGlzLnB1YmxpY0tleS5wdWJsaWNLZXlBbGdvcml0aG0gPT0gMTYpIHsNCgkgICAgCQkvLyBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBFbGdhbWFsIHNlY3JldCBrZXlzOg0KCSAgICAJCS8vICAgLSBNUEkgb2YgRWxnYW1hbCBzZWNyZXQgZXhwb25lbnQgeC4NCgkgICAgCQl0aGlzLnNlY01QSXMgPSBuZXcgQXJyYXkoKTsNCgkgICAgCQl0aGlzLnNlY01QSXNbMF0gPSBuZXcgb3BlbnBncF90eXBlX21waSgpOw0KCSAgICAJCXRoaXMuc2VjTVBJc1swXS5yZWFkKGlucHV0LCBteXBvcywgbGVuLTItIChteXBvcyAtIHBvc2l0aW9uKSk7DQoJICAgIAkJbXlwb3MgKz0gdGhpcy5zZWNNUElzWzBdLnBhY2tldExlbmd0aDsNCgkgICAgCX0gZWxzZSBpZiAodGhpcy5wdWJsaWNLZXkucHVibGljS2V5QWxnb3JpdGhtID09IDE3KSB7DQoJICAgIAkJLy8gQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgRFNBIHNlY3JldCBrZXlzOg0KCSAgICAJCS8vICAgLSBNUEkgb2YgRFNBIHNlY3JldCBleHBvbmVudCB4Lg0KCSAgICAJCXRoaXMuc2VjTVBJcyA9IG5ldyBBcnJheSgpOw0KCSAgICAJCXRoaXMuc2VjTVBJc1swXSA9IG5ldyBvcGVucGdwX3R5cGVfbXBpKCk7DQoJICAgIAkJdGhpcy5zZWNNUElzWzBdLnJlYWQoaW5wdXQsIG15cG9zLCBsZW4tMi0gKG15cG9zIC0gcG9zaXRpb24pKTsNCgkgICAgCQlteXBvcyArPSB0aGlzLnNlY01QSXNbMF0ucGFja2V0TGVuZ3RoOw0KCSAgICAJfQ0KCSAgICAJLy8gY2hlY2tzdW0gYmVjYXVzZSBzMmsgdXNhZ2UgY29udmVudGlvbiBpcyAwDQoJICAgICAgICB0aGlzLmNoZWNrc3VtID0gbmV3IEFycmF5KCk7IA0KCQkgICAgdGhpcy5jaGVja3N1bVswXSA9IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJICAgIHRoaXMuY2hlY2tzdW1bMV0gPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoJICAgIH0NCgkgICAgcmV0dXJuIHRoaXM7DQoJfQ0KCQ0KDQoJLyoqDQoJICogRGVjcnlwdHMgdGhlIHByaXZhdGUga2V5IE1QSXMgd2hpY2ggYXJlIG5lZWRlZCB0byB1c2UgdGhlIGtleS4NCgkgKiBvcGVucGdwX3BhY2tldF9rZXltYXRlcmlhbC5oYXNVbmVuY3J5cHRlZFNlY3JldEtleURhdGEgc2hvdWxkIGJlIA0KCSAqIGZhbHNlIG90aGVyd2lzZQ0KCSAqIGEgY2FsbCB0byB0aGlzIGZ1bmN0aW9uIGlzIG5vdCBuZWVkZWQNCgkgKiANCgkgKiBAcGFyYW0ge1N0cmluZ30gc3RyX3Bhc3NwaHJhc2UgVGhlIHBhc3NwaHJhc2UgZm9yIHRoaXMgcHJpdmF0ZSBrZXkgDQoJICogYXMgc3RyaW5nDQoJICogQHJldHVybiB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgcGFzc3BocmFzZSB3YXMgY29ycmVjdDsgZmFsc2UgaWYgbm90DQoJICovDQoJZnVuY3Rpb24gZGVjcnlwdFNlY3JldE1QSXMoc3RyX3Bhc3NwaHJhc2UpIHsNCgkJaWYgKHRoaXMuaGFzVW5lbmNyeXB0ZWRTZWNyZXRLZXlEYXRhKQ0KCQkJcmV0dXJuIHRoaXMuc2VjTVBJczsNCgkJLy8gY3JlYXRpbmcgYSBrZXkgb3V0IG9mIHRoZSBwYXNzcGhyYXNlDQoJCXZhciBrZXkgPSB0aGlzLnMyay5wcm9kdWNlX2tleShzdHJfcGFzc3BocmFzZSk7DQoJCXZhciBjbGVhcnRleHRNUElzID0gIiI7DQogICAgCXN3aXRjaCAodGhpcy5zeW1tZXRyaWNFbmNyeXB0aW9uQWxnb3JpdGhtKSB7DQoJICAgIGNhc2UgIDE6IC8vIC0gSURFQSBbSURFQV0NCgkgICAgCXV0aWwucHJpbnRfZXJyb3IoIm9wZW5wZ3AucGFja2V0LmtleW1hdGVyaWFsLmpzXG4iKyJzeW1tZXRyaWMgZW5jcnlwdGlvbiBhbGdvcml0aGltOiBJREVBIGlzIG5vdCBpbXBsZW1lbnRlZCIpOw0KCSAgICAJcmV0dXJuIGZhbHNlOw0KICAgIAljYXNlICAyOiAvLyAtIFRyaXBsZURFUyAoREVTLUVERSwgW1NDSE5FSUVSXSBbSEFDXSAtIDE2OCBiaXQga2V5IGRlcml2ZWQgZnJvbSAxOTIpDQogICAgCQljbGVhcnRleHRNUElzID0gbm9ybWFsX2NmYl9kZWNyeXB0KGZ1bmN0aW9uKGJsb2NrLCBrZXkpIHsNCiAgICAJCQlyZXR1cm4gZGVzKGtleSwgYmxvY2ssMSxudWxsLDApOw0KICAgIAkJfSwgdGhpcy5JVkxlbmd0aCwga2V5LCB0aGlzLmVuY3J5cHRlZE1QSURhdGEsIHRoaXMuSVYpOw0KICAgIAkJYnJlYWs7DQogICAgCWNhc2UgIDM6IC8vIC0gQ0FTVDUgKDEyOCBiaXQga2V5LCBhcyBwZXIgW1JGQzIxNDRdKQ0KICAgIAkJY2xlYXJ0ZXh0TVBJcyA9IG5vcm1hbF9jZmJfZGVjcnlwdChmdW5jdGlvbihibG9jaywga2V5KSB7DQogICAgICAgIAkJdmFyIGNhc3Q1ID0gbmV3IG9wZW5wZ3Bfc3ltZW5jX2Nhc3Q1KCk7DQogICAgICAgIAkJY2FzdDUuc2V0S2V5KGtleSk7DQogICAgICAgIAkJcmV0dXJuIGNhc3Q1LmVuY3J5cHQodXRpbC5zdHIyYmluKGJsb2NrKSk7IA0KICAgIAkJfSwgdGhpcy5JVkxlbmd0aCwgdXRpbC5zdHIyYmluKGtleS5zdWJzdHJpbmcoMCwxNikpLCB0aGlzLmVuY3J5cHRlZE1QSURhdGEsIHRoaXMuSVYpOw0KICAgIAkJYnJlYWs7DQoJICAgIGNhc2UgIDQ6IC8vIC0gQmxvd2Zpc2ggKDEyOCBiaXQga2V5LCAxNiByb3VuZHMpIFtCTE9XRklTSF0NCgkgICAgCWNsZWFydGV4dE1QSXMgPSBub3JtYWxfY2ZiX2RlY3J5cHQoZnVuY3Rpb24oYmxvY2ssIGtleSkgew0KICAgIAkJCXZhciBibG93ZmlzaCA9IG5ldyBCbG93ZmlzaChrZXkpOw0KICAgICAgICAJCXJldHVybiBibG93ZmlzaC5lbmNyeXB0KGJsb2NrKTsgDQogICAgCQl9LCB0aGlzLklWTGVuZ3RoLCBrZXksIHRoaXMuZW5jcnlwdGVkTVBJRGF0YSwgdGhpcy5JVik7DQogICAgCQlicmVhazsNCgkgICAgY2FzZSAgNzogLy8gLSBBRVMgd2l0aCAxMjgtYml0IGtleSBbQUVTXQ0KICAgIAljYXNlICA4OiAvLyAtIEFFUyB3aXRoIDE5Mi1iaXQga2V5DQogICAgCWNhc2UgIDk6IC8vIC0gQUVTIHdpdGggMjU2LWJpdCBrZXkNCiAgICAJICAgIHZhciBudW1CeXRlcyA9IDE2Ow0KICAgICAgICAgICAgLy9UaGlzIGlzIGEgd2VpcmQgd2F5IHRvIGFjaGlldmUgdGhpcy4gSWYncyB3aXRoaW4gYSBzd2l0Y2ggaXMgcHJvYmFibHkgbm90IGlkZWFsLg0KICAgIAkgICAgaWYodGhpcy5zeW1tZXRyaWNFbmNyeXB0aW9uQWxnb3JpdGhtID09IDgpew0KICAgIAkgICAgICAgIG51bUJ5dGVzID0gMjQ7DQogICAgCSAgICAgICAga2V5ID0gdGhpcy5zMmsucHJvZHVjZV9rZXkoc3RyX3Bhc3NwaHJhc2UsbnVtQnl0ZXMpOw0KICAgIAkgICAgfQ0KICAgIAkgICAgaWYodGhpcy5zeW1tZXRyaWNFbmNyeXB0aW9uQWxnb3JpdGhtID09IDkpew0KICAgIAkgICAgICAgIG51bUJ5dGVzID0gMzI7DQogICAgCSAgICAgICAga2V5ID0gdGhpcy5zMmsucHJvZHVjZV9rZXkoc3RyX3Bhc3NwaHJhc2UsbnVtQnl0ZXMpOw0KICAgIAkgICAgfQ0KICAgIAkJY2xlYXJ0ZXh0TVBJcyA9IG5vcm1hbF9jZmJfZGVjcnlwdChmdW5jdGlvbihibG9jayxrZXkpew0KICAgIAkJICAgIHJldHVybiBBRVNlbmNyeXB0KHV0aWwuc3RyMmJpbihibG9jayksa2V5KTsNCiAgICAJCX0sDQogICAgCQkJCXRoaXMuSVZMZW5ndGgsIGtleUV4cGFuc2lvbihrZXkuc3Vic3RyaW5nKDAsbnVtQnl0ZXMpKSwgdGhpcy5lbmNyeXB0ZWRNUElEYXRhLCB0aGlzLklWKTsNCgkgICAgCWJyZWFrOw0KICAgIAljYXNlIDEwOiAvLyAtIFR3b2Zpc2ggd2l0aCAyNTYtYml0IGtleSBbVFdPRklTSF0NCiAgICAJCXV0aWwucHJpbnRfZXJyb3IoIm9wZW5wZ3AucGFja2V0LmtleW1hdGVyaWFsLmpzXG4iKyJLZXkgbWF0ZXJpYWwgaXMgZW5jcnlwdGVkIHdpdGggdHdvZmlzaDogbm90IGltcGxlbWVudGVkIik7ICAgCQkNCgkgICAgCXJldHVybiBmYWxzZTsNCiAgICAJY2FzZSAgNTogLy8gLSBSZXNlcnZlZA0KICAgIAljYXNlICA2OiAvLyAtIFJlc2VydmVkDQogICAgCWRlZmF1bHQ6DQogICAgCQl1dGlsLnByaW50X2Vycm9yKCJvcGVucGdwLnBhY2tldC5rZXltYXRlcmlhbC5qc1xuIisidW5rbm93biBlbmNyeXB0aW9uIGFsZ29yaXRobSBmb3Igc2VjcmV0IGtleSA6Iit0aGlzLnN5bW1ldHJpY0VuY3J5cHRpb25BbGdvcml0aG0pOw0KICAgIAkJcmV0dXJuIGZhbHNlOw0KICAgIAl9DQogICAgCQ0KICAgIAlpZiAoY2xlYXJ0ZXh0TVBJcyA9PSBudWxsKSB7DQogICAgCQl1dGlsLnByaW50X2Vycm9yKCJvcGVucGdwLnBhY2tldC5rZXltYXRlcmlhbC5qc1xuIisiY2xlYXJ0ZXh0TVBJcyB3YXMgbnVsbCIpOw0KICAgIAkJcmV0dXJuIGZhbHNlOw0KICAgIAl9DQogICAgCQ0KICAgIAl2YXIgY2xlYXJ0ZXh0TVBJc2xlbmd0aCA9IGNsZWFydGV4dE1QSXMubGVuZ3RoOw0KDQogICAgCWlmICh0aGlzLnMya1VzYWdlQ29udmVudGlvbnMgPT0gMjU0ICYmDQogICAgCQkJc3RyX3NoYTEoY2xlYXJ0ZXh0TVBJcy5zdWJzdHJpbmcoMCxjbGVhcnRleHRNUElzLmxlbmd0aCAtIDIwKSkgPT0gDQogICAgCQkJCWNsZWFydGV4dE1QSXMuc3Vic3RyaW5nKGNsZWFydGV4dE1QSXMubGVuZ3RoIC0gMjApKSB7DQogICAgCQljbGVhcnRleHRNUElzbGVuZ3RoIC09IDIwOw0KICAgIAl9IGVsc2UgaWYgKHRoaXMuczJrVXNhZ2VDb252ZW50aW9ucyAhPSAyNTQgJiYgdXRpbC5jYWxjX2NoZWNrc3VtKGNsZWFydGV4dE1QSXMuc3Vic3RyaW5nKDAsY2xlYXJ0ZXh0TVBJcy5sZW5ndGggLSAyKSkgPT0gDQogICAgCQkJKGNsZWFydGV4dE1QSXMuY2hhckNvZGVBdChjbGVhcnRleHRNUElzLmxlbmd0aCAtMikgPDwgOCB8IGNsZWFydGV4dE1QSXMuY2hhckNvZGVBdChjbGVhcnRleHRNUElzLmxlbmd0aCAtMSkpKSB7DQogICAgCQljbGVhcnRleHRNUElzbGVuZ3RoIC09IDI7DQogICAgCX0gZWxzZSB7DQogICAgCQlyZXR1cm4gZmFsc2U7DQogICAgCX0NCg0KICAgIAlpZiAodGhpcy5wdWJsaWNLZXkucHVibGljS2V5QWxnb3JpdGhtID4gMCAmJiB0aGlzLnB1YmxpY0tleS5wdWJsaWNLZXlBbGdvcml0aG0gPCA0KSB7DQogICAgCQkvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIFJTQSBzZWNyZXQga2V5czoNCiAgICAJCS8vICAgLSBtdWx0aXByZWNpc2lvbiBpbnRlZ2VyIChNUEkpIG9mIFJTQSBzZWNyZXQgZXhwb25lbnQgZC4NCiAgICAJCS8vICAgLSBNUEkgb2YgUlNBIHNlY3JldCBwcmltZSB2YWx1ZSBwLg0KICAgIAkJLy8gICAtIE1QSSBvZiBSU0Egc2VjcmV0IHByaW1lIHZhbHVlIHEgKHAgPCBxKS4NCiAgICAJCS8vICAgLSBNUEkgb2YgdSwgdGhlIG11bHRpcGxpY2F0aXZlIGludmVyc2Ugb2YgcCwgbW9kIHEuDQogICAgCQl2YXIgbXlwb3MgPSAwOw0KICAgIAkJdGhpcy5zZWNNUElzID0gbmV3IEFycmF5KCk7DQogICAgCQl0aGlzLnNlY01QSXNbMF0gPSBuZXcgb3BlbnBncF90eXBlX21waSgpOw0KICAgIAkJdGhpcy5zZWNNUElzWzBdLnJlYWQoY2xlYXJ0ZXh0TVBJcywgMCwgY2xlYXJ0ZXh0TVBJc2xlbmd0aCk7DQogICAgCQlteXBvcyArPSB0aGlzLnNlY01QSXNbMF0ucGFja2V0TGVuZ3RoOw0KICAgIAkJdGhpcy5zZWNNUElzWzFdID0gbmV3IG9wZW5wZ3BfdHlwZV9tcGkoKTsNCiAgICAJCXRoaXMuc2VjTVBJc1sxXS5yZWFkKGNsZWFydGV4dE1QSXMsIG15cG9zLCBjbGVhcnRleHRNUElzbGVuZ3RoLW15cG9zKTsNCiAgICAJCW15cG9zICs9IHRoaXMuc2VjTVBJc1sxXS5wYWNrZXRMZW5ndGg7DQogICAgCQl0aGlzLnNlY01QSXNbMl0gPSBuZXcgb3BlbnBncF90eXBlX21waSgpOw0KICAgIAkJdGhpcy5zZWNNUElzWzJdLnJlYWQoY2xlYXJ0ZXh0TVBJcywgbXlwb3MsIGNsZWFydGV4dE1QSXNsZW5ndGgtbXlwb3MpOw0KICAgIAkJbXlwb3MgKz0gdGhpcy5zZWNNUElzWzJdLnBhY2tldExlbmd0aDsNCiAgICAJCXRoaXMuc2VjTVBJc1szXSA9IG5ldyBvcGVucGdwX3R5cGVfbXBpKCk7DQogICAgCQl0aGlzLnNlY01QSXNbM10ucmVhZChjbGVhcnRleHRNUElzLCBteXBvcywgY2xlYXJ0ZXh0TVBJc2xlbmd0aC1teXBvcyk7DQogICAgCQlteXBvcyArPSB0aGlzLnNlY01QSXNbM10ucGFja2V0TGVuZ3RoOw0KICAgIAl9IGVsc2UgaWYgKHRoaXMucHVibGljS2V5LnB1YmxpY0tleUFsZ29yaXRobSA9PSAxNikgew0KICAgIAkJLy8gQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgRWxnYW1hbCBzZWNyZXQga2V5czoNCiAgICAJCS8vICAgLSBNUEkgb2YgRWxnYW1hbCBzZWNyZXQgZXhwb25lbnQgeC4NCiAgICAJCXRoaXMuc2VjTVBJcyA9IG5ldyBBcnJheSgpOw0KICAgIAkJdGhpcy5zZWNNUElzWzBdID0gbmV3IG9wZW5wZ3BfdHlwZV9tcGkoKTsNCiAgICAJCXRoaXMuc2VjTVBJc1swXS5yZWFkKGNsZWFydGV4dE1QSXMsIDAsIGNsZWFydGV4dE1QSXMpOw0KICAgIAl9IGVsc2UgaWYgKHRoaXMucHVibGljS2V5LnB1YmxpY0tleUFsZ29yaXRobSA9PSAxNykgew0KICAgIAkJLy8gQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgRFNBIHNlY3JldCBrZXlzOg0KICAgIAkJLy8gICAtIE1QSSBvZiBEU0Egc2VjcmV0IGV4cG9uZW50IHguDQogICAgCQl0aGlzLnNlY01QSXMgPSBuZXcgQXJyYXkoKTsNCiAgICAJCXRoaXMuc2VjTVBJc1swXSA9IG5ldyBvcGVucGdwX3R5cGVfbXBpKCk7DQogICAgCQl0aGlzLnNlY01QSXNbMF0ucmVhZChjbGVhcnRleHRNUElzLCAwLCBjbGVhcnRleHRNUElzbGVuZ3RoKTsNCiAgICAJfQ0KICAgIAlyZXR1cm4gdHJ1ZTsNCgl9DQoJDQoJLyoqDQoJICogR2VuZXJhdGVzIERlYnVnIG91dHB1dA0KCSAqIEByZXR1cm4gU3RyaW5nIHdoaWNoIGdpdmVzIHNvbWUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGtleW1hdGVyaWFsDQoJICovDQoJZnVuY3Rpb24gdG9TdHJpbmcoKSB7DQoJCXZhciByZXN1bHQgPSAiIjsNCgkJc3dpdGNoICh0aGlzLnRhZ1R5cGUpIHsNCgkJY2FzZSA2Og0KCQkJIHJlc3VsdCArPSAnNS41LjEuMS4gUHVibGljLUtleSBQYWNrZXQgKFRhZyA2KVxuJysNCgkJCSAgICcgICAgbGVuZ3RoOiAgICAgICAgICAgICAnK3RoaXMucGFja2V0TGVuZ3RoKydcbicrDQoJCQkgICAnICAgIHZlcnNpb246ICAgICAgICAgICAgJyt0aGlzLnZlcnNpb24rJ1xuJysNCgkJCSAgICcgICAgY3JlYXRpb24gdGltZTogICAgICAnK3RoaXMuY3JlYXRpb25UaW1lKydcbicrDQoJCQkgICAnICAgIGV4cGlyYXRpb24gdGltZTogICAgJyt0aGlzLmV4cGlyYXRpb24rJ1xuJysNCgkJCSAgICcgICAgcHVibGljS2V5QWxnb3JpdGhtOiAnK3RoaXMucHVibGljS2V5QWxnb3JpdGhtKydcbic7DQoJCQlicmVhazsNCgkJY2FzZSAxNDoNCgkJCXJlc3VsdCArPSAnNS41LjEuMi4gUHVibGljLVN1YmtleSBQYWNrZXQgKFRhZyAxNClcbicrDQoJCQkgICAnICAgIGxlbmd0aDogICAgICAgICAgICAgJyt0aGlzLnBhY2tldExlbmd0aCsnXG4nKw0KCQkJICAgJyAgICB2ZXJzaW9uOiAgICAgICAgICAgICcrdGhpcy52ZXJzaW9uKydcbicrDQoJCQkgICAnICAgIGNyZWF0aW9uIHRpbWU6ICAgICAgJyt0aGlzLmNyZWF0aW9uVGltZSsnXG4nKw0KCQkJICAgJyAgICBleHBpcmF0aW9uIHRpbWU6ICAgICcrdGhpcy5leHBpcmF0aW9uKydcbicrDQoJCQkgICAnICAgIHB1YmxpY0tleUFsZ29yaXRobTogJyt0aGlzLnB1YmxpY0tleUFsZ29yaXRobSsnXG4nOw0KCQkJYnJlYWs7DQoJCWNhc2UgNToNCgkJCXJlc3VsdCArPSc1LjUuMS4zLiBTZWNyZXQtS2V5IFBhY2tldCAoVGFnIDUpXG4nKw0KCQkJICAgJyAgICBsZW5ndGg6ICAgICAgICAgICAgICcrdGhpcy5wYWNrZXRMZW5ndGgrJ1xuJysNCgkJCSAgICcgICAgdmVyc2lvbjogICAgICAgICAgICAnK3RoaXMucHVibGljS2V5LnZlcnNpb24rJ1xuJysNCgkJCSAgICcgICAgY3JlYXRpb24gdGltZTogICAgICAnK3RoaXMucHVibGljS2V5LmNyZWF0aW9uVGltZSsnXG4nKw0KCQkJICAgJyAgICBleHBpcmF0aW9uIHRpbWU6ICAgICcrdGhpcy5wdWJsaWNLZXkuZXhwaXJhdGlvbisnXG4nKw0KCQkJICAgJyAgICBwdWJsaWNLZXlBbGdvcml0aG06ICcrdGhpcy5wdWJsaWNLZXkucHVibGljS2V5QWxnb3JpdGhtKydcbic7DQoJCQlicmVhazsNCgkJY2FzZSA3Og0KCQkJcmVzdWx0ICs9ICc1LjUuMS40LiBTZWNyZXQtU3Via2V5IFBhY2tldCAoVGFnIDcpXG4nKw0KCQkJICAgJyAgICBsZW5ndGg6ICAgICAgICAgICAgICcrdGhpcy5wYWNrZXRMZW5ndGgrJ1xuJysNCgkJCSAgICcgICAgdmVyc2lvblsxXTogICAgICAgICAnKyh0aGlzLnZlcnNpb24gPT0gNCkrJ1xuJysNCgkJCSAgICcgICAgY3JlYXRpb250aW1lWzRdOiAgICAnK3RoaXMuY3JlYXRpb25UaW1lKydcbicrDQoJCQkgICAnICAgIGV4cGlyYXRpb25bMl06ICAgICAgJyt0aGlzLmV4cGlyYXRpb24rJ1xuJysNCgkJCSAgICcgICAgcHVibGljS2V5QWxnb3JpdGhtOiAnK3RoaXMucHVibGljS2V5QWxnb3JpdGhtKydcbic7DQoJCQlicmVhazsNCgkJZGVmYXVsdDoNCgkJCXJlc3VsdCArPSAndW5rbm93biBrZXkgbWF0ZXJpYWwgcGFja2V0XG4nOw0KCQl9DQoJCWlmICh0aGlzLk1QSXMgIT0gbnVsbCkgew0KCQkJcmVzdWx0ICs9ICJQdWJsaWMgS2V5IE1QSXM6XG4iOw0KCQkJZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLk1QSXMubGVuZ3RoOyBpKyspIHsNCiAgICAgIAkgIAlyZXN1bHQgKz0gdGhpcy5NUElzW2ldLnRvU3RyaW5nKCk7DQogICAgICAgIAl9DQoJCX0NCgkJaWYgKHRoaXMucHVibGljS2V5ICE9IG51bGwgJiYgdGhpcy5wdWJsaWNLZXkuTVBJcyAhPSBudWxsKSB7DQoJCQlyZXN1bHQgKz0gIlB1YmxpYyBLZXkgTVBJczpcbiI7DQoJCQlmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucHVibGljS2V5Lk1QSXMubGVuZ3RoOyBpKyspIHsNCgkgICAgICAJICAJcmVzdWx0ICs9IHRoaXMucHVibGljS2V5Lk1QSXNbaV0udG9TdHJpbmcoKTsNCiAgICAgICAgCX0NCgkJfQ0KCQlpZiAodGhpcy5zZWNNUElzICE9IG51bGwpIHsNCgkJCXJlc3VsdCArPSAiU2VjcmV0IEtleSBNUElzOlxuIjsNCgkJCWZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zZWNNUElzLmxlbmd0aDsgaSsrKSB7DQoJCSAgICAgIAkgIHJlc3VsdCArPSB0aGlzLnNlY01QSXNbaV0udG9TdHJpbmcoKTsNCgkJICAgICAgICB9DQoJCX0NCgkJDQoJCWlmICh0aGlzLnN1YktleVNpZ25hdHVyZSAhPSBudWxsKQ0KCQkJcmVzdWx0ICs9ICJzdWJLZXkgU2lnbmF0dXJlOlxuIit0aGlzLnN1YktleVNpZ25hdHVyZS50b1N0cmluZygpOw0KCQkNCgkJaWYgKHRoaXMuc3ViS2V5UmV2b2NhdGlvblNpZ25hdHVyZSAhPSBudWxsICkNCgkJCXJlc3VsdCArPSAic3ViS2V5IFJldm9jYXRpb24gU2lnbmF0dXJlOlxuIit0aGlzLnN1YktleVJldm9jYXRpb25TaWduYXR1cmUudG9TdHJpbmcoKTsNCiAgICAgICAgcmV0dXJuIHJlc3VsdDsNCgl9DQoJDQoJLyoqDQoJICogQ29udGludWUgcGFyc2luZyBwYWNrZXRzIGJlbG9uZ2luZyB0byB0aGUga2V5IG1hdGVyaWFsIHN1Y2ggYXMgc2lnbmF0dXJlcw0KCSAqIEBwYXJhbSB7T2JqZWN0fSBwYXJlbnRfbm9kZSBUaGUgcGFyZW50IG9iamVjdA0KCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBJbnB1dCBzdHJpbmcgdG8gcmVhZCB0aGUgcGFja2V0KHMpIGZyb20NCgkgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIFN0YXJ0IHBvc2l0aW9uIGZvciB0aGUgcGFyc2VyDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBwYWNrZXQocykgb3IgcmVtYWluaW5nIGxlbmd0aCBvZiBpbnB1dA0KCSAqIEByZXR1cm4ge0ludGVnZXJ9IExlbmd0aCBvZiBub2RlcyByZWFkDQoJICovDQoJZnVuY3Rpb24gcmVhZF9ub2RlcyhwYXJlbnRfbm9kZSwgaW5wdXQsIHBvc2l0aW9uLCBsZW4pIHsNCgkJdGhpcy5wYXJlbnROb2RlID0gcGFyZW50X25vZGU7DQoJCWlmICh0aGlzLnRhZ1R5cGUgPT0gMTQpIHsgLy8gcHVibGljIHN1Yi1rZXkgcGFja2V0DQoJCQl2YXIgcG9zID0gcG9zaXRpb247DQoJCQl2YXIgcmVzdWx0ID0gbnVsbDsNCgkJCXdoaWxlIChpbnB1dC5sZW5ndGggIT0gcG9zKSB7DQoJCQkJdmFyIGwgPSBpbnB1dC5sZW5ndGggLSBwb3M7DQoJCQkJcmVzdWx0ID0gb3BlbnBncF9wYWNrZXQucmVhZF9wYWNrZXQoaW5wdXQsIHBvcywgbCk7DQoJCQkJaWYgKHJlc3VsdCA9PSBudWxsKSB7DQoJCQkJCXV0aWwucHJpbnRfZXJyb3IoIm9wZW5wZ3AucGFja2V0LmtleW1hdGVyaWFsLmpzXG4iKydbdXNlcl9rZXltYXRfcHViXXBhcnNpbmcgZW5kcyBoZXJlIEA6JyArIHBvcyArICIgbDoiICsgbCk7DQoJCQkJCWJyZWFrOw0KCQkJCX0gZWxzZSB7DQoJCQkJCQ0KCQkJCQlzd2l0Y2ggKHJlc3VsdC50YWdUeXBlKSB7DQoJCQkJCWNhc2UgMjogLy8gU2lnbmF0dXJlIFBhY2tldCBjZXJ0aWZpY2F0aW9uIHNpZ25hdHVyZQ0KCQkJCQkJaWYgKHJlc3VsdC5zaWduYXR1cmVUeXBlID09IDI0KSAgeyAvLyBzdWJrZXkgYmluZGluZyBzaWduYXR1cmUNCgkJCQkJCQl0aGlzLnN1YktleVNpZ25hdHVyZSA9IHJlc3VsdDsNCgkJCQkJCQlwb3MgKz0gcmVzdWx0LnBhY2tldExlbmd0aCArIHJlc3VsdC5oZWFkZXJMZW5ndGg7DQoJCQkJCQkJYnJlYWs7DQoJCQkJCQl9IGVsc2UgaWYgKHJlc3VsdC5zaWduYXR1cmVUeXBlID09IDQwKSB7IC8vIHN1YmtleSByZXZvY2F0aW9uIHNpZ25hdHVyZQ0KCQkJCQkJCXRoaXMuc3ViS2V5UmV2b2NhdGlvblNpZ25hdHVyZVt0aGlzLnN1YktleVJldm9jYXRpb25TaWduYXR1cmUubGVuZ3RoXSA9IHJlc3VsdDsNCgkJCQkJCQlwb3MgKz0gcmVzdWx0LnBhY2tldExlbmd0aCArIHJlc3VsdC5oZWFkZXJMZW5ndGg7DQoJCQkJCQkJYnJlYWs7DQoJCQkJCQl9IGVsc2Ugew0KCQkJCQkJCXV0aWwucHJpbnRfZXJyb3IoIm9wZW5wZ3AucGFja2V0LmtleW1hdGVyaWFsLmpzXG51bmtub3duIHNpZ25hdHVyZToiK3Jlc3VsdC50b1N0cmluZygpKTsNCgkJCQkJCX0NCgkJCQkJCQ0KCQkJCQlkZWZhdWx0Og0KCQkJCQkJdGhpcy5kYXRhID0gaW5wdXQ7DQoJCQkJCQl0aGlzLnBvc2l0aW9uID0gcG9zaXRpb24gLSB0aGlzLnBhcmVudE5vZGUucGFja2V0TGVuZ3RoOw0KCQkJCQkJdGhpcy5sZW4gPSBwb3MgLSBwb3NpdGlvbjsNCgkJCQkJCXJldHVybiB0aGlzLmxlbjsNCgkJCQkJCWJyZWFrOw0KCQkJCQl9DQoJCQkJfQ0KCQkJfQ0KCQkJdGhpcy5kYXRhID0gaW5wdXQ7DQoJCQl0aGlzLnBvc2l0aW9uID0gcG9zaXRpb24gLSB0aGlzLnBhcmVudE5vZGUucGFja2V0TGVuZ3RoOw0KCQkJdGhpcy5sZW4gPSBwb3MgLSBwb3NpdGlvbjsNCgkJCXJldHVybiB0aGlzLmxlbjsNCgkJfSBlbHNlIGlmICh0aGlzLnRhZ1R5cGUgPT0gNykgeyAvLyBwcml2YXRlIHN1Yi1rZXkgcGFja2V0DQoJCQl2YXIgcG9zID0gcG9zaXRpb247DQoJCQl3aGlsZSAoaW5wdXQubGVuZ3RoICE9IHBvcykgew0KCQkJCXZhciByZXN1bHQgPSBvcGVucGdwX3BhY2tldC5yZWFkX3BhY2tldChpbnB1dCwgcG9zLCBsZW4gLSAocG9zIC0gcG9zaXRpb24pKTsNCgkJCQlpZiAocmVzdWx0ID09IG51bGwpIHsNCgkJCQkJdXRpbC5wcmludF9lcnJvcigib3BlbnBncC5wYWNrZXQua2V5bWF0ZXJpYWwuanNcbiIrJ1t1c2VyX2tleW1hdF9wcml2XSBwYXJzaW5nIGVuZHMgaGVyZSBAOicgKyBwb3MpOw0KCQkJCQlicmVhazsNCgkJCQl9IGVsc2Ugew0KCQkJCQlzd2l0Y2ggKHJlc3VsdC50YWdUeXBlKSB7DQoJCQkJCWNhc2UgMjogLy8gU2lnbmF0dXJlIFBhY2tldCBjZXJ0aWZpY2F0aW9uIHNpZ25hdHVyZQ0KCQkJCQkJaWYgKHJlc3VsdC5zaWduYXR1cmVUeXBlID09IDI0KSAvLyBzdWJrZXkgZW1iZWRkZWQgc2lnbmF0dXJlDQoJCQkJCQkJdGhpcy5zdWJLZXlTaWduYXR1cmUgPSByZXN1bHQ7IA0KCQkJCQkJZWxzZSBpZiAocmVzdWx0LnNpZ25hdHVyZVR5cGUgPT0gNDApIC8vIHN1YmtleSByZXZvY2F0aW9uIHNpZ25hdHVyZQ0KCQkJCQkJCXRoaXMuc3ViS2V5UmV2b2NhdGlvblNpZ25hdHVyZVt0aGlzLnN1YktleVJldm9jYXRpb25TaWduYXR1cmUubGVuZ3RoXSA9IHJlc3VsdDsNCgkJCQkJCXBvcyArPSByZXN1bHQucGFja2V0TGVuZ3RoICsgcmVzdWx0LmhlYWRlckxlbmd0aDsNCgkJCQkJCWJyZWFrOw0KCQkJCQlkZWZhdWx0Og0KCQkJCQkJdGhpcy5kYXRhID0gaW5wdXQ7DQoJCQkJCQl0aGlzLnBvc2l0aW9uID0gcG9zaXRpb24gLSB0aGlzLnBhcmVudE5vZGUucGFja2V0TGVuZ3RoOw0KCQkJCQkJdGhpcy5sZW4gPSBwb3MgLSBwb3NpdGlvbjsNCgkJCQkJCXJldHVybiB0aGlzLmxlbjsNCgkJCQkJfQ0KCQkJCX0NCgkJCX0NCgkJCXRoaXMuZGF0YSA9IGlucHV0Ow0KCQkJdGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uIC0gdGhpcy5wYXJlbnROb2RlLnBhY2tldExlbmd0aDsNCgkJCXRoaXMubGVuID0gcG9zIC0gcG9zaXRpb247DQoJCQlyZXR1cm4gdGhpcy5sZW47DQoJCX0gZWxzZSB7DQoJCQl1dGlsLnByaW50X2Vycm9yKCJvcGVucGdwLnBhY2tldC5rZXltYXRlcmlhbC5qc1xuIisidW5rbm93biBwYXJlbnQgbm9kZSBmb3IgYSBrZXkgbWF0ZXJpYWwgcGFja2V0ICIrcGFyZW50X25vZGUudGFnVHlwZSk7DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBDaGVja3MgdGhlIHZhbGlkaXR5IGZvciB1c2FnZSBvZiB0aGlzIChzdWIpa2V5DQoJICogQHJldHVybiB7SW50ZWdlcn0gMCA9IGJhZCBrZXksIDEgPSBleHBpcmVkLCAyID0gcmV2b2tlZCwgMyA9IHZhbGlkDQoJICovDQoJZnVuY3Rpb24gdmVyaWZ5S2V5KCkgew0KCQlpZiAodGhpcy50YWdUeXBlID09IDE0KSB7DQoJCQlpZiAodGhpcy5zdWJLZXlTaWduYXR1cmUgPT0gbnVsbCkgew0KCQkJCXJldHVybiAwOw0KCQkJfQ0KCQkJaWYgKHRoaXMuc3ViS2V5U2lnbmF0dXJlLnZlcnNpb24gPT0gNCAmJg0KCQkJCXRoaXMuc3ViS2V5U2lnbmF0dXJlLmtleU5ldmVyRXhwaXJlcyAhPSBudWxsICYmDQoJCQkJIXRoaXMuc3ViS2V5U2lnbmF0dXJlLmtleU5ldmVyRXhwaXJlcyAmJg0KCQkJCW5ldyBEYXRlKCh0aGlzLnN1YktleVNpZ25hdHVyZS5rZXlFeHBpcmF0aW9uVGltZSoxMDAwKSsgdGhpcy5jcmVhdGlvblRpbWUuZ2V0VGltZSgpKSA8IG5ldyBEYXRlKCkpIHsNCgkJCQkgICAgcmV0dXJuIDE7DQoJCQkJfQ0KCQkJdmFyIGhhc2hkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDk5KSt0aGlzLnBhcmVudE5vZGUuaGVhZGVyLnN1YnN0cmluZygxKSt0aGlzLnBhcmVudE5vZGUuZGF0YSsNCgkJCVN0cmluZy5mcm9tQ2hhckNvZGUoMHg5OSkrdGhpcy5oZWFkZXIuc3Vic3RyaW5nKDEpK3RoaXMucGFja2V0ZGF0YTsNCgkJCWlmICghdGhpcy5zdWJLZXlTaWduYXR1cmUudmVyaWZ5KGhhc2hkYXRhLHRoaXMucGFyZW50Tm9kZSkpIHsNCgkJCQlyZXR1cm4gMDsNCgkJCX0NCgkJCWZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zdWJLZXlSZXZvY2F0aW9uU2lnbmF0dXJlLmxlbmd0aDsgaSsrKSB7DQoJCQkgICAgaWYgKHRoaXMuZ2V0S2V5SWQoKSA9PSB0aGlzLnN1YktleVJldm9jYXRpb25TaWduYXR1cmVbaV0ua2V5SWQpew0KCQkJICAgICAgICByZXR1cm4gMjsNCgkJCSAgICB9DQoJCQl9DQoJCX0NCgkJcmV0dXJuIDM7DQoJfQ0KDQoJLyoqDQoJICogQ2FsY3VsYXRlcyB0aGUga2V5IGlkIG9mIHRoZXkga2V5IA0KCSAqIEByZXR1cm4ge1N0cmluZ30gQSA4IGJ5dGUga2V5IGlkDQoJICovDQoJZnVuY3Rpb24gZ2V0S2V5SWQoKSB7DQoJCWlmICh0aGlzLnZlcnNpb24gPT0gNCkgew0KCQkJdmFyIGYgPSB0aGlzLmdldEZpbmdlcnByaW50KCk7DQoJCQlyZXR1cm4gZi5zdWJzdHJpbmcoMTIsMjApOw0KCQl9IGVsc2UgaWYgKHRoaXMudmVyc2lvbiA9PSAzICYmIHRoaXMucHVibGljS2V5QWxnb3JpdGhtID4gMCAmJiB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA8IDQpIHsNCgkJCXZhciBrZXlfaWQgPSB0aGlzLk1QSXNbMF0uc3Vic3RyaW5nKCh0aGlzLk1QSXNbMF0ubXBpQnl0ZUxlbmd0aC04KSk7DQoJCQl1dGlsLnByaW50X2RlYnVnKCJvcGVucGdwLm1zZy5wdWJsaWNrZXkgcmVhZF9ub2RlczpcbiIrIlYzIGtleSBJRDogIitrZXlfaWQpOw0KCQkJcmV0dXJuIGtleV9pZDsNCgkJfQ0KCX0NCgkNCgkvKioNCgkgKiBDYWxjdWxhdGVzIHRoZSBmaW5nZXJwcmludCBvZiB0aGUga2V5DQoJICogQHJldHVybiB7U3RyaW5nfSBBIHN0cmluZyBjb250YWluaW5nIHRoZSBmaW5nZXJwcmludA0KCSAqLw0KCWZ1bmN0aW9uIGdldEZpbmdlcnByaW50KCkgew0KCQlpZiAodGhpcy52ZXJzaW9uID09IDQpIHsNCgkJCXRvaGFzaCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHg5OSkrIFN0cmluZy5mcm9tQ2hhckNvZGUoKCh0aGlzLnBhY2tldGRhdGEubGVuZ3RoKSA+PiA4KSAmIDB4RkYpIA0KCQkJCSsgU3RyaW5nLmZyb21DaGFyQ29kZSgodGhpcy5wYWNrZXRkYXRhLmxlbmd0aCkgJiAweEZGKSt0aGlzLnBhY2tldGRhdGE7DQoJCQl1dGlsLnByaW50X2RlYnVnKCJvcGVucGdwLm1zZy5wdWJsaWNrZXkgY3JlYXRpbmcgc3Via2V5IGZpbmdlcnByaW50IGJ5IGhhc2hpbmc6Iit1dGlsLmhleHN0cmR1bXAodG9oYXNoKSsiXG5wdWJsaWNrZXlhbGdvcml0aG06ICIrdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0pOw0KCQkJcmV0dXJuIHN0cl9zaGExKHRvaGFzaCwgdG9oYXNoLmxlbmd0aCk7DQoJCX0gZWxzZSBpZiAodGhpcy52ZXJzaW9uID09IDMgJiYgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPiAwICYmIHRoaXMucHVibGljS2V5QWxnb3JpdGhtIDwgNCkgew0KCQkJcmV0dXJuIE1ENSh0aGlzLk1QSXNbMF0uTVBJKTsNCgkJfQ0KCX0NCgkNCgkvKg0KICAgICAqIENyZWF0ZXMgYW4gT3BlblBHUCBrZXkgcGFja2V0IGZvciB0aGUgZ2l2ZW4ga2V5LiBtdWNoIA0KCSAqIFRPRE8gaW4gcmVnYXJkcyB0byBzMmssIHN1YmtleXMuDQogICAgICogQHBhcmFtIHtJbnRlZ2VyfSBrZXlUeXBlIEZvbGxvd3MgdGhlIE9wZW5QR1AgYWxnb3JpdGhtIHN0YW5kYXJkLCANCgkgKiBJRSAxIGNvcnJlc3BvbmRzIHRvIFJTQS4NCiAgICAgKiBAcGFyYW0ge1JTQS5rZXlPYmplY3R9IGtleQ0KICAgICAqIEBwYXJhbSBwYXNzd29yZA0KICAgICAqIEBwYXJhbSBzMmtIYXNoDQogICAgICogQHBhcmFtIHN5bW1ldHJpY0VuY3J5cHRpb25BbGdvcml0aG0NCiAgICAgKiBAcGFyYW0gdGltZVBhY2tldA0KICAgICAqIEByZXR1cm4ge09iamVjdH0ge2JvZHk6IFtzdHJpbmddT3BlblBHUCBwYWNrZXQgYm9keSBjb250ZW50cywgDQoJCWhlYWRlcjogW3N0cmluZ10gT3BlblBHUCBwYWNrZXQgaGVhZGVyLCBzdHJpbmc6IFtzdHJpbmddIGhlYWRlcitib2R5fQ0KICAgICAqLw0KICAgIGZ1bmN0aW9uIHdyaXRlX3ByaXZhdGVfa2V5KGtleVR5cGUsIGtleSwgcGFzc3dvcmQsIHMya0hhc2gsIHN5bW1ldHJpY0VuY3J5cHRpb25BbGdvcml0aG0sIHRpbWVQYWNrZXQpew0KICAgICAgICB0aGlzLnN5bW1ldHJpY0VuY3J5cHRpb25BbGdvcml0aG0gPSBzeW1tZXRyaWNFbmNyeXB0aW9uQWxnb3JpdGhtOw0KCQl2YXIgdGFnID0gNTsNCgkJdmFyIGJvZHkgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDQpOw0KCQlib2R5ICs9IHRpbWVQYWNrZXQ7DQoJCXN3aXRjaChrZXlUeXBlKXsNCgkJY2FzZSAxOg0KCQkgICAgYm9keSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGtleVR5cGUpOy8vcHVibGljIGtleSBhbGdvDQoJCSAgICBib2R5ICs9IGtleS5uLnRvTVBJKCk7DQoJCSAgICBib2R5ICs9IGtleS5lZS50b01QSSgpOw0KCQkgICAgdmFyIGFsZ29yaXRobVN0YXJ0ID0gYm9keS5sZW5ndGg7DQoJCSAgICAvL2JlbG93IHNob3dzIHNrZS9zMmsNCgkJICAgIGlmKHBhc3N3b3JkKXsNCgkJICAgICAgICBib2R5ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMjU0KTsgLy9vY3RldCBvZiAyNTQgaW5kaWNhdGVzIHMyayB3aXRoIFNIQTENCgkJICAgICAgICAvL2lmIHMyayA9PSAyNTUsMjU0IHRoZW4gMSBvY3RldCBzeW1tZXRyaWMgZW5jcnlwdGlvbiBhbGdvDQoJCSAgICAgICAgYm9keSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuc3ltbWV0cmljRW5jcnlwdGlvbkFsZ29yaXRobSk7DQoJCSAgICAgICAgLy9pZiBzMmsgPT0gMjU1LDI1NCB0aGVuIHMyayBzcGVjaWZpZXINCgkJICAgICAgICBib2R5ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMyk7IC8vczJrIHNhbHQraXRlcg0KCQkgICAgICAgIGJvZHkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShzMmtIYXNoKTsNCgkJICAgICAgICAvLzggb2N0ZXQgc2FsdCB2YWx1ZQ0KCQkgICAgICAgIC8vMSBvY3RldCBjb3VudA0KCQkgICAgICAgIHZhciBjbGVhcnRleHRNUElzID0ga2V5LmQudG9NUEkoKSArIGtleS5wLnRvTVBJKCkgKyBrZXkucS50b01QSSgpICsga2V5LnUudG9NUEkoKTsNCgkJICAgICAgICB2YXIgc2hhMUhhc2ggPSBzdHJfc2hhMShjbGVhcnRleHRNUElzKTsNCiAgIAkJICAgICAgICB1dGlsLnByaW50X2RlYnVnX2hleHN0cl9kdW1wKCd3cml0ZV9wcml2YXRlX2tleSBzaGExOiAnLHNoYTFIYXNoKTsNCgkJICAgICAgICB2YXIgc2FsdCA9IG9wZW5wZ3BfY3J5cHRvX2dldFJhbmRvbUJ5dGVzKDgpOw0KCQkgICAgICAgIHV0aWwucHJpbnRfZGVidWdfaGV4c3RyX2R1bXAoJ3dyaXRlX3ByaXZhdGVfa2V5IFNhbHQ6ICcsc2FsdCk7DQoJCSAgICAgICAgYm9keSArPSBzYWx0Ow0KCQkgICAgICAgIHZhciBjID0gOTY7IC8vYyBvZiA5NiB0cmFuc2xhdGVzIHRvIGNvdW50IG9mIDY1NTM2DQoJCSAgICAgICAgYm9keSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpOw0KCQkgICAgICAgIHV0aWwucHJpbnRfZGVidWcoJ3dyaXRlX3ByaXZhdGVfa2V5IGM6ICcrIGMpOw0KCQkgICAgICAgIHZhciBzMmsgPSBuZXcgb3BlbnBncF90eXBlX3MyaygpOw0KCQkgICAgICAgIHZhciBoYXNoS2V5ID0gczJrLndyaXRlKDMsIHMya0hhc2gsIHBhc3N3b3JkLCBzYWx0LCBjKTsNCgkJICAgICAgICAvL2lmIHMyaywgSVYgb2Ygc2FtZSBsZW5ndGggYXMgY2lwaGVyJ3MgYmxvY2sNCgkJICAgICAgICBzd2l0Y2godGhpcy5zeW1tZXRyaWNFbmNyeXB0aW9uQWxnb3JpdGhtKXsNCgkJICAgICAgICBjYXNlIDM6DQoJCSAgICAgICAgICAgIHRoaXMuSVZMZW5ndGggPSA4Ow0KCQkgICAgICAgICAgICB0aGlzLklWID0gb3BlbnBncF9jcnlwdG9fZ2V0UmFuZG9tQnl0ZXModGhpcy5JVkxlbmd0aCk7DQogICAgICAgICAgICAJCWNpcGhlcnRleHRNUElzID0gbm9ybWFsX2NmYl9lbmNyeXB0KGZ1bmN0aW9uKGJsb2NrLCBrZXkpIHsNCiAgICAgICAgICAgICAgICAJCXZhciBjYXN0NSA9IG5ldyBvcGVucGdwX3N5bWVuY19jYXN0NSgpOw0KICAgICAgICAgICAgICAgIAkJY2FzdDUuc2V0S2V5KGtleSk7DQogICAgICAgICAgICAgICAgCQlyZXR1cm4gY2FzdDUuZW5jcnlwdCh1dGlsLnN0cjJiaW4oYmxvY2spKTsgDQogICAgICAgICAgICAJCX0sIHRoaXMuSVZMZW5ndGgsIHV0aWwuc3RyMmJpbihoYXNoS2V5LnN1YnN0cmluZygwLDE2KSksIGNsZWFydGV4dE1QSXMgKyBzaGExSGFzaCwgdGhpcy5JVik7DQogICAgICAgICAgICAJCWJvZHkgKz0gdGhpcy5JViArIGNpcGhlcnRleHRNUElzOw0KCQkgICAgICAgICAgICBicmVhazsNCgkJICAgICAgICBjYXNlIDc6DQoJCSAgICAgICAgY2FzZSA4Og0KCQkgICAgICAgIGNhc2UgOToNCgkJICAgICAgICAgICAgdGhpcy5JVkxlbmd0aCA9IDE2Ow0KCQkgICAgICAgICAgICB0aGlzLklWID0gb3BlbnBncF9jcnlwdG9fZ2V0UmFuZG9tQnl0ZXModGhpcy5JVkxlbmd0aCk7DQoJCSAgICAgICAgICAgIGNpcGhlcnRleHRNUElzID0gbm9ybWFsX2NmYl9lbmNyeXB0KEFFU2VuY3J5cHQsDQogICAgICAgICAgICAJCQkJdGhpcy5JVkxlbmd0aCwgaGFzaEtleSwgY2xlYXJ0ZXh0TVBJcyArIHNoYTFIYXNoLCB0aGlzLklWKTsNCiAgICAgICAgICAgIAkJYm9keSArPSB0aGlzLklWICsgY2lwaGVydGV4dE1QSXM7DQoJICAgICAgICAgICAgCWJyZWFrOw0KCQkgICAgICAgIH0NCgkJICAgIH0NCgkJICAgIGVsc2V7DQoJCSAgICAgICAgYm9keSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApOy8vMSBvY3RldCAtLSBzMmssIDAgZm9yIG5vIHMyaw0KCQkgICAgICAgIGJvZHkgKz0ga2V5LmQudG9NUEkoKSArIGtleS5wLnRvTVBJKCkgKyBrZXkucS50b01QSSgpICsga2V5LnUudG9NUEkoKTsNCgkJICAgICAgICB2YXIgY2hlY2tzdW0gPSB1dGlsLmNhbGNfY2hlY2tzdW0oa2V5LmQudG9NUEkoKSArIGtleS5wLnRvTVBJKCkgKyBrZXkucS50b01QSSgpICsga2V5LnUudG9NUEkoKSk7DQogICAgICAgIAkJYm9keSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNoZWNrc3VtLzB4MTAwKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoY2hlY2tzdW0lMHgxMDApOy8vREVQUkVDQVRFRDpzMmsgPT0gMCwgMjU1OiAyIG9jdGV0IGNoZWNrc3VtLCBzdW0gYWxsIG9jdGV0cyU2NTUzNg0KICAgICAgICAJCXV0aWwucHJpbnRfZGVidWdfaGV4c3RyX2R1bXAoJ3dyaXRlX3ByaXZhdGVfa2V5IGJhc2ljIGNoZWNrc3VtOiAnKyBjaGVja3N1bSk7DQoJCSAgICB9DQoJCSAgICBicmVhazsNCgkJZGVmYXVsdCA6DQoJCQlib2R5ID0gIiI7DQoJCQl1dGlsLnByaW50X2Vycm9yKCJvcGVucGdwLnBhY2tldC5rZXltYXRlcmlhbC5qc1xuIisnZXJyb3Igd3JpdGluZyBwcml2YXRlIGtleSwgdW5rbm93biB0eXBlIDonK2tleVR5cGUpOw0KICAgICAgICB9DQoJCXZhciBoZWFkZXIgPSBvcGVucGdwX3BhY2tldC53cml0ZV9wYWNrZXRfaGVhZGVyKHRhZyxib2R5Lmxlbmd0aCk7DQoJCXJldHVybiB7c3RyaW5nOiBoZWFkZXIrYm9keSAsIGhlYWRlcjogaGVhZGVyLCBib2R5OiBib2R5fTsNCiAgICB9DQoJDQoJLyoNCiAgICAgKiBTYW1lIGFzIHdyaXRlX3ByaXZhdGVfa2V5LCBidXQgaGFzIGxlc3MgaW5mb3JtYXRpb24gYmVjYXVzZSBvZiANCgkgKiBwdWJsaWMga2V5Lg0KICAgICAqIEBwYXJhbSB7SW50ZWdlcn0ga2V5VHlwZSBGb2xsb3dzIHRoZSBPcGVuUEdQIGFsZ29yaXRobSBzdGFuZGFyZCwgDQoJICogSUUgMSBjb3JyZXNwb25kcyB0byBSU0EuDQogICAgICogQHBhcmFtIHtSU0Eua2V5T2JqZWN0fSBrZXkNCiAgICAgKiBAcGFyYW0gdGltZVBhY2tldA0KICAgICAqIEByZXR1cm4ge09iamVjdH0ge2JvZHk6IFtzdHJpbmddT3BlblBHUCBwYWNrZXQgYm9keSBjb250ZW50cywgDQoJICogaGVhZGVyOiBbc3RyaW5nXSBPcGVuUEdQIHBhY2tldCBoZWFkZXIsIHN0cmluZzogW3N0cmluZ10gaGVhZGVyK2JvZHl9DQogICAgICovDQogICAgZnVuY3Rpb24gd3JpdGVfcHVibGljX2tleShrZXlUeXBlLCBrZXksIHRpbWVQYWNrZXQpew0KICAgICAgICB2YXIgdGFnID0gNjsNCiAgICAgICAgdmFyIGJvZHkgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDQpOw0KICAgICAgICBib2R5ICs9IHRpbWVQYWNrZXQ7DQoJCXN3aXRjaChrZXlUeXBlKXsNCgkJY2FzZSAxOg0KCQkgICAgYm9keSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDEpOy8vcHVibGljIGtleSBhbGdvDQoJCSAgICBib2R5ICs9IGtleS5uLnRvTVBJKCk7DQoJCSAgICBib2R5ICs9IGtleS5lZS50b01QSSgpOw0KCQkgICAgYnJlYWs7DQoJICAgIGRlZmF1bHQ6DQoJICAgIAl1dGlsLnByaW50X2Vycm9yKCJvcGVucGdwLnBhY2tldC5rZXltYXRlcmlhbC5qc1xuIisnZXJyb3Igd3JpdGluZyBwcml2YXRlIGtleSwgdW5rbm93biB0eXBlIDonK2tleVR5cGUpOw0KCSAgICB9DQogICAgICAgIHZhciBoZWFkZXIgPSBvcGVucGdwX3BhY2tldC53cml0ZV9wYWNrZXRfaGVhZGVyKHRhZyxib2R5Lmxlbmd0aCk7DQogICAgICAgIHJldHVybiB7c3RyaW5nOiBoZWFkZXIrYm9keSAsIGhlYWRlcjogaGVhZGVyLCBib2R5OiBib2R5fTsNCiAgICAgICAgfQ0KDQoJDQoJdGhpcy5yZWFkX3RhZzUgPSByZWFkX3RhZzU7DQoJdGhpcy5yZWFkX3RhZzYgPSByZWFkX3RhZzY7DQoJdGhpcy5yZWFkX3RhZzcgPSByZWFkX3RhZzc7DQoJdGhpcy5yZWFkX3RhZzE0ID0gcmVhZF90YWcxNDsNCgl0aGlzLnRvU3RyaW5nID0gdG9TdHJpbmc7DQoJdGhpcy5yZWFkX3B1Yl9rZXkgPSByZWFkX3B1Yl9rZXk7DQoJdGhpcy5yZWFkX3ByaXZfa2V5ID0gcmVhZF9wcml2X2tleTsNCgl0aGlzLmRlY3J5cHRTZWNyZXRNUElzID0gZGVjcnlwdFNlY3JldE1QSXM7DQoJdGhpcy5yZWFkX25vZGVzID0gcmVhZF9ub2RlczsNCgl0aGlzLnZlcmlmeUtleSA9IHZlcmlmeUtleTsNCgl0aGlzLmdldEtleUlkID0gZ2V0S2V5SWQ7DQoJdGhpcy5nZXRGaW5nZXJwcmludCA9IGdldEZpbmdlcnByaW50Ow0KCXRoaXMud3JpdGVfcHJpdmF0ZV9rZXkgPSB3cml0ZV9wcml2YXRlX2tleTsNCgl0aGlzLndyaXRlX3B1YmxpY19rZXkgPSB3cml0ZV9wdWJsaWNfa2V5Ow0KfQ0KLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0DQovLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3INCi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcg0KLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLA0KLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YNCi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VDQovLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLg0KLy8gDQovLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlDQovLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0ENCg0KLyoqDQogKiBAY2xhc3MNCiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIExpdGVyYWwgRGF0YSBQYWNrZXQgKFRhZyAxMSkNCiAqIA0KICogUkZDNDg4MCA1Ljk6IEEgTGl0ZXJhbCBEYXRhIHBhY2tldCBjb250YWlucyB0aGUgYm9keSBvZiBhIG1lc3NhZ2U7IGRhdGEgdGhhdA0KICogaXMgbm90IHRvIGJlIGZ1cnRoZXIgaW50ZXJwcmV0ZWQuDQogKi8NCmZ1bmN0aW9uIG9wZW5wZ3BfcGFja2V0X2xpdGVyYWxkYXRhKCkgew0KCXRoaXMudGFnVHlwZSA9IDExOw0KDQoJDQoJLyoqDQoJICogU2V0IHRoZSBwYWNrZXQgZGF0YSB0byBhIGphdmFzY3JpcHQgbmF0aXZlIHN0cmluZyBvciBhIHNxdWVuY2Ugb2YgDQoJICogYnl0ZXMuIENvbnZlcnNpb24gdG8gYSBwcm9wZXIgdXRmOCBlbmNvZGluZyB0YWtlcyBwbGFjZSB3aGVuIHRoZSANCgkgKiBwYWNrZXQgaXMgd3JpdHRlbi4NCgkgKiBAcGFyYW0ge1N0cmluZ30gc3RyIEFueSBuYXRpdmUgamF2YXNjcmlwdCBzdHJpbmcNCgkgKiBAcGFyYW0ge29wZW5wZ3BfcGFja2V0X2xpdGVyYWxkYXRhLmZvcm1hdHN9IGZvcm1hdCANCgkgKi8NCgl0aGlzLnNldF9kYXRhID0gZnVuY3Rpb24oc3RyLCBmb3JtYXQpIHsNCgkJdGhpcy5mb3JtYXQgPSBmb3JtYXQ7DQoJCXRoaXMuZGF0YSA9IHN0cjsNCgl9DQoNCgkvKioNCgkgKiBTZXQgdGhlIHBhY2tldCBkYXRhIHRvIHZhbHVlIHJlcHJlc2VudGVkIGJ5IHRoZSBwcm92aWRlZCBzdHJpbmcNCgkgKiBvZiBieXRlcyB0b2dldGhlciB3aXRoIHRoZSBhcHByb3ByaWF0ZSBjb252ZXJzaW9uIGZvcm1hdC4NCgkgKiBAcGFyYW0ge1N0cmluZ30gYnl0ZXMgVGhlIHN0cmluZyBvZiBieXRlcw0KCSAqIEBwYXJhbSB7b3BlbnBncF9wYWNrZXRfbGl0ZXJhbGRhdGEuZm9ybWF0c30gZm9ybWF0DQoJICovDQoJdGhpcy5zZXRfZGF0YV9ieXRlcyA9IGZ1bmN0aW9uKGJ5dGVzLCBmb3JtYXQpIHsNCgkJdGhpcy5mb3JtYXQgPSBmb3JtYXQ7DQoNCgkJaWYoZm9ybWF0ID09IG9wZW5wZ3BfcGFja2V0X2xpdGVyYWxkYXRhLmZvcm1hdHMudXRmOCkNCgkJCWJ5dGVzID0gdXRpbC5kZWNvZGVfdXRmOChieXRlcyk7DQoNCgkJdGhpcy5kYXRhID0gYnl0ZXM7DQoJfQ0KDQoJLyoqDQoJICogR2V0IHRoZSBieXRlIHNlcXVlbmNlIHJlcHJlc2VudGluZyB0aGUgbGl0ZXJhbCBwYWNrZXQgZGF0YQ0KCSAqIEByZXR1cm5zIHtTdHJpbmd9IEEgc2VxdWVuY2Ugb2YgYnl0ZXMNCgkgKi8NCgl0aGlzLmdldF9kYXRhX2J5dGVzID0gZnVuY3Rpb24oKSB7DQoJCWlmKHRoaXMuZm9ybWF0ID09IG9wZW5wZ3BfcGFja2V0X2xpdGVyYWxkYXRhLmZvcm1hdHMudXRmOCkNCgkJCXJldHVybiB1dGlsLmVuY29kZV91dGY4KHRoaXMuZGF0YSk7DQoJCWVsc2UNCgkJCXJldHVybiB0aGlzLmRhdGE7DQoJfQ0KCQ0KCQ0KDQoJLyoqDQoJICogUGFyc2luZyBmdW5jdGlvbiBmb3IgYSBsaXRlcmFsIGRhdGEgcGFja2V0ICh0YWcgMTEpLg0KCSAqIA0KCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDExIHBhY2tldA0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24NCgkgKiAgICAgICAgICAgIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4NCgkgKiAgICAgICAgICAgIExlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mDQoJICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvbg0KCSAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGF9IG9iamVjdCByZXByZXNlbnRhdGlvbg0KCSAqLw0KCXRoaXMucmVhZF9wYWNrZXQgPSBmdW5jdGlvbihpbnB1dCwgcG9zaXRpb24sIGxlbikgew0KCQl0aGlzLnBhY2tldExlbmd0aCA9IGxlbjsNCgkJLy8gLSBBIG9uZS1vY3RldCBmaWVsZCB0aGF0IGRlc2NyaWJlcyBob3cgdGhlIGRhdGEgaXMgZm9ybWF0dGVkLg0KDQoJCXZhciBmb3JtYXQgPSBpbnB1dFtwb3NpdGlvbl07DQoNCgkJdGhpcy5maWxlbmFtZSA9IHV0aWwuZGVjb2RlX3V0ZjgoaW5wdXQuc3Vic3RyKHBvc2l0aW9uICsgMiwgaW5wdXQNCgkJCQkuY2hhckNvZGVBdChwb3NpdGlvbiArIDEpKSk7DQoNCgkJdGhpcy5kYXRlID0gbmV3IERhdGUocGFyc2VJbnQoaW5wdXQuc3Vic3RyKHBvc2l0aW9uICsgMg0KCQkJCSsgaW5wdXQuY2hhckNvZGVBdChwb3NpdGlvbiArIDEpLCA0KSkgKiAxMDAwKTsNCg0KCQl2YXIgYnl0ZXMgPSBpbnB1dC5zdWJzdHJpbmcocG9zaXRpb24gKyA2DQoJCQkJKyBpbnB1dC5jaGFyQ29kZUF0KHBvc2l0aW9uICsgMSkpOw0KCQ0KCQl0aGlzLnNldF9kYXRhX2J5dGVzKGJ5dGVzLCBmb3JtYXQpOw0KCQlyZXR1cm4gdGhpczsNCgl9DQoNCgkvKioNCgkgKiBDcmVhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYWNrZXQNCgkgKiANCgkgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBUaGUgZGF0YSB0byBiZSBpbnNlcnRlZCBhcyBib2R5DQoJICogQHJldHVybiB7U3RyaW5nfSBzdHJpbmctcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhY2tldA0KCSAqLw0KCXRoaXMud3JpdGVfcGFja2V0ID0gZnVuY3Rpb24oZGF0YSkgew0KCQl0aGlzLnNldF9kYXRhKGRhdGEsIG9wZW5wZ3BfcGFja2V0X2xpdGVyYWxkYXRhLmZvcm1hdHMudXRmOCk7DQoJCXRoaXMuZmlsZW5hbWUgPSB1dGlsLmVuY29kZV91dGY4KCJtc2cudHh0Iik7DQoJCXRoaXMuZGF0ZSA9IG5ldyBEYXRlKCk7DQoNCgkJZGF0YSA9IHRoaXMuZ2V0X2RhdGFfYnl0ZXMoKTsNCg0KCQl2YXIgcmVzdWx0ID0gb3BlbnBncF9wYWNrZXQud3JpdGVfcGFja2V0X2hlYWRlcigxMSwgZGF0YS5sZW5ndGggKyA2DQoJCQkJKyB0aGlzLmZpbGVuYW1lLmxlbmd0aCk7DQoJCXJlc3VsdCArPSB0aGlzLmZvcm1hdDsNCgkJcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5maWxlbmFtZS5sZW5ndGgpOw0KCQlyZXN1bHQgKz0gdGhpcy5maWxlbmFtZTsNCgkJcmVzdWx0ICs9IFN0cmluZw0KCQkJCS5mcm9tQ2hhckNvZGUoKE1hdGgucm91bmQodGhpcy5kYXRlLmdldFRpbWUoKSAvIDEwMDApID4+IDI0KSAmIDB4RkYpOw0KCQlyZXN1bHQgKz0gU3RyaW5nDQoJCQkJLmZyb21DaGFyQ29kZSgoTWF0aC5yb3VuZCh0aGlzLmRhdGUuZ2V0VGltZSgpIC8gMTAwMCkgPj4gMTYpICYgMHhGRik7DQoJCXJlc3VsdCArPSBTdHJpbmcNCgkJCQkuZnJvbUNoYXJDb2RlKChNYXRoLnJvdW5kKHRoaXMuZGF0ZS5nZXRUaW1lKCkgLyAxMDAwKSA+PiA4KSAmIDB4RkYpOw0KCQlyZXN1bHQgKz0gU3RyaW5nDQoJCQkJLmZyb21DaGFyQ29kZShNYXRoLnJvdW5kKHRoaXMuZGF0ZS5nZXRUaW1lKCkgLyAxMDAwKSAmIDB4RkYpOw0KCQlyZXN1bHQgKz0gZGF0YTsNCgkJcmV0dXJuIHJlc3VsdDsNCgl9DQoNCgkvKioNCgkgKiBHZW5lcmF0ZXMgZGVidWcgb3V0cHV0IChwcmV0dHkgcHJpbnQpDQoJICogDQoJICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmcgd2hpY2ggZ2l2ZXMgc29tZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUga2V5bWF0ZXJpYWwNCgkgKi8NCgl0aGlzLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7DQoJCXJldHVybiAnNS45LiAgTGl0ZXJhbCBEYXRhIFBhY2tldCAoVGFnIDExKVxuJyArICcgICAgbGVuZ3RoOiAnDQoJCQkJKyB0aGlzLnBhY2tldExlbmd0aCArICdcbicgKyAnICAgIGZvcm1hdDogJyArIHRoaXMuZm9ybWF0DQoJCQkJKyAnXG4nICsgJyAgICBmaWxlbmFtZTonICsgdGhpcy5maWxlbmFtZSArICdcbicNCgkJCQkrICcgICAgZGF0ZTogICAnICsgdGhpcy5kYXRlICsgJ1xuJyArICcgICAgZGF0YTogIHwnDQoJCQkJKyB0aGlzLmRhdGEgKyAnfFxuJyArICcgICAgcmRhdGE6IHwnICsgdGhpcy5yZWFsX2RhdGEgKyAnfFxuJzsNCgl9DQp9DQoNCi8qKg0KICogRGF0YSB0eXBlcyBpbiB0aGUgbGl0ZXJhbCBwYWNrZXQNCiAqIEByZWFkb25seQ0KICogQGVudW0ge1N0cmluZ30NCiAqLw0Kb3BlbnBncF9wYWNrZXRfbGl0ZXJhbGRhdGEuZm9ybWF0cyA9IHsNCgkvKiogQmluYXJ5IGRhdGEgKi8NCgliaW5hcnk6ICdiJywNCgkvKiogVGV4dCBkYXRhICovDQoJdGV4dDogJ3QnLA0KCS8qKiBVdGY4IGRhdGEgKi8NCgl1dGY4OiAndScNCn07DQovLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHQNCi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkgNCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcg0KLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyDQovLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4NCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsDQovLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0KLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUNCi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuDQovLyANCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUNCi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQ0KDQovKioNCiAqIEBjbGFzcw0KICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgc3RyYW5nZSAiTWFya2VyIHBhY2tldCIgKFRhZyAxMCkNCiAqIA0KICogUkZDNDg4MCA1Ljg6IEFuIGV4cGVyaW1lbnRhbCB2ZXJzaW9uIG9mIFBHUCB1c2VkIHRoaXMgcGFja2V0IGFzIHRoZSBMaXRlcmFsDQogKiBwYWNrZXQsIGJ1dCBubyByZWxlYXNlZCB2ZXJzaW9uIG9mIFBHUCBnZW5lcmF0ZWQgTGl0ZXJhbCBwYWNrZXRzIHdpdGggdGhpcw0KICogdGFnLiBXaXRoIFBHUCA1LngsIHRoaXMgcGFja2V0IGhhcyBiZWVuIHJlYXNzaWduZWQgYW5kIGlzIHJlc2VydmVkIGZvciB1c2UgYXMNCiAqIHRoZSBNYXJrZXIgcGFja2V0Lg0KICogDQogKiBTdWNoIGEgcGFja2V0IE1VU1QgYmUgaWdub3JlZCB3aGVuIHJlY2VpdmVkLg0KICovDQpmdW5jdGlvbiBvcGVucGdwX3BhY2tldF9tYXJrZXIoKSB7DQoJdGhpcy50YWdUeXBlID0gMTA7DQoJLyoqDQoJICogUGFyc2luZyBmdW5jdGlvbiBmb3IgYSBsaXRlcmFsIGRhdGEgcGFja2V0ICh0YWcgMTApLg0KCSAqIA0KCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDEwIHBhY2tldA0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24NCgkgKiAgICAgICAgICAgIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4NCgkgKiAgICAgICAgICAgIExlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mDQoJICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvbg0KCSAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGF9IE9iamVjdCByZXByZXNlbnRhdGlvbg0KCSAqLw0KCWZ1bmN0aW9uIHJlYWRfcGFja2V0KGlucHV0LCBwb3NpdGlvbiwgbGVuKSB7DQoJCXRoaXMucGFja2V0TGVuZ3RoID0gMzsNCgkJaWYgKGlucHV0W3Bvc2l0aW9uXS5jaGFyQ29kZUF0KCkgPT0gMHg1MCAmJiAvLyBQDQoJCQkJaW5wdXRbcG9zaXRpb24gKyAxXS5jaGFyQ29kZUF0KCkgPT0gMHg0NyAmJiAvLyBHDQoJCQkJaW5wdXRbcG9zaXRpb24gKyAyXS5jaGFyQ29kZUF0KCkgPT0gMHg1MCkgLy8gUA0KCQkJcmV0dXJuIHRoaXM7DQoJCS8vIG1hcmtlciBwYWNrZXQgZG9lcyBub3QgY29udGFpbiAiUEdQIg0KCQlyZXR1cm4gbnVsbDsNCgl9DQoNCgkvKioNCgkgKiBHZW5lcmF0ZXMgRGVidWcgb3V0cHV0DQoJICogDQoJICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmcgd2hpY2ggZ2l2ZXMgc29tZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgDQoJICoga2V5bWF0ZXJpYWwNCgkgKi8NCglmdW5jdGlvbiB0b1N0cmluZygpIHsNCgkJcmV0dXJuICI1LjguICBNYXJrZXIgUGFja2V0IChPYnNvbGV0ZSBMaXRlcmFsIFBhY2tldCkgKFRhZyAxMClcbiINCgkJCQkrICIgICAgIHBhY2tldCByZWFkczogXCJQR1BcIlxuIjsNCgl9DQoNCgl0aGlzLnJlYWRfcGFja2V0ID0gcmVhZF9wYWNrZXQ7DQoJdGhpcy50b1N0cmluZyA9IHRvU3RyaW5nOw0KfQ0KLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0DQovLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3INCi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcg0KLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLA0KLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YNCi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VDQovLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLg0KLy8gDQovLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlDQovLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0ENCg0KLyoqDQogKiBAY2xhc3MNCiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIE1vZGlmaWNhdGlvbiBEZXRlY3Rpb24gQ29kZSBQYWNrZXQgKFRhZyAxOSkNCiAqIA0KICogUkZDNDg4MCA1LjE0OiBUaGUgTW9kaWZpY2F0aW9uIERldGVjdGlvbiBDb2RlIHBhY2tldCBjb250YWlucyBhIFNIQS0xIGhhc2ggb2YNCiAqIHBsYWludGV4dCBkYXRhLCB3aGljaCBpcyB1c2VkIHRvIGRldGVjdCBtZXNzYWdlIG1vZGlmaWNhdGlvbi4gSXQgaXMgb25seSB1c2VkDQogKiB3aXRoIGEgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgSW50ZWdyaXR5IFByb3RlY3RlZCBEYXRhIHBhY2tldC4gVGhlDQogKiBNb2RpZmljYXRpb24gRGV0ZWN0aW9uIENvZGUgcGFja2V0IE1VU1QgYmUgdGhlIGxhc3QgcGFja2V0IGluIHRoZSBwbGFpbnRleHQNCiAqIGRhdGEgdGhhdCBpcyBlbmNyeXB0ZWQgaW4gdGhlIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIEludGVncml0eSBQcm90ZWN0ZWQNCiAqIERhdGEgcGFja2V0LCBhbmQgTVVTVCBhcHBlYXIgaW4gbm8gb3RoZXIgcGxhY2UuDQogKi8NCg0KZnVuY3Rpb24gb3BlbnBncF9wYWNrZXRfbW9kaWZpY2F0aW9uZGV0ZWN0aW9uY29kZSgpIHsNCgl0aGlzLnRhZ1R5cGUgPSAxOTsNCgl0aGlzLmhhc2ggPSBudWxsOw0KCS8qKg0KCSAqIHBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgbW9kaWZpY2F0aW9uIGRldGVjdGlvbiBjb2RlIHBhY2tldCAodGFnIDE5KS4NCgkgKiANCgkgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgcGF5bG9hZCBvZiBhIHRhZyAxOSBwYWNrZXQNCgkgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uDQoJICogICAgICAgICAgICBwb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZw0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuDQoJICogICAgICAgICAgICBsZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZg0KCSAqICAgICAgICAgICAgaW5wdXQgYXQgcG9zaXRpb24NCgkgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhfSBvYmplY3QgcmVwcmVzZW50YXRpb24NCgkgKi8NCglmdW5jdGlvbiByZWFkX3BhY2tldChpbnB1dCwgcG9zaXRpb24sIGxlbikgew0KCQl0aGlzLnBhY2tldExlbmd0aCA9IGxlbjsNCg0KCQlpZiAobGVuICE9IDIwKSB7DQoJCQl1dGlsDQoJCQkJCS5wcmludF9lcnJvcigib3BlbnBncC5wYWNrZXQubW9kaWZpY2F0aW9uZGV0ZWN0aW9uY29kZS5qc1xuIg0KCQkJCQkJCSsgJ2ludmFsaWQgbGVuZ3RoIGZvciBhIG1vZGlmaWNhdGlvbiBkZXRlY3Rpb24gY29kZSBwYWNrZXQhJw0KCQkJCQkJCSsgbGVuKTsNCgkJCXJldHVybiBudWxsOw0KCQl9DQoJCS8vIC0gQSAyMC1vY3RldCBTSEEtMSBoYXNoIG9mIHRoZSBwcmVjZWRpbmcgcGxhaW50ZXh0IGRhdGEgb2YgdGhlDQoJCS8vIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIEludGVncml0eSBQcm90ZWN0ZWQgRGF0YSBwYWNrZXQsDQoJCS8vIGluY2x1ZGluZyBwcmVmaXggZGF0YSwgdGhlIHRhZyBvY3RldCwgYW5kIGxlbmd0aCBvY3RldCBvZiB0aGUNCgkJLy8gTW9kaWZpY2F0aW9uIERldGVjdGlvbiBDb2RlIHBhY2tldC4NCgkJdGhpcy5oYXNoID0gaW5wdXQuc3Vic3RyaW5nKHBvc2l0aW9uLCBwb3NpdGlvbiArIDIwKTsNCgkJcmV0dXJuIHRoaXM7DQoJfQ0KDQoJLyoNCgkgKiB0aGlzIHBhY2tldCBpcyBjcmVhdGVkIHdpdGhpbiB0aGUgZW5jcnlwdGVkaW50ZWdyaXR5cHJvdGVjdGVkIHBhY2tldA0KCSAqIGZ1bmN0aW9uIHdyaXRlX3BhY2tldChkYXRhKSB7IH0NCgkgKi8NCg0KCS8qKg0KCSAqIGdlbmVyYXRlcyBkZWJ1ZyBvdXRwdXQgKHByZXR0eSBwcmludCkNCgkgKiANCgkgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyB3aGljaCBnaXZlcyBzb21lIGluZm9ybWF0aW9uIGFib3V0IHRoZSANCgkgKiBtb2RpZmljYXRpb24gZGV0ZWN0aW9uIGNvZGUNCgkgKi8NCglmdW5jdGlvbiB0b1N0cmluZygpIHsNCgkJcmV0dXJuICc1LjE0IE1vZGlmaWNhdGlvbiBkZXRlY3Rpb24gY29kZSBwYWNrZXRcbicgKyAnICAgIGJ5dGVzICgnDQoJCQkJKyB0aGlzLmhhc2gubGVuZ3RoICsgJyk6IFsnICsgdXRpbC5oZXhzdHJkdW1wKHRoaXMuaGFzaCkgKyAnXSc7DQoJfQ0KCXRoaXMucmVhZF9wYWNrZXQgPSByZWFkX3BhY2tldDsNCgl0aGlzLnRvU3RyaW5nID0gdG9TdHJpbmc7DQp9Ow0KLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0DQovLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3INCi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcg0KLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLA0KLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YNCi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VDQovLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLg0KLy8gDQovLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlDQovLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0ENCg0KLyoqDQogKiBAY2xhc3MNCiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIE9uZS1QYXNzIFNpZ25hdHVyZSBQYWNrZXRzIChUYWcgNCkNCiAqIA0KICogUkZDNDg4MCA1LjQ6DQogKiBUaGUgT25lLVBhc3MgU2lnbmF0dXJlIHBhY2tldCBwcmVjZWRlcyB0aGUgc2lnbmVkIGRhdGEgYW5kIGNvbnRhaW5zDQogKiBlbm91Z2ggaW5mb3JtYXRpb24gdG8gYWxsb3cgdGhlIHJlY2VpdmVyIHRvIGJlZ2luIGNhbGN1bGF0aW5nIGFueQ0KICogaGFzaGVzIG5lZWRlZCB0byB2ZXJpZnkgdGhlIHNpZ25hdHVyZS4gIEl0IGFsbG93cyB0aGUgU2lnbmF0dXJlDQogKiBwYWNrZXQgdG8gYmUgcGxhY2VkIGF0IHRoZSBlbmQgb2YgdGhlIG1lc3NhZ2UsIHNvIHRoYXQgdGhlIHNpZ25lcg0KICogY2FuIGNvbXB1dGUgdGhlIGVudGlyZSBzaWduZWQgbWVzc2FnZSBpbiBvbmUgcGFzcy4NCiAqLw0KZnVuY3Rpb24gb3BlbnBncF9wYWNrZXRfb25lcGFzc3NpZ25hdHVyZSgpIHsNCgl0aGlzLnRhZ1R5cGUgPSA0Ow0KCXRoaXMudmVyc2lvbiA9IG51bGw7IC8vIEEgb25lLW9jdGV0IHZlcnNpb24gbnVtYmVyLiAgVGhlIGN1cnJlbnQgdmVyc2lvbiBpcyAzLg0KCXRoaXMudHlwZSA9IG51bGw7IAkgLy8gQSBvbmUtb2N0ZXQgc2lnbmF0dXJlIHR5cGUuICBTaWduYXR1cmUgdHlwZXMgYXJlIGRlc2NyaWJlZCBpbiBSRkM0ODgwIFNlY3Rpb24gNS4yLjEuDQoJdGhpcy5oYXNoQWxnb3JpdGhtID0gbnVsbDsgCSAgIC8vIEEgb25lLW9jdGV0IG51bWJlciBkZXNjcmliaW5nIHRoZSBoYXNoIGFsZ29yaXRobSB1c2VkLiAoU2VlIFJGQzQ4ODAgOS40KQ0KCXRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gbnVsbDsJICAgICAvLyBBIG9uZS1vY3RldCBudW1iZXIgZGVzY3JpYmluZyB0aGUgcHVibGljLWtleSBhbGdvcml0aG0gdXNlZC4gKFNlZSBSRkM0ODgwIDkuMSkNCgl0aGlzLnNpZ25pbmdLZXlJZCA9IG51bGw7IC8vIEFuIGVpZ2h0LW9jdGV0IG51bWJlciBob2xkaW5nIHRoZSBLZXkgSUQgb2YgdGhlIHNpZ25pbmcga2V5Lg0KCXRoaXMuZmxhZ3MgPSBudWxsOyAJLy8gIEEgb25lLW9jdGV0IG51bWJlciBob2xkaW5nIGEgZmxhZyBzaG93aW5nIHdoZXRoZXIgdGhlIHNpZ25hdHVyZSBpcyBuZXN0ZWQuICBBIHplcm8gdmFsdWUgaW5kaWNhdGVzIHRoYXQgdGhlIG5leHQgcGFja2V0IGlzIGFub3RoZXIgT25lLVBhc3MgU2lnbmF0dXJlIHBhY2tldCB0aGF0IGRlc2NyaWJlcyBhbm90aGVyIHNpZ25hdHVyZSB0byBiZSBhcHBsaWVkIHRvIHRoZSBzYW1lIG1lc3NhZ2UgZGF0YS4NCg0KCS8qKg0KCSAqIHBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgb25lLXBhc3Mgc2lnbmF0dXJlIHBhY2tldCAodGFnIDQpLg0KCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBwYXlsb2FkIG9mIGEgdGFnIDQgcGFja2V0DQoJICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBwb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZw0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuIGxlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mIGlucHV0IGF0IHBvc2l0aW9uDQoJICogQHJldHVybiB7b3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkZGF0YX0gb2JqZWN0IHJlcHJlc2VudGF0aW9uDQoJICovDQoJZnVuY3Rpb24gcmVhZF9wYWNrZXQoaW5wdXQsIHBvc2l0aW9uLCBsZW4pIHsNCgkJdGhpcy5wYWNrZXRMZW5ndGggPSBsZW47DQoJCXZhciBteXBvcyA9IHBvc2l0aW9uOw0KCQkvLyBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlci4gIFRoZSBjdXJyZW50IHZlcnNpb24gaXMgMy4NCgkJdGhpcy52ZXJzaW9uID0gaW5wdXQuY2hhckNvZGVBdChteXBvcysrKTsNCg0KCSAgICAgLy8gQSBvbmUtb2N0ZXQgc2lnbmF0dXJlIHR5cGUuICBTaWduYXR1cmUgdHlwZXMgYXJlIGRlc2NyaWJlZCBpbg0KCSAgICAgLy8gICBTZWN0aW9uIDUuMi4xLg0KCQl0aGlzLnR5cGUgPSBpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspOw0KDQoJICAgICAvLyBBIG9uZS1vY3RldCBudW1iZXIgZGVzY3JpYmluZyB0aGUgaGFzaCBhbGdvcml0aG0gdXNlZC4NCgkJdGhpcy5oYXNoQWxnb3JpdGhtID0gaW5wdXQuY2hhckNvZGVBdChteXBvcysrKTsNCg0KCSAgICAgLy8gQSBvbmUtb2N0ZXQgbnVtYmVyIGRlc2NyaWJpbmcgdGhlIHB1YmxpYy1rZXkgYWxnb3JpdGhtIHVzZWQuDQoJCXRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gaW5wdXQuY2hhckNvZGVBdChteXBvcysrKTsNCgkgICAgIC8vIEFuIGVpZ2h0LW9jdGV0IG51bWJlciBob2xkaW5nIHRoZSBLZXkgSUQgb2YgdGhlIHNpZ25pbmcga2V5Lg0KCQl0aGlzLnNpZ25pbmdLZXlJZCA9IG5ldyBvcGVucGdwX3R5cGVfa2V5aWQoKTsNCgkJdGhpcy5zaWduaW5nS2V5SWQucmVhZF9wYWNrZXQoaW5wdXQsbXlwb3MpOw0KCQlteXBvcyArPSA4Ow0KCQkNCgkgICAgIC8vIEEgb25lLW9jdGV0IG51bWJlciBob2xkaW5nIGEgZmxhZyBzaG93aW5nIHdoZXRoZXIgdGhlIHNpZ25hdHVyZQ0KCSAgICAgLy8gICBpcyBuZXN0ZWQuICBBIHplcm8gdmFsdWUgaW5kaWNhdGVzIHRoYXQgdGhlIG5leHQgcGFja2V0IGlzDQoJICAgICAvLyAgIGFub3RoZXIgT25lLVBhc3MgU2lnbmF0dXJlIHBhY2tldCB0aGF0IGRlc2NyaWJlcyBhbm90aGVyDQoJICAgICAvLyAgIHNpZ25hdHVyZSB0byBiZSBhcHBsaWVkIHRvIHRoZSBzYW1lIG1lc3NhZ2UgZGF0YS4NCgkJdGhpcy5mbGFncyA9IGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKyk7DQoJCXJldHVybiB0aGlzOw0KCX0NCg0KCS8qKg0KCSAqIGNyZWF0ZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBvbmUtcGFzcyBzaWduYXR1cmUgcGFja2V0DQoJICogQHBhcmFtIHtJbnRlZ2VyfSB0eXBlIFNpZ25hdHVyZSB0eXBlcyBhcyBkZXNjcmliZWQgaW4gUkZDNDg4MCBTZWN0aW9uIDUuMi4xLg0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gaGFzaGFsZ29yaXRobSB0aGUgaGFzaCBhbGdvcml0aG0gdXNlZCB3aXRoaW4gdGhlIHNpZ25hdHVyZQ0KCSAqIEBwYXJhbSB7b3BlbnBncF9tc2dfcHJpdmF0ZWtleX0gcHJpdmF0ZWtleSB0aGUgcHJpdmF0ZSBrZXkgdXNlZCB0byBnZW5lcmF0ZSB0aGUgc2lnbmF0dXJlDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggbGVuZ3RoIG9mIGRhdGEgdG8gYmUgc2lnbmVkDQoJICogQHBhcmFtIHtib29sZWFufSBuZXN0ZWQgYm9vbGVhbiBzaG93aW5nIHdoZXRoZXIgdGhlIHNpZ25hdHVyZSBpcyBuZXN0ZWQuIA0KCSAqICAidHJ1ZSIgaW5kaWNhdGVzIHRoYXQgdGhlIG5leHQgcGFja2V0IGlzIGFub3RoZXIgT25lLVBhc3MgU2lnbmF0dXJlIHBhY2tldA0KCSAqICAgdGhhdCBkZXNjcmliZXMgYW5vdGhlciBzaWduYXR1cmUgdG8gYmUgYXBwbGllZCB0byB0aGUgc2FtZSBtZXNzYWdlIGRhdGEuIA0KCSAqIEByZXR1cm4ge1N0cmluZ30gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBvbmUtcGFzcyBzaWduYXR1cmUgcGFja2V0DQoJICovDQoJZnVuY3Rpb24gd3JpdGVfcGFja2V0KHR5cGUsIGhhc2hhbGdvcml0aG0sIHByaXZhdGVrZXksbGVuZ3RoLCBuZXN0ZWQpIHsNCgkJdmFyIHJlc3VsdCA9IiI7IA0KCQkNCgkJcmVzdWx0ICs9IG9wZW5wZ3BfcGFja2V0LndyaXRlX3BhY2tldF9oZWFkZXIoNCwxMyk7DQoJCXJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDMpOw0KCQlyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh0eXBlKTsNCgkJcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoaGFzaGFsZ29yaXRobSk7DQoJCXJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHByaXZhdGVrZXkucHJpdmF0ZUtleVBhY2tldC5wdWJsaWNLZXkucHVibGljS2V5QWxnb3JpdGhtKTsNCgkJcmVzdWx0ICs9IHByaXZhdGVrZXkuZ2V0S2V5SWQoKTsNCgkJaWYgKG5lc3RlZCkNCgkJCXJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApOw0KCQllbHNlDQoJCQlyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgxKTsNCgkJDQoJCXJldHVybiByZXN1bHQ7DQoJfQ0KCQ0KCS8qKg0KCSAqIGdlbmVyYXRlcyBkZWJ1ZyBvdXRwdXQgKHByZXR0eSBwcmludCkNCgkgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyB3aGljaCBnaXZlcyBzb21lIGluZm9ybWF0aW9uIGFib3V0IHRoZSBvbmUtcGFzcyBzaWduYXR1cmUgcGFja2V0DQoJICovDQoJZnVuY3Rpb24gdG9TdHJpbmcoKSB7DQoJCXJldHVybiAnNS40LiAgT25lLVBhc3MgU2lnbmF0dXJlIFBhY2tldHMgKFRhZyA0KVxuJysNCgkJCSAgICcgICAgbGVuZ3RoOiAnK3RoaXMucGFja2V0TGVuZ3RoKydcbicrDQoJCQkgICAnICAgIHR5cGU6ICAgJyt0aGlzLnR5cGUrJ1xuJysNCgkJCSAgICcgICAga2V5SUQ6ICAnK3RoaXMuc2lnbmluZ0tleUlkLnRvU3RyaW5nKCkrJ1xuJysNCgkJCSAgICcgICAgaGFzaEE6ICAnK3RoaXMuaGFzaEFsZ29yaXRobSsnXG4nKw0KCQkJICAgJyAgICBwdWJLZXlBOicrdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0rJ1xuJysNCgkJCSAgICcgICAgZmxhZ3M6ICAnK3RoaXMuZmxhZ3MrJ1xuJysNCgkJCSAgICcgICAgdmVyc2lvbjonK3RoaXMudmVyc2lvbisnXG4nOw0KCX0NCgkNCgl0aGlzLnJlYWRfcGFja2V0ID0gcmVhZF9wYWNrZXQ7DQoJdGhpcy50b1N0cmluZyA9IHRvU3RyaW5nOw0KCXRoaXMud3JpdGVfcGFja2V0ID0gd3JpdGVfcGFja2V0Ow0KfTsNCi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdA0KLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSA0KLy8gDQovLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yDQovLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXINCi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLg0KLy8gDQovLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwNCi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mDQovLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQ0KLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4NCi8vIA0KLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQ0KLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBDQoNCi8qKg0KICogQGNsYXNzDQogKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBTaWduYXR1cmUgUGFja2V0IChUYWcgMikNCiAqIA0KICogUkZDNDQ4MCA1LjI6DQogKiBBIFNpZ25hdHVyZSBwYWNrZXQgZGVzY3JpYmVzIGEgYmluZGluZyBiZXR3ZWVuIHNvbWUgcHVibGljIGtleSBhbmQNCiAqIHNvbWUgZGF0YS4gIFRoZSBtb3N0IGNvbW1vbiBzaWduYXR1cmVzIGFyZSBhIHNpZ25hdHVyZSBvZiBhIGZpbGUgb3IgYQ0KICogYmxvY2sgb2YgdGV4dCwgYW5kIGEgc2lnbmF0dXJlIHRoYXQgaXMgYSBjZXJ0aWZpY2F0aW9uIG9mIGEgVXNlciBJRC4NCiAqLw0KZnVuY3Rpb24gb3BlbnBncF9wYWNrZXRfc2lnbmF0dXJlKCkgew0KCXRoaXMudGFnVHlwZSA9IDI7DQoJdGhpcy5zaWduYXR1cmVUeXBlID0gbnVsbDsNCgl0aGlzLmNyZWF0aW9uVGltZSA9IG51bGw7DQoJdGhpcy5rZXlJZCA9IG51bGw7DQoJdGhpcy5zaWduYXR1cmVEYXRhID0gbnVsbDsNCgl0aGlzLnNpZ25hdHVyZUV4cGlyYXRpb25UaW1lID0gbnVsbDsNCgl0aGlzLnNpZ25hdHVyZU5ldmVyRXhwaXJlcyA9IG51bGw7DQoJdGhpcy5zaWduZWRIYXNoVmFsdWUgPSBudWxsOw0KCXRoaXMuTVBJcyA9IG51bGw7DQoJdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSBudWxsOyANCgl0aGlzLmhhc2hBbGdvcml0aG0gPSBudWxsOw0KCXRoaXMuZXhwb3J0YWJsZSA9IG51bGw7DQoJdGhpcy50cnVzdExldmVsID0gbnVsbDsNCgl0aGlzLnRydXN0QW1vdW50ID0gbnVsbDsNCgl0aGlzLnJlZ3VsYXJfZXhwcmVzc2lvbiA9IG51bGw7DQoJdGhpcy5yZXZvY2FibGUgPSBudWxsOw0KCXRoaXMua2V5RXhwaXJhdGlvblRpbWUgPSBudWxsOw0KCXRoaXMua2V5TmV2ZXJFeHBpcmVzID0gbnVsbDsNCgl0aGlzLnByZWZlcnJlZFN5bW1ldHJpY0FsZ29yaXRobXMgPSBudWxsOw0KCXRoaXMucmV2b2NhdGlvbktleUNsYXNzID0gbnVsbDsNCgl0aGlzLnJldm9jYXRpb25LZXlBbGdvcml0aG0gPSBudWxsOw0KCXRoaXMucmV2b2NhdGlvbktleUZpbmdlcnByaW50ID0gbnVsbDsNCgl0aGlzLmlzc3VlcktleUlkID0gbnVsbDsNCgl0aGlzLm5vdGF0aW9uRmxhZ3MgPSBudWxsOyANCgl0aGlzLm5vdGF0aW9uTmFtZSA9IG51bGw7DQoJdGhpcy5ub3RhdGlvblZhbHVlID0gbnVsbDsNCgl0aGlzLnByZWZlcnJlZEhhc2hBbGdvcml0aG1zID0gbnVsbDsNCgl0aGlzLnByZWZlcnJlZENvbXByZXNzaW9uQWxnb3JpdGhtcyA9IG51bGw7DQoJdGhpcy5rZXlTZXJ2ZXJQcmVmZXJlbmNlcyA9IG51bGw7DQoJdGhpcy5wcmVmZXJyZWRLZXlTZXJ2ZXIgPSBudWxsOw0KCXRoaXMuaXNQcmltYXJ5VXNlcklEID0gbnVsbDsNCgl0aGlzLnBvbGljeVVSSSA9IG51bGw7DQoJdGhpcy5rZXlGbGFncyA9IG51bGw7DQoJdGhpcy5zaWduZXJzVXNlcklkID0gbnVsbDsNCgl0aGlzLnJlYXNvbkZvclJldm9jYXRpb25GbGFnID0gbnVsbDsNCgl0aGlzLnJlYXNvbkZvclJldm9jYXRpb25TdHJpbmcgPSBudWxsOw0KCXRoaXMuc2lnbmF0dXJlVGFyZ2V0UHVibGljS2V5QWxnb3JpdGhtID0gbnVsbDsNCgl0aGlzLnNpZ25hdHVyZVRhcmdldEhhc2hBbGdvcml0aG0gPSBudWxsOw0KCXRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaCA9IG51bGw7DQoJdGhpcy5lbWJlZGRlZFNpZ25hdHVyZSA9IG51bGw7DQoJdGhpcy52ZXJpZmllZCA9IGZhbHNlOw0KCQ0KDQoJLyoqDQoJICogcGFyc2luZyBmdW5jdGlvbiBmb3IgYSBzaWduYXR1cmUgcGFja2V0ICh0YWcgMikuDQoJICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IHBheWxvYWQgb2YgYSB0YWcgMiBwYWNrZXQNCgkgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIHBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gbGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2YgaW5wdXQgYXQgcG9zaXRpb24NCgkgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhfSBvYmplY3QgcmVwcmVzZW50YXRpb24NCgkgKi8NCglmdW5jdGlvbiByZWFkX3BhY2tldChpbnB1dCwgcG9zaXRpb24sIGxlbikgew0KCQl0aGlzLmRhdGEgPSBpbnB1dC5zdWJzdHJpbmcJKHBvc2l0aW9uLCBwb3NpdGlvbitsZW4pOw0KCQlpZiAobGVuIDwgMCkgew0KCQkJdXRpbC5wcmludF9kZWJ1Zygib3BlbnBncC5wYWNrZXQuc2lnbmF0dXJlLmpzXG4iKyJvcGVucGdwX3BhY2tldF9zaWduYXR1cmUgcmVhZF9wYWNrZXQgbGVuZ3RoIDwgMCBAOiIrcG9zaXRpb24pOw0KCQkJcmV0dXJuIG51bGw7DQoJCX0NCgkJdmFyIG15cG9zID0gcG9zaXRpb247DQoJCXRoaXMucGFja2V0TGVuZ3RoID0gbGVuOw0KCQkvLyBhbGVydCgnc3RhcnRpbmcgcGFyc2luZyBzaWduYXR1cmU6ICcrcG9zaXRpb24rJyAnK3RoaXMucGFja2V0TGVuZ3RoKTsNCgkJdGhpcy52ZXJzaW9uID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KCQkvLyBzd2l0Y2ggb24gdmVyc2lvbiAoMyBhbmQgNCkNCgkJc3dpdGNoICh0aGlzLnZlcnNpb24pIHsNCgkJY2FzZSAzOg0KCQkJLy8gT25lLW9jdGV0IGxlbmd0aCBvZiBmb2xsb3dpbmcgaGFzaGVkIG1hdGVyaWFsLiBNVVNUIGJlIDUuDQoJCQlpZiAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpICE9IDUpDQoJCQkJdXRpbC5wcmludF9kZWJ1Zygib3BlbnBncC5wYWNrZXQuc2lnbmF0dXJlLmpzXG4iKydpbnZhbGlkIE9uZS1vY3RldCBsZW5ndGggb2YgZm9sbG93aW5nIGhhc2hlZCBtYXRlcmlhbC4gIE1VU1QgYmUgNS4gQDonKyhteXBvcy0xKSk7DQoJCQl2YXIgc2lncG9zID0gbXlwb3M7DQoJCQkvLyBPbmUtb2N0ZXQgc2lnbmF0dXJlIHR5cGUuDQoJCQl0aGlzLnNpZ25hdHVyZVR5cGUgPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoNCgkJCS8vIEZvdXItb2N0ZXQgY3JlYXRpb24gdGltZS4NCgkJCXRoaXMuY3JlYXRpb25UaW1lID0gbmV3IERhdGUoKChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkpIDw8IDI0IHwNCgkJCQkJKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCAxNikgfCAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDgpIHwNCgkJCQkJaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpKSogMTAwMCk7DQoJCQkNCgkJCS8vIHN0b3JpbmcgZGF0YSBhcHBlbmRlZCB0byBkYXRhIHdoaWNoIGdldHMgdmVyaWZpZWQNCgkJCXRoaXMuc2lnbmF0dXJlRGF0YSA9IGlucHV0LnN1YnN0cmluZyhwb3NpdGlvbiwgbXlwb3MpOw0KCQkJDQoJCQkvLyBFaWdodC1vY3RldCBLZXkgSUQgb2Ygc2lnbmVyLg0KCQkJdGhpcy5rZXlJZCA9IGlucHV0LnN1YnN0cmluZyhteXBvcywgbXlwb3MgKzgpOw0KCQkJbXlwb3MgKz0gODsNCg0KCQkJLy8gT25lLW9jdGV0IHB1YmxpYy1rZXkgYWxnb3JpdGhtLg0KCQkJdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoNCgkJCS8vIE9uZS1vY3RldCBoYXNoIGFsZ29yaXRobS4NCgkJCXRoaXMuaGFzaEFsZ29yaXRobSA9IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCg0KCQkJLy8gVHdvLW9jdGV0IGZpZWxkIGhvbGRpbmcgbGVmdCAxNiBiaXRzIG9mIHNpZ25lZCBoYXNoIHZhbHVlLg0KCQkJdGhpcy5zaWduZWRIYXNoVmFsdWUgPSAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDgpIHwgaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KCQkJdmFyIG1waWNvdW50ID0gMDsNCgkJCS8vIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIFJTQSBzaWduYXR1cmVzOg0KCQkJLy8gCSAgICAtIG11bHRpcHJlY2lzaW9uIGludGVnZXIgKE1QSSkgb2YgUlNBIHNpZ25hdHVyZSB2YWx1ZSBtKipkIG1vZCBuLg0KCQkJaWYgKHRoaXMucHVibGljS2V5QWxnb3JpdGhtID4gMCAmJiB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA8IDQpDQoJCQkJbXBpY291bnQgPSAxOw0KCQkJLy8gICAgQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgRFNBIHNpZ25hdHVyZXM6DQoJCQkvLyAgICAgIC0gTVBJIG9mIERTQSB2YWx1ZSByLg0KCQkJLy8gICAgICAtIE1QSSBvZiBEU0EgdmFsdWUgcy4NCgkJCWVsc2UgaWYgKHRoaXMucHVibGljS2V5QWxnb3JpdGhtID09IDE3KQ0KCQkJCW1waWNvdW50ID0gMjsNCgkJCQ0KCQkJdGhpcy5NUElzID0gbmV3IEFycmF5KCk7DQoJCQlmb3IgKHZhciBpID0gMDsgaSA8IG1waWNvdW50OyBpKyspIHsNCgkJCQl0aGlzLk1QSXNbaV0gPSBuZXcgb3BlbnBncF90eXBlX21waSgpOw0KCQkJCWlmICh0aGlzLk1QSXNbaV0ucmVhZChpbnB1dCwgbXlwb3MsIChteXBvcy1wb3NpdGlvbikpICE9IG51bGwgJiYgDQoJCQkJCQkhdGhpcy5wYWNrZXRMZW5ndGggPCAobXlwb3MtcG9zaXRpb24pKSB7DQoJCQkJCW15cG9zICs9IHRoaXMuTVBJc1tpXS5wYWNrZXRMZW5ndGg7DQoJCQkJfSBlbHNlIHsNCgkJCSAJCXV0aWwucHJpbnRfZXJyb3IoJ3NpZ25hdHVyZSBjb250YWlucyBpbnZhbGlkIE1QSSBAOicrbXlwb3MpOw0KCQkJCX0NCgkJCX0NCgkJYnJlYWs7DQoJCWNhc2UgNDoNCgkJCXRoaXMuc2lnbmF0dXJlVHlwZSA9IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJCXRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KCQkJdGhpcy5oYXNoQWxnb3JpdGhtID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KDQoJCQkvLyBUd28tb2N0ZXQgc2NhbGFyIG9jdGV0IGNvdW50IGZvciBmb2xsb3dpbmcgaGFzaGVkIHN1YnBhY2tldA0KCQkJLy8gZGF0YS4NCgkJCXZhciBoYXNoZWRfc3VicGFja2V0X2NvdW50ID0gKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCA4KSArIGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCg0KCQkJLy8gSGFzaGVkIHN1YnBhY2tldCBkYXRhIHNldCAoemVybyBvciBtb3JlIHN1YnBhY2tldHMpDQoJCQl2YXIgc3VicGFja2V0X2xlbmd0aCA9IDA7DQoJCQl3aGlsZSAoaGFzaGVkX3N1YnBhY2tldF9jb3VudCAhPSBzdWJwYWNrZXRfbGVuZ3RoKSB7DQoJCQkJaWYgKGhhc2hlZF9zdWJwYWNrZXRfY291bnQgPCBzdWJwYWNrZXRfbGVuZ3RoKSB7DQoJCQkJCXV0aWwucHJpbnRfZGVidWcoIm9wZW5wZ3AucGFja2V0LnNpZ25hdHVyZS5qc1xuIisiaGFzaGVkIG1pc3NlZCBzb21ldGhpbmc6ICIrbXlwb3MrIiBjOiIraGFzaGVkX3N1YnBhY2tldF9jb3VudCsiIGw6IitzdWJwYWNrZXRfbGVuZ3RoKTsNCgkJCQl9DQoNCgkJCQlzdWJwYWNrZXRfbGVuZ3RoICs9IHRoaXMuX3Jhd19yZWFkX3NpZ25hdHVyZV9zdWJfcGFja2V0KGlucHV0LA0KCQkJCQkJbXlwb3MgKyBzdWJwYWNrZXRfbGVuZ3RoLCBoYXNoZWRfc3VicGFja2V0X2NvdW50DQoJCQkJCQkJCS0gc3VicGFja2V0X2xlbmd0aCk7DQoJCQl9DQoJCQkNCgkJCW15cG9zICs9IGhhc2hlZF9zdWJwYWNrZXRfY291bnQ7DQoJCQl0aGlzLnNpZ25hdHVyZURhdGEgPSBpbnB1dC5zdWJzdHJpbmcocG9zaXRpb24sIG15cG9zKTsNCg0KCQkJLy8gYWxlcnQoInNpZ25hdHVyZURhdGE6ICIrdXRpbC5oZXhzdHJkdW1wKHRoaXMuc2lnbmF0dXJlRGF0YSkpOw0KCQkJDQoJCQkvLyBUd28tb2N0ZXQgc2NhbGFyIG9jdGV0IGNvdW50IGZvciB0aGUgZm9sbG93aW5nIHVuaGFzaGVkIHN1YnBhY2tldA0KCQkJdmFyIHN1YnBhY2tldF9jb3VudCA9IChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPDwgOCkgKyBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoJCQkJDQoJCQkvLyBVbmhhc2hlZCBzdWJwYWNrZXQgZGF0YSBzZXQgKHplcm8gb3IgbW9yZSBzdWJwYWNrZXRzKS4NCgkJCXN1YnBhY2tldF9sZW5ndGggPSAwOw0KCQkJd2hpbGUgKHN1YnBhY2tldF9jb3VudCAhPSBzdWJwYWNrZXRfbGVuZ3RoKSB7DQoJCQkJaWYgKHN1YnBhY2tldF9jb3VudCA8IHN1YnBhY2tldF9sZW5ndGgpIHsNCgkJCQkJdXRpbC5wcmludF9kZWJ1Zygib3BlbnBncC5wYWNrZXQuc2lnbmF0dXJlLmpzXG4iKyJtaXNzZWQgc29tZXRoaW5nOiAiK3N1YnBhY2tldF9sZW5ndGgrIiBjOiIrc3VicGFja2V0X2NvdW50KyIgIisiIGw6IitzdWJwYWNrZXRfbGVuZ3RoKTsNCgkJCQl9DQoJCQkJc3VicGFja2V0X2xlbmd0aCArPSB0aGlzLl9yYXdfcmVhZF9zaWduYXR1cmVfc3ViX3BhY2tldChpbnB1dCwNCgkJCQkJCW15cG9zICsgc3VicGFja2V0X2xlbmd0aCwgc3VicGFja2V0X2NvdW50DQoJCQkJCQkJCS0gc3VicGFja2V0X2xlbmd0aCk7DQoNCgkJCX0NCgkJCW15cG9zICs9IHN1YnBhY2tldF9jb3VudDsNCgkJCS8vIFR3by1vY3RldCBmaWVsZCBob2xkaW5nIHRoZSBsZWZ0IDE2IGJpdHMgb2YgdGhlIHNpZ25lZCBoYXNoDQoJCQkvLyB2YWx1ZS4NCgkJCXRoaXMuc2lnbmVkSGFzaFZhbHVlID0gKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCA4KSB8IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJCS8vIE9uZSBvciBtb3JlIG11bHRpcHJlY2lzaW9uIGludGVnZXJzIGNvbXByaXNpbmcgdGhlIHNpZ25hdHVyZS4NCgkJCS8vIFRoaXMgcG9ydGlvbiBpcyBhbGdvcml0aG0gc3BlY2lmaWMsIGFzIGRlc2NyaWJlZCBhYm92ZS4NCgkJCXZhciBtcGljb3VudCA9IDA7DQoJCQlpZiAodGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPiAwICYmIHRoaXMucHVibGljS2V5QWxnb3JpdGhtIDwgNCkNCgkJCQltcGljb3VudCA9IDE7DQoJCQllbHNlIGlmICh0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9PSAxNykNCgkJCQltcGljb3VudCA9IDI7DQoJCQkNCgkJCXRoaXMuTVBJcyA9IG5ldyBBcnJheSgpOw0KCQkJZm9yICh2YXIgaSA9IDA7IGkgPCBtcGljb3VudDsgaSsrKSB7DQoJCQkJdGhpcy5NUElzW2ldID0gbmV3IG9wZW5wZ3BfdHlwZV9tcGkoKTsNCgkJCQlpZiAodGhpcy5NUElzW2ldLnJlYWQoaW5wdXQsIG15cG9zLCAobXlwb3MtcG9zaXRpb24pKSAhPSBudWxsICYmIA0KCQkJCQkJIXRoaXMucGFja2V0TGVuZ3RoIDwgKG15cG9zLXBvc2l0aW9uKSkgew0KCQkJCQlteXBvcyArPSB0aGlzLk1QSXNbaV0ucGFja2V0TGVuZ3RoOw0KCQkJCX0gZWxzZSB7DQoJCQkgCQl1dGlsLnByaW50X2Vycm9yKCdzaWduYXR1cmUgY29udGFpbnMgaW52YWxpZCBNUEkgQDonK215cG9zKTsNCgkJCQl9DQoJCQl9DQoJCQlicmVhazsNCgkJZGVmYXVsdDoNCgkJCXV0aWwucHJpbnRfZXJyb3IoIm9wZW5wZ3AucGFja2V0LnNpZ25hdHVyZS5qc1xuIisndW5rbm93biBzaWduYXR1cmUgcGFja2V0IHZlcnNpb24nK3RoaXMudmVyc2lvbik7DQoJCQlicmVhazsNCgkJfQ0KCQkvLyB1dGlsLnByaW50X21lc3NhZ2UoIm9wZW5wZ3AucGFja2V0LnNpZ25hdHVyZS5qc1xuIisiZW5kIHNpZ25hdHVyZTogbDogIit0aGlzLnBhY2tldExlbmd0aCsibTogIitteXBvcysiIG0tcDogIisobXlwb3MtcG9zaXRpb24pKTsNCgkJcmV0dXJuIHRoaXM7DQoJfQ0KCS8qKg0KCSAqIGNyZWF0ZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBtZXNzYWdlIHNpZ25hdHVyZSBwYWNrZXQgKHRhZyAyKS4NCgkgKiBUaGlzIGNhbiBiZSBvbmx5IHVzZWQgb24gdGV4dCBkYXRhDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBzaWduYXR1cmVfdHlwZSBzaG91bGQgYmUgMSAob25lKSANCgkgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBkYXRhIHRvIGJlIHNpZ25lZA0KCSAqIEBwYXJhbSB7b3BlbnBncF9tc2dfcHJpdmF0ZWtleX0gcHJpdmF0ZWtleSBwcml2YXRlIGtleSB1c2VkIHRvIHNpZ24gdGhlIG1lc3NhZ2UuIChzZWNNUElzIE1VU1QgYmUgdW5sb2NrZWQpDQoJICogQHJldHVybiB7U3RyaW5nfSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBzaWduYXR1cmUgcGFja2V0DQoJICovDQoJZnVuY3Rpb24gd3JpdGVfbWVzc2FnZV9zaWduYXR1cmUoc2lnbmF0dXJlX3R5cGUsIGRhdGEsIHByaXZhdGVrZXkpIHsNCgkJdmFyIHB1YmxpY2tleSA9IHByaXZhdGVrZXkucHJpdmF0ZUtleVBhY2tldC5wdWJsaWNLZXk7DQoJCXZhciBoYXNoX2FsZ28gPSBwcml2YXRla2V5LmdldFByZWZlcnJlZFNpZ25hdHVyZUhhc2hBbGdvcml0aG0oKTsNCgkJdmFyIHJlc3VsdCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoNCk7IA0KCQlyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShzaWduYXR1cmVfdHlwZSk7DQoJCXJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHB1YmxpY2tleS5wdWJsaWNLZXlBbGdvcml0aG0pOw0KCQlyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShoYXNoX2FsZ28pOw0KCQl2YXIgZCA9IE1hdGgucm91bmQobmV3IERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKTsNCgkJdmFyIGRhdGVzdWJwYWNrZXQgPSB3cml0ZV9zdWJfc2lnbmF0dXJlX3BhY2tldCgyLCIiKw0KCQkJCVN0cmluZy5mcm9tQ2hhckNvZGUoKGQgPj4gMjQpICYgMHhGRikgKyANCgkJCQlTdHJpbmcuZnJvbUNoYXJDb2RlKChkID4+IDE2KSAmIDB4RkYpICsNCgkJCQlTdHJpbmcuZnJvbUNoYXJDb2RlKChkID4+IDgpICYgMHhGRikgKyANCgkJCQlTdHJpbmcuZnJvbUNoYXJDb2RlKGQgJiAweEZGKSk7DQoJCXZhciBpc3N1ZXJzdWJwYWNrZXQgPSB3cml0ZV9zdWJfc2lnbmF0dXJlX3BhY2tldCgxNiwgcHJpdmF0ZWtleS5nZXRLZXlJZCgpKTsNCgkJcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChkYXRlc3VicGFja2V0Lmxlbmd0aCArIGlzc3VlcnN1YnBhY2tldC5sZW5ndGgpID4+IDgpICYgMHhGRik7DQoJCXJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlICgoZGF0ZXN1YnBhY2tldC5sZW5ndGggKyBpc3N1ZXJzdWJwYWNrZXQubGVuZ3RoKSAmIDB4RkYpOw0KCQlyZXN1bHQgKz0gZGF0ZXN1YnBhY2tldDsNCgkJcmVzdWx0ICs9IGlzc3VlcnN1YnBhY2tldDsNCgkJdmFyIHRyYWlsZXIgPSAnJzsNCgkJDQoJCXRyYWlsZXIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSg0KTsNCgkJdHJhaWxlciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RkYpOw0KCQl0cmFpbGVyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKHJlc3VsdC5sZW5ndGgpID4+IDI0KTsNCgkJdHJhaWxlciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKCgocmVzdWx0Lmxlbmd0aCkgPj4gMTYpICYgMHhGRik7DQoJCXRyYWlsZXIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoKHJlc3VsdC5sZW5ndGgpID4+IDgpICYgMHhGRik7DQoJCXRyYWlsZXIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgocmVzdWx0Lmxlbmd0aCkgJiAweEZGKTsNCgkJdmFyIHJlc3VsdDIgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApOw0KCQlyZXN1bHQyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMCk7DQoJCXZhciBoYXNoID0gb3BlbnBncF9jcnlwdG9faGFzaERhdGEoaGFzaF9hbGdvLCBkYXRhK3Jlc3VsdCt0cmFpbGVyKTsNCgkJdXRpbC5wcmludF9kZWJ1ZygiRFNBIFNpZ25hdHVyZSBpcyBjYWxjdWxhdGVkIHdpdGg6fCIrZGF0YStyZXN1bHQrdHJhaWxlcisifFxuIit1dGlsLmhleHN0cmR1bXAoZGF0YStyZXN1bHQrdHJhaWxlcikrIlxuIGhhc2g6Iit1dGlsLmhleHN0cmR1bXAoaGFzaCkpOw0KCQlyZXN1bHQyICs9IGhhc2guY2hhckF0KDApOw0KCQlyZXN1bHQyICs9IGhhc2guY2hhckF0KDEpOw0KCQlyZXN1bHQyICs9IG9wZW5wZ3BfY3J5cHRvX3NpZ25EYXRhKGhhc2hfYWxnbyxwcml2YXRla2V5LnByaXZhdGVLZXlQYWNrZXQucHVibGljS2V5LnB1YmxpY0tleUFsZ29yaXRobSwNCgkJCQlwdWJsaWNrZXkuTVBJcywNCgkJCQlwcml2YXRla2V5LnByaXZhdGVLZXlQYWNrZXQuc2VjTVBJcywNCgkJCQlkYXRhK3Jlc3VsdCt0cmFpbGVyKTsNCgkJcmV0dXJuIHtvcGVucGdwOiAob3BlbnBncF9wYWNrZXQud3JpdGVfcGFja2V0X2hlYWRlcigyLCAocmVzdWx0K3Jlc3VsdDIpLmxlbmd0aCkrcmVzdWx0ICsgcmVzdWx0MiksIA0KCQkJCWhhc2g6IHV0aWwuZ2V0X2hhc2hBbGdvcml0aG1TdHJpbmcoaGFzaF9hbGdvKX07DQoJfQ0KCS8qKg0KCSAqIGNyZWF0ZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBzdWIgc2lnbmF0dXJlIHBhY2tldCAoU2VlIFJGQyA0ODgwIDUuMi4zLjEpDQoJICogQHBhcmFtIHtJbnRlZ2VyfSB0eXBlIHN1YnBhY2tldCBzaWduYXR1cmUgdHlwZS4gU2lnbmF0dXJlIHR5cGVzIGFzIGRlc2NyaWJlZCBpbiBSRkM0ODgwIFNlY3Rpb24gNS4yLjMuMg0KCSAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIGRhdGEgdG8gYmUgaW5jbHVkZWQNCgkgKiBAcmV0dXJuIHtTdHJpbmd9IGEgc3RyaW5nLXJlcHJlc2VudGF0aW9uIG9mIGEgc3ViIHNpZ25hdHVyZSBwYWNrZXQgKFNlZSBSRkMgNDg4MCA1LjIuMy4xKQ0KCSAqLw0KCWZ1bmN0aW9uIHdyaXRlX3N1Yl9zaWduYXR1cmVfcGFja2V0KHR5cGUsIGRhdGEpIHsNCgkJdmFyIHJlc3VsdCA9ICIiOw0KCQlyZXN1bHQgKz0gb3BlbnBncF9wYWNrZXQuZW5jb2RlX2xlbmd0aChkYXRhLmxlbmd0aCsxKTsNCgkJcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodHlwZSk7DQoJCXJlc3VsdCArPSBkYXRhOw0KCQlyZXR1cm4gcmVzdWx0Ow0KCX0NCgkNCgkvLyBWNCBzaWduYXR1cmUgc3ViIHBhY2tldHMNCgkNCgl0aGlzLl9yYXdfcmVhZF9zaWduYXR1cmVfc3ViX3BhY2tldCA9IGZ1bmN0aW9uKGlucHV0LCBwb3NpdGlvbiwgbGVuKSB7DQoJCWlmIChsZW4gPCAwKQ0KCQkJdXRpbC5wcmludF9kZWJ1Zygib3BlbnBncC5wYWNrZXQuc2lnbmF0dXJlLmpzXG4iKyJfcmF3X3JlYWRfc2lnbmF0dXJlX3N1Yl9wYWNrZXQgbGVuZ3RoIDwgMCBAOiIrcG9zaXRpb24pOw0KCQl2YXIgbXlwb3MgPSBwb3NpdGlvbjsNCgkJdmFyIHN1YnBsZW4gPSAwOw0KCQkvLyBhbGVydCgnc3RhcnRpbmcgc2lnbmF0dXJlIHN1YnBhY2thZ2UgcmVhZCBhdCBwb3NpdGlvbjonK3Bvc2l0aW9uKycgbGVuZ3RoOicrbGVuKTsNCgkJaWYgKGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgPCAxOTIpIHsNCgkJCXN1YnBsZW4gPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoJCX0gZWxzZSBpZiAoaW5wdXRbbXlwb3NdLmNoYXJDb2RlQXQoKSA+PSAxOTIgJiYgaW5wdXRbbXlwb3NdLmNoYXJDb2RlQXQoKSA8IDIyNCkgew0KCQkJc3VicGxlbiA9ICgoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIC0gMTkyKSA8PCA4KSArIChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkpICsgMTkyOw0KCQl9IGVsc2UgaWYgKGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgPiAyMjMgJiYgaW5wdXRbbXlwb3NdLmNoYXJDb2RlQXQoKSA8IDI1NSkgew0KCQkJc3VicGxlbiA9IDEgPDwgKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSAmIDB4MUYpOw0KCQl9IGVsc2UgaWYgKGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgPCAyNTUpIHsNCgkJCW15cG9zKys7DQoJCQlzdWJwbGVuID0gKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCAyNCkgfCAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDE2KQ0KCQkJCQl8ICAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDgpIHwgIGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJfQ0KCQkNCgkJdmFyIHR5cGUgPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgJiAweDdGOw0KCQkvLyBhbGVydCgnc2lnbmF0dXJlIHN1YnBhY2tldCB0eXBlICcrdHlwZSsiIHdpdGggbGVuZ3RoOiAiK3N1YnBsZW4pOw0KCQkvLyBzdWJwYWNrZXQgdHlwZQ0KCQlzd2l0Y2ggKHR5cGUpIHsNCgkJY2FzZSAyOiAvLyBTaWduYXR1cmUgQ3JlYXRpb24gVGltZQ0KCQkJdGhpcy5jcmVhdGlvblRpbWUgPSBuZXcgRGF0ZSgoKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCAyNCkgfCAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDE2KQ0KCQkJCQl8IChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPDwgOCkgfCBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkpKjEwMDApOw0KCQkJYnJlYWs7DQoJCWNhc2UgMzogLy8gU2lnbmF0dXJlIEV4cGlyYXRpb24gVGltZQ0KCQkJdGhpcy5zaWduYXR1cmVFeHBpcmF0aW9uVGltZSA9ICAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDI0KQ0KCQkJCQl8IChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPDwgMTYpIHwgKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCA4KQ0KCQkJCQl8IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJCXRoaXMuc2lnbmF0dXJlTmV2ZXJFeHBpcmVzID0gKHRoaXMuc2lnbmF0dXJlX2V4cGlyYXRpb25fdGltZSA9PSAwKTsNCgkJCQ0KCQkJYnJlYWs7DQoJCWNhc2UgNDogLy8gRXhwb3J0YWJsZSBDZXJ0aWZpY2F0aW9uDQoJCQl0aGlzLmV4cG9ydGFibGUgPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPT0gMTsNCgkJCWJyZWFrOw0KCQljYXNlIDU6IC8vIFRydXN0IFNpZ25hdHVyZQ0KCQkJdGhpcy50cnVzdExldmVsID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KCQkJdGhpcy50cnVzdEFtb3VudCA9IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJCWJyZWFrOw0KCQljYXNlIDY6IC8vIFJlZ3VsYXIgRXhwcmVzc2lvbg0KCQkJdGhpcy5yZWd1bGFyX2V4cHJlc3Npb24gPSBuZXcgU3RyaW5nKCk7DQoJCQlmb3IgKHZhciBpID0gMDsgaSA8IHN1YnBsZW4gLSAxOyBpKyspDQoJCQkJdGhpcy5yZWd1bGFyX2V4cHJlc3Npb24gKz0gKGlucHV0W215cG9zKytdKTsNCgkJCWJyZWFrOw0KCQljYXNlIDc6IC8vIFJldm9jYWJsZQ0KCQkJdGhpcy5yZXZvY2FibGUgPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPT0gMTsNCgkJCWJyZWFrOw0KCQljYXNlIDk6IC8vIEtleSBFeHBpcmF0aW9uIFRpbWUNCgkJCXRoaXMua2V5RXhwaXJhdGlvblRpbWUgPSAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDI0KQ0KCQkJCQl8IChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPDwgMTYpIHwgKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCA4KQ0KCQkJCQl8IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJCXRoaXMua2V5TmV2ZXJFeHBpcmVzID0gKHRoaXMua2V5RXhwaXJhdGlvblRpbWUgPT0gMCk7DQoJCQlicmVhazsNCgkJY2FzZSAxMTogLy8gUHJlZmVycmVkIFN5bW1ldHJpYyBBbGdvcml0aG1zDQoJCQl0aGlzLnByZWZlcnJlZFN5bW1ldHJpY0FsZ29yaXRobXMgPSBuZXcgQXJyYXkoKTsNCgkJCWZvciAodmFyIGkgPSAwOyBpIDwgc3VicGxlbi0xOyBpKyspIHsNCgkJCQl0aGlzLnByZWZlcnJlZFN5bW1ldHJpY0FsZ29yaXRobXMgPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoJCQl9DQoJCQlicmVhazsNCgkJY2FzZSAxMjogLy8gUmV2b2NhdGlvbiBLZXkNCgkJCS8vICgxIG9jdGV0IG9mIGNsYXNzLCAxIG9jdGV0IG9mIHB1YmxpYy1rZXkgYWxnb3JpdGhtIElELCAyMA0KCQkJLy8gb2N0ZXRzIG9mDQoJCQkvLyBmaW5nZXJwcmludCkNCgkJCXRoaXMucmV2b2NhdGlvbktleUNsYXNzID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KCQkJdGhpcy5yZXZvY2F0aW9uS2V5QWxnb3JpdGhtID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KCQkJdGhpcy5yZXZvY2F0aW9uS2V5RmluZ2VycHJpbnQgPSBuZXcgQXJyYXkoKTsNCgkJCWZvciAoIHZhciBpID0gMDsgaSA8IDIwOyBpKyspIHsNCgkJCQl0aGlzLnJldm9jYXRpb25LZXlGaW5nZXJwcmludCA9IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJCX0NCgkJCWJyZWFrOw0KCQljYXNlIDE2OiAvLyBJc3N1ZXINCgkJCXRoaXMuaXNzdWVyS2V5SWQgPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MsbXlwb3MrOCk7DQoJCQlteXBvcyArPSA4Ow0KCQkJYnJlYWs7DQoJCWNhc2UgMjA6IC8vIE5vdGF0aW9uIERhdGENCgkJCXRoaXMubm90YXRpb25GbGFncyA9IChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPDwgMjQpIHwgDQoJCQkJCQkJCSAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDE2KSB8DQoJCQkJCQkJCSAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8ICA4KSB8IA0KCQkJCQkJCQkgKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSk7DQoJCQl2YXIgbmFtZUxlbmd0aCA9IChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPDwgIDgpIHwgKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSk7DQoJCQl2YXIgdmFsdWVMZW5ndGggPSAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8ICA4KSB8IChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkpOw0KCQkJdGhpcy5ub3RhdGlvbk5hbWUgPSAiIjsNCgkJCWZvciAodmFyIGkgPSAwOyBpIDwgbmFtZUxlbmd0aDsgaSsrKSB7DQoJCQkJdGhpcy5ub3RhdGlvbk5hbWUgKz0gaW5wdXRbbXlwb3MrK107DQoJCQl9DQoJCQl0aGlzLm5vdGF0aW9uVmFsdWUgPSAiIjsNCgkJCWZvciAodmFyIGkgPSAwOyBpIDwgdmFsdWVMZW5ndGg7IGkrKykgew0KCQkJCXRoaXMubm90YXRpb25WYWx1ZSArPSBpbnB1dFtteXBvcysrXTsNCgkJCX0NCgkJCWJyZWFrOw0KCQljYXNlIDIxOiAvLyBQcmVmZXJyZWQgSGFzaCBBbGdvcml0aG1zDQoJCQl0aGlzLnByZWZlcnJlZEhhc2hBbGdvcml0aG1zID0gbmV3IEFycmF5KCk7DQoJCQlmb3IgKHZhciBpID0gMDsgaSA8IHN1YnBsZW4tMTsgaSsrKSB7DQoJCQkJdGhpcy5wcmVmZXJyZWRIYXNoQWxnb3JpdGhtcyA9IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJCX0NCgkJCWJyZWFrOw0KCQljYXNlIDIyOiAvLyBQcmVmZXJyZWQgQ29tcHJlc3Npb24gQWxnb3JpdGhtcw0KCQkJdGhpcy5wcmVmZXJyZWRDb21wcmVzc2lvbkFsZ29yaXRobXMgPSBuZXcgQXJyYXkoKTsNCgkJCWZvciAoIHZhciBpID0gMDsgaSA8IHN1YnBsZW4tMTsgaSsrKSB7DQoJCQkJdGhpcy5wcmVmZXJyZWRDb21wcmVzc2lvbkFsZ29yaXRobXMgPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoJCQl9DQoJCQlicmVhazsNCgkJY2FzZSAyMzogLy8gS2V5IFNlcnZlciBQcmVmZXJlbmNlcw0KCQkJdGhpcy5rZXlTZXJ2ZXJQcmVmZXJlbmNlcyA9IG5ldyBBcnJheSgpOw0KCQkJZm9yICggdmFyIGkgPSAwOyBpIDwgc3VicGxlbi0xOyBpKyspIHsNCgkJCQl0aGlzLmtleVNlcnZlclByZWZlcmVuY2VzID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KCQkJfQ0KCQkJYnJlYWs7DQoJCWNhc2UgMjQ6IC8vIFByZWZlcnJlZCBLZXkgU2VydmVyDQoJCQl0aGlzLnByZWZlcnJlZEtleVNlcnZlciA9IG5ldyBTdHJpbmcoKTsNCgkJCWZvciAoIHZhciBpID0gMDsgaSA8IHN1YnBsZW4tMTsgaSsrKSB7DQoJCQkJdGhpcy5wcmVmZXJyZWRLZXlTZXJ2ZXIgKz0gaW5wdXRbbXlwb3MrK107DQoJCQl9DQoJCQlicmVhazsNCgkJY2FzZSAyNTogLy8gUHJpbWFyeSBVc2VyIElEDQoJCQl0aGlzLmlzUHJpbWFyeVVzZXJJRCA9IGlucHV0W215cG9zKytdICE9IDA7DQoJCQlicmVhazsNCgkJY2FzZSAyNjogLy8gUG9saWN5IFVSSQ0KCQkJdGhpcy5wb2xpY3lVUkkgPSBuZXcgU3RyaW5nKCk7DQoJCQlmb3IgKCB2YXIgaSA9IDA7IGkgPCBzdWJwbGVuLTE7IGkrKykgew0KCQkJCXRoaXMucG9saWN5VVJJICs9IGlucHV0W215cG9zKytdOw0KCQkJfQ0KCQkJYnJlYWs7DQoJCWNhc2UgMjc6IC8vIEtleSBGbGFncw0KCQkJdGhpcy5rZXlGbGFncyA9IG5ldyBBcnJheSgpOw0KCQkJZm9yICggdmFyIGkgPSAwOyBpIDwgc3VicGxlbi0xOyBpKyspIHsNCgkJCQl0aGlzLmtleUZsYWdzID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KCQkJfQ0KCQkJYnJlYWs7DQoJCWNhc2UgMjg6IC8vIFNpZ25lcidzIFVzZXIgSUQNCgkJCXRoaXMuc2lnbmVyc1VzZXJJZCA9IG5ldyBTdHJpbmcoKTsNCgkJCWZvciAoIHZhciBpID0gMDsgaSA8IHN1YnBsZW4tMTsgaSsrKSB7DQoJCQkJdGhpcy5zaWduZXJzVXNlcklkICs9IGlucHV0W215cG9zKytdOw0KCQkJfQ0KCQkJYnJlYWs7DQoJCWNhc2UgMjk6IC8vIFJlYXNvbiBmb3IgUmV2b2NhdGlvbg0KCQkJdGhpcy5yZWFzb25Gb3JSZXZvY2F0aW9uRmxhZyA9IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJCXRoaXMucmVhc29uRm9yUmV2b2NhdGlvblN0cmluZyA9IG5ldyBTdHJpbmcoKTsNCgkJCWZvciAoIHZhciBpID0gMDsgaSA8IHN1YnBsZW4gLTI7IGkrKykgew0KCQkJCXRoaXMucmVhc29uRm9yUmV2b2NhdGlvblN0cmluZyArPSBpbnB1dFtteXBvcysrXTsNCgkJCX0NCgkJCWJyZWFrOw0KCQljYXNlIDMwOiAvLyBGZWF0dXJlcw0KCQkJLy8gVE9ETzogdG8gYmUgaW1wbGVtZW50ZWQNCgkJCXJldHVybiBzdWJwbGVuKzE7DQoJCWNhc2UgMzE6IC8vIFNpZ25hdHVyZSBUYXJnZXQNCgkJCS8vICgxIG9jdGV0IHB1YmxpYy1rZXkgYWxnb3JpdGhtLCAxIG9jdGV0IGhhc2ggYWxnb3JpdGhtLCBOIG9jdGV0cyBoYXNoKQ0KCQkJdGhpcy5zaWduYXR1cmVUYXJnZXRQdWJsaWNLZXlBbGdvcml0aG0gPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoJCQl0aGlzLnNpZ25hdHVyZVRhcmdldEhhc2hBbGdvcml0aG0gPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoJCQl2YXIgc2lnbmF0dXJlVGFyZ2V0SGFzaEFsZ29yaXRobUxlbmd0aCA9IDA7DQoJCQlzd2l0Y2godGhpcy5zaWduYXR1cmVUYXJnZXRIYXNoQWxnb3JpdGhtKSB7DQoJCQljYXNlICAxOiAvLyAtIE1ENSBbSEFDXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1ENSINCgkJCWNhc2UgIDI6IC8vIC0gU0hBLTEgW0ZJUFMxODBdICAgICAgICAgICAgICAgICAgICAgICAiU0hBMSINCgkJCQlzaWduYXR1cmVUYXJnZXRIYXNoQWxnb3JpdGhtTGVuZ3RoID0gMjA7DQoJCQkJYnJlYWs7DQoJCQljYXNlICAzOiAvLyAtIFJJUEUtTUQvMTYwIFtIQUNdICAgICAgICAgICAgICAgICAgICAgIlJJUEVNRDE2MCINCgkJCWNhc2UgIDg6IC8vIC0gU0hBMjU2IFtGSVBTMTgwXSAgICAgICAgICAgICAgICAgICAgICAiU0hBMjU2Ig0KCQkJY2FzZSAgOTogLy8gLSBTSEEzODQgW0ZJUFMxODBdICAgICAgICAgICAgICAgICAgICAgICJTSEEzODQiDQoJCQljYXNlIDEwOiAvLyAtIFNIQTUxMiBbRklQUzE4MF0gICAgICAgICAgICAgICAgICAgICAgIlNIQTUxMiINCgkJCWNhc2UgMTE6IC8vIC0gU0hBMjI0IFtGSVBTMTgwXSAgICAgICAgICAgICAgICAgICAgICAiU0hBMjI0Ig0KCQkJCWJyZWFrOw0KCQkJLy8gMTAwIHRvIDExMCAtIFByaXZhdGUvRXhwZXJpbWVudGFsIGFsZ29yaXRobQ0KCSAgICAJZGVmYXVsdDoNCgkgICAgCQl1dGlsLnByaW50X2Vycm9yKCJvcGVucGdwLnBhY2tldC5zaWduYXR1cmUuanNcbiIrInVua25vd24gc2lnbmF0dXJlIHRhcmdldCBoYXNoIGFsZ29yaXRobToiK3RoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaEFsZ29yaXRobSk7DQoJICAgIAkJcmV0dXJuIG51bGw7DQoJCQl9DQoJCQl0aGlzLnNpZ25hdHVyZVRhcmdldEhhc2ggPSBuZXcgQXJyYXkoKTsNCgkJCWZvciAodmFyIGkgPSAwOyBpIDwgc2lnbmF0dXJlVGFyZ2V0SGFzaEFsZ29yaXRobUxlbmd0aDsgaSsrKSB7DQoJCQkJdGhpcy5zaWduYXR1cmVUYXJnZXRIYXNoW2ldID0gaW5wdXRbbXlwb3MrK107IA0KCQkJfQ0KCQljYXNlIDMyOiAvLyBFbWJlZGRlZCBTaWduYXR1cmUNCgkJCXRoaXMuZW1iZWRkZWRTaWduYXR1cmUgPSBuZXcgb3BlbnBncF9wYWNrZXRfc2lnbmF0dXJlKCk7DQoJCQl0aGlzLmVtYmVkZGVkU2lnbmF0dXJlLnJlYWRfcGFja2V0KGlucHV0LCBteXBvcywgbGVuIC0obXlwb3MtcG9zaXRpb24pKTsNCgkJCXJldHVybiAoKG15cG9zKyB0aGlzLmVtYmVkZGVkU2lnbmF0dXJlLnBhY2tldExlbmd0aCkgLSBwb3NpdGlvbik7DQoJCQlicmVhazsNCgkJY2FzZSAxMDA6IC8vIFByaXZhdGUgb3IgZXhwZXJpbWVudGFsDQoJCWNhc2UgMTAxOiAvLyBQcml2YXRlIG9yIGV4cGVyaW1lbnRhbA0KCQljYXNlIDEwMjogLy8gUHJpdmF0ZSBvciBleHBlcmltZW50YWwNCgkJY2FzZSAxMDM6IC8vIFByaXZhdGUgb3IgZXhwZXJpbWVudGFsDQoJCWNhc2UgMTA0OiAvLyBQcml2YXRlIG9yIGV4cGVyaW1lbnRhbA0KCQljYXNlIDEwNTogLy8gUHJpdmF0ZSBvciBleHBlcmltZW50YWwNCgkJY2FzZSAxMDY6IC8vIFByaXZhdGUgb3IgZXhwZXJpbWVudGFsDQoJCWNhc2UgMTA3OiAvLyBQcml2YXRlIG9yIGV4cGVyaW1lbnRhbA0KCQljYXNlIDEwODogLy8gUHJpdmF0ZSBvciBleHBlcmltZW50YWwNCgkJY2FzZSAxMDk6IC8vIFByaXZhdGUgb3IgZXhwZXJpbWVudGFsDQoJCWNhc2UgMTEwOiAvLyBQcml2YXRlIG9yIGV4cGVyaW1lbnRhbA0KCQkJdXRpbC5wcmludF9lcnJvcigib3BlbnBncC5wYWNrZXQuc2lnbmF0dXJlLmpzXG4iKydwcml2YXRlIG9yIGV4cGVyaW1lbnRhbCBzaWduYXR1cmUgc3VicGFja2V0IHR5cGUgJyt0eXBlKyIgQDoiK215cG9zKyIgc3VicGxlbjoiK3N1YnBsZW4rIiBsZW46IitsZW4pOw0KCQkJcmV0dXJuIHN1YnBsZW4rMTsNCgkJCWJyZWFrOwkNCgkJY2FzZSAwOiAvLyBSZXNlcnZlZA0KCQljYXNlIDE6IC8vIFJlc2VydmVkDQoJCWNhc2UgODogLy8gUmVzZXJ2ZWQNCgkJY2FzZSAxMDogLy8gUGxhY2Vob2xkZXIgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkNCgkJY2FzZSAxMzogLy8gUmVzZXJ2ZWQNCgkJY2FzZSAxNDogLy8gUmVzZXJ2ZWQNCgkJY2FzZSAxNTogLy8gUmVzZXJ2ZWQNCgkJY2FzZSAxNzogLy8gUmVzZXJ2ZWQNCgkJY2FzZSAxODogLy8gUmVzZXJ2ZWQNCgkJY2FzZSAxOTogLy8gUmVzZXJ2ZWQNCgkJZGVmYXVsdDoNCgkJCXV0aWwucHJpbnRfZXJyb3IoIm9wZW5wZ3AucGFja2V0LnNpZ25hdHVyZS5qc1xuIisndW5rbm93biBzaWduYXR1cmUgc3VicGFja2V0IHR5cGUgJyt0eXBlKyIgQDoiK215cG9zKyIgc3VicGxlbjoiK3N1YnBsZW4rIiBsZW46IitsZW4pOw0KCQkJcmV0dXJuIHN1YnBsZW4rMTsNCgkJCWJyZWFrOw0KCQl9DQoJCXJldHVybiBteXBvcyAtcG9zaXRpb247DQoJfTsNCgkvKioNCgkgKiB2ZXJpZnlzIHRoZSBzaWduYXR1cmUgcGFja2V0LiBOb3RlOiBub3Qgc2lnbmF0dXJlIHR5cGVzIGFyZSBpbXBsZW1lbnRlZA0KCSAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIGRhdGEgd2hpY2ggb24gdGhlIHNpZ25hdHVyZSBhcHBsaWVzDQoJICogQHBhcmFtIHtvcGVucGdwX21zZ19wcml2YXRla2V5fSBrZXkgdGhlIHB1YmxpYyBrZXkgdG8gdmVyaWZ5IHRoZSBzaWduYXR1cmUNCgkgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIG1lc3NhZ2UgaXMgdmVyaWZpZWQsIGVsc2UgZmFsc2UuDQoJICovDQoJZnVuY3Rpb24gdmVyaWZ5KGRhdGEsIGtleSkgew0KCQkvLyBjYWxjdWxhdGluZyB0aGUgdHJhaWxlcg0KCQl2YXIgdHJhaWxlciA9ICcnOw0KCQl0cmFpbGVyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy52ZXJzaW9uKTsNCgkJdHJhaWxlciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RkYpOw0KCQl0cmFpbGVyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5zaWduYXR1cmVEYXRhLmxlbmd0aCA+PiAyNCk7DQoJCXRyYWlsZXIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgodGhpcy5zaWduYXR1cmVEYXRhLmxlbmd0aCA+PiAxNikgJjB4RkYpOw0KCQl0cmFpbGVyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKHRoaXMuc2lnbmF0dXJlRGF0YS5sZW5ndGggPj4gOCkgJjB4RkYpOw0KCQl0cmFpbGVyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5zaWduYXR1cmVEYXRhLmxlbmd0aCAmIDB4RkYpOw0KCQlzd2l0Y2godGhpcy5zaWduYXR1cmVUeXBlKSB7DQoJCWNhc2UgMDogLy8gMHgwMDogU2lnbmF0dXJlIG9mIGEgYmluYXJ5IGRvY3VtZW50Lg0KCQkJaWYgKHRoaXMudmVyc2lvbiA9PSA0KSB7DQoJCQkJdGhpcy52ZXJpZmllZCA9IG9wZW5wZ3BfY3J5cHRvX3ZlcmlmeVNpZ25hdHVyZSh0aGlzLnB1YmxpY0tleUFsZ29yaXRobSwgdGhpcy5oYXNoQWxnb3JpdGhtLCANCgkJCQkJdGhpcy5NUElzLCBrZXkub2JqLnB1YmxpY0tleVBhY2tldC5NUElzLCBkYXRhK3RoaXMuc2lnbmF0dXJlRGF0YSt0cmFpbGVyKTsNCgkJCX0NCgkJCWJyZWFrOw0KDQoJCWNhc2UgMTogLy8gMHgwMTogU2lnbmF0dXJlIG9mIGEgY2Fub25pY2FsIHRleHQgZG9jdW1lbnQuDQoJCQlpZiAodGhpcy52ZXJzaW9uID09IDQpIHsNCgkJCQl0aGlzLnZlcmlmaWVkID0gb3BlbnBncF9jcnlwdG9fdmVyaWZ5U2lnbmF0dXJlKHRoaXMucHVibGljS2V5QWxnb3JpdGhtLCB0aGlzLmhhc2hBbGdvcml0aG0sIA0KCQkJCQl0aGlzLk1QSXMsIGtleS5vYmoucHVibGljS2V5UGFja2V0Lk1QSXMsIGRhdGErdGhpcy5zaWduYXR1cmVEYXRhK3RyYWlsZXIpOw0KCQkJCXJldHVybiB0aGlzLnZlcmlmaWVkOw0KCQkJfQ0KCQkJYnJlYWs7DQoJCQkJDQoJCWNhc2UgMjogLy8gMHgwMjogU3RhbmRhbG9uZSBzaWduYXR1cmUuDQoJCQkvLyBUaGlzIHNpZ25hdHVyZSBpcyBhIHNpZ25hdHVyZSBvZiBvbmx5IGl0cyBvd24gc3VicGFja2V0IGNvbnRlbnRzLg0KCQkJLy8gSXQgaXMgY2FsY3VsYXRlZCBpZGVudGljYWxseSB0byBhIHNpZ25hdHVyZSBvdmVyIGEgemVyby1sZW5ndGgNCgkJCS8vIGJpbmFyeSBkb2N1bWVudC4gIE5vdGUgdGhhdCBpdCBkb2Vzbid0IG1ha2Ugc2Vuc2UgdG8gaGF2ZSBhIFYzDQoJCQkvLyBzdGFuZGFsb25lIHNpZ25hdHVyZS4NCgkJCWlmICh0aGlzLnZlcnNpb24gPT0gMykgew0KCQkJCXRoaXMudmVyaWZpZWQgPSBmYWxzZTsNCgkJCQlicmVhazsNCgkJCQl9DQoJCQkNCgkJCXRoaXMudmVyaWZpZWQgPSBvcGVucGdwX2NyeXB0b192ZXJpZnlTaWduYXR1cmUodGhpcy5wdWJsaWNLZXlBbGdvcml0aG0sIHRoaXMuaGFzaEFsZ29yaXRobSwgDQoJCQkJCXRoaXMuTVBJcywga2V5Lm9iai5wdWJsaWNLZXlQYWNrZXQuTVBJcywgdGhpcy5zaWduYXR1cmVEYXRhK3RyYWlsZXIpOw0KCQkJYnJlYWs7DQoJCWNhc2UgMTY6CQkJDQoJCQkvLyAweDEwOiBHZW5lcmljIGNlcnRpZmljYXRpb24gb2YgYSBVc2VyIElEIGFuZCBQdWJsaWMtS2V5IHBhY2tldC4NCgkJCS8vIFRoZSBpc3N1ZXIgb2YgdGhpcyBjZXJ0aWZpY2F0aW9uIGRvZXMgbm90IG1ha2UgYW55IHBhcnRpY3VsYXINCgkJCS8vIGFzc2VydGlvbiBhcyB0byBob3cgd2VsbCB0aGUgY2VydGlmaWVyIGhhcyBjaGVja2VkIHRoYXQgdGhlIG93bmVyDQoJCQkvLyBvZiB0aGUga2V5IGlzIGluIGZhY3QgdGhlIHBlcnNvbiBkZXNjcmliZWQgYnkgdGhlIFVzZXIgSUQuDQoJCWNhc2UgMTc6DQoJCQkvLyAweDExOiBQZXJzb25hIGNlcnRpZmljYXRpb24gb2YgYSBVc2VyIElEIGFuZCBQdWJsaWMtS2V5IHBhY2tldC4NCgkJCS8vIFRoZSBpc3N1ZXIgb2YgdGhpcyBjZXJ0aWZpY2F0aW9uIGhhcyBub3QgZG9uZSBhbnkgdmVyaWZpY2F0aW9uIG9mDQoJCQkvLyB0aGUgY2xhaW0gdGhhdCB0aGUgb3duZXIgb2YgdGhpcyBrZXkgaXMgdGhlIFVzZXIgSUQgc3BlY2lmaWVkLg0KCQljYXNlIDE4Og0KCQkJLy8gMHgxMjogQ2FzdWFsIGNlcnRpZmljYXRpb24gb2YgYSBVc2VyIElEIGFuZCBQdWJsaWMtS2V5IHBhY2tldC4NCgkJCS8vIFRoZSBpc3N1ZXIgb2YgdGhpcyBjZXJ0aWZpY2F0aW9uIGhhcyBkb25lIHNvbWUgY2FzdWFsDQoJCQkvLyB2ZXJpZmljYXRpb24gb2YgdGhlIGNsYWltIG9mIGlkZW50aXR5Lg0KCQljYXNlIDE5Og0KCQkJLy8gMHgxMzogUG9zaXRpdmUgY2VydGlmaWNhdGlvbiBvZiBhIFVzZXIgSUQgYW5kIFB1YmxpYy1LZXkgcGFja2V0Lg0KCQkJLy8gVGhlIGlzc3VlciBvZiB0aGlzIGNlcnRpZmljYXRpb24gaGFzIGRvbmUgc3Vic3RhbnRpYWwNCgkJCS8vIHZlcmlmaWNhdGlvbiBvZiB0aGUgY2xhaW0gb2YgaWRlbnRpdHkuDQoJCQkvLyANCgkJCS8vIE1vc3QgT3BlblBHUCBpbXBsZW1lbnRhdGlvbnMgbWFrZSB0aGVpciAia2V5IHNpZ25hdHVyZXMiIGFzIDB4MTANCgkJCS8vIGNlcnRpZmljYXRpb25zLiAgU29tZSBpbXBsZW1lbnRhdGlvbnMgY2FuIGlzc3VlIDB4MTEtMHgxMw0KCQkJLy8gY2VydGlmaWNhdGlvbnMsIGJ1dCBmZXcgZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIHRoZSB0eXBlcy4NCgkJY2FzZSA0ODoNCgkJCS8vIDB4MzA6IENlcnRpZmljYXRpb24gcmV2b2NhdGlvbiBzaWduYXR1cmUNCgkJCS8vIFRoaXMgc2lnbmF0dXJlIHJldm9rZXMgYW4gZWFybGllciBVc2VyIElEIGNlcnRpZmljYXRpb24gc2lnbmF0dXJlDQoJCQkvLyAoc2lnbmF0dXJlIGNsYXNzIDB4MTAgdGhyb3VnaCAweDEzKSBvciBkaXJlY3Qta2V5IHNpZ25hdHVyZQ0KCQkJLy8gKDB4MUYpLiAgSXQgc2hvdWxkIGJlIGlzc3VlZCBieSB0aGUgc2FtZSBrZXkgdGhhdCBpc3N1ZWQgdGhlDQoJCQkvLyByZXZva2VkIHNpZ25hdHVyZSBvciBhbiBhdXRob3JpemVkIHJldm9jYXRpb24ga2V5LiAgVGhlIHNpZ25hdHVyZQ0KCQkJLy8gaXMgY29tcHV0ZWQgb3ZlciB0aGUgc2FtZSBkYXRhIGFzIHRoZSBjZXJ0aWZpY2F0ZSB0aGF0IGl0DQoJCQkvLyByZXZva2VzLCBhbmQgc2hvdWxkIGhhdmUgYSBsYXRlciBjcmVhdGlvbiBkYXRlIHRoYW4gdGhhdA0KCQkJLy8gY2VydGlmaWNhdGUuDQoNCgkJCXRoaXMudmVyaWZpZWQgPSBvcGVucGdwX2NyeXB0b192ZXJpZnlTaWduYXR1cmUodGhpcy5wdWJsaWNLZXlBbGdvcml0aG0sIHRoaXMuaGFzaEFsZ29yaXRobSwgDQoJCQkJCXRoaXMuTVBJcywga2V5Lk1QSXMsIGRhdGErdGhpcy5zaWduYXR1cmVEYXRhK3RyYWlsZXIpOw0KCQkJYnJlYWs7DQoJCQkJCQkNCgkJY2FzZSAyNDoNCgkJCS8vIDB4MTg6IFN1YmtleSBCaW5kaW5nIFNpZ25hdHVyZQ0KCQkJLy8gVGhpcyBzaWduYXR1cmUgaXMgYSBzdGF0ZW1lbnQgYnkgdGhlIHRvcC1sZXZlbCBzaWduaW5nIGtleSB0aGF0DQoJCQkvLyBpbmRpY2F0ZXMgdGhhdCBpdCBvd25zIHRoZSBzdWJrZXkuICBUaGlzIHNpZ25hdHVyZSBpcyBjYWxjdWxhdGVkDQoJCQkvLyBkaXJlY3RseSBvbiB0aGUgcHJpbWFyeSBrZXkgYW5kIHN1YmtleSwgYW5kIG5vdCBvbiBhbnkgVXNlciBJRCBvcg0KCQkJLy8gb3RoZXIgcGFja2V0cy4gIEEgc2lnbmF0dXJlIHRoYXQgYmluZHMgYSBzaWduaW5nIHN1YmtleSBNVVNUIGhhdmUNCgkJCS8vIGFuIEVtYmVkZGVkIFNpZ25hdHVyZSBzdWJwYWNrZXQgaW4gdGhpcyBiaW5kaW5nIHNpZ25hdHVyZSB0aGF0DQoJCQkvLyBjb250YWlucyBhIDB4MTkgc2lnbmF0dXJlIG1hZGUgYnkgdGhlIHNpZ25pbmcgc3Via2V5IG9uIHRoZQ0KCQkJLy8gcHJpbWFyeSBrZXkgYW5kIHN1YmtleS4NCgkJCWlmICh0aGlzLnZlcnNpb24gPT0gMykgew0KCQkJCXRoaXMudmVyaWZpZWQgPSBmYWxzZTsNCgkJCQlicmVhazsNCgkJCX0NCgkJCQ0KCQkJdGhpcy52ZXJpZmllZCA9IG9wZW5wZ3BfY3J5cHRvX3ZlcmlmeVNpZ25hdHVyZSh0aGlzLnB1YmxpY0tleUFsZ29yaXRobSwgdGhpcy5oYXNoQWxnb3JpdGhtLCANCgkJCQkJdGhpcy5NUElzLCBrZXkuTVBJcywgZGF0YSt0aGlzLnNpZ25hdHVyZURhdGErdHJhaWxlcik7DQoJCQlicmVhazsNCgkJY2FzZSAyNToNCgkJCS8vIDB4MTk6IFByaW1hcnkgS2V5IEJpbmRpbmcgU2lnbmF0dXJlDQoJCQkvLyBUaGlzIHNpZ25hdHVyZSBpcyBhIHN0YXRlbWVudCBieSBhIHNpZ25pbmcgc3Via2V5LCBpbmRpY2F0aW5nDQoJCQkvLyB0aGF0IGl0IGlzIG93bmVkIGJ5IHRoZSBwcmltYXJ5IGtleSBhbmQgc3Via2V5LiAgVGhpcyBzaWduYXR1cmUNCgkJCS8vIGlzIGNhbGN1bGF0ZWQgdGhlIHNhbWUgd2F5IGFzIGEgMHgxOCBzaWduYXR1cmU6IGRpcmVjdGx5IG9uIHRoZQ0KCQkJLy8gcHJpbWFyeSBrZXkgYW5kIHN1YmtleSwgYW5kIG5vdCBvbiBhbnkgVXNlciBJRCBvciBvdGhlciBwYWNrZXRzLg0KCQkJDQoJCQkvLyBXaGVuIGEgc2lnbmF0dXJlIGlzIG1hZGUgb3ZlciBhIGtleSwgdGhlIGhhc2ggZGF0YSBzdGFydHMgd2l0aCB0aGUNCgkJCS8vIG9jdGV0IDB4OTksIGZvbGxvd2VkIGJ5IGEgdHdvLW9jdGV0IGxlbmd0aCBvZiB0aGUga2V5LCBhbmQgdGhlbiBib2R5DQoJCQkvLyBvZiB0aGUga2V5IHBhY2tldC4gIChOb3RlIHRoYXQgdGhpcyBpcyBhbiBvbGQtc3R5bGUgcGFja2V0IGhlYWRlciBmb3INCgkJCS8vIGEga2V5IHBhY2tldCB3aXRoIHR3by1vY3RldCBsZW5ndGguKSAgQSBzdWJrZXkgYmluZGluZyBzaWduYXR1cmUNCgkJCS8vICh0eXBlIDB4MTgpIG9yIHByaW1hcnkga2V5IGJpbmRpbmcgc2lnbmF0dXJlICh0eXBlIDB4MTkpIHRoZW4gaGFzaGVzDQoJCQkvLyB0aGUgc3Via2V5IHVzaW5nIHRoZSBzYW1lIGZvcm1hdCBhcyB0aGUgbWFpbiBrZXkgKGFsc28gdXNpbmcgMHg5OSBhcw0KCQkJLy8gdGhlIGZpcnN0IG9jdGV0KS4NCgkJY2FzZSAzMToNCgkJCS8vIDB4MUY6IFNpZ25hdHVyZSBkaXJlY3RseSBvbiBhIGtleQ0KCQkJLy8gVGhpcyBzaWduYXR1cmUgaXMgY2FsY3VsYXRlZCBkaXJlY3RseSBvbiBhIGtleS4gIEl0IGJpbmRzIHRoZQ0KCQkJLy8gaW5mb3JtYXRpb24gaW4gdGhlIFNpZ25hdHVyZSBzdWJwYWNrZXRzIHRvIHRoZSBrZXksIGFuZCBpcw0KCQkJLy8gYXBwcm9wcmlhdGUgdG8gYmUgdXNlZCBmb3Igc3VicGFja2V0cyB0aGF0IHByb3ZpZGUgaW5mb3JtYXRpb24NCgkJCS8vIGFib3V0IHRoZSBrZXksIHN1Y2ggYXMgdGhlIFJldm9jYXRpb24gS2V5IHN1YnBhY2tldC4gIEl0IGlzIGFsc28NCgkJCS8vIGFwcHJvcHJpYXRlIGZvciBzdGF0ZW1lbnRzIHRoYXQgbm9uLXNlbGYgY2VydGlmaWVycyB3YW50IHRvIG1ha2UNCgkJCS8vIGFib3V0IHRoZSBrZXkgaXRzZWxmLCByYXRoZXIgdGhhbiB0aGUgYmluZGluZyBiZXR3ZWVuIGEga2V5IGFuZCBhDQoJCQkvLyBuYW1lLg0KCQljYXNlIDMyOg0KCQkJLy8gMHgyMDogS2V5IHJldm9jYXRpb24gc2lnbmF0dXJlDQoJCQkvLyBUaGUgc2lnbmF0dXJlIGlzIGNhbGN1bGF0ZWQgZGlyZWN0bHkgb24gdGhlIGtleSBiZWluZyByZXZva2VkLiAgQQ0KCQkJLy8gcmV2b2tlZCBrZXkgaXMgbm90IHRvIGJlIHVzZWQuICBPbmx5IHJldm9jYXRpb24gc2lnbmF0dXJlcyBieSB0aGUNCgkJCS8vIGtleSBiZWluZyByZXZva2VkLCBvciBieSBhbiBhdXRob3JpemVkIHJldm9jYXRpb24ga2V5LCBzaG91bGQgYmUNCgkJCS8vIGNvbnNpZGVyZWQgdmFsaWQgcmV2b2NhdGlvbiBzaWduYXR1cmVzLg0KCQljYXNlIDQwOg0KCQkJLy8gMHgyODogU3Via2V5IHJldm9jYXRpb24gc2lnbmF0dXJlDQoJCQkvLyBUaGUgc2lnbmF0dXJlIGlzIGNhbGN1bGF0ZWQgZGlyZWN0bHkgb24gdGhlIHN1YmtleSBiZWluZyByZXZva2VkLg0KCQkJLy8gQSByZXZva2VkIHN1YmtleSBpcyBub3QgdG8gYmUgdXNlZC4gIE9ubHkgcmV2b2NhdGlvbiBzaWduYXR1cmVzDQoJCQkvLyBieSB0aGUgdG9wLWxldmVsIHNpZ25hdHVyZSBrZXkgdGhhdCBpcyBib3VuZCB0byB0aGlzIHN1YmtleSwgb3INCgkJCS8vIGJ5IGFuIGF1dGhvcml6ZWQgcmV2b2NhdGlvbiBrZXksIHNob3VsZCBiZSBjb25zaWRlcmVkIHZhbGlkDQoJCQkvLyByZXZvY2F0aW9uIHNpZ25hdHVyZXMuDQoJCQl0aGlzLnZlcmlmaWVkID0gb3BlbnBncF9jcnlwdG9fdmVyaWZ5U2lnbmF0dXJlKHRoaXMucHVibGljS2V5QWxnb3JpdGhtLCB0aGlzLmhhc2hBbGdvcml0aG0sIA0KCQkJCQl0aGlzLk1QSXMsIGtleS5NUElzLCBkYXRhK3RoaXMuc2lnbmF0dXJlRGF0YSt0cmFpbGVyKTsNCgkJCWJyZWFrOw0KCQkJDQoJCQkvLyBLZXkgcmV2b2NhdGlvbiBzaWduYXR1cmVzICh0eXBlcyAweDIwIGFuZCAweDI4KQ0KCQkJLy8gaGFzaCBvbmx5IHRoZSBrZXkgYmVpbmcgcmV2b2tlZC4NCgkJY2FzZSA2NDoNCgkJCS8vIDB4NDA6IFRpbWVzdGFtcCBzaWduYXR1cmUuDQoJCQkvLyBUaGlzIHNpZ25hdHVyZSBpcyBvbmx5IG1lYW5pbmdmdWwgZm9yIHRoZSB0aW1lc3RhbXAgY29udGFpbmVkIGluDQoJCQkvLyBpdC4NCgkJY2FzZSA4MDoNCgkJCS8vICAgIDB4NTA6IFRoaXJkLVBhcnR5IENvbmZpcm1hdGlvbiBzaWduYXR1cmUuDQoJCQkvLyBUaGlzIHNpZ25hdHVyZSBpcyBhIHNpZ25hdHVyZSBvdmVyIHNvbWUgb3RoZXIgT3BlblBHUCBTaWduYXR1cmUNCgkJCS8vIHBhY2tldChzKS4gIEl0IGlzIGFuYWxvZ291cyB0byBhIG5vdGFyeSBzZWFsIG9uIHRoZSBzaWduZWQgZGF0YS4NCgkJCS8vIEEgdGhpcmQtcGFydHkgc2lnbmF0dXJlIFNIT1VMRCBpbmNsdWRlIFNpZ25hdHVyZSBUYXJnZXQNCgkJCS8vIHN1YnBhY2tldChzKSB0byBnaXZlIGVhc3kgaWRlbnRpZmljYXRpb24uICBOb3RlIHRoYXQgd2UgcmVhbGx5IGRvDQoJCQkvLyBtZWFuIFNIT1VMRC4gIFRoZXJlIGFyZSBwbGF1c2libGUgdXNlcyBmb3IgdGhpcyAoc3VjaCBhcyBhIGJsaW5kDQoJCQkvLyBwYXJ0eSB0aGF0IG9ubHkgc2VlcyB0aGUgc2lnbmF0dXJlLCBub3QgdGhlIGtleSBvciBzb3VyY2UNCgkJCS8vIGRvY3VtZW50KSB0aGF0IGNhbm5vdCBpbmNsdWRlIGEgdGFyZ2V0IHN1YnBhY2tldC4NCgkJZGVmYXVsdDoNCgkJCXV0aWwucHJpbnRfZXJyb3IoIm9wZW5wZ3AucGFja2V0LnNpZ25hdHVyZS5qc1xuIisic2lnbmF0dXJlIHZlcmlmaWNhdGlvbiBmb3IgdHlwZSIrIHRoaXMuc2lnbmF0dXJlVHlwZSsiIG5vdCBpbXBsZW1lbnRlZCIpOw0KCQkJYnJlYWs7DQoJCX0NCgkJcmV0dXJuIHRoaXMudmVyaWZpZWQ7DQoJfQ0KCS8qKg0KCSAqIGdlbmVyYXRlcyBkZWJ1ZyBvdXRwdXQgKHByZXR0eSBwcmludCkNCgkgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyB3aGljaCBnaXZlcyBzb21lIGluZm9ybWF0aW9uIGFib3V0IHRoZSBzaWduYXR1cmUgcGFja2V0DQoJICovDQoNCglmdW5jdGlvbiB0b1N0cmluZyAoKSB7DQoJCWlmICh0aGlzLnZlcnNpb24gPT0gMykgew0KCQkJdmFyIHJlc3VsdCA9ICc1LjIuIFNpZ25hdHVyZSBQYWNrZXQgKFRhZyAyKVxuJysNCgkgICAgICAgICAgIlBhY2tldCBMZW5ndGg6ICAgICAgICAgICAgICAgICAgICAgOiIrdGhpcy5wYWNrZXRMZW5ndGgrJ1xuJysNCgkgICAgICAgICAgIlBhY2tldCB2ZXJzaW9uOiAgICAgICAgICAgICAgICAgICAgOiIrdGhpcy52ZXJzaW9uKydcbicrDQoJICAgICAgICAgICJPbmUtb2N0ZXQgc2lnbmF0dXJlIHR5cGUgICAgICAgICAgIDoiK3RoaXMuc2lnbmF0dXJlVHlwZSsnXG4nKw0KCSAgICAgICAgICAiRm91ci1vY3RldCBjcmVhdGlvbiB0aW1lLiAgICAgICAgICA6Iit0aGlzLmNyZWF0aW9uVGltZSsnXG4nKw0KCSAgICAgICAgICJFaWdodC1vY3RldCBLZXkgSUQgb2Ygc2lnbmVyLiAgICAgICA6Iit1dGlsLmhleGlkdW1wKHRoaXMua2V5SWQpKydcbicrDQoJICAgICAgICAgICJPbmUtb2N0ZXQgcHVibGljLWtleSBhbGdvcml0aG0uICAgIDoiK3RoaXMucHVibGljS2V5QWxnb3JpdGhtKydcbicrDQoJICAgICAgICAgICJPbmUtb2N0ZXQgaGFzaCBhbGdvcml0aG0uICAgICAgICAgIDoiK3RoaXMuaGFzaEFsZ29yaXRobSsnXG4nKw0KCSAgICAgICAgICAiVHdvLW9jdGV0IGZpZWxkIGhvbGRpbmcgbGVmdFxuIiArDQoJICAgICAgICAgICIgMTYgYml0cyBvZiBzaWduZWQgaGFzaCB2YWx1ZS4gICAgIDoiK3RoaXMuc2lnbmVkSGFzaFZhbHVlKydcbic7DQoJCX0gZWxzZSB7DQogICAgICAgICAgdmFyIHJlc3VsdCA9ICc1LjIuIFNpZ25hdHVyZSBQYWNrZXQgKFRhZyAyKVxuJysNCiAgICAgICAgICAiUGFja2V0IExlbmd0aDogICAgICAgICAgICAgICAgICAgICA6Iit0aGlzLnBhY2tldExlbmd0aCsnXG4nKw0KICAgICAgICAgICJQYWNrZXQgdmVyc2lvbjogICAgICAgICAgICAgICAgICAgIDoiK3RoaXMudmVyc2lvbisnXG4nKw0KICAgICAgICAgICJPbmUtb2N0ZXQgc2lnbmF0dXJlIHR5cGUgICAgICAgICAgIDoiK3RoaXMuc2lnbmF0dXJlVHlwZSsnXG4nKw0KICAgICAgICAgICJPbmUtb2N0ZXQgcHVibGljLWtleSBhbGdvcml0aG0uICAgIDoiK3RoaXMucHVibGljS2V5QWxnb3JpdGhtKydcbicrDQogICAgICAgICAgIk9uZS1vY3RldCBoYXNoIGFsZ29yaXRobS4gICAgICAgICAgOiIrdGhpcy5oYXNoQWxnb3JpdGhtKydcbicrDQogICAgICAgICAgIlR3by1vY3RldCBmaWVsZCBob2xkaW5nIGxlZnRcbiIgKw0KICAgICAgICAgICIgMTYgYml0cyBvZiBzaWduZWQgaGFzaCB2YWx1ZS4gICAgIDoiK3RoaXMuc2lnbmVkSGFzaFZhbHVlKydcbicrDQogICAgICAgICAgIlNpZ25hdHVyZSBDcmVhdGlvbiBUaW1lICAgICAgICAgICAgOiIrdGhpcy5jcmVhdGlvblRpbWUrJ1xuJysNCiAgICAgICAgICAiU2lnbmF0dXJlIEV4cGlyYXRpb24gVGltZSAgICAgICAgICA6Iit0aGlzLnNpZ25hdHVyZUV4cGlyYXRpb25UaW1lKydcbicrDQogICAgICAgICAgIlNpZ25hdHVyZSBOZXZlciBFeHBpcmVzICAgICAgICAgICAgOiIrdGhpcy5zaWduYXR1cmVOZXZlckV4cGlyZXMrJ1xuJysNCiAgICAgICAgICAiRXhwb3J0YWJsZSBDZXJ0aWZpY2F0aW9uICAgICAgICAgICA6Iit0aGlzLmV4cG9ydGFibGUrJ1xuJysNCiAgICAgICAgICAiVHJ1c3QgU2lnbmF0dXJlIGxldmVsOiAgICAgICAgICAgICA6Iit0aGlzLnRydXN0TGV2ZWwrJyBhbW91bnQnK3RoaXMudHJ1c3RBbW91bnQrJ1xuJysNCiAgICAgICAgICAiUmVndWxhciBFeHByZXNzaW9uICAgICAgICAgICAgICAgICA6Iit0aGlzLnJlZ3VsYXJfZXhwcmVzc2lvbisnXG4nKw0KICAgICAgICAgICJSZXZvY2FibGUgICAgICAgICAgICAgICAgICAgICAgICAgIDoiK3RoaXMucmV2b2NhYmxlKydcbicrDQogICAgICAgICAgIktleSBFeHBpcmF0aW9uIFRpbWUgICAgICAgICAgICAgICAgOiIrdGhpcy5rZXlFeHBpcmF0aW9uVGltZSsiICIrdGhpcy5rZXlOZXZlckV4cGlyZXMrJ1xuJysNCiAgICAgICAgICAiUHJlZmVycmVkIFN5bW1ldHJpYyBBbGdvcml0aG1zICAgICA6Iit0aGlzLnByZWZlcnJlZFN5bW1ldHJpY0FsZ29yaXRobXMrJ1xuJysNCiAgICAgICAgICAiUmV2b2NhdGlvbiBLZXkiKydcbicrDQogICAgICAgICAgIiAgICggMSBvY3RldCBvZiBjbGFzcywgICAgICAgICAgICAgOiIrdGhpcy5yZXZvY2F0aW9uS2V5Q2xhc3MgKydcbicrDQogICAgICAgICAgIiAgICAgMSBvY3RldCBvZiBwdWJsaWMta2V5IElELCAgICAgOiIgK3RoaXMucmV2b2NhdGlvbktleUFsZ29yaXRobSsnXG4nKw0KICAgICAgICAgICIgICAgMjAgb2N0ZXRzIG9mIGZpbmdlcnByaW50KSAgICAgIDoiK3RoaXMucmV2b2NhdGlvbktleUZpbmdlcnByaW50KydcbicrDQogICAgICAgICAgIklzc3VlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiIrdXRpbC5oZXhzdHJkdW1wKHRoaXMuaXNzdWVyS2V5SWQpKydcbicrDQogICAgICAgICAgIlByZWZlcnJlZCBIYXNoIEFsZ29yaXRobXMgICAgICAgICAgOiIrdGhpcy5wcmVmZXJyZWRIYXNoQWxnb3JpdGhtcysnXG4nKw0KICAgICAgICAgICJQcmVmZXJyZWQgQ29tcHJlc3Npb24gQWxnLiAgICAgICAgIDoiK3RoaXMucHJlZmVycmVkQ29tcHJlc3Npb25BbGdvcml0aG1zKydcbicrDQogICAgICAgICAgIktleSBTZXJ2ZXIgUHJlZmVyZW5jZXMgICAgICAgICAgICAgOiIrdGhpcy5rZXlTZXJ2ZXJQcmVmZXJlbmNlcysnXG4nKw0KICAgICAgICAgICJQcmVmZXJyZWQgS2V5IFNlcnZlciAgICAgICAgICAgICAgIDoiK3RoaXMucHJlZmVycmVkS2V5U2VydmVyKydcbicrDQogICAgICAgICAgIlByaW1hcnkgVXNlciBJRCAgICAgICAgICAgICAgICAgICAgOiIrdGhpcy5pc1ByaW1hcnlVc2VySUQrJ1xuJysNCiAgICAgICAgICAiUG9saWN5IFVSSSAgICAgICAgICAgICAgICAgICAgICAgICA6Iit0aGlzLnBvbGljeVVSSSsnXG4nKw0KICAgICAgICAgICJLZXkgRmxhZ3MgICAgICAgICAgICAgICAgICAgICAgICAgIDoiK3RoaXMua2V5RmxhZ3MrJ1xuJysNCiAgICAgICAgICAiU2lnbmVyJ3MgVXNlciBJRCAgICAgICAgICAgICAgICAgICA6Iit0aGlzLnNpZ25lcnNVc2VySWQrJ1xuJysNCiAgICAgICAgICAiTm90YXRpb24gICAgICAgICAgICAgICAgICAgICAgICAgICA6Iit0aGlzLm5vdGF0aW9uTmFtZSsiID0gIit0aGlzLm5vdGF0aW9uVmFsdWUrIlxuIisNCiAgICAgICAgICAiUmVhc29uIGZvciBSZXZvY2F0aW9uXG4iKw0KICAgICAgICAgICIgICAgICBGbGFnICAgICAgICAgICAgICAgICAgICAgICAgIDoiK3RoaXMucmVhc29uRm9yUmV2b2NhdGlvbkZsYWcrJ1xuJysNCiAgICAgICAgICAiICAgICAgUmVhc29uICAgICAgICAgICAgICAgICAgICAgICA6Iit0aGlzLnJlYXNvbkZvclJldm9jYXRpb25TdHJpbmcrJ1xuTVBJOlxuJzsNCgkJfQ0KICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5NUElzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgIAkgIHJlc3VsdCArPSB0aGlzLk1QSXNbaV0udG9TdHJpbmcoKTsNCiAgICAgICAgICB9DQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsNCiAgICAgfQ0KDQoJLyoqDQoJICogZ2V0cyB0aGUgaXNzdWVyIGtleSBpZCBvZiB0aGlzIHNpZ25hdHVyZQ0KCSAqIEByZXR1cm4ge1N0cmluZ30gaXNzdWVyIGtleSBpZCBhcyBzdHJpbmcgKDhieXRlcykNCgkgKi8NCglmdW5jdGlvbiBnZXRJc3N1ZXIoKSB7DQoJCSBpZiAodGhpcy52ZXJzaW9uID09IDQpDQoJCQkgcmV0dXJuIHRoaXMuaXNzdWVyS2V5SWQ7DQoJCSBpZiAodGhpcy52ZXJpb25zID09IDQpDQoJCQkgcmV0dXJuIHRoaXMua2V5SWQ7DQoJCSByZXR1cm4gbnVsbDsNCgl9DQoNCgkvKioNCgkgKiBUcmllcyB0byBnZXQgdGhlIGNvcnJlc3BvbmRpbmcgcHVibGljIGtleSBvdXQgb2YgdGhlIHB1YmxpYyBrZXlyaW5nIGZvciB0aGUgaXNzdWVyIGNyZWF0ZWQgdGhpcyBzaWduYXR1cmUNCgkgKiBAcmV0dXJuIHtPYmplY3R9IHtvYmo6IFtvcGVucGdwX21zZ19wdWJsaWNrZXldLCB0ZXh0OiBbU3RyaW5nXX0gaWYgZm91bmQgdGhlIHB1YmxpYyBrZXkgd2lsbCBiZSByZXR1cm5lZC4gbnVsbCBvdGhlcndpc2UNCgkgKi8NCglmdW5jdGlvbiBnZXRJc3N1ZXJLZXkoKSB7DQoJCSB2YXIgcmVzdWx0ID0gbnVsbDsNCgkJIGlmICh0aGlzLnZlcnNpb24gPT0gNCkgew0KCQkJIHJlc3VsdCA9IG9wZW5wZ3Aua2V5cmluZy5nZXRQdWJsaWNLZXlzRm9yS2V5SWQodGhpcy5pc3N1ZXJLZXlJZCk7DQoJCSB9IGVsc2UgaWYgKHRoaXMudmVyc2lvbiA9PSAzKSB7DQoJCQkgcmVzdWx0ID0gb3BlbnBncC5rZXlyaW5nLmdldFB1YmxpY0tleXNGb3JLZXlJZCh0aGlzLmtleUlkKTsNCgkJIH0gZWxzZSByZXR1cm4gbnVsbDsNCgkJIGlmIChyZXN1bHQubGVuZ3RoID09IDApDQoJCQkgcmV0dXJuIG51bGw7DQoJCSByZXR1cm4gcmVzdWx0WzBdOw0KCX0NCgl0aGlzLmdldElzc3VlcktleSA9IGdldElzc3VlcktleTsNCgl0aGlzLmdldElzc3VlciA9IGdldElzc3VlcjsJIA0KCXRoaXMud3JpdGVfbWVzc2FnZV9zaWduYXR1cmUgPSB3cml0ZV9tZXNzYWdlX3NpZ25hdHVyZTsNCgl0aGlzLnZlcmlmeSA9IHZlcmlmeTsNCiAgICB0aGlzLnJlYWRfcGFja2V0ID0gcmVhZF9wYWNrZXQ7DQogICAgdGhpcy50b1N0cmluZyA9IHRvU3RyaW5nOw0KfQ0KLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0DQovLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3INCi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcg0KLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLA0KLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YNCi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VDQovLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLg0KLy8gDQovLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlDQovLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0ENCg0KLyoqIA0KICogQGNsYXNzDQogKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBVc2VyIEF0dHJpYnV0ZSBQYWNrZXQgKFRhZyAxNykNCiAqICBUaGUgVXNlciBBdHRyaWJ1dGUgcGFja2V0IGlzIGEgdmFyaWF0aW9uIG9mIHRoZSBVc2VyIElEIHBhY2tldC4gIEl0DQogKiAgaXMgY2FwYWJsZSBvZiBzdG9yaW5nIG1vcmUgdHlwZXMgb2YgZGF0YSB0aGFuIHRoZSBVc2VyIElEIHBhY2tldCwNCiAqICB3aGljaCBpcyBsaW1pdGVkIHRvIHRleHQuICBMaWtlIHRoZSBVc2VyIElEIHBhY2tldCwgYSBVc2VyIEF0dHJpYnV0ZQ0KICogIHBhY2tldCBtYXkgYmUgY2VydGlmaWVkIGJ5IHRoZSBrZXkgb3duZXIgKCJzZWxmLXNpZ25lZCIpIG9yIGFueSBvdGhlcg0KICogIGtleSBvd25lciB3aG8gY2FyZXMgdG8gY2VydGlmeSBpdC4gIEV4Y2VwdCBhcyBub3RlZCwgYSBVc2VyIEF0dHJpYnV0ZQ0KICogIHBhY2tldCBtYXkgYmUgdXNlZCBhbnl3aGVyZSB0aGF0IGEgVXNlciBJRCBwYWNrZXQgbWF5IGJlIHVzZWQuDQogKg0KICogIFdoaWxlIFVzZXIgQXR0cmlidXRlIHBhY2tldHMgYXJlIG5vdCBhIHJlcXVpcmVkIHBhcnQgb2YgdGhlIE9wZW5QR1ANCiAqICBzdGFuZGFyZCwgaW1wbGVtZW50YXRpb25zIFNIT1VMRCBwcm92aWRlIGF0IGxlYXN0IGVub3VnaA0KICogIGNvbXBhdGliaWxpdHkgdG8gcHJvcGVybHkgaGFuZGxlIGEgY2VydGlmaWNhdGlvbiBzaWduYXR1cmUgb24gdGhlDQogKiAgVXNlciBBdHRyaWJ1dGUgcGFja2V0LiAgQSBzaW1wbGUgd2F5IHRvIGRvIHRoaXMgaXMgYnkgdHJlYXRpbmcgdGhlDQogKiAgVXNlciBBdHRyaWJ1dGUgcGFja2V0IGFzIGEgVXNlciBJRCBwYWNrZXQgd2l0aCBvcGFxdWUgY29udGVudHMsIGJ1dA0KICogIGFuIGltcGxlbWVudGF0aW9uIG1heSB1c2UgYW55IG1ldGhvZCBkZXNpcmVkLg0KICovDQpmdW5jdGlvbiBvcGVucGdwX3BhY2tldF91c2VyYXR0cmlidXRlKCkgew0KCXRoaXMudGFnVHlwZSA9IDE3Ow0KCXRoaXMuY2VydGlmaWNhdGlvblNpZ25hdHVyZXMgPSBuZXcgQXJyYXkoKTsNCgl0aGlzLmNlcnRpZmljYXRpb25SZXZvY2F0aW9uU2lnbmF0dXJlcyA9IG5ldyBBcnJheSgpOw0KCXRoaXMucmV2b2NhdGlvblNpZ25hdHVyZXMgPSBuZXcgQXJyYXkoKTsNCgl0aGlzLnBhcmVudE5vZGUgPSBudWxsOw0KDQoJLyoqDQoJICogcGFyc2luZyBmdW5jdGlvbiBmb3IgYSB1c2VyIGF0dHJpYnV0ZSBwYWNrZXQgKHRhZyAxNykuDQoJICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IHBheWxvYWQgb2YgYSB0YWcgMTcgcGFja2V0DQoJICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBwb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZw0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuIGxlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mIGlucHV0IGF0IHBvc2l0aW9uDQoJICogQHJldHVybiB7b3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkZGF0YX0gb2JqZWN0IHJlcHJlc2VudGF0aW9uDQoJICovDQoJZnVuY3Rpb24gcmVhZF9wYWNrZXQgKGlucHV0LCBwb3NpdGlvbiwgbGVuKSB7DQoJCXZhciB0b3RhbF9sZW4gPSAwOw0KCQl0aGlzLnBhY2tldExlbmd0aCA9IGxlbjsNCgkJdGhpcy51c2VyYXR0cmlidXRlcyA9IG5ldyBBcnJheSgpOw0KCQl2YXIgY291bnQgPSAwOw0KCQl2YXIgbXlwb3MgPSBwb3NpdGlvbjsNCgkJd2hpbGUgKGxlbiAhPSB0b3RhbF9sZW4pIHsNCgkJCXZhciBjdXJyZW50X2xlbiA9IDA7DQoJCQkvLyA0LjIuMi4xLiBPbmUtT2N0ZXQgTGVuZ3Rocw0KCQkJaWYgKGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgPCAxOTIpIHsNCgkJCQlwYWNrZXRfbGVuZ3RoID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KCQkJCWN1cnJlbnRfbGVuID0gMTsNCgkJCS8vIDQuMi4yLjIuIFR3by1PY3RldCBMZW5ndGhzDQoJCQl9IGVsc2UgaWYgKGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgPj0gMTkyICYmIGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgPCAyMjQpIHsNCgkJCQlwYWNrZXRfbGVuZ3RoID0gKChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgLSAxOTIpIDw8IDgpDQoJCQkJCSsgKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSkgKyAxOTI7DQoJCQkJY3VycmVudF9sZW4gPSAyOw0KCQkJLy8gNC4yLjIuNC4gUGFydGlhbCBCb2R5IExlbmd0aHMNCgkJCX0gZWxzZSBpZiAoaW5wdXRbbXlwb3NdLmNoYXJDb2RlQXQoKSA+IDIyMyAmJiBpbnB1dFtteXBvc10uY2hhckNvZGVBdCgpIDwgMjU1KSB7DQoJCQkJcGFja2V0X2xlbmd0aCA9IDEgPDwgKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSAmIDB4MUYpOw0KCQkJCWN1cnJlbnRfbGVuID0gMTsNCgkJCS8vIDQuMi4yLjMuIEZpdmUtT2N0ZXQgTGVuZ3Rocw0KCQkJfSBlbHNlIHsNCgkJCQljdXJyZW50X2xlbiA9IDU7DQoJCQkJbXlwb3MrKzsNCgkJCQlwYWNrZXRfbGVuZ3RoID0gKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCAyNCkgfCAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDE2KQ0KCQkJCQl8IChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPDwgOCkgfCBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoJCQl9DQoJCQkNCgkJCXZhciBzdWJwYWNrZXR0eXBlID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KCQkJcGFja2V0X2xlbmd0aC0tOw0KCQkJY3VycmVudF9sZW4rKzsNCgkJCXRoaXMudXNlcmF0dHJpYnV0ZXNbY291bnRdID0gbmV3IEFycmF5KCk7DQoJCQl0aGlzLnVzZXJhdHRyaWJ1dGVzW2NvdW50XSA9IGlucHV0LnN1YnN0cmluZyhteXBvcywgbXlwb3MgKyBwYWNrZXRfbGVuZ3RoKTsNCgkJCW15cG9zICs9IHBhY2tldF9sZW5ndGg7DQoJCQl0b3RhbF9sZW4gKz0gY3VycmVudF9sZW4rcGFja2V0X2xlbmd0aDsNCgkJfQ0KCQl0aGlzLnBhY2tldExlbmd0aCA9IG15cG9zIC0gcG9zaXRpb247DQoJCXJldHVybiB0aGlzOw0KCX0NCgkNCgkvKioNCgkgKiBnZW5lcmF0ZXMgZGVidWcgb3V0cHV0IChwcmV0dHkgcHJpbnQpDQoJICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmcgd2hpY2ggZ2l2ZXMgc29tZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdXNlciBhdHRyaWJ1dGUgcGFja2V0DQoJICovDQoJZnVuY3Rpb24gdG9TdHJpbmcoKSB7DQoJCXZhciByZXN1bHQgPSAnNS4xMi4gIFVzZXIgQXR0cmlidXRlIFBhY2tldCAoVGFnIDE3KVxuJysNCgkJICAgICAgICAgICAgICcgICAgQXR0cmlidXRlUGFja2V0czogKGNvdW50ID0gJyt0aGlzLnVzZXJhdHRyaWJ1dGVzLmxlbmd0aCsnKVxuJzsNCgkJZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnVzZXJhdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7DQoJCQlyZXN1bHQgKz0gJyAgICAoJyt0aGlzLnVzZXJhdHRyaWJ1dGVzW2ldLmxlbmd0aCsnKSBieXRlczogWycrdXRpbC5oZXhpZHVtcCh0aGlzLnVzZXJhdHRyaWJ1dGVzW2ldKSsnXVxuJzsgDQoJCX0NCgkJcmV0dXJuIHJlc3VsdDsNCgl9DQoJDQoJLyoqDQoJICogQ29udGludWUgcGFyc2luZyBwYWNrZXRzIGJlbG9uZ2luZyB0byB0aGUgdXNlciBhdHRyaWJ1dGUgcGFja2V0IHN1Y2ggYXMgc2lnbmF0dXJlcw0KCSAqIEBwYXJhbSB7T2JqZWN0fSBwYXJlbnRfbm9kZSB0aGUgcGFyZW50IG9iamVjdA0KCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBpbnB1dCBzdHJpbmcgdG8gcmVhZCB0aGUgcGFja2V0KHMpIGZyb20NCgkgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIHN0YXJ0IHBvc2l0aW9uIGZvciB0aGUgcGFyc2VyDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gbGVuZ3RoIG9mIHRoZSBwYWNrZXQocykgb3IgcmVtYWluaW5nIGxlbmd0aCBvZiBpbnB1dA0KCSAqIEByZXR1cm4ge0ludGVnZXJ9IGxlbmd0aCBvZiBub2RlcyByZWFkDQoJICovDQoJZnVuY3Rpb24gcmVhZF9ub2RlcyhwYXJlbnRfbm9kZSwgaW5wdXQsIHBvc2l0aW9uLCBsZW4pIHsNCgkJDQoJCXRoaXMucGFyZW50Tm9kZSA9IHBhcmVudF9ub2RlOw0KCQl2YXIgZXhpdCA9IGZhbHNlOw0KCQl2YXIgcG9zID0gcG9zaXRpb247DQoJCXZhciBsID0gbGVuOw0KCQl3aGlsZSAoaW5wdXQubGVuZ3RoICE9IHBvcykgew0KCQkJdmFyIHJlc3VsdCA9IG9wZW5wZ3BfcGFja2V0LnJlYWRfcGFja2V0KGlucHV0LCBwb3MsIGwpOw0KCQkJaWYgKHJlc3VsdCA9PSBudWxsKSB7DQoJCQkJdXRpbC5wcmludF9lcnJvcigib3BlbnBncC5wYWNrZXQudXNlcmF0dHJpYnV0ZS5qc1xuIisnW3VzZXJfYXR0cl0gcGFyc2luZyBlbmRzIGhlcmUgQDonICsgcG9zICsgIiBsOiIgKyBsKTsNCgkJCQlicmVhazsNCgkJCX0gZWxzZSB7DQoJCQkJc3dpdGNoIChyZXN1bHQudGFnVHlwZSkgew0KCQkJCWNhc2UgMjogLy8gU2lnbmF0dXJlIFBhY2tldA0KCQkJCQlpZiAocmVzdWx0LnNpZ25hdHVyZVR5cGUgPiAxNQ0KCQkJCQkJCSYmIHJlc3VsdC5zaWduYXR1cmVUeXBlIDwgMjApIC8vIGNlcnRpZmljYXRpb24NCgkJCQkJCS8vIC8vDQoJCQkJCQkvLyBzaWduYXR1cmUNCgkJCQkJCXRoaXMuY2VydGlmaWNhdGlvblNpZ25hdHVyZXNbdGhpcy5jZXJ0aWZpY2F0aW9uU2lnbmF0dXJlcy5sZW5ndGhdID0gcmVzdWx0Ow0KCQkJCQllbHNlIGlmIChyZXN1bHQuc2lnbmF0dXJlVHlwZSA9PSAzMikgLy8gY2VydGlmaWNhdGlvbiByZXZvY2F0aW9uIHNpZ25hdHVyZQ0KCQkJCQkJdGhpcy5jZXJ0aWZpY2F0aW9uUmV2b2NhdGlvblNpZ25hdHVyZXNbdGhpcy5jZXJ0aWZpY2F0aW9uUmV2b2NhdGlvblNpZ25hdHVyZXMubGVuZ3RoXSA9IHJlc3VsdDsNCgkJCQkJcG9zICs9IHJlc3VsdC5wYWNrZXRMZW5ndGggKyByZXN1bHQuaGVhZGVyTGVuZ3RoOw0KCQkJCQlsID0gbGVuIC0gKHBvcyAtIHBvc2l0aW9uKTsNCgkJCQkJYnJlYWs7DQoJCQkJZGVmYXVsdDoNCgkJCQkJdGhpcy5kYXRhID0gaW5wdXQ7DQoJCQkJCXRoaXMucG9zaXRpb24gPSBwb3NpdGlvbiAtIHBhcmVudF9ub2RlLnBhY2tldExlbmd0aDsNCgkJCQkJdGhpcy5sZW4gPSBwb3MgLSBwb3NpdGlvbjsNCgkJCQkJcmV0dXJuIHRoaXMubGVuOw0KCQkJCQlicmVhazsNCgkJCQl9DQoJCQl9DQoJCX0NCgkJdGhpcy5kYXRhID0gaW5wdXQ7DQoJCXRoaXMucG9zaXRpb24gPSBwb3NpdGlvbiAtIHBhcmVudF9ub2RlLnBhY2tldExlbmd0aDsNCgkJdGhpcy5sZW4gPSBwb3MgLSBwb3NpdGlvbjsNCgkJcmV0dXJuIHRoaXMubGVuOw0KDQoJfQ0KCQ0KCXRoaXMucmVhZF9wYWNrZXQgPSByZWFkX3BhY2tldDsNCgl0aGlzLnJlYWRfbm9kZXMgPSByZWFkX25vZGVzOw0KCXRoaXMudG9TdHJpbmcgPSB0b1N0cmluZzsNCgkNCn07DQovLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHQNCi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkgNCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcg0KLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyDQovLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4NCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsDQovLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0KLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUNCi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuDQovLyANCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUNCi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQ0KDQovKioNCiAqIEBjbGFzcw0KICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgVXNlciBJRCBQYWNrZXQgKFRhZyAxMykNCiAqIEEgVXNlciBJRCBwYWNrZXQgY29uc2lzdHMgb2YgVVRGLTggdGV4dCB0aGF0IGlzIGludGVuZGVkIHRvIHJlcHJlc2VudA0KICogdGhlIG5hbWUgYW5kIGVtYWlsIGFkZHJlc3Mgb2YgdGhlIGtleSBob2xkZXIuICBCeSBjb252ZW50aW9uLCBpdA0KICogaW5jbHVkZXMgYW4gUkZDIDI4MjIgW1JGQzI4MjJdIG1haWwgbmFtZS1hZGRyLCBidXQgdGhlcmUgYXJlIG5vDQogKiByZXN0cmljdGlvbnMgb24gaXRzIGNvbnRlbnQuICBUaGUgcGFja2V0IGxlbmd0aCBpbiB0aGUgaGVhZGVyDQogKiBzcGVjaWZpZXMgdGhlIGxlbmd0aCBvZiB0aGUgVXNlciBJRC4gDQogKi8NCg0KZnVuY3Rpb24gb3BlbnBncF9wYWNrZXRfdXNlcmlkKCkgew0KCXRoaXMudGV4dCA9ICcnDQoJdGhpcy50YWdUeXBlID0gMTM7DQoJdGhpcy5jZXJ0aWZpY2F0aW9uU2lnbmF0dXJlcyA9IG5ldyBBcnJheSgpOw0KCXRoaXMuY2VydGlmaWNhdGlvblJldm9jYXRpb25TaWduYXR1cmVzID0gbmV3IEFycmF5KCk7DQoJdGhpcy5yZXZvY2F0aW9uU2lnbmF0dXJlcyA9IG5ldyBBcnJheSgpOw0KCXRoaXMucGFyZW50Tm9kZSA9IG51bGw7DQoJDQoJLyoqDQoJICogU2V0IHRoZSBwYWNrZXQgdGV4dCBmaWVsZCB0byBhIG5hdGl2ZSBqYXZhc2NyaXB0IHN0cmluZw0KCSAqIENvbnZlcnNpb24gdG8gYSBwcm9wZXIgdXRmOCBlbmNvZGluZyB0YWtlcyBwbGFjZSB3aGVuIHRoZSANCgkgKiBwYWNrZXQgaXMgd3JpdHRlbi4NCgkgKiBAcGFyYW0ge1N0cmluZ30gc3RyIEFueSBuYXRpdmUgamF2YXNjcmlwdCBzdHJpbmcNCgkgKi8NCgl0aGlzLnNldF90ZXh0ID0gZnVuY3Rpb24oc3RyKSB7DQoJCXRoaXMudGV4dCA9IHN0cjsNCgl9DQoNCgkvKioNCgkgKiBTZXQgdGhlIHBhY2tldCB0ZXh0IHRvIHZhbHVlIHJlcHJlc2VudGVkIGJ5IHRoZSBwcm92aWRlZCBzdHJpbmcNCgkgKiBvZiBieXRlcy4NCgkgKiBAcGFyYW0ge1N0cmluZ30gYnl0ZXMgQSBzdHJpbmcgb2YgYnl0ZXMNCgkgKi8NCgl0aGlzLnNldF90ZXh0X2J5dGVzID0gZnVuY3Rpb24oYnl0ZXMpIHsNCgkJdGhpcy50ZXh0ID0gdXRpbC5kZWNvZGVfdXRmOChieXRlcyk7DQoJfQ0KDQoJLyoqDQoJICogR2V0IHRoZSBieXRlIHNlcXVlbmNlIHJlcHJlc2VudGluZyB0aGUgdGV4dCBvZiB0aGlzIHBhY2tldC4NCgkgKiBAcmV0dXJucyB7U3RyaW5nfSBBIHNlcXVlbmNlIG9mIGJ5dGVzDQoJICovDQoJdGhpcy5nZXRfdGV4dF9ieXRlcyA9IGZ1bmN0aW9uKCkgew0KCQlyZXR1cm4gdXRpbC5lbmNvZGVfdXRmOCh0aGlzLnRleHQpOw0KCX0NCgkNCg0KCS8qKg0KCSAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgdXNlciBpZCBwYWNrZXQgKHRhZyAxMykuDQoJICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IHBheWxvYWQgb2YgYSB0YWcgMTMgcGFja2V0DQoJICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBwb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZw0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuIGxlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mIGlucHV0IGF0IHBvc2l0aW9uDQoJICogQHJldHVybiB7b3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkZGF0YX0gb2JqZWN0IHJlcHJlc2VudGF0aW9uDQoJICovDQoJdGhpcy5yZWFkX3BhY2tldCA9IGZ1bmN0aW9uKGlucHV0LCBwb3NpdGlvbiwgbGVuKSB7DQoJCXRoaXMucGFja2V0TGVuZ3RoID0gbGVuOw0KDQoJCXZhciBieXRlcyA9ICcnOw0KCQlmb3IgKCB2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykgew0KCQkJYnl0ZXMgKz0gaW5wdXRbcG9zaXRpb24gKyBpXTsNCgkJfQ0KDQoJCXRoaXMuc2V0X3RleHRfYnl0ZXMoYnl0ZXMpOw0KCQlyZXR1cm4gdGhpczsNCgl9DQoNCgkvKioNCgkgKiBDcmVhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB1c2VyIGlkIHBhY2tldA0KCSAqIEBwYXJhbSB7U3RyaW5nfSB1c2VyX2lkIHRoZSB1c2VyIGlkIGFzIHN0cmluZyAoIkpvaG4gRG9lIDxqb2huLmRvZUBtYWlsLnVzIikNCgkgKiBAcmV0dXJuIHtTdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvbg0KCSAqLw0KCXRoaXMud3JpdGVfcGFja2V0ID0gZnVuY3Rpb24odXNlcl9pZCkgew0KCQl0aGlzLnNldF90ZXh0KHVzZXJfaWQpOw0KCQl2YXIgYnl0ZXMgPSB0aGlzLmdldF90ZXh0X2J5dGVzKCk7DQoNCgkJdmFyIHJlc3VsdCA9IG9wZW5wZ3BfcGFja2V0LndyaXRlX3BhY2tldF9oZWFkZXIoMTMsIGJ5dGVzLmxlbmd0aCk7DQoJCXJlc3VsdCArPSBieXRlczsNCgkJcmV0dXJuIHJlc3VsdDsNCgl9DQoNCgkvKioNCgkgKiBDb250aW51ZSBwYXJzaW5nIHBhY2tldHMgYmVsb25naW5nIHRvIHRoZSB1c2VyaWQgcGFja2V0IHN1Y2ggYXMgc2lnbmF0dXJlcw0KCSAqIEBwYXJhbSB7T2JqZWN0fSBwYXJlbnRfbm9kZSB0aGUgcGFyZW50IG9iamVjdA0KCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBpbnB1dCBzdHJpbmcgdG8gcmVhZCB0aGUgcGFja2V0KHMpIGZyb20NCgkgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIHN0YXJ0IHBvc2l0aW9uIGZvciB0aGUgcGFyc2VyDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gbGVuZ3RoIG9mIHRoZSBwYWNrZXQocykgb3IgcmVtYWluaW5nIGxlbmd0aCBvZiBpbnB1dA0KCSAqIEByZXR1cm4ge0ludGVnZXJ9IGxlbmd0aCBvZiBub2RlcyByZWFkDQoJICovDQoJdGhpcy5yZWFkX25vZGVzID0gZnVuY3Rpb24ocGFyZW50X25vZGUsIGlucHV0LCBwb3NpdGlvbiwgbGVuKSB7DQoJCWlmIChwYXJlbnRfbm9kZS50YWdUeXBlID09IDYpIHsgLy8gcHVibGljIGtleQ0KCQkJdGhpcy5wYXJlbnROb2RlID0gcGFyZW50X25vZGU7DQoJCQl2YXIgcG9zID0gcG9zaXRpb247DQoJCQl2YXIgbCA9IGxlbjsNCgkJCXdoaWxlIChpbnB1dC5sZW5ndGggIT0gcG9zKSB7DQoJCQkJdmFyIHJlc3VsdCA9IG9wZW5wZ3BfcGFja2V0LnJlYWRfcGFja2V0KGlucHV0LCBwb3MsIGwgLSAocG9zIC0gcG9zaXRpb24pKTsNCgkJCQlpZiAocmVzdWx0ID09IG51bGwpIHsNCgkJCQkJdXRpbC5wcmludF9lcnJvcignW3VzZXJfaWRdIHBhcnNpbmcgZW5kcyBoZXJlIEA6JyArIHBvcyArICIgbDoiICsgbCk7DQoJCQkJCWJyZWFrOw0KCQkJCX0gZWxzZSB7DQoJCQkJCQ0KCQkJCQlwb3MgKz0gcmVzdWx0LnBhY2tldExlbmd0aCArIHJlc3VsdC5oZWFkZXJMZW5ndGg7DQoJCQkJCWwgPSBpbnB1dC5sZW5ndGggLSBwb3M7DQoJCQkJCXN3aXRjaCAocmVzdWx0LnRhZ1R5cGUpIHsNCgkJCQkJY2FzZSAyOiAvLyBTaWduYXR1cmUgUGFja2V0DQoJCQkJCQlpZiAocmVzdWx0LnNpZ25hdHVyZVR5cGUgPiAxNQ0KCQkJCQkJCQkmJiByZXN1bHQuc2lnbmF0dXJlVHlwZSA8IDIwKSB7IC8vIGNlcnRpZmljYXRpb24NCgkJCQkJCQkvLyAvLw0KCQkJCQkJCS8vIHNpZ25hdHVyZQ0KCQkJCQkJCXRoaXMuY2VydGlmaWNhdGlvblNpZ25hdHVyZXNbdGhpcy5jZXJ0aWZpY2F0aW9uU2lnbmF0dXJlcy5sZW5ndGhdID0gcmVzdWx0Ow0KCQkJCQkJCWJyZWFrOw0KCQkJCQkJfSBlbHNlIGlmIChyZXN1bHQuc2lnbmF0dXJlVHlwZSA9PSA0OCkgey8vIGNlcnRpZmljYXRpb24gcmV2b2NhdGlvbiBzaWduYXR1cmUNCgkJCQkJCQl0aGlzLmNlcnRpZmljYXRpb25SZXZvY2F0aW9uU2lnbmF0dXJlc1t0aGlzLmNlcnRpZmljYXRpb25SZXZvY2F0aW9uU2lnbmF0dXJlcy5sZW5ndGhdID0gcmVzdWx0Ow0KCQkJCQkJCWJyZWFrOw0KCQkJCQkJfSBlbHNlIGlmIChyZXN1bHQuc2lnbmF0dXJlVHlwZSA9PSAyNCkgeyAvLyBvbWcuIHN0YW5kYWxvbmUgc2lnbmF0dXJlIA0KCQkJCQkJCXRoaXMuY2VydGlmaWNhdGlvblNpZ25hdHVyZXNbdGhpcy5jZXJ0aWZpY2F0aW9uU2lnbmF0dXJlcy5sZW5ndGhdID0gcmVzdWx0Ow0KCQkJCQkJCWJyZWFrOw0KCQkJCQkJfSBlbHNlIHsNCgkJCQkJCQl1dGlsLnByaW50X2RlYnVnKCJ1bmtub3duIHNpZyB0OiAiK3Jlc3VsdC5zaWduYXR1cmVUeXBlKyJAIisocG9zIC0gKHJlc3VsdC5wYWNrZXRMZW5ndGggKyByZXN1bHQuaGVhZGVyTGVuZ3RoKSkpOw0KCQkJCQkJfQ0KCQkJCQlkZWZhdWx0Og0KCQkJCQkJdGhpcy5kYXRhID0gaW5wdXQ7DQoJCQkJCQl0aGlzLnBvc2l0aW9uID0gcG9zaXRpb24gLSBwYXJlbnRfbm9kZS5wYWNrZXRMZW5ndGg7DQoJCQkJCQl0aGlzLmxlbiA9IHBvcyAtIHBvc2l0aW9uIC0ocmVzdWx0LmhlYWRlckxlbmd0aCArIHJlc3VsdC5wYWNrZXRMZW5ndGgpOw0KCQkJCQkJcmV0dXJuIHRoaXMubGVuOw0KCQkJCQl9DQoJCQkJfQ0KCQkJfQ0KCQkJdGhpcy5kYXRhID0gaW5wdXQ7DQoJCQl0aGlzLnBvc2l0aW9uID0gcG9zaXRpb24gLSBwYXJlbnRfbm9kZS5wYWNrZXRMZW5ndGg7DQoJCQl0aGlzLmxlbiA9IHBvcyAtIHBvc2l0aW9uIC0ocmVzdWx0LmhlYWRlckxlbmd0aCArIHJlc3VsdC5wYWNrZXRMZW5ndGgpOw0KCQkJcmV0dXJuIHRoaXMubGVuOw0KCQl9IGVsc2UgaWYgKHBhcmVudF9ub2RlLnRhZ1R5cGUgPT0gNSkgeyAvLyBzZWNyZXQgS2V5DQoJCQl0aGlzLnBhcmVudE5vZGUgPSBwYXJlbnRfbm9kZTsNCgkJCXZhciBleGl0ID0gZmFsc2U7DQoJCQl2YXIgcG9zID0gcG9zaXRpb247DQoJCQl3aGlsZSAoaW5wdXQubGVuZ3RoICE9IHBvcykgew0KCQkJCXZhciByZXN1bHQgPSBvcGVucGdwX3BhY2tldC5yZWFkX3BhY2tldChpbnB1dCwgcG9zLCBsIC0gKHBvcyAtIHBvc2l0aW9uKSk7DQoJCQkJaWYgKHJlc3VsdCA9PSBudWxsKSB7DQoJCQkJCXV0aWwucHJpbnRfZXJyb3IoJ3BhcnNpbmcgZW5kcyBoZXJlIEA6JyArIHBvcyArICIgbDoiICsgbCk7DQoJCQkJCWJyZWFrOw0KCQkJCX0gZWxzZSB7DQoJCQkJCXBvcyArPSByZXN1bHQucGFja2V0TGVuZ3RoICsgcmVzdWx0LmhlYWRlckxlbmd0aDsNCgkJCQkJbCA9IGlucHV0Lmxlbmd0aCAtIHBvczsNCgkJCQkJc3dpdGNoIChyZXN1bHQudGFnVHlwZSkgew0KCQkJCQljYXNlIDI6IC8vIFNpZ25hdHVyZSBQYWNrZXQgY2VydGlmaWNhdGlvbiBzaWduYXR1cmUNCgkJCQkJCWlmIChyZXN1bHQuc2lnbmF0dXJlVHlwZSA+IDE1DQoJCQkJCQkJCSYmIHJlc3VsdC5zaWduYXR1cmVUeXBlIDwgMjApDQoJCQkJCQkJdGhpcy5jZXJ0aWZpY2F0aW9uU2lnbmF0dXJlc1t0aGlzLmNlcnRpZmljYXRpb25TaWduYXR1cmVzLmxlbmd0aF0gPSByZXN1bHQ7DQoJCQkJCQkvLyBjZXJ0aWZpY2F0aW9uIHJldm9jYXRpb24gc2lnbmF0dXJlDQoJCQkJCQllbHNlIGlmIChyZXN1bHQuc2lnbmF0dXJlVHlwZSA9PSA0OCkNCgkJCQkJCQl0aGlzLmNlcnRpZmljYXRpb25SZXZvY2F0aW9uU2lnbmF0dXJlc1t0aGlzLmNlcnRpZmljYXRpb25SZXZvY2F0aW9uU2lnbmF0dXJlcy5sZW5ndGhdID0gcmVzdWx0Ow0KCQkJCQlkZWZhdWx0Og0KCQkJCQkJdGhpcy5kYXRhID0gaW5wdXQ7DQoJCQkJCQl0aGlzLnBvc2l0aW9uID0gcG9zaXRpb24gLSBwYXJlbnRfbm9kZS5wYWNrZXRMZW5ndGg7DQoJCQkJCQl0aGlzLmxlbiA9IHBvcyAtIHBvc2l0aW9uIC0ocmVzdWx0LmhlYWRlckxlbmd0aCArIHJlc3VsdC5wYWNrZXRMZW5ndGgpOw0KCQkJCQkJcmV0dXJuIHRoaXMubGVuOw0KCQkJCQl9DQoJCQkJfQ0KCQkJfQ0KCQl9IGVsc2Ugew0KCQkJdXRpbC5wcmludF9lcnJvcigidW5rbm93biBwYXJlbnQgbm9kZSBmb3IgYSB1c2VySWQgcGFja2V0ICIrcGFyZW50X25vZGUudGFnVHlwZSk7DQoJCX0NCgl9DQoJDQoJLyoqDQoJICogZ2VuZXJhdGVzIGRlYnVnIG91dHB1dCAocHJldHR5IHByaW50KQ0KCSAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIHdoaWNoIGdpdmVzIHNvbWUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHVzZXIgaWQgcGFja2V0DQoJICovDQoJdGhpcy50b1N0cmluZyA9IGZ1bmN0aW9uKCkgew0KCQl2YXIgcmVzdWx0ID0gJyAgICAgNS4xMS4gIFVzZXIgSUQgUGFja2V0IChUYWcgMTMpXG4nICsgJyAgICB0ZXh0ICgnDQoJCQkJKyB0aGlzLnRleHQubGVuZ3RoICsgJyk6ICInICsgdGhpcy50ZXh0LnJlcGxhY2UoIjwiLCAiJmx0OyIpDQoJCQkJKyAnIlxuJzsNCgkJcmVzdWx0ICs9ImNlcnRpZmljYXRpb24gc2lnbmF0dXJlczpcbiI7DQoJCWZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5jZXJ0aWZpY2F0aW9uU2lnbmF0dXJlcy5sZW5ndGg7IGkrKykgew0KCQkJcmVzdWx0ICs9ICIgICAgICAgICIrdGhpcy5jZXJ0aWZpY2F0aW9uU2lnbmF0dXJlc1tpXS50b1N0cmluZygpOw0KCQl9DQoJCXJlc3VsdCArPSJjZXJ0aWZpY2F0aW9uIHJldm9jYXRpb24gc2lnbmF0dXJlczpcbiI7DQoJCWZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5jZXJ0aWZpY2F0aW9uUmV2b2NhdGlvblNpZ25hdHVyZXMubGVuZ3RoOyBpKyspIHsNCgkJCXJlc3VsdCArPSAiICAgICAgICAiK3RoaXMuY2VydGlmaWNhdGlvblJldm9jYXRpb25TaWduYXR1cmVzW2ldLnRvU3RyaW5nKCk7DQoJCX0NCgkJcmV0dXJuIHJlc3VsdDsNCgl9DQoNCgkvKioNCgkgKiBsb29rdXAgZnVuY3Rpb24gdG8gZmluZCBjZXJ0aWZpY2F0aW9uIHJldm9jYXRpb24gc2lnbmF0dXJlcw0KCSAqIEBwYXJhbSB7U3RyaW5nfSBrZXlJZCBzdHJpbmcgY29udGFpbmluZyB0aGUga2V5IGlkIG9mIHRoZSBpc3N1ZXIgb2YgdGhpcyBzaWduYXR1cmUNCgkgKiBAcmV0dXJuIGEgQ2VydGlmaWNhdGlvblJldm9jYXRpb25TaWduYXR1cmUgaWYgZm91bmQ7IG90aGVyd2lzZSBudWxsDQoJICovDQoJdGhpcy5oYXNDZXJ0aWZpY2F0aW9uUmV2b2NhdGlvblNpZ25hdHVyZSA9IGZ1bmN0aW9uKGtleUlkKSB7DQoJCWZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5jZXJ0aWZpY2F0aW9uUmV2b2NhdGlvblNpZ25hdHVyZXMubGVuZ3RoOyBpKyspIHsNCgkJCWlmICgodGhpcy5jZXJ0aWZpY2F0aW9uUmV2b2NhdGlvblNpZ25hdHVyZXNbaV0udmVyc2lvbiA9PSAzICYmDQoJCQkJIHRoaXMuY2VydGlmaWNhdGlvblJldm9jYXRpb25TaWduYXR1cmVzW2ldLmtleUlkID09IGtleUlkKSB8fA0KCQkJCSh0aGlzLmNlcnRpZmljYXRpb25SZXZvY2F0aW9uU2lnbmF0dXJlc1tpXS52ZXJzaW9uID09IDQgJiYNCgkJCQkgdGhpcy5jZXJ0aWZpY2F0aW9uUmV2b2NhdGlvblNpZ25hdHVyZXNbaV0uaXNzdWVyS2V5SWQgPT0ga2V5SWQpKQ0KCQkJCXJldHVybiB0aGlzLmNlcnRpZmljYXRpb25SZXZvY2F0aW9uU2lnbmF0dXJlc1tpXTsNCgkJfQ0KCQlyZXR1cm4gbnVsbDsNCgl9DQoNCgkvKioNCgkgKiBWZXJpZmllcyBhbGwgY2VydGlmaWNhdGlvbiBzaWduYXR1cmVzLiBUaGlzIG1ldGhvZCBkb2VzIG5vdCBjb25zaWRlciBwb3NzaWJsZSByZXZvY2F0aW9uIHNpZ25hdHVyZXMuDQoJICogQHBhcmFtIHtPYmplY3R9IHB1YmxpY0tleVBhY2tldCB0aGUgdG9wIGxldmVsIGtleSBtYXRlcmlhbA0KCSAqIEByZXR1cm4ge0ludGVnZXJbXX0gQW4gYXJyYXkgb2YgaW50ZWdlcnMgY29ycmVzcG9uZGluZyB0byB0aGUgYXJyYXkgb2YgY2VydGlmaWNhdGlvbiBzaWduYXR1cmVzLiBUaGUgbWVhbmluZyBvZiBlYWNoIGludGVnZXIgaXMgdGhlIGZvbGxvd2luZzoNCgkgKiAwID0gYmFkIHNpZ25hdHVyZQ0KCSAqIDEgPSBzaWduYXR1cmUgZXhwaXJlZA0KCSAqIDIgPSBpc3N1ZXIga2V5IG5vdCBhdmFpbGFibGUNCgkgKiAzID0gcmV2b2tlZA0KCSAqIDQgPSBzaWduYXR1cmUgdmFsaWQNCgkgKiA1ID0gc2lnbmF0dXJlIGJ5IGtleSBvd25lciBleHBpcmVkDQoJICogNiA9IHNpZ25hdHVyZSBieSBrZXkgb3duZXIgcmV2b2tlZA0KCSAqLw0KCXRoaXMudmVyaWZ5Q2VydGlmaWNhdGlvblNpZ25hdHVyZXMgPSBmdW5jdGlvbihwdWJsaWNLZXlQYWNrZXQpIHsNCgkJdmFyIGJ5dGVzID0gdGhpcy5nZXRfdGV4dF9ieXRlcygpOw0KCQlyZXN1bHQgPSBuZXcgQXJyYXkoKTsNCgkJZm9yICh2YXIgaSA9IDAgOyBpIDwgdGhpcy5jZXJ0aWZpY2F0aW9uU2lnbmF0dXJlcy5sZW5ndGg7IGkrKykgew0KCQkJLy8gQSBjZXJ0aWZpY2F0aW9uIHNpZ25hdHVyZSAodHlwZSAweDEwIHRocm91Z2ggMHgxMykgaGFzaGVzIHRoZSBVc2VyDQoJCQkvLyBJRCBiZWluZyBib3VuZCB0byB0aGUga2V5IGludG8gdGhlIGhhc2ggY29udGV4dCBhZnRlciB0aGUgYWJvdmUNCgkJCS8vIGRhdGEuICBBIFYzIGNlcnRpZmljYXRpb24gaGFzaGVzIHRoZSBjb250ZW50cyBvZiB0aGUgVXNlciBJRCBvcg0KCQkJLy8gYXR0cmlidXRlIHBhY2tldCBwYWNrZXQsIHdpdGhvdXQgYW55IGhlYWRlci4gIEEgVjQgY2VydGlmaWNhdGlvbg0KCQkJLy8gaGFzaGVzIHRoZSBjb25zdGFudCAweEI0IGZvciBVc2VyIElEIGNlcnRpZmljYXRpb25zIG9yIHRoZSBjb25zdGFudA0KCQkJLy8gMHhEMSBmb3IgVXNlciBBdHRyaWJ1dGUgY2VydGlmaWNhdGlvbnMsIGZvbGxvd2VkIGJ5IGEgZm91ci1vY3RldA0KCQkJLy8gbnVtYmVyIGdpdmluZyB0aGUgbGVuZ3RoIG9mIHRoZSBVc2VyIElEIG9yIFVzZXIgQXR0cmlidXRlIGRhdGEsIGFuZA0KCQkJLy8gdGhlbiB0aGUgVXNlciBJRCBvciBVc2VyIEF0dHJpYnV0ZSBkYXRhLg0KDQoJCQlpZiAodGhpcy5jZXJ0aWZpY2F0aW9uU2lnbmF0dXJlc1tpXS52ZXJzaW9uID09IDQpIHsNCgkJCQlpZiAodGhpcy5jZXJ0aWZpY2F0aW9uU2lnbmF0dXJlc1tpXS5zaWduYXR1cmVFeHBpcmF0aW9uVGltZSAhPSBudWxsICYmDQoJCQkJCQl0aGlzLmNlcnRpZmljYXRpb25TaWduYXR1cmVzW2ldLnNpZ25hdHVyZUV4cGlyYXRpb25UaW1lICE9IG51bGwgJiYNCgkJCQkJCXRoaXMuY2VydGlmaWNhdGlvblNpZ25hdHVyZXNbaV0uc2lnbmF0dXJlRXhwaXJhdGlvblRpbWUgIT0gMCAmJg0KCQkJCQkJIXRoaXMuY2VydGlmaWNhdGlvblNpZ25hdHVyZXNbaV0uc2lnbmF0dXJlTmV2ZXJFeHBpcmVzICYmDQoJCQkJCQluZXcgRGF0ZSh0aGlzLmNlcnRpZmljYXRpb25TaWduYXR1cmVzW2ldLmNyZWF0aW9uVGltZS5nZXRUaW1lKCkgKyh0aGlzLmNlcnRpZmljYXRpb25TaWduYXR1cmVzW2ldLnNpZ25hdHVyZUV4cGlyYXRpb25UaW1lKjEwMDApKSA8IG5ldyBEYXRlKCkpIHsNCgkJCQkJaWYgKHRoaXMuY2VydGlmaWNhdGlvblNpZ25hdHVyZXNbaV0uaXNzdWVyS2V5SWQgPT0gcHVibGljS2V5UGFja2V0LmdldEtleUlkKCkpDQoJCQkJCQlyZXN1bHRbaV0gPSA1Ow0KCQkJCQllbHNlDQoJCQkJCQlyZXN1bHRbaV0gPSAxOw0KCQkJCQljb250aW51ZTsNCgkJCQl9DQoJCQkJaWYgKHRoaXMuY2VydGlmaWNhdGlvblNpZ25hdHVyZXNbaV0uaXNzdWVyS2V5SWQgPT0gbnVsbCkgew0KCQkJCQlyZXN1bHRbaV0gPSAwOw0KCQkJCQljb250aW51ZTsNCgkJCQl9DQoJCQkJdmFyIGlzc3VlclB1YmxpY0tleSA9IG9wZW5wZ3Aua2V5cmluZy5nZXRQdWJsaWNLZXlzRm9yS2V5SWQodGhpcy5jZXJ0aWZpY2F0aW9uU2lnbmF0dXJlc1tpXS5pc3N1ZXJLZXlJZCk7DQoJCQkJaWYgKGlzc3VlclB1YmxpY0tleSA9PSBudWxsIHx8IGlzc3VlclB1YmxpY0tleS5sZW5ndGggPT0gMCkgew0KCQkJCQlyZXN1bHRbaV0gPSAyOw0KCQkJCQljb250aW51ZTsNCgkJCQl9DQoJCQkJLy8gVE9ETzogdHJ5IHRvIHZlcmlmeSBhbGwgcmV0dXJuZWQgaXNzdWVyIHB1YmxpYyBrZXlzIChrZXkgaWRzIGFyZSBub3QgdW5pcXVlISkNCgkJCQl2YXIgaXNzdWVyUHVibGljS2V5ID0gaXNzdWVyUHVibGljS2V5WzBdOw0KCQkJCXZhciBzaWduaW5nS2V5ID0gaXNzdWVyUHVibGljS2V5Lm9iai5nZXRTaWduaW5nS2V5KCk7DQoJCQkJaWYgKHNpZ25pbmdLZXkgPT0gbnVsbCkgew0KCQkJCQlyZXN1bHRbaV0gPSAwOw0KCQkJCQljb250aW51ZTsNCgkJCQl9DQoJCQkJdmFyIHJldm9jYXRpb24gPSB0aGlzLmhhc0NlcnRpZmljYXRpb25SZXZvY2F0aW9uU2lnbmF0dXJlKHRoaXMuY2VydGlmaWNhdGlvblNpZ25hdHVyZXNbaV0uaXNzdWVyS2V5SWQpOw0KCQkJCWlmIChyZXZvY2F0aW9uICE9IG51bGwgJiYgcmV2b2NhdGlvbi5jcmVhdGlvblRpbWUgPiANCgkJCQkJdGhpcy5jZXJ0aWZpY2F0aW9uU2lnbmF0dXJlc1tpXS5jcmVhdGlvblRpbWUpIHsNCg0KCQkJCQl2YXIgc2lnbmF0dXJlZGF0YSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHg5OSkrIHB1YmxpY0tleVBhY2tldC5oZWFkZXIuc3Vic3RyaW5nKDEpKw0KCQkJCQlwdWJsaWNLZXlQYWNrZXQuZGF0YStTdHJpbmcuZnJvbUNoYXJDb2RlKDB4QjQpKw0KCQkJCQlTdHJpbmcuZnJvbUNoYXJDb2RlKChieXRlcy5sZW5ndGggPj4gMjQpICYgMHhGRikrDQoJCQkJCVN0cmluZy5mcm9tQ2hhckNvZGUoKGJ5dGVzLmxlbmd0aCA+PiAxNikgJiAweEZGKSsNCgkJCQkJU3RyaW5nLmZyb21DaGFyQ29kZSgoYnl0ZXMubGVuZ3RoID4+ICA4KSAmIDB4RkYpKw0KCQkJCQlTdHJpbmcuZnJvbUNoYXJDb2RlKChieXRlcy5sZW5ndGgpICYgMHhGRikrDQoJCQkJCWJ5dGVzOw0KCQkJCQlpZiAocmV2b2NhdGlvbi52ZXJpZnkoc2lnbmF0dXJlZGF0YSwgc2lnbmluZ0tleSkpIHsNCgkJCQkJCWlmICh0aGlzLmNlcnRpZmljYXRpb25TaWduYXR1cmVzW2ldLmlzc3VlcktleUlkID09IHB1YmxpY0tleVBhY2tldC5nZXRLZXlJZCgpKQ0KCQkJCQkJCXJlc3VsdFtpXSA9IDY7DQoJCQkJCQllbHNlDQoJCQkJCQkJcmVzdWx0W2ldID0gMzsNCgkJCQkJCWNvbnRpbnVlOw0KCQkJCQl9DQoJCQkJfQ0KDQoJCQkJdmFyIHNpZ25hdHVyZWRhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4OTkpKyBwdWJsaWNLZXlQYWNrZXQuaGVhZGVyLnN1YnN0cmluZygxKSsNCgkJCQkJCXB1YmxpY0tleVBhY2tldC5kYXRhK1N0cmluZy5mcm9tQ2hhckNvZGUoMHhCNCkrDQoJCQkJCQlTdHJpbmcuZnJvbUNoYXJDb2RlKChieXRlcy5sZW5ndGggPj4gMjQpICYgMHhGRikrDQoJCQkJCQlTdHJpbmcuZnJvbUNoYXJDb2RlKChieXRlcy5sZW5ndGggPj4gMTYpICYgMHhGRikrDQoJCQkJCQlTdHJpbmcuZnJvbUNoYXJDb2RlKChieXRlcy5sZW5ndGggPj4gIDgpICYgMHhGRikrDQoJCQkJCQlTdHJpbmcuZnJvbUNoYXJDb2RlKChieXRlcy5sZW5ndGgpICYgMHhGRikrDQoJCQkJCQlieXRlczsNCgkJCQlpZiAodGhpcy5jZXJ0aWZpY2F0aW9uU2lnbmF0dXJlc1tpXS52ZXJpZnkoc2lnbmF0dXJlZGF0YSwgc2lnbmluZ0tleSkpIHsNCgkJCQkJcmVzdWx0W2ldID0gNDsNCgkJCQl9IGVsc2UNCgkJCQlyZXN1bHRbaV0gPSAwOw0KCQkJfSBlbHNlIGlmICh0aGlzLmNlcnRpZmljYXRpb25TaWduYXR1cmVzW2ldLnZlcnNpb24gPT0gMykgew0KCQkJCWlmICh0aGlzLmNlcnRpZmljYXRpb25TaWduYXR1cmVzW2ldLmtleUlkID09IG51bGwpIHsNCgkJCQkJcmVzdWx0W2ldID0gMDsNCgkJCQkJY29udGludWU7DQoJCQkJfQ0KCQkJCXZhciBpc3N1ZXJQdWJsaWNLZXkgPSBvcGVucGdwLmtleXJpbmcuZ2V0UHVibGljS2V5c0ZvcktleUlkKHRoaXMuY2VydGlmaWNhdGlvblNpZ25hdHVyZXNbaV0ua2V5SWQpOw0KCQkJCWlmIChpc3N1ZXJQdWJsaWNLZXkgPT0gbnVsbCB8fCBpc3N1ZXJQdWJsaWNLZXkubGVuZ3RoID09IDApIHsNCgkJCQkJcmVzdWx0W2ldID0gMjsNCgkJCQkJY29udGludWU7DQoJCQkJfQ0KCQkJCWlzc3VlclB1YmxpY0tleSA9IGlzc3VlclB1YmxpY0tleVswXTsNCgkJCQl2YXIgc2lnbmluZ0tleSA9IHB1YmxpY0tleS5vYmouZ2V0U2lnbmluZ0tleSgpOw0KCQkJCWlmIChzaWduaW5nS2V5ID09IG51bGwpIHsNCgkJCQkJcmVzdWx0W2ldID0gMDsNCgkJCQkJY29udGludWU7DQoJCQkJfQ0KCQkJCXZhciByZXZvY2F0aW9uID0gdGhpcy5oYXNDZXJ0aWZpY2F0aW9uUmV2b2NhdGlvblNpZ25hdHVyZSh0aGlzLmNlcnRpZmljYXRpb25TaWduYXR1cmVzW2ldLmtleUlkKTsNCgkJCQlpZiAocmV2b2NhdGlvbiAhPSBudWxsICYmIHJldm9jYXRpb24uY3JlYXRpb25UaW1lID4gDQoJCQkJCXRoaXMuY2VydGlmaWNhdGlvblNpZ25hdHVyZXNbaV0uY3JlYXRpb25UaW1lKSB7DQoJCQkJCXZhciBzaWduYXR1cmVkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDk5KSsgdGhpcy5wdWJsaWNLZXlQYWNrZXQuaGVhZGVyLnN1YnN0cmluZygxKSsNCgkJCQkJdGhpcy5wdWJsaWNLZXlQYWNrZXQuZGF0YStieXRlczsNCgkJCQkJaWYgKHJldm9jYXRpb24udmVyaWZ5KHNpZ25hdHVyZWRhdGEsIHNpZ25pbmdLZXkpKSB7DQoJCQkJCQlpZiAocmV2b2NhdGlvbi5rZXlJZCA9PSBwdWJsaWNLZXlQYWNrZXQuZ2V0S2V5SWQoKSkNCgkJCQkJCQlyZXN1bHRbaV0gPSA2Ow0KCQkJCQkJZWxzZQ0KCQkJCQkJCXJlc3VsdFtpXSA9IDM7DQoJCQkJCQljb250aW51ZTsNCgkJCQkJfQ0KCQkJCX0NCgkJCQl2YXIgc2lnbmF0dXJlZGF0YSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHg5OSkrIHB1YmxpY0tleVBhY2tldC5oZWFkZXIuc3Vic3RyaW5nKDEpKw0KCQkJCQlwdWJsaWNLZXlQYWNrZXQuZGF0YSArIGJ5dGVzOw0KCQkJCWlmICh0aGlzLmNlcnRpZmljYXRpb25TaWduYXR1cmVzW2ldLnZlcmlmeShzaWduYXR1cmVkYXRhLCBzaWduaW5nS2V5KSkgew0KCQkJCQlyZXN1bHRbaV0gPSA0Ow0KCQkJCX0gZWxzZSANCgkJCQlyZXN1bHRbaV0gPSAwOw0KCQkJfSBlbHNlIHsNCgkJCQlyZXN1bHRbaV0gPSAwOw0KCQkJfQ0KCQl9DQoJCXJldHVybiByZXN1bHQ7DQoJfQ0KDQoJLyoqDQoJICogdmVyaWZpZXMgdGhlIHNpZ25hdHVyZXMgb2YgdGhlIHVzZXIgaWQNCgkgKiBAcmV0dXJuIDAgaWYgdGhlIHVzZXJpZCBpcyB2YWxpZDsgMSA9IHVzZXJpZCBleHBpcmVkOyAyID0gdXNlcmlkIHJldm9rZWQNCgkgKi8NCgl0aGlzLnZlcmlmeSA9IGZ1bmN0aW9uKHB1YmxpY0tleVBhY2tldCkgew0KCQl2YXIgcmVzdWx0ID0gdGhpcy52ZXJpZnlDZXJ0aWZpY2F0aW9uU2lnbmF0dXJlcyhwdWJsaWNLZXlQYWNrZXQpOw0KCQlpZiAocmVzdWx0LmluZGV4T2YoNikgIT0gLTEpDQoJCQlyZXR1cm4gMjsNCgkJaWYgKHJlc3VsdC5pbmRleE9mKDUpICE9IC0xKQ0KCQkJcmV0dXJuIDE7DQoJCXJldHVybiAwOw0KCX0NCg0KCS8vIFRPRE86IGltcGxlbWVudGF0aW9uIG1pc3NpbmcNCgl0aGlzLmFkZENlcnRpZmljYXRpb24gPSBmdW5jdGlvbihwdWJsaWNLZXlQYWNrZXQsIHByaXZhdGVLZXlQYWNrZXQpIHsNCgkJDQoJfQ0KDQoJLy8gVE9ETzogaW1wbGVtZW50YXRpb24gbWlzc2luZw0KCXRoaXMucmV2b2tlQ2VydGlmaWNhdGlvbiA9IGZ1bmN0aW9uKHB1YmxpY0tleVBhY2tldCwgcHJpdmF0ZUtleVBhY2tldCkgew0KCQkNCgl9DQp9DQovLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHQNCi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkgNCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcg0KLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyDQovLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4NCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsDQovLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0KLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUNCi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuDQovLyANCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUNCi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQ0KDQovKioNCiAqIEBjbGFzcw0KICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0eXBlIGtleSBpZCAoUkZDNDg4MCAzLjMpDQogKiAgQSBLZXkgSUQgaXMgYW4gZWlnaHQtb2N0ZXQgc2NhbGFyIHRoYXQgaWRlbnRpZmllcyBhIGtleS4NCiAgIEltcGxlbWVudGF0aW9ucyBTSE9VTEQgTk9UIGFzc3VtZSB0aGF0IEtleSBJRHMgYXJlIHVuaXF1ZS4gIFRoZQ0KICAgc2VjdGlvbiAiRW5oYW5jZWQgS2V5IEZvcm1hdHMiIGJlbG93IGRlc2NyaWJlcyBob3cgS2V5IElEcyBhcmUNCiAgIGZvcm1lZC4NCiAqLw0KZnVuY3Rpb24gb3BlbnBncF90eXBlX2tleWlkKCkgew0KCS8qKg0KCSAqIFBhcnNpbmcgbWV0aG9kIGZvciBhIGtleSBpZA0KCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBJbnB1dCB0byByZWFkIHRoZSBrZXkgaWQgZnJvbSANCgkgKiBAcGFyYW0ge2ludGVnZXJ9IHBvc2l0aW9uIFBvc2l0aW9uIHdoZXJlIHRvIHN0YXJ0IHJlYWRpbmcgdGhlIGtleSANCgkgKiBpZCBmcm9tIGlucHV0DQoJICogQHJldHVybiB7b3BlbnBncF90eXBlX2tleWlkfSBUaGlzIG9iamVjdA0KCSAqLw0KCWZ1bmN0aW9uIHJlYWRfcGFja2V0KGlucHV0LCBwb3NpdGlvbikgew0KCQl0aGlzLmJ5dGVzID0gaW5wdXQuc3Vic3RyaW5nKHBvc2l0aW9uLCBwb3NpdGlvbis4KTsNCgkJcmV0dXJuIHRoaXM7DQoJfQ0KCQ0KCS8qKg0KCSAqIEdlbmVyYXRlcyBkZWJ1ZyBvdXRwdXQgKHByZXR0eSBwcmludCkNCgkgKiBAcmV0dXJuIHtTdHJpbmd9IEtleSBJZCBhcyBoZXhhZGVjaW1hbCBzdHJpbmcNCgkgKi8NCglmdW5jdGlvbiB0b1N0cmluZygpIHsNCgkJcmV0dXJuIHV0aWwuaGV4c3RyZHVtcCh0aGlzLmJ5dGVzKTsNCgl9DQoJDQoJdGhpcy5yZWFkX3BhY2tldCA9IHJlYWRfcGFja2V0Ow0KCXRoaXMudG9TdHJpbmcgPSB0b1N0cmluZzsNCn07DQovLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHQNCi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkgNCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcg0KLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyDQovLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4NCi8vIA0KLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsDQovLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0KLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUNCi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuDQovLyANCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUNCi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQ0KDQovLyBIaW50OiBXZSBob2xkIG91ciBNUElzIGFzIGFuIGFycmF5IG9mIG9jdGV0cyBpbiBiaWcgZW5kaWFuIGZvcm1hdCBwcmVjZWVkaW5nIGEgdHdvDQovLyBvY3RldCBzY2FsYXI6IE1QSTogW2EsYixjLGQsZSxmXQ0KLy8gLSBNUEkgc2l6ZTogKGEgPDwgOCkgfCBiIA0KLy8gLSBNUEkgPSBjIHwgZCA8PCA4IHwgZSA8PCAoKE1QSS5sZW5ndGggLTIpKjgpIHwgZiAoKE1QSS5sZW5ndGggLTIpKjgpDQoNCi8qKg0KICogQGNsYXNzDQogKiBAY2xhc3NkZXNjSW1wbGVtZW50YXRpb24gb2YgdHlwZSBNUEkgKFJGQzQ4ODAgMy4yKQ0KICogTXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgKGFsc28gY2FsbGVkIE1QSXMpIGFyZSB1bnNpZ25lZCBpbnRlZ2VycyB1c2VkDQogKiB0byBob2xkIGxhcmdlIGludGVnZXJzIHN1Y2ggYXMgdGhlIG9uZXMgdXNlZCBpbiBjcnlwdG9ncmFwaGljDQogKiBjYWxjdWxhdGlvbnMuDQogKiBBbiBNUEkgY29uc2lzdHMgb2YgdHdvIHBpZWNlczogYSB0d28tb2N0ZXQgc2NhbGFyIHRoYXQgaXMgdGhlIGxlbmd0aA0KICogb2YgdGhlIE1QSSBpbiBiaXRzIGZvbGxvd2VkIGJ5IGEgc3RyaW5nIG9mIG9jdGV0cyB0aGF0IGNvbnRhaW4gdGhlDQogKiBhY3R1YWwgaW50ZWdlci4NCiAqLw0KZnVuY3Rpb24gb3BlbnBncF90eXBlX21waSgpIHsNCgl0aGlzLk1QSSA9IG51bGw7DQoJdGhpcy5tcGlCaXRMZW5ndGggPSBudWxsOw0KCXRoaXMubXBpQnl0ZUxlbmd0aCA9IG51bGw7DQoJdGhpcy5kYXRhID0gbnVsbDsNCgkvKioNCgkgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIG1waSAoUkZDIDQ4ODAgMy4yKS4NCgkgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBtcGkgZGF0YQ0KCSAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCANCgkgKiBzdHJpbmcNCgkgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBMZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZiANCgkgKiBpbnB1dCBhdCBwb3NpdGlvbg0KCSAqIEByZXR1cm4ge29wZW5wZ3BfdHlwZV9tcGl9IE9iamVjdCByZXByZXNlbnRhdGlvbg0KCSAqLw0KCWZ1bmN0aW9uIHJlYWQoaW5wdXQsIHBvc2l0aW9uLCBsZW4pIHsNCgkJdmFyIG15cG9zID0gcG9zaXRpb247DQoJCQ0KCQl0aGlzLm1waUJpdExlbmd0aCA9IChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPDwgOCkgfCBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoJCQ0KCQkvLyBBZGRpdGlvbmFsIHJ1bGVzOg0KCQkvLw0KCQkvLyAgICBUaGUgc2l6ZSBvZiBhbiBNUEkgaXMgKChNUEkubGVuZ3RoICsgNykgLyA4KSArIDIgb2N0ZXRzLg0KCQkvLw0KCQkvLyAgICBUaGUgbGVuZ3RoIGZpZWxkIG9mIGFuIE1QSSBkZXNjcmliZXMgdGhlIGxlbmd0aCBzdGFydGluZyBmcm9tIGl0cw0KCQkvLwkgIG1vc3Qgc2lnbmlmaWNhbnQgbm9uLXplcm8gYml0LiAgVGh1cywgdGhlIE1QSSBbMDAgMDIgMDFdIGlzIG5vdA0KCQkvLyAgICBmb3JtZWQgY29ycmVjdGx5LiAgSXQgc2hvdWxkIGJlIFswMCAwMSAwMV0uDQoNCgkJLy8gVE9ETzogVmVyaWZpY2F0aW9uIG9mIHRoaXMgc2l6ZSBtZXRob2QhIFRoaXMgc2l6ZSBjYWxjdWxhdGlvbiBhcw0KCQkvLyAJCSBzcGVjaWZpZWQgYWJvdmUgaXMgbm90IGFwcGxpY2FibGUgaW4gSmF2YVNjcmlwdA0KCQl0aGlzLm1waUJ5dGVMZW5ndGggPSAodGhpcy5tcGlCaXRMZW5ndGggLSAodGhpcy5tcGlCaXRMZW5ndGggJSA4KSkgLyA4Ow0KCQlpZiAodGhpcy5tcGlCaXRMZW5ndGggJSA4ICE9IDApDQoJCQl0aGlzLm1waUJ5dGVMZW5ndGgrKzsNCgkJDQoJCXRoaXMuTVBJID0gaW5wdXQuc3Vic3RyaW5nKG15cG9zLG15cG9zK3RoaXMubXBpQnl0ZUxlbmd0aCk7DQoJCXRoaXMuZGF0YSA9IGlucHV0LnN1YnN0cmluZyhwb3NpdGlvbiwgcG9zaXRpb24rMit0aGlzLm1waUJ5dGVMZW5ndGgpOw0KCQl0aGlzLnBhY2tldExlbmd0aCA9IHRoaXMubXBpQnl0ZUxlbmd0aCArMjsNCgkJcmV0dXJuIHRoaXM7DQoJfQ0KCQ0KCS8qKg0KCSAqIEdlbmVyYXRlcyBkZWJ1ZyBvdXRwdXQgKHByZXR0eSBwcmludCkNCgkgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyB3aGljaCBnaXZlcyBzb21lIGluZm9ybWF0aW9uIGFib3V0IHRoZSBtcGkNCgkgKi8NCglmdW5jdGlvbiB0b1N0cmluZygpIHsNCgkJdmFyIHIgPSAiICAgIE1QSSgiK3RoaXMubXBpQml0TGVuZ3RoKyJiLyIrdGhpcy5tcGlCeXRlTGVuZ3RoKyJCKSA6IDB4IjsNCgkJcis9dXRpbC5oZXhzdHJkdW1wKHRoaXMuTVBJKTsNCgkJcmV0dXJuIHIrJ1xuJzsNCgl9DQoJDQoJLyoqDQoJICogQ29udmVydHMgdGhlIG1waSB0byBhbiBCaWdJbnRlZ2VyIG9iamVjdA0KCSAqIEByZXR1cm4ge0JpZ0ludGVnZXJ9DQoJICovDQoJZnVuY3Rpb24gZ2V0QmlnSW50ZWdlcigpIHsNCgkJcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKHV0aWwuaGV4c3RyZHVtcCh0aGlzLk1QSSksMTYpOyANCgl9DQoNCgkNCglmdW5jdGlvbiBnZXRCaXRzKG51bSkgew0KCQlmb3IgKHZhciBpID0gMDsgaSA8IDk7IGkrKykNCgkJaWYgKG51bSA+PiBpID09IDApDQoJCXJldHVybiBpOw0KCX0NCgkNCgkvKioNCgkgKiBHZXRzIHRoZSBsZW5ndGggb2YgdGhlIG1waSBpbiBieXRlcw0KCSAqIEByZXR1cm4ge0ludGVnZXJ9IE1waSBieXRlIGxlbmd0aA0KCSAqLw0KCWZ1bmN0aW9uIGdldEJ5dGVMZW5ndGgoKSB7DQoJCXJldHVybiB0aGlzLm1waUJ5dGVMZW5ndGg7DQoJfQ0KCQ0KCS8qKg0KCSAqIENyZWF0ZXMgYW4gbXBpIGZyb20gdGhlIHNwZWNpZmllZCBzdHJpbmcNCgkgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIHJlYWQgdGhlIG1waSBmcm9tDQoJICogQHJldHVybiB7b3BlbnBncF90eXBlX21waX0gDQoJICovDQoJZnVuY3Rpb24gY3JlYXRlKGRhdGEpIHsNCgkJdGhpcy5NUEkgPSBkYXRhOw0KCQl0aGlzLm1waUJpdExlbmd0aCA9IChkYXRhLmxlbmd0aCAtMSkgKjggKyBnZXRCaXRzKGRhdGEuY2hhckNvZGVBdCgwKSk7DQoJCXRoaXMubXBpQnl0ZUxlbmd0aCA9IGRhdGEubGVuZ3RoOw0KCQlyZXR1cm4gdGhpczsNCgl9DQoJDQoJLyoqDQoJICogQ29udmVydHMgdGhlIG1waSBvYmplY3QgdG8gYSBzdHJpbmcgYXMgc3BlY2lmaWVkIGluIFJGQzQ4ODAgMy4yDQoJICogQHJldHVybiB7U3RyaW5nfSBtcGkgQnl0ZSByZXByZXNlbnRhdGlvbg0KCSAqLw0KCWZ1bmN0aW9uIHRvQmluKCkgew0KCQl2YXIgcmVzdWx0ID0gU3RyaW5nLmZyb21DaGFyQ29kZSgodGhpcy5tcGlCaXRMZW5ndGggPj4gOCkgJiAweEZGKTsNCgkJcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5tcGlCaXRMZW5ndGggJiAweEZGKTsNCgkJcmVzdWx0ICs9IHRoaXMuTVBJOw0KCQlyZXR1cm4gcmVzdWx0Ow0KCX0NCgkNCgl0aGlzLnJlYWQgPSByZWFkOw0KCXRoaXMudG9CaWdJbnRlZ2VyID0gZ2V0QmlnSW50ZWdlcjsNCgl0aGlzLnRvU3RyaW5nID0gdG9TdHJpbmc7DQoJdGhpcy5jcmVhdGUgPSBjcmVhdGU7DQoJdGhpcy50b0JpbiA9IHRvQmluOw0KCXRoaXMuZ2V0Qnl0ZUxlbmd0aCA9IGdldEJ5dGVMZW5ndGg7DQp9DQoNCi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdA0KLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSA0KLy8gDQovLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yDQovLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXINCi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLg0KLy8gDQovLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwNCi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mDQovLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQ0KLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4NCi8vIA0KLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYw0KLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQ0KLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBDQoNCi8qKg0KICogQGNsYXNzDQogKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBTdHJpbmctdG8ta2V5IHNwZWNpZmllciAoUkZDNDg4MCAzLjcpDQogKiBTdHJpbmctdG8ta2V5IChTMkspIHNwZWNpZmllcnMgYXJlIHVzZWQgdG8gY29udmVydCBwYXNzcGhyYXNlIHN0cmluZ3MNCiAgIGludG8gc3ltbWV0cmljLWtleSBlbmNyeXB0aW9uL2RlY3J5cHRpb24ga2V5cy4gIFRoZXkgYXJlIHVzZWQgaW4gdHdvDQogICBwbGFjZXMsIGN1cnJlbnRseTogdG8gZW5jcnlwdCB0aGUgc2VjcmV0IHBhcnQgb2YgcHJpdmF0ZSBrZXlzIGluIHRoZQ0KICAgcHJpdmF0ZSBrZXlyaW5nLCBhbmQgdG8gY29udmVydCBwYXNzcGhyYXNlcyB0byBlbmNyeXB0aW9uIGtleXMgZm9yDQogICBzeW1tZXRyaWNhbGx5IGVuY3J5cHRlZCBtZXNzYWdlcy4NCiAqLw0KZnVuY3Rpb24gb3BlbnBncF90eXBlX3MyaygpIHsNCgkvKioNCgkgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIHN0cmluZy10by1rZXkgc3BlY2lmaWVyIChSRkMgNDg4MCAzLjcpLg0KCSAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIHN0cmluZy10by1rZXkgc3BlY2lmaWVyDQoJICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBQb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZw0KCSAqIEByZXR1cm4ge29wZW5wZ3BfdHlwZV9zMmt9IE9iamVjdCByZXByZXNlbnRhdGlvbg0KCSAqLw0KCWZ1bmN0aW9uIHJlYWQoaW5wdXQsIHBvc2l0aW9uKSB7DQoJCXZhciBteXBvcyA9IHBvc2l0aW9uOw0KCQl0aGlzLnR5cGUgPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7DQoJCXN3aXRjaCAodGhpcy50eXBlKSB7DQoJCWNhc2UgMDogLy8gU2ltcGxlIFMySw0KCQkJLy8gT2N0ZXQgMTogaGFzaCBhbGdvcml0aG0NCgkJCXRoaXMuaGFzaEFsZ29yaXRobSA9IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJCXRoaXMuczJrTGVuZ3RoID0gMTsNCgkJCWJyZWFrOw0KDQoJCWNhc2UgMTogLy8gU2FsdGVkIFMySw0KCQkJLy8gT2N0ZXQgMTogaGFzaCBhbGdvcml0aG0NCgkJCXRoaXMuaGFzaEFsZ29yaXRobSA9IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCg0KCQkJLy8gT2N0ZXRzIDItOTogOC1vY3RldCBzYWx0IHZhbHVlDQoJCQl0aGlzLnNhbHRWYWx1ZSA9IGlucHV0LnN1YnN0cmluZyhteXBvcywgbXlwb3MrOCk7DQoJCQlteXBvcyArPSA4Ow0KCQkJdGhpcy5zMmtMZW5ndGggPSA5Ow0KCQkJYnJlYWs7DQoNCgkJY2FzZSAzOiAvLyBJdGVyYXRlZCBhbmQgU2FsdGVkIFMySw0KCQkJLy8gT2N0ZXQgMTogaGFzaCBhbGdvcml0aG0NCgkJCXRoaXMuaGFzaEFsZ29yaXRobSA9IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCg0KCQkJLy8gT2N0ZXRzIDItOTogOC1vY3RldCBzYWx0IHZhbHVlDQoJCQl0aGlzLnNhbHRWYWx1ZSA9IGlucHV0LnN1YnN0cmluZyhteXBvcywgbXlwb3MrOCk7DQoJCQlteXBvcyArPSA4Ow0KDQoJCQkvLyBPY3RldCAxMDogY291bnQsIGEgb25lLW9jdGV0LCBjb2RlZCB2YWx1ZQ0KCQkJdGhpcy5FWFBCSUFTID0gNjsNCgkJCXZhciBjID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KCQkJdGhpcy5jb3VudCA9ICgxNiArIChjICYgMTUpKSA8PCAoKGMgPj4gNCkgKyB0aGlzLkVYUEJJQVMpOw0KCQkJdGhpcy5zMmtMZW5ndGggPSAxMDsNCgkJCWJyZWFrOw0KDQoJCWNhc2UgMTAxOg0KCQkJaWYoaW5wdXQuc3Vic3RyaW5nKG15cG9zKzEsIG15cG9zKzQpID09ICJHTlUiKSB7DQoJCQkJdGhpcy5oYXNoQWxnb3JpdGhtID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpOw0KCQkJCW15cG9zICs9IDM7IC8vIEdOVQ0KCQkJCXZhciBnbnVFeHRUeXBlID0gMTAwMCArIGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTsNCgkJCQlpZihnbnVFeHRUeXBlID09IDEwMDEpIHsNCgkJCQkJdGhpcy50eXBlID0gZ251RXh0VHlwZTsNCgkJCQkJdGhpcy5zMmtMZW5ndGggPSA1Ow0KCQkJCQkvLyBHbnVQRyBleHRlbnNpb24gbW9kZSAxMDAxIC0tIGRvbid0IHdyaXRlIHNlY3JldCBrZXkgYXQgYWxsDQoJCQkJfSBlbHNlIHsNCgkJCQkJdXRpbC5wcmludF9lcnJvcigidW5rbm93biBzMmsgZ251IHByb3RlY3Rpb24gbW9kZSEgIit0aGlzLnR5cGUpOw0KCQkJCX0NCgkJCX0gZWxzZSB7DQoJCQkJdXRpbC5wcmludF9lcnJvcigidW5rbm93biBzMmsgdHlwZSEgIit0aGlzLnR5cGUpOw0KCQkJfQ0KCQkJYnJlYWs7DQoNCgkJY2FzZSAyOiAvLyBSZXNlcnZlZCB2YWx1ZQ0KCQlkZWZhdWx0Og0KCQkJdXRpbC5wcmludF9lcnJvcigidW5rbm93biBzMmsgdHlwZSEgIit0aGlzLnR5cGUpOw0KCQkJYnJlYWs7DQoJCX0NCgkJcmV0dXJuIHRoaXM7DQoJfQ0KCQ0KCQ0KCS8qKg0KCSAqIHdyaXRlcyBhbiBzMmsgaGFzaCBiYXNlZCBvbiB0aGUgaW5wdXRzLg0KCSAqIEByZXR1cm4ge1N0cmluZ30gUHJvZHVjZWQga2V5IG9mIGhhc2hBbGdvcml0aG0gaGFzaCBsZW5ndGgNCgkgKi8NCglmdW5jdGlvbiB3cml0ZSh0eXBlLCBoYXNoLCBwYXNzcGhyYXNlLCBzYWx0LCBjKXsNCgkgICAgdGhpcy50eXBlID0gdHlwZTsNCgkgICAgaWYodGhpcy50eXBlID09IDMpe3RoaXMuc2FsdFZhbHVlID0gc2FsdDsNCgkgICAgICAgIHRoaXMuaGFzaEFsZ29yaXRobSA9IGhhc2g7DQoJICAgICAgICB0aGlzLmNvdW50ID0gKDE2ICsgKGMgJiAxNSkpIDw8ICgoYyA+PiA0KSArIDYpOw0KCSAgICAgICAgdGhpcy5zMmtMZW5ndGggPSAxMDsNCgkgICAgfQ0KCSAgICByZXR1cm4gdGhpcy5wcm9kdWNlX2tleShwYXNzcGhyYXNlKTsNCgl9DQoNCgkvKioNCgkgKiBQcm9kdWNlcyBhIGtleSB1c2luZyB0aGUgc3BlY2lmaWVkIHBhc3NwaHJhc2UgYW5kIHRoZSBkZWZpbmVkIA0KCSAqIGhhc2hBbGdvcml0aG0gDQoJICogQHBhcmFtIHtTdHJpbmd9IHBhc3NwaHJhc2UgUGFzc3BocmFzZSBjb250YWluaW5nIHVzZXIgaW5wdXQNCgkgKiBAcmV0dXJuIHtTdHJpbmd9IFByb2R1Y2VkIGtleSB3aXRoIGEgbGVuZ3RoIGNvcnJlc3BvbmRpbmcgdG8gDQoJICogaGFzaEFsZ29yaXRobSBoYXNoIGxlbmd0aA0KCSAqLw0KCWZ1bmN0aW9uIHByb2R1Y2Vfa2V5KHBhc3NwaHJhc2UsIG51bUJ5dGVzKSB7DQoJCXBhc3NwaHJhc2UgPSB1dGlsLmVuY29kZV91dGY4KHBhc3NwaHJhc2UpOw0KCQlpZiAodGhpcy50eXBlID09IDApIHsNCgkJCXJldHVybiBvcGVucGdwX2NyeXB0b19oYXNoRGF0YSh0aGlzLmhhc2hBbGdvcml0aG0scGFzc3BocmFzZSk7DQoJCX0gZWxzZSBpZiAodGhpcy50eXBlID09IDEpIHsNCgkJCXJldHVybiBvcGVucGdwX2NyeXB0b19oYXNoRGF0YSh0aGlzLmhhc2hBbGdvcml0aG0sdGhpcy5zYWx0VmFsdWUrcGFzc3BocmFzZSk7DQoJCX0gZWxzZSBpZiAodGhpcy50eXBlID09IDMpIHsNCgkJCXZhciBpc3AgPSBbXTsNCgkJCWlzcFswXSA9IHRoaXMuc2FsdFZhbHVlK3Bhc3NwaHJhc2U7DQoJCQl3aGlsZSAoaXNwLmxlbmd0aCoodGhpcy5zYWx0VmFsdWUrcGFzc3BocmFzZSkubGVuZ3RoIDwgdGhpcy5jb3VudCkNCgkJCQlpc3AucHVzaCh0aGlzLnNhbHRWYWx1ZStwYXNzcGhyYXNlKTsNCgkJCWlzcCA9IGlzcC5qb2luKCcnKTsJCQkNCgkJCWlmIChpc3AubGVuZ3RoID4gdGhpcy5jb3VudCkNCgkJCQlpc3AgPSBpc3Auc3Vic3RyKDAsIHRoaXMuY291bnQpOw0KCQkJaWYobnVtQnl0ZXMgJiYgKG51bUJ5dGVzID09IDI0IHx8IG51bUJ5dGVzID09IDMyKSl7IC8vVGhpcyBpZiBhY2NvdW50cyBmb3IgUkZDIDQ4ODAgMy43LjEuMSAtLSBJZiBoYXNoIHNpemUgaXMgZ3JlYXRlciB0aGFuIGJsb2NrIHNpemUsIHVzZSBsZWZ0bW9zdCBiaXRzLiAgSWYgYmxvY2tzaXplIGxhcmdlciB0aGFuIGhhc2ggc2l6ZSwgd2UgbmVlZCB0byByZWhhc2ggaXNwIGFuZCBwcmVwZW5kIHdpdGggMC4NCgkJCSAgICB2YXIga2V5ID0gb3BlbnBncF9jcnlwdG9faGFzaERhdGEodGhpcy5oYXNoQWxnb3JpdGhtLGlzcCk7DQoJCQkgICAgcmV0dXJuIGtleSArIG9wZW5wZ3BfY3J5cHRvX2hhc2hEYXRhKHRoaXMuaGFzaEFsZ29yaXRobSxTdHJpbmcuZnJvbUNoYXJDb2RlKDApK2lzcCk7DQoJCQl9DQoJCQlyZXR1cm4gb3BlbnBncF9jcnlwdG9faGFzaERhdGEodGhpcy5oYXNoQWxnb3JpdGhtLGlzcCk7DQoJCX0gZWxzZSByZXR1cm4gbnVsbDsNCgl9DQoJDQoJdGhpcy5yZWFkID0gcmVhZDsNCgl0aGlzLndyaXRlID0gd3JpdGU7DQoJdGhpcy5wcm9kdWNlX2tleSA9IHByb2R1Y2Vfa2V5Ow0KfQ0KLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0DQovLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3INCi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMNCi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcg0KLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uDQovLyANCi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLA0KLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YNCi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VDQovLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLg0KLy8gDQovLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljDQovLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlDQovLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0ENCg0KdmFyIFV0aWwgPSBmdW5jdGlvbigpIHsNCg0KICAgIHRoaXMuZW1haWxSZWdFeCA9IC9bYS16MC05ISMkJSYnKisvPT9eX2B7fH1+LV0rKD86XC5bYS16MC05ISMkJSYnKisvPT9eX2B7fH1+LV0rKSpAKD86W2EtejAtOV0oPzpbYS16MC05LV0qW2EtejAtOV0pP1wuKStbYS16MC05XSg/OlthLXowLTktXSpbYS16MC05XSk/LzsNCgkNCgl0aGlzLmhleGR1bXAgPSBmdW5jdGlvbihzdHIpIHsNCgkgICAgdmFyIHI9W107DQoJICAgIHZhciBlPXN0ci5sZW5ndGg7DQoJICAgIHZhciBjPTA7DQoJICAgIHZhciBoOw0KCSAgICB2YXIgaSA9IDA7DQoJICAgIHdoaWxlKGM8ZSl7DQoJICAgICAgICBoPXN0ci5jaGFyQ29kZUF0KGMrKykudG9TdHJpbmcoMTYpOw0KCSAgICAgICAgd2hpbGUoaC5sZW5ndGg8MikgaD0iMCIraDsNCgkgICAgICAgIHIucHVzaCgiICIraCk7DQoJICAgICAgICBpKys7DQoJICAgICAgICBpZiAoaSAlIDMyID09IDApDQoJICAgICAgICAJci5wdXNoKCJcbiAgICAgICAgICAgIik7DQoJICAgIH0NCgkgICAgcmV0dXJuIHIuam9pbignJyk7DQoJfTsNCgkNCgkvKioNCgkgKiBDcmVhdGUgaGV4c3RyaW5nIGZyb20gYSBiaW5hcnkNCgkgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBjb252ZXJ0DQoJICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmcgY29udGFpbmluZyB0aGUgaGV4YWRlY2ltYWwgdmFsdWVzDQoJICovDQoJdGhpcy5oZXhzdHJkdW1wID0gZnVuY3Rpb24oc3RyKSB7DQoJCWlmIChzdHIgPT0gbnVsbCkNCgkJCXJldHVybiAiIjsNCgkgICAgdmFyIHI9W107DQoJICAgIHZhciBlPXN0ci5sZW5ndGg7DQoJICAgIHZhciBjPTA7DQoJICAgIHZhciBoOw0KCSAgICB3aGlsZShjPGUpew0KCSAgICAgICAgaD1zdHJbYysrXS5jaGFyQ29kZUF0KCkudG9TdHJpbmcoMTYpOw0KCSAgICAgICAgd2hpbGUoaC5sZW5ndGg8MikgaD0iMCIraDsNCgkgICAgICAgIHIucHVzaCgiIitoKTsNCgkgICAgfQ0KCSAgICByZXR1cm4gci5qb2luKCcnKTsNCgl9Ow0KCQ0KCS8qKg0KCSAqIENyZWF0ZSBiaW5hcnkgc3RyaW5nIGZyb20gYSBoZXggZW5jb2RlZCBzdHJpbmcNCgkgKiBAcGFyYW0ge1N0cmluZ30gc3RyIEhleCBzdHJpbmcgdG8gY29udmVydA0KCSAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIGNvbnRhaW5pbmcgdGhlIGJpbmFyeSB2YWx1ZXMNCgkgKi8NCgl0aGlzLmhleDJiaW4gPSBmdW5jdGlvbihoZXgpIHsNCgkgICAgdmFyIHN0ciA9ICcnOw0KCSAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhleC5sZW5ndGg7IGkgKz0gMikNCgkgICAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KGhleC5zdWJzdHIoaSwgMiksIDE2KSk7DQoJICAgIHJldHVybiBzdHI7DQoJfTsNCgkNCgkvKioNCgkgKiBDcmVhdGluZyBhIGhleCBzdHJpbmcgZnJvbSBhbiBiaW5hcnkgYXJyYXkgb2YgaW50ZWdlcnMgKDAuLjI1NSkNCgkgKiBAcGFyYW0ge1N0cmluZ30gc3RyIEFycmF5IG9mIGJ5dGVzIHRvIGNvbnZlcnQNCgkgKiBAcmV0dXJuIHtTdHJpbmd9IEhleGFkZWNpbWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhcnJheQ0KCSAqLw0KCXRoaXMuaGV4aWR1bXAgPSBmdW5jdGlvbihzdHIpIHsNCgkgICAgdmFyIHI9W107DQoJICAgIHZhciBlPXN0ci5sZW5ndGg7DQoJICAgIHZhciBjPTA7DQoJICAgIHZhciBoOw0KCSAgICB3aGlsZShjPGUpew0KCSAgICAgICAgaD1zdHJbYysrXS50b1N0cmluZygxNik7DQoJICAgICAgICB3aGlsZShoLmxlbmd0aDwyKSBoPSIwIitoOw0KCSAgICAgICAgci5wdXNoKCIiK2gpOw0KCSAgICB9DQoJICAgIHJldHVybiByLmpvaW4oJycpOw0KCX07DQoNCg0KCS8qKg0KCSAqIENvbnZlcnQgYSBuYXRpdmUgamF2YXNjcmlwdCBzdHJpbmcgdG8gYSBzdHJpbmcgb2YgdXRmOCBieXRlcw0KCSAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgVGhlIHN0cmluZyB0byBjb252ZXJ0DQoJICogQHJldHVybiB7U3RyaW5nfSBBIHZhbGlkIHNxdWVuY2Ugb2YgdXRmOCBieXRlcw0KCSAqLw0KCXRoaXMuZW5jb2RlX3V0ZjggPSBmdW5jdGlvbihzdHIpIHsNCgkJcmV0dXJuIHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChzdHIpKTsNCgl9Ow0KDQoJLyoqDQoJICogQ29udmVydCBhIHN0cmluZyBvZiB1dGY4IGJ5dGVzIHRvIGEgbmF0aXZlIGphdmFzY3JpcHQgc3RyaW5nDQoJICogQHBhcmFtIHtTdHJpbmd9IHV0ZjggQSB2YWxpZCBzcXVlbmNlIG9mIHV0ZjggYnl0ZXMNCgkgKiBAcmV0dXJuIHtTdHJpbmd9IEEgbmF0aXZlIGphdmFzY3JpcHQgc3RyaW5nDQoJICovDQoJdGhpcy5kZWNvZGVfdXRmOCA9IGZ1bmN0aW9uKHV0ZjgpIHsNCgkJcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChlc2NhcGUodXRmOCkpOw0KCX07DQoNCgl2YXIgc3RyMmJpbiA9IGZ1bmN0aW9uKHN0ciwgcmVzdWx0KSB7DQoJCWZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7DQoJCQlyZXN1bHRbaV0gPSBzdHIuY2hhckNvZGVBdChpKTsNCgkJfQ0KDQoJCXJldHVybiByZXN1bHQ7DQoJfTsNCgkNCgl2YXIgYmluMnN0ciA9IGZ1bmN0aW9uKGJpbikgew0KCQl2YXIgcmVzdWx0ID0gW107DQoNCgkJZm9yICh2YXIgaSA9IDA7IGkgPCBiaW4ubGVuZ3RoOyBpKyspIHsNCgkJCXJlc3VsdC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYmluW2ldKSk7DQoJCX0NCg0KCQlyZXR1cm4gcmVzdWx0LmpvaW4oJycpOw0KCX07DQoNCgkvKioNCgkgKiBDb252ZXJ0IGEgc3RyaW5nIHRvIGFuIGFycmF5IG9mIGludGVnZXJzKDAuMjU1KQ0KCSAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNvbnZlcnQNCgkgKiBAcmV0dXJuIHtJbnRlZ2VyW119IEFuIGFycmF5IG9mIChiaW5hcnkpIGludGVnZXJzDQoJICovDQoJdGhpcy5zdHIyYmluID0gZnVuY3Rpb24oc3RyKSB7IA0KCQlyZXR1cm4gc3RyMmJpbihzdHIsIG5ldyBBcnJheShzdHIubGVuZ3RoKSk7DQoJfTsNCgkNCgkNCgkvKioNCgkgKiBDb252ZXJ0IGFuIGFycmF5IG9mIGludGVnZXJzKDAuMjU1KSB0byBhIHN0cmluZyANCgkgKiBAcGFyYW0ge0ludGVnZXJbXX0gYmluIEFuIGFycmF5IG9mIChiaW5hcnkpIGludGVnZXJzIHRvIGNvbnZlcnQNCgkgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGFycmF5DQoJICovDQoJdGhpcy5iaW4yc3RyID0gYmluMnN0cjsNCgkNCgkvKioNCgkgKiBDb252ZXJ0IGEgc3RyaW5nIHRvIGEgVWludDhBcnJheQ0KCSAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNvbnZlcnQNCgkgKiBAcmV0dXJuIHtVaW50OEFycmF5fSBUaGUgYXJyYXkgb2YgKGJpbmFyeSkgaW50ZWdlcnMNCgkgKi8NCgl0aGlzLnN0cjJVaW50OEFycmF5ID0gZnVuY3Rpb24oc3RyKSB7IA0KCQlyZXR1cm4gc3RyMmJpbihzdHIsIG5ldyBVaW50OEFycmF5KG5ldyBBcnJheUJ1ZmZlcihzdHIubGVuZ3RoKSkpOyANCgl9Ow0KCQ0KCS8qKg0KCSAqIENvbnZlcnQgYSBVaW50OEFycmF5IHRvIGEgc3RyaW5nLiBUaGlzIGN1cnJlbnRseSBmdW5jdGlvbnMgDQoJICogdGhlIHNhbWUgYXMgYmluMnN0ci4gDQoJICogQHBhcmFtIHtVaW50OEFycmF5fSBiaW4gQW4gYXJyYXkgb2YgKGJpbmFyeSkgaW50ZWdlcnMgdG8gY29udmVydA0KCSAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhcnJheQ0KCSAqLw0KCXRoaXMuVWludDhBcnJheTJzdHIgPSBiaW4yc3RyOw0KCQ0KCS8qKg0KCSAqIENhbGN1bGF0ZXMgYSAxNmJpdCBzdW0gb2YgYSBzdHJpbmcgYnkgYWRkaW5nIGVhY2ggY2hhcmFjdGVyIA0KCSAqIGNvZGVzIG1vZHVsdXMgNjU1MzUNCgkgKiBAcGFyYW0ge1N0cmluZ30gdGV4dCBTdHJpbmcgdG8gY3JlYXRlIGEgc3VtIG9mDQoJICogQHJldHVybiB7SW50ZWdlcn0gQW4gaW50ZWdlciBjb250YWluaW5nIHRoZSBzdW0gb2YgYWxsIGNoYXJhY3RlciANCgkgKiBjb2RlcyAlIDY1NTM1DQoJICovDQoJdGhpcy5jYWxjX2NoZWNrc3VtID0gZnVuY3Rpb24odGV4dCkgew0KCQl2YXIgY2hlY2tzdW0gPSB7ICBzOiAwLCBhZGQ6IGZ1bmN0aW9uIChzYWRkKSB7IHRoaXMucyA9ICh0aGlzLnMgKyBzYWRkKSAlIDY1NTM2OyB9fTsNCgkJZm9yICh2YXIgaSA9IDA7IGkgPCB0ZXh0Lmxlbmd0aDsgaSsrKSB7DQoJCQljaGVja3N1bS5hZGQodGV4dC5jaGFyQ29kZUF0KGkpKTsNCgkJfQ0KCQlyZXR1cm4gY2hlY2tzdW0uczsNCgl9Ow0KCQ0KCS8qKg0KCSAqIEhlbHBlciBmdW5jdGlvbiB0byBwcmludCBhIGRlYnVnIG1lc3NhZ2UuIERlYnVnIA0KCSAqIG1lc3NhZ2VzIGFyZSBvbmx5IHByaW50ZWQgaWYNCgkgKiBvcGVucGdwLmNvbmZpZy5kZWJ1ZyBpcyBzZXQgdG8gdHJ1ZS4gVGhlIGNhbGxpbmcNCgkgKiBKYXZhc2NyaXB0IGNvbnRleHQgTVVTVCBkZWZpbmUNCgkgKiBhICJzaG93TWVzc2FnZXModGV4dCkiIGZ1bmN0aW9uLiBMaW5lIGZlZWRzICgnXG4nKQ0KCSAqIGFyZSBhdXRvbWF0aWNhbGx5IGNvbnZlcnRlZCB0byBIVE1MIGxpbmUgZmVlZHMgJzxici8+Jw0KCSAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIG9mIHRoZSBkZWJ1ZyBtZXNzYWdlDQoJICogQHJldHVybiB7U3RyaW5nfSBBbiBIVE1MIHR0IGVudGl0eSBjb250YWluaW5nIGEgcGFyYWdyYXBoIHdpdGggYSANCgkgKiBzdHlsZSBhdHRyaWJ1dGUgd2hlcmUgdGhlIGRlYnVnIG1lc3NhZ2UgaXMgSFRNTGVuY29kZWQgaW4uIA0KCSAqLw0KCXRoaXMucHJpbnRfZGVidWcgPSBmdW5jdGlvbihzdHIpIHsNCgkJaWYgKG9wZW5wZ3AuY29uZmlnLmRlYnVnKSB7DQoJCQlzdHIgPSBvcGVucGdwX2VuY29kaW5nX2h0bWxfZW5jb2RlKHN0cik7DQoJCQlzaG93TWVzc2FnZXMoIjx0dD48cCBzdHlsZT1cImJhY2tncm91bmQtY29sb3I6ICNmZmZmZmY7IHdpZHRoOiA2NTJweDsgd29yZC1icmVhazogYnJlYWstd29yZDsgcGFkZGluZzogNXB4OyBib3JkZXItYm90dG9tOiAxcHggc29saWQgYmxhY2s7XCI+IitzdHIucmVwbGFjZSgvXG4vZywiPGJyPiIpKyI8L3A+PC90dD4iKTsNCgkJfQ0KCX07DQoJDQoJLyoqDQoJICogSGVscGVyIGZ1bmN0aW9uIHRvIHByaW50IGEgZGVidWcgbWVzc2FnZS4gRGVidWcgDQoJICogbWVzc2FnZXMgYXJlIG9ubHkgcHJpbnRlZCBpZg0KCSAqIG9wZW5wZ3AuY29uZmlnLmRlYnVnIGlzIHNldCB0byB0cnVlLiBUaGUgY2FsbGluZw0KCSAqIEphdmFzY3JpcHQgY29udGV4dCBNVVNUIGRlZmluZQ0KCSAqIGEgInNob3dNZXNzYWdlcyh0ZXh0KSIgZnVuY3Rpb24uIExpbmUgZmVlZHMgKCdcbicpDQoJICogYXJlIGF1dG9tYXRpY2FsbHkgY29udmVydGVkIHRvIEhUTUwgbGluZSBmZWVkcyAnPGJyLz4nDQoJICogRGlmZmVyZW50IHRoYW4gcHJpbnRfZGVidWcgYmVjYXVzZSB3aWxsIGNhbGwgaGV4c3RyZHVtcCBpZmYgbmVjZXNzYXJ5Lg0KCSAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIG9mIHRoZSBkZWJ1ZyBtZXNzYWdlDQoJICogQHJldHVybiB7U3RyaW5nfSBBbiBIVE1MIHR0IGVudGl0eSBjb250YWluaW5nIGEgcGFyYWdyYXBoIHdpdGggYSANCgkgKiBzdHlsZSBhdHRyaWJ1dGUgd2hlcmUgdGhlIGRlYnVnIG1lc3NhZ2UgaXMgSFRNTGVuY29kZWQgaW4uIA0KCSAqLw0KCXRoaXMucHJpbnRfZGVidWdfaGV4c3RyX2R1bXAgPSBmdW5jdGlvbihzdHIsc3RyVG9IZXgpIHsNCgkJaWYgKG9wZW5wZ3AuY29uZmlnLmRlYnVnKSB7DQoJCQlzdHIgPSBzdHIgKyB0aGlzLmhleHN0cmR1bXAoc3RyVG9IZXgpOw0KCQkJc3RyID0gb3BlbnBncF9lbmNvZGluZ19odG1sX2VuY29kZShzdHIpOw0KCQkJc2hvd01lc3NhZ2VzKCI8dHQ+PHAgc3R5bGU9XCJiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmZmZmOyB3aWR0aDogNjUycHg7IHdvcmQtYnJlYWs6IGJyZWFrLXdvcmQ7IHBhZGRpbmc6IDVweDsgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIGJsYWNrO1wiPiIrc3RyLnJlcGxhY2UoL1xuL2csIjxicj4iKSsiPC9wPjwvdHQ+Iik7DQoJCX0NCgl9Ow0KCQ0KCS8qKg0KCSAqIEhlbHBlciBmdW5jdGlvbiB0byBwcmludCBhbiBlcnJvciBtZXNzYWdlLiANCgkgKiBUaGUgY2FsbGluZyBKYXZhc2NyaXB0IGNvbnRleHQgTVVTVCBkZWZpbmUNCgkgKiBhICJzaG93TWVzc2FnZXModGV4dCkiIGZ1bmN0aW9uLiBMaW5lIGZlZWRzICgnXG4nKQ0KCSAqIGFyZSBhdXRvbWF0aWNhbGx5IGNvbnZlcnRlZCB0byBIVE1MIGxpbmUgZmVlZHMgJzxici8+Jw0KCSAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIG9mIHRoZSBlcnJvciBtZXNzYWdlDQoJICogQHJldHVybiB7U3RyaW5nfSBBIEhUTUwgcGFyYWdyYXBoIGVudGl0eSB3aXRoIGEgc3R5bGUgYXR0cmlidXRlIA0KCSAqIGNvbnRhaW5pbmcgdGhlIEhUTUwgZW5jb2RlZCBlcnJvciBtZXNzYWdlDQoJICovDQoJdGhpcy5wcmludF9lcnJvciA9IGZ1bmN0aW9uKHN0cikgew0KCQlzdHIgPSBvcGVucGdwX2VuY29kaW5nX2h0bWxfZW5jb2RlKHN0cik7DQoJCXNob3dNZXNzYWdlcygiPHAgc3R5bGU9XCJmb250LXNpemU6IDgwJTsgYmFja2dyb3VuZC1jb2xvcjogI0ZGODg4ODsgbWFyZ2luOjA7IHdpZHRoOiA2NTJweDsgd29yZC1icmVhazogYnJlYWstd29yZDsgcGFkZGluZzogNXB4OyBib3JkZXItYm90dG9tOiAxcHggc29saWQgYmxhY2s7XCI+PHNwYW4gc3R5bGU9XCJjb2xvcjogIzg4ODtcIj48Yj5FUlJPUjo8L2I+PC9zcGFuPgkiK3N0ci5yZXBsYWNlKC9cbi9nLCI8YnI+IikrIjwvcD4iKTsNCgl9Ow0KCQ0KCS8qKg0KCSAqIEhlbHBlciBmdW5jdGlvbiB0byBwcmludCBhbiBpbmZvIG1lc3NhZ2UuIA0KCSAqIFRoZSBjYWxsaW5nIEphdmFzY3JpcHQgY29udGV4dCBNVVNUIGRlZmluZQ0KCSAqIGEgInNob3dNZXNzYWdlcyh0ZXh0KSIgZnVuY3Rpb24uIExpbmUgZmVlZHMgKCdcbicpDQoJICogYXJlIGF1dG9tYXRpY2FsbHkgY29udmVydGVkIHRvIEhUTUwgbGluZSBmZWVkcyAnPGJyLz4nLg0KCSAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIG9mIHRoZSBpbmZvIG1lc3NhZ2UNCgkgKiBAcmV0dXJuIHtTdHJpbmd9IEEgSFRNTCBwYXJhZ3JhcGggZW50aXR5IHdpdGggYSBzdHlsZSBhdHRyaWJ1dGUgDQoJICogY29udGFpbmluZyB0aGUgSFRNTCBlbmNvZGVkIGluZm8gbWVzc2FnZQ0KCSAqLw0KCXRoaXMucHJpbnRfaW5mbyA9IGZ1bmN0aW9uKHN0cikgew0KCQlzdHIgPSBvcGVucGdwX2VuY29kaW5nX2h0bWxfZW5jb2RlKHN0cik7DQoJCXNob3dNZXNzYWdlcygiPHAgc3R5bGU9XCJmb250LXNpemU6IDgwJTsgYmFja2dyb3VuZC1jb2xvcjogIzg4RkY4ODsgbWFyZ2luOjA7IHdpZHRoOiA2NTJweDsgd29yZC1icmVhazogYnJlYWstd29yZDsgcGFkZGluZzogNXB4OyBib3JkZXItYm90dG9tOiAxcHggc29saWQgYmxhY2s7XCI+PHNwYW4gc3R5bGU9XCJjb2xvcjogIzg4ODtcIj48Yj5JTkZPOjwvYj48L3NwYW4+CSIrc3RyLnJlcGxhY2UoL1xuL2csIjxicj4iKSsiPC9wPiIpOw0KCX07DQoJDQoJdGhpcy5wcmludF93YXJuaW5nID0gZnVuY3Rpb24oc3RyKSB7DQoJCXN0ciA9IG9wZW5wZ3BfZW5jb2RpbmdfaHRtbF9lbmNvZGUoc3RyKTsNCgkJc2hvd01lc3NhZ2VzKCI8cCBzdHlsZT1cImZvbnQtc2l6ZTogODAlOyBiYWNrZ3JvdW5kLWNvbG9yOiAjRkZBQTg4OyBtYXJnaW46MDsgd2lkdGg6IDY1MnB4OyB3b3JkLWJyZWFrOiBicmVhay13b3JkOyBwYWRkaW5nOiA1cHg7IGJvcmRlci1ib3R0b206IDFweCBzb2xpZCBibGFjaztcIj48c3BhbiBzdHlsZT1cImNvbG9yOiAjODg4O1wiPjxiPldBUk5JTkc6PC9iPjwvc3Bhbj4JIitzdHIucmVwbGFjZSgvXG4vZywiPGJyPiIpKyI8L3A+Iik7DQoJfTsNCgkNCgl0aGlzLmdldExlZnROQml0cyA9IGZ1bmN0aW9uIChzdHJpbmcsIGJpdGNvdW50KSB7DQoJCXZhciByZXN0ID0gYml0Y291bnQgJSA4Ow0KCQlpZiAocmVzdCA9PSAwKQ0KCQkJcmV0dXJuIHN0cmluZy5zdWJzdHJpbmcoMCwgYml0Y291bnQgLyA4KTsNCgkJdmFyIGJ5dGVzID0gKGJpdGNvdW50IC0gcmVzdCkgLyA4ICsxOw0KCQl2YXIgcmVzdWx0ID0gc3RyaW5nLnN1YnN0cmluZygwLCBieXRlcyk7DQoJCXJldHVybiB0aGlzLnNoaWZ0UmlnaHQocmVzdWx0LCA4LXJlc3QpOyAvLyArU3RyaW5nLmZyb21DaGFyQ29kZShzdHJpbmcuY2hhckNvZGVBdChieXRlcyAtMSkgPDwgKDgtcmVzdCkgJiAweEZGKTsNCgl9Ow0KDQoJLyoqDQoJICogU2hpZnRpbmcgYSBzdHJpbmcgdG8gbiBiaXRzIHJpZ2h0DQoJICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlIFRoZSBzdHJpbmcgdG8gc2hpZnQNCgkgKiBAcGFyYW0ge0ludGVnZXJ9IGJpdGNvdW50IEFtb3VudCBvZiBiaXRzIHRvIHNoaWZ0IChNVVNUIGJlIHNtYWxsZXIgDQoJICogdGhhbiA5KQ0KCSAqIEByZXR1cm4ge1N0cmluZ30gUmVzdWx0aW5nIHN0cmluZy4gDQoJICovDQoJdGhpcy5zaGlmdFJpZ2h0ID0gZnVuY3Rpb24odmFsdWUsIGJpdGNvdW50KSB7DQoJCXZhciB0ZW1wID0gdXRpbC5zdHIyYmluKHZhbHVlKTsNCiAgICAgICAgaWYgKGJpdGNvdW50ICUgOCAhPSAwKSB7DQogICAgICAgIAlmb3IgKHZhciBpID0gdGVtcC5sZW5ndGgtMTsgaSA+PSAwOyBpLS0pIHsNCiAgICAgICAgCQl0ZW1wW2ldID4+PSBiaXRjb3VudCAlIDg7DQogICAgICAgIAkJaWYgKGkgPiAwKQ0KICAgICAgICAJCQl0ZW1wW2ldIHw9ICh0ZW1wW2kgLSAxXSA8PCAoOCAtIChiaXRjb3VudCAlIDgpKSkgJiAweEZGOw0KICAgICAgICAJfQ0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAJcmV0dXJuIHZhbHVlOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiB1dGlsLmJpbjJzdHIodGVtcCk7DQoJfTsNCgkNCgkvKioNCgkgKiBSZXR1cm4gdGhlIGFsZ29yaXRobSB0eXBlIGFzIHN0cmluZw0KCSAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIHJlcHJlc2VudGluZyB0aGUgbWVzc2FnZSB0eXBlDQoJICovDQoJdGhpcy5nZXRfaGFzaEFsZ29yaXRobVN0cmluZyA9IGZ1bmN0aW9uKGFsZ28pIHsNCgkJc3dpdGNoKGFsZ28pIHsNCgkJY2FzZSAxOg0KCQkJcmV0dXJuICJNRDUiOw0KCQljYXNlIDI6DQoJCQlyZXR1cm4gIlNIQTEiOw0KCQljYXNlIDM6DQoJCQlyZXR1cm4gIlJJUEVNRDE2MCI7DQoJCWNhc2UgODoNCgkJCXJldHVybiAiU0hBMjU2IjsNCgkJY2FzZSA5Og0KCQkJcmV0dXJuICJTSEEzODQiOw0KCQljYXNlIDEwOg0KCQkJcmV0dXJuICJTSEE1MTIiOw0KCQljYXNlIDExOg0KCQkJcmV0dXJuICJTSEEyMjQiOw0KCQl9DQoJCXJldHVybiAidW5rbm93biI7DQoJfTsNCn07DQoNCi8qKg0KICogYW4gaW5zdGFuY2UgdGhhdCBzaG91bGQgYmUgdXNlZC4gDQogKi8NCiBmdW5jdGlvbiBzaG93TWVzc2FnZXMoYykgeyBsaWJha2FzYWthY29yZS5zeXNsb2cobGliYWthc2FrYWNvcmUuc3RyaXAoYykpOyB9DQp2YXIgdXRpbCA9IG5ldyBVdGlsKCk7DQoNCnRyeSB7DQoJbGliYWthc2FrYWNvcmUuc2VuZEV2dCgncGdwX2Fycml2ZWQnKTsNCn0gY2F0Y2goZSl7fQ0KDQoNCnZhciB2UEdQID0gbmV3IE9iamVjdDsNCg0KdlBHUC5uYW1lID0gJ3ZQR1AgMic7DQp2UEdQLmRlc2NyaXB0aW9uID0gIlBhcmFub2lkIG1vZGUgZm9yIFZLIDopIjsNCnZQR1AuYXV0aG9yID0gIkFrYXNha2EgUnl1dW5vc3VrZSI7DQp2UEdQLmhvbWVwYWdlID0gImh0dHA6Ly92ay5jb20vYWthc2FrYSI7DQp2UEdQLmljb24gPSAnaHR0cHM6Ly9jZG4xLmljb25maW5kZXIuY29tL2RhdGEvaWNvbnMvRnV0dXJvc29mdCUyMEljb25zJTIwMC41LjIvMTI4eDEyOC9taW1ldHlwZXMvZW5jcnlwdGVkLnBuZyc7DQoNCg0KdlBHUC5yZWdpc3RlciA9IGZ1bmN0aW9uKCkgew0KdHJ5IHsNCiAgY29uc29sZS5sb2cobGliYWthc2FrYWNvcmUpOw0KCWxpYmFrYXNha2Fjb3JlLnJlZ2lzdGVyKHZQR1ApOyANCn0NCiBjYXRjaChFKSB7DQogICBjb25zb2xlLmxvZygiVlBHUCBpcyB3YWl0aW5nIGZvciByZWdpc3RyYXRpb24gY2FsbCIpOw0KCWRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoImxpYmFrYXNha2Fjb3JlX3BsdWdpbl9zZWFyY2giLHZQR1AucmVnaXN0ZXIsZmFsc2UpOw0KfQ0KfQ0KdlBHUC5zdGFydCA9IGZ1bmN0aW9uKGlzRmlyc3RSdW4pIHsNCiAgY29uc29sZS5sb2coIlZQR1AgaXMgd2FpdGluZyBmb3IgZW5naW5lIHRvIGFycml2ZSIpOw0KaWYodHlwZW9mIG9wZW5wZ3AgPT0gJ3VuZGVmaW5lZCcpIA0KICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJwZ3BfYXJyaXZlZCIsdlBHUC5lbmdpbmVBcnJpdmFsLGZhbHNlKTsNCiBlbHNlIHZQR1AuZW5naW5lQXJyaXZhbCgpOw0KZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigibGliYWthc2FrYWNvcmVfcGx1Z2luX3NlYXJjaCIsdlBHUC5yZWdpc3Rlcik7DQp9DQoNCnZQR1Auc2F2ZVNldHRpbmcgPSBmdW5jdGlvbihzZXR0aW5nLCB2YWx1ZSkgew0KCXZQR1Auc2V0dGluZ3Nbc2V0dGluZ10gPSB2YWx1ZTsNCgl3aW5kb3cubG9jYWxTdG9yYWdlLnNldE9iamVjdCgndnBncF9zZXR0aW5ncycsIHZQR1Auc2V0dGluZ3MpOw0KfQ0KdlBHUC5ib3VuZGFyeSA9ICdfX1ZQR1BfXyc7DQoNCnZQR1Aua2V5U3RvcmUgPSB7DQoJc3RvcmU6IG5ldyBPYmplY3QoKSwNCgkNCglfbG9hZElmTm90OiBmdW5jdGlvbigpIHsNCgkJdGhpcy5zdG9yZSA9IHZQR1Auc2V0dGluZ3Mua2V5U3RvcmUgfHwgdGhpcy5zdG9yZTsNCgl9LA0KCV9zYXZlOiBmdW5jdGlvbigpIHsNCgkJdlBHUC5zYXZlU2V0dGluZygna2V5U3RvcmUnLCB0aGlzLnN0b3JlKTsNCgl9LA0KCXB1YmxpY0tleTogZnVuY3Rpb24odWlkKSB7DQoJCXRoaXMuX2xvYWRJZk5vdCgpOw0KCQlpZighdGhpcy5wdWJsaWNLZXlFeGlzdHModWlkKSAmJiB1aWQgIT0gdmsuaWQpIHJldHVybiB1bmRlZmluZWQ7DQoJCXJldHVybiAodWlkICE9IHZrLmlkID8gdGhpcy5zdG9yZVt1aWRdLnJlcGxhY2UoLzxiclxzKltcL10/Pi9naSwgJ1xuJykgOiB2UEdQLnNldHRpbmdzLnB1YmxpY2tleSk7DQoJfSwNCglwdWJsaWNLZXlFeGlzdHM6ZnVuY3Rpb24odWlkKSB7DQoJCXRoaXMuX2xvYWRJZk5vdCgpOw0KCQlpZih1aWQgPT0gdmsuaWQpIHJldHVybiB0cnVlOw0KCQlyZXR1cm4gKHVpZCAhPSB2ay5pZCAmJiAodHlwZW9mIHRoaXMuc3RvcmVbdWlkXSAhPSAndW5kZWZpbmVkJykgKTsNCgl9LA0KCXByaXZhdGVLZXk6IGZ1bmN0aW9uKCkgew0KCQlyZXR1cm4gdlBHUC5zZXR0aW5ncy5wcml2YXRla2V5Ow0KCX0sDQoJcGFzc3dvcmQ6IHVuZGVmaW5lZCwNCglfcHdDYWxsYmFja3M6IG5ldyBBcnJheSgpLA0KCV9pc1B3aW5nOiBmYWxzZSwNCglwYXNzd29yZFByb21wdGluZ0lmTmVlZGVkOiBmdW5jdGlvbihjYWxsYmFjaykgew0KCQlpZih0eXBlb2YgdGhpcy5wYXNzd29yZCA9PSAndW5kZWZpbmVkJykgew0KCQkJdGhpcy5fcHdDYWxsYmFja3NbdGhpcy5fcHdDYWxsYmFja3MubGVuZ3RoXSA9IGNhbGxiYWNrOw0KCQkJaWYodlBHUC5rZXlTdG9yZS5faXNQd2luZykgcmV0dXJuOw0KCQkJdlBHUC5rZXlTdG9yZS5faXNQd2luZyA9IHRydWU7DQoJCQlsaWJha2FzYWthZ3VpLnByb21wdCh2UEdQLm5hbWUsIllvdSBuZWVkIHRvIGVudGVyIHlvdXIgUEdQIHBhc3N3b3JkIG9uY2UgaW4gYSB3aGlsZSB0byB1bmxvY2sgZW5jcnlwdGVkIG1lc3NhZ2VzIGJlY2F1c2UgaXQgaXNuJ3Qgc2F2ZWQgYW55d2hlcmUgZm9yIHNlY3VyaXR5IHJlYXNvbnMuPGJyPjxzdHJvbmc+UGxlYXNlIGVudGVyIHlvdXIgcGFzc3dvcmQgYmVsb3cgdG8gdW5sb2NrIHRoaXMgY29udmVyc2F0aW9uOjwvc3Ryb25nPiIsDQoJCQkgICdFbnRlciBQR1AgcGFzc3dvcmQnLCANCgkJCSAgbGliYWthc2FrYWd1aS5kZWZGb290ZXIsIA0KCQkJICBmdW5jdGlvbihwYXNzd2QpIHsNCgkJCSAgCXZQR1Aua2V5U3RvcmUucGFzc3dvcmQgPSBwYXNzd2Q7DQoJCQkgIAlmb3IgKGkgaW4gdlBHUC5rZXlTdG9yZS5fcHdDYWxsYmFja3MpIHsNCgkJCSAgCQlsaWJha2FzYWthY29yZS5zeXNsb2coJ1B3IGNhbGxiYWNrICcrKGkpKycgb2YgJyt2UEdQLmtleVN0b3JlLl9wd0NhbGxiYWNrcy5sZW5ndGgpOw0KCQkJICAJCXZQR1Aua2V5U3RvcmUuX3B3Q2FsbGJhY2tzW2ldKHBhc3N3ZCk7DQoJCQkgIAl9DQoJCQkgIAl2UEdQLmtleVN0b3JlLl9wd0NhbGxiYWNrcyA9IG5ldyBBcnJheSgpOw0KCQkJICAJdlBHUC5rZXlTdG9yZS5faXNQd2luZyA9IGZhbHNlOw0KCQkJICB9LA0KCQkJICBmYWxzZSk7DQoJCX0JZWxzZSBjYWxsYmFjayh0aGlzLnBhc3N3b3JkKTsNCgl9LA0KCQ0KCW1lbW9yaXplOiBmdW5jdGlvbih1aWQsIGtkYXRhKSB7DQoJCXRoaXMuc3RvcmVbdWlkXSA9IGxpYmFrYXNha2Fjb3JlLnN0cmlwKGtkYXRhKTsNCgkJdGhpcy5fc2F2ZSgpOw0KCX0NCg0KfTsNCnZQR1Auc2VuZFN5cyA9IGZ1bmN0aW9uICh0aXRsZSwgbXNnLCBzZW5kUGVlcikgew0KDQogICAgIHBlZXIgPSBzZW5kUGVlcjsNCiAgICB2YXIgcGVlclRhYiA9IGN1ci50YWJzW3BlZXJdOw0KCQ0KICAgIHZhciBtc2dfaWQgPSAtLXBlZXJUYWIuc2VudCwNCiAgICAgICAgcGFyYW1zID0ge2FjdDogJ2Ffc2VuZCcsIHRvOiBwZWVyLCBoYXNoOiBwZWVyVGFiLmhhc2gsIG1zZzogbXNnLCB0aXRsZTogdGl0bGUsIHRzOiBjdXIudHN9LA0KICAgICAgICBtZWRpYSA9IFtdLCBrbHVkZ2VzID0ge30sIGkgPSAxOw0KICAgIA0KICAgIA0KICAgIGFqYXgucG9zdCgnYWxfaW0ucGhwJywgcGFyYW1zLCB7DQogICAgICBvbkRvbmU6IGZ1bmN0aW9uKHJlc3BvbnNlKSB7DQogICAgICAgIAljb25zb2xlLmxvZygncmVxIHNlbmQgc3lzJyk7DQogICAgICB9LA0KICAgICAgb25GYWlsOiBmdW5jdGlvbihlcnJvcikgew0KICAgICAgCWNvbnNvbGUubG9nKCdwZ3AgZXJyIHN5c2VuZCAnK2Vycm9yKTsNCiAgICAgIAlzaG93RmFzdEJveCgnVktQR1AgRXJyb3InLCAnRXJyb3IgcGVyZm9ybWluZyBkYXRhIGV4Y2hhbmdlOiAnK2Vycm9yKTsNCiAgICAgICB9DQogIH0pOw0KIH0NCg0KdlBHUC5lbmdpbmVBcnJpdmFsID0gZnVuY3Rpb24oKSB7DQogIGNvbnNvbGUubG9nKCJWUEdQIGVuZ2luZSBoYXMgYXJyaXZlZCIpOw0KCXZQR1Auc2V0dGluZ3MgPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldE9iamVjdCgndnBncF9zZXR0aW5ncycpOw0KCSBpZih0eXBlb2YgdlBHUC5zZXR0aW5ncyA9PSAidW5kZWZpbmVkIiB8fHZQR1Auc2V0dGluZ3M9PW51bGwpIHZQR1Auc2V0dGluZ3MgPSAgbmV3IE9iamVjdCgpOw0KCQlpZih0eXBlb2YgdlBHUC5lbmFibGVkID09InVuZGVmaW5lZCIgfHwgdlBHUC5lbmFibGVkPT1udWxsKSB2UEdQLmVuYWJsZWQgPSBuZXcgT2JqZWN0KCk7DQoJaWYoIXZQR1Auc2V0dGluZ3MuZmlyc3RSdW4pIHsNCgkJdmFyIG1lID0gc2hvd0Zhc3RCb3godlBHUC5uYW1lLCAnSXQgc2VlbXMgeW91IGhhdmUgbmV2ZXIgdXNlZCAnK3ZQR1AubmFtZSsnIGJlZm9yZS4gV291bGQgeW91IGxpa2UgdG8gc2V0IHVwICcrdlBHUC5uYW1lKycgbm93PycsICdTZXQgdXAgbm93JywgZnVuY3Rpb24oKXsNCgkJCW1lLmhpZGUoKTsNCgkJCWxpYmFrYXNha2FndWkucHJvbXB0KCdTZXQgdXAgJyt2UEdQLm5hbWUsDQoJCQkgJzwvY2VudGVyPldlbGNvbWUgdG8gdGhlICcrdlBHUC5uYW1lKycgc2V0dXAgd2l6YXJkLjxicj48YnI+XA0KCQkJIDxkaXYgaWQ9Imdyb3VwX2xfbXNnIiBjbGFzcz0ibXNnIiBzdHlsZT0iZGlzcGxheTogYmxvY2s7IGJhY2tncm91bmQtY29sb3I6IHJnYigyNDksIDI0NiwgMjMxKTsgYm9yZGVyLWNvbG9yOiByZ2IoMjEyLCAxODgsIDc2KTsiPlwNCgkJCSA8Yj5XaGF0IGlzIFBHUD88L2I+PGJyPlByZXR0eSBHb29kIFByaXZhY3kgKFBHUCkgaXMgYSBkYXRhIGVuY3J5cHRpb24gYW5kIGRlY3J5cHRpb24gY29tcHV0ZXIgcHJvZ3JhbSB0aGF0IHByb3ZpZGVzIGNyeXB0b2dyYXBoaWMgcHJpdmFjeSBhbmQgYXV0aGVudGljYXRpb24gZm9yIGRhdGEgY29tbXVuaWNhdGlvbi4gUEdQIGlzIG9mdGVuIHVzZWQgZm9yIHNpZ25pbmcsIGVuY3J5cHRpbmcsIGFuZCBkZWNyeXB0aW5nIHRleHRzLCBlLW1haWxzLCBmaWxlcywgZGlyZWN0b3JpZXMsIGFuZCB3aG9sZSBkaXNrIHBhcnRpdGlvbnMgYW5kIHRvIGluY3JlYXNlIHRoZSBzZWN1cml0eSBvZiBlLW1haWwgY29tbXVuaWNhdGlvbnMuIEl0IHdhcyBjcmVhdGVkIGJ5IFBoaWwgWmltbWVybWFubiBpbiAxOTkxIHdoaWxlIHdvcmtpbmcgYXQgUEtXQVJFLCBJbmMuPC9kaXY+PGJyPjxicj5cDQoJCQkgQW5kICcrdlBHUC5uYW1lKycgaXMgaGVyZSB0byBicmluZyB0aGlzIGRhbW4gZ29vZCBwcml2YWN5IGVuZ2luZSB0byB0aGUgVksuY29tIGNoYXQhPGJyPlwNCgkJCSBJbiBvcmRlciB0byBnZW5lcmF0ZSB5b3VyIGtleXMsIHdlIHdpbGwgdXNlIHlvdXIgVksgSUQgYW5kIGEgcGFzc3dvcmQuPGJyPlwNCgkJCSBZb3Ugd2lsbCBuZWVkIHRvIGVudGVyIHRoaXMgcGFzc3dvcmQgZXZlcnkgdGltZSB5b3UgZ28gdG8gVksgYW5kIHJlY2VpdmUgYW4gZW5jcnlwdGVkIG1lc3NhZ2UgKGJ1dCBvbmNlIHBlciBzZXNzaW9uKSBmb3Igc2VjdXJpdHkgcmVhc29ucy4gUHJldHR5IG11Y2ggbGlrZSBUb3VjaCBJRCBvbiB0aGUgaVBob25lLiA8YnI+XA0KCQkJIDxicj48Y2VudGVyPjxzdHJvbmc+UGxlYXNlIGVudGVyIHRoZSBwYXNzd29yZCB5b3Ugd291bGQgbGlrZSB0byB1c2U6PC9zdHJvbmc+JywNCgkJCSAgJ0VudGVyIHBhc3N3b3JkJywgDQoJCQkgIGxpYmFrYXNha2FndWkuZGVmRm9vdGVyLCANCgkJCSAgDQoJCQkgIGZ1bmN0aW9uKHBhc3N3ZCkgeyANCgkJCSAgbWUuaGlkZSgpOw0KCQkJICBvcGVucGdwLmluaXQoKTsNCgkJCSAgCXZhciBrZXlzID0gb3BlbnBncC5nZW5lcmF0ZV9rZXlfcGFpcigxLCA1MTIsIHZrLmlkLCBwYXNzd2QpOw0KCQkJICAJdlBHUC5zYXZlU2V0dGluZygncHJpdmF0ZWtleScsIGtleXMucHJpdmF0ZUtleUFybW9yZWQpOw0KCQkJICAJdlBHUC5zYXZlU2V0dGluZygncHVibGlja2V5Jywga2V5cy5wdWJsaWNLZXlBcm1vcmVkKTsNCgkJCQl2YXIgbXlib3ggPSB3aW5kb3cuTWVzc2FnZUJveCh7IA0KCQkJCQkJdGl0bGU6IHZQR1AubmFtZSwgDQoJCQkJCQl3aWR0aDogNDEwLCANCgkJCQkJCWhlaWdodDogJ2F1dG8nLCANCgkJCQkJCWFuaW1TcGVlZDogMCwgDQoJCQkJCQlib2R5U3R5bGU6ICcnLCANCgkJCQkJCWRhcms6IHRydWUsIA0KCQkJCQkJc2VsZkRlc3RydWN0OiBmYWxzZSwgDQoJCQkJCQlwcm9ncmVzczogZmFsc2UsIA0KCQkJCQkJaGlkZU9uQkdDbGljazogdHJ1ZSwgDQoJCQkJCQloaWRlQnV0dG9uczogZmFsc2UsIA0KCQkJCQkJb25TaG93OiBmYWxzZSwgDQoJCQkJCQlvbkhpZGVBdHRlbXB0OiBmYWxzZSwgDQoJCQkJCQlvbkJlZm9yZUhpZGU6IGZhbHNlLCANCgkJCQkJCW9uSGlkZTogZmFsc2UsIA0KCQkJCQkJb25DbGVhbjogZmFsc2UsIA0KCQkJCQkJb25EZXN0cm95OiBmYWxzZSANCgkJCQkJICB9KTsgDQoJCQkJCS8qIML78fLg4uv/5ewg6u7t8uXt8iAqLyANCgkJCQkJbXlib3guY29udGVudCgnV2UgaGF2ZSBmaW5pc2hlZCBnZW5lcmF0aW5nIHlvdXIga2V5IHBhaXIuIFlvdSB3aWxsIHN0aWxsIGJlIGFza2VkIHRvIGlucHV0IHlvdXIgcGFzc3dvcmQgb25jZSBpbiBhIHdoaWxlLiAnKTsgDQoJCQkJCS8qIMTu4eDi6//l7CDq7e7v6uggKi8gDQoJCQkJCW15Ym94LmFkZEJ1dHRvbignT0snLCB1bmRlZmluZWQsICdncmF5Jyk7IA0KCQkJCQlteWJveC5zZXRDb250cm9sc1RleHQobGliYWthc2FrYWd1aS5kZWZGb290ZXIgKTsgDQoJCQkJCS8qIM7p6/7y8SEgKi8gDQoJCQkJCW15Ym94LnNob3coKTsgDQoJCQkgIAkJdlBHUC5zYXZlU2V0dGluZygnc2V0dXBEb25lJywgdHJ1ZSk7DQoJCQkgICB9LCANCgkJCSAgDQoJCQkgIHRydWUpOw0KCQkJDQoJCQkNCgkJfSwgJ0RvIGl0IGxhdGVyJywgZnVuY3Rpb24oKXtzaG93RG9uZUJveCgnSnVzdCBjbGljayBTZXR0aW5ncyBpbiB0aGUgUGx1Z2luIGxpc3QgaXRlbSBvZiAnK3ZQR1AubmFtZSsnIHdoZW4geW91IHdhbnQgdG8gc2V0dXAgYW5kIHlvdVwncmUgZG9uZSA6KScpOyBtZS5oaWRlKCk7fSkNCgkJdlBHUC5zYXZlU2V0dGluZygnZmlyc3RSdW4nLCB0cnVlKTsNCgkJcmV0dXJuOw0KCX0NCg0KZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigicGdwX2Fycml2ZWQiLHZQR1AuZW5naW5lQXJyaXZhbCk7DQp9DQoNCnZQR1AubW9kYWwgPSB1bmRlZmluZWQ7DQp2UEdQLnR1cm5PbiA9IGZ1bmN0aW9uKHBlZXIpIHsNCglpZighdlBHUC5rZXlTdG9yZS5wdWJsaWNLZXlFeGlzdHMocGVlcikpIHsNCgkJdlBHUC5tb2RhbCA9IHdpbmRvdy5NZXNzYWdlQm94KHsgDQoJCQkJCQl0aXRsZTogdlBHUC5uYW1lLCANCgkJCQkJCXdpZHRoOiA0MTAsIA0KCQkJCQkJaGVpZ2h0OiAnYXV0bycsIA0KCQkJCQkJYW5pbVNwZWVkOiAwLCANCgkJCQkJCWJvZHlTdHlsZTogJycsIA0KCQkJCQkJZGFyazogdHJ1ZSwgDQoJCQkJCQlzZWxmRGVzdHJ1Y3Q6IHRydWUsIA0KCQkJCQkJcHJvZ3Jlc3M6IHRydWUsIA0KCQkJCQkJaGlkZU9uQkdDbGljazogZmFsc2UsIA0KCQkJCQkJaGlkZUJ1dHRvbnM6IGZhbHNlLCANCgkJCQkJCW9uU2hvdzogZmFsc2UsIA0KCQkJCQkJb25IaWRlQXR0ZW1wdDogZmFsc2UsIA0KCQkJCQkJb25CZWZvcmVIaWRlOiBmYWxzZSwgDQoJCQkJCQlvbkhpZGU6IGZhbHNlLCANCgkJCQkJCW9uQ2xlYW46IGZhbHNlLCANCgkJCQkJCW9uRGVzdHJveTogZmFsc2UgDQoJCQkJCSAgfSk7IA0KCQkJCQkvKiDC+/Hy4OLr/+XsIOru7fLl7fIgKi8gDQoJCQkJCXZQR1AubW9kYWwuY29udGVudCgnV2UgYXJlIG5vdyBjaGVja2luZyBpZiB0aGUgcmVjaXBpZW50IGlzIGNhcGFibGUgb2YgUEdQIGVuY3J5cHRpb24uLi4nKTsgDQoJCQkJCXZQR1AubW9kYWwuc2hvd1Byb2dyZXNzKCk7DQoJCQkJCS8qIM7p6/7y8SEgKi8gDQoJCQkJCXZQR1AubW9kYWwuc2hvdygpOyANCgkJCQkJdlBHUC5zZW5kU3lzKHZQR1AuYm91bmRhcnkrJ0NBUEFCSUxJVFlfQ0hFQ0snLCdEbyB5b3UgaGF2ZSB2UEdQIGluc3RhbGxlZD8nLCBwZWVyKTsNCgl9IGVsc2Ugew0KCQl2UEdQLmVuYWJsZWRbcGVlcl0gPSAodlBHUC5lbmFibGVkW3BlZXJdID8gZmFsc2UgOiB0cnVlKTsNCgkJJCgnI2ltX2VkaXRhYmxlJytjdXIucGVlcilbMF0uc3R5bGVbJ2JhY2tncm91bmRDb2xvciddPSh2UEdQLmVuYWJsZWRbcGVlcl0/ICcjZWZlJyA6ICcjZmZmJyk7DQoJCXNob3dEb25lQm94KCdQR1AgZm9yICcrKGxpYmFrYXNha2Fjb3JlLnRyeVJlc29sdmVQZWVyKHBlZXIpLm5hbWUgfHwgJ3RoaXMgdXNlcicpKycgaXMgbm93IDxzdHJvbmc+JysodlBHUC5lbmFibGVkW3BlZXJdPyAnb24nIDogJ29mZicpKyc8L3N0cm9uZz4hJyk7DQoJfQ0KfQ0KdlBHUC5wcm9jZXNzSU1IaXN0b3J5SXRlbSA9ICBmdW5jdGlvbihwZWVyX2lkLCBvdXQsIG1lc3NhZ2UpIHsgDQogCQl0cnkgeyBpZigkKCcjcGdwX29uJykubGVuZ3RoID09IDApDQoJCQkkKCcjaW1fc2VuZF93cmFwJykuYXBwZW5kKCc8ZGl2IGNsYXNzPSJidXR0b25fYmx1ZSBpbV9zZW5kX2NvbnQgZmxfbCI+PGJ1dHRvbiBpZD0icGdwX29uIiBvbmNsaWNrPSJ2UEdQLnR1cm5PbihjdXIucGVlcikiPlRvZ2dsZSBQR1A8L2J1dHRvbj48L2Rpdj4nKTsNCgkJfSBjYXRjaCh4KXt9DQoJCWlmKCFvdXQgJiYgbWVzc2FnZS5pbmRleE9mKHZQR1AuYm91bmRhcnkpID09IDApIHsNCgkJCWlmKG1lc3NhZ2UuaW5kZXhPZignQ0FQQUJJTElUWV9DSEVDSycpID4gLTEgKXsgDQoJCQlyZXR1cm4gJzxmb250IHN0eWxlPSJjb2xvcjogI2FhYSI+dlBHUCByZXF1ZXN0PC9mb250Pic7DQoJCQl9IGVsc2UgaWYobWVzc2FnZS5pbmRleE9mKCdDQVBBQkxFJykgPiAtMSApeyANCgkJCXJldHVybiAnPGZvbnQgc3R5bGU9ImNvbG9yOiAjYWFhIj52UEdQIHJlc3BvbnNlPC9mb250Pic7DQoJCQl9IGVsc2Ugew0KCQkJdmFyIHRpZCA9ICd2cGdwX3RlbXBfJytsaWJha2FzYWthY29yZS5tYWtlUmFuZG9tU3RyaW5nKDEwKTsgdmFyIHN1cyA9ICcqKiB3YWl0aW5nIGZvciBwYXNzd29yZCAqKic7DQoJCQl2UEdQLmRlY29kZShtZXNzYWdlLnN1YnN0cih2UEdQLmJvdW5kYXJ5Lmxlbmd0aCwgbWVzc2FnZS5sZW5ndGgpLCBvdXQsIGZ1bmN0aW9uKHRleHQpIHsNCgkJCS8vY29uc29sZS5sb2coJ2RlY29kZWQ6ICcrdGV4dCk7DQoJCQkJJCgnIycrdGlkKS5odG1sKHRleHQpOw0KCQkJCXN1cyA9IHRleHQ7DQoJCQl9KTsNCgkJCXJldHVybiAnPGZvbnQgc3R5bGU9ImNvbG9yOiAjYWFhIj52UEdQLWVuY29kZWQgbWVzc2FnZTo8L2ZvbnQ+PGJyPjxkaXYgaWQ9IicrdGlkKyciPicrc3VzKyc8L2Rpdj4nOyB9DQoJCSB9DQogfQ0KDQp2UEdQLnByb2Nlc3NJTSA9IGZ1bmN0aW9uKHBlZXIsIG91dCwgdGl0bGUsIG1lc3NhZ2UsIGRhdGUsIGtsdWRnZXMpIHsgDQoJaWYodHlwZW9mIG1lc3NhZ2U9PSJ1bmRlZmluZWQiIHx8IG1lc3NhZ2UgPT0gbnVsbCljb25zb2xlLmxvZygiVlBHUF9wcm9jZXNzSU06IG1lc3NhZ2UgaXMgdW5kZWZpbmVkIik7DQogaWYoIW91dCAmJiB0aXRsZSA9PSB2UEdQLmJvdW5kYXJ5ICsgJ0NBUEFCTEUnICYmIHZQR1AubW9kYWwpIHsNCiAJdlBHUC5tb2RhbC5oaWRlKCk7DQoJIHNob3dEb25lQm94KChsaWJha2FzYWthY29yZS50cnlSZXNvbHZlUGVlcihwZWVyKS5uYW1lIHx8ICdUaGlzIHVzZXInKSArICcgaXMgY2FwYWJsZSBvZiBQR1AhJyk7DQoJdlBHUC5rZXlTdG9yZS5tZW1vcml6ZShwZWVyLCBtZXNzYWdlKTsNCglyZXR1cm4gJzxmb250IHN0eWxlPSJjb2xvcjogI2FhYSI+dlBHUCBLZXkgQ2FwYWJpbGl0eSBSZXNwb25zZTwvZm9udD4nOw0KIH0NCiAgaWYoIW91dCAmJiB0aXRsZSA9PSB2UEdQLmJvdW5kYXJ5ICsgJ0NBUEFCSUxJVFlfQ0hFQ0snKSB7DQoJdlBHUC5zZW5kU3lzKHZQR1AuYm91bmRhcnkrJ0NBUEFCTEUnLHZQR1Aua2V5U3RvcmUucHVibGljS2V5KHZrLmlkKS5yZXBsYWNlKC9cbi9nLCI8YnI+IiksIHBlZXIpOw0KCXJldHVybiAnPGZvbnQgc3R5bGU9ImNvbG9yOiAjYWFhIj52UEdQIEtleSBDYXBhYmlsaXR5IFJlcXVlc3Q8L2ZvbnQ+JzsNCiB9DQogaWYob3V0ICYmIHRpdGxlID09IHZQR1AuYm91bmRhcnkgKyAnQ0FQQUJMRScpIHsNCglyZXR1cm4gJzxmb250IHN0eWxlPSJjb2xvcjogI2FhYSI+dlBHUCBLZXkgQ2FwYWJpbGl0eSBSZXNwb25zZTwvZm9udD4nOw0KIH0NCiAgaWYob3V0ICYmIHRpdGxlID09IHZQR1AuYm91bmRhcnkgKyAnJykgew0KCXJldHVybiAnPGZvbnQgc3R5bGU9ImNvbG9yOiAjYWFhIj52UEdQLWVuY29kZWQgbWVzc2FnZSAoc2VudCBtZXNzYWdlcyBjYW5ub3QgYmUgZGVjb2RlZCk8L2ZvbnQ+JzsNCiB9DQogIGlmKCFvdXQgJiYgbWVzc2FnZS5pbmRleE9mKHZQR1AuYm91bmRhcnkpID09IDApIHsNCiAgCXZhciB0aWQgPSAndnBncF90ZW1wXycrbGliYWthc2FrYWNvcmUubWFrZVJhbmRvbVN0cmluZygxMCk7DQogIC8vIHJhY2UgY29uZGl0aW9uIG1heSBvY2N1ciBzbyB3ZSBqdXN0IHByZXZlbnQNCiAgCXZhciBzdXMgPScqKiB3YWl0aW5nIGZvciBwYXNzd29yZCAqKic7IHZQR1AuZGVjb2RlKG1lc3NhZ2Uuc3Vic3RyKHZQR1AuYm91bmRhcnkubGVuZ3RoLCBtZXNzYWdlLmxlbmd0aCksIHRydWUsIGZ1bmN0aW9uKHRleHQpIHsNCiAgCS8vY29uc29sZS5sb2coJ2RlY29kZWQ6ICcrdGlkKTsNCiAgCQkkKCcjJyt0aWQpLmh0bWwodGV4dCk7DQogIAkJc3VzID0gdGV4dDsNCiAgCX0pOw0KICAJLy8JY29uc29sZS5sb2coJ25ldyB0aWQgJyt0aWQrICcgc3VzICcrc3VzKTsNCglyZXR1cm4gJzxmb250IHN0eWxlPSJjb2xvcjogI2FhYSI+dlBHUC1lbmNvZGVkIG1lc3NhZ2U6PC9mb250Pjxicj48ZGl2IGlkPSInK3RpZCsnIj4nKyhzdXMpKyc8L2Rpdj4nOw0KIH0NCn0NCg0KdlBHUC5wcmVwcm9jZXNzT3V0Z29pbmdJTSA9IGZ1bmN0aW9uKGltLCBwZWVyKSB7DQoJLy9jb25zb2xlLmxvZygiUFJFUFJPQyAiLGltLHBlZXIpOw0KCWlmKCF2UEdQLmVuYWJsZWRbY3VyLnBlZXJdKSB7bGliYWthc2FrYWNvcmUuc3lzbG9nKCdOTyBOZWVkIGVuY3J5cHQgdGhpcyBJTSEnKTsgcmV0dXJuIGltO30NCgkJbGliYWthc2FrYWNvcmUuc3lzbG9nKCdOZWVkIGVuY3J5cHQgdGhpcyBJTSEnKTsNCgkJb3BlbnBncC5pbml0KCk7DQoJCXZhciBwdWJfa2V5ID0gb3BlbnBncC5yZWFkX3B1YmxpY0tleSh2UEdQLmtleVN0b3JlLnB1YmxpY0tleShjdXIucGVlcikpOw0KCQlyZXR1cm4gdlBHUC5ib3VuZGFyeStvcGVucGdwLndyaXRlX2VuY3J5cHRlZF9tZXNzYWdlKHB1Yl9rZXksaW0pLnJlcGxhY2UoL1xuL2csIjxicj4iKTsNCn0NCg0KdlBHUC5kZWNvZGUgPSAgZnVuY3Rpb24gKG1lc3NhZ2UsIGlzVG9NZSwgY2FsbGJhY2spIHsNCgljb25zb2xlLmxvZygiVlBHUCBkZWNvZGUgIixtZXNzYWdlKTsNCgkNCglpZighaXNUb01lKSBjYWxsYmFjayggIioqIG93biBtZXNzYWdlIGNhbid0IGJlIGRlY29kZWQgZHVlIHRvIFBHUCBsaW1pdGF0aW9ucyAqKiIgKTsNCglvcGVucGdwLmluaXQoKTsNCgkNCgl3aW5kb3cuc2hpdD1tZXNzYWdlOw0KCQ0KCW1lc3NhZ2UgPSBsaWJha2FzYWthY29yZS5yZXBsYWNlQWxsKCcgXG4nLCdcbicsbWVzc2FnZS5yZXBsYWNlKC9bXHUyMDE0XS9nLCAnLS0nKS5yZXBsYWNlKC88YnJccypbXC9dPz4vZ2ksICdcbicpKTsNCgkNCgkNCgkNCgkNCgl2YXIgc2hvd01lc3NhZ2VzID0gZnVuY3Rpb24oYyl7Y29uc29sZS5sb2coYyk7fQ0KCXZhciAgcHJpdl9rZXkgPSBvcGVucGdwLnJlYWRfcHJpdmF0ZUtleSh2UEdQLmtleVN0b3JlLnByaXZhdGVLZXkoKSk7DQoJdlBHUC5rZXlTdG9yZS5wYXNzd29yZFByb21wdGluZ0lmTmVlZGVkKGZ1bmN0aW9uKHBhc3cpIHsNCgkJLy9jb25zb2xlLmxvZygncHBpbiAnK21lc3NhZ2UpOw0KCQkNCgkJY29uc29sZS5sb2coIlZQR1AgZGVjb2RlIDIiLG1lc3NhZ2UpOw0KCQkNCgkJCXZhciBtc2c9IG9wZW5wZ3AucmVhZF9tZXNzYWdlKG1lc3NhZ2UpOw0KCQkJCXZhcgkga2V5bWF0ID0gbnVsbDsNCgkJCQl2YXIJIHNlc3NrZXkgPSBudWxsOw0KCQkJDQoJCQlmb3IgKHZhciBpID0gMDsgaTwgbXNnWzBdLnNlc3Npb25LZXlzLmxlbmd0aDsgaSsrKSB7DQoJCQkJCQlpZiAocHJpdl9rZXlbMF0ucHJpdmF0ZUtleVBhY2tldC5wdWJsaWNLZXkuZ2V0S2V5SWQoKSA9PSBtc2dbMF0uc2Vzc2lvbktleXNbaV0ua2V5SWQuYnl0ZXMpIHsNCgkJCQkJCQlrZXltYXQgPSB7IGtleTogcHJpdl9rZXlbMF0sIGtleW1hdGVyaWFsOiBwcml2X2tleVswXS5wcml2YXRlS2V5UGFja2V0fTsNCgkJCQkJCQlzZXNza2V5ID0gbXNnWzBdLnNlc3Npb25LZXlzW2ldOw0KCQkJCQkJCWJyZWFrOw0KCQkJCQkJfQ0KCQkJCQkJZm9yICh2YXIgaiA9IDA7IGogPCBwcml2X2tleVswXS5zdWJLZXlzLmxlbmd0aDsgaisrKSB7DQoJCQkJCQkJaWYgKHByaXZfa2V5WzBdLnN1YktleXNbal0ucHVibGljS2V5LmdldEtleUlkKCkgPT0gbXNnWzBdLnNlc3Npb25LZXlzW2ldLmtleUlkLmJ5dGVzKSB7DQoJCQkJCQkJCWtleW1hdCA9IHsga2V5OiBwcml2X2tleVswXSwga2V5bWF0ZXJpYWw6IHByaXZfa2V5WzBdLnN1YktleXNbal19Ow0KCQkJCQkJCQlzZXNza2V5ID0gbXNnWzBdLnNlc3Npb25LZXlzW2ldOw0KCQkJCQkJCQlicmVhazsNCgkJCQkJCQl9DQoJCQkJCQl9DQoJCQkJCX0NCgkJCQkJDQoJCQkJCWlmIChrZXltYXQgIT0gbnVsbCkgew0KCQkJCQkJaWYgKCFrZXltYXQua2V5bWF0ZXJpYWwuZGVjcnlwdFNlY3JldE1QSXMocGFzdykpIHsNCgkJCQkJCQkvL2FsZXJ0KCJQYXNzd29yZCBmb3Igc2VjcmVjdCBrZXkgd2FzIGluY29ycmVjdCEiKTsNCgkJCQkJCQl2UEdQLmtleVN0b3JlLnBhc3N3b3JkID0gdW5kZWZpbmVkOw0KCQkJCQkJCWNhbGxiYWNrKCAiKiogVktQR1AgZXJyb3IgcGFzc3dvcmQgaW5jb3JyZWN0ICoqIiApOw0KCQkJDQoJCQkJCQl9DQoJCQkJCQl2YXIgYSA9ICBtc2dbMF0uZGVjcnlwdChrZXltYXQsIHNlc3NrZXkpOw0KCQkJCQkJY2FsbGJhY2soIGEpOyANCgkJCQkJfSBlbHNlIHsNCgkJCQkJCS8vYWxlcnQoIk5vIHByaXZhdGUga2V5IGZvdW5kISIpOw0KCQkJCQkJY2FsbGJhY2soICIqKiBWS1BHUCBlcnJvciBubyBwa2V5IGZvdW5kICoqIiApOw0KCQkJCQl9DQoNCiAgCQ0KCX0pOw0KfQ0KDQoNCnZQR1AubmF2UHJvYyA9IGZ1bmN0aW9uKHRvKSB7DQoJaWYodG8uaW5kZXhPZignL2ltJykgPiAtMSAmJiBjdXIucGVlcikgew0KCQlpZigoJCgnI3BncF9vbicpLmxlbmd0aCA9PSAwKSkNCgkJCSQoJyNpbV9zZW5kX3dyYXAnKS5hcHBlbmQoJzxkaXYgY2xhc3M9ImJ1dHRvbl9ibHVlIGltX3NlbmRfY29udCBmbF9sIj48YnV0dG9uIGlkPSJwZ3Bfb24iIG9uY2xpY2s9InZQR1AudHVybk9uKCcrY3VyLnBlZXIrJykiPkVuYWJsZSBQR1A8L2J1dHRvbj48L2Rpdj4nKTsNCgl9DQp9DQoNCnZQR1Auc2hvd1NldHRpbmdzID0gZnVuY3Rpb24oKSB7DQoJaWYodHlwZW9mIHZQR1Auc2V0dGluZ3MgPT0gInVuZGVmaW5lZCIgfHwgdlBHUC5zZXR0aW5ncyA9PSBudWxsKSB2UEdQLnNldHRpbmdzID0gIG5ldyBPYmplY3QoKTsNCglpZih2UEdQLnNldHRpbmdzLnNldHVwRG9uZSkgc2hvd0RvbmVCb3goJ1lvdSBoYWQgYWxyZWFkeSBjb21wbGV0ZWQgdGhlIHNldHVwIHdpemFyZC4nKTsNCgllbHNlIHsNCgkJdlBHUC5zYXZlU2V0dGluZygnZmlyc3RSdW4nLCBmYWxzZSk7DQoJCXZQR1AuZW5naW5lQXJyaXZhbCgpOw0KCQl9DQp9DQoNCnZQR1AucmVnaXN0ZXIoKTsNCg0K";
addJS_Node(null,uri,null,null);
console.log("GGL Team. El. Psy. Congroo.")
@JulyMorning
Copy link

could you update it, please?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment