diff --git a/agents/meshcmd.min.js b/agents/meshcmd.min.js new file mode 100644 index 00000000..45485f59 --- /dev/null +++ b/agents/meshcmd.min.js @@ -0,0 +1,2005 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* @description MeshCmd, command line tool for Intel AMT and MeshCentral. +* @author Ylian Saint-Hilaire +* @version v0.2.0 +*/ + +// Debug Stuff +//console.displayFinalizerMessages = 1; // Display objects that have event listeners that are disposed. +//console.displayStreamPipeMessages = 1; // Display stream pipe and un-pipes +//var __gc = setInterval(function () { console.log('GC'); _debugGC() }, 2000); // + + +var fs = require('fs'); +var os = require('os'); +var net = require('net'); +var http = require('http'); +var dgram = require('dgram'); +var httpHeaders = require('http-headers'); +var tcpserver = null; +var broadcastSockets = {}; +var multicastSockets = {}; +var discoveryInterval = null; +var membershipIPv4 = '239.255.255.235'; +var membershipIPv6 = 'FF02:0:0:0:0:0:0:FE'; +var settings = null; +var meshCmdVersion = '***Mesh*Cmd*Version***'; // Dynamically replaced with MeshCentral version +var amtLms = null, amtMei = null, amtMeiState = null; +var wsstack = null, amtstack = null; +var oswsstack = null, osamtstack = null; +var amtMeiTmpState = null; +var SMBiosTables = null; +var globalDebugFlags = 0; // 1 = IDER Debug +const RCSMessageProtocolVersion = 1; // RCS Message Protocol Version. Needs to be less than or equal to RCS server Message Protocol Version + +// MeshCommander for Firmware (GZIP'ed, Base64) v0.7.5 +var Large_IntelAmtWebApp = "H4sIAAAAAAAEAHq/e7+Noou/c0hkgCuA0+rcdhMHwq/CcXohAVwD4W7vve/fAQ2gc4WkFXILx+++kuUCgdRbrdHMN/0Dr9I1u3lp/3qN3jNMK6RlpeMwCO4ZOQK5eVmjBqOopY//rekm/df/6zP/C1FL0DRj6OWCa+Q6nXz3VYqkxIkzuco17vRz6yPJK1AN6nStC3816YJ+4ZT9P/cST/YcakwLoWrQPkGNuaaCd1EZykpwTLkwLhnlt55Clk6oUZl42gCltIYSn0teepXCIp0Q0BBfhEkGDS5mT+nfn//y+zb44ZtSpAbpWIibTJB926lGUsPO757FBlXBxDauKCHIk0KY8AuoKdvHoCiwp16FbIOa5vDUa4A3foOKFk6xoa8wfiF1kgsmVJwxyG+TzPwplVhzEm8rqtH4VCXlvhYyDs4HhoW+npQJyB79LWa3VBvVdV75OTAm1jrmguPlam3cmxAY5ueLW9uUEXktXo1Jm6FwIDgw2rrQTFASCKG8jAMjhgxZS2gjGexNusKk61LfUk7E1s5IJ3+/e5eMAG4p0ZVrhMOOK9uQdgBRmQIxW6TktfPR4wHiDW2oRtLas08wFwrsoLl0nM2dYFZYVTtj76PnQjnJ5vN5cqjC9tr2MJTaTcHWzVMmGOkNQrfVc7nrzkEYXM+Z0FrU8cJIDlXU9gfrvR0s+g4WA3zTPtm+xWI2tOiPZ2QD1KQfoJFUQ8m5dmvVmGCloFyj6i7GHQBIDs8sNRk9KRp67EJBd0gStyinDTmvxmlpF0u56wEF00XiHZ5JJUqFTZPBGJwzG0eMhoAmMsp7tZqZfhkpE2Xb1c2yDLK5uwjfeONpS0OeVjHXZqsryshDQcijngGuEAs0BsWasRwZG03jhdxd4nddulRK7gZkdnhWA+UfARbOF0O4897airiymXvLi8wHRkseG1DjksPGNWHcoTHu+XMU4BxmQhFU13HzGsEo8e58Hnyx+PqLEXeDxnXOjHIE5ZcKCEWuH2rhOadPvTtZQcIi94J7T0919ywHPXLRh+2ZoEITQmB+7f/VZT1sqd++l0fa9xsJOcZcbBXIpL8KzlHUG7Fp1N/HoAc5sFevU5ERBe3g2WOkYevqel7r8FJYU5t9cmRCV1Ebh7WI2hHh9INhpm9i8zur6SpaZsOkGqkQSO+B3XlEDHDOKWpaozqF14nrDmQ5YDi0O18Yy7pTxqXUViRkl+aj4M0sfOeLlf0e513XVUv0DjRqR4z6WltQvH2TrzywX5aacsHD9lQXy9rncs17TOYrlAj2gX761L07vj3Fa8Uedt+mSlqc36b+55UqFtwEwvC79FSPW/0fQSZMYCDG3iaExS1GJi9f9/a8v14/c7u5bpM8pgACLO6AhfvqOiOHbq76m7M71fbncyxUXtmb220fqWKsq7tz0+tcJs8aHNdByros3BaTcHS5dDodZYwQUACYggVfSwD68lw15Tlren2b78LjjoJKKccLtK5Ss1KYxwx8PyJ2r2057jJLRkMKU51UDlJzXyKKVyYjbRzZtG21KoIFn6dEtPjADRwPlIsdPjpXM8doT5DT6cTAIYz2pckcl0fLmzZBQrA5Es09CJ3HQ1+P2zB3fRfI8e2jJ98V7z+o4owScMiay4KTFgCc3xXkfyloqtJ8VqMDyE2ZVItNk5Q7wYLlQLJbd6N7voyABSfZtc38uLs3rf5qF+ZEXOdw9JLjMiUmVGC3b3+xHTwo27lpgEUDI9yeJvI/2en8zj74i/1ChtYhsIoNN+s2qe/QwtRzHw1vUKea9BGkvlj6w3ire02MN+5AetYzVNLp1QRKI4mugogEhpu8isLIE5Y2XBlwrIZ6XLCSeuvMnUAj+iILVsaqd8xw9omd51Bs3FbyV3BKWTuxbBbV7Ep3bnrxi73rZ23K9YNIyOIzRTIE6fLKvx8GHEIEmy1rU66k7IooU4DBNAz5wzFn587pRj4Stj6hsbIbQ1ACXpAHGpbR5GmhqQPbkq03TZNQmUHqeimXnTUa1BktRmZVgzrhOkrFTyDJ8eJ8Gy21jdlvHUVPd4FAn+sEwgAddtm3K5BPcrYLJhMA5KtjVYA9YyfE6JT/tT428gIv8ahfGx4BNXXhEZiqaniErbzaWGn4OwGFfgp+Va3Mv5E/ueBivaaBy+IjIVshDD0UAeub/bZTBOKkuZIAsAIPzijvGwBuX7ooxmaD+4YSJ/lT3yncehnwAC5rO1zd/k7Y7C2xmcZO6HrbotuNu/6W6KzduBtsi24n7v78Qqm0BrVSaQ0ULvmzHZe1Ha6uNdgFm70ltr61C7beltiGo12w9bfEZhq9XdANtkVn7yInYKn+SsjS80VfZrdIbgkKjdyhPtuTIR4JI+p4ydPeQDxA4kCL27sqajW+IBh86E6QDESWfkiTLMwhhJRNQF3kKc2oCDyX8h8BWvx2xvAvRp4V24fdNaai6m3RJKHOai1wfcOdOPR9WBrrtXwBrVszhswAY8jkL8aYyX+rHaMG/NvEGHbvsGP819wyJFffsl+GM3+xSJMkDNAb7RWYkL91b1QLM/RQX0vJVZ1qtWQx82ni3bOy9sDD/41x2C+Qhe5n3mkWurhId28mjfUeC/kZWXU8EAP/B3502M9bUuBwIfbNtlBPlrSkbSktaVvtWhIQWtsjtK2dMNrbYxz0dsAYL/7a3K+dkkLazDa+qI9zAnDzr1iQaina2Rj+FYAfu3xFXZEYNYhBTFio+HZB94hxgP8d2mT/bTUf5TjOW6KElC5Ec5owPd/tezzpyssrSXr11qSPwaVKjMlz8Jg/S0fuL11PrPGj8OoM4GcN7OTpp16v9za/wfEC0A9deZGjp3dHm4BNro3eAhT3C8+YEoSm2osVPCf9L/JNdNmSpn5STTGXT7AiX7+OWY7hXy39Ox6L4/nuKLv3e5d4ifjrivHVaS5x746yxncyGx8GaSCkwp10Lhd7+x3xjNu+ZkE6WYkZPjvdCMIeu2dBsj9953r3xHMnBnF8yvkku8EQ+OjCZ9iGsSHexW4SmMrtFuskZsAsl9zLnOmkIyZ1SJYsnnSyv8UtZrQBaercFLssoMgsgYPpR5IsSTSOLtyTKF4s/dZ4c+zqcq4xcwVcMVP/E0HZiCa/xEDIheSww+B0apKUybCWchXrwyMaAMje9DKkMPbw8PDdEbSWcParl95KwEH61MABEpfdUAg5EP9H0HEbmpsuE0TB95y7yXyxZ4odp9P5E0/YmswTmqT83RHdTOs1zevJiTdsHSaMnDF+JxjVZtpNM+0MJYPL5y7IfPfy+H1xqtUw05ITv6Wx+0BjRi4CeesOp6k4e9AweyBnn4OUk8vwVqO130RrX046Tl2vMskym8jENU3CmN6y4pRRw4yRnPCeJQ9hfEfmLEmENOj7MGyicCjnXoDMBSypnzxumjzO2LuFNbmOGWeBw7SZo6aZo6LcnLElC7g+s1HgstX5nrOYHDtOmAaJRqzVuPtWhjJdcCf2Ith2faLdNDETuB/pHSPHPo3X+jSjaZqR4ZPIyLmQgDDWOLSaOLQyfPOr4/fkJA4fOIOJ6pTyTDDglp7jydbdvFrFkwtAfuGpOkYl5WaWrntHS+qMXN26arfgMKGiThBowa+YvvOCKE2yipXMRQRlnLJJZy4IJxdn590bMmeci53pqAVZOnv7ihUFt+CjDEpm1xIL8GWw4NHbd4upBvTd0WKjNcdTTVfqi2Uan3pRyob8lYuUSdNmdR5fsToVUtRq3aRBIAYiFrVcCLU0Ta6T2bqK1i8qWhqTmgerO7q6mwZYdE+uX7NEBeCiWy1351GczgOypD5n+53pl589WkNz8LZtA3pt4vlx5XGSJ/rfcLL04rW0TXwVpr5LFoykkUsT5h7gHIoYdBax7gsKzfg3R0eciW4veepmvsQhjPHhQuGIuveemPd0SHn0+I+yXWzUxfuP55fd+XHXMIxh/0ufBrep0DCihwXdZdzJCs6CUCBhcSzQBWEYsYCJnkTsF0smnf9ciFl3wqNKp5HPKGfEWTHnjqxYLPR6OgUFdggSVSsodpMriBV63jKmayaH9lqH5jGFITBkk8qo+jg/F7pR4UB0H1G21fBIAFqZmoMlHnWQkYkgNUmFabpbBDOV+jEH6uTowKwGYNisnw+Q/HqHRkc2bEA2aEBWcHN0QCMFSDWNG2CPmmCX/RQdhWVUUFhmAwqzceV190BHYDVBa1p63RQDNDlJj2mgwImAYUXBmhjySSBy5FNVbMu3mCrkkdB1Mc3MenbFJpmwyTr1Ey8SQzr5r07z0cgihqMMADKO2NDkSKi9GsPzp5TFT5r0ATFKJT7wNQ3kmL39Zut16jMaNwPpPO1Z/QPy5s1+p0COYxCxDw5bhb7L4skM8tW1QO7YUxpllGSDgBQM7ZDXRVwM8lIu2e1jb1kQ7BpBKKQUhiO5miuzHISQjywWw6gPMqJwSlT5SVOJiGoYVjZb+lEvmiG+Ch9mjCZpzPiZfwvcbniTtRiIbZPVRWhw8171F1qv1lEC66/ZZYkpp/46DGQM4X8Zs9u35PjqI7lhrhdjNXMUxgkJY1Jer2XGBPE4ESsB++VuzulwekAkv9KIkCQkLJAHzksOW7wOa/Spl/o6fGDxseTkd7PaGDkr5wGWMAgTEgGtzBX0lxfP4zxlhGYjCKYZD7UVlCdmKyWm6DUKtJeqOYyNZsP5mj9UzZKVC05PT08b3OVCUZ3mPyudwFngwqG8gNbv2BPHNBWB5XfCGAR0Ei6X2TONvEQA+wuDJsSmktt5yifXqUbRSZQSs/DTeNIRiCW2E/Ek8mYFw6MsJfpyVWUpyY4g/TTpxCxJ4yDzNTtZjxs+BKUOFEOHunq0IGWWZELLhd/SaZVo5FVL9dqwbVUSQS+biCWLrmTSEOITGicklmIJp/mOrMH6kjBiWaazsz17G6o9l8USw7PEAoHWL7OqyOMpjUBrdXLOP4a3tz4jHDqPOIRp4ZIkaAqIk40+IA8rFhDojiDGSlbqlRIYDo84kizS5ZLF5MHzfYgAOL1nLpxgCve4rLCVOQ4kKKOjZYGUJmqWQFg9OzfaYRAwJ1HoLh08PUpZTzr5rw6CVNJuG9MzjzsZCObqGltXB8WzDhWc5WQoZCFjBkDhKAsQ4ulX1yjAkrm9WHlLki3aoWg6DV1GJhMiUpgkS6ALlXQNEHBh39ZJYcaD7k7dfH05K4nfw4omUowQhsCXiRDoQF1mshmn4CYVuLN+ce7IC9kbGY9Wv8SeOk+gcOvYmYt2nSH797JdHekakb2ZaZAJOZ+ffv2vH672y/pjZsIhhzECNydsnfpSbwIXtRzPHnV+e78bfs8fExa4zCXH3PG8TtNWPs8ivCcnmETd0q6/fnOxPU387qnGxFysgoC2Bxnk3x+tP9XSavV+d8SKE1NP6vB3R+qJsDLyvZZagkfaee3/Ml7KNeUJqzPRm3D7j3v2wRs57s2BfQAUyof9DtpnDJ4rgXHvRYExDrcHMkbWr/hUZKyDtocC8v/Hx9/9cNUaE9uj18XE9vj/Y+L/wzGxqhQw9Ai0sGfxIjfSN2FCE0Yu2bJwz+TGsnWvawpjHPo0jtEat4G4AexVGBJErEAU4zbdg9G9BqiYINyJGQvIOnTZa8JJ1JAzAUqR9f3iRSFlv4200Em5JAqjPOpAaY5A4T+hS34Lx5zKzYMWiI25PON4v7MDN52ZRH/s+4W1Fto2I052vojDQR2Hcyr4oLju4uDnwaoK9DO1vgP5gEEkKDTSoe0C6uG2Sk0gPLxWAJjIBFy+lwgmHIe9hnJNE6Jhy9FunUwZ/o6TKXUScbqiwS0DGUC1yeVh18ViTZ2VF+xwRj9ZBktpKWUMnVH57OuGqmwI9btgzWaiHtXugdtzK+OG3Mp3Krey/Yq9JB3TM59Px8hxViUpgy9YV7Iy1VpEtcRwJqTiQWCdzFYnMQ0E2lhMRzMPe0TcMBEkZSWiVr9/YIh/D639t9VC0EoNcbkssbJiUs/KNXPVz3ylsTeNsC+NSj3r8J5BH/7E3nzRHBrcU56zS6QDMBn0DHy9T1jb3Dforjm+lUcdVfOpf+gkevwNOCHwil8Y0Z/hvIHvn7H0iTwTkCa76p8Uj6QupFL1Q+4DnvPbTgRQ+i5HYbQgN4wST+l/Y/qjF+hNJjR9fRY+lNot2f59pLfasvVSb+zJxiu9sT+dr7xl8nVN12A6M/WW4XRm6S2j6czWW8bTWa9EujGd9UtN5nQ2KDVZ09mw1GRPZ6NSU286G5ea+oJOo9QGtJultqFos9QFMio3FP0fz2rNcODuYqNgdzFs5ioDhFprg77Xq7tsTmK/e+wn3TPm72TdBXrxDrPErivTfpEE9JtkvcsifJyeQCUMmUuPSSdbzR8W549K83/w2IN0HfXJrYF5vyYwL+Db1GisTKxGrdR29I2muohhU11EtWpUh2g2QRw1QdQLQkvgrCZw4wZwemVqGZzdAM4yGsDptZyqDqRYAKIXbfTrXntRiABMBjErEKqqyupnNQqQoUA4ipi7ob6leBBkCunuKB/zwUucFYTBPOMLXnUgTA4i92JCB6iEH9nEEwlRnY4zZ8/Yfw7lSer5LqvDKV+pqMWGc6rozBZ079lDweGX5SbgjyJriKdwtGXzfwbsIdsB8CFboEP9VwE8PBKaw17G4VrezFXAx2nQDl4PgbSYS4FPwnrgXIzKoKM1b4Z/w+TdpFqdcB0JiMX1oYFLbhlEHNR9ApSCdOIhbzBOAtjQELbyA6+FeEHKVD4gDYrIFFAnjWM4oOyROSkmwryggEYtYCYMbThPBOl3OcJrmnLJXwF0uCzQsEGxgHkvRTJPWKSCSgkZgnwBFNobEECfDr82RZdNW2SyX6+ALFRAeKpAA1l1tWKGeieqmmKz+kbh3UIDHgqRTxVC3lSbMpBneFksy+pkWLxgxWIvyfFYqghWh40xgP6hpGoJcEcrA+tgHZhEjoEhVnukeSJSEcdb6bKHgp8GKlRN6BO+plnDQKdtJ3X0Kr+pr30V5kvJAa7dOIwmHdQHS/mMjv+BEEWP71eUxhKf9VCmmYtMbxZkL5M5iFJozKgaKJ+ayw+HUKEdMxlE5x8pq/ncofZxyWP5cclv1bclN5+WJDxivi/9pUlH+mywETlNkoPaA7TIGEH155Imjhwc0M7Ty1h6jlZ1EwKU/UBjD9w7rk62tInYqguTRoxlGDXUtEsSylENzZXvuWgfj9E6dv94jHaGcH8CQS6r2xfZ0bglo+oi/ObsSYsKzvyko298yedsriHH18B037XX5Lta7RXd+ttPOsx+E0y7Aab+SpQGa6DDalYzrkeF45xLNr6WC7tq1Lxlf35+rr1cjO+Py1c0PhsMBjX6g3xb+3Ha6gv1NZ9jNAfq8y+orosr0JE8VM9kDd2GYduCOnyazWZV/AT+N4iBUGENh9WAQAmxWfpCFoBoz1sqS/BHiGe1hKXCOCrHL01Xdcgpnq2BGlYZrNFolr/9N4KJmiCY2jxpMGsSj9hrF6b3xzrt8ouBLRJnVRFpYLF2u/QC00Bzf1wLTntA16y6Uyg2UjEr/+SJoX8y/R4nVghsxxdRzh+E6GAhWv6I1azryGeJkMVwuexsTdE1wvrqlSRZn5wkMATwQhTJSavbzYHRSGSmhZFKKDmSLwG2U1HJJV6GDvX1RvUGSzmZeBw85RkyXFOFtUz69A8xDSDpvRnCsTf1JV9mrlk23zvowgpL3bN55Un7qq2U4s35rDoAUF7Z8OmQ6ktQNaYTTFjqt75waODp+erKC7x1uiYjAp9Dp07CYk5E+L8iaRSx+IAIXCx2KGcHxOiODwiVCUN5k/QP//TZ51/8x5d0Hb39am//627zOba3VRiaR+HaEdS9qKY1ffRZcJusJp2eMR7kItvucMkdabTtSGf/tfpGk+N+dn8wly3PSbIuiuo2rSqM2luem48Y/EjjAHYdLfk8XOc3fhkVXCzXE4kZT31BXUBcmlDih5zDTso+V904kWSlrl4PNgWAYZxdbsaFWhjOsuNw2Lzpg0+hvAfgZ7Ig+cgen1nKolgMNtGmk83P7kPdvdqbuyBdL1jMPwgHEEOuTrbkiJxA5VmF0XYhGJxlXghYdIl7kv2FILFX0LOdpruOPbGGsGlyflnnzZng160ZIEn6uPJiFzHjlFpPVI5TEFBC9RVBKM+5jMNPcaAc09hqlczpzeX56IDMQGvwRO+0oNMcHJAbBpVEsgC2fLN0c/yjmD4Xqk/v6UEPzP2BxU+yX18cWQxBzgMnBEXcLjAQBmm+aZG3qkkAv7nAsRZMVZMg9cZDvbWn3WTIzRrCbb0skJnOxS+SXQt/DEMftqh9WubQZvOkISZXsmzmVLa/YD51s8nFG6H2ab639pIZvDh8QxM2vYRHIp8JNLRPDkJJX1b+ND0LgzcJyR4ywvW6x+mHZMVidXfynMCP2wW+iSrHNKfFUsPrME7U4ZD9VstcewoliXoJp+KiZV5PfnmhgBcmNQ/vl9+kVDjK8YHx8lWA4Cok4GVPXNPIEA2UunsfJoKvn1NBoAvYnps53KgAnEWWWLEJ4f1LQIzyw26Ne+PB0Br3p8f+A33iipBGts12tpU3bLUIkLl7zANcjF9uLG1rYy3li0mYOr+ij9I1tK2Cb4iRb/uQ6ziEyxDyftvYybGM35Lu+fzibDsz71hmO8EqoAcKy95e7IXwAYhtUVrboCwXPPx4fWyR6/l3ensP2qFZp/A4TVYsgLwMjN2WTvs1dML5sBVVp6dX193j83mxt6fs9MfvLq67N6e9Ym9/UzVyfl3sGKhykPdhwHQ+hcmOn+TQLcW1p8fTW3iodr3wXsp+smDJA2MBGUkvfWBXJHmL8a9MGjhW/38Cc83phwb92m6h5cde8I08eo+3k0HixWxTQam/IiANTAKzsJySeAHeBh8qqhBkECbqXdEDskgTwiFe4yzgnqxFltEZBGULAOP4qcvcQ6nyF7G2N4NK0IviTdeJJPTwzzwM6pNqr7TOliFhWAZV5vkMCxmRuvZpC2WbL8SphpA0gmDiRXOdjfd+dbrlXFfpC4n3S1IB0WTQLfOVK2VmqM3QUEruL0tQchCjY5+vKnkA/fOgzBZQpgYqdzOGL4BqtUC1NKgIuVrphx86fF6fDJVSAFzN6sTO4U0vrgl1XYjVn1ddkuWRhnC0NcJ5uoBKKcHd3ZbKcrw1rj/QhAm/cjs8trEtHpUyOHs/3xKXuTWuY7j0DwRjZWzPqWXL/iSZAvt53wizMT8vNedI12d6u6naD8jZt6fX+DZIOa9wHsgxumdx9iROnOfAcsBbTSxIttyDZ5wovKiQBEnDFAtyyN7aC9KE8f0tkfVeguzjx0uyx2WiSUfQnmo+g2/lJhsaPU7MXs8gSOoBkQP8hAB80Tk2DIJYDlvkpvdp5Kb/Urm5rMqNhXnbNNLb+9juPDk+07tG2AWFrZVS4hvGWaK3jsfj6ZwlZBGGCcl6uC5oGP3jh3VfmnuSvA92SkENra1SUGr7rJ574oVcFoE1Z2usnhpU2oOTiw9zIjs0860BnzMnjdmJWLRWDNrIEppz+Fybw0g2gMCINnxJGrWjwkF1zMiOeuAzoOEaP3osiwR4G5qa4SWEcgSJcAhhckw97svQuQNpxVrPNryloSWc0It3EwvZ34xPHoHn8amhzfhi6H4W39xnLHoenxrajI9D97P4RL38IqSx245sM64O0x321WOBu+s8+jh5ghiuDVd1dJ2AqkhwIYfUI75hS5/yFUh6G8bNsDIq7CGAsh7FnC7ZVei2qo18TAk4NMt3QBtXTaREb9oA45ASXNFKoLmBYJk3/SCU5CVtFTBtoI6iOfmqYwI1dR7TdqVaGFbCUghu0aSg5pODEal+MQk6sS5B/iLDO9zB8BoylaO3majaTs+Ozn44k/paH2DhgOufzmt6beyFz3XCJdddzZgejjnz6G0Q8sRz5CDNHuOihKkYuO2SjD75klxAvRYxSwuBzVZpBbDZrm/u1bB5xVyPEtn/sjjNc93/FFIIBwYAnLF7z2H6Iox3WgRJVhISMTuKyrekqvf07ObDlc6PPNqyH4jaeu96xk5k44s16AljbwbYVNT/KfWY3mf9N3vvwta4zSyOf5Ws3//DWrUwdhJCcGL4Z7mVtlwK7LY9lGcf+UKSEpK8iYEulO/+mxlZjnwJLNv33E8vxJZmRqOZ0Wgk65JpFD5MBpN5nMttKA3m9jzlq014eILem/R3dr6HnQYBvlzvnC9S3Ujqi2bzGFMKU/tL6eFcl+59gImvnvyrv7LAQ6tI4SLgKmGUbh7Pr7laF7jm8vOLK8/c9gsfNf7om6xi50BWWA/p115foFbFaLXKqvif09BSgi5h2nV0pr9yjQVvrquTbF6qJK1eJRbML3gF1O0Ebx+PxBf271rpZHj771Lp9fZXV5pYMAfQhXi3YJ8wFv53rfJQDcz/01S9mL4A9c5XsebzVaj63692udEpt52XQTQJS/Pqr7jsHzHcJ+zSpBHQB7OFFLnCEjOV131dGL3rBE+XBEN4fRqttKi2dER/3jeF1RtyBV45sVRqbY2qOpF/MXmsbzOkEtYrSjj58UXqOjWXVWl6vVCNVkUhqdh1NbaLq8L1kuov7a/R7tBS53hpKeWlUwpdLt/fur4by/UcQpiCPcFMgnkvYPTrX17x0Hc6YVfYsmV1QstigT29mw9McRleZaf4Bc/nyQy0asNYPZlgdW3a5Tf/BRZp/vWX+UKur4rHslNyju/7+LHKhsokFLGdXJuCO+yZdUqk4nFUXYzKqy5k1X2XFjLMCqBXWdVVVWcsM5PQrcYkNMM7vHrP7sfJ3ijGxw9fDiOAeM7g/4nwyeyLwkF8mxTyHIokHJgBe3pegN8BD4FEIMjsMI53QQof5uD/XMBjSXaqZD/YNgzPQFUblXhfCI/KgNqP49n3F0c/+cEC4AMCqJqawsZvmbi8sJcAx91um1n5NMvVKh2I5dgAWYWvYe/oyDW3tbGxUXdb3xXgrSqybqucXq9kt6EVGIqXK1tv/itLuxav1w9RqmljmW8V6K5ms2kDwV2zOym0Kba22it4VorAvxpiX7yGSWgKX8MciNfLrDcVtttST9V8DN/Gh05SFaNR+0OnJlZWxnCA1zsfHoxJ8Ad0esY7H10HfEEX25fiyhML1Bsd9Yfzk2N7KmBcYNLjnBgbXn8BGK24EeEMr01DAhh+Rp4pJuxZTLtSzbWVtT43aK26wRapW5TaT3KJXUoc5RMNSvzn3SSf/F6ShX1JkNxBZgJYNBmLcRU3lC+jo6rsRdVuU1PGziL0DQMRHRKl+U789RcK1vcFSzEN8xgSGEEJWDYAPcA4RNK92QziZNXrRJAFpYWWb8A0Tm1ty7AmAhu8cYiDzn8YVmQZXs2wsPTL6IpjA+jEo3lcKxI+IX0S5aVUgVjNr6QGsKQ71cWFi4pP/50r/vvs97Fh/bOy2tO3V7tEU1V6+pZKTwrBgWGkwUHzOyHjAihFHjNiKPRA6wm/Br1WhTkvtqCsgYKsIVJQHbUSt9FRJXSEbxqGJZh9S53gmm2v9VlHMRF2QkCe47E7JusgA1XOxXD+NKyQVTB2p7kDU1j19Razk4mkYbrwMr8LgGVztY7pH3Gnyo4Ad6F5h3sisZAI8VYVc1k+lqa7+JBV8fRQEDPZmJmJiFfRhkDOL5BWlMd47sZoEpiX+PQRRl9tSTFgV0yLQ3THeCSSgQ2xM/BAjzMxjia3JvtOaBhfCKPsAH83z35n5K1wctdges7FUZqVzEQUQ+aC3KMwpRiF/xQLDwLXG+E5/PvAc/kxPHyIPGONLnUx+NxTaGbAQx7xmN/wEXsyyZZuwKjwL8jo+yDrHeyf+2xlhQBiJbxtYf8QSBJEwHN9P94mgLuxtKrLLPeKeZRDobOe/MyHwYIhsvN3JjKw5SMHaOF6oUxZC6Up25WcXDrQlC9d/FPHPw3807zC7GEAVvfMfwgq6k5lOljJYwZfcOlhZQUKDMynOZ0m40HKM5dcX0lP8YQsWlYHGDTRdBk1upGP8upgPAqPYDG/7k7wkkBckxzPkzQWHUMsOgK8FOTop++TZJqCsM7IxvvAzJvtG884PTm/MHi8HQMHHyLMw+mGyV3iu+t7DQSV18pq8hM2hOAjWy2cwh05fJTx/kw48Ww2melIVNkilCrqJbi9lZU9m+wKbDKMV1bSfeU2TOOZBt31tHq+d7xrGlaQatAyGPrxAOToFxqVApEu6gaa6k1XpXUs64bFlzdXfqA31RsUCh4uZcao4GCAtn8YFdTMnr6G0bO9nU+VjKKuV1ex/1L2wRYmE4HFmah2Dm88uqwrCwGQugNAoS2tSINUSRp4jXIDDiiYqlvtKG+17OlFfsIcP6HGjwJXQE8H3tNB4AUpMyg+xVeY5yARGgfSvXacrtYsOyoYyDXLBSsBUQRSz51yHPVB6wSenjuB3fcFlC0PN/QDSLgFUwDe4HtqnFATg7ehoEQa64aTkS/UI2YOoEnCz6nwXfg5EQrpz+ypL3TDVuRUGWiYv8TBOb2Zo4lcWp2VkHlluibQ4MbD3GCWsbZmWBnsYDJPLHS6q9qOPINlZUALw4YO5nwR6Ym38Xwu+jGkn+XSQ9gOiKnnmPqb6ULrQ1S9FmTkVFqVkZ/t7R6ere6cHB/v7VwYjKjUWQe89kKKKyuB/RHa4QScTb0qYwwZjaqM2wgYIhsg4cHBMvEZXVfNYfTu8hgmUzqhPYOk3vzDcAxL3WSgsB2WnJhAfcSBKWx5I6It90WyDnQFsep8kKpXRdBc9NmxssQrGJFkwORrPtC9MBCwquLj8d/iQCNqZsXi1AmosUj4l75lYeNVA67FIMPGlcXYlkEpEYtlbylTF8FuVaUZMOPwV8QhCV2xBanrMveKUikjxwe11hGFmEUnrsBUDDaGlhl8SWK5TJz3oZn1u+MOyICNqiNOcdkH50MKGLFn4hVfFOVnysrJFKoCgw+c0cKGDO+6cDPpLgYsPC5xzcBOY41R4h99guhGHQHMhtXMxpcCPaUfSkb1ML00eESl19/lGk9De4WYQNUACwcvZvmCf02jznquQb7vuhdIBRTudn2VSc4aKzan8+MQQO9QHYiwQgE1cTc8YLe5tcBTtahGdBWig3huowJR+EWcOo3GF5Bdt2Fl0kLHUiVyd5M79K+b/gLPQBtRO3QEWSe98R+6tj+g/5JpxFudmNus4C32r0lYfL3I0qYVK6CwVAHWicCzacYSk7FEsukWoDctQZwCRfQk4bZZcr7VNW7U03paQ2TyFIuw+sJ095ry13Ho11mWOsS/jNe/rrhWUwlWiZcXfL5JHabLsQ9pMMakpDuapBsNlHQ9ZwYyW/j1RmdpTTcraloFiFD1jUz9bok/6PTncaK+VplQYMTrew2Albx3JO86z02XTNep4tl1cpD1ZZAhQFpmSfOMZuFoorKY18a8ktWFkh5GKvYOWaYcTsvBNXhosqQwxxSJvF3FfVuHa61XwynBYJF9AepsdxcgYC1VnLSJjQVYoQHmfNXH8c0YVtLKnTm4KUfdEoGuquSGLKMmwhCo+rpjYx1pabJBPkM9cHyY8T/w8+wJ1X8Q7/j6jKaX6zy+wsGqMYwouVfBSHFymKyiNZSVfKJuFHpikcS+nwWU9snp3vFiliIsd6FquiIGnxJ3xWIMFEPoHhemK2ItqKShUGjLa+9kbXdztS1ySg1nCL1n3hdtL2ugTafaFWU8g4/zEBkkQ7LWop9y6UtLaZRLIXLD0DdEEIJ9OW690VxvbbQ3DbRY/ROXLlrDUELsxLIXRyIkPhDd0rkaBFI10mYDoaTzt4fcP52c7+0aqekijd8KEeGtnDyFB19wtNXf8JlxJa4/IRf/mgHHdKLxh84G+jIn9WyrrhoAFaVtZmZCgwmT8dygimUIJ8hNiAe/Zv4TExnPxlLEwiTyK/vnVtpxtBt8Y5NvtHijjryNl4K7BL6xztstvrHB2wR++wr1jQZvtXlrk8DLM4E7OCWWvQmlq2EUV6jKFtMprINIU/jllQ2PoUhM/CQ869N3zjnTv2vgzFfE7/k+e0rjoagyjHI8YRrnO+eHXu1i7/zi88fjw4vPZ3u93d8MHrAsllJBV8vxUneCI40Je4rtoenyOg9gUQp38o4PIC4AE/9C0N6RoC0AbToaqOb53Y2WTr73KvkzIn/2Knnl8FVl5QYSPJaG5ppqDayswpCEHCBEdDT+2t6+b+YF6bKVhvramM9JvzXm0hoYj+VSmjRoi8CeIx9nqDuZOlAJn1vAGN/nEeuEJj3w+xxHrvMfydIvZ4cXexpPRe3okaybyXrv7OzkzKsdnezufT7f+wlG90RCoa8DeqNeRG8p9Azx+FwWTR1aCwK+QtVo/rdQNfa070e+881mjLj7vltvd95upYi9rmG/aoStvBH+CAqHoW51cBnxfSiI36+4qdieNWG2CsJsaI2899NPJ798PgLH//EI2vnRyafeT0qoIBbfh0n1pXJRZQEsCCEH21sGu7w1Nda9vLHvn5wd9S4+7/ROezuHF4d758TYvv/BjPjGq74Ip+Lx18YdY5IbR5PH694mJdB7ncCrqmxWqnIgzPby0YILzqvJ6/BUz6lWSWsjLy0lJumnycjfLp+yzVIXi2DU/E0Fv7W1yVZdcgW7e58+7/90cnoKJUes1DC+ucSeKrGXlui6epE7u7ASn0p8uwaqBVcnP8Y6qJ/9VD/Rcv1Ii99ue5XqaaIj3gFDrYMylMXmy3WdV5x5s76chnK+GpHY/mcEdNbd+nd5PbQ2vKzRYJT56Bf7hzofi5L/3EC3P8bQqpi5yba2Sl3TxckOr0XxPY5/LIPjVdZyNLSPb7fza3h8xEcIdm9FAm9jUdmI892AUtrCpL5K35u6vl2sx/YrLtSF/yiyq2szNUq1nhLF46tk2mUyUI00YUPRXa9zdzOl/Q0UnTLFjNec7jccD1UOGqy/K6qdJ4LMog5OtWReB3vgeU+O9w8PPp71Lg5PjtHOxgJwsI3IgAuCSd2ZtRxmkU/T+6FHn5LQlhISoOX3CN+FBFx9AYnuViIYZBxgen2RXk/TewIzGouMRprxSXZTGqVWmnNIGI6G4qQ5P1Mh6xoSvKR5D5TX0liDlzRvJjpUl8ds5PjYUc9b+1gz/1EbyjsgJtbJxPNY8hAbTS8n7L1Pe8cXn88vehcfzz8fn1wc7h/uZIIvaq4QoPFC85QCLikc5aMnEi57ygVmRi4Oa3PFNMU+ekRAvcI2hISe6vvznhus6tWgBWKhKucJjTy2T822y2ki0NL/Vo6xGjAUc7gchJNn5oC7Lv0HlJ8P2rNIVPqt3cPznc+Hx/snWQzqVMeg7fWXQljXeS2G3XQqY1hC5EXn22pojfKRxrBvaHT7ma629Q5839f7b0/XF2TpHa3yy2W2lKP2Hv20hHq77Wz5+9uR8GLhXQi9zuueBKLmoQDH3k2+f2qUifW9kTctjABAr4pUwnJ5m3reoNiJankwxyTDkcftgqa8F5qqu1EvqB5+eqi7+nKjqZ5UhK1ggK2mFpGimlU0eHFEzgssaiuCQ1NAasj78iPRgAyEHyq1o6MdoLK5rv7DnPpZh+SiQHtcN4fDvDmA+94K//orsMKtw0xwgjcaKDj6NKDCeoEtUJnWAChJfrbNoNv1N3mIf5lHb65Lr0Ce7/sDfu8LjEIC/uiHPDL7+uxFZGbL9x553x+DK96K7Tv7V+Q+9OUjtJNVP+yMhQV/SSqFT7udQcUCFFT7PQceH+VycvnplAdoAk73cWUFy37GfhGJyAtsDKtvGbVkAg9m3wqZZXB4S8QID3Ki1WeDqk+b+/Z8NAxjs88RiT0jj7H/pOYwvQb/GVdB7eOf48hr7DX5aQTPP0ReHZ5hi+4cePZcfu0ZBj9HsDCEP3ckbh7Lo0K8dy7IEaLSiUzuyZ+LADPO6O80oLRnfuNXe2bw+81N6Z1VvMIbDsepL5zAQnOscwCDGGYdfsv/NosJgOAQNcZHSwrdrOPISi/U5S79aFTkb4PX4RGY0Ytw2zJfT2r9y/kHbLcMrwZsWQ8EVQERMj5eKmGAKEu4SZ1XfVGXtvNm+fb/4+W7nPt/X+km/vKQOVfTemsJXcYHX01jcymN2TIt1ws0mlDTpnqDbJ2MAqwuYrqkiKZTKELKCZfTVxf6hjJ71WWSgTSlshDsYJkEEUyVCtTEEri6BgfkPi0TJoE1XUXvcAkcTdAra6I6Sro/L6OLpCH/oTIfkSl7Jpbkr8v8SCw3pK9sd4zHy4mAwX8lkYulRJqv2QrGMr/5+uI5IWOWVfooKA88p5hHRnUxfd1spM99gd+L8HdBIkdhlhg4xMTABOILLOxn4Tvwsy9/zuVPGNLPKX7Z7yP4cUQf7SBJPfwAD0N8SHtFRgX/UV3uZEqjmmlQ+kyEiYzj3/STUpyu48N6IcUdkZMGcmr5askl5F/DGy2nUKXBATlhPJ/vikQYHPJTUH6PzF4z1umwpwBXZUWmGkYH8nswvqEI3vnXBMvTsVkacZ7c0QXsc1x4Ow5BCQjLF6BYfVMNADDPspA/H3lYDEsDiCJRtH5hYTEEkjIwDlFGtEIY7wXtBvTJNdque06nD1mR5UNgFFYaWEA2pBQThvipNVxI9KMZksYxPlMC3Fh/h6aTqSoeR1JyoSa3UCp3uOBZ8IxrsZ0OFatNfklnsrnBF+PFUPVTcrDofQtBGIFCTNvUabo8QBaJJvL/Y4l/GdP2QbyOpypMS0NknZpLWFCgtGdKvcBuKhT+ttt2PBfKlv6gTzB9zBS83QY+G1rFRaGDBnUhz8z79yq+LLhS2c80j5kTFXsifupL+AmokEByIMt2uJ68vGxUuEtF3ovSsgM5NhLUFpCBjWoGGswSRGKUG1fQkpVF+1f7sbJpecwqf4BVq10ajo4r3YMc/xTw6pvkRRbA3YZjhSkGjItwhTINj/pFzDajjN9KGZsy46KU4Toy52M5x2WyFOEH0iG5LZkyCLOUtMCoXIcU+1Nfeb76uuwm7lgHlolLLNTFYlEODZoMLrMYJ9/HOm13s96VjEjww9Eo7osRXcVWk6tMajiqNbiEKmMOwjzmw2yYxGXUgSo0XWRL88vgq4YCp988t5DmbkBinRKBM5UK1cyWAqDasun6NA3YoMUYRloWb6cQbQVBneTmImNTQz09OT4wsqwNuZSwbFYC132c78H0/c5HWABi8JKdpObvZrxupiQbcunkq6aqCPFIKXiTYbnpZOdu76JnkD9UjSPMZpmiFRf08fdEnJ8rAueWjpThm3Z9+50DI+JO2gHV5HXMuFgqg8phNzycVaUO6yzuD+d4nEIy6fdHce1aDEd3s9hgz2qvcENN9JKY3ErR9z6cnF1Uy5y6c0XLTWmtKwWnam2TWuvtr9SB22QwB7yNn1Fw7BZV5PN+IWRwYUgHuhuU/YT6WvB552gXFQgi7wMgR5mZIe/To6pCXXEsraZZ5jhzFSWf5jaVT8uKpM9fvAYAtDfSJBDW+ca+23VhEKINaoEEDDI304hAVQHL0D88KWdEppNN4wHfsLUrbbLKGBy522Cf3+NHlEdFMdb2fRcWAAXasjAegR/nY4iKx13cTzQcRcdQpbmKGcaWpWIJPftyfAVClX1ZX6anJx/swBmaCXyPrUzf7tt4GgVe5QxJHiq1YySzu9hQ4SHKhK401ZLAPdD2aoitTZwSM3yVpSUzkkLih9kqRGBAJKCtAM9rhTUbXf1d2QcKIvGfPuFZHF74LLdFliDVDsnk0vj/DUvPhS2TNh5pdOUXU++RZCe67Nu4E2Z0jEDFPb/b+Wy5VjphXj45lXM+cTvxLvMpPLlSNhHpy7OE3Esoytti1TZTuTlY2AMxP3kYwzhjGs+SLyBUkBrKOjsYA2oPaabcoWuFelNm1nvfeG8JqLr13nhftRAtrGDl5f3wmC3sw1Rqh7tpxvvugyevK5vMzuNkS3utoSh8Y4FibAFTGgnL6K4twLfUiyJlpN7NKBRh8KijbaQGvkriijDQsvz3JW5ALJH1HhjB6uA+a/sshj4fx1qnYgYQeDWAmoUOgUHh7Y0junEzAwQGMM/EzJ48Y3zLsIhY+ooVW+QBWEUhIClIntMxfx/PDhWFCkhbA0PKebyicHA2ciklDTJ7RklQC7CHc/o1xyzbAJ/ujFENry9Xq+oaMazAHOPmGMuAOuCTTS24oFxD7WUvI6eYS9AQo2gZIN1qka5VqutZFY1yKRGEfLWU1iqVZND8PTjmf/Nc/inbr/zciezvfdzgDA/z4pBvvBho42i6j4MLRLDn5vvu9p+3o1o6n+Ebru0YtVhe+wVwd8n1atvY3uruje/jERhzDaDHc+/P+dCnbX3e2trDw4P90LAns/5a3XHcNdirex4O4luxqlyakWFFr2MpYJGBzil9bkP6fCKmiAPVRrTmmtNeE9KsgV+F+lBCjW6Ta4kXxLdSZmuu/LWBqxRxCXONNWd9DUtejVMpGLX3+DFmq/s9feLBFtUjgWOr4Zr0Qx6zJ7nBdTswI45K4OmW0vD5mfI9Exe63ES4GDzbS07Qwj7Q2xoXHEghRhWpluNCFpIcMzSHJD+2BHVDEjxh3l6g56nN4rmDlIw1Q/npVZocEJ7QZ3Qslyj9EuaNbYTGxhM+4DNJd4p9SQ/+dJLFauuBqiduLpyCW0y8w/n8Lo4uJjfxeJ6qMXndAkAxTn0NooR5opQ/jzO0aBLO7YmYD+eruIs0RVOW467JLHxz3FXIwP/j8A4vMlqFBzw2EdoDGcgWsJjuPj9PQYjXs3QLOeZTwgX0U1vfWr663nc1QVKrU3n5FDLxj49pFhXSXdNK01iLoxxzeDCcpxDLKdD7Daz33TU9CfPVEZQ1oP7vIcx/qAIuIBH74Bn6Oa1g8JtlxteW13LtNd2s5e1rCy0S+2K8FKqWXvH1Fp8B7IWpctYQay0a9qF0Y23rvdofgDsJwICX9bW3npj1wVskWHV6WdqJQDs0TiH4wyPKeuGNgY0x8I2X2NPBPUJGLOAI8JZ4UTrdEFr22m48GkJ38OUIY3miBAyUnfFrZNKL34MYqqWcY1eA1UKlI/sTVpveylFHOaQAvCO54ftwl9D/zbJqCKank6RhfwLQ1OKgt3Yha7MJ6FSMJ+Mvt5O7eS5sWluUAAGu2WfWFJuP6gM+TKIvW93Yy2qOL0qaNRRnSYjvrQCCP4Q7niTD6wLv761RLnBT5rKAhpSeTFHlAJc6BwaGAyaJVLK3pjpyaANjGni+l24zfquGlb+9zRD/tGE0arynfuHXYr/Ant5uQx/H8//xVjRillG2Ia3may8rMfh7SpTa+pTT1g0fyZCx/3XkNqEDFuM5eC5wF8n/SE0B1ycwkhNYrQt55MvW6UXLsR3HOQf2y7nkIcq6lQd8qfDnRsZIiY8hmSnIz3ZnHrbz92nzmtHIWQ4R1SBogAPNGwaUbooDzQGOy2FT/WAxLv/82Sgn4mBdMXE5uIKD7ZQBaFvyMYdVHhMgcfBv9XhVWGlFBhgl6x6McD5924AUcf/+gJRG8TOs9t8Zk84WY9IpjEmn3Zkak04ti4nysHJ2OU3HpPD04pi0CjnFXIIm3jQmTfWixqGlqpHaqXayZvheqpwiIrWCNcpONQNes0JUnco4yxFufGGZaUqCKUwyeuMb0hX2rZtqZzjiTjr6OSv3P7QiXWtpb/VtO7NYJPH/Kve23LXdT4ZRzanou/qgtHHmvfoV3quP3isgKyLoPllEABM1SE2laJ0ekYSkZRqXvJDaz8vDUfb0dlXLg5dJWv+n6qCk5dqapgSlKa3xPQalGSj2hEBv1cNBnHT/TwkvCl+Kl8T+MayY+OOJWqxtGHxGjXCGDTBk2beQ8HJ2xUq9AKZqfRzhYNJAefIZtVtIQ++vPPhs4fLLgAWoyL4OiNEBDkWI1WdKXDKlJG0IFLxGm71IuP/XPAdlJ4xSx5ElbDA5/XhRDiTluFICGRKo0rmOM51chH+vRcdwVHDKOxRAz/+O/vX9f8+mDdLPZKMmpN8sXqO2VqHL95qb6BW98zdr8hTcx/8psaREFMu364+MQL3tyCsaoMmSw6vI6ZIWKptvmEZGeoB0oy0Xk5cC0FdX/fu9+toYdCDHpM0sCsMA+Jo6kBc3rvi+3x9NAjHqpMe2xkxl04f6zrPBmMlY4BMhcwbTtMNZbOIsZASTRczePTk6xS/1M8bkQen7sHoiHReE3MA6rgGwsTiPL8NQVLOEr6FAlYt8xEOzvY9/lUdhm8bRMJxN5pPrxIZvUUCTvpGJ+ZcxLjOAR9zDAzm4njTwo+dnKSX8AvOMqyQC7YqH+YcvF6KPH3hNQ9qGwfDg3X5nDEfaLocVngbNOqiZsfrgjX01dd+4JTLqjisWZESWpSYU9Gz6yGgfXCb6uoFEX21BdRksZQtNi1jqDID9wQvsI6TG/CDHvNMdlJmm75F6OiAv+OR9bR7j5OMF9FQGA5tLkVc3CL2f2wG7yGSMQ73tozgZTCK/Dy+hL8xCYfrJRdKGZ5kNF07mwpVZuAGLrAzPJJZH33KsHSxwLi+w2Csdr4OCFlDf/cCEcrsC+J/5gqnvYvYnSJnKg46mvuCYYAo+kwv+JLTDFgXI+AnExG/4NP3SeLNtxuaAC2KL0nlkukxtjwtgrifrZtQnEvw8kEkKj1EK7bKv2R7YD9B7mH1enb/48ElLkDFgC00BDzG8Xl7xAbDyzDydu5bTyPjTF4NkdeIj3mPZKcEj1gfcgHAphzCVZ1BnPvz1l4E+MasbruVUdVMEZOHNHIls5dMBBrsx1BGP1Z8zoJy9XB5cLT2cf6zQFCTTJtXUzJmeDyulQNtyZU8hXXL0Cn4lMmC+qL0bHr+iPQHqilF7Sg8R6GHAe6Q8lBaXQpTK4cIE3RV2TQ7suViFHgR/t8CsD+mMcnj4cXEwugnUAkpSR8GCuf9QOKEc1ePothGrrQPSOrCoayiqTrN6PT/MaB34QK1jfAem3QOS0HQwBTj2e7m1SaxzYPYWlb/hPX7Ax/we2iqUf9m78p/UOeGeNLCDbfz1DuyQB94BT48/Hz9jE70HxmUNwVU2HTwDgg4sna6skAWPV1aa9Lttpox/F6bwKEgekWSxZJqCBxFhalZpmTNiLD1p/QZfOsLUBHSD8g9o4ZnysXiuKXwXxf0Q24H9c4BlEAD80GHa8JuIPhSGNvIYwM++mZK4zFCvmG4iyE6sVpVEf/1FtYsL5OUO0Yw6lHYZZU3xyo84MsueAeAoYjwrybIKdRpley/izBlgoYYDDSMEcz4j10uToywGbQMLsuzF0eFQtcAMZUORhn8YQVnD62E8A1nHWnHjv18cOXqyUAgWMLkjY45dcLrKVIlQOJlF5EY6i7Vuqq3jnugClH9ZSLhKz4FH3wOeUmSH68PjvyZ4286CNpFMAoOZPThgnnkP0DFPHmxMkykpkQP29Jz6YtWP0XVGDuNOdwrmX99sbrY26pvrW1PGnkb+k7yeNI3DPVE4ZILu/D6PoSOe4XqEfP56ml/OaaU5J9fX8zjJ520oqjQEKeO2s1LvY1xNkM/dZFyyc0zX3+QzXQdwx0kJyXVVulpuWMivp2WCgdDVFDi48JTFmO5e4ztzarWc7yKMvTDzcTKOZeVMhluV5Hy92+jU3a0pzdOP7Iyi7CZyJYLwOwBBPEG07PfEpXq9gozdeB76fROS8vLnaYosmmtl5MhBnKgTV4uW6XxH4mXEntFMXNmgjidHk1kszXrOXmmqlzF1EdTaVOuWrTBN1LujvhrjYmHrvp8tIK034C0EtG3jcAwLcmGIhLUwPDoRoneJ5/JfeQfyt4PYbYrA3A1H4qWEjF4feKs9oPFHkz5EhHfCDPFKDfnQUA919eDCg7GawrVU6jql2rZdk3c0RnKr/8A+BxY2JAvrxAEyqArfERj6jHEFFIYJxOdmPQPT2IWWBxWg0lEWlFpfVKI2U1dk49XcNby3uwZXc9fm8RwpQ/3mtRgsNxgN54M4smVReSJnL5O4Ho4lbg2X9mBwncBwnCjPgPRkpsjWq3nDFe+rZ4t7Al7mrVHmrUzibbw9I9mWZkPCJ3Wm179hcfLAQ1I7nXKIhsAD34C7mVAJXFOHCckPwEhkMJ45ReBabBs9mEAADmMYnkYw2sDDR4HDEbQG4oguKoIc4Jum8MAAIOtahLFteBmpekYKJikCWGL/7aQcInU+nUyu386QsS8Bae7nNXBlwZqQU0vdNtTirtp0MhqGXwDrfnKDKjuf3Ma1CQysoK7jOIElZDe1ZCaur4dhzbz4lVGhoMTpFLXo1f8ewbMSwWWEVG1QqdToyo0RnmT91EMjs1gyxJlc14bHl6lWALY5ltZL9HWijboi2lBE3TzRvd6OPKvMq4kERgxTuj0cuhRgfQ4Qce0BBsdx7Rjghukp1L/DNrTriM6iHs5r6rrJFwpvLqnRTjxDJx6KJIbKpLLOVju3yMhwSR76egCidimAmwjMhBqaamNtxvAolCGGuLWLQVyby9vGb8WXWhDXwNTjGdYPDBXU05DmezypBZNJQoP4W3ABAnJkG0ln9MZ9RQfmH27upmgB08kDkCL7nN1NE0BZl22BAImg2oMFeRt63vVwdvsgQKJ0jSlUwhRJbRQL0Cbe27pz+hHFOaWVG6MvtfhPMCJkggHL2SYf2fHSSky83027ECapDFJVOAoRRKRFojRa8mMcVY2yOJT3aCt4dxFRzmVgG0csiykxk7r4FML/Q5jFNMZLKflAFIPEElY+ZtSnWg4sAzReCR/4T727aJj0ptPDXe+DjCsJSr7SEQ3jYTIUSVW82KQjmRUF/9MlvihyV5BFpCDddZzv9DwrzdKgIMRR8OjeMwB5SoGd44KmqYqRqwbj62urW7xl9XFHHP503Cpigf1jPAtimK9EL3E4ljdo+XgtKhAuFLWZL2pfmCJ/TL7rQEGIRg+delWJOgWjO9z6CafoumvDLQPw1lmn8TVIP346qu3KnWy108ks0fB7xHwf40OMbv186NvD0HdUHfp2+pbfBLSjHeQJ2waWnhdBH4eUvXIaoB3HSTr00JVAxyX1iHZvCeLen1UImI4R78D+/0JzuRVxhGOddP4mYBhaoMFf4IFO0uBpV9zWVO1GG9h3ganeLJcnaRw8LYTAU9zOLid0cRs2xNL+gYCf6fWf/qX6HoEObYTLNdXq4XB4C6uHxW2yKj9VwIvBX1sRLZHgr0KqA9IrRQync62Iqw7O//iX+HstfAd+5vLnMPBd+PmU+hG5ZsvhU8rcD/RN7yqg/06bXrKQEPx5gG0PsZaI7zeQAaU9Y2FR8UiK3Lwjwv8SyukQRtkZtLyb72c8KwPkj0MPfAUDfs7QO5CFhTyWC5Gkf81IZ/lp8ZJsKMlKlQKSIjhaQu8xeAs9R6N4XykGSfWTJgCt+v1F9aOs+jHQRURF904sYfXsbUQzgr9UMCopnr+VzYymWGIDku7Hr9b/wP4C06tsYQVZCR+CQhGS9LXUlwGR1edfhvtDdIkwG3s97N/JYS+MpHBqxGBA/Xs8koTrZGTdVc1epyIZjMHRZ18E1eop9ZNx/MOCYU3Kc9HFlrltUuuyOFbiQsonLBjdYGF2AZAYqClbNGSa2ITGqm66TEu4yko/LIhLGeO1sLQJUxA7qJPEghBPIPNiNeLrSnu5MZ9wftILOP7MvZD/HHgRT6cfPYcHHlBLRN+L+VHk9Rf2t1+8UgtjS/WNSmrSYGrkQk4XvLIlOiXIncOjEqRbCXl4el6CrAMksvMlyPGj31QtbNgHLcUB7/lJS+iaMWVEX6JCs5C7+CJGZfyUXy+AejgO6QlzZ7nzRwA6JEEVt5+hpdD2M8yL4kKekJKjmZRT6Ipxyeov6YSKwbNDDyjfQEVLOsH/Y+86uBPXlfBf2Xd72ZLyKq8SSkIKsDEpt+YYW4A3RvZ1SWBz9r8/jUdG4xghG/LeabftYhl9Mxp9qjMSrKiZGakZxyxavRBQlrzYKN/L+ySL5WwJbc3SxIWNLj30h+exNFXAXbcJOQB34LvZtVgN+3WfPeLHsdzs5CMInfPgm435N589TmMG6cLP7syYc8/c1whjuXg/Iz51bEdezdhDvxxcJZTpeu/UqykMnGz6PgLHWWWdrkBt7MPdGqB5sT87ZslKW8IBuw6Xrpsb2PSDW6fKAasGn36sDV6DUbdFcDoumoVswSxHscglFGIwqII+X9Qv7Drm3M0zP9Gdm87nS1VapqtxmGafZzRswXVr8FHV7pTpWx3JmZ8jpPfOPclEtrKOjPwZssgL3Mb4k2wt6biiDNuVa1oBLjAjPHWbFVFCzVipSteDWSyRT869QIO/UDuBaQkh3I2Fwl1fjGUwh+Cun91l4WZSJkUp6yV0FmEQJXmC5U25naQR2AU+e3x6wWDH2ovnqo48toaR2gJInDO2vLCTbPN4DTgu5l+r74ry4K9QDiZkYwkG88KjKyYc2O9W0WmYbeBdpj5D1Uii0KkDISCgRZbMXNyFGOcbEEI0fhV0VYLvdxR8lPr3Wwv3HZNw0cYi7yOdKWK3ADsLTcfv8CRadhZCgXZ2yFUeywVFMCE/tStUoZsSludmHQXcSzhk0dzLNtpFhyHo789j6C3OsGnOiYpGzVTsCtHPY89a0v6n1+cIHhTLb8SHcaZUcmw3QO+LfN4TO5o+14R/FbqgvE7E62dWHj+3slOyslu2MsutPF1ZOaQKm9UEf8lDQc2CHfoIGtW1LjDbnXu8UPYNlFqpz2uR5PiZmGwgGCCST5tjfSi8rIuMLPPt8Pos0UL+pp8i6g0LcNhH4DhFSSXTwZ5DWw4xD+O6LUMvAijxXoCg9kyvfX4bCjK2hW42KWLX4TcoyjVKpQUbBrEc1OQn6EXVeBbuDn1ixzMdfLwtPHYmEjOvEkwsSuBUQi31O7YzCCEfJWi0fRVbzyDFwzXjbhDBPIXYqulPBQeT2ZzMrzaY6cGLAj6HUASWMAeJm4A7BZz6KBb9Mm02YTxmqzEdPyhLJTsIwbZxHfLLIIVkMmrn8A+bLJfMWMSBMVEigWNU/dzj98MoP80pYAsJpE0oYz1qy3HC0siLE88ZZo5cdM8CebLEOGuGMUvwMCm2Oqgo+ozfVKVaaOiVD1XETMiqVsSykA7bb9nODKlL+LXUKa9BtDSIZft/1CLLswZyBQEhOv4q/kQArYlFUagtfa1S3B07uEQzhEsJ2rXP47iidscsd7bpCiwmQAuyfmkc/m1PLVqarK4crZhhgGvNUdBnC8Lqo/JcWickh2iaZF0ED6w5jgM/zda7+G1cY6ul0oNTiTdK764XxVIyVoWkSloNqBsx9pFhPeJnxbb2BjsP07HvOdlSigsw6KwKs/rW5TkMEZEvCo6BOljSWNn4rAhfERw7DQF/7sWJfvXe2QocNCerOgFPno78YKwEHG8tYBSl0AgvgyCpKKu7tSzxRgCLP4uAPT29TaDHjAO52fCsZe3vyS4FZQxtD3je7vdxRXEFNFPUPn1hoZ0FFZuv2Ml4/rqf+j4kM1qpMrfS68RIc4NWUgfURsm3X4tH3Dogw6W2WZJwsZoT1bxWz1kt7BGs47hAsDA4TSDLT8U53cLZVG8Y8IaTsAL1LkJ4ZGAWfNvjkwB2i90DWIR99i1eT/oakrvZrybiy2QZqpcwRcFk2BxaJcPKAaO78aUtnlcvSV2LOiArXLK2bfVh6+JSzgK2KyB9QbdVnkaRN51mXf4o5Zz5596EwVCLuvriKfGIATqLhHGXuTDHEFrmdhNa5j/7mCeBzhbqfKGra42+LT+IGX3VWoV36TvRvlaIxZI0bHK37ABEacF87iVI2FiPf7st/hUPo+DBk6wd5p9hHy9wCXVH2woY2hFM8agcbSmuthSCI1nXt+PZDbOjQZqIgiSmOhlsKw1pRm2F8z7YcZNfVlKut5UiXl90jhayqQF4/lGB32zocM3wo3NraJ0BcK8NM7ihpXrXIUU2o5LlJ7ULbHwWplQZtrU19lXqUaDLrYEIHY8gdlDoKlpaGHA4IEkkvH9pM1wfUAeWDr287kVQucwgED9q6KUDsSiI/ETWWpptLD0ebl3QtehTH+Nve3mIsKBW1j4HHNYhjT+Ird4rAM9dlk1nkxWGEM+ZXTQrWUsTwA7XtowhEIBP6mpoUShcf6zfhoSiW0vuzKKAr9s3Ow8eRe8uKtZZrr6aibvJxaHjTOspMIuBwpx409k6OSN7Dwa9+X5jLP48yKZY0j/QWl8gGJ1l7B4DWvJtJkBu4KQwM3srUqNlfjnVN595PEyTnzjcf+3u7//SkL7pfOAtLn+lZ/pWunsnekrdsPFV74X2EtvPzHI0FjJcF+Jr1M7MEzzm212Np7u7UF6zhZGnn5ENm7u7KL/xIPIaJ2+7GAFCAUSUTzY//wwSX+Wpr/Y+EywhX8vF98CIa4Ti8VSUCSaOQ9thVGIZSkiWp7kzBZz9v8mKIPz/LAsFF2ejIQ68UVQxxxFBuypvMZBbTgqdg4N8csWdaBkWXh3KV5bVa4vHPfk4FDUDwfUiaT9Pss5g9BrOIjtmIv2PmC7iFzqdzl/3DvYXBSthrEPL9xgn20QytUlSkGo/yCiVidbDA2zArmoDIfLkhr2h/sY6lZ2yvm5BWeVuH080nbYhHEz53HsjvAR305zQ2VkK9ClmOVNNCwfyir4NgmJ3bdwTs4h1y0q8AG6lwxOOKEKMTBqxeeiDYLWTQsciIuQoCKS1ZKULdCwFvBlELosAP+svwDI/IiPPCdwztMIwoOAvg2zhU5LX+PofGPQs79re4q712nev/OPd6qqV8r2EO+jxD3KXDKLUvv79X/UDnddUIxSxcK8NuY5xW8X+seHHKwo98itQ5lWhCb7a+8c78mMWxcsh11SBuCUI+ALO8y9s+EkajETZ0FhaduRmq0rOM2iYTAFzVwmwDoA05g64ahYfipBlwF4M02dRiHFGXzk4jYIWTBRUV3Gvx5nZgh1xdShfC9W1uXQfhYxlizIWw6m97FEBXGiaujjyQDd5msOKnZezfyhj9uBnEA/zCTrX6nkhpNi4hdBmsi+AaKAsXUYGETeUplY1SGqmLN0q+EC6WVW7MYXWwdKVNvWl1yoe+nbwMXf10DoJa6ENuO9xhYaPCuy3WmDvU4/FjkLDZwKX1rCSZT8wecOvQCHmSuqZWjTI9ThRTTbsNPo+ag05nC1jz7H9LvRI1dvuwggIjk57WgOy72ghgfil2YGySfZeGabUVjCrKwW/xDj8+zgMVZoK5XFC9r8fhFsRw5tzfDuOIemzf61TI89Vyo9ZJBPw27VHamhcuIJZt1oer4bv7oamjcRMw9Bf1uviWxRUB1jq3JdFVbT5TN36x4o4hg69WRHG2JV3zNbY1Im3zdkN3fdR5TreqePubxKDP0AdRPWIdEYh18OVaHRcVEOTy0SiEzOKmUI9M0gVAl2YraCnz7kps4E8pxVrdSfqDDRK4i62NnBlqNWNZN1Vt/d6IfV9v0ZpP2yQZjFeuwVdU7wyVrn5XGo5K7OY245lgDA3nJERwdxqbvUlNzSZG31Oc3u5MlfgjhT5UW+c3DFi+xj4Vj9Sz56uLzs5xHXGWNiEnxMipZ5NNaUmWesRlxkVKVH3C41hSCYzecdTE4iZvo4RowqBp2YLaCk8MeQ1kNitUJ07h2PrZay2jOtRxqeIa9FKlPE0NUUymSnzwQhipsy9EaMKZbjZAlrKzA15DZQZOIbs/3+fICq2KFq2eH2BjeenT4I4ObJj5maedrJZDo/gZJaHMsCrpDxT8siZ9EDjF9RhpwunH3CHFc+bNdxyvBuDUy1eYvurs3NwLOcet4HKypvVBk8khMWC3B4XlvYgLgVTaIhVLz5n9oSmjUXas/hGEuK63pBV9AHTvIgty9ZzS9ZTnq/lVta7CqeR7TL0r40C0AXsJ3VYG7FY0kFZ7bGoQwX5bbxBC+XL8xEQHqX3iR1RGURCcXOZhsSXowhJU/64BRz8BW2aMx/iLghas2iA+ng3wshQeEiSMdCq6K6r0An0IBTMJ+0Yjv5BmiymHOpJXlufGWP9SW4c46sJZtzNklpYgavPDffPompjYJhol7l/eiwDuKnJDKWSj0SzTtXcQVjO3CqPyjqAnUb/4w1yaDDTiy3jukWBZnF0walpdycbCmE5EWNcHw4nm10+rSGPUAjgRnbf2wO7ZHCLXNxPyUmn3ibBzOkNXqiWknVdPu3CRqOhMN9iWRh7spQ8vtbjSTGS2KaRw2OMFHbyjr/NYyudTLyFOqHcLU4sVvecLMY/2b/8W/4tbsT7L1lVlvCsDQPvwvO/8GVPuhoQ4AZs1zbZXnyQXr5jGYqTfmuY8aKRRkJdlb6rQNZqW2AjiN/+KS+Fm+qanCu+fV0KqTxZJYZ51bfNpVDaB0uieRbftnHBTQyyCcaHUTdUfNut2IhTREdhINX5vvi2vxReVAOFVqqOrLE4PcTjxE3IAQy2H9KdnZX+Geqe6mtoQVJTfDvGmN1kjLaemiDdzYUbWSe1Kr6dLoUwZpC18HgOKchOOoQf957XqBJs07pGeAGh5fvuRpPjI+iBpeCRCX5Ueur64Ly20AV8sx6rxBgRpKQadH39/xlZYqqnp6Db1lEk9h9ErScV8UO61JAdpYdiQMcEoWxk8XhaLot/KG4P2vdMnRcK62ca1SvXqzqrJ5MOdzGFDjRkJvgz+M0mr+pYkV2i3EDwKB5hkKNkX9Q935SpFZPvg38aAgyt8ZGUX3K9VHdzWHc0fW1mO22OKyxNEE1j2ZubU7Zcj0KquQKb85tNVodsId7S3xM5HyZFD0M1eOBf60nJninWbabZWH2T8RgYF+UXPvLb94t09RdOBJ5J93IkIPtMg2roAShTa4RF5J4s4EytIj8KdwUIqe0gXB/uVnqaU02PmqhhAefs+DFvuF35yTjZKeEnSyChG7qMdhSEYt+sydrl4vHbajsKDzxveeNWHKIrWAW2GEehYMXFczuIr7VSVL+Ve3d4g73WAfueIJACiyx3pGhuUqliAbpU+N0p8dkY2p1xFlkv22gqyih0dnRiIx0KmxrEaLQ5mE0ZT0KS79peg2zThAuVcMTkh400jUFN0fmR3ZfvbKVjV5oYLdOrpZaEMJwl1cF+UgxvdJbbHthAjO5ypziHcNPqzFQQO4wMIqvzdAqiHgIpb58xf5Mj5pHcOPICN73qGDsBm9LwS4sgnW7YOugutFa/iEUdoNlc5bI1XOnpGP9K+FKwnMoEA2MoExlrxtgu1S+u4eLBUnXPzJ6nCwhbzW2+zhjQh7wMCTrmXSu1lT7de0qjs8XYSgvPWSCWGuhFPTjsY/mectPb2RVHfv8FYLqWbE5Geao10rO7GTnM4xfZiCU2WuH8yJyQrcnx/FQOWIgjSVpuifJ84PdQ+HzrgkmTH4yMYcrXvAGqBlktfRuyZDB9/pgysetLnoNOT7YmxwBC6oVt7sJG1wB1y8UgN/9NTW0/XqvMb9cmWjehoHxfqKa2Jcvt7XrExSxPhDF86Ik29f2/hF0Hd+M2DP4r7J4ZkjMfO+OM3sh4cfe2RV6jF9nyoyTfpf3zBfCJNCXL3T3jA0EQpCAKJEHqXcjlrr1/uTaPTPNnvYn6Kvuw+PSXsMP8l98ooy1ug+AM+dXSZnwm1ezqmzKkNLbz0j1JpuB2M0PxpGSPb1FYQ39Sdch/LOUa+bjsFv9UEXdUClT1wHnT3yyty+0iI/J0oZqFs1m5so6F+MzGu/q7mEzlnNkxefW4R8/m3bM9SqqujMSstpWANjuzkkpu42GBtq6JuZmB/3/r93naC+u28d5N9lJVOvXd5Ew92qeeBpLlRPh4Do600GrBOZ05X3pf1io3thys86YE6M1gJD8A9+SlzwL94RnN2j9S97fXJMG5RqIiESPng16VBSUdtGqeV5IjXX249CtwFfXztFbVA8uqpnP6jyzqkjFW6wLWBBm4tQN3dH0k0ml8ES589CUU0lbvVssip/vPNG0Dv+qNw+t29MlJgKI9crCr5cOUZYSe6LHQUDKqtlWtkYNqSkJCUz6sPuqxa8l1Po13jIO2Az4ykB/QFcdSNPem31CvsvgbTN+Nn22DkHRCuqBX//fSeT2i5BHoEyfX6qyp+tQXfmRFg6PHcjGfWWNszLI3D/uI/qPgOQ4UqaqW38hr/sCFtESqGTOBZ7iMpSvuAOTVQBG0thB62U+G/nr6aHeapVpJpBZ9P8Qoj5DvZc2BL5ikdGpecmYL/Oy1jrqKj1AafVmUy+XTNsNiMMnXpiiPxwxEl88746snozPAv552Rri+ZcV0m21dh/VuttOj5q/lJeHTQk/QxKjD5qVpCusBUdI/LoDW0gJBksnjudVfG/HeGZe7dCVJXE4XtoAkMl/2GBN82bi2c5evrJoR57IgTq9K3h5OJddOAjjoAH60tSMiUjGupSH74Y9dzaPWg73dZqtmPW29KhlwPWlm/s/Qwv8Cu1hbmbY5T5Hd5acshwC5nJLFypIHqh7j/9B2LA5amt7ej+A7A0NloAP5qkf2zJodsw6bqa8vQp82lb5yZbPsgBdvvHnX6WCou2qiPnl7slqzYmqs9kenVnw7RPU6J9+7NvrevDNenu3dbg6diHg95C3CNQP62d31M5UhpCpekPSX/9M4cCRMfk/GEwATenXvTb6egCtU90pGYpUby0D86PAS0Odvax1FdLX+hnpP3m6cq7LW7SUrY2hHrqJ0pLGWDHUK6jtPVRJ317g9x6eEVJJWvk+EWD3OXdbktTpzllyS021ISXFsS+PMf6E49uTmcB7h3YuzOvri2bdaKvjuRofDS4hcBZ230KFt2xKKGSoOgpMOfBZTCJq+X5hYzLVGJQrDqGfDyef/cHSmrJU4UmskSDXBXSISjrpvFhyplBgR5V4kYxtEVyZNtZQD6W9j0vg9iTqKLh8RFRF1uR/fIt4S9ZbvAERberZZg+l+JDI0D9GW2OJESQMFdedVjTct4iyho/sYNbIzJBBo6XVvBFIjuyMiwo75vJyzBfoqetsj5kIfX4ix0FoEYioy1aCZwM6zhRItKsROEM9VZ+RK+b2IgIlfCw+cyRF/j8QRZd+PgiU9jLeEFtajVAuPEsn5RlYxLXkUk69LI28mQQ5iBBn5ABwK4McouZUH5S+xWp8Qg7pHsQwJBwuZ7EYHtkFQiBtD9AkAJDZQ0UIhkWrhON3KARWZKdkHU5tTRfGiY4c1ND9JBjn7QsGbgpfGgUyEjaL5gdeLY5k+O1Q4ktixZ3IQcVxPqTonAjo8ZFo5+q/47D9fnaTkIgbrKtKkaqsio+KV2O4s74og21L98Aaqew6SGWEgsnO7EKmwEqjqEo9K8DmBl4M7i+XwoDuWAWkduz1rFNT6bilIsomc0zxHsHQTGz9lhRVwFIFotpAPpGE4ahQyuCUnrAF9A96rdpGDMLuwRqCkB0m+C0BpC2G/BWijloZ5KohSbflySPohkAHhR0Bi2ccgdUSfiGcIAmBWQKddiF4MAJJ9AJHoJAEpFs1j9fubsfKr3OoSVxmNxHtW7IXJbn0/bISebNBRmtD0YjTkn5UsZgnDPhXvc+CAvR+l4EqH5PgmgGW4KjQcHAeDHEgZ3LIcDrLc47taeCTGI3Os9539S9MsS2yEBztNGf12fPfsTkXHFDxGbeV1dtlZH4jUNNyI0yWPqEfoQrohMdQOTqnnDeXJHLS8Wx1tlhixUldye6YK77m6dvmsqW1gYu08ekFeOHSAgOkavLzbQKMXqCyQ87Bfv0G5+q8L62pFc+sqo3qtEXri6fSV00VSvHXj4QJgFAOXrvzbchWHXMX4TCE9IPy1kJOYDOcMIBUAFoz4RzE55j8QINwHFCwv4KGAIVVh1fqbgB/1cLzJonbJixrTBv8WF6WAJRsYNAOabpbMotrF5YZZR3ukGcIFTQZQiAeeDuDh8U/FndJoUW0yTCWZspyS1TdCE6B4ClEgBSl6dsWTRkJgHgEOAExs5MPpij94NSZR0MVLFySJEV8JoBRQ8HGYSAAbAcMuCB6nWWatacGDDhi824i9GyZnfkBAJEGtX1uYUIr3WWBmJjApI/5btQIkFYs1LYdsIO0f68pf/cvel3C3bStt/xWHfesQJiRz00YK8nGSJvV7m9um6a6q94BLpFSyrMqKnbb2/e3fMwDBRaYT59s3+4gEBjODwTYABiBg2zQwE0Le3MARwsH01Zn1G5/c8vqNpHbjk899p4HmMbr2nhgGzfsL97BO6lwCfTF7QdirCKfmXlLSh1KN9Cxegz15b6Cz6Z60s4JbH9z0nfOpmFpVyVmmeFso74pLtxA7wuIHltMQvH5zfuFAnPoOPD1lA8UUcx0aAiFSPWAsPC/f7d7JFXlahHAsrmeCn85ASTyLaBRGgmDSOn1qJ1wzbbLTrypb9tiEms2I2EwtMhIAmbIdLyUcyuCsdP/4Guti8OmEw3v68p8tKYuo11c5BEV7DnmeKOEcq6udfuUMK2cfThoeat+wCvDcmtuvuUMW+Z6OyU6rG/9wPbo+sUddq6Yzxul/ER7ZBoW1XrIGwt2FSmj+WpU+YBEaaz0lyFmQWFxPteji0daSRToehEylSG1eZz9pD90AzDBKX//YEoVqTmqr0/7yy7vEVvemyWLlxWw1uTU3+KeJoIsTE+HG/XCSJTFLk2mWzIR7U96F2j/CJQWLrkwubeWAscd2nCxBa6guqU/sot2ZXZRLvgLrOBHv1tjRKze5jXksRMYnirYEqRSJudXICLMW01R4g8DvDUNvFPBMdPwB/MFwMOL/Tvm/sxmfQ9L5WMiYrabzycSf3Qi7kR9zBr3mDxnuzDyii+s+D1m8mibC6x/Z0hlOJqhaXjgTwyOpItYMk3juAEXd4qjAS50jy5hJMc2FnAYzbqd4e7Mb1CDbJpg7c6bpoZ3B6c/Yzb/Tw5znh+nNv/PDjKe/Zb/lPPvNJj+bTaVYTibhzLGRw0u8VtPpkveOlo7HAzx7fHC0BNbsc6/vzCkShjTYiH2Ais69Afd93uMj1HTuuzzknse9PvcD3kej4F6P+95sGh5JZ0mJhjj5ZDIJ/I5kVCKzIlVhjCStp53OcibWJIfEQ1WHRFhWHPiU5MQRNgJBPoPIR7b3G3geDtih12NoFkWD8PqlOryUdlK7Tv5LWdwVpZf9hOpsqJKKWi9R3nJHEfNUyZeSgbioSJSrqdLrGcOjdrYQuGTdvWOANE0e5yKL6xHnZcQ5ywU5qztCM2GNt5HlpA6+eJWR+UhYfwg7Pq4gCGz7JnV8HdU/vLWcvNs49cixxsdNFFDUP3W1+FJoSasr7SFmF6bir6/Xxab0P+0lddCPhFhWV2T9618WgLZlsrx2h36OAsXN/RcJrYDcgasr9LtvL9XbJhjai5054jHJ1vxq9zGq0mNr8tghtKrcGaWrQp5YjFG2O0KBm5/y3pNxxybbrdtEJE5+q8okF2mj7LKy7LI7ZbcSjx5l3dqBT8jK1Yk1/iOyImts8bXyHWvvscVXRVnnaHgnj/V30dEflMYGF6T3cWRZjETj83rhzKlwMpbtF868KJz5gwonm87vFALBqBDuFhmFnJh7YtUlxkBaYwkUMIwL9LW6q/wKqxB0YRKuUrdYtHLE0plTAhzQN8ptTfCivFaqvFSW6HJwRH5rRjVJ1Zafq7ZMOVC01dcdy5HNHsix9mEDKB3hx+nY3ER5HMap45BmIdw3YMrDo5TFdyN8kxTK41GpNJo6QwpZWJjBSo0/w4mJBhX/0nokpLqf2XpdOBvkVVK8OCnlixPHMQNHKJbLHLNzW06TmYogJT5Jkw8BRHqbCp293TcYFDwtcgCUdOd9W4iJsBMw55nuUN+sLiAT9SHHyo8rmG2fBz5jzFlIFXDY7/WCHou1og72BU8d8VZqcasRKk2FN7t/mYz9jsZ8nrDWF5uD39+db7CwTIuXZPnPYDvFlA/joLe0DKRHvAeqPqMWqrw++P0C9V9HefD75cVaZZJyEa7MsoJMpuBKYcT4+jJRi/S4wQbuzTuCpOpQKTgyaArloIugD7S0asUeoHImD/e7deUDbUbVDAs28zVZgdX+5VSWaw4HqBFtCfeFpccfmD5jhcy4NsU8Tn18c0C3Nh8kuwt5sMjf+5Qu/Hy4D7ZynWHMd571sKC2zIFCTVeJc7mA5adyvVdOJF6DyKEBCFEIuwtiXDnfI6O1q3S8/2hyfvLFtBxP8Sw3rnnCKRHdBIVnX+Nxcc04pagJuZT8SvL3kucJ/13yJzyR/ClPJX8j+TM+l3wh+Vs5a406ENYG9V+vql6qi1wOCKDu3aNqRB5JZi/jSSvbtka9NkaGilGmz8VUkIVZYyPPu0usjWKJS3n0hfBSLwIscPbjCr9dQtNe2k1TLIRSRcaCnp61FZ7kT9BRmVWyFrVKWwQ+nuOBmC4S/hYZlnC+TPgq4ecJXyf8teQXADXn2UUrfK4GRu1hbxIVtklm1Tj6j4RQjCL6+w2d100KqF9qOKODmt1COUvWohcN1WLczLT7nu8N/SD0Hqlrp132ET6oLrTFQLOr8fHGT0h130dONriNNoUaUdBRkTnZ8Ei7v8vm5d8MsC1Z3Oufn2DehhVCm8K+Ei6eL0WCJ9W3XHi32rmtkcgGzTYRMnbHkmby3VMpwF2dp4rE2Xux5KCgb0UYMSUGdTH05aJgAU4pWdpKLgRDTMSckHScLvH4MWnb3m9GNfJEu6K0+1Nilz0Zem6ORJIQgO8ZbbCQdS8buE3VOElKpjAk5bbHeDKl/q+8dn5ZiqOmjBTZn3IvsrT7Jr0jFwKAjJAGMgc/rx6/jk0sI0JtkQMEOpfzRi5TvRKiKF3lRamPUVMMZ90gpHhiE5AjFCxrPsdnfFn3h4yvBDn6fE0z3Hk1hqNcnuvac/kjehAzXtPdEQVj1FSbGi7juRka7EwUK8YXAq56PV45PsfP2TG+FYvmAAnYixqqpwYV/mSrB1axN16Y/P7bYqZjZxTlRjSCNlS/DeDWgnPx9s3O1hFs880KY1jCdDYOgjlVRnvD1J36W2oLSBwlFxNMUXYa9oLINZjFa3VFMWC3JCLIbm4CPFmdNJX2giNVBa4hxZASyb+lbEdjTcS0ykbPncxVPiaaRAm2poEv09tBY6rjVA++wGCO6X0jqk1LdApulNASeaw8XgS0hCbchI+xvhDkOzxMMOYaJ9OAZj9j0QSLAv6oCX9k4E2wMOBJEz4p4U0wQRmSDZg7U3OZA+OLa5L7kWm9a1Cd1CrcmhpHRI3RJicnrqxOGiBwnZzQw06rIT3FgPbJIqOG0eXeCW8wCiOjRH00xNeJeOTG/2l7HidUTmlCpfkhIwngapD2orINKfnogRKcElGRZahip2LeoOpHp4Iwi+pvqygIt4E1MFhmEgW0JsbQYKjKfzd8ZMJpoHo32HNNuG5djTAPYf/5+ut/dtXA1b6T+55vEHQDfvvmzxakoIjBocgbIWER0rkT0kOImW60sOw3Smshu2eqSIvS6W7lXhF5g32Cq48QDPcJ3smPUIz2KX78MIHv7hPUY0COGCru3q0XvhchMNFNqd4Z2y29MX9YV08MWTMWf1/Ey6xdRpKQACE9evTo7wkc7LP6S7OqGHh7FGGj9VYxkqvejRAQcp+KtoAmy16kfZleaixFGvG98dprPUb7gnz84J3eFYpB3TksYFkEs7VkWp/5pJdPTkX7ZGQqO1Dcs0r41nyK2sfVh4ftcDBFrFqnfBDDTvmHI2axuRb+9PCw0rKnZlj0gv1dGl+M7eUF4n0hXnTP9ffZjBMdurr8fZpv9KL0C3Z7W41biPNXE1EbtYCDyXiXm8EpjRkvUIHpaae16fptTIp3b0D7svtMzc21VU3IaghcaG+vyY6Y7O6/Ih9Dshfq+aXazCfg5UU3BCfjsOGo4CcX2Z8CniowpcCXiQqFRXNDC5KXgkAGh9yMV6ENVFE5DX4FIaqVkq5+KT+6MEHwCn9VDNK3cm8Uylc0FqDRLaUe72pJgXqrEj5dz6qguQoikAmk3gxFqgo64eCii1yZg8mui5Zk8VUb+F/oFyy+Taar2Yl6RpZqUgefWQ4ITKG1FJbpqlumDHeqpDxp9kFAjeStmT3ZVV2qjGmXCfGrrOzi3LZ0W5JQEOasETOg/JVmaZnAp/M5DZqX9NAGs5UaOWtOa5EihTSCXTeG0Z999vrH028wf9Zoc7Guz6kDIeZVu1hO52ixMzFHk6WRJqgxNlsrs50LRznuL4ccS7YuGc6Z7uXBZabHjzuEnau2fGxNf7NmR9bN9LdfsVjmHM/VYBtMd4YpRRdZQkXHsukOL5TD9xsYdJ9K9P9sVq1NKYPzulX/eOVgpeCAOy8MBxZ3PESAlLbT+h+i5e5YkzoCWvWjvIIH8vIVLyResTMTeFRHSfN24pTRUiWU/wYLjq29AUXAuGWpPF+IZ7bJ047H+FbVlK36QovpLN+Web2bbmdEnOvx/5T83OSyszCOAdgvHDDutVtPA2URLZcme6xaEdhUAylizuKNjvXkQ/x8xW/DooWA5V8TqEpY+ehRppK42Uh2HdbOGWDCqs/6eJOMRfu8nHt4uZoXu6UsX5PduMywkDlkAhaL29vbsqHmUHgiRyO9U7PjpYZ7s3guMqyv1Rdc5g+vEyuZ5CuqEamqDolIzPje5UuVp3PmlLAlxDRLCwgqbVGUEjxqxv9dw/4FjZWJPs+hkUhOVOWEZSLRZd5mFbM+O2g3hKkKuyxMX3v2sGVF3Gr9omQuiQa4lfGrSbBn61JFEWeVkV6naKnoM8ZX2kFmi3XhDBlHiTh9vqN1WErqzY3ahRKpvLYcO+v0mUM6uurDFsKNF+N1vDAWiq3iNmd807CxzR2f4+dsGcd8o2mboP0vpyc7xIR0bhpWisgrgh4fWI/3wtRKmV8jfWpvOEgCgKBvNkL7EV8+3WCshdScVonZ8Hx6OhMbxgvqU0Yr8JDwNhVkA1iepI7dqnVp0Xqn8yGCShuLe1GD6ZLGhxX6PXg+8LwaXpw5YlVWuLJTzURa7yhjqp+qJBZ6aXCJBrWYcag71Cm0PIgllopjRAuoyJQS0NZVY6+GMXOd24Pa3orEHIii16xd6ki3F/ojNpj8vIZ/3k0l6uSleV2/zaBs5t2fOmnkPxAziYIGZhq5SKy7B2vGm3yE+yInSz3Yn0lIEjwMN0k6CeIuw7GAdHaOwTidm0SNBplS5V9a1xzhUaILsIqGwd+Q2eAmn8+7G3ATtcW45JhgDIotPUKWODbli9fJWKx4F3OiZo4IIjkiqY/CTrifShT/B6PiiSgiSZmKMuMqKhYrob87QejTboaUT1PHmWE07/shb8JsAGnnS7AHX9oICRDQR6ezz2cyGR764ZDfAQeHfs+/G0PgUQwsrgJmwu/1qoLIalbvRqW5uWnWGRn5TX+ntU5GwR5We32J3EqEvF0EFaf3oDj9h8W5J1pdhmVNBs8fjOWJdAI/khXGCg2+qKRPTNP3j+BB3j6zW4c/3CtXjc/l+8Lxdo0y/VGiqKRkHdBzl92HdpEALWmgSafc30VsOsRmP4AIO4qQsZiwBGHFBBYE1g3iA2JzV/+DL5j9IvX7Z/Cr8qNYgKCOLxFqiU511Uk3BRPTWrWvMfHAFy1kwA+FCTTLEdpX9XY0fLRdoGmzOehOUCIui1qYqvPviG3/42x7rRxwvtVGZsRi8HEWfRbtphpcGroOD+doYXbKCyPM35R6fNJPJLE3CAShQKt4wxGL+17lRe+h+4o0bqQWiemNCWvkThQyMFAnoWI8X8E9P6wC+thxMGTxUBSQfs8fwj+q+xGxF9QAowCAfgXouT0ABnXAAIBhDeCBxK9hBIQRBDVAvwdAWAf0AejVAUTSrwNcAAZ1gAfAsA7wARjVAZAjdOuAEIB6LIMRAFUsekfGqK9zzu2VOdcJkU2eW2KGPnkHpTcg76j0Ug55buntk9crvSq7Sla9EXmrhHnkHZbIIXmbnEdNzqMm55FvvCOE+t6o9Hrw+m7p9cnrld6AvCVtAKlUVc24LAf68+65WuDWtoC/z2Vk4SKhpXUL1HwhZNmtY7ijQ9ROXPoULH+PMZafWcR1A+16kV6shA9PYUyD642wLLxeSghO/q+kGLhwaPVNKIWKJif0jXr9rF/fKV7zVDwi319Sv7/QgU/1ci4i1v4kUa+f1PNMw2SCGQneLzLh4fWlNDTf6vBrsKQA0zFoooKffkGDdjylP/X7iYJ+0zwZrm4XRsZSChrherdz2TXhs4rV692fq1xYn7nqz+KNQHyCtLNJDRfZxE0mMd7aCwqVcyZP+6HL27tBobK2zPHQdfkfNspfsi4+g8JX1sKS73YXGIFTdkO974euaWu0SuDTum2Pukc8aYyNEnfUkj4c1aSK8hIo1MUbIyxpsgqHSeH53FQcj1MPZX37/MmB6wZd1x2qsbjqu8DGq7PZ40Ke5p43zax96s/KKP2Su1/jHja4IxlhYaN6SgmlfrlsRL/bLP5ARGWjCG5NREEtIn8vpkadlEV0vp4SV3hjP3Qk00sIUpAnfkD9UK3xSZGA+EE1Be3WkPi6z1rodj0nxbJwBKwFXh+p1E73/qzwuVu3ixyHZEtZOCDq+H7AzCiautR2BsX4hA/x7+ph1qB8BO12mR73eUFXK4lQKY8tHfn8MyhjDPPKBq97dlIZkARPe84p2zhlBCtLMCxL0KyE36l+5co4oU8Q3DSElMJ4ruuUGYx61lyPlsKrAwLiNqxxu7mpVQpdWULmDE0kqlnEw9IKc4L2GNkLUWFyKaShX5y40aJKJCQb39NqjZ3ZVCa+LSsJ32knuPOzwtln/JXYHZ2VFXqov0oaTLQG8Sa7m5t+OMbTm5wp55lpYDUVW21+2tH3aZdv/8oPbIuMAtxyzhyL8doeM6oLgOj2iTioyB8JxEA9xiNxxv4miKCOY6d7EdV7nCnBmpOioO5lRHHGCRmEC2LgWO8thwCqd6LeB2YGckORFj5BIVWLUzssq5kyeBBDGmvD1G6spy4NICVrb9hUKZute3e/7v9KNps15L9/JuA2ZwKKOTkNMWNc6ewPtZRKZbvl917XIIqJ0nl1hIa+p9CMNqOuRBvNXimjWbrfsq4BdGxfT7lbwvBZSUT7eVic0ESar/m2VqX7ShzlqrdJHbepnZ6/r269fqlukYw+hfZo7xpSty8CZhOJVGyuoeEQXaen078QCiiunR7fSrHYF5xnstjOzvPSVcG+k7Ts81y4/Ip+Gmw6163ZAY6cu0LOXamcW9ybb4t7cu2qPddUBBDq0xm2DX228wSt1jZWk1wZSphqxDb5tIVEA5aAGMtIBGdhCymwc2MEqaiN9QMQZvGFyOw1aafc3pIld9Ey3EJS+Y6f1UYZ4y2KFsqJcnUHjXwmvF5cZi9CVf5+J6dXs0/Pktin3Dw5EzvhRZjMUVz2TvhQlgFTscTPx68OD6/Hi3IYRdC27Ec1GHZ2ZIu+iq86Yocyh1SUK1eHZzP+HCit5ekPdZVpj+3v/5qSjq/QU2U4c84RWQt5fL2AyrZhhhII1+kkuTudqxhS51IJe9sq7GjcqN7wdZCC/6YyuCfhlIZW6ZEjiCqTnyNitSJD9qIMUj04xbcfT/GtFKRndMrL4eU3KS306EWdL2hDOVS22vdBH49++cVP5L5SCoeZ3o6+skQ8Zd9tlwMfjgCaBJ1gyBNhSbo4g9tecYKi+zEaW+s6MBX41ZYVJMQEOE3MhOrr5oYIncqJjJl00HKkkJ+rkbN8dMeum4jWno2nor0f+2jHnNxDyNP2mNRYT1BYQnlEiSqvAtE9dHElpm1pMouZITAh350LL9SnrFu5vqRjSmxtUlNPhDW77wSAZi+dAqKSktudkXtUpUt/3IkzLb0h+LhNk/Wim23ltRpJ2HuJ1PF6D8dvN7QSE/+/mck95lkWB5+Snnu5ULVtVo2GyKydTiT3zKrT9rr2cYbpPQyT2MDvryIliqkGqAWyWfiVADXrTDPHEp7RduYcD8LX0bcKVRlg2hNTToW+yg4P6WnP75gl4NjMtUqYy/qG8RZLENliynVRSStyNDZmxeYhck/ljDj93mT0Z6amZ+/xquZtUHOE+qyhfMrQZ6Snim0nf38j8YVK5I34U7m5VFdO+y5/Td8SRoHPX7272MEx4i/frt9dRmGPa6vwS2waeotDEaPQLyD41jQKA/4NfZClT+aKwpA/pb0X5NBIOPpEfWFVMXqW43JYuYrCPtdXHZDrNR3nFIUDg/OWjmol/+v8/C1saRfrqDfiX/zxDoR9j3/9+qv8zS4aefwJmC/znfZSwLcoBh2CgEvFduQbtCIw4IWeeonvvMhLuH+ohI/6JILKFQ+JQLpwhF/h7WmeKqeUaRlj0ES5IBr4bckNbjoNdcgX6nvySJmK+TNVwJGyxvIvL84VvO/yb1Bjv98oT0956Bwo5e3zU+zNuqZEKr+n/QWyr306bQQINKAkDyFdplwDjsvp861CG4z4cw+OcODy575yePx5oBw+fx4qR8Cf95Qj5M/7ytHjzwfK0efPh8ox4M9HyjEEQ1e5iLXiPXTh8pXL46/JqK8TQWZ27SexNaDPi0O1SpSBgVRIQ366Knl4AfnKQC/kL/OdLEM95a2C/Vtl8717vsjdfWvMtMvi+26is2nhkHZhqjftif3gElLIEz1pXICSqdb51bzZkvPUJjjeTTji0sn3WGx8XlD3Bb09n9vArHzExS3a/gI2Xr7Vht7Lhih6q4j5aGVf/8WyizM0L6A13m0QlqQVgD7iBUjWQHSGDkDfyxjxuVCFpLH2InMfEpliRDq3ET8BmvFrECVORbZtpAzJos9IzDgGdFiOUsn4JeFNaJGWn/fh6mROBPxHQplHmUnKtx6J2x6JEqwtEoK3RqICqIQoEkTY0Ob1VQqpEH5pRVjbLi9s7/eEe0X4eTNcYulCLWIW5z0dHu5D0ONItSuYPiaX82KMcgdUbuxEkcRUOxrR0MLFjfDGY9lN3uHz0XVsUoZKU6QsuUtyqNevOnaNkt0lhaMi1c07fFQaJwux3Fi1bYB/SOxzbdpnesWjve8/LpC6F+q4lS8V8MhOukhyjp0qUAtEn8j2ocUe+Y8EM9Q/g9qbObY8QT6q7ua7i03kFucUkejX5fkSJCHPBUWE2P6xv7Um29sqkD9oA032sM0teeTGWoLYSEDpdfdi9B4Uo/+wGIO95BWrUpT02/v0bo9TbdEGOlm8Eyre93rR7jna3aUFpCdmmy2cJoOrfQeU0+3SEzrP66iJ5O1J0LgLvUeCL0VRDfhKLBs16bidHBTLepU5bhWIr8Uf9aQxvmtU7GIQWMzd6Hu5FXpIUe61sDMl5tGKOiubqnJH7Zp1rM17C9ho2zXkXCMvC2SPkL0KWY+vF0erTt+AdFpqsP311hjSNjWRng7rwyb84gwBiKS+I6FloJiR1xGyyB3q8jkFViA0Ii5L3zcqC6qzG4xrXu3luKLdbKVP2qkeGvz63nUttbVhgGfdqMFMpWlAzdxr2f0DCVErtvDZ2SEd8XNivxIZvxYuRwDtVhz5FEb2Ph0Gax2CPU50LAJYB4duEez1EOwXweCogsGFTu9wx9eE9AqmQf7KATIGgtedDpBRx69ZZF+LVzpmo1yESM3CSPuhEK8Ks5On03MCRjolFF87yVZOCWMwY5Bfkx0ePoAuq+jiYgkpQ/6Zj8poy2XzGySC/frO90ZeM6BXBgSoaZOlrpKIdysKN4s3ABct1FNbPytvGXtaxG79mliRO94qDtuOxxP1eQCrIiWcnRVlsD1uPx/qY4HoC/Bxpk4QkYS/h762oo3j7MuR24w3ZWkQba1oC77ND6W2E1FPosvxBmu+AfyDvBlPkEa+dZzb26oVqK8vzrD/Fbu3hYx/KFz2nAzOjr0bj+kMs3V9E2N11ooUKpwnYhsnYy2WPu5DcUxmVIr8h8ItGxvwKi5JwUXnoeGSKi5yNk0NF+1OKi652Y7KE60yKLPGVZK1JBQ1Ho43Aw+48YC7IKiQa5SKjsIV7ZTo9FuSLiollAX3qTQSancYDm/1Xuq//5hH6tJP6zZedl+llXltnhv9/OTPs8zWSAxI5WYSL6ampF4vEC9e31P6isjFEE6jaf1erA8cslz1d/DkiXq5Ljngoxd85IdPveihfOrVU38Hz5/TCz5ywEcv+MgPn3rRQ/nor34kBXoll8/FgO/wppkAp8q5we8UvxeUfacSrh/IdUYPUk7XlKQ908ktQfYPGDDpxqgpqqc9oX29vdKsYuqQDqVKRLU7pdJD3dZvg5sBNytLMwMqYU4zU5rk1qUJnMym0vkdfQaJ9/O+vE+bg1BtOVp2/wMNEU9HJKyMlmxC+bj6fMdsjF+1qsnGyXF5pStPy+V1DdhHLIJ9+mzZ21Mh0l6x2/oHs4bHyqjAqRVRYcVUbPGp8Bt6yUagCBsgRqDeXjQo93osfkTdq2uNxQoHH42siUB0L6anaDHqeeK5R8rh2KsOejs8NMNyJcSKLUFEp2h5tSAwcWdYaaaXcLWF+kq8QN0Cosf/MiuF+4lMrWjZXSZ2U+ueWjSkvaZeoiOuwJK7kw35wLqJ+aTCdDRmpd4bncwe3dOSblvQtfdaTapnFVUpl+6j9uXKKrkUYse7V7B70/aiis3wqKLjg9FYuwejPbr/tKiUNakvFClbdr9ObNOT6I6FuiZwqi+SX9/caDK3IFPdqs1QfhvHi/+qGvVfaDGZ/RcrqTWdd4fOBdWm4xmCpqRfWjRcwQjKmxAZkkMv4TFOAE8DPAWggHoGkr+Wh4RWK0DylmXIyyKgfPTgYOjTkd8NWc6tiKTWEl8rea+mf+kPDclx4gn9xs4XxDB3xJBFvobB0u+b0LFQwR0KHhTAtfAjv/K4UeCOheYeDCYabK8E0fK58nYCl6OJDieijIxFYUkVGqqdxg7daFQGjkZFYMFq6EeeW4Z6bhEMvgU1hrIR3LrrgHjNQvqHqk40nAWF94gqiS4sgMgBNVeUP8O7XgOuikEFdTDX4218bQYl10a9a/dVbD6U0Iwze1OMgdM9xbCwIurWGrCVgnm3e6oujABoHkxBGLdVB/KPeaO/aHRfVd+gR5Mf7RZSxgqL31aKqTcacfoswg8C7vt9/Ib4hfgBHnj4wR308CMcgg3x63NvRL8B913CceEGPAzx6+Png6eHN/EGrUf8gNP38Qvw6/FhAIt96PoIIOZgFAZAdvEGoTvi3gBubwjGHh+OBn0AQD0c4Qdg34Pfg3vAR31vRI8hPeAla/QIpmA8+iM8Bi4evSE9BuT1yBXQg0IhCh4hPQALh0M8Rj68PsG8PrFyiSnBAnr0+/QY0IO8PfIOFGfFRUVEAUOXYD16KBSfHoHx9pVUIT0UipJURd4nMRDQd4f0IJfn0aNPXpIFGeaDkQdCYhNQaIC8oDehE3+fD8OhYsWHAyrDUDGHx8Nj6FL+DcjRo0cfWTzy6REAE/CBynCAUSfAOSAmLgrNo4Ihlh4VArqV7P/wOhT+r65D/78OxdTlVwquMddz2yZaFNQ2/Uuq6V/hlqQ9l0njBDQQoveId3grDa3HFmrYgdE7I4pvP7BrHcH1ZVN4n8kGehXeqoslU0RXWUVkjgftprvtCp+1sOorKzqMDDtj0sUJxWOjp/aCOuxbbUz6PjmBAYDsBvrDUPeRwTk8VISFj3Es7/x3NORTSt7dScmwFnvg1zyj0l2Z2v+HLCtArN0dsehboUoUd1J5PCGqzK/nV6cfMv4QCfkDJTRfetdK1pQ2CrN9J/iAMY6MAlXwKVRo3Lw/rGiHn0rbq2hHn0pbyRy6n0rbL2nboyVz2n/XUqHYtLqZQuFCBXqkonwX7z5+A/wC/EL8fD4YzHgqplCD6GjQQUFLoieAFoYOhh5H/wAtiY6wH6JzNAyHPif9F/IhVCU0ImlNPoS+dpFivUPO88ZFWtVXa2XdVNm3zTe53KlaDD/ZeA6B5U8+KWPRPyRTU7GRlFmZz57m+QA2aTsD/8EMIER2l8ftp2qNhlL7H6NDbsmCU3UddUMm14fP0CMTHs/1Kf5VR+U48wpbbc82PRWCFuVpgDAuzmf0if1WCLLLCjWFkjfCZ1w+Ehk8iSNSXjs4AhVQHvoIyOCEv894QmedY9sJDsfRG4ZpQ8w2+uyxs5piaysZ+meOFdMNn/MtXYrcKRAsjZATArh6Ojorpq0vHTpNUV9WFIEk3+KiztzSkcU4Qp1kGh9TrBPLSSGchMjirEiPNEaTQysilofyfBM37PDWuAhZ7fYCJkXAfD/goAhYJ5fErGk9Qoi8nT9qGrUJfZzQge63ZE/FsTLrfPvldy+/AviNviXzr1w8Dh9PxgmSkTipg0QlOM6dQifKDHvdWMrXFiBtcqzOJ1oqA+51Iq7xqe9ep2NR7r1B5mW1c9DX8uotKtwFzqJ8dPzy9dkXB1OvM5r92j3u0oW4dhnepdOC1UVGzCx7yW77rst/vratxW63iY6Pr6+vu9dB92I7P8bQfHT8frE7X1nckhajcqNNBqsLmVl08CGK7vgHfcrHr8fTX7NfuzOne/RavpHbtx+QhufUJvNk+Xb3La6pBhquk8r1fZl8SRprH3pzg6sLZPeXOV81JrNoxXTC3bm6uXuncKqdtsyuZf5ugW1LB0l8S1tWtAG5wamx6GDpHbi1TE9OEBVueKcYtOTawyDr1cUy/5p2+RAMvKIEQNphgsKmc+ChxPKTtLkJOEUHQILsSiHMuRZ0UmgXo8ZU7sCrZkEup+pZpxPrAkU+Tq2LNWofzMfUE7TfgcDoONG8S5fHI5YUYpuz3qBpVnhglYYvWvZzHP/2Xyi7Gt+0lST+r1yjEyJ9flRPH6dTEIpogNZ3SfABfb1TW1VrvASrxrbWJoQ2/O83s+OBWbzodJJCvL/Zz/nasQ07X6u33dsbNOqv777O376qssxSaGslDnkDXgG0lK+/Qekaqvd7b/F5AawVCgP429ar3//+LiV1UD2c1PVtrneYoCnufoH3aSu9Wl0F6lvwC4k3VOeAx3kF5jSrLCgDIwT1p/jeifsVoB3wXyV7m/MKkhHseqPp45i3F9XDNey79TqtAmWetpQiXbynCqkXDdskeFFhg2+OLEXNpBSwbFmwIIH2415hzUTnwgVQXQWSpIPS+lr1soK42VsbvQLzUrW6OaX4freCLq9+47ODUbuVwXO9vgT9b+/ggahcarPQ/r/QycSWMKxG0CGqZdaqGz6GiwOHlEaBN0nUdaIGFxSdHAYrOvWo1W1rCYk6HuyqekWp826igqvvMSZWvbq2LO2221xcSf8J2kvpAPar7u6CL1c7zItnzxgA91Sa4snYFEGE838QwBWcFQXOspsN8Ik8PbTfDVD+fTPIrLLxEy34EhvMViv7CyBa8A28Xpo93cCeHkx8LOyX0HUpHCPlSPj/OBnEzAi44p4GZSA8RkuLUOMeCvCq42f63jyoCHC4Dx2kVYnmTQR1zXz0c/nQ3Fiwq+p0DGi9MPR3xbLW9e9VDU03aARA704GGSnl62vWLG+ORXDQE/I0WQDPdnu4SwaXe7sOkOvwKBaGPbEQxijpXcdVz+Xr5Z4G9nRmjT+dUv0ft3jGWzP6D5DDYvwQTWfD2X+CPPiz634zzRSFfUs6sqmSC7PvXlXKJutbqLPK4l02tMRGaPPdsl1TNVK2yRtNl4i82aB3YO0cSELLmsAXFqgifvsAOxBqHsB2QT+Nx/7tmaY+32MJfWVP13iDRjp8P50tvo9ns04nRNfxvy1LxQWQvvVgcxqDp3IWHtOOpL4Ndnx1QKW0bckN2eZyajFB/lUezsHPs3ARPn44XAfhNX1ISbDZgsG2RMLbcj/uYkuXTBwZIEcep4vvk+mnxxFy5RYq34TY4Po0JCEHfLdE79GtF3FDtjftkK3TOcVDUcxb0nkIsASPosBZqVOKPdkMq72+Codz6JdtnqJ/k3zDMmsNXrMUsbWsV1qvBrcdJTMaXuqWtiW8nC1JfaDW/Ak+pvgR2Y8YPljrSqHf9BXaCyttYHRlhjCMRfxMrHS26nTwExbvq0D5PDod+v/6aleMqfLtV9O8TSi1fqdD/3sfk9vjVS9ZQ0h+421GCB8lO3CLVOo9wO0YXXbhCwgnwfCad/GBtqIx/tb0Y/BBWU4FL3B7OHxYfIe0nn+8nLJ5N78q+AuT/s2ZQxEYQt/PmnKyohQpJyqRMOLmxOl3qlRxmqV1qj1Ue1D0Si01pd5sV8AEjODi2wTOk3qZQglUiZ4ps7nDLCXcXxjNBTpdLrfGYGOqXuEmqOLsvChnYxML39MEqEBrmG0zrlCvC5P+tK5VtsRk1g5bGGxSiGP8ZDHK5f5CTLbp1N+rShNpdk//zb6swVmqcp0uW51C1lW/OMd5UhZpXlM69+ZnCTxHqvCcmiLf2CcSNaXz9wjLW+98GeN6rU2ugT+Gl0jTw2ABWWiXdkKaVPtiOoQf8w4bi/nYQliY0y3ciHLaiOl+0OAuVMazkJhs0tbaj4lBE6D+CeFEwJH9LQ5RPCzyV+QZ+Gp4jcrXcxjRMdKVmBZnmz8XAjF1I+yE8obOhxHR6ZhtVuiHaP6p0gbzsnGqXYs/6hquf9CAEgHh8rMrP/OdmheZ7a3o6Su6C0f6qB7ReCE7YYxmOSnMQhnYrRl2JECgSHR/d0qW9FFVa6JvYxgZHrYLoks4sdediL+OVG0iRyZ9hk6hVqRSYuxMJxgdnnsPEhsZbmssSfRbvqxB/BxieKurRQEy91WRPk2S5KSAmdtymCcw0ip92pqWz5s/PkQ+I7YBgP3BZIpNoH1iL4joF74PD93RZIU2ISp2IP/lWm8IXaxTk0TK1Hs0lyYH+jDZpDkYYGst/upOhXSj5/sc721yj/9f3M89siFC1HxBkh30JfyuyDLSDa5xbvDA1JL0HgxADo92HebAZeA8Cixv69hnHX8KHSCdpGiOXvnehQ/fh03quRDktySqyO5FVZbLYpvX8tpvNf4aYjQmThs/TxjKi3LwUznTRkyHsArT1ukktMyv9wwWS8sMqxf+EXEzB4jXJilym5cEzN/cPOs8lidaYW7087KoWhGtKBpes5ti1BnBjRlOmM13Kls67CXAJHSxVsCUBlynpb0Q2kXFTVnktA4qbcGBEu89EO5iwMKGki+NrrXoQqAjXeocZLHcM1wbHNo0xSLDpenjgk9mI4vCilzUL8qzQal72AbDTUkiOOnLOPMrJ+MgocJswHVyZCyI98Wy1ZEUloSLVY359hy1ZBqHASo7NaODwWGvRrip6KX4py8DMgtMFE2TdkYh/RboM+yPBUg94f0CnJNAHWYzKKXhrDkcj8d0E+JOWVA4cCJUmrcsOiPkVa0y4IqXzZANXG60w8ii98NH9rRUBhFgmDjSFYzOI3rxz3NWO27LikAFMkiOeqlA4hKK7gpQQiwzWZbcYhpNoprpZdFYOiGJsCGB8kgCImN2CMAoRXLmuVp0E2szXUm1Ibig9cnYEooyvJNl30oE7fLeMzWJhkW5Lma6w2DuNCe5DqL9o4glCBHlmf+J1vsKWSw6FqhsKzFp+pI2wezLDsIcEpB0nRTYiEu6oRUAR0sSC+WeKKI3t+ipBYbllo5xobNSpro9yI3T43Aub6xEmm9hLFoqBsLgSZkHXLrcuazjHcAUqLDCVQi0MFxyoisG8dgGjnNdPsy0ytKfzQzIyCDMYg0ngEvtQJ5gTsyd0O7B6BP6FOOiMu4ePqs0AzcvZ8RVpG9jiOyMixyoCndNxAKG4gu8n078gY2scVEoVOc+3aTg7RcFhaEWBwd7nD8wTC5grpdbA1PnoQjLWUYSdtbwfs9e27M0Ca9WIIRKDskUL0eZCr3LXUwQ6F+L6O7x87UyLa/LWxEPJzGOET0YF51Y0but+cKG5k5l/FLzkMKE6RIDUVGUno8x4flluMeRJtxdTFes+fQojgvpJBUGJgGPAkmis+fzrYgsuM3DaE53A/K2nkzS0u6yFJbkJ9oIxSq3vaVlpWNKGPFcCFosIujnhXXWBaUeIgEEZOaAwJifKugDJ06E6PlvWHD6dgMToVVEfd54uwKT3KrswtqmJbhtOVVZzz7CFJUl7eTPkDJTlXdsOjXHt00L8vlCwOrDqazm77rIfDjdGfvWSqo34qfAzk/5/hns4Yu6wT38/cSLIX68x3Ogg4fgcfBL8zFsfwR/VfBSJ/gJn3CicoyfC4vs8PMQ3MWDL1ej45mk+P7u6u50PmmvB2WrR3R5d6z2LRjFwTimx++T/7b3N2xt5Er+APpVOn3mJN2L4tjmJYmdhkuABCYhcIBMJsPyzNNvGAaDPdgkMDncz35/VSWp1e22gUx29/732bM7wV0qvZdKpVKpKlFv5WcRc2RTXq7Sv3TFowPIcbwHcS+VX5IZaAXUoA1jVHLiqutIazEpPBGp+Moxq7ptFHyTrPyM2uszUcRT3aa3EuIZHFB73UfAPhO0+t//riRwoHDys4Y8SfQuCZUUklAZFXsGlWp7hijBT7EseM1hgcRSb1rbwtC9un9Pt6ZpW8KsRT7YInGOeEjc1O++a8AtiY08zF+AkY+9bfq3KGY7MUbPO/yntUAjBLu/KNpunD9+/Og8gCl2g6PY55m5ZNtGgb+ZKWzN2yzvGucGheq8yoDitPnDd1f2+e7KxpXKdr67sp/uruyLVEZ0uKsJ8V9VSt+jGdpPyLf0AcdTBAaQ9atGUOJG4+wLGgKU1oLUp2HHKIee1ckXiOUmFCT1EX9csBQDo3gpBo44cfW1HmOeN6MN/tP4BdaNSeG/DPeO7cXlmF9Bw9NGb4BLZdiih13+eOHDBlT/bs37RUKr7aS0m/JBl/uy9UKdAfJXvk/A9kv9Y6HJP95H4EbEi7q7EUKYIwj5ZzsM8fmYBeXq1ZGMJRznwGyuu9G4GOACH+p9+I0ONpJSJFa4+6FYdlQfjIT9V9npF21/yeaTcR+KsU6aE3p3GGfE/57C1hTO1IbXy++xDIWhUb5laX7z75fCTLcbp6abKLWlB6X1/O8Xn6QyPmmK+04qvP33y8ykTGrhC9PUl3+/2NwWu2DIYrH5Q6ZpkYs7TskeJ41O0ug0jf5Io73oLI36ttbF1o+obHH+75eyL0065zm7gOU6rqq/3R51B7qtQ/I1QnX9gMm8wgsaXrxX4nHm07pvPjN8wpHVSADMSr6c5l+JnWCzQsYXlKBK3JGtiv7U7dxErGjfh81YnYwOHvAfd92b+LCzTomVtNrchlHq7khjfOmH+FfpRDjmqzRUV9IQ3PgjHRxRE4Hk2Ugm8mwkoRFJYBRDqNf0zw3981caMCOT1bmJvMQxhaNvNsZxAP4Tqk2dGZsucVgZB725bnZ/AY9X6Adx4GZLlyZnUs9VmcnrJe9Ls/G8seg7Xf5Fxyb8M2iH2l9Cqwknms+SOf+fPvmlgSyymgY0C/KxyX5k3vOjhGA1eYzXMSv4+2+E0kCzfw782jshX73G8K2l0r0hOqPO6J/1NNhIV1rk93qRCt3HzhF2dNGtcOUcSPZzKVw5db7nyacNPY91+vOGphA7RVp4byRqczAuU7FQURnvze0mSsv+/e8F+uuA8BO7xaETt0j/aNTR3uzUBhEGSpuWqkzmu8gX1dwTs3FpIxb/mkh40gdkCo2LIuQ1gm8lyDYsqnb2OqCsq37mXQzGHmkjiO77dLllgkY2QNnj1FrJ3ybR2xQjoYhI/LChjc5F+LROGxIyK29sNj701COQ5mYaYHJUbAt570SXN2cQVMQO1rDd1ye2kJhGLqgbF6gpZ05cgGRobcz/RzLngNsAkxsQREaCrS2FeIhXsgieLHlxtJtLCLKSMuQ5QegBu4W80JDnFvIyQvbF5YSgCxa6KKXICw+89pOFt7ho0lstBgScsW3BS8328yKb5nJMyt0T4h5bNBGtR4UMx2v4gIjzgtYiHvRjBf6cBsi7S1DYqP0LDEyER2FDhewYaLnwHfDvKUIC1RUbA5Eb1XsqQWZ/M5VwSyQvbrNnLLtuV1MtVG+njyL8QnLcdR6JqlpfOdBkHcS9DziPBXjqgAs1EmFepULV4njI1/JdMiZr+/QwkfMb2ke/yQqX73+iRyUZH5I6SJNHcLPxJgnAinbx/42ZKjBwT+KQM3H8wsjM8ik9LJBA76igASajtng8HZZ3wucR4uItEstfI928dZvdFtpSa0x8AJ5mg0Q56g0tkFJ/a+cfdZn1azbl12lvqNjamyVKqKphCDZT2wMaeOnUCOyZmhaga8EjUR9SPn7IAtwpSQ+f4poJw17yiLaXQAy9UXuukuKnfecSEKNJG2njIG7OLW0s/AdsYSXlLygLd9hDHWZV4RATP030FNMcfkrUrvoV/7BsV5x3y7ucMeVPG7O7KvvgnWjsKvNqFN6FJ9JKqf6ZE0PV341la5+NVlN5LQnZSmtTbWX1yTWVVMmRyq9NsEVPpEipUiTt9vUrCryfCq5PtsU/flwcqZuyd1m/UhIAX8sUhzmcmdC/OuNyxjuJA6FYgmgP4A5DilKHGuGwzO92We7z4LX1PT3D80b9PB921/GP/inp6U0KkTQgcciDC8awCyr3nnqbsKLobpIxE+5+kU7QEXDCrsF08kv60xPkgX4pHo0BT65GHpnjjbvrp3HvYkAae3QUSZdXCGcdfNhG4JIPkFjkDQIxPF01VwC7zzTHHuY0x8ImqrAp5TbVFBeWMWoKD6e0l+y4Q6ts7fpOFGUaeFre2Hke4bjw6iYJzQOBpqz+aA8oKqfHo2fRbqOGmVuhr/smiUzYDF+LvXfuZwEy/Ss9vHNbIq0oDwAbpx1pXc2bBKeKR6IUa77Cua8ZFg80ZY/Gm9gK/FH0hoQT1ia6L2ve0WO8UJQ/XPKZ1CiWO9zUOWx4ytvtX/VwF//09MJX+Ny58F7HYwz3jX90WMpzxFGzDwKfYb7aT1GG8kcng68MET34er8XhD4qJt+AdKFB0kY3xYdYTvGnPUU0rfChH6c2KN68hDQ1gVTxNPV0+QP4/qtnp/QUNurHQWLaQsV5jz0p21cHaaCbtJGdctW2PZ9pmCSTvpTawln8Yxp8ThpTLYwsOTR2+/GYTHHeftxaLyuzQxH4fk2MGzpQ10X0i0j2uJWL2eywDyMoag8G+c5jOcfLuGi49w77EoiFRYMAVXgxWccDlhHX4rsoTxsX4P1UhjW1urYd+mqhWhAl1hUhV1aVMta4DATgDM1485nm8WXe63rbG+jLF39O95SNYMjgft2vPdDMwWceH8jNQFPcGYgRkUMnK+WpLhJYficfOo+iBy4uyjj/8rsymsPv7uwtRaa9F+2m7P9sBr4lJmPUo42p1BiZyesZuX29O7fOJSTRDlWfcre/K3eLnC0j9/yRUZAyhVl2V7fJg3pkD13gPdQWsBRNy1FfOTbse+TQb6l1HoiQD6sFOR7aLmgxyf0rmJHyHHyPJHA6wNtEDC1u258OcLp/CnMupPVt2tb6xlOTGQknNgGNwDeRfU4wLEOPCN43C0xevXj6On7ELC134ie1Q+FvBsHwt1s9Z7OlQJzJZiOYIREecV9k2lJhJHMew9iI3mn2Y+gfnxMlGakNzxa17b7Ix3RSX1yuAmlADidLwg0n9C1ZGTZ/mdmvo8NKSUfY5Y0PCGiVyAfEwUnuZYLjXYpOUGf3YJw6RuqTuco15dwTfxnAOevXQbWoI1ujxZfNJpGDJhs7uQTzKNHLJcUPJQuLs2LZZJH9uRJcb9xzvjfi3vpzUCzWYaz4I7/j+yEwB8Mx7duhKkrUl9hFadgZwG2lNDe1XNJIEryxpPjqpcsHZp9rVoKgL8ynHvFuJhTaQXlNL6r50US/j4mgAbwO4Jqrz4rwJUcRDlUQp+CHkqWjNb2kZodGXlaOLBYN0qRr1oxsKkvqUQ/PxMf88VwlKe8YzwV6wh8vCFrmjNUziqX0mjR3TeVWqPRG1Hlf9WblkOknHojll3HwNSmEJHYBC5HZBAP0IKwQs/FI5QQMHRK0/XLRoq72v8Y3o3IxMxuzFl9ALjg9vqmQc1SM9BohXozNCOuZoQcBnk7yVR46FgefUglOiIrrFSKNRPuSyY2aqgc1FfLncK3SKPE2NJ+BW6M1fmwHVm0cgJyS3NJIB+fPviY5/hkhptKz1rP4HE+tSSUf46NeVa/LdFtk7ep2YzK5hCwzAmzEUvLHvS3u0Phe2ZDe5+fZwLO/IQk0fiFrAiWOcj5ZBR3FM/2Uwp9MQxpHwmgU0Y7kSOaeTAzTvyCv59ac2hycOqwEVk+s9C6ZaN78J3NjcL7wCS2QT4XUjD6QqE28w1eBUdoE9ldodDRgnJ+SMGRemsb9XFtTUHF59Gsa+KR/Za7jd7HqP6em4XKCGIkpS/25ws20H2OjZBaic+AbJs+g5dXzMcOrOfauLrx9Hgqdg3//fnl1IVC3EnT6Y5Dr2+yMVAX+qzG/2ExJlo/g+67lpXm/r28BoyZ/UbQr+ZJbQ75FIh+u/+wmAzIjfnqJO0IECnuB+0J/7mPg81Wh9uEzp4enJa3A04kLtnu7ECNlb2Tst86xbaUUl8yjB8EevDXh18BLcgBxIrq6iI2A2/Cp7dkc+/15ddJe1idez3DDV88A9OfoaNylo3G3JISz6Yy4wxI7wzf/Wv8g/EN5I4Z4X2F94+3sg4E06/HAM5j0xx45v2LUGQe4uXzyCNfSZ0qyhZKdtcttWl//sP9xmGGu9ZZC50X908vxjB+bomBJ7LTTVLDNnaTdIEfKOzh4D1HAZsBnkep3KtW9vlnfXNslFmnFeDY58iXZS248QvBGjGHFu/UbaNOh0UA51dPq+oXdmIT4xE8OB9TabUxTMTcS8q4zK/0wZSc6SeMThNT3sA8hW2SR5d7DIZjcTqQhLCVSHd8FT/XxRX/gEP9p+f+JIBrbq2urWUb+ExDLKaKDPKxYqNGWyCBvcBEr/iesxz4w/Q7/zJiw7VtTIT7KyvQng0SNNNtji1QBBNgafRyuSBIm6Wrod+wHOQ3ACN/ZWMvKAPJigfmq1B2yGJEO8X+NaSag7p4uZTLD4Tn9LT2s5KwXfI5k7j/huSd/201zFEl+10TVKQPTuLVuZB4wk4Gn6/4JFddkrK98jk4w+1vrfAwfrYw6pWUf8kiAFGz/9riUjLjMEITFPT0sliMUAGvbu56pC99722vut6Q/9kpg0TGxXaUAdBPnAjjMO0+HNUnwSh3qkaNUd3ew8gYuTBa8kZ0QpiFajYZH+LA8B8Mh1eIVWXuWlmqHppKStnYtkUh9bJt7NSzER6c2ixlnQQIZShOU8vl0B1yCm0PKW7QMsheJvU4RPYF6zzwoVs98VUWf85Hkz3FBeCKFhU54tgbi3klDH57AX6jGHFUAW85PAhZRW4oqp5RGL5N3jnT3ZwZGBDerFKm7mbJadgjL4Ev1WMKTrN59HDlUdKkeKglOioHfLXiJ1BVFouUKLkOy8/Wo9XazxKCl7Ll/Qtbka7BL3vGEBJBNEwFuBtzZ3xuQ+kuA7oQJpDonY7ufKc+SLa1ZaMsee+dsja1PcYYIsV05tLnkrISxEDJBLctBjzj4+SUFPLeX1/ABxpuG7p3uyRaeI5LWtg5ubSPqEqM/4trCUN3wyxK1myQPIgmZ4jpcd9abr0y+Qn9sIHIWDlXxXVcaJs8Iw4rNJdwRs6t5P7XFFkNHpZiRe6IgL9eVLyK0vsmvK1rWrTAGk79MIS57WCqUF5zoqymZygU61MWkWZOgXPwS7bmsoh5Due2r5xi3tyzM4G+9scVTgF8n1oCqHcpNsmL7z4zPpLFNXUBqP0Gq/ub4WPAT+x5CDBDfE+P5KwEwycgOA1g3iVjkqpZrrxBnYuhl3OeZg31MxB1bkvI7HZ+A9IOECQqek/DVXpqpLOva8vKMjMCz6BuchuEiTdv7dHyxMFN9OgeRaqXDRyZYzo1T/nQOT3CJdbBmjkrqdDSYRNja3zEIZGwKT+v+mxyPEADxcj74yFJXHt4Zk8OSr/Epn3TC7s8YATkwbQiio8iH6GgkiKYSw5Ysi+b5ml9771HHGaeQwhfwtSToZfRjPQlOMufW/ziz7p6yxtcRuBNMzs5HJFlmgYPXYzzGiulVCA5TUVLBOSlwyG9tLQ59feNY9RmJ3z9j5L4mwdc4+Hl/50NDVKbQVwSpbr7vgTGQ7+A+ZM/g2X9ePOspcRMO2SFtL4kVv2tC90cmJnSkgR3i3HfNIuk5AzK8CYxTaFd0tq5cNgbNegTool9Qii3LwIXeYFLdnJUcEm1KstbWGWVdGQ/70L0Vt2XFpK1+MARmfenk6DDSFqzpAmg7dgbrLLMu2c7i4L6NAMcqa2/N6Il+1g4f0Mr6y2jGaAB7UlEbTZs6NmGpaGnjGt3rjPHh/b+mTi5p781r4+SmboZpKX0J/JnDhZFWfSw6Gtr7a1qBXxL7C5s+3Yyk2oaZ5VIjzt0F388KyxqxFF0h7U7nU1Ud6znGSxtkNIk9JaMzyBW3jo4VZEHATRk1fKeK83IVj1AFSucyUJa0tdAbp9YEM8mpROUlJgk6E5uA58CYojyDelQ0KCO5Ew64VSEa0Nls9O8eDtPK6ihg1u89R1HaMFYjFMvfZW9sqqbNq2BeQobFrSVrWOw8e/fVBfZKZsiDTJufDLPKQ5iLrKaZmTaJWZLbvBQgZEzJebXva1vcIVMxVg9+QVICkb+5HPyVX6yQUu3jxdNj9PGv3ON2+G/4A79h0I1hJJQ3temi1FHxf6ViTSMf45kXQj+SAc7yK7Z8xNYR8baiHU3xjnAy6KOgSEA6K6QkqOA6C8NrT4epdvMFoVbdvXpGarwJXd6p1uXRKKyRMbwMgvymMTCJ2JtFjUm/xPupSY5DxW9BYtHh+Xp6s7QyvQO9YSIh4a2ILF6aKu/m/wUj/Gp8if8yz0RTJNCQIM5/giF1XrZKpb7kDIkeK/mXOw1v49NztVo6G7Hj2ZhLGlNsV6q4lOJoxSnZL7RtNIbQZ0kMypbqR3xehUFwvyEepkAA9I6cghNGbTD+pfokvAIj+RkDQdR2jcsGphw+cJmmzIOq2MltxHpAcdA/hu52JAezsNLuIdOYBpym5Iv0DKVJ3/WG2eFXkF0heopd3BUifkq/O4vDa/PNC4IAy0K+OFUWxt3hXAtnSrd2fZX6hO4ZaQaqGn6gP1meSMTmZRD8HCrebzcg/Y4PuRAjlfoK5wFMmN9+mp32Tse+ytABm3obCtFPlIqPcqknmGinFNHbOgC5VS0At5XOcRUb/AYB5VoZ0YcaAIuSJWW/LguR0W1ORxze/Yw3/o59uZWbZdu9KMmuf5KwhKctaWBAtfscUYRmGh/tVsnvapTHm2CHdtKwc5qgcOEM5mHJZXUDGCb6SU8UraXW/HrSAQ9GKwsL+f/Qn+KJBm26y3+Pf6TGrsAwcvagheYLtp80dpRByZYSvUhdSXxsc8pr0gDZ7WMV+lvkht2f2dba+r0ka21oX+vS+8c4usqIXKfwKM0XZb20aH3QDMoTIi/nGRlZL3OjBiXyFJdtSS+zxpRxs1v/KEwjoM0eRBefzE8F84FarSkEjR3izmZKtSoGK3N5DzlziC8t++KrRLfRBRvDCgifLNdvx8J53ET3Vd08eBXZ1yDD16fXnZPTLMsvDBsSPvqUyL/htHrOl+gVJnZFHcZdlUqrDFdUeBjBNomgITsKsyiFNeneyBmMkXdMgUYaUK6bsoUn5NHkBeAuFp3sJm4JQQj0hOhY32Z+gGrAxcCsQlvgQl5fjceDC7lS4oYnZXJnOYntW4oHlouq9LLjjxoRdL4tIqjrpNZXX4zcmVcFky91cqfYkC2K1JlEKcmVVJjc3KoYo91aKTTDHaMF9RWURHoiFBhjegZYCOCCBa72z2E36L1BIzjlhU2xoNaShX0YwCcmATE+J61lbgMxXPeCtCUXpEBy73pi8y1+TwChXhhF2Ycr8VolLiNGINVL/hWMQjLVYVRcSqZARV6SivHI0CNR2jfl7oD02eW0N9R3+u1IRsqmyPEU12xwxjjyvp5geRxTJzsgD+B4A4M4klI/ohP8BDgJFStyvmYuk/2qZcjckSH/i66+g/uI6KQd+h4RnfLNENE9WWgg7la9AG7IOpgqvLsYRkgxDwXtO8GMLHU8boyHUZO9w/ACX0IUmJjW2dz//4npInC7Qvp9hO+2Eb61E9DBZZ38vZrWi94idpPIDcn7THgCPIWpC3zYAru5FtB7dG/QRDCpD7nRvheaql7kwu0WyGHeO3f+08JUdzotYp5nIt2TUaS2tNMQ89oZn9cQG10EgZCt56MIpo30p4f0C0mHjrV8NCAimXU0oHGYcTRwhPOz6cK5O5NA/PGCerWG/3qh/WKuNymV32ZaIM9dgdws01t2fZDJbnVdFZLPSEh2ZN//mOlxHjQy1T/8rDShfmDM8lGM5HpnppCqb1yp+iarecZtX0TN7IC1YsdApGUB9jpr1FffSMIkmpFK4mKQ0huIpLGKi4aUXZPdW2JV/v9HnkrUPJ8gW9EZI47uirxL27s0QBr2ffVXvCBKC6QClVHxGISpjWkkyhdfZvQm4u8Phi1LtyBUsW7CLBpqJPXdIOkla/wcQ6ajP3jcL9/yCjQOWRU4mzrLg+128MePdvKjJnM1rZb9t4cxsflnLnZbhNsGksMQm4WmAX9oGuRbpiFxTWWvsbjzyDememLJFF+fnl+de6Ym8KO6htSaLjWQ+WAAz7WMSgLqV1tKtXzG86Td31eHZEUlsfySKj4GhinT11UmHfuuc3nlRjOmtnlD3TjbNfe0rkc2imavYrqXm41i5b38ztMhnQynta3+jCgB9g1jPiPGPLsxiPpzR3MPz46gBvmYosQA0hR5YTPMJaSjYmMbb8WwdvJMFGKOqlQEmdkYAb/Rm4WDSvLZ6gQSeUyDrdRDqs7QnA4obE2U8Al38gghF0nRE4h+mmoh2z+xpWNeymszYMlc6Rr8bgxOqM0fHlLdurii0cReqjLjpHKto0q1Mioz1BISlVP0GiRkbjb2D2Nz4BS7PnuaJ2vZQiPVJ7qhXoVpRH8O+0eKZjIpRQVV+PlXFqSNnb5+DIUF+/gyvrzsojZOgdZBUhR+i9E9/cChVCTinYuCe+qyvY7HSaS5xKEG3TQ113e302rzCTGxfZGB0R+3eSQ6VVZf0DnuLLHnNJpwM8hynAPEAAhLiuLc4k8qD29FF/GSdRHiTG41sw81ujtkVtvV6oeu0Uh0909ADGw8SEj0IGPVPqE22F4CysHrZooV29268A7yER5i0851iRL+dQVWmeZd8hlIJbnPmtXriRbsDGG3zTXKK4UJgEfO2zzteHgylRqcoTiL8eb08px875TzkYfWMmS1CE/XNY40rXvj+rfYIBXxTzIP+jBRkP3VixttacJnN4kZXBz+QM0hvSOKH6ehJh1D5OmRjRqWuK/hHBl4Tasu2uKYqfEpmCWZfzMMr5NY3nerzhKnwPXMjXAcBb7P1gNfexJEzhp1NF/ZS5PJZJJXi5xiMzAjr4MguZU4c+HE3tVpZlLKL9VURgqEwpMLrq/kIM2XyzrY9Oo4yOC0YPERPz1cePGK/i4+X47QjpfP+avVbONzBfrODlt53FLY6cS1+cj6vZ0z0SuWbT82rO1HbVdVUjN2/A4y5uKXmiF9CT+K5pea+Ea4yokDQKepipkbD+JgFAfYyCbHxxr5PCUbH6z7SUioeOVdDc1rgE6iZK3UVSsp+kPbg9iMsZq+2XW4cWQXZxp3i7uVq3gmfcbqTeZ68qo1grDo7t0QeKiVKJSXs63FP/iKCGzSKfJtMWFNorLqSmwZao+hbbAP70Rt6twShsoiJhXEpIw4QT7NV2xvhym3RcgFqS3Eae4mj4C0OEVr5WqbWpzXtTh3G5I6DcnLLS4jZmVETNMfaYBBr2cXTuu24lnzowWCqdOkZeJZs7Wlu7/ZOEuDu1rz84NbI0Ekqw0a1bSIxl88KCr2oKgKD4pqkEoCe1BUP2cRal940fHxmJOs6SX42MhX7ebigkBX9wrwrXqHHEggA3RfLfGPJYDfA9xk/MFXRU7W6BVhq+OvI0y9/W53/D16eNOHT3h8zmt8Xy0IIsrZRjkIs2Z88WP4WgrfWKpGRdhpGwCZ1svX/mXqptJ3KZEt24mPUGkWgtcXRekuigVZHLcKgHBjgFdfOcr3Ne5Emucj9WBt900/7o12LjrzxcfxcWfe8XzUJ2UW3dksuNe5U0JcgSLuDo5GSNVwdYDVRIsrF6dhR+qDu6o/1F0N7Uep2gF3UiKXiS9cJxOlfbPH4n3NxcShZ+EEjbjCfuPuDuHAFEf3Q4QHNBD9Ibm8iH+sLseVaZ6HR6RQkCbVtqPsbSP+Dq2I1Iot1uoTKn5WMJoQ6Xkz5l8NqZuaj1zylk0bpPOzLvvqdJ8ftaUnRKcaQ5LYHEzetNEVfHs5IYdzhqFfpDS4GSdn4onJCDAIA69yfnCxArnfGzK78DvF75EvLeKrlxVf2uN37NMzD2eDjOT821je1cVRbA4QVxl9P0DloC9ZOs0ZugdtTJjJrMnl3WleUT2gsTOm2GgU4vtpFKbUeJdGwVkk9SsjndVGmrGcZXhtk2DEps34IsPA085bn4LnINOSQhQ5JUmPicrlXEAEcMx4uExsvcqNO4NQxXfrFqQPhWYhoQP4XSfvPlrtLgQ5iHNLSgYDDyKo+9ORdLaWjKocuZHYWzBBmGTPf5fGpDWzSOybJbHaFoZpfcuJrII8+jk7TBul7ZqQjmAahEQWHsx7V8+ggChqshTuMd5TkVKNjn1zRDfqFZh59hKPkaWSRpbYlu94z8hXh/hNSBsiVWkdyDYJUtarBQM9smUmsH8vApVqDYE21T1JNGgW/Vk3ZuS4BPvHi8WX7S64ovxcwM9Q6NmhZOXV0LKdxHoqohcatQQmM9nFZL3TM7m1qz1C3T2JLnbYnTF/3R8wf92Hzp82DW0Wu9V2FmKfwn55NjdH19GOl5ezMps6s2yq+2AqaP2PUcHt7VT7IWOxVNoiSvo4aYfVxmkUgZYQhbVWEQVKiKF4ZY/DrujtBynZ2ZOkKCeOcnyCQerGJwCeWtyYLwfv+Fr4OB9M+DhHAaE50oTiFb7IuWsUXOT3GBbyaUgITRXzI7EmiYnx0cpmA37Nn7yKO1qEx3AWvwGeFNcA/tpxnIksawcm4qVk1MjOx8eNwWWv7McE/xo/Ju1n1QCMr56VS0QFjkjofnpEBVEhnC7bh7BY3s5KRaHwlhQTjRSZ0bdKwc/qO0jKjW+FANvhoWoUgFsK/UIwiPNyDsA0ufL/R3u8Vbl9dmIt0urjxvvqX4TdQVFOSf/K3JJirGjH4/kFOft0jxRnIpeSF9CzowYFkeGzp9z/EcwVxB/q7KVh3uvbnN9xrChda3L7wYKjTJF7BhrJW6Zi7bu+PBR7rn6F1CNiciZ1AMEq8jIcCIixZ6JkvdeR8cmdNFecpnxaGBOD4V2f9y9GnSTyKwsC8NEgHsqaGD3D5C08a754pp/ZklZdZ00jf/ZaoueKz1ryt3E9yqghdrE+tNZn8KKYP4svBhc354Or0f8T637S2mK5pkyb6/s5RzL35Ls4B+CTlLF8Z5tkTQph/R9hPdwjVnU9P5iwCt5ODvUyh9fP+T+eEOqL8tVTEvNW+knH8Dzs/bd4JM5RAkghfz9e9q1gVZ0nr/TYCyl8Bw09eP5fPbPTXTMy39+OV86MSikPJusfwrNKhOVM4Pe26dX3sihQpkNMZaqsF2uE0/wfXVTn4EewnB9PFzN51CytV+oKqw8nk1u172rA9+tu9qxuVVrg6SZYJav/sfRqWkQ1c1nDdzX90u3RgdaYt5ZJspPTKBm0GKHOXgRG9ekrfI9D1zYQdr85Y+X5OOvwnajN5150qrsuUmfct07ocTqxcs/yTpVDAdhaKwffAhEP6y3S5Hm/wItLIu8tKRmmVUYq8kkdQ4Ge4csOs9z71l2gJOpjJs5i9FS0p03FQmfpv3USrB7mf278xQDidCiJBuy475l6cdA4BUO+3jkO/AhYZwIr7lqaKg9VXoXmcy3yqr2dkZ1cH5qEs4iu4qDKMVBx9Ywpwp8FiloEbVbuRFNSAOaOZ3tkiWBrJ7bvDXKCuKaNMoLivpmiLinns1X+bJc/549C+l+Hy8bdxo8nUVef5xKpEy/NMSF4VUt7xiAFx83ZDXTCT9W3S1EdKKZwZLscu15IutduNiitfDWjRkK3BCXIr+rXm6t3qGXV2HarbFrGa+K6Xwq3d+o1fPrThA0TeaVXCflq/dXdNX6tbcoe3eLXVi/3+7YF5/EZOcG4hOnE+MmIvGLQyoE70Yavm0Sz+tnxcPQbTbUZbZ5s2XTcyXacy6LVeurNm6jPmQHcmLzSTnpCoR9NHpAnDknzKGYd/ElR48xVg1wyEKo8tnK4JYUjsppqNDys161qnWnp+Xtz2stUf+6nzIwp2ihDKG0WCxZ9beSHdz8oxYv766f2dZTzqlW/aRW1bZwHnzPoVkJWx4o2tqyMnxy70mtNFBAXNmszrl542Kbfv9CcpY6UU9jweentnRcCyDzrSkBNLdn2I8ktY7GUNr52bMks9LKAilXQXZRJe3lWsOa04DsZVhlp5Sf31uLKr0P+T/T37qUcA9O8k6qDay2ysUqw03oVFyAyPyH/sfE/2wWQdzze/TrzQN6r5k8E5OZPkH+vNn9yi2PsZ6dbcf0NKlahy+Brz7exSl2ml+b3ZHqSf4LpyWTMYnpZXmF6MxqXqNxtXJ7PYIOSp44NSpvuywbjtGCDO6m2p2l3jeM6G4b1P6Y5i/VVOc39NloMwKog6zHpSB3n0pTfYOIy33H8Zc63ny+9sG+jeVE2BfqyAlXe/vWz1TUcP35CIbCW2oG9mY0XjzyAHB/D7EpS3JjzyNPLo28tpNAp2VeUG0ddziTenj16Q02mVp92V73d/Xe+WpTfWxsbGx64S6N1TWUTrC0Iz+XDxUBFJ9WKPm3scj0H77Z2n+6tLXAta/Al+3R1Y5+qET+Kjs3TcT7hkypOo7Rjo0BL7MfT3CVCfMl1jhYfuQTaVjKVEze8jy9gep5jPSBb4xMtchk/29PeuLRn2gfY0rQcQxEr4nHVXuDrKS5Ur8S2w/oM19N4+gVWqRVXFXGUkiXO4pKOQ245+6QbYdfhdBbNTCcWj7WR4ekuZvFirE3Ht/PxyQCXBhm5PB2Qkxyx/b3zIYi4SJ401ajfs3GbmTXIsXE4x9evvfywviVHkn5C6Rt4w3gzLKV58m7U85XxueBKA0++oknyYWQB0hmJz09lHyvcx6IEtYurW+cKtux+IsXU0J2Nbocv5hgTBOaJFfFYpCSRkCYvbUGD5Cg4Xclxd6vdSJgi/MIjNaAayBevHcLWUeVbhUubW9dTRM7vZsEhHf0qO1FzF84sl2nVRVb2kHaaSyBPZ9F+jo27ybM8SGFUQJeA0/loteq+rprOcjMpOrK1O57vrIhC175AabeNHILf8/Ibp4ylRbWwnIT0a0HNv5Jf8/bXkqTiHzRinp2uL+DfEF+2FPIxBXw5cQJhcQJhPrSXlNnd63dmKo7CLkGiqtZLqaXq+tG4Zn1lMaz8AVi7WYE9B2yhArMQVNNenDhwnZun2L7eMuujtHmU4kLo0Yugn4DmcaaQ36dDDY0vM/lFb110ZxnHvmqRr5ObEVhGfxvr/PKGQdt5dhqvpoQkiuQSom6PfRJDXojJXpL99vEGflEEgJl4UUQxAyhSSgF4feNRC71gd2f/QLw9IXAxBDl5EVR6LzTIq++F1vdWt7v7NxfpyeXgAldFHgPWYmhI5efG+g7+o1+/MCr9w//tbHffgFucdDc2dvlD/si/a5xjXkqXf99yLv69vr5H/z1td1/T55vXT9e3thk8j4/1Nv1a6L7fxR/5ty1/5uXPQqlPQ/RJd8Z0bR+l4Z/dLk1ndx0/fsN/mLfh5Sl2CJomCpnJlR7s7+x29wZfESbTS4E+6u5x7h1O3ecPaWCp1j9JBHnZ6rjB7tZgV/J4fBlneddre+tXA+cBlGq9bM9A3h/04TLfxZ6fgb1xPb4EPZYzLMzI8K+rOCtjL96j+PMBpJdKLUuze1yb5/nsjtdnejE10+nzMiaE2PUrxFgjHM/Ng50PRC0fRY5b9TnpFtwjr3GKoJWD3f8Sr5PdzxREQ/yOidsxqCHqQrycT3U8Q0FQ6U2e8T3jewYCvk4BKGMRV0deL6aFAS4Rj41pZkKv9ujhFbl8NhH2hQc6kU0zk4CCLVRM2iTFZYsWoWEi9euErXVjRi3yrgmQqcXcyzz4ZkM9ggqyHD6JEGqDfihYu14dxykFsLsE0P1UWtkMsP6lfAm0512wQyUqRQDiYEk54Tw7eAmWNmp2Awnu6MbwDMsP6G55qmxnXgOYDDA+0htKow6V2p2V2+2DIWRX6dhjvQOlUldtd7Kp3ckq3Vkd0ZUOfEJREsK1K39PHq4Rta5wIJqMQnG9zt/sfaRgFp9xwqRTkF/tBGax3P5fcD0Jh4EzJrl2Ks6oCeJRPKPHm4VX8mBGUToLoTXoH6LLMJzubYbSf8NRruPDETr64vTGL955SYWW+bInkgpM/I9YKgfjFwiVRuNiET3X32Uu/i5lwFTdhN/EQXnOQ/UGwXz6N50/88OkIb+PzKgJuv4IlfWkMBqw6elomOcZ0TLga33A9gmA5b69+ZevyG4NTOWCyl3b/SifR7NGpCyryLDUJrgjITAK9nrVz2k05vKaQfBfw4Gy9z5OZAnTFz5mL2NL5R/qF+3+6V95x449OhkTox3fPGvhonHx+VJII/GavAVjvXpU6gCFDGk8CPKGAUfqAIr6zoCg0hX6PiotoUSWEC5gxw4DoU9pyYwxnRT2ZFjr01yqq0qElEhDW4y89hjncTF30yHzEstTqhyE3s2WuciKDV2NTDMGfht7SOOSDPg55D5TIzeJ0Oxc6Mlwh4pcmz5XcciqlFuJvV91+/c6NaczJKWCaRNHufu4mnPqp87ZIL0iTkLh5DRTGb2+wSzScSTw2RsDbW/2tTM/I/KHxMxFsYfhIAvFBjgxDi300329Kmn2smsVrXTa9Us8eS49MZrAJFVpqsY5Gab+lqirHMchx702nVZ+S6JWV3w9AL2bpsBFLRdpQJWdl8Zgp6auIE0Pn7Zgdiq0BQeB56cj5icvX75U66c9vAekQwL1DYw8bZgPBXvU/vmoQyN5q5I0KiV+yUsWtO/jOtFITtEiv7RaIsCgP1RQ+QVO2U2Ukx7GLjYtCDiVT1BXHOLXIOVfXWqMozjYds15MYBPn3btaBSlRbmiD+nlyurlZXzTOB3x36BIgA7A+YoOi99HYcdNwC0Em/cCVh2cf5XaY5syzqfg75bwCwe2PJoyADlSnBxUgPiwbb76rYhST6pBMiD/Pr+0kAar+kCoAlFuCp/44nXwUnzdp1oss9rA0uVZmprboVTe5Ckic0XPHdJGmQBXgiyqwoDt/0QMiZ8P6p8tjH4WvdHeZtLGu/wygQA/okz7pxluXTC6CeP/tDPicOa+uAQ+o4d/nNgw0btanTZfKpL/hEd5EXWdYFgkj9Ck6uLhy4Uz8c5ntefshY8P5VHT6b6hJB8tgDrr0ADQBDTwgt93RAZo7QvazVAXz476Bpdcej+qw50PVxB4kHsJ4/TLGNgs1l0QuOVdErbf6c/BV6AvXyNfBxJCBZWMyi6Qp637vCihIS90qSbzLJWqvGdhLSiV7/G9KIVDtO5ZrXdW37z8XBWiI8FFFKTWw45TJT7OdNCpR/lEDf5GJtFrKmVOLc66ub3zMlZOcfPzTfx2vKTP8DScWa/CmWho76qDdLsTb2iSyK8f5JJDdnHcGZvKDwa9HqQzaZFdzU90IbCOgkTfAxfspleXI/xmfV5eTPqY8lcGL0TzsH7oRdB1e/F1m9wjys+1rlxnx8tTIhpcX+uiOPRQhAXXvUgK38RJ4ZtY44lbYv1xL4/ESckjcbtdvuP+UFX6onrXg62+TZQwZvam+5Bks6x9pbmUVtXmAA0tl9DAMwLqaC0tDetHxwkZphQlFIYpFyL3iJlDZoP5nD1yymkbOzu63JSh8EwIk60LpOFeqjAS9I2zm1t559RfuYjY2UmeBKC/jj8nAT91KFervLVnL2HJzHYY/Qwa/CATKasvRfXFtRzdYsah2c974kpjJwyI8/WO/v1vqKR74GzoOm7a53qOs4xUXNT1zGOseAXKftr8LlRf5ZifztOWQC8ZShFVRiQBWAw2WuIb1GFZCHs3e4qv2coByvOm0mG7HC95scw4LbU+7kH6dFIpuQzjDiQD8hUsfCW6wXZMblgvr+c5TnoUu6za93SXtQvR5RL/ffVM1/CMaju59J4tV3wa7UiDMtqhSmW7vlHI90hU1BR2eec5kgX1PT0BYyRWhfUkJc35pZb6IZygLrVU4q6sG+dKo+WKBJYiEqGIpKCIJCzJ1qzzeoxdr7rUrMq/lwQTywvFTcCiydXjxpyiZv6VR4c+axMkyrnyte2++aT3pYEgPPZ0WugfFSL7am4I7SpoL4jGzvWapg0KE7IQtIc3swngl8PN3RAb7SZtAIpFx0Q7WF2h3/bN9YphfsHG+XB8E/odAM7jABiq6bgqYoHuP4PL/wzJZ5EV7/ywowtwmyB7AVSCyxvG2MLUbjmqcjZIfZBrL6rYPRuQicM7zCYa/K5xvvKu0YuDsPOu8UdJ6n2t+Wxq7qDE+YK2KMBaKSwI4EwimEevxvn1GOljbNzRGl0TY0LnFxUTVHf09RT7SUAlkqKp2YkbvQZ5nFH04w/8IMSdx49/Lh0e1nJqLTD2gmwe9DLOqZYYUpM0SyhlnSjl48GbF94BcfuLuA/qgC6czPXhIHB/bWvL18MrXy6RbDC72UoCYTPzPCw2YmCDzA3Z5R1svcmTUQXUOD4tDk6GN5H+7A3ge2wc1U0aINhBDAk5x+9LAFdHB+hGUFcU5Gp3AN5w62r7jpbgq5ezUg4mQ4gCOA9VCCH6al6t6cH5U3vtuaoe4N8RJWwLJWyDEoJtjPMBCeQfGjB7GpC8A37gfpJwrgitl0bzywWcYX/F0Qf8w7834+htzr/2YinxIF5pk+NtBn4l1K+ESsSnNjHLlde9V+XXvZu5am0shLTPbROlqtJTXmCHpn9cmEvJ9P3t+av3dG1J3SwMemwAr3IgNiTMjNR2pLZytMOM63mwMB+C62Ov3jzYfg/+4vp1mrRg0vm4gLRR2wbwkVT9mTZOEmDMaoxg/lw+sP5c1r34vta8NLvzy2mXrA0wISh9ayRvac1GNEfM44m7A/niENPHg5kgpTxoUTmW38oT4k2ECU1Yj1VNT4VPrQ+yHiwpQaf+E95Zn2gvmj4VNtcCwNcysL/PzIGfO3CpXoEiLv/Jl+oo8rUl4XGMs5JOIY+HkwkiGvuZBKeT4qXBwROK6hr6Wuh9Enar8wfbPLBvx6+4I7jkNRodPU+T8/DesNCX92KhC606Firi7TwLUo84vuqX0/wrbYDgrgsL2NvwlzuKwRj5+nsd35/W+ettyQ5qm2ijWLdR2mrqzfdD46c4yp7TGfIYKrqR2feR8JdJkCOIk/JnYlLizAEfUAb21PWGZF5y3OWkfqXUi8E27qzzvcHYTeRIqlp52qD1jxNuYKZxZA09KuE/P0DW/ZAHbERD3cCkEJN5TVSvrQ7EGcUb6hikrzq+1MXi3CbGrxkMatNeAIN3qVoseaiiyr7ZoXP4Y7dmALlJ3boBZHbZnRjAiMa1O20AucndKQPIXJU0fCnEKKo3xAeohEqU3eALe1I4SEqqzY8mCsxBshKAJEd4g9rAlakMvZxQKbZKy0dOZaP8hlKOQkYLW5mRvQ25ZpwGxMSRMVbUli8p3IA1Ff6G+LFkfszbXxAJ/eL3C1/hJ/5bCf4MntN10xCzzD9JNOPfrcWwYa95UZdF9JdeDq99B9tvLS4JxM3jvwAsVLRwZMx2crWbdwsFolbvtR7xk4L+YDi82ToHxW6J7lr2cSsRC1qa4VXIVKzwk40y4zmM3p4hV8ce3baRk5Lcy05HcFVARXlUhnd+NdLhMPtsz9nQtvOenJHv08bmzK7Q5eoINwb/XGy1Z7XUPe02Ts973Lxqa2YPhTRmBpZtCz1Zu39jRoNSY7651xIiFt1zpIL4jpEKu/frZZDMwOJyjulSYSePXsfBGqQk+t24jqO9nH70GoMolh+rUSI/LrhtpxA52RvhgfPMhRHikmhNxX/bIbMvSmOeJxXwqDDsp5586AuPnTzs7uYTflR289Bg4KfjckLvf3Ssa0EifUTnAPp4bj6ugxf6eECLrUs/V4KSHIjCS3Lgfg5W3CTXrjnxkQe0hjJ8k/HCrq1/oFLSYvDXm3iFhqRzE7xUvmM7TVakGmHOx4HRfv+LvrE/NHxhE30tEJ7pv3vy5w/9eYB7JbHntipqa8rNZmD5RQF8DoeYFiSQlkZ77Dm4t+pUF3+i//aqYv5+bI/9Euxk4+LLKaxrziUW5YRI6RGOXDqcO75rJd7v/uoup8uX6OHXLvm1PC4hMWYkwUxgiKk++5nORweD7d39KSh7dFHNjSQ9tg4HlGcyF05wXc6OYsythIm+zPDdqwRlwWJ9LYff7WOyCi7Z7HVbLToN6BgMIu1vHhzswnDg+saG/vVLYNNIMuV3QifG6mPpBVnZJMkEPnwkl0ZQg4iBOl1h3N3Hh2E7VupywfdcLvj6dDd7llIZd0+9LQQ5GhZBzDjYqV8NOOzuUeGzaaaRdP9IH9aP7illuJPWUPKJINYSBJKxIL4RuAMd8WofJEE/cHd0Coktxe/b6nXn3dTLPkXvh0iXpAnF9IYPoT3twUexg1EZrkzfgf9Nb0DgiGS6EaHY4YgYP/jAIVcjjaISHl5DsSjdupylhH3qyIQy6f5SvvfFp+PG9ax4eBE5/C+N+mmjZgGC+iWhdgnWkScd72vA7n4rt1jC0aejgqlng3O8TRR/blPxHEdv1suqeE51VpmXmczGdWp8LNcjgkqE6Z3KauAgz0MdguUgDQ7ywz9SN7w72b7kuDUrr6DTy1hKrLp4pRuLVz2xEqgoqHzffVKtcUL46tZ41j2/xIzQCGQ7LrOwBVtFiP1uwutYZ/KCta33q2jR7WQX88xL7YrnTibqCXUJVCvEJvh4ZzGjQ7yKTY9ML6RXJnVWXwSjtjOSUtsbPWGM8YDuSIbZ/THMqL5LDsKsXlmk2o7ZxPq+yYt68Assuuk7cyOZYAkA6JIlOmJuAvyxJUDeMEpY2l34fL4WnEEDblufw1wdq5GgC2SHJBHhRrRJO7h5JAjqjH+8CFWruXzG5gN+k66/FJcmLiFzuRKjZRzDYs/SoWnonVNmMWXW6p0K/ygfsJc80t653Tu9ERhgnRvYPUMe949Ra0qXIu9yFyw0txcmEQ3gHpEKPdNR/GvtgxOyQ0Pu5eiU+LlrkpDdx8HlXpmIjSPefox9pnLtTqOThviH2uKMM+0bZDt+jb2YLGUy6qIzzg4ZOGON3WnGvoMFQDq8h0+EbQgqPT7twYTyrmlIwnuMLbfvgUNLY1ge3ZAXTGLmWwYbzlMLXH23tn4x2r86Pj69npgDuv0UA4EsMt4+ZeKtt0+XpUgS7VqK88zZTNyj2jycQllkSc52VupmZDv7jH2LtlRsrBkdfc6vxb0onQzg8BO8BwcEhP1/D3qAU509e+tPp0W2E5Al1SpCvdRBH7m4bQMlim2xQrfgNFH0CSKPKXw86bwnlRSyor6se/aOMhHLxW4hrN+zmo7MCdTBbkhSF9A6EicOywiy3p5/hX+by/QM7eWrlMu5vTUXswnY8qs9uwNduZ1TMDWoHZqwW+1mcGW7MiObAifmgeB7bV816wZnxT+AUU2PJQxRAHjBvuwhIcaFNLj0PCiLb7xgc7OzvU00d2WLmVF92GW0/ulxTi2d1b9YumRTUohkhP+qvl/ThnBWNoxaOaFty3MfTBaUDAIXScpE4BE5zIqNIJnv2e7jcMW+4K/PBVP/cqZODGtaXJj9VrqI+G3GoiNqnLbQQlJnFJRNoQZExDK0hQXrUpyFtkXKSa01T9sxH5okLJVFJ3EwueZYMBFGN3NBSn7H+QSWXThXBrUACrupGOwgKSU+JTHW1RkZk9QTAsSh/34HdFXHlP9b/NHN1lv81/ulEz+sTyDx1E32UYPSH+6ELpxOPS73KSO1HRI7+z8S+99NYu2/T2IiWUCZ1sc/3XiF6IY26cpOaLfqTDRF2Ar65pc6m8jTrstzZvOckQ0I1ZS5ZVg00s3epIGY6/e1sPeTI+zFx3zV+Yh3xZ/yqEa/s3JWr+iErjC0gQ2tOay/wea4V0MyX1ggMeQyJkejokPyRiwwN7ytY7Lgt7b59MITVwcjXNYQfJRr/JGqHhD5StwbQjAfiQOQBKX0B3SggWF0+YTnnmkscsxGHsURh4/hP7nu66zPCbfx0hitysrPXVWWl2n9XcPxRWGUqClKwYiHyQ/30EWn9DoFtiCQtfsP8dbl2oX/RMYx1jZcvmrcdhEtLCxPjGlyaew5YbOZZ1v8ky3/TgZ93NJFZrxpOZdeIONWaHgtBi5XwyiFytBDm6X0aGm+JkauVAGGqa1s6Jdb4gvqp2vEiPOpPUtOG1kUEoQ0uWzpC4vStkrCzs9Bq6VKSk6bgbyprMx3Wio5BmaXGu54/ToWhXCSGsmPFxrk58m7BixZvKwJ/HtcWpBLq+xYNVXL1T5nxzWuo6Y12n8Tn4KcjU8rWUzKE9tKcbgqj4vIykiHREeRFdiMCgizHxd2n7+TuadHjlf2Y3eIUhoioiT3gMDTqr3yaSqq+F90SsiphM3GWuoW+2vNSzR23XL3fYyvjmVsnYvj4xorKL7eSdUv1miid1ww3RPkKDsAm70n4gzBJ4e9w96x7E+36o9jpwl/OE1YaL6IZHYlv1Y8ePSFQapxEGYnOOazi4clf0pmE9XZOONmC8f/Rl5K46k+SeMad6TJ4YQ70hix3yrAeK5VxL51/M8cm/OR9LNrzkMxfB3Z7TH+W2La/7mirrsq/m/1RV32Uu60ouPJu6cObCF53lOkmXl/uLTWEXMTMdt3XCoCJnb4BkYnB6nvosJk7JnXSSJx6zq1a9Gx/YinuRVEh8UTuyzTezHfGl5bX9r9Oe35ceHbVut16hzbzkeS5qoGxAocwyFZawcr7Lad9Tojpzsf7iOKyYkxnlYlZVBQg1VOLi0uzi86EaeriGFILz9Eu1LXZ8u9Oj4e5dR33eZML2rzSRU3hNGnwumZRKumpBV/czAaM4ZEhPU0U/HJLIgGhrFV3TAaDDRBTbbSpqdSQqu2BOetSfHC29IE52i13NFRSfG2R5xAp/rJT8J+RmOHpyfkYTougZoqwQyyJcDsx11AatDQMKuI8bHOsjh/pl1p1/GfGUaf/T6Lf8Y3/1r/EOkE3UORn2pqIi+bFRdu9WgDvfFXtv9B3fY/u08sGmyVozwN7WDfZ0wgIq5/2P84JAcl+kacXKin821NTo+aHdCdi/b6Zn1zbVf4gsnSmsziloKOSAlGfSglGdsyIM5rYhC0g4P3gC3cPeLx3xrxP4/FOTOq95XTXiFjNKAMdXJeFoMsIyxWkvUGN3HjPZ69oU12uNJWy5pmxyVLhIgt2eaCIG0tCAq/3G6Gc4AsWkgbEBoXxKIq5y/Gw32J/yhixm7MNycbqyDV/XmVj+Tl8Rq/ivMYnS5+6Qnidhrcp+jKg4rV3btLxtzWj6A7vdVdb3Z3vN2P2u+b7HMBSGN6LSOhDmWdLk50wldjwRESqrhTHNUv3PrqZq7dcX1JtW2aWdAV0ecu37fuDMdbE5U3GEozgxKzwncIZuryxog92mnIIXFrMMHmUUeTn2HdsjCrlfhqRsXV9VqT+0v9Yv1yPMPDyNfjyH9/enGmtTpa+u3K/WoV+rY/SJxPOqc598fdD3AGFlMMdPxeX12ncwhumXuMy2bP3SwfYh7iMRDwA1Ihsj1zgPn18JRKwoOd/im9kO5eFGW6PvOKk9z1RO9Wgl3td1dRN8MOKJ4Cu0PzNSThYyKaiSTSKnMjmjjPVB+yMajkXkTRriEKmMahrD0pyW4qWLRB8rgVInnvPB1OR2nP5vcnSYUu/qJupe3nDaM8i9L2C/fjpfMx33Q/WsXHo6zdGrQNfy1KX60ZNDfwkh058pRGnaO90XSIyrSM3ni3ibE4tEhWgPavEhRI8fEtzLwHe4sJ/RrfWDi5AYa+6QbbZAGTq1kNbUblmsFDnEojGivZbN16adQsuFw1j6EkwbkHDaLd1d3WFAmhxms5eG4Li6TQTnb9sNKMv67qSV7fd60seLacymKxXp6H9ixXWjQ40O6SY6TXg0HJZ3XFBHytpiVTsxKbJvl9MebMsqDQMD9U65B8KROpuyFzuID0JqW730UXRm/zfPVCQFhFOYppNTme8rTayf1Xmq+fxr2LAQX2pHTMS1EmeoOhySwCTgDNplPDZCp2Q/Xy1XtdCrk5fDogT+gtab9ALnXrFjSsn+foof7aPE3Iqpie1T4PZzefLPQxmVfDUqPlcoDSUEW1uRbeml02kSYY/8ZlPMprSpdUj5OptAWnlrr0xbCCsLW+8XTPe8MvWzC51Ex32OtQWrVFrK3Djywlt2tLcDHmKwXs/rqBUa+rWlJMjWt48jQ494RC2VwIjkpCtUjTTOlmryR/2ToZZPhzsKh0oatySULvpDeOZSG6CaV12MutB87UmY/63WujYMTlFaR3HUxMFCGoMCaAdOpkmLFGezrc4OXXmCJ9xCpugTzRapbmb4WuFuTeyQV7xqEC3lp5l1poshc/zn3ISc4XLy1cMpSuEor8WQQlAn069w7z7RrPNvq+YgHXC+JMxljeuzckUx0Z4Frl0+reh60PbztsdIYIMXJxhX+G7I4y5vk/yc1Fl0xEw7g7eJtELUUXEjUT++ZYxZjaN6VLiDd3zI84maKwJW+BaV+ugX4INkUU3BTWL2YpME2lcEivYvH4zW9K6am9Mp4F3tOHedtBD7Dm+QUSiUT4OEYq/O4dTxDkGu2S5PqaEYmqw67Y1r9NWLHEf4O3rOiT2XO0eqLFftTsLi0TK8RPtLeFmm+QifrmAB8xEP1woMnK7L537NGF+FbpeuZnwZC72F+LXektTQVrahay16eD0W4MZZh/J3tltLDrZJQ1QMh35y5wbRFQmJI3bCrp7vwauVI/GL5/v33BZuSNblcL7Bzo5Y7aOUNWzmFLA8MDa92bXQJh2Bzwm3IGxTe7wZ2dzWBRjlJ2Qefrx9klOIgThTDvv08hgjhZiPi/3IGW5318RxH7O+9tNmc39e+77ZYazjLCfRouiJMNp03KcMvXN7RcZ5czic9FpQut2fngpDYZjOB99V9X8KGu87TvmUd+5DrX/D1zia+F1/34At39mXzvmC27zNTm1bvjsPu+xKHfa7aAq/jfMUxEtFTRei785pwHz9C7dU+EBtose/sbNE4G153pcGUSZsvoEKOTvYFwLE/y5MPhMxZCS5o+alYzgSurREAuzQvIpSYBuauTvifnnqAO56LP/fg4JxeyXjFADHYXiFfuvPsuUt6jpPP62BWW4ozF4XkQwyGFHSxS8xOGTr3iVDLStQW4Hr9oTn8lX6m/Njb41imdXzSbE2BvCeaMuTsrSN6U5OoslHC2HByZl1Lyz7rWF06tnwW20HRgvzGsfkZLBcaZFPjSyZwzrDJ9pVw9F8Plny7SiYsktDKJ9IeLJNQziTQUpBKllBDWgFC/oJC4LokVCiqhbAhKQXul1DeSWke+JbwPSTRjWXYfgaoiwiKLRUG08k31ivLXxrskqsW5t1A1U9BxHQvVmZhUK9hw4qIVsS0jOmWXlZsQAx8V0H0RBheqoJV2VIUE2dKanHTIp5Rxd+JDKl5SchDSyb6CmLx9HKoPx/TW/5gdcdSMCTsPwJjQY8Snp3y8IqVzllEGEoRrJWf0vVJb6RTG0dcu8jwjQ4v6et+K0OjR0rYaEan9TuHSmZY4eeC01N8uu33xCH3m5fLfmARloxppUlv9ggtxOnweDORxcE1UJdcR8W5jZuZGEoneXeGByJ245F+Dx0pT4GbjfRK0lRtTH4Ptjvc2W8k0xRdkkgUl1HoCyy8ymugrhz7MPKdZ4Bae/IDJnL2ev5+iR1dkPnR81ReCvou5PJySf34ogwnqD7VKbLPgul7fHsSEQbXy5kIufOTMC+c/xRErom1Z0QPkY9oKi20XCZuUYM80AGwRgBLZvfwWXZMD+jNB30C3QYFFrHCIhM9IqD3QIO03SitLfYDGGaDutgpYTrDKRgpwz4C5dxZ8QmB3sxTwHwQ22yN6BNCQQHpDxOea/sTpAV/r+stseABtCKi6xUW0AWoXpmlFe1f61nvbPQ8hCniV4mjT40JZ8pU2RAQkY2l3TjHVtTMKsDufL1+S9gKqquV4clqbtXPanDahVHR1OqEaZCUYFID4S/fG1cmlXNWpFaA7sQJ0p9UFupNKADulLekfFMfon51aqwx5FDmJzkyjkNp5BvxesxyUdX/h/WecBKBq4c1Xb+1b8OrUv8XEk2qMWhWqkkcuqkczjw5Ul3Eleb9uDybEYRykqolia/m5ZEoo06iycX+Zwu5StXus0jLD2z2uuOYnlhdM8jy6Nq8pVHkOMyz1K6d1MKPlF9i0ufmm1ZflbeineKbWUMlQO8pD5xzFKrRDnxcHNN/P1n9Z90RXJTBSbZcBFBLqaXYJq/0yvLgWEfjRoa0EMSW0+hFtAO0yneHug9qSRFPyU3sXNO6Ci+s26rZEH2IYQQk7FB6LKCMhiRkKTnETnawknbJN6v/ZpM7GF9NU/GtMU9vPIKMJbXPVmkj/5+xSyQY1ebjNqfva0zEHdelJwrrIcjTX7PMSA1bxew4lr9pFOWH8KIXfapYyTLYo+BetZi60uBxC5unK/pamf1xm2S1J1k5pXcRRW7A1ls3VtitNsJuC3WrKTY8Ye7ZDfC3KF6WFXWYT8kkaEaS3KsnLccUVo7ZP4m47RkoYrZhHSLGoHqt/1d9nfTAsTg8MMWryXOYERqmz6sGr+ZdKyjIZ6Q1TPxdHg3T3oipVNV3nme5x4OegCXOZFl3Yhl1rxYRoToOUHx9wMcWzACup71VP3nukTio+d+jTGHQuRVH1LFb7UOLDsWvag611a8dWuH8s5joHxyU3mft1AwTJuuwStw5mn9tPJmFLJZjEb9o5FuAIhdRAbTF1iXJ7fHC8EnCz1WQjsiU4XsLR9UbGhDbnut4jI0aAdsxKhmiiSEWq7CXc2l1mgknXwq9qGycj+vFYvNT9ckwPBz/Rv8X4JpmOvv6i+zZuIJwA+Wn+9VhxjqbyxX5f/D0+I4XBxoHvvnLh6eGj6GbjGItpNQ3IBZqJgIQkid0osY+KF2sqI9/I7eWsm8E58rds4KVRrClGxVFx4JfXSY1j+GzE4rtcg1AYZCGZRnS/nlAs5XQ5tpQ2vrz5hu6yr1qeN4qBkMbkBf2X8JsOAMHj0JVxSKOPx41UvP9SoytBkHQcIYpO5bw8EeCZvCr5wgEAV5zfHd/v5odn8Osf0B/kFQ13XzLEw+GK+WFQD/uELb8kA2NItC0DP7QwedAS3hZtj9IovzWySHros9F042R87qNgfIObDS7kO8Snj0p8v/Pt9rZbRkZtnCz/OQlRGc+4eyxDw66tarI0NyFy8dzSXKh+lo9jzhnHcZr7Eb5/NCnPjNx0oXpqHPVJl4Qb+ObEzF+iSUOGDglKcwHiQhQjSlxF4ltOfGsSD4dIX0U65iZ7FF38+9/DR1GPoyH16d33XEQhRHT8bwWeoXrRkCA+yeJ9jmg+57N3mGGIIEb+HgmJUhteI/lPsF8Hguw/k5AaQwEMLeDtHPBQJkIgPbnLe5AMkfVxg+KRWeHvUP5yYerJ3Go8K8ZRSLXxa9KdIUWj5D9vsIx1+YHPBSiOOhRq9MBEKloffGX//b6yPyfyPrFtkTKehLqQ+0eKf6ujwyvv1SkgerYO34rDWwx6cjPOR47bIBNEx8Hsw7gUfmV0dK0xvUIdkjVHb4BQ+ChCRvoi/tIyw4ykU3YybUIuAe9JhdfSqGPyMOb0L/UyNK7bOUnIAWDENcJD80p7TLyh4TJomGLd5yA/8u/xy7F9UJHhNIxPesWN35z6qUgdIvWTpOL3LXj5Knpn94iSdnLKbmF6gCnceL9xsIE5fmD+Iie3AMEgvruAW3e58XvsnD7u706KnQTXu/MKu2ezvCNhjzWRiT8OiZLF2dLPCYHJSZKvW0wzN/LVmGCLC+pMRyijD9c4ioqwjIzsdVAeKkeYHK5jTxz5+koqLjmr0ds1SdDuWP52PG0EEzuC7tFCihFtQbJSeIT23WYKUxd/2cHG3h4fMUIlEXnAfONx9Xm+nCLyDOuE9LtovqsP0JKgqRYhjHSQJFdkp/aSBVPkUSoK+ZoEX+OAdC5OWXHPlCUOFQi3+3xj3nX1BzcLwHGeEyE9JMeiLqypCBoa2SlRSU9lNcMYzwWkQlzxV7DrQ0qImCuzVsUd2MS2a/bQ0qr8GwOrNWcrcY99UynyRwXxrDriPyc27tcjhFzCiJNDT1879emmQvJyuvNiD4fcfh+tkiZeMaXjl6VUcp2QkwEdcEVSUh5GAwwxpuoonXNzhCNeV6giwPRiy6o3pqOgQM5z/3NdExUy22yOQgBm5Drfs1be5kcRMSOhUBhiYMfLVlrn7gNPwg7Oy3e2TQz9KPMDW2mDUGW9IJzZEnLBcLfBoVO7TEDJM8IvAurjQVIFjUCOUWKrdR+jRF0czWbZc0M6Fz2srS6RuA2G119pbQ3idzV5tcj/I9ptiLnU6Dca+ODGSca/3SjQYrlBzqA9G6TjnNgWlse5O7SSjQD3aen21vaGB4fIk0198qCm0nZ4j/qMWLR1TPoVsEG0HkIbuAwVQBxIBH05KXl0kmT+yL5ivuaJNyT2ukxvhKoGtE9kfGmPRedrFhBBlyvBzX45Drmr4le44Ce/HENGA08xpT6TYqmA6dU4s+PUxfV8mlLPp1I9T5x66mqwM7tcKWgaXfhVRA6L8eyPYd6bSCJv4c9wmOvXpwz7mAIk2RaiyWJYbCJMCLsjo7W0p1IVs+M/cMNSkL20Z/YpwLNKJDCVmUhgeQ+/zZokexVnnTo+6HSwsNcIaYanTfpxseP+Lp3Mqr1LpjWByarN6TrN6TrNSYtQG/TdrW1G6oQrc/2uoP+yS1vXGZNNRPuSUvtWYgK4lXbIqfZtHMWOgVrjDzhhDWjTTwr4U18CRxTxVtrLCUopf7eK70Da4ywcM94R5VNIriF4B4fivONPm95Rue1w2hc3UPDo0+kY8QUavb/4rXb1PbjRFD2dDysZQKT0AL8K64v1ortWUOcEdXdK+cbXY659ZkYhfomMYJpV0+JWCy2tzKb7RD6KHT80Pes7BbM1dci1T8bZY66yaEatXY6PLxE2zb5kXVrXd1vy5Mgzi7dIGWduGcTEnTJY8qc/Kf5YbRG+M8Qbek9i7loMvR/GXzRT9akrAbUmERf1v+jhUQRL2bOAD1EAAAj7fIRN+d8MAnK1IJaCcfsSEwtDtFJe5CN2z2tDBZrR62aQoLPJtVlehWE3q6Fk3iBOlnWgsqcbOvhVx+v9dTpE4Ew6hFZwaAfuiHNuQsB/tnE0fmemVBpgHB1ZZ0C/bVHPTL+QWo17GIMplo5Ux0x8rubWP+AXbA45O84cdiGxttiNP1ro5FlHHnIdOyLeY6GbBD3BRVwZvE1gXD/hlEMJ3VLtXkuXo/RPYLippjxlflfTbcGq+PJ86zhoCmdx70x6PCa0YXO4grjbtrrqbghQEzBbHGs7T3qVZ4Q/p/YW/Pt1oF/js9yL+/HlueviHDZwchWxSilrfdhz7KSwduBLRb/GW4BR6udGqT/PSn2xYc5cT/roRqbIT2xi4d0EaigsFon4zcHnxf6N7kG1Ek4ail77cwFtmzjJ5wHjsn0kXW81CDbGjzDkhZjG/Vzvjs7sKZ40ck1fvPrhcoxbCU37ciaFP3x/DvRbwrA/5I6H09ZZo7FzsSa3cRgcXY4yyo6vJzn2Yzjv8+/lqJ296BbOxJNZ+lQ1PZg7F5VlPI+6GB/NfkDgdjhqGcyM207K0aoHchKJDMWq+ztmd8nRg2KeHGDUOWfH3jIRKp2WA8kijgtzcUWI8vq6TF9pGMIPrjLEqt8wSNXhmh03PSvFTV9cIt81om0E5Tsr/bRnl+lJT1O8E+4ZoxTCCdus5XbSA4W5Sk0stKdPIe1Sl29dP2y2KrG5XuRe/258cZut0pWRpD3W/07zlZuxxgUTP49zcUbkkqW+5Hp8WqFV/I6DH8jdPbLFoev9rZDk25TUp++q8F3fdJXdq8Uqv1dDUZrDgCChkufopy38aR+pnAA5ACqnzyZhg9VnDeyPHw/WKOzi5zy+DOB8GlXOOUnb2JpPAtr5qilUE2c4KIE3aY9ieKdckOxNNSnymF5SfvNVfl8i6cIU3rHpR3TnpsL/HRmpDjv2HHV8zl8/oF8t/NqkH238wEZ8FrXKNJANUsfpGS6dOkz4Bzl4JzorBjQdLPKH+Y9zlo+5PddFje4q6nQ4KoqauhKXX406hVUOXa3M4QztwgjDbkjLr4Ydsyfphgwj/172R2jgOSRuVJFRFUU5YINODdIgmTjUZn9/b20iEBblUG32gyqb3OaMeFiXhuyVqQXvlk2XTNOgGT9O4GTnTeDXz16ofMOMfZXO9OoDPOHxVQ92Am14++zAruPx1ZPcicBcFvFqSeEjSKQNp8vf2Du+GtMzbhrwhl9rxX53lQpVVXJBGnlw3cLjYTZMnkR4JyALFUsB0ZMfQ2R+icgw2lbIoRp+PGFRDZMEE52RFcysvXA2FZDcUzMnoip/ACXIVIzrZ0M2efnnW7H0O2mj+LgNXS1Uv+ferT10t6/u8udGp2Nt1MBbR+nl6XA8oOt0cVtRVjjdFQr/XYLfNWqluDYK/ruk0CaQXU3imtVUjoPGyCbHXSyfEsisGzdGDWkx2YShD7YHMRphFRguUogGnufyLRnoEotmuJTlSxxwrKsCOQwpa0LDPFoJ0CfzEar1NIAOpUNA/mgyqmR7LRk+R2VAZyPFSf0zDIQqPrY/h6RjjD4fpqSP2kgPk8Y1G+TQyfcMrSKtEnSrCf7BL06LNE5ZSYzTYxKiVor1Q9Mrv+yQOF9hl6qDnmcEEjFufdaTLi479f0wgi3Kzi5uxzst9fs5zKQ6/jaugddycnjdb/u3CuqO0vCuJ9GfycRIqpS8lCQrSG78C3btscKPkzjapL+DOBr26McF8vKPETEpMukUC8i9K9jscUFOLGApWUcDdv0Rkii7TlqYa5QAuVTKG+cSCZpethqINFe2ldD109fTL6Ec3cLWhzc7Ha9GAbiEqS+j7n9cW9vY36/FfjmBjbvWnb1a3Od0j8+aa9oRYqeB16npY4t7s4+fZJQpYzcYopumj2RW1DO+nDdSRQSoLvX5atRD8rhXaAbWU+o5wBx8XIaYnIrTozlqdliAk6tTXPUA3jJwCmi/QcjWl8AGjlSl5NeSyU2nYl3fnTz2eFscFy76T48BK62ZOCQT/UXeXbUB3+o4aFpulcwFcnDEuhnxov3dJ5lLHyQlfHtnOGAK7yZxeta7JCOMp+LS5B9pmrqHWH3w7Cxa3+udNl+lZklfDt4yJr8fA5GrIwunlO1rMujkenGCWseXVznlAYAJ3GZyYNp4hy6XQo0LvZ2LKRAHzzHhibGoG1k+opqfhCoja0QJqcBCxz8mWvmERgWofqjxrAbA4tL0TyAnuAPy0nOqM9Pa8n/7IdVKSf6yL00hFmUPu7ewSRH+yQGorkCVXdDbRkrvhlxfgu5ZVHJgkY8d97olZal7IoYBNhFFUiIKLCxQn6WCBCyBuaw0r1yYXZb0INPi0YhOxdPh+PWK+lrVtV3be5Qd6RVx+vioe0lrjLmvDa1qoxglDfwdrTzvLGIKE5lQvxRGUDDCUsBbgRk7Uvk6zDXDZ8u/bgG0F8XgIX3MmHNz7M9Nookf5AJOOnidU6IbDNnV2xOtd7xgo+HRDowhAm1GZy+0yoXA9L4KCs8iX+5ti/gNBYYMxhPv1CyKX7l/mFiyrKPflQwMohywzQOGG0sBG8w/cdLgumRc56uNkeGkFklU/oc3qVqhZSZNw0qaZB7KRHxB81hp+igkO7DKTefcBZSZblu1L2ZPWplnYqBJC7Fa3OEFh76Q8tBrLv2Z5MMiXaiZZnS/1rsU8UbziCCCL7b/3vkKu4v1bUXK0t29IMHh4Q2+u1EZXY+PieFPoFlGXa2ODC7HWRmfbX1cTGGmwBND0zMTwITrEvKdGBBzX5zRfnjVr+uU3RR9uix/yr+fUt7OBVTOXWNN0XTjq8iu6NB0MuBXZC1siqMBSWf/aDabk/sqjOvH+aQe2C6EYm3g5BeqHi+KXv2iwDwTJ68kWMbcC2XKPesuVGVyMbX8igMRluyoGCkZXFcH6JpGSNRqcz7GvH5F9XhFSal03UV6Zl5VVziu4lKdzQ8SnkCVqhuy5ovdU9FNz7WJs4rKz6xJS/MgIW/Blz25W9SyW0l/+Rm7FM1/Wt4WxL5cYEId8nGYGeqw39IVkhdKe0olfRRiR66OT8bjk4eF+89KLhPg6dY4YVuabIi9oa2QZ2a2jbMaO4h+9VTaN6fS4qg/0UeJ0lc9a/JWfIsCao6yZ85RVvpQKbK23ZJ0y+U63mPt7V33EZ3q6MoupvMvNkl9d2Uv74pco+LCzvddgeezAceOwHttRZ05v17gxb3jU2NSuDC8rhGAcVnGBLfix3GMzSRNU5Lv7haKJ+XdsoCsv2vlXDTNwbOwGtx+Hn/JHVwLq+D+eFmboIOhRZLPemkcq9KVxlN+G1SRsq979m7Npol26x/gCm1lE+k2iSRuEsIdidt/4nOScLNJS7pybCmhVl23nRq0oeaacIDbfnqvIIZ0tOVIh4xMn8iWQzBH8ExxoJQI27IFysXXE0cR8guwrkY4PeT9viahqMlfo2Gcypc0YWJ/eXoZZ6dXI4fi+MbxBdpXioNfaVMeCcBdst2FqAwVIaH5ahLVvb/w/4P+RxcbtdmDuqpGh5OwI4go9y9hxRd+xMoO0gVMbaR5XIIV+0He8Ps2wrkVdtzsVt5hAYRHPGrTXi9zQNjkS2zFlxmg8XZ3+fhFqxm/EGGTyhguV0q3Qst3lYdtBVYjc7dujHbXyJMumwsJSNDc2+Rb34bNfeLQtm9YV4soSTheD2/z/GXWjns3ZLghJIvhZI7mPfZooQ+Ry5NDbGHzSdfRHkUABO0Zw1DJzdiD68YrMeymVxmSYM7BWCiTlqsU4s2aYLu8/s/AL3h72JAhfI/ao1Xh1fN2JJM+WDqNYzfWGpSNlNQqjd+Z9elL/3/Q/zzrJ4rXp8fA/7z8zwt/zuLj3ivDPBKUUwoV5pnehuhYe3bEeN0kSswl4D//+c//L/4zNnVnRcY+ZaQ8slLLeVjMdvJZvMO+1WDaDki7SS3PaEJyRTc2Mah9Gljp3u+/jz2W5KSLidOrW+ovGH5pdDYusvqxEVw7MtWKZJxu6/XTYpiz6mjeBsW7iDiKxr3wG+Y0qWqKXQpIJyggraUAR/oYkGrlhpQOM7TgoyRwxSd6LSJLYU0yGCdaEGFDqzse97hIeTRjS/N9Inm0/5RW6IhNtwhCO5AUKlcq7KwMqyvPxKh01Hv8mHUjuJ6pb6nDlcc90jiP4mAKZqjupckOoQgV3TR+iG4af6Gbft2jH9BNr/XU6x6qc1XFNJjfRH0zRqOBKPrXAmONJb7JwZmjXZKIjqZ3vRcd2iFQpPC+ANHhF3n7Ach5XP2ay3N1o2Bw0gINJ0HD3Q7jxnaYiU5dGwD+/jvZpab2mV7agHQ4DkL3VSoK9gfJH3lKEblpcxocU0n8YPgo1CrWRL9vFIHAi7CyzuPAoqm2fkLiO8eVPKrLp866Z5HNiN8TlZ+t8F2RKMdx6UbBZM9I3ZjTo8szXRPIvUxyCVkZm7FV3oeBuUro2nET78jrvcNYdOZHOFjqnxICVBTwjfdgK8Rmxgm6+EesAKE7osWm+8Sr+pZrsYmWQdyaRvmJ63S8F5R0hXFU6fK34lqrU8tZlLly6fAxZ0TRCZTsNh0dsaB0KfVZ30n6Hlkh2ndttuxR/KVkpKu9P++oNz31tqc2HQ72c+HzR52F33ag33wDk73u216Udjd70Zm1FSL7vmv9O33c0h8L9NGmj8Xn/EvASwReCLs4+8JY6oVK9JYYIeTT0nLCJoBAzE5jGO6SejeRCwcLUviieWwVwU/zsEP+MPDXDeyRFgsLvUsj9C+L0MOfsTCC9PELWHJDqYB2EKvOnJx0r/TtT1shLJKIIwfBKWJwXn4imWql+NmxcU7khzn3YU+eltKAnI4/nJ0Dlt4HceVuJLcxvdykj17fHMQ9sqAMIKVlN36Ik6+bKXxKnv2ftef84bWv/ew2FRmHPw8bUANC6txkSeYphbn7Av1+e6mzOB+ysfafuJQLG5k4mZCNdr5tkl7UpCDDYtgQ0aimithWsoRbBGnSn3SGGp2h4T5FCJa8cBCQPI1rEVjsRXpRunTUFD3fNkXLhrTQLqGhrfUFTqKGXRQXUJeAafVgN0D1RRUGao2CBL061yWWu4tRV25d9hCEEqRvNcnJAIe/c4sRduobgAWP+EH+1PL95szCkewsiU8izdAqoxVL3mXikuuXreMaDDe9Z800zK6BPYLCt/atFV13Vw5lUD/NDi9kA/FRCXidhacC6PqIfKf5zcbzBvhQpvkmwVJ1omMadu5bLkd8IluPjhjdqatxyp/W5phMi2FKZ+yK1eloMImwtb9jEG7V54RUmA2JlAC9zsc0+Jyw3881/Qp3n5N2IehBUVG0ahcGU+RD6e3HrfXyvRVtV/kcj1iflrw1KxTbwcBv4h9OKawKYWzPWsinbQeJcbirM9LF0HAGgrU4dFC6Zzg/Rpnei6pbvrNbFe5b//OC/LeKwE0Wyjk23D9GA3zxZnWZRGTp0/F33nHokY6/ihCS4GbmWaYItEh60fG1uyMDWyL0T/vbqx88uMQiX2JFSrvjvp5GKjy+HRzsemYePHkbQajzhIowXXw3I1g5LsksKuEsTOIM0dkC57bYazdTe1qQB+tvYfi6SVeIojxEfAj0mCWblyLfYBMTRwkfIjilUpvQfwYca+UmWFCXCa4kV/jfTuGINA7VfsJWGFj34GOiHWjaxwpSQ7Fk992n3fCOqD31tOYV+WPHj0W9888r8dbFez39Xo4dmxhY+L9oLqd08Kfs/hCiokoZXS4z/qR3AgCGXX4tdOhX1ZfgRoS/4v8jTtI4b9Ep6G5k1gAQ5u1NAtmFNvVbp3N6xKXv/qu4XrMqyoSk72g+6XaJlBmPIR6cj7okSYonDb8o/aBUupekK7q+TuywRDaegrb4ktWN4sAJYkMVAnEl5mPILjQWcS+WNwUTIKBpYmkVdaxrtiwzYaUDef6qBYTAl8tDVlnSszOMVmqU693ziZBTYSPOsiB137Ak+lL8ReFnybRFm300FakSM/zHznqYPFjXEBvdf+ze8p9Bobbwqg9yby33VyAcdl4u0WerPY/vFN8Lz+l78QU+M3zmUetWjzZdec6luMfIHaPxnFqoEdyDAmplESyumHWSd8s1vBewp+PG28Z2Pj4Z4HqEzgwBZehj5t0HQb/74naa/SS407CXBqb2iiYVAmbr7+pPSWEq6jRX5QfYkEAuXV5l/03tqKn7wF0SE0+UKIOspPLzisQJmpoXAv1eak63iRBRlmAuD7PkSE54B0hQ/B0WUdzxVsN3hZqPQTzZngH19yJqS4PgWiIW7aVVSzqeUio8hFT2dQr6J9yxJ1UOoodT37Xg3sYt+6fs75UNfoiXgxd5aQp+RYNnFcmmiJfiGiYZmyr2BFBUAf9tx3Gfgo+g8rqO0PrAhrANBZa4zHAMGJxjlh6+SUswMjZybGgjuw96lGLmk9ZwUdovOtx5UV7mlJcdkRQSpUU52ZRyPjpj5JUMA9WLcM4FLKilMqCtFsqAphIRyQWSEWOrXcZ7gU2zBnFBtSo1tNqqtVCDuaTaNQUA5jhq6QXF0GCkSKmURiTnUnLjBNOuhbYyzBo2rvBrTKPUfeyH7J4ve5Vqjs9O+mLxX2czRUBrcsithDVB5feQ4VFUAcZzLcUgKdNZvI5nIXdlPJnmVQXg6X4h2q71g3m99ipxDDrIhoP+iFGGfSAnPKp8KeFYR9mLareJ9MaB93OzwcFKqvwd0XvlhRevKmjY3p4vV2C3XXqZtlu4Z13v9yLHRhyC2oRD5ZHr894NlVfj+n7NSfbVmvF935X3cF+4WKry7TGD3uQxmcWPKq14tAOtCr2/cyJVR7viR6g170LmCbLgQtoEWXQheERFqqNW2zcPNSUneTmFE9SK9z7TJHIIcXls2q49j7rtrOrm7h3vuJu2lmz7SPAF4LkFtATwwgLc8CIxHYyb1dAT8+oKnk311GKSZNpmt3XWOZaUDmhGbSTdcC6gtKlhdMNXryDdZ+1mXO4iIInTR4GkFtLWkMxC5qW37ebEDFGtnqmWen9je48ZIE/3s7s+M4guziBLz/XBZOmF/uFTQNumzwcX+errrxv5avmKTpEI6U9euFM3HgOkImovBeb1Rhy13rfZ2nzTMTUPxZC1jte9JAezQV4JrusOpRv1l5PbNvlRCbtrg+9GceZG5aWbGCS+cBKd4Lw69aWbWo7RKxjzTQfDCc2rU1tuqrwhdNIpkDLNd0tVY+fOq1Vngr8ssZdkd4rtOZP4xq45rch6pAyVSY5hHDX8sgR/2VdxP2rqK+EsSBuErEcEFyIEMv3cG5CCRQOdrhmI250wFCKikg0ZtUpk1HTJiL5u7JcE2bZij0thkpTLPCsvNvTm0tNUJG/Okw6bwOO5JqVmQStJhbYgEz8qRkooy0100lzCKg/kJPFUBnWSdtKZtJPOph0nRjm9vhJZkg70X4n3+h3+20fDSJ70+Jh+HKfMRyw96WPCTBLSdFMNdZ24fY+SclfxXfQMH25HIr/T8eXVWl2lvkrUNbYjJbNQX6EbXbtatUyBpNRFzQa4Pkj23W0qtDWJjkQkqgE3iEMjUaTKSe3dGCt0yHadhPUCEWNahTRq3NA3HEf19neDz95R5Fsv92i1BKY3TSZ1izEvPIu5cqgYG1ujNX43N45KS2Kl3WlJhPD6TkEFra6JN7nsiaZiCnfSrEmOn28cGwflmFCIWPwmKeTiaJ68cB3oC9Y3ibkpFX8HdN6ctNKChArcr8eHhD7XOkIO5TFgjiF4Ur3IpVD2ZbmKF79Y1AfLJEYPW0MtUcimOCqHNCbyYHI1TaFgM5FdyuPCWqwuiZ3XeZDy+wpYb/bPR0TpFEmKDpV68Uvy+mkP/vI/6qSVOmDnjX69J4nv8ktI2IMRJe+fZryIjNW6YSwFpG2tFQgtR+yBEV0NlNqAHqH3uzZRgfkoeTWqO+srcnabrMx3nivXfuJrHiRsK6FuSFleGSLe2mrGSaXOSG02/kxRCDv7fNTqPGqqBOXg3qB+nEWqp+E9PKoZ1O8firb0+kP+1Xa6zETRVyaHlu2urBKaB+2RxLZy4llMmoLLyv1xlFTmt5uTK/PIzHIyOcPYM0q+Qkgv+TSGOc4FOx/B0vgt8OmqxlfQQ4xz1CV+VgCmSZDgsQxvaMlqxZcfRP/rdn9mg2Q6gaWh5C6IgmTCDLa1pzicop2XxuphEu+v/DCZoKkj46hKzDrYuF2Whj0fz4chksuVqDpEHOW1J2LlrV5lp0VrPGvjwQOuM7Lj8M3GzqEpCSwHA4RGnGm2ZIvzQ4UfVVx+1ujiRv4HdlnTld4Lpq9EN+Y8YPBvoTnV5ESOpZR1CeMbJkvLbP1i9DfON+Q2SARn7HQfhxktuhsSovdZQNfzzNYbrbCK6aa2STYxqyTB73n5rTNgMk/hQyuVjObNOtAWSmgHB++7f2oRZl756zegcUhsSPHknp3W1ZBl4PGgB8vmqQsdRT4i72tYa8VYEZljsKYvtfveaqZ3Ya4PyOEl4eoQ5qQctxoebTzT4LuaJJrmcLfsqDNrtWjFl13mTtfMNK2HUGoFzDSlSSWPut0iJkt0V4/2oTfJszf/Wv+gqO3Tmqtfg0l7j//MLu5qoft+SyzjWVnslx9sPVmW+pU3ot7EI29nv5zVZ02q7z3h3MhlCyBt6Xqe0aUmFZCdHkOIss5JUc4zQXVGiypD993BslKBuWP2CJPo8eKYth1Hn7QLO8P0ZgqhFQKi72tB8FPqSoL0hNRVKdOdwEA0ykMqfcilOx5I07KSl6gCgyDgfXImkdN9N0kt9tGPVSLr3OvFJb+2FpPOVhUOogyT/lHXR7l0fR/WUBTUi0LmvR9MaLDowh52C1La6vnYoILrndifksrVmHTEk6DrevGViGt/WsqoaQM31Jc5yuH9qY712RchZZOI+CEmEWJIC/xkqkFAcg+DgOQOg4DkLoOAZKpBQNpeMmIJHPewWR6EenPHTzMIpR5NjScjVg3PwcNH05hnNIkQv7J+Dl0aiQjbuIYvke8bktQnaNhehOZyJKCwEbt05QvFBnn6/VXJ38/gc+ayUP+IIu7Z6hgK6wSdC/yUXFKSBWXl3Q9qrWZ+VJvZnCpISqtDsEr3f6Mi37hsJ19xfk1r+hxbmdw4yMucsPwELAsxReSrLj9aYde/J5fGjH7i1R9bP/M9uvds+UknSDibac0//FBRCY7/uvScJsHeFPk8+mD5UOHyo8hkmT6acvopONSfaHYxfz5ZzgwjPQNip1XFEJM8PVmCclNGUSnpaFyQaGpECrc35ZoBkhUUKjXLyl2cH3Le2J+LxzjyqyG4JQXXdo5Fnp0PyLp38NWV/Vl4h+HYC/OgDg4+txu9RpwizeS5Gt4jR+LmIN9198jzMZY8lwPhOU4GSt7JAvpDqcxEMTJvRfSAKfza6ro7DjWl5ynhZhgPWq5b8PE8ydbY79t249yyNz18k1xu7n8Xm7MWf6BmWOc6VvgJTlYJnSKJ5w17Pjn1kWE8YOnwDbiTQ4IyVa+jgP/MLS2E/2y9bFP5qY3VD3NzeDL0kFOs789j5+s9PY3UX0eHXMqzpYUjqlKo/uspHPNIRDBbrb1rJzXLn2njhAyvK4HL4q5VLb37ZXsvz8CtOXNJxZKod3lYu8xmnwBmFuucBbrJzJNivcjnPjhbKEuAuI3MtNnqg6TA5rJWy3k6t32VX8ZrLYuerg7T77589V7L2eVc7eX5y2wSH5PiPvivdeIpPdRTZ4twhMR7DpGV6em+Nucz7ljM62aPk+OMYvGe7iVmdWRfqvZM3YFefmFJ7uVDgtzbieBnRvXhfaWx/h/p6Q4F+nc6KnRT6ahQwHdReT/vxelsIncCjPyRBeEEyRtFisKFHjl5w76RZ1MJf8Nca7yXmrG8PfIjhDGxee5Dy6TE9hZfNpulkbj/QBgiJj2ZM9kWdpdjjPsSwQshgquhDN6MHlFnPFth8MKjC//KTAtvEDlS2KPwYTd8vLm6BrV/L1mMkh9CEXcRwUMm3Lx1PaC3mMdywe/h58UAwuYxPJmbG6M8e7Isg4IXfvEFWTzULBb5kMPiTLHuLFMJ7+TOnlA8+ivvhoJWYYwOsmZbB5JQx56kABqVyewuqi7CNkyWscXlkrdGRFG0TvRwk1emBxKQ7lBiS74rTyGm6Ur5qBZ2iU5I9wXV6D4YBKLJl8SMd5BI1mP8EhS8je7DDIXmWOShioxg/IZStp9C/peVElbZvU/TqEvwbfTt5itG1ToLK44elGv8Xy+Wih2+jB1JoBKJ4la/+2R41x1KvDK0Y6nnUGZlH9dU7sy80FPCnGIFxIPXPqYYGItezzd9Rek9tkFX8+QMsIz1onndXrRIL2A9txiGbpVvrt0KkXe+EH9FDRO8aTW9yNvYX5s73NkOSYPfR/4LDKWb1qSUXw7Qjrlyls8hJGRqwNs4CuQv5uif80duMyhogtsQwvtT4/8p+F00bsE0bj0/lCSUcooTNg+qU4CQYlc/al/eZtU5uM2Zx2FzRuTtPq5qQWzktqfexvUQ6gDSOcT9hvWO7j27WzkLDj8c3vDBbavsSmn6FrBIW0CcpvlwDF3w6XnP17GnuCxxxB4Q3N287m5KmkEH87daMhrolqyt7+1sm4YAHJa1x/G99MB2omi2Z7dhYgvcgaRnwnpXd7+3l3GaH1/1q9L9FmSnjMJtl7ZDK+xyU0pbWSUKknNMop3rXzm9k+TX5/yWSaMRW9ga5+Ds1L+ry74fsg8gSSXzJoHafce1Mi0FsOiiPuwtX04vBxdEergPlNpxfe7S9k/aXxBqyTOeWlM4eOVxYEqii7+ti9MxjUC2dnoZz9CPuh5zDvKQ5rNe80zKfJrLr31xniN9kt9glH+kpX2KXS5MaJoPctwXl7TLYrxnG+sd4HV33meF5DHdDEuHtocj2a0nT9QqjRDQ5z2e1GCrxoa89Cp6j0PsJwx3lwu3YWcqVfnmyQyMnfsp70givMjVo9S3d9XPG4nyiy/R+NP5/V4XIG0hg9YMKXDJlQJ/zSekwKet5YCuC0O/rHzcCycPtuyRC7PRo+vLwyZuKc2vBjU8ivYOc/lZ6w+PU6X/pHafPA7bU7l0qxJvTuTkhwxLCuL8G0PTXF7b2ltlrs0bU4URtEojAfqwg/E6nuw/ynqPskAhUlZ9x7d39ydD7Ykjrld7Vh562DC0HzQEcjSbSSP3pI+WpY/Wj6IPOVX/OApp/3dRSMulkNbDKcTtej2N3KI1/NAOrLQhfO796XFOBxA5Sd19/dvuIwMdZ+57qKQRcafeOdcvSxM8W2S9RqTrm3t77S4o5Wdn80sQOyUgGVudZA0aYNJXkEKRHHqtBRlF6sj5x0LIFjqEz98v8N1clvwkYmdARLs69CtU9yWRMW1RD1s7UnaZRMSgK62Zb9N15fEISTSPOhpq1eenucWZmoJhKWpJ7sX021eTC+cATe9hfxpX6OYeREFtu7yTIkR1MkEQxjEej6W4aay78sbhhkzsLwqh6HNOu+Cv1riCjq31lky9Y+uweo/NmMgciW2OhJV4ek91OAupx+m8bc2Q6MNXAgwpde2DTVvjeAimFKSEemvvxh3j85p5GojxNC38uMC1Yn6Y2bhYeP755ZQUJfr6896WltEfcfBDCqp4jvoxZZ4e/5jGwX2UMSnFnUsWUaHd5DKPz+CN8VZCet/Kis5MZVsXD61FqlAU3sy+ezKGbn64IjNefaNOvNbXouRjb5d0js88ocenhOodvN/3QyV5tYZqa91XeDR3Qk4UGgLbWscpemYNazmcgR0TMEcN24hiEfcna3CxhCjPjoO3VsrcvUogTEJv4+A1EmrG/hW79QmZhMNuFrV04K1oMSzr16RzHrmipDOyytTJMUUH7OLA4EqxgjdxPI5mNyW5r3D7EP5b2zKxBZvYtdvN1vKmdjPhkb1ROXl+mR5FGLPcMh8tmNT3sFKq8H6cdHZ/pC7ZsqnM5Qnd+pN7tIaUsO7Nh69vPoLyMzYvirym9+9/T8CXI2/hhff4sVeBv4q8RQRQ8O/oqQz2wsL8/AM6vSwwj9peUhXMEHGkt1fpRan36R12Y9/RKGenqE7I/Qg+xlr/MQTvd/GUs2wLWNVuOIsS23DdLabhjM929WVHeS04TKxuPUi3xWReZoAwDPhu8iTb6R83RdKXh0yMu1LQ/x9ILWPoYXqeHdRqi+xDgeoApjKA9yanFDP8o8ip/PK79uxXeQruqKPmF+SAdybvxd2daPKQ5xKmOzZ2VGSrQoO90nZFUmP/mC+BjklqnNGj6Px4qk5sb9Je56fcuAOPVUtUYcbklzjfneb1mZjX38dM/uBUpEz6OxEQ1Rh07+M2IWU0srob3yC9cGwRXJLCnJXPvs3hWF9SNvpEUkSh8O72pkLB5QeX+fX1datwXBz4BuYr7WGggLV9RXa24fLjf+Ca4PVa19tGAhyv2I3LIOrK9X0d+72XlzYnl7A/45bTbZWn31xR4wWiAaaDMhDFkJThnqHKAsFAjJrO91VeKDeAxTNLh80iFq4EKfWVOLR3cKC30PWJGU1mqt9hB2K+0rjyaacxv8CIi/BnMARGoAILZIsGOygCKFNDuRiBucWUkumj0ooPbO5AGAKQb0a6D41M0kW7hi5aZbpod733LGHFdhdPnStfig1HrbVyKA6Jeq35KiXl7Rvcbv5F5sBV87rNxhX5mHAEU46OTELpNmqMe5TJVxcZ2XN11/q4+AOg+oyHHaT5nCoyjgfXKyuYffKYptvG5cyrP7MQBTESnOKP64RiaNUl/Z4RdbKUnCtew+6Ws5F/RfapzNFxMnmJNSs6joNn2cRU5FAsrLlPkyMhxrQZoqi5NtaMzG4epWOjkoW1MzwZHR1iPIWZNTaUfu+xye3YULby2FQdd+Y0BOGMnovDBJRzJydXaZQzL8+62X15eTqNl3PQ+4a+MBhcCnNBNgvxlZNsM3zIx5r32RyWObqpyKBTi+D8hMEdBUwnCxlTAv9wYiIBco3WhoJm9G+ecDiTKO+a+MqeQJpRFn4DiymjZPBS16e75qX4S4muT6lEepvbLlKtHh/e0c0cfWs79aGw1wF9QiMYRQ78abtcgAy+tN51voLjMD+FoqHxpvMcJ3q0fpFAOaaul7yyXghZ1osQe82iYRRZNDkvmiz7RJEYs4F2NGErcn2FXWd83F7tsQImH5EixGTDA+pE6FV7kZoMd8NOz8msnjZeZ8Y2G/s0+X4hCX/tjWK5kiuFbrHc/y0ZGeG6DjnNTZz3zIRkgYupg8F9qkgeXoUrFJqee6tWmbiZydzJACALqV7p3YfGIUipCTw1lRbo68ZySz5hJ2YnhHZ/kAaxTTthiBH7rXbWXZ7MUWU2pQ/rjFntBts4bWUmWeKjSwo9KxTX9191nhVf3UkTtmWrBY3VGTo81AoTwzdbzbFQtrtrLdmz0/odhncTB+u54Dta17s6ze7duvn7ts7avYndEWboMr7I8PpLxNWtdQqpAM+CvvnGuteodl7eomUUwL7itUgMlR7eUXY7fu+evvD4AHEyoCiRfAFz73lhg4eroReMaq94vq/1Ylb3ve1fun/rtYlefevrGAutxI2MbDaoaBEfTFqdBBHfxaDjoyLgZtyAvRm9Gc4zkdqco9vjx7QpzsYIkskDXz8OZmUiZbDksjieOU+9zg4nsh4ZdO3HwbzyAksGsgYyzGJq2w2DuUqlalgZ0ZCSeb9L3hw1zICwNchMBaPQN/nMJLr5NKw+n55Xy2X9OXiTM4GI44ZZpRgbtajWMsWOBLp1K3aCaarECD4xvX1eWgYblVeXIn806FXomhZ2gus4aC8uhmwhKszJWvRIi5LQEJqoarQlq7VYqRdVu8l3WBTLw0+5LEGZ09feEsqZtCMhE4GKpmifCV+cJaPhOFrm0vBGUqtDSueC85QdBMzIWXU5SDlcSK1xwR3lyW/aYTRlmDcYksPTWZyXqXsgirkHPeeQvCX2QlTFW7Auf/KAJJP6/duxBHCdvSUvTd2Sf3nglvxgkpPmzb7pWSppKn+ps2Q3PsbggcYjp9z4JUNZ1XpbxNW9mZhtuQSagTFPGEtljPtQAylfJjbIJ/d+C3E6lCGjrDLLLvSOOXa3SH+HexP3PTI8G/n3nvNtYn4ASL5Jg83vpAHYRP4tEti5GifkWxpXpweQvUbnpxMGnVsXBgMvYHJEpLnX6jW2mpVJ+/6eDi8H+PH3CH61Dw91yltDfya6uQ5P07VJ7eU9kkzfn06MzbwUWAYucEn3GaPVvzNADgngkO7StQu/N/d6cW9ClqVLt/kiGPywCZaD2d+YX9acLq8PPISSo6VWnWHRUQBwTmvxPjNk1XFTpNvqPif8jPa5AxZ10UjjgUKSXEm33vWWhKPpsjcrckpD++9mdvmi2W6Z0rHlW4aMRXuMWx96WL8PaxBRXARp9HN2mDWQD6Yl9LSrv7VOJRxBv4lEfkprizAokOZqssD8wjRja3eTAwSMnIZs7U5twjvdhK3dXyR2hVs78lXrtXjaVKjf7Ue+4wYJAnnWoJ9I7zvq+dx8WhZrW5SaJMuOfHJ6mDWkBxa64tfwQUhBE6zPRgUv4vtzDOztLMwQqJpN8S4wLvSh4mib/7bZSA9e20uhGUdxkIdAzcvB3+fI/UwJ1qqBtWtg85C601LYLAyqH3KbUkdxR3gyKjIKGP9UFYNaXiW+atF4CauS65gLHucV/7MO22iPBZaipFzSBmaOgIkjwadM9dXhmcqOygJcVSy3S+JzRkFIv1uME9GcxDijaHglII9gyx3zNQQd5BkdMPUL1uUn3yP3/fZfLfdJc8dWbWJkZM06KZhjfJazamtgCHosi2F6h1rzCMJXv1XW7ZGVzVEQVc2+Oc/odSkLbiYFqqoiLEpWN91y6+poXF7P7tk9xur0ojxU/+8Mxt3Hp4NfiXv9Wr9LF6MoS3ZkMfhyYr8xsfs0jNdHujSSdHdbcDHCb/cXBuq9mbuTfW1FdVcJj6IcMwvWjtc12ir9axMpGHlcd6x2mBefhlPefm6tIn5K/8M0qk2RnfEBNUmr7GRbtoaplhLFv1pN1ASSTdyRotsKq4OvZA9CmfVZ1ETlSZ6ya3grCU0/8Sf8UOs3kYQqVbscH3eQnwsDU+h1ZMbtvSYJD0Cgt1Z1qYpqgLrnki1R6iuJaUMpWaX8ZnWR0uA7rVJmKUTEXKUqsySOliTkCKEGsmt3HWs2bUHIO4mmBSP2qQ1rl2u9xok9rPj0L/ZjZiZ+t4zBvMMYYnj85YcVHN7VwV4cRP6yHhEdjiLiAJts6Mbs3dmYvXs0Zu/BjdlzG8MeqbRstwYraIJvsvesEYtrMS3aaQhSbiG6BHNsxRvn04rEfIe8TI38I9NFeZN6i652k/SiWa7SwjPdJxhtWX/h93sS+Fv6/U8C45TdH386fXNKZvvug/a7Hgr+lk48FPykvewWLsv+wGp3uzZjQcWR0xhELSYDmYoLa1cpO9NqYFcrB+yqi425O0+QVZTv0xVS3KC/gNVYlfuql0PNXgZKXCRHL59e3gwF+4SwBVCDiQdqAzFDihvmd0gmOnbgdMMxv6Vr8q8YOrGpq+Fh1srmiaB4X01pRkcC94N3ja07PnBdtvJEDHRqWjZftghC66cV7KtvP/c6d9XsrA3EDIxVk93vhgXNwF+vrnzGgpAnIxxVdXFpOUu6GQKrSjIBKfUPWiwzWxPObusfR3bWcAiSF6vwsEY/6nbxLOF1kmFtk6+2dotDuaZt42xgCb/n9e+FbtoyHufTdtP+WrC/FvUvnxdbW3bZO2dnnTyW4SiXB5aMJLpRxdhiB3hIH8E7/r+u8svS2esGdyvKtw6/xdSoPR/qmDo6yFnckO6PrBvwVzmHyEmLpMMM+A1zrQCXfbJ9p+Z9tBSOQp14aUkosVURxfA1+ZmASsGJshpLCQTlvdQx174K2gvqEbFs8ulaJGw2tgL/9eXg64h0FrFazcUHOJzlmSGYZmGVNu+yqbpOwmvT1GuS7xyTKv6eZUIlyxeb5Go/vjwfufXzWpR0tlr4SmeVmNFozk97ymcHJbDGYIkn7uNNWxVzxbeBbTKuoo4NX1FkhkXO8PsFs89H8rDehKKxftJOeiziWPchQSK3jGyqRYAxP5s8rxRob+YSl+eU0EYZclu8tMa1SK8XpGW/IhbsuBIpF4rmuIVajyLI2rFZHSciJbA8vCSwSBXmQtScJApI8cOaE++y3+ji+6DyvY7vdeVCNgHZLEG2AdkGxPHAr6ANaSr835FrdpuacAEpLGqtA4MuKokYhKXCkSSbRxEH/URzA8DLoarO6D4brShnad2dZbuSpX1Xllt3jszrTTtNWeMPMOEAcxvespXcTGzfL814NkhNkkilYvazc7Emvq1A+OQlSAou3OBA0h5pEnKC21qqIilwKk37vppOyEk9ISf1hOz6xFHTCTmpIeRkgpCbTV/dMXRq2tA1yc33omw4NB6MUYSmileed+A5ChyI97c/elbHvdrPL+827Bc2cm/v9yWuERL8E3E4HhMVzOZFYdWC1FlfyqNglvHYI4N/3TdnVdsjmXlY7qvjXlCz6kP7XmD1GBDmv76aRn7GEo3ZMWbvXZ4P9Uc45xpxMwwSe6n7KjVnjfrkRdXvqbSQwLVTlLpbB9rHnYmxAas/HjfIpSxKxCxh/6J4hL4vMXlz7uYvMGnliKHaujaRlKrRbCKhm+08puaT/CqhpsYIf3EoSW5AtD7FOOmfXpzZst7jw1cCDMOKLxjy8OKjt5+PVa4y6m1vcPqGHrFW+mh7uJ8EidXdN0Ynp8djPLHENh1BtmktgMtepg10TDTnaRhaaJTqUMASE3gecgNVuDPML8j8Uzep/kZni2uVDWOADIH/LD5HABTJ88yfi5X/e0J+3Dg2LaHkl/xqF1/H5M+U19Y6PO5CK5ZNq0+lcihAdamOmjwKMJs/HSOtqWoqfbtx4JMEIuZMv19eXezzr8lge+uI3KefuV5deIJFEsg51n/ZAlTKoj5UfRs5EVWNO6PGeS74y37RDHIiLjVMcg9EelpPQvwEIZbm0FiASkYPnmjTMxvnRZpI3CXG4b1o5b6t6Wf45OY8k8FfbbhFCqZ4mXPYGrwioVNh33vGJoaI766t0MBMpWiqyLBS60n6H49ev99Ze/foH/+gmN9gfuQx2qQyKJMDjbOh5xQ70iJFqK5dukLCAxrs6a7/IoSbzFFueBs3UMCIGidtwtcpHe9HqLd95LTql9U93aai+koWI/BUwE7TKLsJdY9/LnA86HFxPekNdaTndkSVOkJNxr/oC8nt9NcmoY08jiPy6F3pbVO9wNvzfnUQXuhBUBc4inTOpo4R+M1pxgFDLjhqvdQT9WlyKElph3H8W8YTrDA6o8FNKaRlggCN0PbFSO9qXPlNw54RbtyNq88qMicePDn0nkqNxF5FThHqJhRn9W1MWX20giCf1Kw72drBasd26Xm89uzan1TJikX+uPf48QBbp0TM4M9xT+4ZOdj6rXgcKBVyk3ahIR0+uODgBudSRcUjd+BwqGOjvHb5Xtn7/WVPOKec0//CZh2qBDNSuhK9Tmh0f+drUWSQdEsdz2kzH6XaAF1OQb0oukTL4AhtuSwdkqgRhE+/9kzM3eseigS77yFD92svqkO/dXuUgSFz4yq9Att1esBTib0hTkkP4TcbC6ROIusOvqk+xsVCfnyMEzZrW/Ms8unUOIEjIm5saC65OiWDpmeJUBsNRBhWG4cN8SFNazWafk0ZkIpqSuEypIRD7Zmfrhv8o8gX5/xtXFlgb0zPJsvs56Dz+i03xoqMcTsVy7b7oEgILPkgGMsI2+jsFtKTS786mYNhfZP0eEmDVBZVJqY3a2JClRfnqUlq7ZK2IVvZJGrtBGVSHwmps4cO8nG+kR6Wcx+B16HECMr2k4YY3gcEuhY9cgmXSi8aUkkDy/xMqp7P5m4lUy00nHwJ5U+fhsr0jNozQoOpH2gUApBofVCosBY/27MrKrNF5RBgJD0PFS1NxUuTxj6o6mvsZNOYarl49PrmIO6RCBr4zCz1VveGQiy9SayeCL8pvDOi0R3JxvD1FAPy9dBAjiL+FXY3op+JZ9mqJhiTcKVb51ZS9ERO81K6Sch1CwNftGV+CFIkUUUUR/jA3JRUS6yFa8RZRrxpO3odB1dJEOJn4zqO3uddqHLSlxIFgvpX7xdR+8QfGZ1tSKzwg2xUPMHIijI5KsQ7quML1/GO6nidT/H7SeBW4at0bW/u/Rtf+fhHvI1+TI64dfPSOjRj2Jr3uS/yehLRwUj2RfPQWgpc7WOeIXPfhSus4H7IFJNhIyc8O3t3N8DFvbsBs5GpAZuCVwmeACGbYnks+Zy4l5QJTKxLtpMKjANxfKhCxS3JTtIdXIjMGr3NJehFiFJfPdNi9/8PGBneP4S7AwA="; +var Medium_IntelAmtWebApp = "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"; +var Small_IntelAmtWebApp = "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"; + +// Check the server certificate fingerprint +function onVerifyServer(clientName, certs) { + if (certs == null) { certs = clientName; } // Temporary thing until we fix duktape + try { for (var i in certs) { if (certs[i].fingerprint.replace(/:/g, '') == settings.serverhttpshash) { return; } } } catch (e) { } + if (serverhash != null) { console.log('Error: Failed to verify server certificate.'); throw 'Invalid server certificate'; } +} + +// Various utility functions +function debug(level, message) { if ((settings.debuglevel != null) && (settings.debuglevel >= level)) { console.log(message); } } +function exit(status) { if (status == null) { status = 0; } try { process.exit(status); } catch (e) { } } +function getInstance(x, y) { for (var i in x) { if (x[i]["InstanceID"] == y) return x[i]; } return null; } +function md5hex(str) { return require('MD5Stream').create().syncHash(str).toString('hex'); } +function guidToStr(g) { return g.substring(6, 8) + g.substring(4, 6) + g.substring(2, 4) + g.substring(0, 2) + "-" + g.substring(10, 12) + g.substring(8, 10) + "-" + g.substring(14, 16) + g.substring(12, 14) + "-" + g.substring(16, 20) + "-" + g.substring(20); } +function parceArguments(argv) { var r = {}; for (var i in argv) { i = parseInt(i); if (argv[i].startsWith('--') == true) { var key = argv[i].substring(2).toLowerCase(), val = true; if (((i + 1) < argv.length) && (argv[i + 1].startsWith('--') == false)) { val = argv[i + 1]; } r[key] = val; } } return r; } + +// Convert an object to string with all functions +function objToString(x, p, ret) { + if (ret == undefined) ret = ''; + if (p == undefined) p = 0; + if (x == null) { return '[null]'; } + if (p > 8) { return '[...]'; } + if (x == undefined) { return '[undefined]'; } + if (typeof x == 'string') { if (p == 0) return x; return '"' + (x.split('\0')[0]) + '"'; } + if (typeof x == 'buffer') { return '[buffer]'; } + if (typeof x != 'object') { return x; } + var r = '{' + (ret ? '\r\n' : ' '); + for (var i in x) { + if (i != '_ObjectID') { r += (addPad(p + 2, ret) + i + ': ' + objToString(x[i], p + 2, ret) + (ret ? '\r\n' : ' ')); } + } + return r + addPad(p, ret) + '}'; +} + +// Return p number of spaces +function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ' '; } return r; } + +// Parse the incoming arguments +function run(argv) { + if (meshCmdVersion[0] == '*') { meshCmdVersion = ''; } else { meshCmdVersion = ' v' + meshCmdVersion; } + var args = parceArguments(argv); + //console.log(JSON.stringify(argv)); + //console.log('addedModules = ' + JSON.stringify(addedModules)); + var actionpath = 'meshaction.txt'; + if (args.actionfile != null) { actionpath = args.actionfile; } + var actions = ['HELP', 'ROUTE', 'MICROLMS', 'AMTLOADWEBAPP', 'AMTLOADSMALLWEBAPP', 'AMTLOADLARGEWEBAPP', 'AMTCLEARWEBAPP', 'AMTSTORAGESTATE', 'AMTINFO', 'AMTINFODEBUG', 'AMTVERSIONS', 'AMTHASHES', 'AMTSAVESTATE', 'AMTSCRIPT', 'AMTUUID', 'AMTCCM', 'AMTACM', 'AMTDEACTIVATE', 'AMTACMDEACTIVATE', 'SMBIOS', 'RAWSMBIOS', 'MESHCOMMANDER', 'AMTAUDITLOG', 'AMTPRESENCE']; + + // Load the action file + var actionfile = null; + try { actionfile = fs.readFileSync(actionpath); } catch (e) { } + if ((actionpath != 'meshaction.txt') && (actionfile == null)) { console.log('Unable to load \"' + actionpath + '\". Create this file or specify the location using --actionfile [filename].'); exit(1); return; } + if (actionfile != null) { try { settings = JSON.parse(actionfile); } catch (e) { console.log(actionpath, e); exit(1); return; } } else { if (argv.length >= 2) { settings = { action: argv[1] } } } + if (settings == null) { settings = {}; } + var settings2 = {}; for (var i in settings) { settings2[i.toLowerCase()] = settings[i]; } settings = settings2; + + // Set the arguments + if ((typeof args.action) == 'string') { settings.action = args.action; } + if ((typeof args.localport) == 'string') { settings.localport = parseInt(args.localport); } + if ((typeof args.remotenodeid) == 'string') { settings.remotenodeid = args.remotenodeid; } + if ((typeof args.username) == 'string') { settings.username = args.username; } + if ((typeof args.password) == 'string') { settings.password = args.password; } + if ((typeof args.wss) == 'string') { settings.wss = args.wss; } + if ((typeof args.profile) == 'string') { settings.profile = args.profile; } + if ((typeof args.type) == 'string') { settings.type = args.type; } + if ((typeof args.user) == 'string') { settings.username = args.user; } + if ((typeof args.pass) == 'string') { settings.password = args.pass; } + if ((typeof args.host) == 'string') { settings.hostname = args.host; } + if ((typeof args.hostname) == 'string') { settings.hostname = args.hostname; } + if ((typeof args.serverid) == 'string') { settings.serverid = args.serverid; } + if ((typeof args.serverhttpshash) == 'string') { settings.serverhttpshash = args.serverhttpshash; } + if ((typeof args.remoteport) == 'string') { settings.remoteport = parseInt(args.remoteport); } + if ((typeof args.out) == 'string') { settings.output = args.out; } + if ((typeof args.output) == 'string') { settings.output = args.output; } + if ((typeof args.debug) == 'string') { settings.debuglevel = parseInt(args.debug); } + if ((typeof args.debugflags) == 'string') { globalDebugFlags = parseInt(args.debugflags); } + if ((typeof args.script) == 'string') { settings.script = args.script; } + if ((typeof args.agent) == 'string') { settings.agent = args.agent; } + if ((typeof args.proxy) == 'string') { settings.proxy = args.proxy; } + if ((typeof args.floppy) == 'string') { settings.floppy = args.floppy; } + if ((typeof args.cdrom) == 'string') { settings.cdrom = args.cdrom; } + if ((typeof args.timeout) == 'string') { settings.timeout = parseInt(args.timeout); } + if (args.debug === true) { settings.debuglevel = 1; } + if (args.debug) { try { waitForDebugger(); } catch (e) { } } + if (args.noconsole) { settings.noconsole = true; } + if (args.nocommander) { settings.noconsole = true; } + if (args.lmsdebug) { settings.lmsdebug = true; } + if (args.tls) { settings.tls = true; } + if ((argv.length > 1) && (actions.indexOf(argv[1].toUpperCase()) >= 0)) { settings.action = argv[1]; } + + // Validate meshaction.txt + if (settings.action == null) { + console.log('MeshCentral Command (MeshCmd) ' + meshCmdVersion); + console.log('No action specified, use MeshCmd like this:\r\n'); + console.log(' meshcmd [action] [arguments...]\r\n'); + console.log('Valid MeshCentral actions:'); + console.log(' Route - Map a local TCP port to a remote computer.'); + console.log('\r\nValid local actions:'); + console.log(' SMBios - Display System Management BIOS tables for this computer.'); + console.log(' RawSMBios - Display RAW System Management BIOS tables for this computer.'); + console.log(' MicroLMS - Run MicroLMS, allowing local access to Intel AMT.'); + console.log(' AmtInfo - Show Intel AMT version and activation state.'); + console.log(' AmtVersions - Show all Intel ME version information.'); + console.log(' AmtHashes - Show all Intel AMT trusted activation hashes.'); + console.log(' AmtCCM - Activate Intel AMT into Client Control Mode.'); + console.log(' AmtACM - Activate Intel AMT into Admin Control Mode.'); + console.log(' AmtDeactivate - Deactivate Intel AMT if activated in Client Control mode.'); + console.log(' AmtAcmDeactivate - Deactivate Intel AMT if activated in Admin Control mode.'); + console.log('\r\nValid local or remote actions:'); + console.log(' MeshCommander - Launch a local MeshCommander web server.'); + console.log(' AmtUUID - Show Intel AMT unique identifier.'); + console.log(' AmtAuditLog - Show the Intel AMT audit log.'); + console.log(' AmtLoadWebApp - Load MeshCommander in Intel AMT 11.6+ firmware.'); + console.log(' AmtClearWebApp - Clear everything from Intel AMT web storage.'); + console.log(' AmtStorageState - Show contents of the Intel AMT web storage.'); + console.log(' AmtSaveState - Save all Intel AMT WSMAN object to file.'); + console.log(' AmtPresence - Heartbeat a local Intel AMT watchdog agent.'); + console.log(' AmtScript - Run .mescript on Intel AMT.'); + console.log(' AmtIDER - Mount local disk image to remote computer.'); + console.log('\r\nHelp on a specific action using:\r\n'); + console.log(' meshcmd help [action]'); + exit(1); return; + } + if (settings.action == 'help') { + if (argv.length <= 2) { + actions.shift(); + console.log('Help usage:\r\n\r\n MeshCmd help [action]\r\n\r\nValid actions are: ' + actions.join(', ') + '.'); + exit(1); return; + } + var action = argv[2].toLowerCase(); + if (action == 'route') { + console.log("The route action is used along with a MeshCentral account to map a local TCP port to a remote port on any computer on your MeshCentral account. This action requires many arguments, to avoid specifying them all it's best to download the meshaction.txt file from the web site and place it in the current folder. Example usage:\r\n\r\n (Place meshaction.txt file in current folder)\r\n meshcmd route --pass myAccountPassword"); + } else if (action == 'smbios') { + console.log("SMBios action will display this computer's system management BIOS information. Example usage:\r\n\r\n meshcmd smbios --out smbios.txt\r\n"); + console.log('\r\Optional arguments:\r\n'); + console.log(' --output [filename] Optional filename to write the results to.'); + } else if (action == 'rawsmbios') { + console.log("RawSMBios action will display this computer's system management BIOS information in raw hexdecimal form. Example usage:\r\n\r\n meshcmd rawsmbios --out smbios.txt\r\n"); + console.log('\r\Optional arguments:\r\n'); + console.log(' --output [filename] Optional filename to write the results to.'); + } else if (action == 'amtinfo') { + console.log('AmtInfo action will get the version and activation state of Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Example usage:\r\n\r\n meshcmd amtinfo'); + } else if ((action == 'amtversion') || (action == 'amtversions')) { + console.log('AmtVersions will display all version information about Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Example usage:\r\n\r\n meshcmd amtversions'); + } else if (action == 'amthashes') { + console.log('Amthashes will display all trusted activations hashes for Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd amthashes'); + } else if ((action == 'microlms') || (action == 'lms') || (action == 'amtlms')) { + console.log('Starts MicroLMS on this computer, allowing local access to Intel AMT on TCP ports 16992 and 16993 when applicable. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd microlms'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --noconsole MeshCommander for LMS will no be available on port 16994.'); + console.log('\r\nRun as a background service:\r\n'); + console.log(' microlms install/uninstall/start/stop.'); + } else if (action == 'amtccm') { + console.log('AmtCCM will attempt to activate Intel AMT on this computer into client control mode (CCM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be in "pre-provisioning" state for this command to work and a administrator password must be provided. Example usage:\r\n\r\n meshcmd amtccm --pass mypassword'); + } else if (action == 'amtacm') { + console.log('AmtACM will attempt to activate Intel AMT on this computer into admin control mode (ACM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be in "pre-provisioning" state for this command to work and a administrator password and provisioning certificate must be provided via RCS. Example usage:\r\n\r\n meshcmd amtacm --wss servername:port'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --wss [server:port] The address of the AMT remote configuration server.'); + console.log(' --profile [name] The name of the AMT profile stored on the AMT remote configuration server.'); + } else if (action == 'amtdeactivate') { + console.log('AmtDeactivate will attempt to deactivate Intel AMT on this computer when in client control mode (CCM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be activated in client control mode for this command to work. Example usage:\r\n\r\n meshcmd amtdeactivate'); + } else if (action == 'amtacmdeactivate') { + console.log('AmtACMDeactivate will attempt to deactivate Intel AMT on this computer when in admin control mode (ACM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be activated in admin control mode for this command to work. Example usage:\r\n\r\n meshcmd amtacmdeactivate'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --type [partial/full] Specifies to perform partial or full unprovision.'); + } else if (action == 'amtuuid') { + console.log('AmtUUID action will get the unique identifier of the local or remote Intel AMT computer. By default, the local UUID is obtained unless a host is specified. Intel AMT must be activated for this command to work. Example usage:\r\n\r\n meshcmd amtuuid --host 1.2.3.4 --user admin --pass mypassword --tls'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); + } else if ((action == 'amtloadwebapp') || (action == 'amtloadsmallwebapp') || (action == 'amtloadlargewebapp') || (action == 'amtclearwebapp') || (action == 'amtstoragestate')) { + console.log('AmtLoadWebApp action will load MeshCommander into Intel AMT 11.6 or higher. If the computer is in ACM mode, MeshCommander will replace the default index.htm on HTTP/16992 or HTTPS/16993. If Intel AMT is in CCM mode, MeshCommander will be installed alongside the default web page and will be accessible in the "Web Applications" section. This action works on Intel AMT 11.6 and higher only. Example usage:\r\n\r\n meshcmd amtloadwebapp --host 1.2.3.4 --user admin --pass mypassword --tls'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); + } else if (action == 'amtclearwebstorage') { + console.log('AmtClearWebStorage will clear the web storage of Intel AMT, removing any loaded firmware version of MeshCommander. This command can clear the local or a remote Intel AMT computer. By default, the local computer storage is cleared unless a host is specified. Intel AMT must be activated for this command to work. This action works on Intel AMT 11.6 and higher only. Example usage:\r\n\r\n meshcmd amtclearwebstorage --host 1.2.3.4 --user admin --pass mypassword --tls'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); + } else if (action == 'amtstoragestate') { + console.log('AmtStorageState will display the content of the web storage of Intel AMT including any loaded firmware version of MeshCommander. This command can read the storage state of a local or remote Intel AMT computer. By default, the local computer storage state is displayed unless a host is specified. Intel AMT must be activated for this command to work. This action works on Intel AMT 11.6 and higher only. Example usage:\r\n\r\n meshcmd amtstoragestate --host 1.2.3.4 --user admin --pass mypassword --tls'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); + } else if (action == 'amtsavestate') { + console.log('AmtSaveState action will fetch all the entire state of Intel AMT and save it as a JSON file. This action will take multiple minutes to perform. The command will fetch the local computer state unless host is specified. Intel AMT must be ativated for this command to work. Example usage:\r\n\r\n meshcmd amtsavestate --host 1.2.3.4 --user admin --pass mypassword --tls --output state.json'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --output [filename] The output file for the Intel AMT state in JSON format.'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); + } else if (action == 'amtpresence') { + console.log('AmtPresence will heartbeat a local Intel AMT watchdog agent. Example usage:\r\n\r\n meshcmd amtpresence --agent B4B6A24C-255E-A75C-F5E8-B00B4D946AA7'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --agent [uuid] The unique identifier of the watchdog agent.'); + } else if (action == 'amtscript') { + console.log('AmtScript will run a .mescript file on the local or remote Intel AMT. Script files can be built using the MeshCommander script editor and be used to setup or perform actions on Intel AMT. Example usage:\r\n\r\n meshcmd amtscript --script myscript.mescript --host 1.2.3.4 --user admin --pass mypassword --tls'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --script [filename] The script file to run on Intel AMT.'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); + } else if (action == 'meshcommander') { + console.log('This action launched a local web server that hosts MeshCommander, a Intel AMT management console.'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --localport [port] Local port used for the web server, 3000 is default.'); + console.log('\r\nRun as a background service:\r\n'); + console.log(' meshcommander install/uninstall/start/stop.'); + } else if (action == 'amtauditlog') { + console.log('AmtAuditLog action will fetch the local or remote audit log. If used localy, no username/password is required. Example usage:\r\n\r\n meshcmd amtauditlog --host 1.2.3.4 --user admin --pass mypassword --tls --output audit.json'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --output [filename] The output file for the Intel AMT state in JSON format.'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); + } else if (action == 'amtider') { + console.log('AmtIDER will mount a local disk images to a remote Intel AMT computer. Example usage:\r\n\r\n meshcmd amtider --host 1.2.3.4 --user admin --pass mypassword --tls --floppy disk.img --cdrom disk.iso'); + console.log('\r\nPossible arguments:\r\n'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); + console.log(' --floppy [file] Specifies .img file to be mounted as a flppy disk.'); + console.log(' --cdrom [file] Specifies .img file to be mounted as a CDROM disk.'); + console.log(' --timeout [seconds] Optional, disconnect after number of seconds without disk read.'); + } else { + actions.shift(); + console.log('Invalid action, usage:\r\n\r\n meshcmd help [action]\r\n\r\nValid actions are: ' + actions.join(', ') + '.'); + } + exit(1); return; + } + settings.action = settings.action.toLowerCase(); + debug(1, "Settings: " + JSON.stringify(settings)); + + // Setup the proxy if needed + if ((typeof settings.proxy) == 'string') { + var proxy = settings.proxy.split(':'), proxyport = (proxy.length == 2) ? parseInt(proxy[1]) : 0; + if ((proxy.length != 2) || (proxy[0].length < 1) || (proxyport < 1) || (proxyport > 65535)) { console.log('Invalid \"proxy\" specified, use --proxy [hostname]:[port].'); exit(1); return; } + try { require('global-tunnel').initialize({ host: proxy[0], port: proxyport }); } catch (ex) { console.log(ex); exit(1); return; } + console.log('Proxy set to ' + proxy[0] + ':' + proxyport); + } + + if (settings.action == 'smbios') { + // Display SM BIOS tables in raw form + SMBiosTables = require('smbios'); + SMBiosTables.get(function (data) { + var r = SMBiosTables.parse(data); + var out = objToString(r, 0, '\r\n'); + if (settings.output == null) { console.log(out); } else { var file = fs.openSync(settings.output, 'w'); fs.writeSync(file, Buffer.from(out, 'utf8')); fs.closeSync(file); } + exit(1); + }); + } else if (settings.action == 'rawsmbios') { + // Display SM BIOS tables in raw form + SMBiosTables = require('smbios'); + SMBiosTables.get(function (data) { + var out = ''; + for (var i in data) { var header = false; for (var j in data[i]) { if (data[i][j].length > 0) { if (header == false) { out += ('Table type #' + i + ((SMBiosTables.smTableTypes[i] == null) ? '' : (', ' + SMBiosTables.smTableTypes[i]))) + '\r\n'; header = true; } out += (' ' + data[i][j].toString('hex')) + '\r\n'; } } } + if (settings.output == null) { console.log(out); } else { var file = fs.openSync(settings.output, 'w'); fs.writeSync(file, Buffer.from(out, 'utf8')); fs.closeSync(file); } + exit(1); + }); + } else if (settings.action == 'route') { + // MeshCentral Router, port map local TCP port to a remote computer + if ((settings.localport == null) || (typeof settings.localport != 'number') || (settings.localport < 0) || (settings.localport > 65535)) { console.log('No or invalid \"localPort\" specified, use --localport [localport].'); exit(1); return; } + if ((settings.remotenodeid == null) || (typeof settings.remotenodeid != 'string')) { console.log('No or invalid \"remoteNodeId\" specified.'); exit(1); return; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { console.log('No or invalid \"username\" specified, use --username [username].'); exit(1); return; } + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.serverid == null) || (typeof settings.serverid != 'string') || (settings.serverid.length != 96)) { console.log('No or invalid \"serverId\" specified.'); exit(1); return; } + if ((settings.serverhttpshash == null) || (typeof settings.serverhttpshash != 'string') || (settings.serverhttpshash.length != 96)) { console.log('No or invalid \"serverHttpsHash\" specified.'); exit(1); return; } + if ((settings.remoteport == null) || (typeof settings.remoteport != 'number') || (settings.remoteport < 0) || (settings.remoteport > 65535)) { console.log('No or invalid \"remotePort\" specified, use --remoteport [remoteport].'); exit(1); return; } + if (settings.serverurl != null) { startRouter(); } else { discoverMeshServer(); } // Start MeshCentral Router + } else if ((settings.action == 'amtloadwebapp') || (settings.action == 'amtloadsmallwebapp') || (settings.action == 'amtloadlargewebapp') || (settings.action == 'amtclearwebapp') || (settings.action == 'amtstoragestate')) { // Intel AMT Web Application Actions + // Intel AMT 11.6+ Load MeshCommander into firmware + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { settings.hostname = '127.0.0.1'; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; } + settings.protocol = 'http:'; + settings.localport = 16992; + debug(1, "Settings: " + JSON.stringify(settings)); + digest = require('http-digest').create(settings.username, settings.password); + digest.http = require('http'); + if (settings.action == 'amtstoragestate') { + getAmtStorage(function (statusCode, data) { if (statusCode == 200) { console.log("Storage State: " + JSON.stringify(data, null, 2)); exit(); return; } else { console.log("Unable to read storage state."); exit(); return; } }); + } else { + if (settings.action == 'amtloadwebapp') { settings.webapp = Medium_IntelAmtWebApp; } + else if (settings.action == 'amtloadsmallwebapp') { settings.webapp = Small_IntelAmtWebApp; } + else if (settings.action == 'amtloadlargewebapp') { settings.webapp = Large_IntelAmtWebApp; } + else if (settings.action == 'amtclearwebapp') { settings.webapp = null; } + nextStepStorageUpload(); + } + } else if ((settings.action == 'amtversion') || (settings.action == 'amtversions') || (settings.action == 'amtver')) { + // Display Intel AMT versions + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + amtMei.getVersion(function (val) { + console.log("MEI Version = " + val.BiosVersion.toString()); + for (var version in val.Versions) { console.log(val.Versions[version].Description + " = " + val.Versions[version].Version); } + exit(1); return; + }); + } else if (settings.action == 'amthashes') { + // Display Intel AMT list of trusted hashes + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + amtMei.getHashHandles(function (handles) { + exitOnCount = handles.length; + for (var i = 0; i < handles.length; ++i) { + this.getCertHashEntry(handles[i], function (result) { + console.log(result.name + ', (' + (result.isDefault ? 'Default' : '') + (result.isActive ? ', Active' : ', Disabled') + ')\r\n ' + result.hashAlgorithmStr + ': ' + result.certificateHash); + if (--exitOnCount == 0) { exit(1); } + }); + } + }); + } else if (settings.action == 'amtinfo') { + // Display Intel AMT version and activation state + mestate = {}; + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + amtMei.getVersion(function (result) { if (result) { for (var version in result.Versions) { if (result.Versions[version].Description == 'AMT') { mestate.ver = result.Versions[version].Version; } } } }); + amtMei.getProvisioningState(function (result) { if (result) { mestate.ProvisioningState = result; } }); + amtMei.getProvisioningMode(function (result) { if (result) { mestate.ProvisioningMode = result; } }); + amtMei.getEHBCState(function (result) { if (result) { mestate.ehbc = result; } }); + amtMei.getControlMode(function (result) { if (result) { mestate.controlmode = result; } }); + amtMei.getMACAddresses(function (result) { if (result) { mestate.mac = result; } }); + amtMei.getLanInterfaceSettings(0, function (result) { if (result) { mestate.net0 = result; } }); + amtMei.getLanInterfaceSettings(1, function (result) { if (result) { mestate.net1 = result; } }); + amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { mestate.uuid = result.uuid; } }); + amtMei.getDnsSuffix(function (result) { + if (result) { mestate.dns = result; } + if (mestate.ver && mestate.ProvisioningState && mestate.ProvisioningMode) { + var str = 'Intel AMT v' + mestate.ver; + if (mestate.ProvisioningState.stateStr == 'PRE') { str += ', pre-provisioning state'; } + else if (mestate.ProvisioningState.stateStr == 'IN') { str += ', in-provisioning state'; } + else if (mestate.ProvisioningState.stateStr == 'POST') { + if (mestate.ProvisioningMode) { + if (mestate.controlmode) { + if (mestate.ProvisioningMode.modeStr == 'ENTERPRISE') { str += ', activated in ' + ["none", "client control mode", "admin control mode", "remote assistance mode"][mestate.controlmode.controlMode]; } else { str += ', activated in ' + mestate.ProvisioningMode.modeStr; } + } else { + str += ', activated in ' + mestate.ProvisioningMode.modeStr; + } + } + } + if ((mestate.ehbc) && (mestate.ehbc.EHBC == true)) { str += ', EHBC enabled'; } + str += '.'; + if (mestate.net0 != null) { str += '\r\nWired ' + ((mestate.net0.enabled == 1) ? 'Enabled' : 'Disabled') + ((mestate.net0.dhcpEnabled == 1) ? ', DHCP' : ', Static') + ', ' + mestate.net0.mac + (mestate.net0.address == '0.0.0.0' ? '' : (', ' + mestate.net0.address)); } + if (mestate.net1 != null) { str += '\r\nWireless ' + ((mestate.net1.enabled == 1) ? 'Enabled' : 'Disabled') + ((mestate.net1.dhcpEnabled == 1) ? ', DHCP' : ', Static') + ', ' + mestate.net1.mac + (mestate.net1.address == '0.0.0.0' ? '' : (', ' + mestate.net1.address)); } + if ((mestate.ProvisioningState.stateStr != 'POST') && (mestate.net0 != null) && (mestate.net0.enabled == 1)) { + if (mestate.dns != null) { + // Intel AMT has a trusted DNS suffix set, use that one. + str += '\r\nTrusted DNS suffix: ' + mestate.dns; + } else { + // Look for the DNS suffix for the Intel AMT Ethernet interface + var fqdn = null, interfaces = require('os').networkInterfaces(); + for (var i in interfaces) { + for (var j in interfaces[i]) { + if ((interfaces[i][j].mac == mestate.net0.mac) && (interfaces[i][j].fqdn != null) && (interfaces[i][j].fqdn != '')) { fqdn = interfaces[i][j].fqdn; } + } + } + if (fqdn != null) { str += '\r\nDNS suffix: ' + fqdn; } + } + } + console.log(str + '.'); + } else { + console.log('Intel(R) AMT not supported.'); + } + exit(1); + }); + } else if (settings.action == 'amtinfodebug') { + // Display Intel AMT version and activation state + mestate = {}; + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + amtMei.getVersion(function (result) { console.log('getVersion: ' + JSON.stringify(result)); }); + amtMei.getProvisioningState(function (result) { console.log('getProvisioningState: ' + JSON.stringify(result)); }); + amtMei.getProvisioningMode(function (result) { console.log('getProvisioningMode: ' + JSON.stringify(result)); }); + amtMei.getEHBCState(function (result) { if (result) { console.log('getEHBCState: ' + JSON.stringify(result)); } }); + amtMei.getControlMode(function (result) { if (result) { console.log('getControlMode: ' + JSON.stringify(result)); } }); + amtMei.getMACAddresses(function (result) { if (result) { console.log('getMACAddresses: ' + JSON.stringify(result)); } }); + amtMei.getLanInterfaceSettings(0, function (result) { console.log('getLanInterfaceSettings0: ' + JSON.stringify(result)); }); + amtMei.getLanInterfaceSettings(1, function (result) { console.log('getLanInterfaceSettings1: ' + JSON.stringify(result)); }); + amtMei.getUuid(function (result) { console.log('getUuid: ' + JSON.stringify(result)); }); + amtMei.getDnsSuffix(function (result) { console.log('getDnsSuffix: ' + JSON.stringify(result)); exit(1); }); + } else if (settings.action == 'amtsavestate') { + // Save the entire state of Intel AMT info a JSON file + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { settings.hostname = '127.0.0.1'; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; } + if ((settings.output == null) || (typeof settings.output != 'string') || (settings.output == '')) { console.log('No or invalid \"output\" file specified, use --output [filename].'); exit(1); return; } + settings.protocol = 'http:'; + settings.localport = 16992; + debug(1, "Settings: " + JSON.stringify(settings)); + saveEntireAmtState(); + } else if ((settings.action == 'microlms') || (settings.action == 'amtlms') || (settings.action == 'lms')) { + // Start Intel AMT MicroLMS + startLms(function (state) { + console.log(['MicroLMS did not start. Must run as administrator or LMS already active.', 'MicroLMS started.', 'MicroLMS started, MeshCommander on HTTP/16994.', 'MEI error'][state]); + if (((state == 0) || (state == 3)) && (settings.noconsole === true)) { exit(0); } else { console.log('Press ctrl-c to exit.'); } + }, settings.noconsole !== true); + } else if (settings.action == 'amtpresence') { + // Heartbeat a Intel AMT watchdog + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; } + if ((settings.agent == null) || (typeof settings.agent != 'string') || (settings.agent == '')) { console.log('No or invalid \"agent\" specified, use --agent [agent].'); exit(1); return; } + performAmtAgentPresence(); + } else if (settings.action == 'amtscript') { + // Start running a MEScript + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { settings.hostname = '127.0.0.1'; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; } + if ((settings.script == null) || (typeof settings.script != 'string') || (settings.script == '')) { if (mescriptJSON != '') { settings.scriptjson = mescriptJSON; } else { console.log('No or invalid \"script\" file specified, use --script [filename].'); exit(1); return; } } + startMeScript(); + } else if (settings.action == 'amtuuid') { + // Start running + if (settings.hostname != null) { + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; } + } + settings.protocol = 'http:'; + settings.localport = 16992; + debug(1, "Settings: " + JSON.stringify(settings)); + getAmtUuid(); + } else if (settings.action == 'amtccm') { + // Start activation to CCM + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + settings.protocol = 'http:'; + settings.localport = 16992; + debug(1, "Settings: " + JSON.stringify(settings)); + activeToCCM(); + } else if (settings.action == 'amtacm') { + // Start activation to ACM + if ((settings.wss == null) || (typeof settings.wss != 'string') || (settings.wss == '')) { console.log('No or invalid \"server name\" specified, use --wss [servername:port].'); exit(1); return; } + if ((settings.profile == null) || (typeof settings.profile != 'string') || (settings.profile == '')) { console.log('No or invalid \"profile name\" specified, use --profile [name].'); exit(1); return; } + settings.protocol = 'http:'; + settings.localport = 16992; + debug(1, "Settings: " + JSON.stringify(settings)); + activeToACM(); + } else if (settings.action == 'amtdeactivate') { + // Deactivate CCM + debug(1, "Settings: " + JSON.stringify(settings)); + deactivateCCM(); + } else if (settings.action == 'amtacmdeactivate') { + // Deactivate ACM + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.type == null) || (typeof settings.type != 'string') || (settings.type == '')) { console.log('Unprovisioning \"type\" must be specified, use --type [partial/full].'); exit(1); return; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; } + if (settings.hostname == null) { settings.hostname = '127.0.0.1'; } + if (settings.tls == null) { settings.tls = false; } + debug(1, "Settings: " + JSON.stringify(settings)); + deactivateACM(); + } else if (settings.action == 'meshcommander') { // Start MeshCommander + startMeshCommander(); + //} else if (settings.action == 'amtdisable') { // Disable AMT Network Interface + // amtDisable(); + } else if (settings.action == 'amtauditlog') { // Read the Intel AMT audit log + if (settings.hostname != null) { + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; } + } else { settings.hostname = '127.0.0.1'; } + readAmtAuditLog(); + } else if (settings.action == 'amtider') { // Remote mount IDER image + if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { console.log('No or invalid \"hostname\" specified, use --hostname [password].'); exit(1); return; } + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; } + if ((settings.floppy == null) || (typeof settings.floppy != 'string') || (settings.floppy == '')) { settings.floppy = null; } + if ((settings.cdrom == null) || (typeof settings.cdrom != 'string') || (settings.cdrom == '')) { settings.cdrom = null; } + if ((settings.floppy == null) && (settings.cdrom == null)) { console.log('No or invalid \"floppy\" or \"cdrom\" specified, use --floppy [file] or --cdrom [file].'); exit(1); return; } + performIder(); + } else { + console.log('Invalid \"action\" specified.'); exit(1); return; + } +} + +// +// Intel AMT Agent Presence +// + +function performAmtAgentPresence() { startLms(function () { tempWatchdogTimer = setTimeout(performAmtAgentPresenceRegister, 3000); }); } + +function performAmtAgentPresenceRegister() { + // Setup the Intel AMT WSMAN stack + tempWatchdogTimer = null; + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + wsstack = new wsman(transport, '127.0.0.1', settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls); + amtstack = new amt(wsstack); + + // Register the watchdog + watchdog = { DeviceID: Buffer.from(guidToStr(settings.agent.split('-').join('')).split('-').join(''), 'hex').toString('base64'), Retry: 0 }; + amtstack.AMT_AgentPresenceWatchdog_RegisterAgent(performAmtAgentPresenceRegisterRetry, watchdog, watchdog.Seq, { 'DeviceID': watchdog.DeviceID }); +} + +// Called after the agent is registered +function performAmtAgentPresenceRegisterRetry(stack, name, response, status, watchdog) { + if ((status == 200) && (response.Body.SessionSequenceNumber) && (response.Body.TimeoutInterval)) { + console.log('Asserting presence of the watchdog...'); + watchdog.Seq = response.Body.SessionSequenceNumber; + watchdog.Interval = response.Body.TimeoutInterval * 800; + watchdog.Retry = 0; + tempWatchdogTimer = setTimeout(performAmtAgentPresenceAssert, watchdog.Interval); + } else { + debug(1, 'Failed to register, status = ' + status); + watchdog.Retry++; + if (watchdog.Retry < 5) { + tempWatchdogTimer = setTimeout(function () { amtstack.AMT_AgentPresenceWatchdog_RegisterAgent(performAmtAgentPresenceRegisterRetry, watchdog, watchdog.Seq, { 'DeviceID': watchdog.DeviceID }); }, 1000); + } else { + console.log('Failed to register this watchdog.'); + process.exit(0); + } + } +} + +// Start a new agent assert +function performAmtAgentPresenceAssert() { + watchdog.Seq++; + amtstack.AMT_AgentPresenceWatchdog_AssertPresence(watchdog.Seq, performAmtAgentPresenceAssertRetry, watchdog, 0, { 'DeviceID': watchdog.DeviceID }); +} + +// Called after the agent is asserted +function performAmtAgentPresenceAssertRetry(stack, name, response, status, watchdog) { + if (status == 200) { + debug(1, 'Succesful assert, sequence = ' + watchdog.Seq); + watchdog.Retry = 0; + tempWatchdogTimer = setTimeout(performAmtAgentPresenceAssert, watchdog.Interval); + } else { + debug(1, 'Failed to assert, status = ' + status); + watchdog.Retry++; + if (watchdog.Retry < 5) { + amtstack.AMT_AgentPresenceWatchdog_AssertPresence(watchdog.Seq, performAmtAgentPresenceAssertRetry, watchdog, 0, { 'DeviceID': watchdog.DeviceID }); + } else { + console.log('Failed to assert presence on this watchdog.'); + process.exit(0); + } + } +} + +function performAmtAgentPresenceEx5(stack, name, response, status, watchdog) { + console.log('b', status, watchdog); + if (status == 200) { + watchdog.Retry = 0; + } else { + watchdog.Retry++; + if (watchdog.Retry < 5) { + amtstack.AMT_AgentPresenceWatchdog_AssertPresence(watchdog.Seq, performAmtAgentPresenceEx4, watchdog, 0, { 'DeviceID': watchdog.DeviceID }); + } else { + console.log('Failed to assert presence on this watchdog.'); + process.exit(0); + } + } +} + +// +// Intel AMT Audit Log +// + +function readAmtAuditLog() { + // See if MicroLMS needs to be started + if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) { + settings.noconsole = true; startLms(readAmtAuditLogEx); + } else { + readAmtAuditLogEx(9999); + } +} + +function readAmtAuditLogEx(x) { + if (x == 9999) { + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls); + amtstack = new amt(wsstack); + amtstack.GetAuditLog(readAmtAuditLogEx2); + } else { + osamtstack.GetAuditLog(readAmtAuditLogEx2); + } +} + +function readAmtAuditLogEx2(stack, response, status) { + if (status != 200) { + console.log('Unable to get audit log, status = ' + status + '.'); + } else { + var out = ''; + for (var i in response) { + var name = ((response[i].Initiator != '') ? (response[i].Initiator + ': ') : '') + out += (response[i].Time + ' - ' + name + response[i].Event + '\r\n'); + } + if (settings.output == null) { console.log(out); } else { var file = fs.openSync(settings.output, 'w'); fs.writeSync(file, Buffer.from(out, 'utf8')); fs.closeSync(file); } + } + exit(1); +} + +// +// Disable AMT Network +// + +//function amtDisable() { +// settings.noconsole = true; +// startLms(amtDisableEx); +//} + +//function amtDisableEx(stack, response, status) { +// //console.log(osamtstack); +// osamtstack.Get('AMT_EthernetPortSettings', function (stack, name, response, status) { +// console.log(response.Body); +// }); +//} + +// +// MeshCommander local web server +// + +function startMeshCommander() { + // MeshCommander Local v0.7.5 + var _IntelAmtLocalWebApp_etag = "2yqTVWrrXNG95TGphPSo"; + var _IntelAmtLocalWebApp = "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"; + + if (settings.localport == null) { settings.localport = 3000; } + + // Start the web server + var http = require('http'); + webServer = http.createServer(); + webServer.listen(settings.localport); + webServer.wsList = {}; + webServer.wsListIndex = 0; + webServer.on('upgrade', function (req, socket, head) { + //console.log("WebSocket for " + req.url.split('?')[0]); + switch (req.url.split('?')[0]) { + case '/webrelay.ashx': // MeshCommander relay channel + var ws = socket.upgradeWebSocket(); + socket.ws = ws; + ws.wsIndex = ++webServer.wsListIndex; + webServer.wsList[ws.wsIndex] = ws; // Keep a reference so the websocket and forwarder don't get disposed. + ws.pause(); + + // We got a new web socket connection, initiate a TCP connection to the target Intel AMT host/port. + var webargs = parseUrlArguments(req.url); + if (webargs.p) { webargs.p = parseInt(webargs.p); } + if (webargs.tls) { webargs.tls = parseInt(webargs.tls); } + if (webargs.tls1only) { webargs.tls1only = parseInt(webargs.tls1only); } + if (webargs.port) { webargs.port = parseInt(webargs.port); } + debug(1, 'Opening web socket connection to ' + webargs.host + ':' + webargs.port + '.'); + //console.log('Opening web socket connection to ' + webargs.host + ':' + webargs.port + '.'); + if (webargs.tls == 0) { + // If this is TCP (without TLS) set a normal TCP socket + var net = require('net'); + ws.forwardclient = net.connect({ host: webargs.host, port: webargs.port }) + ws.forwardclient.on('connect', function () { debug(1, 'Connected TCP to ' + webargs.host + ':' + webargs.port + '.'); this.pipe(this.ws, { end: false }); this.ws.pipe(this, { end: false }); }); + ws.forwardclient.on('error', function () { debug(1, 'TCP connection error to ' + webargs.host + ':' + webargs.port + '.'); try { this.ws.end(); } catch (e) { } }); + ws.forwardclient.ws = ws; + } else { + // If TLS is going to be used, setup a TLS socket + var tls = require('tls'); + var tlsoptions = { host: webargs.host, port: webargs.port, secureProtocol: ((webargs.tls1only == 1) ? 'TLSv1_method' : 'SSLv23_method'), rejectUnauthorized: false }; + ws.forwardclient = tls.connect(tlsoptions, function () { debug(1, 'Connected TLS to ' + webargs.host + ':' + webargs.port + '.'); this.pipe(this.ws, { end: false }); this.ws.pipe(this, { end: false }); }); + ws.forwardclient.on('error', function () { debug(1, 'TLS connection error to ' + webargs.host + ':' + webargs.port + '.'); try { this.ws.end(); } catch (e) { } }); + ws.forwardclient.ws = ws; + } + + // Handle pipe closure + ws.on('end', function () { debug(1, 'Disconnected from ' + webargs.host + ':' + webargs.port + '.'); try { this.forwardclient.end(); } catch (e) { } delete webServer.wsList[this.wsIndex]; }); + ws.forwardclient.on('end', function () { try { this.ws.end(); } catch (e) { } }); + + break; + default: + socket.end(); + break; + } + }); + webServer.on('request', function (req, rsp) { + //console.log("WebRequest for " + req.url.split('?')[0]); + switch (req.url.split('?')[0]) { + case '/': // Serve MeshCommander Web Application + var meshcommander = null; + try { meshcommander = fs.readFileSync('meshcommander.htm'); } catch (e) { } + if (meshcommander != null) { + rsp.writeHead(200, 'OK', { Server: 'JSLMS', 'Cache-Control': 'max-age=0, no-cache', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Transfer-Encoding': 'chunked' }); + rsp.end(meshcommander); + } else { + rsp.writeHead(200, 'OK', { Server: 'JSLMS', 'Cache-Control': 'max-age=0, no-cache', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Content-Encoding': 'gzip', 'Transfer-Encoding': 'chunked', ETag: _IntelAmtLocalWebApp_etag }); + rsp.end(Buffer.from(_IntelAmtLocalWebApp, 'base64')); + } + break; + default: // Unknown request + rsp.statusCode = 404; + rsp.statusMessage = "Not Found"; + rsp.end(); + break; + } + }); + console.log('MeshCommander running on HTTP port ' + settings.localport + '.'); + console.log('Press ctrl-c to exit.'); +} + + +// +// Deactivate Intel AMT CCM +// + +// When called, this will use MEI to deactivate Intel AMT when it's in CCM mode. Simply calls "unprovision" on MEI and checks the return code. +function deactivateCCM() { + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + amtMei.unprovision(1, function (status) { if (status == 0) { console.log('Success'); } else { console.log('Error ' + status); } exit(1); }); +} + + +// +// Activate Intel AMT to CCM +// + +function activeToCCM() { + // See if MicroLMS needs to be started and setup the $$OsAdmin wsman stack + settings.noconsole = true; + startLms(activeToCCMEx); // TODO: Fix this so that it works even if LMS already running. +} + +function activeToCCMEx(state) { + osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], activeToCCMEx2); +} + +function activeToCCMEx2(stack, name, responses, status) { + if (status != 200) { console.log('Failed to fetch activation status, status ' + status); exit(1); } + else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) { console.log('Client control mode activation not allowed'); exit(1); } + else { osamtstack.IPS_HostBasedSetupService_Setup(2, md5hex('admin:' + responses['AMT_GeneralSettings'].response['DigestRealm'] + ':' + settings.password).substring(0, 32), null, null, null, null, activeToCCMEx3); } +} + +function activeToCCMEx3(stack, name, responses, status) { + if (status != 200) { console.log('Failed to activate, status ' + status); } + else if (responses.Body.ReturnValue != 0) { console.log('Client control mode activation failed: ' + responses.Body.ReturnValueStr); } + else { console.log('Success'); exit(0); } + exit(1); +} + +// +// Deactivate Intel AMT ACM +// + +// When called, this will use MEI to deactivate Intel AMT when it's in ACM mode. Calls "unprovision" on MEI and checks the return code. +function deactivateACM() { + settings.noconsole = true; + startLms(deactivateACMEx); +} + +function deactivateACMEx() { + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls); + amtstack = new amt(wsstack); + amtstack.Get("AMT_SetupAndConfigurationService", function (stack, name, responses, status) { + if (status !== 200) { + console.log('Command not allowed. Status: ' + status); + exit(1); + } else { + var sacs = responses.Body; + if (sacs.ZeroTouchConfigurationEnabled == true) { sacs.ZeroTouchConfigurationEnabled = true; } + amtstack.Put("AMT_SetupAndConfigurationService", sacs, function (stack, name, responses, status) { + if (settings.type == 'full') { + amtstack.AMT_SetupAndConfigurationService_Unprovision(2, function (stack, name, responses, status) { + if (status != 200) { console.log('Failed to fully unconfigure AMT, status ' + status); exit(1); } + else if (responses.Body.ReturnValue != 0) { console.log('Unprovision failed: ' + responses.Body.ReturnValueStr); exit(1); } + else { console.log('AMT fully unprovisioned.'); exit(0); } + }); + } else { + console.log('Only full unprovision is currently supported.'); + exit(0); + } + //} else if (settings.type == 'partial') { + // amtstack.AMT_SetupAndConfigurationService_PartialUnprovision(null, function (stack, name, responses, status) { + // if (status != 200) { console.log('Failed to partially unconfigure AMT, status ' + status); exit(1); } + // else if (responses.Body.ReturnValue != 0) { console.log('Unprovision failed: ' + responses.Body.ReturnValueStr); exit(1); } + // else { console.log('AMT partially unprovisioned.'); exit(0); } + // }); + //} + }); + } + }); +} + + +// +// Activate Intel AMT to ACM +// + +function activeToACM() { + // See if MicroLMS needs to be started and setup the $$OsAdmin wsman stack + console.log('Starting AMT Provisioning to Admin Control Mode.'); + settings.noconsole = true; + // Display Intel AMT version and activation state + mestate = {}; + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + amtMei.getProvisioningState(function (result) { + if (result) { + mestate.ProvisioningState = result; + startLms(getFwNonce); // TODO: Fix this so that it works even if LMS already running. + } + }); +} + +// Gets the FWNonce from AMT and saves it to a file. +function getFwNonce() { + osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], function (stack, name, responses, status) { + var fwNonce = responses['IPS_HostBasedSetupService'].response['ConfigurationNonce']; + var digestRealm = responses['AMT_GeneralSettings'].response['DigestRealm']; + var amtMeiModule, amtMei, str; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.getLanInterfaceSettings(0, function (result) { if (result) { mestate.net0 = result; } }); + amtMei.getDnsSuffix(function (result) { + var fqdn = null; + if ((mestate.net0 == null) && (meinfo.net0.enabled != 0)) { console.log("No Intel AMT wired interface, can't perform ACM activation."); exit(100); return; } + if (result) { fqdn = result; } // If Intel AMT has a trusted DNS suffix set, use that one. + else { + // Look for the DNS suffix for the Intel AMT Ethernet interface + var interfaces = require('os').networkInterfaces(); + for (var i in interfaces) { + for (var j in interfaces[i]) { + if ((interfaces[i][j].mac == mestate.net0.mac) && (interfaces[i][j].fqdn != null) && (interfaces[i][j].fqdn != '')) { fqdn = interfaces[i][j].fqdn; } + } + } + } + if (fqdn != null) { + activeToACMEx(fwNonce, fqdn, digestRealm); + } else { + console.log("Trusted DNS suffix not set, can't perform ACM activation."); exit(100); return; + } + }); + }); +} + +// Sends a message to RCS server using RCS Message Protocol +function sendRCSMessage(socket, status, event, message) { + //console.log('Status: ' + status + '. Event: ' + event + '. Message: ' + message); + if (socket !== null) { socket.write({ "status": status, "event": event, "data": message }); } +} + +function activeToACMEx(fwNonce, dnsSuffix, digestRealm) { + // open connection to RCS + console.log('Initializing WebSocket...'); + // Establish WebSocket connection to RCS server + var connection = http.request(settings.wss); + connection.on('upgrade', function (response, socket) { + // WebSocket is up. Handle data on the duplex socket + socket.on('data', function (data) { + // All messages from RCS are JSON.stringify format and need to be parsed + var message = JSON.parse(data); + // Check RCS Message Protocol version. Exit if version not supported + if (message.version > RCSMessageProtocolVersion) { console.log('Unsupported RCS server.'); socket.end(); exit(0) } + // Handle the AMT provisioning certificate blob (contains provisioning certificate, mcnonce, digital signature and password hash) + if (message.data.provCertObj !== undefined) { + activeToACMEx1(message.data, function (stack, name, responses, status, message) { + if (status !== 200) { + if (status == 2) { + console.log('AMT already provisioned.Exiting ' + status); + sendRCSMessage(socket, "error", "finish", "failed with status: " + status); + } else { + console.log('Failed to fetch activation status, status ' + status); + sendRCSMessage(socket, "error", "finish", "failed with status: " + status); + } + socket.end(); + exit(status); + } else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) { + console.log('Admin control mode activation not allowed'); + sendRCSMessage(socket, "error", "finish", "failed with message: Admin control mode activation not allowed"); + socket.end(); + exit(status); + } else { + activeToACMEx2(message, function (stack, name, responses, status, message) { + if (status != 200) { + console.log('Failed to activate, status ' + status); + sendRCSMessage(socket, "error", "finish", "failed to activate. Status: " + status); + } else if (responses.Body.ReturnValue != 0) { + console.log('Admin control mode activation failed: ' + responses.Body.ReturnValueStr); + sendRCSMessage(socket, "error", "finish", "failed to activate: " + responses.Body.ReturnValueStr); + } else { + if (message.profileScript !== null) { + console.log("Running MEScript..."); + settings.scriptjson = message.profileScript; + settings.password = message.amtPassword + settings.username = 'admin'; + startMeScriptEx(function () { + console.log('AMT Profile applied'); + sendRCSMessage(socket, "ok", "finish", "success"); + socket.end(); + exit(0); + }, stack); + } else { + sendRCSMessage(socket, "ok", "finish", "success"); + socket.end(); + exit(0); + } + console.log('AMT Provisioning Success'); + } + //socket.end(); + //exit(status); + }); + } + }); + } + if (message.event.toString() == "cmd" && message.data.toString() == "acmready") { + sendRCSMessage(socket, "ok", "message", JSON.stringify(fwNonce)); + } + }); + socket.on('end', function () { console.log('WebSocket closed'); }); + sendRCSMessage(socket, "ok", "cmd", { "cmd": "acm", "dnssuffix": dnsSuffix, "profile": settings.profile, 'digestrealm': digestRealm, 'fwnonce': fwNonce }); + }); +} + +// Detects AMT provisioning state and injects the certificate chain into AMT firmware +function activeToACMEx1(data, callback) { + if (mestate.ProvisioningState.state == 0) { + console.log('Performing ACM provisioning...'); + // Perform full provisioning -- AMT was fully unprovisioned + injectCert(0, data, function (stack, name, responses, status, data) { + if (status !== 200) { exit(status); return; } + else if (responses['Body']['ReturnValue'] !== 0) { exit(responses['Body']['ReturnValueStr']); return; } + else if (responses['Body']['ReturnValue'] == 0) { + osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], function (stack, name, responses, status) { + callback(stack, name, responses, status, data); + }); + } + }); + } else if (mestate.ProvisioningState.state == 1) { + // Perform partial provisioning -- AMT was partial unprovisioned + // Currently not functional due to limitations in the HW. + console.log('Partial provisioning flow currently not available.'); + exit(0); + //osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], activeToACMEx2); + } else { + // AMT already provisioned + callback(null, null, null, 2, 'AMT already provisioned. Exiting') + exit(0); + } +} + +// Recursive function to inject the provisioning certificates into AMT in the proper order +function injectCert(index, cert, callback, stack, name, responses, status) { + var leaf = false; + var root = false; + if (index == 0) { leaf = true; } + if (index == cert.provCertObj.certChain.length - 1) { root = true; } + if (index < cert.provCertObj.certChain.length) { + if (cert.provCertObj.certChain[index] !== undefined) { + osamtstack.IPS_HostBasedSetupService_AddNextCertInChain(cert.provCertObj.certChain[index], leaf, root, function (stack, name, responses, status) { + if (status !== 200) { exit(status); return; } + else if (responses['Body']['ReturnValue'] !== 0) { exit(responses['Body']['ReturnValueStr']); return; } + else if (responses['Body']['ReturnValue'] == 0) { + index++; + injectCert(index, cert, callback, stack, name, responses, status); + } + }); + } + } else { callback(stack, name, responses, status, cert); } +} + +// Sends the password hash, mcnonce, and digital signature to complete the admin control mode provisioning +function activeToACMEx2(data, callback) { + //var passwordhash = md5hex('admin:' + responses['AMT_GeneralSettings'].response['DigestRealm'] + ':' + data.passwordHash).substring(0, 32); + //var debugreturn = {"Body": {"ReturnValue": 0}}; + //console.log("DEBUG: Everything up to activation works"); callback(null, null, debugreturn, 200, data); + osamtstack.IPS_HostBasedSetupService_AdminSetup(2, data.passwordHash, data.mcNonce, 2, data.digitalSignature, function (stack, name, responses, status) { callback(stack, name, responses, status, data); }); +} + +// +// Get AMT UUID +// + +// Called to get the UUID of Intel AMT, start by setting up MicroLMS if we are doing the operation on the local computer +function getAmtUuid() { + if (settings.hostname == null) { + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + amtMei.getUuid(function (result) { if ((result == null) || (result.uuid == null)) { console.log('Failed.'); } else { console.log(result.uuid); } exit(1); }); + } else { + if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) { settings.noconsole = true; startLms(getAmtUuidEx); return; } else { getAmtUuidEx(); } + } +} + +// Fetch the computer's UUID by fetching the CIM_ComputerSystemPackage WSMAN object. +function getAmtUuidEx() { + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls); + amtstack = new amt(wsstack); + amtstack.Get("CIM_ComputerSystemPackage", function (obj, name, response, xstatus, tag) { + if (xstatus == 200) { console.log("GUID: " + guidToStr(response.Body.PlatformGUID.toLowerCase())); } else { console.log("Intel AMT is not available or not activated."); } exit(1); + }); +} + + +// +// Run MESCRIPT +// + +// Run a .mescript targeting local or remote Intel AMT. +function startMeScript() { + // See if MicroLMS needs to be started + if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) { settings.noconsole = true; startLms(startMeScriptEx); return; } else { startMeScriptEx(); } +} + +function startMeScriptEx(callback, amtstack) { + //console.log('Running script...'); + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + if (!wsstack) { wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls); } + if (!amtstack) { amtstack = new amt(wsstack); } + //IntelAmtEntireStateProgress = 101; + //amtstack.onProcessChanged = onWsmanProcessChanged; + + var scriptData = null; + if (settings.script != null) { + try { scriptData = fs.readFileSync(settings.script); } catch (e) { console.log('Unable to read script file (1): ' + settings.script + '.'); exit(1); return; } + } else { + scriptData = settings.scriptjson; + } + if (scriptData == null) { console.log('Unable to read script file (2): ' + settings.script + '.'); exit(1); return; } + try { scriptData = JSON.parse(scriptData); } catch (e) { console.log('Unable to read script file (3): ' + settings.script + '.'); exit(1); return; } + if (scriptData.mescript == null) { console.log('Unable to read script file (4): ' + settings.script + '.'); exit(1); return; } + var scriptData = Buffer.from(scriptData.mescript, 'base64'); + + var scriptModule = require('amt-script'); + var script = scriptModule.setup(scriptData, {}) + script.amtstack = amtstack; + script.start(); + script.onCompleted = function () { if (callback) { callback(); } exit(1); } +} + + +// +// FETCH ALL INTEL AMT STATE +// + + +function saveEntireAmtState2() { + console.log('Fetching all Intel AMT state, this may take a few minutes...'); + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls); + amtstack = new amt(wsstack); + amtstack.onProcessChanged = onWsmanProcessChanged; + //var AllWsman = "AMT_GeneralSystemDefenseCapabilities".split(','); + var AllWsman = "AMT_8021xCredentialContext,AMT_8021XProfile,AMT_ActiveFilterStatistics,AMT_AgentPresenceCapabilities,AMT_AgentPresenceInterfacePolicy,AMT_AgentPresenceService,AMT_AgentPresenceWatchdog,AMT_AgentPresenceWatchdogAction,AMT_AlarmClockService,IPS_AlarmClockOccurrence,AMT_AssetTable,AMT_AssetTableService,AMT_AuditLog,AMT_AuditPolicyRule,AMT_AuthorizationService,AMT_BootCapabilities,AMT_BootSettingData,AMT_ComplexFilterEntryBase,AMT_CRL,AMT_CryptographicCapabilities,AMT_EACCredentialContext,AMT_EndpointAccessControlService,AMT_EnvironmentDetectionInterfacePolicy,AMT_EnvironmentDetectionSettingData,AMT_EthernetPortSettings,AMT_EventLogEntry,AMT_EventManagerService,AMT_EventSubscriber,AMT_FilterEntryBase,AMT_FilterInSystemDefensePolicy,AMT_GeneralSettings,AMT_GeneralSystemDefenseCapabilities,AMT_Hdr8021Filter,AMT_HeuristicPacketFilterInterfacePolicy,AMT_HeuristicPacketFilterSettings,AMT_HeuristicPacketFilterStatistics,AMT_InterfacePolicy,AMT_IPHeadersFilter,AMT_KerberosSettingData,AMT_ManagementPresenceRemoteSAP,AMT_MessageLog,AMT_MPSUsernamePassword,AMT_NetworkFilter,AMT_NetworkPortDefaultSystemDefensePolicy,AMT_NetworkPortSystemDefenseCapabilities,AMT_NetworkPortSystemDefensePolicy,AMT_PCIDevice,AMT_PETCapabilities,AMT_PETFilterForTarget,AMT_PETFilterSetting,AMT_ProvisioningCertificateHash,AMT_PublicKeyCertificate,AMT_PublicKeyManagementCapabilities,AMT_PublicKeyManagementService,AMT_PublicPrivateKeyPair,AMT_RedirectionService,AMT_RemoteAccessCapabilities,AMT_RemoteAccessCredentialContext,AMT_RemoteAccessPolicyAppliesToMPS,AMT_RemoteAccessPolicyRule,AMT_RemoteAccessService,AMT_SetupAndConfigurationService,AMT_SNMPEventSubscriber,AMT_StateTransitionCondition,AMT_SystemDefensePolicy,AMT_SystemDefensePolicyInService,AMT_SystemDefenseService,AMT_SystemPowerScheme,AMT_ThirdPartyDataStorageAdministrationService,AMT_ThirdPartyDataStorageService,AMT_TimeSynchronizationService,AMT_TLSCredentialContext,AMT_TLSProtocolEndpoint,AMT_TLSProtocolEndpointCollection,AMT_TLSSettingData,AMT_TrapTargetForService,AMT_UserInitiatedConnectionService,AMT_WebUIService,AMT_WiFiPortConfigurationService,CIM_AbstractIndicationSubscription,CIM_Account,CIM_AccountManagementCapabilities,CIM_AccountManagementService,CIM_AccountOnSystem,CIM_AdminDomain,CIM_AlertIndication,CIM_AssignedIdentity,CIM_AssociatedPowerManagementService,CIM_AuthenticationService,CIM_AuthorizationService,CIM_BIOSElement,CIM_BIOSFeature,CIM_BIOSFeatureBIOSElements,CIM_BootConfigSetting,CIM_BootService,CIM_BootSettingData,CIM_BootSourceSetting,CIM_Capabilities,CIM_Card,CIM_Chassis,CIM_Chip,CIM_Collection,CIM_Component,CIM_ComputerSystem,CIM_ComputerSystemPackage,CIM_ConcreteComponent,CIM_ConcreteDependency,CIM_Controller,CIM_CoolingDevice,CIM_Credential,CIM_CredentialContext,CIM_CredentialManagementService,CIM_Dependency,CIM_DeviceSAPImplementation,CIM_ElementCapabilities,CIM_ElementConformsToProfile,CIM_ElementLocation,CIM_ElementSettingData,CIM_ElementSoftwareIdentity,CIM_ElementStatisticalData,CIM_EnabledLogicalElement,CIM_EnabledLogicalElementCapabilities,CIM_EthernetPort,CIM_Fan,CIM_FilterCollection,CIM_FilterCollectionSubscription,CIM_HostedAccessPoint,CIM_HostedDependency,CIM_HostedService,CIM_Identity,CIM_IEEE8021xCapabilities,CIM_IEEE8021xSettings,CIM_Indication,CIM_IndicationService,CIM_InstalledSoftwareIdentity,CIM_KVMRedirectionSAP,CIM_LANEndpoint,CIM_ListenerDestination,CIM_ListenerDestinationWSManagement,CIM_Location,CIM_Log,CIM_LogEntry,CIM_LogicalDevice,CIM_LogicalElement,CIM_LogicalPort,CIM_LogicalPortCapabilities,CIM_LogManagesRecord,CIM_ManagedCredential,CIM_ManagedElement,CIM_ManagedSystemElement,CIM_MediaAccessDevice,CIM_MemberOfCollection,CIM_Memory,CIM_MessageLog,CIM_NetworkPort,CIM_NetworkPortCapabilities,CIM_NetworkPortConfigurationService,CIM_OrderedComponent,CIM_OwningCollectionElement,CIM_OwningJobElement,CIM_PCIController,CIM_PhysicalComponent,CIM_PhysicalElement,CIM_PhysicalElementLocation,CIM_PhysicalFrame,CIM_PhysicalMemory,CIM_PhysicalPackage,CIM_Policy,CIM_PolicyAction,CIM_PolicyCondition,CIM_PolicyInSystem,CIM_PolicyRule,CIM_PolicyRuleInSystem,CIM_PolicySet,CIM_PolicySetAppliesToElement,CIM_PolicySetInSystem,CIM_PowerManagementCapabilities,CIM_PowerManagementService,CIM_PowerSupply,CIM_Privilege,CIM_PrivilegeManagementCapabilities,CIM_PrivilegeManagementService,CIM_ProcessIndication,CIM_Processor,CIM_ProtocolEndpoint,CIM_ProvidesServiceToElement,CIM_Realizes,CIM_RecordForLog,CIM_RecordLog,CIM_RedirectionService,CIM_ReferencedProfile,CIM_RegisteredProfile,CIM_RemoteAccessAvailableToElement,CIM_RemoteIdentity,CIM_RemotePort,CIM_RemoteServiceAccessPoint,CIM_Role,CIM_RoleBasedAuthorizationService,CIM_RoleBasedManagementCapabilities,CIM_RoleLimitedToTarget,CIM_SAPAvailableForElement,CIM_SecurityService,CIM_Sensor,CIM_Service,CIM_ServiceAccessBySAP,CIM_ServiceAccessPoint,CIM_ServiceAffectsElement,CIM_ServiceAvailableToElement,CIM_ServiceSAPDependency,CIM_ServiceServiceDependency,CIM_SettingData,CIM_SharedCredential,CIM_SoftwareElement,CIM_SoftwareFeature,CIM_SoftwareFeatureSoftwareElements,CIM_SoftwareIdentity,CIM_StatisticalData,CIM_StorageExtent,CIM_System,CIM_SystemBIOS,CIM_SystemComponent,CIM_SystemDevice,CIM_SystemPackaging,CIM_UseOfLog,CIM_Watchdog,CIM_WiFiEndpoint,CIM_WiFiEndpointCapabilities,CIM_WiFiEndpointSettings,CIM_WiFiPort,CIM_WiFiPortCapabilities,IPS_AdminProvisioningRecord,IPS_ClientProvisioningRecord,IPS_HostBasedSetupService,IPS_HostIPSettings,IPS_IderSessionUsingPort,IPS_IPv6PortSettings,IPS_KVMRedirectionSettingData,IPS_KvmSessionUsingPort,IPS_ManualProvisioningRecord,IPS_OptInService,IPS_ProvisioningAuditRecord,IPS_ProvisioningRecordLog,IPS_RasSessionUsingPort,IPS_ScreenSettingData,IPS_SecIOService,IPS_SessionUsingPort,IPS_SolSessionUsingPort,IPS_TLSProvisioningRecord".split(','); + IntelAmtEntireStateProgress = 101; + IntelAmtEntireStateCalls = 3; + IntelAmtEntireState = { 'localtime': Date(), 'utctime': new Date().toUTCString(), 'isotime': new Date().toISOString() }; + amtstack.BatchEnum(null, AllWsman, saveEntireAmtStateOk2, null, true); + amtstack.GetAuditLog(saveEntireAmtStateOk3); + amtstack.GetMessageLog(saveEntireAmtStateOk4); + +} + +// Save the entire Intel AMT state +function saveEntireAmtState() { + // See if MicroLMS needs to be started + if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) { + settings.noconsole = true; + startLms().then(saveEntireAmtState2); + } + else { + saveEntireAmtState2(); + } +} + +function onWsmanProcessChanged(a, b) { var x = Math.floor((a * 100) / b); if (x < IntelAmtEntireStateProgress) { IntelAmtEntireStateProgress = x; console.log((100 - x) + '%'); } } +function saveEntireAmtStateOk2(stack, name, responses, status) { if (status == 600) { console.log('ERROR: Unable to connect to Intel(R) AMT.'); exit(2); } IntelAmtEntireState['wsmanenums'] = responses; saveEntireAmtStateDone(); } +function saveEntireAmtStateOk3(stack, messages, status) { if (status == 600) { console.log('ERROR: Unable to connect to Intel(R) AMT.'); exit(2); } IntelAmtEntireState['auditlog'] = messages; saveEntireAmtStateDone(); } +function saveEntireAmtStateOk4(stack, messages, tag, status) { if (status == 600) { console.log('ERROR: Unable to connect to Intel(R) AMT.'); exit(2); } IntelAmtEntireState['eventlog'] = messages; saveEntireAmtStateDone(); } + +// Called when the entire state of Intel AMT is fetched. +function saveEntireAmtStateDone() { + if (--IntelAmtEntireStateCalls != 0) return; + var out = fs.openSync(settings.output, 'w'); + fs.writeSync(out, Buffer.from(JSON.stringify(IntelAmtEntireState))); + fs.closeSync(out); + console.log('Done, results written to ' + settings.output + '.'); + exit(1); +} + + +// +// FETCH ALL INTEL AMT MEI STATE +// + +// Get Intel AMT information using MEI +// TODO: If this call is called many time at once, it's going to cause issues. +var getAmtInfoFetching = null; +var getAmtInfoFetchingTimer = null; +function getAmtInfo(func, tag) { + if (amtMei == null) { if (func != null) { func(null, tag); } return; } + if (getAmtInfoFetching != null) { getAmtInfoFetching.push({ f: func, t: tag }); return; } + getAmtInfoFetching = [{ f: func, t: tag }]; + amtMeiTmpState = { Flags: 0, TrustedHashes: [] }; // Flags: 1=EHBC, 2=CCM, 4=ACM + getAmtInfoFetchingTimer = setTimeout(function () { + // MEI failed to respond, break out and reset everthing. + for (var i in getAmtInfoFetching) { if (getAmtInfoFetching[i].f != null) { getAmtInfoFetching[i].f(amtMeiTmpState, getAmtInfoFetching[i].t); } } + getAmtInfoFetching = null; + getAmtInfoFetchingTimer = null; + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + }, 3000); + amtMei.getProtocolVersion(function (result) { if (result != null) { amtMeiTmpState.MeiVersion = result; } }); + amtMei.getVersion(function (val) { + amtMeiTmpState.Versions = {}; + if (val != null) { + for (var version in val.Versions) { amtMeiTmpState.Versions[val.Versions[version].Description] = val.Versions[version].Version; } + amtMei.getProvisioningMode(function (result) { if (result != null) { amtMeiTmpState.ProvisioningMode = result.mode; } }); + amtMei.getProvisioningState(function (result) { if (result != null) { amtMeiTmpState.ProvisioningState = result.state; } }); + amtMei.getEHBCState(function (result) { if ((result != null) && (result.EHBC == true)) { amtMeiTmpState.Flags += 1; } }); + amtMei.getControlMode(function (result) { if (result != null) { if (result.controlMode == 1) { amtMeiTmpState.Flags += 2; } if (result.controlMode == 2) { amtMeiTmpState.Flags += 4; } } }); + //amtMei.getMACAddresses(function (result) { if (result != null) { amtMeiTmpState.mac = result; } }); + amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.dns = result; } }); + amtMei.getHashHandles(function (handles) { + exitOnCount = handles.length; + for (var i = 0; i < handles.length; ++i) { + amtMei.getCertHashEntry(handles[i], function (result) { + amtMeiTmpState.TrustedHashes.push({ Active: result.isActive, Default: result.isDefault, HashAlgorithm: result.hashAlgorithm, Name: result.name, Hash: result.certificateHash }); + if (--exitOnCount == 0) { + amtMeiTmpState.Notifications = lmsNotifications; amtMeiState = amtMeiTmpState; + for (var i in getAmtInfoFetching) { if (getAmtInfoFetching[i].f != null) { getAmtInfoFetching[i].f(amtMeiTmpState, getAmtInfoFetching[i].t); } } + getAmtInfoFetching = null; + clearTimeout(getAmtInfoFetchingTimer); + getAmtInfoFetchingTimer = null; + } + }); + } + }); + } else { + amtMeiState = amtMeiTmpState; + amtMeiState.ProvisioningMode = -858993460; + amtMeiState.TrustedHashes = {}; + amtMeiState.Notifications = lmsNotifications; + //console.log('getAmtInfo3', JSON.stringify(amtMeiState)); + if (func != null) { func(amtMeiState, tag); } + } + }); +} + + +// +// MicroLMS +// + +var lmsControlSockets = {}; +var lmsControlSocketsNextId = 1; +var lmsNotifications = []; +var amtLms = null; +var promise = require('promise'); + +function startLms(func, lmscommander) { + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + var lme_heci = null + try { lme_heci = require('amt-lme'); } catch (ex) { } + if (lme_heci == null) { if (func != null) { func(func, 0); } this.promise._res(); return; } + + //var amtLms = null; + var http = require('http'); + + console.log('Setting up MEI...'); + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); + //console.log("PTHI Connected."); + + console.log('Setting up LME...'); + amtLms = new lme_heci({ debug: settings.lmsdebug }); + amtLms.promise = ret; + amtLms.on('error', function (e) { + //console.log('LME connection failed', e); + if (lmscommander === true) { //settings.noconsole !== true) { + startMeshCommanderLms(); + //console.log("LMS started, MeshCommander on HTTP/16994."); + tempTimer = setTimeout(function () { delete tempTimer; setupMeiOsAdmin(func, 2); }, 100); + } else { + //console.log('LME connection failed: ' + JSON.stringify(e)); + tempTimer = setTimeout(function () { delete tempTimer; setupMeiOsAdmin(func, 0); }, 100); + } + this.promise._res(); + }); + amtLms.on('notify', function (data, options, str, code) { + if (code == 'iAMT0052-3') { + kvmGetData(); + } else if (str != null) { + var notify = { date: Date.now(), str: str, code: code }; + lmsNotifications.push(notify); + while (lmsNotifications.length > 100) { lmsNotifications.shift(); } + var notifyBuf = Buffer.concat([Buffer.from('0900', 'hex'), Buffer.from(JSON.stringify(notify))]) // Add a notification + for (var i in lmsControlSockets) { lmsControlSockets[i].write(notifyBuf); } + } + }); + //console.log('LME Connecting...'); + amtLms.on('bind', function (mapping) { + if (mapping[16992]) { this.removeAllListeners('bind'); } else { return; } + //console.log('LMS Bounded'); + amtLms.connected = true; + this.promise._res(); + + //console.log("LME Connected."); + if (settings.noconsole !== true) { + startMeshCommanderLms(); + //console.log("LMS started, MeshCommander on HTTP/16994."); + tempTimer = setTimeout(function () { delete tempTimer; setupMeiOsAdmin(func, 2); }, 100); + //console.logReferenceCount(tempTimer); + } else { + //console.log("LMS started."); + tempTimer = setTimeout(function () { delete tempTimer; setupMeiOsAdmin(func, 1); }, 100); + //console.logReferenceCount(tempTimer); + } + + }); + return (ret); +} + +function startMeshCommanderLms() { + // MeshCommander LMS v0.7.5 + var _IntelAmtWebApp_etag = "C2ZfnIbUEl7w4c1S1Xbd"; + var _IntelAmtWebApp = "77u/PCFET0NUWVBFIGh0bWw+DQo8aHRtbCBzdHlsZT0iaGVpZ2h0OjEwMCUiPg0KPGhlYWQ+DQogICAgPG1ldGEgaHR0cC1lcXVpdj0iWC1VQS1Db21wYXRpYmxlIiBjb250ZW50PSJJRT1lZGdlIj4gDQogICAgPG1ldGEgY29udGVudD0idGV4dC9odG1sO2NoYXJzZXQ9dXRmLTgiIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSI+DQogICAgPG1ldGEgbmFtZT0iZm9ybWF0LWRldGVjdGlvbiIgY29udGVudD0idGVsZXBob25lPW5vIj4NCiAgICA8bGluayByZWw9Imljb24iIHR5cGU9ImltYWdlL3BuZyIgaHJlZj0iZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvPSI+IDwhLS0gU3RvcCBmYXZpY29uLmljbyBmcm9tIGxvYWRpbmcgLS0+DQogICAgPHN0eWxlPmJvZHkgew0KICAgIGhlaWdodDogMTAwJTsNCiAgICBtYXgtaGVpZ2h0OiAxMDAlOw0KICAgIG92ZXJmbG93OiBoaWRkZW47DQogICAgZm9udC1mYW1pbHk6IGFyaWFsLCBoZWx2ZXRpY2EsIHNhbnMtc2VyaWY7DQogICAgZm9udC1zaXplOiA5cHQ7DQogICAgY29sb3I6IGJsYWNrOw0KICAgIGJhY2tncm91bmQ6IHdoaXRlOw0KICAgIG1hcmdpbi10b3A6IDA7DQogICAgbWFyZ2luLWxlZnQ6IDA7DQogICAgbWFyZ2luLXJpZ2h0OiAwOw0KICAgIC13ZWJraXQtdG91Y2gtY2FsbG91dDogbm9uZTsNCiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lOw0KICAgIC1raHRtbC11c2VyLXNlbGVjdDogbm9uZTsNCiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lOw0KICAgIC1tcy11c2VyLXNlbGVjdDogbm9uZTsNCiAgICB1c2VyLXNlbGVjdDogbm9uZTsNCn0NCg0KbGkgew0KICAgIG1hcmdpbjogMDsNCiAgICBwYWRkaW5nOiAwOw0KfQ0KDQpsYWJlbCB7DQogICAgZGlzcGxheTogYmxvY2s7DQogICAgY29sb3I6IHdpbmRvd3RleHQ7DQogICAgYmFja2dyb3VuZC1jb2xvcjogd2luZG93Ow0KICAgIG1hcmdpbjogMDsNCiAgICBwYWRkaW5nOiAwOw0KICAgIHdpZHRoOiAxMDAlOw0KfQ0KDQogICAgbGFiZWw6aG92ZXIgew0KICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBoaWdobGlnaHQ7DQogICAgICAgIGNvbG9yOiBoaWdobGlnaHR0ZXh0Ow0KICAgIH0NCg0KYTp2aXNpdGVkIHsNCiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7DQogICAgY29sb3I6ICMwNGY7DQp9DQoNCmE6bGluayB7DQogICAgdGV4dC1kZWNvcmF0aW9uOiBub25lOw0KICAgIGNvbG9yOiAjMDRmOw0KfQ0KDQphOmhvdmVyIHsNCiAgICBjb2xvcjogIzU1NTsNCn0NCg0KaDEgew0KICAgIGZvbnQtc2l6ZTogMTFwdDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBjb2xvcjogYmxhY2s7DQogICAgbWFyZ2luLWxlZnQ6IDVweDsNCiAgICBtYXJnaW4tdG9wOiAxMHB4Ow0KICAgIG1hcmdpbi1ib3R0b206IDZweDsNCn0NCg0KaDIgew0KICAgIGZvbnQtc2l6ZTogOXB0Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGNvbG9yOiBibGFjazsNCiAgICBtYXJnaW4tbGVmdDogNnB4Ow0KICAgIG1hcmdpbi10b3A6IDZweDsNCiAgICBtYXJnaW4tYm90dG9tOiAwOw0KfQ0KDQpwIHsNCiAgICBtYXJnaW4tbGVmdDogNnB4Ow0KICAgIG1hcmdpbi10b3A6IDRweDsNCiAgICBtYXJnaW4tYm90dG9tOiAwOw0KICAgIG1hcmdpbi1yaWdodDogMnB4Ow0KfQ0KDQp0ZCB7DQogICAgZm9udC1zaXplOiA5cHQ7DQp9DQoNCnRoIHsNCiAgICBmb250LXNpemU6IDlwdDsNCn0NCg0KICAgIHRoOmhvdmVyIHsNCiAgICAgICAgY3Vyc29yOiBwb2ludGVyOw0KICAgICAgICBiYWNrZ3JvdW5kOiAjYWFhOw0KICAgIH0NCg0KLmhlYWRlciB7DQogICAgcG9zaXRpb246IGZpeGVkOw0KICAgIHRvcDogMDsNCiAgICBsZWZ0OiAwOw0KICAgIHJpZ2h0OiAwOw0KICAgIGhlaWdodDogNjdweDsNCiAgICBiYWNrZ3JvdW5kOiAjMDM2Ow0KICAgIC8qIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICM2YTY5NjAgMCUsIzQyNDEzYyAxMDAlKTsgKi8NCn0NCg0KLnByb2dyZXNzYmFyIHsNCiAgICBwb3NpdGlvbjogZml4ZWQ7DQogICAgdG9wOiA2N3B4Ow0KICAgIGxlZnQ6IDA7DQogICAgcmlnaHQ6IDA7DQogICAgaGVpZ2h0OiAycHg7DQogICAgYmFja2dyb3VuZDogIzAzNjsNCn0NCg0KLmluIHsNCiAgICBtYXJnaW4tbGVmdDogNDBweDsNCn0NCg0KLmxvZyB7DQogICAgYmFja2dyb3VuZDogI2JiYmFiNTsNCn0NCg0KLmxvZzEgew0KICAgIGJhY2tncm91bmQ6ICNiYmJhYjU7DQp9DQoNCi5sb2cgdGJvZHkgdHI6bnRoLWNoaWxkKG9kZCkgew0KICAgIGJhY2tncm91bmQ6ICNlOGVlZmU7DQp9DQoNCi5mdWxsY2VsbCB7DQogICAgcG9zaXRpb246IGZpeGVkOw0KICAgIHRvcDogNjlweDsNCiAgICByaWdodDogMDsNCiAgICBib3R0b206IDA7DQogICAgbGVmdDogMHB4Ow0KICAgIG92ZXJmbG93OiBoaWRkZW47DQp9DQoNCi5tYWluY2VsbCB7DQogICAgcG9zaXRpb246IGZpeGVkOw0KICAgIHRvcDogNjlweDsNCiAgICByaWdodDogMDsNCiAgICBib3R0b206IDA7DQogICAgbGVmdDogMTU2cHg7DQogICAgb3ZlcmZsb3c6IGhpZGRlbjsNCiAgICBwYWRkaW5nLWxlZnQ6IDJweDsNCiAgICB2ZXJ0aWNhbC1hbGlnbjogdG9wOw0KfQ0KDQoubmF2YmFyIHsNCiAgICBwb3NpdGlvbjogZml4ZWQ7DQogICAgdG9wOiA2OXB4Ow0KICAgIGxlZnQ6IDA7DQogICAgYm90dG9tOiAwOw0KICAgIHdpZHRoOiAxNTZweDsNCiAgICBib3JkZXItcmlnaHQ6IDJweCBzb2xpZCAjQjBDNkZDOw0KICAgIHZlcnRpY2FsLWFsaWduOiB0b3A7DQogICAgYmFja2dyb3VuZDogIzAzNjsNCiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQodG8gYm90dG9tLCAjYmZkMWZjIDAlLCNlOGVlZmUgMTAwJSk7DQp9DQoNCi5uYXYxIHsNCiAgICBwYWRkaW5nOiAxcHggMHB4IDFweCA4cHg7DQogICAgbWFyZ2luOiAwcHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgY29sb3I6IGJsYWNrOw0KICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KfQ0KDQoubmF2MiB7DQogICAgbWFyZ2luLWxlZnQ6IDMycHg7DQogICAgbWFyZ2luLXRvcDogMDsNCiAgICBjb2xvcjogYmxhY2s7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KfQ0KDQouciB7DQogICAgZm9udC1zaXplOiAxMXB0Ow0KfQ0KDQoucjAgew0KICAgIGJhY2tncm91bmQ6IHdoaXRlOw0KfQ0KDQoucjEgew0KICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCBncmF5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCi5yMiB7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLnIzIHsNCiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgZ3JheTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQogICAgLnIzOmhvdmVyIHsNCiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogIzgzODI3YjsNCiAgICAgICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIH0NCg0KLnNwcmVhZCB7DQogICAgaGVpZ2h0OiAxMDAlOw0KICAgIHdpZHRoOiAxMDAlOw0KICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlOw0KfQ0KDQoudGltZXIgew0KICAgIGJvcmRlcjogMXB4IHNvbGlkICNhYmNhZTE7DQogICAgYmFja2dyb3VuZC1jb2xvcjogI2FiY2FlMTsNCn0NCg0KLnRtIHsNCiAgICBmb250LXNpemU6IDdwdDsNCn0NCg0KLnRvcDEgew0KICAgIGZvbnQtc2l6ZTogMjBwdDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBjb2xvcjogI0M4QzhDODsNCiAgICBtYXJnaW4tdG9wOiA2cHg7DQogICAgbWFyZ2luLWxlZnQ6IDEwcHg7DQp9DQoNCi50b3AyIHsNCiAgICBjb2xvcjogI0M4QzhDODsNCiAgICBtYXJnaW4tbGVmdDogMTBweDsNCn0NCg0KLndhcm4gew0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGNvbG9yOiAjYzAwMDAwOw0KfQ0KDQouaWNvbjEgew0KICAgIHdpZHRoOiAxNHB4Ow0KICAgIGhlaWdodDogMTVweDsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybCgiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoRUFBUUFMTVBBTEMyeXg5RHIwbHkyV3VSOEZkdXVoUXlsb09XenpkZ3ltNkd5WnVxMS92NytxQ2hwY2pKMEplWG03ZTV2di8vL3lINUJBRUFBQThBTEFBQUFBQVFBQkFBQUFSeThNbEpxMTJPTWJlc2JFQXlqRU1DTkJWb2pJb3lDTWhKQVlZZ0RPMXd3TUMwSkxhZzRFQThHRG9QQnlLWWFCRUNVSUpEd2hnT0V3d0ZvZ0FOTUtqRFF3Q3JNSENoM3lSQ1BNNXVvOVBId3RBbEU4N0hDZUE1ZG5JSlBSTWdUekY3QlFRSktCUXFmQVFHTWg0WUdod2VsUllSQURzPSIpOw0KfQ0KDQouaWNvbjIgew0KICAgIHdpZHRoOiAxNHB4Ow0KICAgIGhlaWdodDogMTVweDsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybCgiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoRUFBUUFKRURBUERWTWFtTUR3QUFBUC8vL3lINUJBRUFBQU1BTEFBQUFBQVFBQkFBQUFJeW5JK3BCckFhV25pb05XcWluYlFKY1QzYUp6MFdHU1lhZ0FKY3RhME9JbHNiZklMMlViZWxEUXhLQXNTaXNUakRJQW9BT3c9PSIpOw0KfQ0KDQouaWNvbjMgew0KICAgIHdpZHRoOiAxNHB4Ow0KICAgIGhlaWdodDogMTVweDsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybCgiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoRUFBUUFLSUhBTEVjSGVYdDdhQ2hwY2pKMEplWG03ZTV2di8vLy8vLy95SDVCQUVBQUFjQUxBQUFBQUFRQUJBQUFBTmFlTHJjTG1XTUlwd2lwWkJOSUdsWUI0ekFwakZhWUJBallRVFk0aFhHU3FoQ1dSM2FTTCtCbkU4eElBRUVnYUJ4UURRaUE0V2xvZ2VnU1FMRjRVSEFzbzRHaG1KbkVTVmtSN0FxUTJRa2NVSFUxc2tDa1ZBc2VFY0NBRHM9Iik7DQp9DQoNCi5pdGVtQmFyIHsNCiAgICBwYWRkaW5nOiA3cHg7DQogICAgbWluLWhlaWdodDogMjBweDsNCiAgICBtYXJnaW4tdG9wOiA0cHg7DQogICAgbWFyZ2luLXJpZ2h0OiA4cHg7DQogICAgd2lkdGg6IGF1dG87DQogICAgYm9yZGVyLXJhZGl1czogOHB4Ow0KICAgIGJhY2tncm91bmQtY29sb3I6ICM4YzhiODE7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KfQ0KDQouY29tcHV0ZXJpdGVtY2lyIHsNCiAgICB3aWR0aDogMTJweDsNCiAgICBoZWlnaHQ6IDEycHg7DQogICAgYm9yZGVyLXJhZGl1czogNHB4Ow0KICAgIGJhY2tncm91bmQ6IGdyYXk7DQogICAgbWFyZ2luLXJpZ2h0OjRweDsNCn0NCg0KLmNvbXB1dGVyaXRlbSB7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIHdpZHRoOiBhdXRvOw0KICAgIC8qDQogICAgYm9yZGVyLXJhZGl1czogNXB4Ow0KICAgIGJhY2tncm91bmQtY29sb3I6ICNhNmE1YTA7DQogICAgKi8NCiAgICBoZWlnaHQ6IDI4cHg7DQogICAgbWFyZ2luOiA0cHg7DQogICAgcGFkZGluZzogMnB4Ow0KfQ0KDQogICAgLmNvbXB1dGVyaXRlbTpob3ZlciB7DQogICAgICAgIGJhY2tncm91bmQtY29sb3I6ICM4MzgyN2I7DQogICAgfQ0KDQoudXMgew0KICAgIC13ZWJraXQtdG91Y2gtY2FsbG91dDogaW5pdGlhbDsNCiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBhdXRvOw0KICAgIC1raHRtbC11c2VyLXNlbGVjdDogdGV4dDsNCiAgICAtbW96LXVzZXItc2VsZWN0OiB0ZXh0Ow0KICAgIC1tcy11c2VyLXNlbGVjdDogdGV4dDsNCiAgICB1c2VyLXNlbGVjdDogdGV4dDsNCn0NCg0KDQovKiBTdHlsZXMgYmVsb3cgYXJlIG9ubHkgdXNlZCBpbiBOb2RlSlMsIFdlYlNpdGUgY29tcGlsZXIgc2hvdWxkIHJlbW92ZSB0aGVzZSBpbiB0aGUgZnV0dXJlICovDQoNCi50b3BDZWxsIHsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOnVybCgnaW1hZ2VzLWNvbW1hbmRlci9sb2dvYmFjay5wbmcnKTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpuby1yZXBlYXQ7DQp9DQoNCi5pMSB7DQogICAgYmFja2dyb3VuZDogdXJsKGltYWdlcy1jb21tYW5kZXIvaWNvbnM1MC5wbmcpIDBweCAwcHg7DQogICAgaGVpZ2h0OiA1MHB4Ow0KICAgIHdpZHRoOiA1MHB4Ow0KICAgIGN1cnNvcjogcG9pbnRlcjsNCiAgICBib3JkZXI6IG5vbmU7DQp9DQoNCi5pMiB7DQogICAgYmFja2dyb3VuZDogdXJsKGltYWdlcy1jb21tYW5kZXIvaWNvbnM1MC5wbmcpIC01MHB4IDBweDsNCiAgICBoZWlnaHQ6IDUwcHg7DQogICAgd2lkdGg6IDUwcHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmkzIHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczUwLnBuZykgLTEwMHB4IDBweDsNCiAgICBoZWlnaHQ6IDUwcHg7DQogICAgd2lkdGg6IDUwcHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmk0IHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczUwLnBuZykgLTE1MHB4IDBweDsNCiAgICBoZWlnaHQ6IDUwcHg7DQogICAgd2lkdGg6IDUwcHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmk1IHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczUwLnBuZykgLTIwMHB4IDBweDsNCiAgICBoZWlnaHQ6IDUwcHg7DQogICAgd2lkdGg6IDUwcHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmk2IHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczUwLnBuZykgLTI1MHB4IDBweDsNCiAgICBoZWlnaHQ6IDUwcHg7DQogICAgd2lkdGg6IDUwcHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmoxIHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczI2LnBuZykgMHB4IDBweDsNCiAgICBoZWlnaHQ6IDI2cHg7DQogICAgd2lkdGg6IDI2cHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmoyIHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczI2LnBuZykgLTI2cHggMHB4Ow0KICAgIGhlaWdodDogMjZweDsNCiAgICB3aWR0aDogMjZweDsNCiAgICBjdXJzb3I6IHBvaW50ZXI7DQogICAgYm9yZGVyOiBub25lOw0KfQ0KDQouajMgew0KICAgIGJhY2tncm91bmQ6IHVybChpbWFnZXMtY29tbWFuZGVyL2ljb25zMjYucG5nKSAtNTJweCAwcHg7DQogICAgaGVpZ2h0OiAyNnB4Ow0KICAgIHdpZHRoOiAyNnB4Ow0KICAgIGN1cnNvcjogcG9pbnRlcjsNCiAgICBib3JkZXI6IG5vbmU7DQp9DQoNCi5qNCB7DQogICAgYmFja2dyb3VuZDogdXJsKGltYWdlcy1jb21tYW5kZXIvaWNvbnMyNi5wbmcpIC03OHB4IDBweDsNCiAgICBoZWlnaHQ6IDI2cHg7DQogICAgd2lkdGg6IDI2cHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmo1IHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczI2LnBuZykgLTEwNHB4IDBweDsNCiAgICBoZWlnaHQ6IDI2cHg7DQogICAgd2lkdGg6IDI2cHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmo2IHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczI2LnBuZykgLTEzMHB4IDBweDsNCiAgICBoZWlnaHQ6IDI2cHg7DQogICAgd2lkdGg6IDI2cHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmdyYXkgew0KICAgIC8qZmlsdGVyOiB1cmwoImRhdGE6aW1hZ2Uvc3ZnK3htbDt1dGY4LCZsdDtzdmcgeG1sbnM9XCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wnJmd0OyZsdDtmaWx0ZXIgaWQ9XCdncmF5c2NhbGVcJyZndDsmbHQ7ZmVDb2xvck1hdHJpeCB0eXBlPVwnbWF0cml4XCcgdmFsdWVzPVwnMC4zMzMzIDAuMzMzMyAwLjMzMzMgMCAwIDAuMzMzMyAwLjMzMzMgMC4zMzMzIDAgMCAwLjMzMzMgMC4zMzMzIDAuMzMzMyAwIDAgMCAwIDAgMSAwXCcvJmd0OyZsdDsvZmlsdGVyJmd0OyZsdDsvc3ZnJmd0OyNncmF5c2NhbGUiKTsqLyAvKiBGaXJlZm94IDEwKywgRmlyZWZveCBvbiBBbmRyb2lkICovDQogICAgZmlsdGVyOiBncmF5OyAvKiBJRTYtOSAqLw0KICAgIC13ZWJraXQtZmlsdGVyOiBncmF5c2NhbGUoMTAwJSkgb3BhY2l0eSg2MCUpOyAvKiBDaHJvbWUgMTkrLCBTYWZhcmkgNissIFNhZmFyaSA2KyBpT1MgKi8NCn0NCg0KLmcxIHsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwJSAwJTsNCiAgICB3aWR0aDogMTRweDsNCiAgICBoZWlnaHQ6IDEwMCU7DQogICAgZmxvYXQ6IGxlZnQ7DQogICAgLyogZmFsbGJhY2sgKE9wZXJhKSAqLw0KICAgIC8qIE1vemlsbGE6ICovDQogICAgLyogQ2hyb21lLCBTYWZhcmk6Ki8NCiAgICBiYWNrZ3JvdW5kLWltYWdlOiBsaW5lYXItZ3JhZGllbnQodG8gcmlnaHQsICNmZmZmZmYgMCUsICNjOWM5YzkgMTAwJSk7DQogICAgYmFja2dyb3VuZC1jb2xvcjogI2M5YzljOTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtYXR0YWNobWVudDogc2Nyb2xsOw0KfQ0KDQouZzIgew0KICAgIGJhY2tncm91bmQtcG9zaXRpb246IDAlIDAlOw0KICAgIHdpZHRoOiAxNHB4Ow0KICAgIGhlaWdodDogMTAwJTsNCiAgICBmbG9hdDogcmlnaHQ7DQogICAgLyogZmFsbGJhY2sgKE9wZXJhKSAqLw0KICAgIC8qIE1vemlsbGE6ICovDQogICAgLyogQ2hyb21lLCBTYWZhcmk6Ki8NCiAgICBiYWNrZ3JvdW5kLWltYWdlOiBsaW5lYXItZ3JhZGllbnQodG8gcmlnaHQsICNjOWM5YzkgMCUsICNmZmZmZmYgMTAwJSk7DQogICAgYmFja2dyb3VuZC1jb2xvcjogI2M5YzljOTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtYXR0YWNobWVudDogc2Nyb2xsOw0KfQ0KDQouZzFzIHsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwJSAwJTsNCiAgICB3aWR0aDogMTRweDsNCiAgICBoZWlnaHQ6IDEwMCU7DQogICAgZmxvYXQ6IGxlZnQ7DQogICAgLyogZmFsbGJhY2sgKE9wZXJhKSAqLw0KICAgIC8qIE1vemlsbGE6ICovDQogICAgLyogQ2hyb21lLCBTYWZhcmk6Ki8NCiAgICBiYWNrZ3JvdW5kLWltYWdlOiBsaW5lYXItZ3JhZGllbnQodG8gcmlnaHQsICNmZmZmZmYgMCUsICNhMGEwYTAgMTAwJSk7DQogICAgYmFja2dyb3VuZC1jb2xvcjogI2EwYTBhMDsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtYXR0YWNobWVudDogc2Nyb2xsOw0KfQ0KDQouZzJzIHsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwJSAwJTsNCiAgICB3aWR0aDogMTRweDsNCiAgICBoZWlnaHQ6IDEwMCU7DQogICAgZmxvYXQ6IHJpZ2h0Ow0KICAgIC8qIGZhbGxiYWNrIChPcGVyYSkgKi8NCiAgICAvKiBNb3ppbGxhOiAqLw0KICAgIC8qIENocm9tZSwgU2FmYXJpOiovDQogICAgYmFja2dyb3VuZC1pbWFnZTogbGluZWFyLWdyYWRpZW50KHRvIHJpZ2h0LCAjYTBhMGEwIDAlLCAjZmZmZmZmIDEwMCUpOw0KICAgIGJhY2tncm91bmQtY29sb3I6ICNhMGEwYTA7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6IHJlcGVhdDsNCiAgICBiYWNrZ3JvdW5kLWF0dGFjaG1lbnQ6IHNjcm9sbDsNCn0NCg0KDQoubGJidXR0b24gew0KICAgIHdpZHRoOjQ0cHg7DQogICAgaGVpZ2h0OjQ0cHg7DQogICAgYm9yZGVyLXJhZGl1czo1cHg7DQogICAgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsNCiAgICBtYXJnaW4tbGVmdDo0cHg7DQogICAgbWFyZ2luLXRvcDo0cHg7DQogICAgcG9zaXRpb246cmVsYXRpdmU7DQogICAgY3Vyc29yOnBvaW50ZXI7DQogICAgb3BhY2l0eTowLjU7DQp9DQoNCi5sYmJ1dHRvbjpob3ZlciB7DQogICAgb3BhY2l0eToxOw0KfQ0KDQoubGJidXR0b25zZWwgew0KICAgIG9wYWNpdHk6MC45Ow0KfQ0KDQoubGJidXR0b25zZWwyIHsNCiAgICB3aWR0aDo4MnB4Ow0KICAgIGJvcmRlci1yYWRpdXM6NXB4IDBweCAwcHggNXB4Ow0KICAgIG9wYWNpdHk6MTsNCn0NCg0KLmxiMSB7DQogICAgYmFja2dyb3VuZDogdXJsKGltYWdlcy1jb21tYW5kZXIvbGVmdGJhci0zMi5wbmcpIC0wcHggMHB4Ow0KICAgIGhlaWdodDogMzJweDsNCiAgICB3aWR0aDogMzJweDsNCiAgICBjdXJzb3I6IHBvaW50ZXI7DQogICAgYm9yZGVyOiBub25lOw0KfQ0KDQoubGIyIHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9sZWZ0YmFyLTMyLnBuZykgLTMycHggMHB4Ow0KICAgIGhlaWdodDogMzJweDsNCiAgICB3aWR0aDogMzJweDsNCiAgICBjdXJzb3I6IHBvaW50ZXI7DQogICAgYm9yZGVyOiBub25lOw0KfQ0KDQoubGIzIHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9sZWZ0YmFyLTMyLnBuZykgLTY0cHggMHB4Ow0KICAgIGhlaWdodDogMzJweDsNCiAgICB3aWR0aDogMzJweDsNCiAgICBjdXJzb3I6IHBvaW50ZXI7DQogICAgYm9yZGVyOiBub25lOw0KfTwvc3R5bGU+DQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgPHN0eWxlPg0KICAgICAgICAubWVudWl0ZW0geyBjdXJzb3I6IHBvaW50ZXI7IGJvcmRlcjogbm9uZTsgcGFkZGluZzo1cHg7IH0NCiAgICAgICAgLm1lbnVpdGVtOmhvdmVyIHsgYmFja2dyb3VuZC1jb2xvcjogIzZiOWRjNzsgfQ0KICAgIDwvc3R5bGU+DQogICAgICAgICAgICAgICAgPHRpdGxlPkxNUyBNZXNoQ29tbWFuZGVyPC90aXRsZT4NCiAgICAgICAgICAgIDwvaGVhZD4NCjxib2R5IG9udW5sb2FkPSJjbGVhbnVwKCkiPg0KICAgIDxkaXYgaWQ9ImlkX3RvcGhlYWRlciIgY2xhc3M9ImhlYWRlciI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0YWJsZSBjbGFzcz0idG9wQ2VsbCIgc3R5bGU9IndpZHRoOjEwMCU7aGVpZ2h0OjU1cHgiPg0KICAgICAgICAgICAgPHRyPg0KICAgICAgICAgICAgICAgIDx0ZCB2YWxpZ249InRvcCIgbm93cmFwPSJub3dyYXAiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPSJ0b3AxIj5MTVMgTWVzaENvbW1hbmRlcjwvcD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPSJ0b3AyIiBpZD0iaWRfY29tcHV0ZXJuYW1lIj4NCiAgICAgICAgICAgICAgICA8L3RkPg0KICAgICAgICAgICAgICAgIDx0ZCB2YWxpZ249InRvcCI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+DQogICAgICAgICAgICA8L3RyPg0KICAgICAgICA8L3RhYmxlPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9InByb2dyZXNzYmFyIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9ImlkX3Byb2dyZXNzYmFyIiBzdHlsZT0iaGVpZ2h0OjJweDt3aWR0aDowJTtiYWNrZ3JvdW5kLWNvbG9yOnJlZCI+PC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgIDwvZGl2Pg0KICAgIDxkaXYgaWQ9ImlkX21lc3NhZ2V2aWV3IiBjbGFzcz0iZnVsbGNlbGwiIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlcjtwYWRkaW5nLXRvcDoxMDBweDtmb250LXNpemU6MjBweCI+DQogICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfbWVzc2FnZXZpZXdzdHIiPkxvYWRpbmcuLi48L3NwYW4+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxicj48YnI+PGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkNsb3NlIiBvbmNsaWNrPSJkaXNjb25uZWN0KCkiPg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgIDxkaXYgaWQ9ImlkX2xtc01haW5QYW5lbCIgY2xhc3M9ImZ1bGxjZWxsIiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgPGRpdiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjpsaWdodGdyYXk7aGVpZ2h0OjI0cHg7bWFyZ2luLWJvdHRvbTo2cHg7cGFkZGluZy10b3A6MnB4Ij4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImlkX2xtc1Rvb2xCYXJDb250ZW50IiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZmxvYXQ6bGVmdDtoZWlnaHQ6MjZweDt3aWR0aDoyNnB4O2N1cnNvcjpwb2ludGVyIiBvbmNsaWNrPSJ0b29sbWVudWNsaWNrKDApIj4NCiAgICAgICAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxNnB4Ij4mbmJzcDsmIzk3NzY7PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iUmVmcmVzaCIgb25jbGljaz0ibG1zUmVmcmVzaCgpIj4NCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJpZF9sbXNBY3RpdmF0ZUJ1dHRvbiIgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iQWN0aXZhdGUuLi4iIHN0eWxlPSJkaXNwbGF5Om5vbmUiIG9uY2xpY2s9Imxtc0FjdGl2YXRlKCkiPg0KICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9ImlkX2xtc0RlYWN0aXZhdGVCdXR0b24iIHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkRlYWN0aXZhdGUuLi4iIHN0eWxlPSJkaXNwbGF5Om5vbmUiIG9uY2xpY2s9Imxtc0RlYWN0aXZhdGUoKSI+DQogICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD0iaWRfbG1zTG9naW5CdXR0b24iIHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkxvZ2luLi4uIiBzdHlsZT0iZGlzcGxheTpub25lIiBvbmNsaWNrPSJsbXNMb2dpbigpIj4NCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJpZF9sbXNDb25maWd1cmVCdXR0b24iIHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkludGVsJnJlZzsgQU1UIExvZ2luLi4uIiBzdHlsZT0iZGlzcGxheTpub25lIiBvbmNsaWNrPSJsbXNDb25maWd1cmUoKSI+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgPC9kaXY+DQogICAgICAgIDxkaXYgaWQ9ImlkX2xtc0RhdGEiIHN0eWxlPSJtYXJnaW46MTBweCI+PC9kaXY+DQogICAgICAgIDxkaXYgaWQ9ImlkX2xtc0RhdGEyIiBzdHlsZT0ibWFyZ2luOjEwcHgiPjwvZGl2Pg0KICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJpZF9jb21wdXRlclNlbGVjdG9yTWVudSIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6I0VFRUVFRTtkaXNwbGF5Om5vbmU7cG9zaXRpb246YWJzb2x1dGU7bGVmdDowO3RvcDo5NHB4O3dpZHRoOjIwMHB4O3BhZGRpbmc6M3B4O3otaW5kZXg6MTAwMDtib3gtc2hhZG93OjVweCA1cHggNXB4ICM4ODg4ODg7Ym9yZGVyOjFweCBzb2xpZCBncmF5Ij4NCiAgICAgICAgPGRpdiBjbGFzcz0ibWVudWl0ZW0iIG9uY2xpY2s9InRvb2xtZW51Y2xpY2soMTAxKSI+PHNwYW4gaWQ9ImlkX21lbnVpdGVtMSI+JmJ1bGw7IDwvc3Bhbj5Db21wdXRlciBDb25maWd1cmF0aW9uPC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBjbGFzcz0ibWVudWl0ZW0iIG9uY2xpY2s9InRvb2xtZW51Y2xpY2soMTAyKSI+PHNwYW4gaWQ9ImlkX21lbnVpdGVtMiIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+JmJ1bGw7IDwvc3Bhbj5VU0IgU2V0dXAuYmluIEVkaXRvcjwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGlkPSJpZF91c2JTZXR1cFBhbmVsIiBjbGFzcz0iZnVsbGNlbGwiIHN0eWxlPSJkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgICAgIDx0YWJsZSBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojODA4MDgwO3dpZHRoOjEwMCUiPg0KICAgICAgICAgICAgPHRyPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9IndpZHRoOjI2cHg7Y3Vyc29yOnBvaW50ZXIiIG9uY2xpY2s9InRvb2xtZW51Y2xpY2soMCkiPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT0iZm9udC1zaXplOjE2cHgiPiZuYnNwOyYjOTc3Njs8L3NwYW4+DQogICAgICAgICAgICAgICAgPC90ZD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPg0KICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iTmV3Li4uIiBvbmNsaWNrPSJ1c2JfbmV3U2V0dXBCaW4oKSI+DQogICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJidXR0b24iIHZhbHVlPSJPcGVuLi4uIiBvbmNsaWNrPSJ1c2Jfb3BlblNldHVwQmluKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD0iaWRfc2F2ZVNldHVwQmluIiB0eXBlPSJidXR0b24iIHZhbHVlPSJTYXZlLi4uIiBvbmNsaWNrPSJ1c2Jfc2F2ZVNldHVwQmluKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD4NCiAgICAgICAgICAgIDwvdHI+DQogICAgICAgIDwvdGFibGU+DQogICAgICAgIDxkaXYgaWQ9ImlkX3VzYlNldHVwUGFuZWwyIiBzdHlsZT0icG9zaXRpb246Zml4ZWQ7b3ZlcmZsb3cteTpzY3JvbGw7bGVmdDowO3JpZ2h0OjA7Ym90dG9tOjA7dG9wOjk2cHgiPg0KICAgICAgICAgICAgPGRpdiBpZD0iaWRfU3RhcnR1cFNjcmVlbiIgc3R5bGU9IndpZHRoOjEwMCU7dGV4dC1hbGlnbjpjZW50ZXI7Y29sb3I6Z3JheTttYXJnaW4tdG9wOjM2cHgiPg0KICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPSJmb250LXNpemU6MjBweCI+SW50ZWw8c3VwIHN0eWxlPSJmb250LXNpemU6MTBweCI+JnJlZzs8L3N1cD4gQU1UIFVTQiBTZXR1cC5iaW4gTWFuYWdlcjwvc3Bhbj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJtYXJnaW46NHB4Ij5HZXQgc3RhcnRlZCBieSA8YSBvbmNsaWNrPSJ1c2JfbmV3U2V0dXBCaW4oKSIgc3R5bGU9ImN1cnNvcjpwb2ludGVyIj48dT5jcmVhdGluZzwvdT48L2E+IGEgbmV3IGZpbGUsIDxhIG9uY2xpY2s9InVzYl9vcGVuU2V0dXBCaW4oKSIgc3R5bGU9ImN1cnNvcjpwb2ludGVyIj48dT5vcGVuaW5nPC91PjwvYT4gYW4gZXhpc3Rpbmcgb25lPGJyPm9yIGRyYWcgJiBkcm9wcGluZyBhIHNldHVwLmJpbiBmaWxlIGluIHRoaXMgd2luZG93LjwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGlkPSJpZF9TZXR1cEJpbkFyZWEiIHN0eWxlPSJtYXJnaW46MTBweCI+PC9kaXY+DQogICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImlkX21haW52aWV3IiBzdHlsZT0iaGVpZ2h0OjEwMCU7ZGlzcGxheTpub25lIj4NCiAgICAgICAgPGRpdiBpZD0iaWRfbGVmdGJhciIgY2xhc3M9Im5hdmJhciI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdwYWRkaW5nOjhweCc+DQogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgaWQ9ImRpc2Nvbm5lY3RCdXR0b24iIHZhbHVlPSJEaXNjb25uZWN0IiBvbmtleXByZXNzPSJyZXR1cm4gZmFsc2UiIG9ua2V5ZG93bj0icmV0dXJuIGZhbHNlIiBvbmNsaWNrPSJkaXNjb25uZWN0KCkiIHN0eWxlPSJ3aWR0aDoxMzhweCI+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGlkPSJnbzEiIGNsYXNzPSJuYXYxIiBvbmNsaWNrPSJnbygxKSI+PGE+U3lzdGVtIFN0YXR1czwvYT48L3A+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBpZD0iZ28yIiBjbGFzcz0ibmF2MSIgb25jbGljaz0iZ28oMikiPjxhPkhhcmR3YXJlIEluZm9ybWF0aW9uPC9hPjwvcD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGlkPSJnbzYiIGNsYXNzPSJuYXYxIiBvbmNsaWNrPSJnbyg2KSI+PGE+RXZlbnQgTG9nPC9hPjwvcD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGlkPSJnbzE1IiBjbGFzcz0ibmF2MSIgb25jbGljaz0iZ28oMTUpIj48YT5BdWRpdCBMb2c8L2E+PC9wPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgaWQ9ImdvMjEiIGNsYXNzPSJuYXYxIiBvbmNsaWNrPSJnbygyMSkiPjxhPlN0b3JhZ2U8L2E+PC9wPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgaWQ9ImdvOCIgY2xhc3M9Im5hdjEiIG9uY2xpY2s9ImdvKDgpIj48YT5OZXR3b3JrIFNldHRpbmdzPC9hPjwvcD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGlkPSJnbzE3IiBjbGFzcz0ibmF2MSIgb25jbGljaz0iZ28oMTcpIj48YT5JbnRlcm5ldCBTZXR0aW5nczwvYT48L3A+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBpZD0iZ28xNiIgY2xhc3M9Im5hdjEiIG9uY2xpY2s9ImdvKDE2KSI+PGE+U2VjdXJpdHkgU2V0dGluZ3M8L2E+PC9wPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgaWQ9ImdvMTkiIGNsYXNzPSJuYXYxIiBvbmNsaWNrPSJnbygxOSkiPjxhPkFnZW50IFByZXNlbmNlPC9hPjwvcD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGlkPSJnbzE4IiBjbGFzcz0ibmF2MSIgb25jbGljaz0iZ28oMTgpIj48YT5TeXN0ZW0gRGVmZW5zZTwvYT48L3A+DQogICAgICAgICAgICAgICAgICAgICAgICA8cCBpZD0iZ28xMSIgY2xhc3M9Im5hdjEiIG9uY2xpY2s9ImdvKDExKSI+PGE+VXNlciBBY2NvdW50czwvYT48L3A+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBpZD0iZ28yMyIgY2xhc3M9Im5hdjEiIG9uY2xpY2s9ImdvKDIzKSI+PGE+V2FrZSBBbGFybXM8L2E+PC9wPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgaWQ9ImdvMjAiIGNsYXNzPSJuYXYxIiBvbmNsaWNrPSJnbygyMCkiPjxhPlNjcmlwdCBFZGl0b3I8L2E+PC9wPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgPGRpdiBpZD0iaWRfbWFpbmFyZWEiIGNsYXNzPSJtYWluY2VsbCI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJpZF9zY3JpcHRzdGF0dXMiIHN0eWxlPSJoZWlnaHQ6MjFweDtiYWNrZ3JvdW5kOiM4ZmFjOGQ7cGFkZGluZzo1cHg7bWFyZ2luLWJvdHRvbToxcHg7ZGlzcGxheTpub25lO292ZXJmbG93OmhpZGRlbiI+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZmxvYXQ6cmlnaHQiPjxpbnB1dCB0eXBlPSJidXR0b24iIHZhbHVlPSJTdG9wIFNjcmlwdCIgb25jbGljaz0ic2NyaXB0X1N0b3AoKSI+PC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZm9udC1zaXplOjE2cHg7cGFkZGluZy10b3A6MnB4O292ZXJmbG93OmhpZGRlbiI+Jm5ic3A7PGI+UnVubmluZyBTY3JpcHQ8L2I+PHNwYW4gc3R5bGU9Im92ZXJmbG93OmhpZGRlbiIgaWQ9ImlkX3NjcmlwdHN0YXR1c3N0ciI+PC9zcGFuPjwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJpZF9tYWluYXJlYV9mcmFtZSIgc3R5bGU9IndpZHRoOjEwMCU7aGVpZ2h0OjEwMCUiPg0KICAgICAgICAgICAgICAgIDxpZnJhbWUgaWQ9ImlkX1N0b3JhZ2VJRnJhbWUiIHN0eWxlPSJ3aWR0aDoxMDAlO2hlaWdodDoxMDAlO2JvcmRlcjowIj48L2lmcmFtZT4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iaWRfbWFpbmFyZWFfcGFkIiBzdHlsZT0icGFkZGluZzo4cHg7b3ZlcmZsb3cteDpoaWRkZW4iPg0KICAgICAgICAgICAgICAgIDxkaXYgaWQ9InAwIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPkxvYWRpbmcuLi48L2gxPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgaWQ9InAxIiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPlN5c3RlbSBTdGF0dXM8L2gxPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVTeXNTdGF0dXMiPjwvc3Bhbj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0icDIiIHN0eWxlPSJkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgICAgICAgICA8aDEgc3R5bGU9Im1hcmdpbi1ib3R0b206MTZweCI+SGFyZHdhcmUgSW5mb3JtYXRpb248L2gxPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVTeXNJbmZvIj48L3NwYW4+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJwNiIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+DQogICAgICAgICAgICAgICAgICAgIDxoMT5FdmVudCBMb2c8L2gxPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVFdmVudExvZyI+PC9zcGFuPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVFdmVudExvZzIiPjwvc3Bhbj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InA4IiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPk5ldHdvcmsgU2V0dGluZ3M8L2gxPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVOZXR3b3JrU2V0dGluZ3NTcGFuIj48L3NwYW4+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gaWQ9ImlkX1RhYmxlV2lmaTIiPjwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJwMTEiIHN0eWxlPSJkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgICAgICAgICA8aDE+VXNlciBBY2NvdW50czwvaDE+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIGlkPSJpZF9UYWJsZVVzZXJBY2NvdW50cyI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJwMTUiIHN0eWxlPSJkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVBdWRpdExvZzEiPjwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPkF1ZGl0IExvZzwvaDE+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIGlkPSJpZF9UYWJsZUF1ZGl0TG9nMiI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0icDE2IiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPlNlY3VyaXR5IFNldHRpbmdzPC9oMT4NCiAgICAgICAgICAgICAgICAgICAgPHNwYW4gaWQ9ImlkX1RhYmxlQ2VydHMiPjwvc3Bhbj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InAxNyIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+DQogICAgICAgICAgICAgICAgICAgIDxoMT5JbnRlcm5ldCBTZXR0aW5nczwvaDE+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIGlkPSJpZF9UYWJsZVJlbW90ZUFjY2VzcyI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0icDE4IiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPlN5c3RlbSBEZWZlbnNlPC9oMT4NCiAgICAgICAgICAgICAgICAgICAgPHNwYW4gaWQ9ImlkX1RhYmxlU3lzdGVtRGVmZW5zZSI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0icDE5IiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPkFnZW50IFByZXNlbmNlPC9oMT4NCiAgICAgICAgICAgICAgICAgICAgPHNwYW4gaWQ9ImlkX1RhYmxlU3lzdGVtQWdlbnRQcmVzZW5jZSI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0icDIwIiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPlNjcmlwdCBFZGl0b3I8L2gxPg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJsb2cxIiBzdHlsZT0icGFkZGluZzo1cHg7Ym9yZGVyLXJhZGl1czo1cHgiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0nRWRpdFNjcmlwdFN0YXR1cycgc3R5bGU9ImZsb2F0OnJpZ2h0O2ZvbnQtd2VpZ2h0OmJvbGQ7cGFkZGluZzo1cHgiPlN0b3BwZWQ8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IlZpZXcgRWRpdG9yIiB0aXRsZT0iU3dpdGNoIHRvIHNjcmlwdCBsaW5lIGVkaXRvciB2aWV3IiBpZD0idmlld0VkaXRvckJ1dHRvbiIgb25jbGljaz0ic2NyaXB0Vmlld0J1dHRvbigwKSI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IlZpZXcgQnVpbGRlciIgdGl0bGU9IlN3aXRjaCB0byBibG9jayBlZGl0b3IgdmlldyIgaWQ9InZpZXdCdWlsZGVyQnV0dG9uIiBvbmNsaWNrPSJzY3JpcHRWaWV3QnV0dG9uKDEpIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iTmV3Li4uIiB0aXRsZT0iQ2xlYXIgdGhlIHNjcmlwdCBlZGl0b3IiIG9uY2xpY2s9InNjcmlwdF9uZXdTY3JpcHREbGcoKSI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkxvYWQuLi4iIHRpdGxlPSJMb2FkIGEgc2NyaXB0IGZyb20gZmlsZSIgb25jbGljaz0ic2NyaXB0X3J1blNjcmlwdERsZygpIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IlNhdmUuLi4iIHRpdGxlPSJTYXZlIGEgc2NyaXB0IHRvIGZpbGUiIG9uY2xpY2s9InNjcmlwdF9zYXZlU2NyaXB0KGV2ZW50KSI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJidXR0b24iIHZhbHVlPSJSZXN0YXJ0IiB0aXRsZT0iQ29tcGlsZSB0aGUgc2NyaXB0IGFuZCBnZXQgcmVhZHkgdG8gcnVuIGl0IGZyb20gdGhlIHN0YXJ0IiBvbmNsaWNrPSJyZXNldFNjcmlwdEJ1dHRvbigpIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iQ29udGludWUiIHRpdGxlPSJSdW4gdGhlIHNjcmlwdCBmcm9tIHRoZSBjdXJyZW50IGV4ZWN1dGlvbiBwb2ludCIgb25jbGljaz0icnVuU2NyaXB0QnV0dG9uKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJidXR0b24iIHZhbHVlPSJCcmVhayIgdGl0bGU9IlBhdXNlIHRoZSBleGVjdXRpb24gb2YgdGhlIHNjcmlwdCIgb25jbGljaz0iYnJlYWtTY3JpcHRCdXR0b24oKSI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IlN0ZXAiIHRpdGxlPSJFeGVjdXRlIG9uZSBzdGVwIG9mIHRoZSBzY3JpcHQiIG9uY2xpY2s9InN0ZXBTY3JpcHRCdXR0b24oKSI+DQogICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InNjcmlwdGJ1aWxkZXIiIHN0eWxlPSJkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPGgyPlNjcmlwdCBCdWlsZGVyPC9oMj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9InBhZGRpbmc6MDttYXJnaW46MCI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0id2lkdGg6MjUwcHg7aGVpZ2h0OjQwMHB4O2Zsb2F0OmxlZnQ7cGFkZGluZzowO21hcmdpbjowO3BhZGRpbmctcmlnaHQ6M3B4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJibG9ja2ZpbHRlciIgc3R5bGU9IndpZHRoOmluaGVyaXQ7aGVpZ2h0OjI0cHg7cGFkZGluZzowO21hcmdpbjowO2JvcmRlcjoxcHggc29saWQgZ3JheTttYXJnaW4tYm90dG9tOjFweCIgcGxhY2Vob2xkZXI9IkZpbHRlciBibG9ja3MuLi4iIG9ua2V5dXA9InNjcmlwdF9mb25maWx0ZXJjaGFuZ2VkKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJibG9ja3MiIHN0eWxlPSJ3aWR0aDppbmhlcml0O2hlaWdodDozNzNweDtib3JkZXI6MXB4IHNvbGlkIGdyYXk7b3ZlcmZsb3cteTpzY3JvbGw7cGFkZGluZzowO21hcmdpbjowIj48L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJzY3JpcHRibG9ja3MiIHN0eWxlPSJ3aWR0aDphdXRvO2hlaWdodDo0MDBweDtwYWRkaW5nOjA7bWFyZ2luOjA7Ym9yZGVyOjFweCBzb2xpZCBncmF5O292ZXJmbG93LXk6c2Nyb2xsIiBvbmRyb3A9InNjcmlwdF9mb25kcm9wKGV2ZW50LCB0aGlzKSIgb25jbGljaz0ic2NyaXB0X2ZvbmNsaWNrKGV2ZW50KSI+PC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InNjcmlwdGVkaXRvciI+DQogICAgICAgICAgICAgICAgICAgICAgICA8aDI+U2NyaXB0PC9oMj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZXh0YXJlYSBpZD0ic2NyaXB0YXJlYSIgc3R5bGU9IndpZHRoOjEwMCU7aGVpZ2h0OjE3NnB4O3Jlc2l6ZTp2ZXJ0aWNhbDttYXJnaW46MDtwYWRkaW5nOjA7Zm9udC1mYW1pbHk6QXJpYWwsSGVsdmV0aWNhLHNhbnMtc2VyaWYiIHNwZWxsY2hlY2s9ImZhbHNlIj48L3RleHRhcmVhPg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnI+PGgyPkNvbXBpbGVkIFNjcmlwdDwvaDI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIGlkPSJjb21waWxlZGFyZWEiIHN0eWxlPSJ3aWR0aDoxMDAlO2hlaWdodDoxNnB4O3Jlc2l6ZTp2ZXJ0aWNhbDttYXJnaW46MDtwYWRkaW5nOjAiIHNwZWxsY2hlY2s9ImZhbHNlIj48L3RleHRhcmVhPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxicj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGgyPlZhcmlhYmxlczwvaDI+DQogICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJ2YXJpYWJsZXMiIHN0eWxlPSJ3aWR0aDoxMDAlO2hlaWdodDoyMDBweDtyZXNpemU6dmVydGljYWw7Ym9yZGVyOjFweCBzb2xpZCBncmF5O292ZXJmbG93OnNjcm9sbDttYXJnaW46MDtwYWRkaW5nOjA7dXNlci1zZWxlY3Q6dGV4dDstd2Via2l0LXVzZXItc2VsZWN0OnRleHQ7LWtodG1sLXVzZXItc2VsZWN0OnRleHQ7LW1vei11c2VyLXNlbGVjdDp0ZXh0Oy1tcy11c2VyLXNlbGVjdDp0ZXh0Ij48L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxoMj5Db25zb2xlPC9oMj4NCiAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIGlkPSJjb25zb2xlIiBzdHlsZT0id2lkdGg6MTAwJTtoZWlnaHQ6ODBweDtyZXNpemU6dmVydGljYWw7bWFyZ2luOjA7cGFkZGluZzowO3VzZXItc2VsZWN0OnRleHQ7LXdlYmtpdC11c2VyLXNlbGVjdDp0ZXh0Oy1raHRtbC11c2VyLXNlbGVjdDp0ZXh0Oy1tb3otdXNlci1zZWxlY3Q6dGV4dDstbXMtdXNlci1zZWxlY3Q6dGV4dCIgcmVhZG9ubHk9IiI+PC90ZXh0YXJlYT4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InAyMSIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+DQogICAgICAgICAgICAgICAgICAgIDxoMT5TdG9yYWdlPC9oMT4NCiAgICAgICAgICAgICAgICAgICAgPHNwYW4gaWQ9ImlkX1RhYmxlU3lzdGVtU3RvcmFnZSI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InAyMyIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+DQogICAgICAgICAgICAgICAgICAgIDxoMT5XYWtlIEFsYXJtczwvaDE+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIGlkPSJpZF9UYWJsZUFsYXJtIj48L3NwYW4+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICA8L2Rpdj4NCiAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZyIgc3R5bGU9InotaW5kZXg6MTAwMDtiYWNrZ3JvdW5kLWNvbG9yOiNFRUU7Ym94LXNoYWRvdzowcHggMHB4IDE1cHggIzY2Njtmb250LWZhbWlseTpBcmlhbCwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmO2JvcmRlci1yYWRpdXM6NXB4O3Bvc2l0aW9uOmZpeGVkO3RvcDoxNjBweDt3aWR0aDo0MDBweDtkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgPGRpdiBzdHlsZT0id2lkdGg6MTAwJTtiYWNrZ3JvdW5kLWNvbG9yOiMwMDMzNjY7Y29sb3I6I0ZGRjtib3JkZXItcmFkaXVzOjVweCA1cHggMCAwIj4NCiAgICAgICAgICAgIDxkaXYgaWQ9J2lkX2RpYWxvZ2Nsb3NlJyBzdHlsZT0iZmxvYXQ6cmlnaHQ7cGFkZGluZzoxcHg7bWFyZ2luLXJpZ2h0OjVweDtjdXJzb3I6cG9pbnRlcjtmb250LXNpemU6MTVweCIgb25jbGljaz0ic2V0RGlhbG9nTW9kZSgpIj4mI3gyNzE2OzwvZGl2Pg0KICAgICAgICAgICAgPGRpdiBpZD0naWRfZGlhbG9ndGl0bGUnIHN0eWxlPSJwYWRkaW5nOjVweCI+PC9kaXY+DQogICAgICAgICAgICA8ZGl2IHN0eWxlPSJ3aWR0aDoxMDAlO21hcmdpbjo2cHgiPjwvZGl2Pg0KICAgICAgICA8L2Rpdj4NCiAgICAgICAgPGRpdiBzdHlsZT0ibWFyZ2luLXJpZ2h0OjE2cHg7bWFyZ2luLWxlZnQ6OHB4Ij4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZzEiIHN0eWxlPSJtYXJnaW46YXV0bzt0ZXh0LWFsaWduOmNlbnRlcjttYXJnaW46M3B4Ij4NCiAgICAgICAgICAgICAgICA8ZGl2IGlkPSJpZF9kaWFsb2dNZXNzYWdlIiBzdHlsZT0icGFkZGluZzoxMHB4Ij48L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nMiIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxicj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+PGlucHV0IGlkPSJkMnVzZXJuYW1lIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiIG9ua2V5dXA9InVwZGF0ZUFjY291bnREaWFsb2coKSI+PGRpdj5Vc2VybmFtZTwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImQycGFzc3dvcmQxIiB0eXBlPSJwYXNzd29yZCIgYXV0b2NvbXBsZXRlPSJvZmYiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgb25rZXl1cD0idXBkYXRlQWNjb3VudERpYWxvZygpIj48ZGl2PlBhc3N3b3JkKjwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImQycGFzc3dvcmQyIiB0eXBlPSJwYXNzd29yZCIgYXV0b2NvbXBsZXRlPSJvZmYiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgb25rZXl1cD0idXBkYXRlQWNjb3VudERpYWxvZygpIj48ZGl2PkNvbmZpcm0gUGFzc3dvcmQ8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IGlkPSJpZF9kMnBlcm1pc3Npb25zIj4NCiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0naGVpZ2h0OjI2cHgnPjxzZWxlY3QgaWQ9ImQycGVybWlzc2lvbiIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4Ij48b3B0aW9uIHZhbHVlPSIwIj5Mb2NhbDxvcHRpb24gdmFsdWU9IjEiPk5ldHdvcms8b3B0aW9uIHZhbHVlPSIyIj5Bbnk8L3NlbGVjdD48ZGl2PlBlcm1pc3Npb248L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPGRpdj5HcmFudGVkIFBlcm1pc3Npb25zPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDx1bCBpZD0iaWRfZDJyZWFsbXMiIHN0eWxlPSJsaXN0LXN0eWxlLXR5cGU6bm9uZTtoZWlnaHQ6MTAwcHg7b3ZlcmZsb3c6YXV0bzt3aWR0aDoxMDAlO2JvcmRlcjogMXB4IHNvbGlkICMwMDA7YmFja2dyb3VuZC1jb2xvcjp3aGl0ZTtvdmVyZmxvdy14OmhpZGRlbjttYXJnaW46MDtwYWRkaW5nOjAiPjwvdWw+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZm9udC1zaXplOjEwcHgiPjxicj4qTWluaW11bSA4IGNoYXJhY3RlcnMgd2l0aCB1cHBlciwgbG93ZXJjYXNlLCAwLTksIGFuZCBvbmUgb2YgIUAjJCVeJmFtcDsqKCkrLTwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2c0IiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGJyPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImQ0dXNlcm5hbWUiIHBsYWNlaG9sZGVyPSJhZG1pbiIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IiBvbmtleXVwPSJsbXNVcGRhdGVMb2dpbkRpYWxvZyhldmVudCwgMSkiPjxkaXY+VXNlcm5hbWU8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+PGlucHV0IGlkPSJkNHBhc3N3b3JkIiB0eXBlPSJwYXNzd29yZCIgYXV0b2NvbXBsZXRlPSJvZmYiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgb25rZXl1cD0ibG1zVXBkYXRlTG9naW5EaWFsb2coZXZlbnQsIDIpIj48ZGl2PlBhc3N3b3JkKjwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImZvbnQtc2l6ZToxMHB4Ij48YnI+Kk1pbmltdW0gOCBjaGFyYWN0ZXJzIHdpdGggdXBwZXIsIGxvd2VyY2FzZSwgMC05LCBhbmQgb25lIG9mICFAIyQlXiZhbXA7KigpKy08L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nNSIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxicj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+DQogICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgaWQ9ImQ1YWN0aW9uU2VsZWN0IiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiPjwvc2VsZWN0Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2PlBvd2VyIEFjdGlvbjwvZGl2Pg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXY+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPldhcm5pbmc6PC9zcGFuPiBTb21lIHBvd2VyIGFjdGlvbnMgbWF5IHJlc3VsdCBpbiBkYXRhIGxvc3MgYW5kIG1heSBkaXNjb25uZWN0IHRoZSBkZXNrdG9wLCB0ZXJtaW5hbCBvciBkaXNrIHJlZGlyZWN0aW9uIHNlc3Npb25zLg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2c2IiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGJyPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImQ2Q29uc2VudFRleHQiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgbWF4bGVuZ3RoPSI2IiBvbmtleXVwPSJjb25zZW50Q2hhbmdlZCgpIiBvbmtleXByZXNzPSJyZXR1cm4gbnVtYmVyc09ubHkoZXZlbnQpIj48ZGl2PkNvbnNlbnQgQ29kZTwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48c2VsZWN0IGlkPSJkNkRpc3BsYXkiIG9uY2hhbmdlPSJjaGFuZ2VDb25zZW50RGlzcGxheSgpIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiPjxvcHRpb24gdmFsdWU9IjAiPlByaW1hcnkgZGlzcGxheTxvcHRpb24gdmFsdWU9IjEiPlNlY29uZGFyeSBkaXNwbGF5PG9wdGlvbiBpZD0iZDZUaGlyZERpc3BsYXkiIHZhbHVlPSIyIiBzdHlsZT0iZGlzcGxheTpub25lIj5UaGlyZCBkaXNwbGF5PC9zZWxlY3Q+PGRpdj5Db25zZW50IERpc3BsYXk8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nOCIgc3R5bGU9ImRpc3BsYXk6dGFibGU7bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0ibWFyZ2luOjNweCAwIDNweCAwO3BhZGRpbmctdG9wOjVweCI+DQogICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD0iaWR4X2Q4dXNlcm5hbWUiIHZhbHVlPSJhZG1pbiIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIyMHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iaGVpZ2h0OjIwcHgiPlVzZXJuYW1lPC9kaXY+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0ibWFyZ2luOjNweCAwIDNweCAwIj4NCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJpZHhfZDhwYXNzd29yZCIgdHlwZT0icGFzc3dvcmQiIGF1dG9jb21wbGV0ZT0ib2ZmIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjIwcHgiPg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJoZWlnaHQ6MjBweCI+UGFzc3dvcmQ8L2Rpdj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nOSIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJjaGVja2JveCIgaWQ9J2lkeF9kOXJlZGlyJz5SZWRpcmVjdGlvbiBQb3J0PGJyPg0KICAgICAgICAgICAgICAgIDxkaXYgaWQ9ImlkeF9kOWt2bV9kaXYiPjxpbnB1dCB0eXBlPSJjaGVja2JveCIgaWQ9J2lkeF9kOWt2bSc+S1ZNIFJlbW90ZSBEZXNrdG9wPGJyPjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJjaGVja2JveCIgaWQ9J2lkeF9kOWlkZXInPklERS1SZWRpcmVjdGlvbjxicj4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iY2hlY2tib3giIGlkPSdpZHhfZDlzb2wnPlNlcmlhbC1vdmVyLUxBTjxicj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nMTAiIHN0eWxlPSJtYXJnaW46YXV0bzttYXJnaW46M3B4Ij4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0icmFkaW8iIG5hbWU9ImQxMCIgaWQ9J2lkeF9kMTBub25lJyB2YWx1ZT0iMCI+Tm90IFJlcXVpcmVkPGJyPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJyYWRpbyIgbmFtZT0iZDEwIiBpZD0naWR4X2QxMGt2bScgdmFsdWU9IjEiPlJlcXVpcmVkIGZvciBLVk0gb25seTxicj4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0icmFkaW8iIG5hbWU9ImQxMCIgaWQ9J2lkeF9kMTBhbGwnIHZhbHVlPSI0Mjk0OTY3Mjk1Ij5BbHdheXMgUmVxdWlyZWQ8YnI+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZzExIiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGRpdiBpZD0iaWRfZGlhbG9nT3B0aW9ucyI+PC9kaXY+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZzEyIiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGJyPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImlkeF9kMTJuYW1lIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiIG1heGxlbmd0aD0iMzIiIG9ua2V5dXA9InVwZGF0ZVdpZmlEaWFsb2coKSIgdGl0bGU9Ik1heGltdW0gMzIgY2hhcmFjdGVycyI+PGRpdiB0aXRsZT0iTWF4aW11bSAzMiBjaGFyYWN0ZXJzIj5Qcm9maWxlIE5hbWU8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+PGlucHV0IGlkPSJpZHhfZDEyc3NpZCIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IiBtYXhsZW5ndGg9IjMyIiBvbmtleXVwPSJ1cGRhdGVXaWZpRGlhbG9nKCkiIHRpdGxlPSJNYXhpbXVtIDMyIGNoYXJhY3RlcnMiPjxkaXYgdGl0bGU9Ik1heGltdW0gMzIgY2hhcmFjdGVycyI+U1NJRDwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz4NCiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBpZD0iaWR4X2QxMnByaSIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IiBvbmNsaWNrPSJ1cGRhdGVXaWZpRGlhbG9nKCkiPjwvc2VsZWN0Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2PlByaW9yaXR5PC9kaXY+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0naGVpZ2h0OjI2cHgnPg0KICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGlkPSJpZHhfZDEyYXV0aCIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IiBvbmNsaWNrPSJ1cGRhdGVXaWZpRGlhbG9nKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPCEtLTxvcHRpb24gdmFsdWU9IjciPldQQTIgSUVFRSA4MDIuMXg8L29wdGlvbj4tLT4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjYiPldQQTIgUFNLDQogICAgICAgICAgICAgICAgICAgICAgICA8IS0tPG9wdGlvbiB2YWx1ZT0iNSI+V1BBIElFRUUgODAyLjF4PC9vcHRpb24+LS0+DQogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSI0Ij5XUEEgUFNLDQogICAgICAgICAgICAgICAgICAgICAgICA8IS0tPG9wdGlvbiB2YWx1ZT0iMyI+U2hhcmVkIEtleTwvb3B0aW9uPi0tPg0KICAgICAgICAgICAgICAgICAgICAgICAgPCEtLTxvcHRpb24gdmFsdWU9IjIiPk9wZW48L29wdGlvbj4tLT4NCiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgICAgIDxkaXY+QXV0aGVudGljYXRpb248L2Rpdj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+DQogICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgaWQ9ImlkeF9kMTJlbmMiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgb25jbGljaz0idXBkYXRlV2lmaURpYWxvZygpIj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gaWQ9ImlkX2QxMmU0IiB2YWx1ZT0iNCI+Q0NNUC1BRVMNCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gaWQ9ImlkX2QxMmUzIiB2YWx1ZT0iMyI+VEtJUC1SQzQNCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gaWQ9ImlkX2QxMmUyIiB2YWx1ZT0iMiI+V0VQDQogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIGlkPSJpZF9kMTJlNSIgdmFsdWU9IjUiPk5vbmUNCiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgICAgIDxkaXY+RW5jcnlwdGlvbjwvZGl2Pg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImlkeF9kMTJwYXNzd29yZDEiIHR5cGU9InBhc3N3b3JkIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiIG1heGxlbmd0aD0iNjMiIG9ua2V5dXA9InVwZGF0ZVdpZmlEaWFsb2coKSIgdGl0bGU9Ikxlbmd0aCBiZXR3ZWVuIDggYW5kIDYzIGNoYXJhY3RlcnMiPjxkaXYgdGl0bGU9Ikxlbmd0aCBiZXR3ZWVuIDggYW5kIDYzIGNoYXJhY3RlcnMiPlBhc3N3b3JkKjwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImlkeF9kMTJwYXNzd29yZDIiIHR5cGU9InBhc3N3b3JkIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiIG1heGxlbmd0aD0iNjMiIG9ua2V5dXA9InVwZGF0ZVdpZmlEaWFsb2coKSIgdGl0bGU9Ikxlbmd0aCBiZXR3ZWVuIDggYW5kIDYzIGNoYXJhY3RlcnMiPjxkaXYgdGl0bGU9Ikxlbmd0aCBiZXR3ZWVuIDggYW5kIDYzIGNoYXJhY3RlcnMiPkNvbmZpcm0gUGFzc3dvcmQ8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nMTMiIHN0eWxlPSJtYXJnaW46YXV0bzttYXJnaW46M3B4Ij4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iY2hlY2tib3giIGlkPSdkMTN2YWxpZCc+VmFsaWQgUmVjb3JkPGJyPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJjaGVja2JveCIgaWQ9J2QxM3NjcmFtYmxlJz5TY3JhbWJsZWQgUmVjb3JkPGJyPg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2cxNCIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz4NCiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBpZD0iaWR4X2QxNHZlcnNpb24iIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCI+DQogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSIxIj5WZXJzaW9uIDENCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjIiPlZlcnNpb24gMg0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMyI+VmVyc2lvbiAzDQogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSI0Ij5WZXJzaW9uIDQNCiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgICAgIDxkaXY+U2V0dXAuYmluIHZlcnNpb248L2Rpdj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+DQogICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgaWQ9ImlkeF9kMTRjb25zdW1lIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMSI+UmVjb3JkcyB3aWxsIG5vdCBiZSBjb25zdW1lZA0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMCI+UmVjb3JkcyB3aWxsIGJlIGNvbnN1bWVkDQogICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2PlJlY29yZCBjb25zdW1wdGlvbjwvZGl2Pg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2cxNSIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxpbnB1dCBpZD0iZDE1c2V0dXBiaW5maWxlIiB0eXBlPSJmaWxlIiBzdHlsZT0id2lkdGg6MTAwJSIgYWNjZXB0PSIuYmluIj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nMTYiIHN0eWxlPSJtYXJnaW46YXV0bzttYXJnaW46M3B4Ij4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+DQogICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgaWQ9ImQxNnR5cGUiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyNjBweCIgb25jaGFuZ2U9InVzYl9vbmQxNnR5cGVjaGFuZ2UoKSIgb25jbGljaz0idXNiX29uZDE2dHlwZWNoYW5nZSgpIiBvbnNjcm9sbD0idXNiX29uZDE2dHlwZWNoYW5nZSgpIiBvbmtleWRvd249InVzYl9vbmQxNnR5cGVjaGFuZ2UoKSI+PC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgICAgIDxkaXY+VmFyaWFibGUgVHlwZTwvZGl2Pg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgaWQ9ImQxNmdlbmVyaWN2YWx1ZSIgc3R5bGU9J2hlaWdodDoyNnB4Jz4NCiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBpZD0iaWR4X2QxNnZhbHVlMSIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4Ij48L3NlbGVjdD4NCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJpZHhfZDE2dmFsdWUyIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHg7ZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGRpdj5WYXJpYWJsZSBWYWx1ZTwvZGl2Pg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgaWQ9ImQxNmN1c3RvbXZhbHVlIj48L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nMTkiIHN0eWxlPSJtYXJnaW46YXV0bzttYXJnaW46M3B4Ij4NCiAgICAgICAgICAgICAgICBUaGlzIHdpbGwgc2F2ZSB0aGUgZW50aXJlIHN0YXRlIG9mIEludGVsJnJlZzsgQU1UIGZvciB0aGlzIG1hY2hpbmUgaW50byBmaWxlLiBQYXNzd29yZHMgd2lsbCBub3QgYmUgc2F2ZWQsIGJ1dCBzb21lIHNlbnNpdGl2ZSBkYXRhIG1heSBiZSBpbmNsdWRlZC48YnI+PGJyPg0KICAgICAgICAgICAgICAgIDxpbnB1dCBpZD0iaWR4X2QxOXNhdmVzdGF0ZWZpbGVuYW1lIiBzdHlsZT0id2lkdGg6MTAwJSIgdmFsdWU9ImFtdHN0YXRlLmpzb24iPg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2cyMCIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJyYWRpbyIgbmFtZT0iZDIwIiBpZD0iZDIwYSIgdmFsdWU9IjAiPkRpc2FibGVkPGJyPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJyYWRpbyIgbmFtZT0iZDIwIiBpZD0iZDIwYiIgdmFsdWU9IjEiPklDTVAgcmVzcG9uc2U8YnI+DQogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSJkMjAiIGlkPSJkMjBjIiB2YWx1ZT0iMiI+Uk1DUCByZXNwb25zZTxicj4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0icmFkaW8iIG5hbWU9ImQyMCIgaWQ9ImQyMGQiIHZhbHVlPSIzIj5JQ01QICYgUk1DUCByZXNwb25zZTxicj48YnI+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZzIxIiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSJkMjEiIGlkPSJkMjFvMCIgb25jbGljaz0idXBkYXRlSVBTZXR1cERsZygpIj48c3BhbiBpZD0iZDIxbDAiPjwvc3Bhbj48YnI+DQogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSJkMjEiIGlkPSJkMjFvMSIgb25jbGljaz0idXBkYXRlSVBTZXR1cERsZygpIj48c3BhbiBpZD0iZDIxbDEiPjwvc3Bhbj48YnI+DQogICAgICAgICAgICAgICAgPGRpdiBpZD0iaWRfZDIxbWFudWFsZGl2Ij4NCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSJkMjEiIGlkPSdkMjFvMicgb25jbGljaz0idXBkYXRlSVBTZXR1cERsZygpIj48c3BhbiBpZD0iZDIxbDIiPjwvc3Bhbj48YnI+PGJyPg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJtYXJnaW4tbGVmdDoyMHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4Ij48aW5wdXQgaWQ9ImlkeF9kMjFhZGRyZXNzIiBvbmtleXVwPSJ1cGRhdGVJUFNldHVwRGxnKCkiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMzBweCI+PGRpdj5JUCBhZGRyZXNzPC9kaXY+PC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJoZWlnaHQ6MjZweCIgaWQ9ImlkX2QyMXN1Ym5ldGRpdiI+PGlucHV0IGlkPSJpZHhfZDIxc3VibmV0IiBvbmtleXVwPSJ1cGRhdGVJUFNldHVwRGxnKCkiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMzBweCI+PGRpdj5TdWJuZXQgbWFyazwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iaGVpZ2h0OjI2cHgiPjxpbnB1dCBpZD0iaWR4X2QyMWdhdGV3YXkiIG9ua2V5dXA9InVwZGF0ZUlQU2V0dXBEbGcoKSIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIzMHB4Ij48ZGl2PkdhdGV3YXk8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4Ij48aW5wdXQgaWQ9ImlkeF9kMjFkbnMxIiBvbmtleXVwPSJ1cGRhdGVJUFNldHVwRGxnKCkiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMzBweCI+PGRpdj5QcmltYXJ5IEROUzwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iaGVpZ2h0OjI2cHgiPjxpbnB1dCBpZD0iaWR4X2QyMWRuczIiIG9ua2V5dXA9InVwZGF0ZUlQU2V0dXBEbGcoKSIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIzMHB4Ij48ZGl2PkFsdGVybmF0ZSBETlM8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZzIzIiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGJyPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz4NCiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBpZD0iaWR4X2QyM2RkbnMiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgb25jaGFuZ2U9InNob3dFZGl0RG5zRGxnQ2hhbmdlKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMCI+RGlzYWJsZWQNCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjEiPkRpc2FibGVkLCBESENQIHVwZGF0ZQ0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMiI+RW5hYmxlZA0KICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD4NCiAgICAgICAgICAgICAgICAgICAgPGRpdj5EeW5hbWljIEROUyBjbGllbnQ8L2Rpdj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+PGlucHV0IGlkPSJpZHhfZDIzaW50ZXJ2YWwiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCI+PGRpdj5VcGRhdGUgSW50ZXJ2YWwgKG1pbnV0ZXMpPC9kaXY+PC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0naGVpZ2h0OjI2cHgnPjxpbnB1dCBpZD0iaWR4X2QyM3R0bCIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4Ij48ZGl2PlRUTCAoc2Vjb25kcyk8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJmb250LXNpemU6MTBweCI+PGJyPkRlZmF1dCBJbnRlcnZhbCBpcyAxNDQwIG1pbnV0ZXMsIERlZmF1bHQgVFRMIGlzIDkwMCBzZWNvbmRzLjwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2cyNSIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9InRleHQtYWxpZ246bGVmdCI+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4Ij48aW5wdXQgaWQ9ImQyNWFsYXJtX25hbWUiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoxODBweCIgbWF4bGVuZ3RoPSIzMiIgb25rZXl1cD0iYWxlcnREaWFsb2dVcGRhdGUoKSI+PGRpdiBzdHlsZT0icGFkZGluZy10b3A6NHB4Ij5BbGFybSBuYW1lPC9kaXY+PC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9ImQyNWFsYXJtX3NkYXRlIiBzdHlsZT0id2lkdGg6MTgwcHgiIG1heGxlbmd0aD0iMTAiIG9ua2V5dXA9ImFsZXJ0RGlhbG9nVXBkYXRlKCkiIG9ua2V5cHJlc3M9InJldHVybiBudW1iZXJzT25seShldmVudCw0NSkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJwYWRkaW5nLXRvcDo0cHgiPldha2UgZGF0ZSAoeWVhci1tb250aC1kYXkpPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJoZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweCI+DQogICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJmbG9hdDpyaWdodCI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJkMjVhbGFybV9zdGltZSIgc3R5bGU9IndpZHRoOjE4MHB4IiBtYXhsZW5ndGg9IjEwIiBvbmtleXVwPSJhbGVydERpYWxvZ1VwZGF0ZSgpIiBvbmtleXByZXNzPSJyZXR1cm4gbnVtYmVyc09ubHkoZXZlbnQsNTgpIj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0icGFkZGluZy10b3A6NHB4Ij5XYWtlIHRpbWUgKGhvdXI6bWluOnNlYyk8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9ImQyNWFsYXJtX2ludGVydmFsIiBzdHlsZT0id2lkdGg6MTgwcHgiIG1heGxlbmd0aD0iMTAiIG9ua2V5dXA9ImFsZXJ0RGlhbG9nVXBkYXRlKCkiIG9ua2V5cHJlc3M9InJldHVybiBudW1iZXJzT25seShldmVudCw0NSkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJwYWRkaW5nLXRvcDo0cHgiPkludGVydmFsIChkYXlzLWhvdXJzLW1pbik8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjE4MHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGlkPSJkMjVhbGFybV9kb2MiIHN0eWxlPSJ3aWR0aDoxMDAlIiBvbmNoYW5nZT0ic2hvd0FkdlBvd2VyRGxnQ2hhbmdlKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSIwIj5LZWVwIGFsYXJtDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjEiPkRlbGV0ZSBvbiBjb21wbGV0aW9uDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9InBhZGRpbmctdG9wOjRweCI+QWZ0ZXIgd2FrZTwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgPGRpdiBzdHlsZT0icGFkZGluZzoxMHB4O21hcmdpbi1ib3R0b206NHB4Ij4NCiAgICAgICAgICAgIDxpbnB1dCBpZD0iaWR4X2RsZ0NhbmNlbEJ1dHRvbiIgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iQ2FuY2VsIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6ODBweDttYXJnaW4tbGVmdDo1cHgiIG9uY2xpY2s9ImRpYWxvZ2Nsb3NlKDApIj4NCiAgICAgICAgICAgIDxpbnB1dCBpZD0iaWR4X2RsZ09rQnV0dG9uIiB0eXBlPSJidXR0b24iIHZhbHVlPSJPSyIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjgwcHgiIG9uY2xpY2s9ImRpYWxvZ2Nsb3NlKDEpIj4NCiAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNXB4Ij48aW5wdXQgaWQ9ImlkeF9kbGdEZWxldGVCdXR0b24iIHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkRlbGV0ZSIgc3R5bGU9IndpZHRoOjgwcHg7ZGlzcGxheTpub25lIiBvbmNsaWNrPSJkaWFsb2djbG9zZSgyKSI+PC9kaXY+DQogICAgICAgIDwvZGl2Pg0KICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICANCjwvYm9keT4NCjwvaHRtbD4NCjxzY3JpcHQ+LyoqIA0KKiBAZGVzY3JpcHRpb24gU2V0IG9mIHNob3J0IGNvbW1vbmx5IHVzZWQgbWV0aG9kcyBmb3IgaGFuZGxpbmcgSFRNTCBlbGVtZW50cw0KKiBAYXV0aG9yIFlsaWFuIFNhaW50LUhpbGFpcmUNCiogQHZlcnNpb24gdjAuMC4xYg0KKi8NCg0KLy8gQWRkIHN0YXJ0c1dpdGggZm9yIElFIGJyb3dzZXINCmlmICghU3RyaW5nLnByb3RvdHlwZS5zdGFydHNXaXRoKSB7IFN0cmluZy5wcm90b3R5cGUuc3RhcnRzV2l0aCA9IGZ1bmN0aW9uIChzdHIpIHsgcmV0dXJuIHRoaXMubGFzdEluZGV4T2Yoc3RyLCAwKSA9PT0gMDsgfTsgfQ0KaWYgKCFTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoKSB7IFN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGggPSBmdW5jdGlvbiAoc3RyKSB7IHJldHVybiB0aGlzLmluZGV4T2Yoc3RyLCB0aGlzLmxlbmd0aCAtIHN0ci5sZW5ndGgpICE9PSAtMTsgfTsgfQ0KDQovLyBRdWljayBVSSBmdW5jdGlvbnMsIGEgYml0IG9mIGEgcmVwbGFjZW1lbnQgZm9yIGpRdWVyeQ0KLy9mdW5jdGlvbiBRKHgpIHsgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHgpID09IG51bGwpIHsgY29uc29sZS5sb2coJ0ludmFsaWQgZWxlbWVudDogJyArIHgpOyB9IHJldHVybiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh4KTsgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAiUSINCmZ1bmN0aW9uIFEoeCkgeyByZXR1cm4gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoeCk7IH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIlEiDQpmdW5jdGlvbiBRUyh4KSB7IHRyeSB7IHJldHVybiBRKHgpLnN0eWxlOyB9IGNhdGNoICh4KSB7IH0gfSAgICAgICAgICAgICAgICAgICAgIC8vICJRIiBzdHlsZQ0KZnVuY3Rpb24gUUUoeCwgeSkgeyB0cnkgeyBRKHgpLmRpc2FibGVkID0gIXk7IH0gY2F0Y2ggKHgpIHsgfSB9ICAgICAgICAgICAgICAgICAvLyAiUSIgZW5hYmxlDQpmdW5jdGlvbiBRVih4LCB5KSB7IHRyeSB7IFFTKHgpLmRpc3BsYXkgPSAoeSA/ICcnIDogJ25vbmUnKTsgfSBjYXRjaCAoeCkgeyB9IH0gIC8vICJRIiB2aXNpYmxlDQpmdW5jdGlvbiBRQSh4LCB5KSB7IFEoeCkuaW5uZXJIVE1MICs9IHk7IH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICJRIiBhcHBlbmQNCmZ1bmN0aW9uIFFIKHgsIHkpIHsgUSh4KS5pbm5lckhUTUwgPSB5OyB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIlEiIGh0bWwNCg0KLy8gTW92ZSBjdXJzb3IgdG8gZW5kIG9mIGlucHV0IGJveA0KZnVuY3Rpb24gaW5wdXRCb3hGb2N1cyh4KSB7IFEoeCkuZm9jdXMoKTsgdmFyIHYgPSBRKHgpLnZhbHVlOyBRKHgpLnZhbHVlID0gJyc7IFEoeCkudmFsdWUgPSB2OyB9DQoNCi8vIEJpbmFyeSBlbmNvZGluZyBhbmQgZGVjb2RpbmcgZnVuY3Rpb25zDQpmdW5jdGlvbiBSZWFkU2hvcnQodiwgcCkgeyByZXR1cm4gKHYuY2hhckNvZGVBdChwKSA8PCA4KSArIHYuY2hhckNvZGVBdChwICsgMSk7IH0NCmZ1bmN0aW9uIFJlYWRTaG9ydFgodiwgcCkgeyByZXR1cm4gKHYuY2hhckNvZGVBdChwICsgMSkgPDwgOCkgKyB2LmNoYXJDb2RlQXQocCk7IH0NCmZ1bmN0aW9uIFJlYWRJbnQodiwgcCkgeyByZXR1cm4gKHYuY2hhckNvZGVBdChwKSAqIDB4MTAwMDAwMCkgKyAodi5jaGFyQ29kZUF0KHAgKyAxKSA8PCAxNikgKyAodi5jaGFyQ29kZUF0KHAgKyAyKSA8PCA4KSArIHYuY2hhckNvZGVBdChwICsgMyk7IH0gLy8gV2UgdXNlICIqMHgxMDAwMDAwIiBpbnN0ZWFkIG9mICI8PDI0IiBiZWNhdXNlIHRoZSBzaGlmdCBjb252ZXJ0cyB0aGUgbnVtYmVyIHRvIHNpZ25lZCBpbnQzMi4NCmZ1bmN0aW9uIFJlYWRTSW50KHYsIHApIHsgcmV0dXJuICh2LmNoYXJDb2RlQXQocCkgPDwgMjQpICsgKHYuY2hhckNvZGVBdChwICsgMSkgPDwgMTYpICsgKHYuY2hhckNvZGVBdChwICsgMikgPDwgOCkgKyB2LmNoYXJDb2RlQXQocCArIDMpOyB9DQpmdW5jdGlvbiBSZWFkSW50WCh2LCBwKSB7IHJldHVybiAodi5jaGFyQ29kZUF0KHAgKyAzKSAqIDB4MTAwMDAwMCkgKyAodi5jaGFyQ29kZUF0KHAgKyAyKSA8PCAxNikgKyAodi5jaGFyQ29kZUF0KHAgKyAxKSA8PCA4KSArIHYuY2hhckNvZGVBdChwKTsgfQ0KZnVuY3Rpb24gU2hvcnRUb1N0cih2KSB7IHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKCh2ID4+IDgpICYgMHhGRiwgdiAmIDB4RkYpOyB9DQpmdW5jdGlvbiBTaG9ydFRvU3RyWCh2KSB7IHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKHYgJiAweEZGLCAodiA+PiA4KSAmIDB4RkYpOyB9DQpmdW5jdGlvbiBJbnRUb1N0cih2KSB7IHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKCh2ID4+IDI0KSAmIDB4RkYsICh2ID4+IDE2KSAmIDB4RkYsICh2ID4+IDgpICYgMHhGRiwgdiAmIDB4RkYpOyB9DQpmdW5jdGlvbiBJbnRUb1N0clgodikgeyByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSh2ICYgMHhGRiwgKHYgPj4gOCkgJiAweEZGLCAodiA+PiAxNikgJiAweEZGLCAodiA+PiAyNCkgJiAweEZGKTsgfQ0KZnVuY3Rpb24gTWFrZVRvQXJyYXkodikgeyBpZiAoIXYgfHwgdiA9PSBudWxsIHx8IHR5cGVvZiB2ID09ICdvYmplY3QnKSByZXR1cm4gdjsgcmV0dXJuIFt2XTsgfQ0KZnVuY3Rpb24gU3BsaXRBcnJheSh2KSB7IHJldHVybiB2LnNwbGl0KCcsJyk7IH0NCmZ1bmN0aW9uIENsb25lKHYpIHsgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodikpOyB9DQpmdW5jdGlvbiBFc2NhcGVIdG1sKHgpIHsgaWYgKHR5cGVvZiB4ID09ICJzdHJpbmciKSByZXR1cm4geC5yZXBsYWNlKC8mL2csICcmYW1wOycpLnJlcGxhY2UoLz4vZywgJyZndDsnKS5yZXBsYWNlKC88L2csICcmbHQ7JykucmVwbGFjZSgvIi9nLCAnJnF1b3Q7JykucmVwbGFjZSgvJy9nLCAnJmFwb3M7Jyk7IGlmICh0eXBlb2YgeCA9PSAiYm9vbGVhbiIpIHJldHVybiB4OyBpZiAodHlwZW9mIHggPT0gIm51bWJlciIpIHJldHVybiB4OyB9DQoNCi8vIE1vdmUgYW4gZWxlbWVudCBmcm9tIG9uZSBwb3NpdGlvbiBpbiBhbiBhcnJheSB0byBhIG5ldyBwb3NpdGlvbg0KZnVuY3Rpb24gQXJyYXlFbGVtZW50TW92ZShhcnIsIGZyb20sIHRvKSB7IGFyci5zcGxpY2UodG8sIDAsIGFyci5zcGxpY2UoZnJvbSwgMSlbMF0pOyB9Ow0KDQovLyBQcmludCBvYmplY3QgZm9yIEhUTUwNCmZ1bmN0aW9uIE9iamVjdFRvU3RyaW5nRXgoeCwgYykgew0KICAgIHZhciByID0gIiI7DQogICAgaWYgKHggIT0gMCAmJiAoIXggfHwgeCA9PSBudWxsKSkgcmV0dXJuICIoTnVsbCkiOw0KICAgIGlmICh4IGluc3RhbmNlb2YgQXJyYXkpIHsgZm9yICh2YXIgaSBpbiB4KSB7IHIgKz0gJzxiciAvPicgKyBnYXAoYykgKyAiSXRlbSAjIiArIGkgKyAiOiAiICsgT2JqZWN0VG9TdHJpbmdFeCh4W2ldLCBjICsgMSk7IH0gfQ0KICAgIGVsc2UgaWYgKHggaW5zdGFuY2VvZiBPYmplY3QpIHsgZm9yICh2YXIgaSBpbiB4KSB7IHIgKz0gJzxiciAvPicgKyBnYXAoYykgKyBpICsgIiA9ICIgKyBPYmplY3RUb1N0cmluZ0V4KHhbaV0sIGMgKyAxKTsgfSB9DQogICAgZWxzZSB7IHIgKz0gRXNjYXBlSHRtbCh4KTsgfQ0KICAgIHJldHVybiByOw0KfQ0KDQovLyBQcmludCBvYmplY3QgZm9yIGNvbnNvbGUNCmZ1bmN0aW9uIE9iamVjdFRvU3RyaW5nRXgyKHgsIGMpIHsNCiAgICB2YXIgciA9ICIiOw0KICAgIGlmICh4ICE9IDAgJiYgKCF4IHx8IHggPT0gbnVsbCkpIHJldHVybiAiKE51bGwpIjsNCiAgICBpZiAoeCBpbnN0YW5jZW9mIEFycmF5KSB7IGZvciAodmFyIGkgaW4geCkgeyByICs9ICdcclxuJyArIGdhcDIoYykgKyAiSXRlbSAjIiArIGkgKyAiOiAiICsgT2JqZWN0VG9TdHJpbmdFeDIoeFtpXSwgYyArIDEpOyB9IH0NCiAgICBlbHNlIGlmICh4IGluc3RhbmNlb2YgT2JqZWN0KSB7IGZvciAodmFyIGkgaW4geCkgeyByICs9ICdcclxuJyArIGdhcDIoYykgKyBpICsgIiA9ICIgKyBPYmplY3RUb1N0cmluZ0V4Mih4W2ldLCBjICsgMSk7IH0gfQ0KICAgIGVsc2UgeyByICs9IEVzY2FwZUh0bWwoeCk7IH0NCiAgICByZXR1cm4gcjsNCn0NCg0KLy8gQ3JlYXRlIGFuIGlkZW50IGdhcA0KZnVuY3Rpb24gZ2FwKGMpIHsgdmFyIHggPSAnJzsgZm9yICh2YXIgaSA9IDA7IGkgPCAoYyAqIDQpIDsgaSsrKSB7IHggKz0gJyZuYnNwOyc7IH0gcmV0dXJuIHg7IH0NCmZ1bmN0aW9uIGdhcDIoYykgeyB2YXIgeCA9ICcnOyBmb3IgKHZhciBpID0gMDsgaSA8IChjICogNCkgOyBpKyspIHsgeCArPSAnICc7IH0gcmV0dXJuIHg7IH0NCg0KLy8gUHJpbnQgYW4gb2JqZWN0IGluIGh0bWwNCmZ1bmN0aW9uIE9iamVjdFRvU3RyaW5nKHgpIHsgcmV0dXJuIE9iamVjdFRvU3RyaW5nRXgoeCwgMCk7IH0NCmZ1bmN0aW9uIE9iamVjdFRvU3RyaW5nMih4KSB7IHJldHVybiBPYmplY3RUb1N0cmluZ0V4Mih4LCAwKTsgfQ0KDQovLyBDb252ZXJ0IGEgaGV4IHN0cmluZyB0byBhIHJhdyBzdHJpbmcNCmZ1bmN0aW9uIGhleDJyc3RyKGQpIHsNCiAgICBpZiAodHlwZW9mIGQgIT0gInN0cmluZyIgfHwgZC5sZW5ndGggPT0gMCkgcmV0dXJuICcnOw0KICAgIHZhciByID0gJycsIG0gPSAoJycgKyBkKS5tYXRjaCgvLi4vZyksIHQ7DQogICAgd2hpbGUgKHQgPSBtLnNoaWZ0KCkpIHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgnMHgnICsgdCk7DQogICAgcmV0dXJuIHINCn0NCg0KLy8gQ29udmVydCBkZWNpbWFsIHRvIGhleA0KZnVuY3Rpb24gY2hhcjJoZXgoaSkgeyByZXR1cm4gKGkgKyAweDEwMCkudG9TdHJpbmcoMTYpLnN1YnN0cigtMikudG9VcHBlckNhc2UoKTsgfQ0KDQovLyBDb252ZXJ0IGEgcmF3IHN0cmluZyB0byBhIGhleCBzdHJpbmcNCmZ1bmN0aW9uIHJzdHIyaGV4KGlucHV0KSB7DQogICAgdmFyIHIgPSAnJywgaTsNCiAgICBmb3IgKGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspIHsgciArPSBjaGFyMmhleChpbnB1dC5jaGFyQ29kZUF0KGkpKTsgfQ0KICAgIHJldHVybiByOw0KfQ0KDQovLyBVVEYtOCBlbmNvZGluZyAmIGRlY29kaW5nIGZ1bmN0aW9ucw0KZnVuY3Rpb24gZW5jb2RlX3V0ZjgocykgeyByZXR1cm4gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KHMpKTsgfQ0KZnVuY3Rpb24gZGVjb2RlX3V0ZjgocykgeyByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZShzKSk7IH0NCg0KLy8gQ29udmVydCBhIHN0cmluZyBpbnRvIGEgYmxvYg0KZnVuY3Rpb24gZGF0YTJibG9iKGRhdGEpIHsNCiAgICB2YXIgYnl0ZXMgPSBuZXcgQXJyYXkoZGF0YS5sZW5ndGgpOw0KICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykgYnl0ZXNbaV0gPSBkYXRhLmNoYXJDb2RlQXQoaSk7DQogICAgdmFyIGJsb2IgPSBuZXcgQmxvYihbbmV3IFVpbnQ4QXJyYXkoYnl0ZXMpXSk7DQogICAgcmV0dXJuIGJsb2I7DQp9DQoNCi8vIEdlbmVyYXRlIHJhbmRvbSBudW1iZXJzDQpmdW5jdGlvbiByYW5kb20obWF4KSB7IHJldHVybiBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBtYXgpOyB9DQoNCi8vIFRyYWRlbWFya3MNCmZ1bmN0aW9uIHRyYWRlbWFya3MoeCkgeyByZXR1cm4geC5yZXBsYWNlKC9cKFJcKS9nLCAnJnJlZzsnKS5yZXBsYWNlKC9cKFRNXCkvZywgJyZ0cmFkZTsnKTsgfQ0KDQoNCi8qKiANCiogQGRlc2NyaXB0aW9uIEludGVsIEFNVCBMTVMgY29udHJvbCBtb2R1bGUgLSB1c2luZyB3ZWJzb2NrZXQNCiogQGF1dGhvciBZbGlhbiBTYWludC1IaWxhaXJlDQoqIEB2ZXJzaW9uIHYwLjAuMQ0KKi8NCg0KLy8gQ29uc3RydWN0IGEgTE1TIGNvbnRyb2wgb2JqZWN0DQp2YXIgQ3JlYXRlTG1zQ29udHJvbCA9IGZ1bmN0aW9uICgpIHsNCiAgICB2YXIgb2JqID0ge307DQogICAgdmFyIHNvY2tldCA9IG51bGw7DQogICAgb2JqLlN0YXRlID0gMDsNCiAgICBvYmoub25TdGF0ZUNoYW5nZWQgPSBudWxsOw0KICAgIG9iai5vbkRhdGEgPSBudWxsOw0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICBvYmouU3RhcnQgPSBmdW5jdGlvbiAoKSB7DQogICAgICAgIHNvY2tldCA9IG5ldyBXZWJTb2NrZXQod2luZG93LmxvY2F0aW9uLnByb3RvY29sLnJlcGxhY2UoImh0dHAiLCAid3MiKSArICIvLyIgKyB3aW5kb3cubG9jYXRpb24uaG9zdCArICIvbG1zLmFzaHgiKTsNCiAgICAgICAgc29ja2V0Lm9ub3BlbiA9IF9PblNvY2tldENvbm5lY3RlZDsNCiAgICAgICAgc29ja2V0Lm9ubWVzc2FnZSA9IF9Pbk1lc3NhZ2U7DQogICAgICAgIHNvY2tldC5vbmNsb3NlID0gb2JqLlN0b3A7DQogICAgICAgIF9TdGF0ZUNoYW5nZSgxKTsNCiAgICB9DQoNCiAgICBmdW5jdGlvbiBfT25Tb2NrZXRDb25uZWN0ZWQoKSB7DQogICAgICAgIF9TdGF0ZUNoYW5nZSgyKTsNCiAgICB9DQoNCiAgICAvLyBTZXR1cCB0aGUgZmlsZSByZWFkZXINCiAgICB2YXIgZmlsZVJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7DQogICAgdmFyIGZpbGVSZWFkZXJJbnVzZSA9IGZhbHNlLCBmaWxlUmVhZGVyQWNjID0gW107DQogICAgaWYgKGZpbGVSZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKSB7DQogICAgICAgIC8vIENocm9tZSAmIEZpcmVmb3ggKERyYWZ0KQ0KICAgICAgICBmaWxlUmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uIChlKSB7IF9PblNvY2tldERhdGEoZS50YXJnZXQucmVzdWx0KTsgaWYgKGZpbGVSZWFkZXJBY2MubGVuZ3RoID09IDApIHsgZmlsZVJlYWRlckludXNlID0gZmFsc2U7IH0gZWxzZSB7IGZpbGVSZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKG5ldyBCbG9iKFtmaWxlUmVhZGVyQWNjLnNoaWZ0KCldKSk7IH0gfQ0KICAgIH0gZWxzZSBpZiAoZmlsZVJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcikgew0KICAgICAgICAvLyBDaHJvbWUgJiBGaXJlZm94IChTcGVjKQ0KICAgICAgICBmaWxlUmVhZGVyLm9ubG9hZGVuZCA9IGZ1bmN0aW9uIChlKSB7IF9PblNvY2tldERhdGEoZS50YXJnZXQucmVzdWx0KTsgaWYgKGZpbGVSZWFkZXJBY2MubGVuZ3RoID09IDApIHsgZmlsZVJlYWRlckludXNlID0gZmFsc2U7IH0gZWxzZSB7IGZpbGVSZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoZmlsZVJlYWRlckFjYy5zaGlmdCgpKTsgfSB9DQogICAgfQ0KDQogICAgZnVuY3Rpb24gX09uTWVzc2FnZShlKSB7DQogICAgICAgIGlmICh0eXBlb2YgZS5kYXRhID09ICdvYmplY3QnKSB7DQogICAgICAgICAgICBpZiAoZmlsZVJlYWRlckludXNlID09IHRydWUpIHsgZmlsZVJlYWRlckFjYy5wdXNoKGUuZGF0YSk7IHJldHVybjsgfQ0KICAgICAgICAgICAgaWYgKGZpbGVSZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKSB7DQogICAgICAgICAgICAgICAgLy8gQ2hyb21lICYgRmlyZWZveCAoRHJhZnQpDQogICAgICAgICAgICAgICAgZmlsZVJlYWRlckludXNlID0gdHJ1ZTsNCiAgICAgICAgICAgICAgICBmaWxlUmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyhuZXcgQmxvYihbZS5kYXRhXSkpOw0KICAgICAgICAgICAgfSBlbHNlIGlmIChmaWxlUmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKSB7DQogICAgICAgICAgICAgICAgLy8gQ2hyb21lICYgRmlyZWZveCAoU3BlYykNCiAgICAgICAgICAgICAgICBmaWxlUmVhZGVySW51c2UgPSB0cnVlOw0KICAgICAgICAgICAgICAgIGZpbGVSZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoZS5kYXRhKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gSUUxMCwgcmVhZEFzQmluYXJ5U3RyaW5nIGRvZXMgbm90IGV4aXN0LCB1c2UgYW4gYWx0ZXJuYXRpdmUuDQogICAgICAgICAgICAgICAgdmFyIGJpbmFyeSA9ICIiLCBieXRlcyA9IG5ldyBVaW50OEFycmF5KGUuZGF0YSksIGxlbmd0aCA9IGJ5dGVzLmJ5dGVMZW5ndGg7DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeyBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7IH0NCiAgICAgICAgICAgICAgICBfT25Tb2NrZXREYXRhKGJpbmFyeSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBfT25Tb2NrZXREYXRhKGUuZGF0YSk7DQogICAgICAgIH0NCiAgICB9Ow0KICAgDQogICAgZnVuY3Rpb24gX09uU29ja2V0RGF0YShkYXRhKSB7DQogICAgICAgIGlmICghZGF0YSkgcmV0dXJuOw0KDQogICAgICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcpIHsNCiAgICAgICAgICAgIC8vIFRoaXMgaXMgYW4gQXJyYXlCdWZmZXIsIGNvbnZlcnQgaXQgdG8gYSBzdHJpbmcgYXJyYXkgKHVzZWQgaW4gSUUpDQogICAgICAgICAgICB2YXIgYmluYXJ5ID0gIiI7DQogICAgICAgICAgICB2YXIgYnl0ZXMgPSBuZXcgVWludDhBcnJheShkYXRhKTsNCiAgICAgICAgICAgIHZhciBsZW5ndGggPSBieXRlcy5ieXRlTGVuZ3RoOw0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeyBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7IH0NCiAgICAgICAgICAgIGRhdGEgPSBiaW5hcnk7DQogICAgICAgIH0NCiAgICAgICAgZWxzZSBpZiAodHlwZW9mIGRhdGEgIT09ICdzdHJpbmcnKSB7IHJldHVybjsgfQ0KDQogICAgICAgIC8vIFNlbmQgdGhlIGRhdGEgdXANCiAgICAgICAgaWYgKG9iai5vbkRhdGEgIT0gbnVsbCkgb2JqLm9uRGF0YShvYmosIGRhdGEpOw0KICAgIH0NCiAgICANCiAgICBmdW5jdGlvbiBfU2VuZCh4KSB7DQogICAgICAgIGlmIChzb2NrZXQgIT0gbnVsbCAmJiBzb2NrZXQucmVhZHlTdGF0ZSA9PSBXZWJTb2NrZXQuT1BFTikgew0KICAgICAgICAgICAgdmFyIGIgPSBuZXcgVWludDhBcnJheSh4Lmxlbmd0aCk7DQogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyArK2kpIHsgYltpXSA9IHguY2hhckNvZGVBdChpKTsgfQ0KICAgICAgICAgICAgc29ja2V0LnNlbmQoYi5idWZmZXIpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgb2JqLlNlbmRDbWQgPSBmdW5jdGlvbiAoY21kaWQsIGRhdGEpIHsNCiAgICAgICAgaWYgKHNvY2tldCA9PSBudWxsIHx8IG9iai5TdGF0ZSAhPSAyKSByZXR1cm47DQogICAgICAgIGlmICghZGF0YSB8fCBkYXRhID09IG51bGwpIGRhdGEgPSAiIjsNCiAgICAgICAgX1NlbmQoU2hvcnRUb1N0clgoY21kaWQpICsgZGF0YSk7DQogICAgfQ0KDQogICAgZnVuY3Rpb24gX1N0YXRlQ2hhbmdlKG5ld3N0YXRlKSB7DQogICAgICAgIGlmIChvYmouU3RhdGUgPT0gbmV3c3RhdGUpIHJldHVybjsNCiAgICAgICAgb2JqLlN0YXRlID0gbmV3c3RhdGU7DQogICAgICAgIGlmIChvYmoub25TdGF0ZUNoYW5nZWQgIT0gbnVsbCkgb2JqLm9uU3RhdGVDaGFuZ2VkKG9iaiwgb2JqLlN0YXRlKTsNCiAgICB9DQoNCiAgICBvYmouU3RvcCA9IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgX1N0YXRlQ2hhbmdlKDApOw0KICAgICAgICBpZiAoc29ja2V0ICE9IG51bGwpIHsgc29ja2V0LmNsb3NlKCk7IHNvY2tldCA9IG51bGw7IH0NCiAgICB9DQoNCiAgICByZXR1cm4gb2JqOw0KfS8qKiANCiogQGRlc2NyaXB0aW9uIFdTTUFOIGNvbW11bmljYXRpb24gdXNpbmcgd2Vic29ja2V0DQoqIEBhdXRob3IgWWxpYW4gU2FpbnQtSGlsYWlyZQ0KKiBAdmVyc2lvbiB2MC4yLjBjDQoqLw0KDQovLyBDb25zdHJ1Y3QgYSBXU01BTiBjb21tdW5pY2F0aW9uIG9iamVjdA0KdmFyIENyZWF0ZVdzbWFuQ29tbSA9IGZ1bmN0aW9uIChob3N0LCBwb3J0LCB1c2VyLCBwYXNzLCB0bHMpIHsNCiAgICB2YXIgb2JqID0ge307DQogICAgb2JqLlBlbmRpbmdBamF4ID0gW107ICAgICAgICAgICAgICAgLy8gTGlzdCBvZiBwZW5kaW5nIEFKQVggY2FsbHMuIFdoZW4gb25lIGZyZWVzIHVwLCBhbm90aGVyIHdpbGwgc3RhcnQuDQogICAgb2JqLkFjdGl2ZUFqYXhDb3VudCA9IDA7ICAgICAgICAgICAgLy8gTnVtYmVyIG9mIGN1cnJlbnRseSBhY3RpdmUgQUpBWCBjYWxscw0KICAgIG9iai5NYXhBY3RpdmVBamF4Q291bnQgPSAxOyAgICAgICAgIC8vIE1heGltdW0gbnVtYmVyIG9mIGFjdGl2YXRlIEFKQVggY2FsbHMgYXQgdGhlIHNhbWUgdGltZS4NCiAgICBvYmouRmFpbEFsbEVycm9yID0gMDsgICAgICAgICAgICAgICAvLyBTZXQgdGhpcyB0byBub24temVybyB0byBmYWlsIGFsbCBBSkFYIGNhbGxzIHdpdGggdGhhdCBlcnJvciBzdGF0dXMsIDk5OSBjYXVzZXMgcmVzcG9uc2VzIHRvIGJlIHNpbGVudC4NCiAgICBvYmouY2hhbGxlbmdlUGFyYW1zID0gbnVsbDsNCiAgICBvYmoubm9uY2Vjb3VudGVyID0gMTsNCiAgICBvYmouYXV0aGNvdW50ZXIgPSAwOw0KICAgIG9iai5zb2NrZXQgPSBudWxsOw0KICAgIG9iai5zb2NrZXRTdGF0ZSA9IDA7DQogICAgb2JqLmhvc3QgPSBob3N0Ow0KICAgIG9iai5wb3J0ID0gcG9ydDsNCiAgICBvYmoudXNlciA9IHVzZXI7DQogICAgb2JqLnBhc3MgPSBwYXNzOw0KICAgIG9iai50bHMgPSB0bHM7DQogICAgb2JqLnRsc3Yxb25seSA9IDA7DQogICAgb2JqLmNub25jZSA9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cmluZyg3KTsgLy8gR2VuZXJhdGUgYSByYW5kb20gY2xpZW50IG5vbmNlDQogICAgb2JqLmluRGF0YUNvdW50ID0gMDsNCiAgICBvYmouYW10VmVyc2lvbiA9IG51bGw7DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIC8vb2JqLkRlYnVnID0gZnVuY3Rpb24gKG1zZykgeyBjb25zb2xlLmxvZyhtc2cpOyB9DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIC8vICAgcHJpID0gcHJpb3JpdHksIGlmIHNldCB0byAxLCB0aGUgY2FsbCBpcyBoaWdoIHByaW9yaXR5IGFuZCBwdXQgb24gdG9wIG9mIHRoZSBzdGFjay4NCiAgICBvYmouUGVyZm9ybUFqYXggPSBmdW5jdGlvbiAocG9zdGRhdGEsIGNhbGxiYWNrLCB0YWcsIHByaSwgdXJsLCBhY3Rpb24pIHsNCiAgICAgICAgaWYgKG9iai5BY3RpdmVBamF4Q291bnQgPCBvYmouTWF4QWN0aXZlQWpheENvdW50ICYmIG9iai5QZW5kaW5nQWpheC5sZW5ndGggPT0gMCkgew0KICAgICAgICAgICAgLy8gVGhlcmUgYXJlIG5vIHBlbmRpbmcgQUpBWCBjYWxscywgcGVyZm9ybSB0aGUgY2FsbCBub3cuDQogICAgICAgICAgICBvYmouUGVyZm9ybUFqYXhFeChwb3N0ZGF0YSwgY2FsbGJhY2ssIHRhZywgdXJsLCBhY3Rpb24pOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhIGhpZ2ggcHJpb3JpdHkgY2FsbCwgcHV0IHRoaXMgY2FsbCBpbiBmcm9udCBvZiB0aGUgYXJyYXksIG90aGVyd2lzZSBwdXQgaXQgaW4gdGhlIGJhY2suDQogICAgICAgICAgICBpZiAocHJpID09IDEpIHsgb2JqLlBlbmRpbmdBamF4LnVuc2hpZnQoW3Bvc3RkYXRhLCBjYWxsYmFjaywgdGFnLCB1cmwsIGFjdGlvbl0pOyB9IGVsc2UgeyBvYmouUGVuZGluZ0FqYXgucHVzaChbcG9zdGRhdGEsIGNhbGxiYWNrLCB0YWcsIHVybCwgYWN0aW9uXSk7IH0NCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIC8vIFByaXZhdGUgbWV0aG9kDQogICAgb2JqLlBlcmZvcm1OZXh0QWpheCA9IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgaWYgKG9iai5BY3RpdmVBamF4Q291bnQgPj0gb2JqLk1heEFjdGl2ZUFqYXhDb3VudCB8fCBvYmouUGVuZGluZ0FqYXgubGVuZ3RoID09IDApIHJldHVybjsNCiAgICAgICAgdmFyIHggPSBvYmouUGVuZGluZ0FqYXguc2hpZnQoKTsNCiAgICAgICAgb2JqLlBlcmZvcm1BamF4RXgoeFswXSwgeFsxXSwgeFsyXSwgeFszXSwgeFs0XSk7DQogICAgICAgIG9iai5QZXJmb3JtTmV4dEFqYXgoKTsNCiAgICB9DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIG9iai5QZXJmb3JtQWpheEV4ID0gZnVuY3Rpb24gKHBvc3RkYXRhLCBjYWxsYmFjaywgdGFnLCB1cmwsIGFjdGlvbikgew0KICAgICAgICBpZiAob2JqLkZhaWxBbGxFcnJvciAhPSAwKSB7IG9iai5nb3ROZXh0TWVzc2FnZXNFcnJvcih7IHN0YXR1czogb2JqLkZhaWxBbGxFcnJvciB9LCAnZXJyb3InLCBudWxsLCBbcG9zdGRhdGEsIGNhbGxiYWNrLCB0YWcsIHVybCwgYWN0aW9uXSk7IHJldHVybjsgfQ0KICAgICAgICBpZiAoIXBvc3RkYXRhKSBwb3N0ZGF0YSA9ICIiOw0KICAgICAgICAvL2NvbnNvbGUubG9nKCJTRU5EOiAiICsgcG9zdGRhdGEpOyAvLyBERUJVRw0KDQogICAgICAgIC8vIFdlIGFyZSBpbiBhIHdlYnNvY2tldCByZWxheSBlbnZpcm9ubWVudCANCiAgICAgICAgb2JqLkFjdGl2ZUFqYXhDb3VudCsrOw0KICAgICAgICByZXR1cm4gb2JqLlBlcmZvcm1BamF4RXhOb2RlSlMocG9zdGRhdGEsIGNhbGxiYWNrLCB0YWcsIHVybCwgYWN0aW9uKTsNCiAgICB9DQoNCiAgICAvLyBXZWJzb2NrZXQgcmVsYXkgc3BlY2lmaWMgcHJpdmF0ZSBtZXRob2QNCiAgICBvYmoucGVuZGluZ0FqYXhDYWxsID0gW107DQoNCiAgICAvLyBXZWJzb2NrZXQgcmVsYXkgc3BlY2lmaWMgcHJpdmF0ZSBtZXRob2QNCiAgICBvYmouUGVyZm9ybUFqYXhFeE5vZGVKUyA9IGZ1bmN0aW9uIChwb3N0ZGF0YSwgY2FsbGJhY2ssIHRhZywgdXJsLCBhY3Rpb24pIHsgb2JqLlBlcmZvcm1BamF4RXhOb2RlSlMyKHBvc3RkYXRhLCBjYWxsYmFjaywgdGFnLCB1cmwsIGFjdGlvbiwgMyk7IH0NCg0KICAgIC8vIFdlYnNvY2tldCByZWxheSBzcGVjaWZpYyBwcml2YXRlIG1ldGhvZA0KICAgIG9iai5QZXJmb3JtQWpheEV4Tm9kZUpTMiA9IGZ1bmN0aW9uIChwb3N0ZGF0YSwgY2FsbGJhY2ssIHRhZywgdXJsLCBhY3Rpb24sIHJldHJ5KSB7DQogICAgICAgIGlmIChyZXRyeSA8PSAwIHx8IG9iai5GYWlsQWxsRXJyb3IgIT0gMCkgew0KICAgICAgICAgICAgLy8gVG9vIG1hbnkgcmV0cnksIGZhaWwgaGVyZS4NCiAgICAgICAgICAgIG9iai5BY3RpdmVBamF4Q291bnQtLTsNCiAgICAgICAgICAgIGlmIChvYmouRmFpbEFsbEVycm9yICE9IDk5OSkgb2JqLmdvdE5leHRNZXNzYWdlcyhudWxsLCAnZXJyb3InLCB7IHN0YXR1czogKChvYmouRmFpbEFsbEVycm9yID09IDApID8gNDA4IDogb2JqLkZhaWxBbGxFcnJvcikgfSwgW3Bvc3RkYXRhLCBjYWxsYmFjaywgdGFnLCB1cmwsIGFjdGlvbl0pOyAvLyA0MDggaXMgdGltZW91dCBlcnJvcg0KICAgICAgICAgICAgb2JqLlBlcmZvcm1OZXh0QWpheCgpOw0KICAgICAgICAgICAgcmV0dXJuOw0KICAgICAgICB9DQogICAgICAgIG9iai5wZW5kaW5nQWpheENhbGwucHVzaChbcG9zdGRhdGEsIGNhbGxiYWNrLCB0YWcsIHVybCwgYWN0aW9uLCByZXRyeV0pOw0KICAgICAgICBpZiAob2JqLnNvY2tldFN0YXRlID09IDApIHsgb2JqLnh4Q29ubmVjdEh0dHBTb2NrZXQoKTsgfQ0KICAgICAgICBlbHNlIGlmIChvYmouc29ja2V0U3RhdGUgPT0gMikgeyBvYmouc2VuZFJlcXVlc3QocG9zdGRhdGEsIHVybCwgYWN0aW9uKTsgfQ0KICAgIH0NCg0KICAgIC8vIFdlYnNvY2tldCByZWxheSBzcGVjaWZpYyBwcml2YXRlIG1ldGhvZCAoQ29udGVudCBMZW5ndGggRW5jb2RpbmcpDQogICAgb2JqLnNlbmRSZXF1ZXN0ID0gZnVuY3Rpb24gKHBvc3RkYXRhLCB1cmwsIGFjdGlvbikgew0KICAgICAgICB1cmwgPSB1cmwgPyB1cmwgOiAiL3dzbWFuIjsNCiAgICAgICAgYWN0aW9uID0gYWN0aW9uID8gYWN0aW9uIDogIlBPU1QiOw0KICAgICAgICB2YXIgaCA9IGFjdGlvbiArICIgIiArIHVybCArICIgSFRUUC8xLjFcclxuIjsNCiAgICAgICAgaWYgKG9iai5jaGFsbGVuZ2VQYXJhbXMgIT0gbnVsbCkgew0KICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gaGV4X21kNShoZXhfbWQ1KG9iai51c2VyICsgJzonICsgb2JqLmNoYWxsZW5nZVBhcmFtc1sicmVhbG0iXSArICc6JyArIG9iai5wYXNzKSArICc6JyArIG9iai5jaGFsbGVuZ2VQYXJhbXNbIm5vbmNlIl0gKyAnOicgKyBvYmoubm9uY2Vjb3VudGVyICsgJzonICsgb2JqLmNub25jZSArICc6JyArIG9iai5jaGFsbGVuZ2VQYXJhbXNbInFvcCJdICsgJzonICsgaGV4X21kNShhY3Rpb24gKyAnOicgKyB1cmwpKTsNCiAgICAgICAgICAgIGggKz0gJ0F1dGhvcml6YXRpb246ICcgKyBvYmoucmVuZGVyRGlnZXN0KHsgInVzZXJuYW1lIjogb2JqLnVzZXIsICJyZWFsbSI6IG9iai5jaGFsbGVuZ2VQYXJhbXNbInJlYWxtIl0sICJub25jZSI6IG9iai5jaGFsbGVuZ2VQYXJhbXNbIm5vbmNlIl0sICJ1cmkiOiB1cmwsICJxb3AiOiBvYmouY2hhbGxlbmdlUGFyYW1zWyJxb3AiXSwgInJlc3BvbnNlIjogcmVzcG9uc2UsICJuYyI6IG9iai5ub25jZWNvdW50ZXIrKywgImNub25jZSI6IG9iai5jbm9uY2UgfSkgKyAnXHJcbic7DQogICAgICAgIH0NCiAgICAgICAgaCArPSAnSG9zdDogJyArIG9iai5ob3N0ICsgJzonICsgb2JqLnBvcnQgKyAnXHJcbkNvbnRlbnQtTGVuZ3RoOiAnICsgcG9zdGRhdGEubGVuZ3RoICsgJ1xyXG5cclxuJyArIHBvc3RkYXRhOyAvLyBVc2UgQ29udGVudC1MZW5ndGgNCiAgICAgICAgLy9oICs9ICdIb3N0OiAnICsgb2JqLmhvc3QgKyAnOicgKyBvYmoucG9ydCArICdcclxuVHJhbnNmZXItRW5jb2Rpbmc6IGNodW5rZWRcclxuXHJcbicgKyBwb3N0ZGF0YS5sZW5ndGgudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCkgKyAnXHJcbicgKyBwb3N0ZGF0YSArICdcclxuMFxyXG5cclxuJzsgLy8gVXNlIENodW5rZWQtRW5jb2RpbmcNCiAgICAgICAgX1NlbmQoaCk7DQogICAgfQ0KDQogICAgLy8gV2Vic29ja2V0IHJlbGF5IHNwZWNpZmljIHByaXZhdGUgbWV0aG9kDQogICAgb2JqLnBhcnNlRGlnZXN0ID0gZnVuY3Rpb24gKGhlYWRlcikgew0KICAgICAgICB2YXIgdCA9IGhlYWRlci5zdWJzdHJpbmcoNykuc3BsaXQoJywnKTsNCiAgICAgICAgZm9yIChpIGluIHQpIHRbaV0gPSB0W2ldLnRyaW0oKTsNCiAgICAgICAgcmV0dXJuIHQucmVkdWNlKGZ1bmN0aW9uIChvYmosIHMpIHsgdmFyIHBhcnRzID0gcy5zcGxpdCgnPScpOyBvYmpbcGFydHNbMF1dID0gcGFydHNbMV0ucmVwbGFjZSgvIi9nLCAnJyk7IHJldHVybiBvYmo7IH0sIHt9KQ0KICAgIH0NCg0KICAgIC8vIFdlYnNvY2tldCByZWxheSBzcGVjaWZpYyBwcml2YXRlIG1ldGhvZA0KICAgIG9iai5yZW5kZXJEaWdlc3QgPSBmdW5jdGlvbiAocGFyYW1zKSB7DQogICAgICAgIHZhciBwYXJhbXNuYW1lcyA9IFtdOw0KICAgICAgICBmb3IgKGkgaW4gcGFyYW1zKSB7IHBhcmFtc25hbWVzLnB1c2goaSk7IH0NCiAgICAgICAgcmV0dXJuICdEaWdlc3QgJyArIHBhcmFtc25hbWVzLnJlZHVjZShmdW5jdGlvbiAoczEsIGlpKSB7IHJldHVybiBzMSArICcsJyArIGlpICsgJz0iJyArIHBhcmFtc1tpaV0gKyAnIicgfSwgJycpLnN1YnN0cmluZygxKTsNCiAgICB9DQoNCiAgICAvLyBXZWJzb2NrZXQgcmVsYXkgc3BlY2lmaWMgcHJpdmF0ZSBtZXRob2QNCiAgICBvYmoueHhDb25uZWN0SHR0cFNvY2tldCA9IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgLy9vYmouRGVidWcoInh4Q29ubmVjdEh0dHBTb2NrZXQiKTsNCiAgICAgICAgb2JqLmluRGF0YUNvdW50ID0gMDsNCiAgICAgICAgb2JqLnNvY2tldFN0YXRlID0gMTsNCiAgICAgICAgb2JqLnNvY2tldCA9IG5ldyBXZWJTb2NrZXQod2luZG93LmxvY2F0aW9uLnByb3RvY29sLnJlcGxhY2UoImh0dHAiLCAid3MiKSArICIvLyIgKyB3aW5kb3cubG9jYXRpb24uaG9zdCArIHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZS5zdWJzdHJpbmcoMCwgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLmxhc3RJbmRleE9mKCcvJykpICsgIi93ZWJyZWxheS5hc2h4P3A9MSZob3N0PSIgKyBvYmouaG9zdCArICImcG9ydD0iICsgb2JqLnBvcnQgKyAiJnRscz0iICsgb2JqLnRscyArICImdGxzMW9ubHk9IiArIG9iai50bHN2MW9ubHkgKyAoKHVzZXIgPT0gJyonKSA/ICImc2VydmVyYXV0aD0xIiA6ICIiKSArICgodHlwZW9mIHBhc3MgPT09ICJ1bmRlZmluZWQiKSA/ICgiJnNlcnZlcmF1dGg9MSZ1c2VyPSIgKyB1c2VyKSA6ICIiKSk7IC8vIFRoZSAicD0xIiBpbmRpY2F0ZXMgdG8gdGhlIHJlbGF5IHRoYXQgdGhpcyBpcyBhIFdTTUFOIHNlc3Npb24NCiAgICAgICAgb2JqLnNvY2tldC5vbm9wZW4gPSBfT25Tb2NrZXRDb25uZWN0ZWQ7DQogICAgICAgIG9iai5zb2NrZXQub25tZXNzYWdlID0gX09uTWVzc2FnZTsNCiAgICAgICAgb2JqLnNvY2tldC5vbmNsb3NlID0gX09uU29ja2V0Q2xvc2VkOw0KICAgIH0NCg0KICAgIC8vIFdlYnNvY2tldCByZWxheSBzcGVjaWZpYyBwcml2YXRlIG1ldGhvZA0KICAgIGZ1bmN0aW9uIF9PblNvY2tldENvbm5lY3RlZCgpIHsNCiAgICAgICAgb2JqLnNvY2tldFN0YXRlID0gMjsNCiAgICAgICAgb2JqLnNvY2tldFBhcnNlU3RhdGUgPSAwOw0KICAgICAgICBvYmouc29ja2V0QWNjdW11bGF0b3IgPSAnJzsNCiAgICAgICAgb2JqLnNvY2tldEhlYWRlciA9IG51bGw7DQogICAgICAgIG9iai5zb2NrZXREYXRhID0gJyc7DQogICAgICAgIC8vY29uc29sZS5sb2coInh4T25Tb2NrZXRDb25uZWN0ZWQiKTsNCiAgICAgICAgZm9yIChpIGluIG9iai5wZW5kaW5nQWpheENhbGwpIHsgb2JqLnNlbmRSZXF1ZXN0KG9iai5wZW5kaW5nQWpheENhbGxbaV1bMF0sIG9iai5wZW5kaW5nQWpheENhbGxbaV1bM10sIG9iai5wZW5kaW5nQWpheENhbGxbaV1bNF0pOyB9DQogICAgfQ0KDQogICAgLy8gU2V0dXAgdGhlIGZpbGUgcmVhZGVyDQogICAgdmFyIGZpbGVSZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpOw0KICAgIHZhciBmaWxlUmVhZGVySW51c2UgPSBmYWxzZSwgZmlsZVJlYWRlckFjYyA9IFtdOw0KICAgIGlmIChmaWxlUmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZykgew0KICAgICAgICAvLyBDaHJvbWUgJiBGaXJlZm94IChEcmFmdCkNCiAgICAgICAgZmlsZVJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAoZSkgeyBfT25Tb2NrZXREYXRhKGUudGFyZ2V0LnJlc3VsdCk7IGlmIChmaWxlUmVhZGVyQWNjLmxlbmd0aCA9PSAwKSB7IGZpbGVSZWFkZXJJbnVzZSA9IGZhbHNlOyB9IGVsc2UgeyBmaWxlUmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyhuZXcgQmxvYihbZmlsZVJlYWRlckFjYy5zaGlmdCgpXSkpOyB9IH0NCiAgICB9IGVsc2UgaWYgKGZpbGVSZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIpIHsNCiAgICAgICAgLy8gQ2hyb21lICYgRmlyZWZveCAoU3BlYykNCiAgICAgICAgZmlsZVJlYWRlci5vbmxvYWRlbmQgPSBmdW5jdGlvbiAoZSkgeyBfT25Tb2NrZXREYXRhKGUudGFyZ2V0LnJlc3VsdCk7IGlmIChmaWxlUmVhZGVyQWNjLmxlbmd0aCA9PSAwKSB7IGZpbGVSZWFkZXJJbnVzZSA9IGZhbHNlOyB9IGVsc2UgeyBmaWxlUmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKGZpbGVSZWFkZXJBY2Muc2hpZnQoKSk7IH0gfQ0KICAgIH0NCg0KICAgIGZ1bmN0aW9uIF9Pbk1lc3NhZ2UoZSkgew0KICAgICAgICBpZiAodHlwZW9mIGUuZGF0YSA9PSAnb2JqZWN0Jykgew0KICAgICAgICAgICAgaWYgKGZpbGVSZWFkZXJJbnVzZSA9PSB0cnVlKSB7IGZpbGVSZWFkZXJBY2MucHVzaChlLmRhdGEpOyByZXR1cm47IH0NCiAgICAgICAgICAgIGlmIChmaWxlUmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZykgew0KICAgICAgICAgICAgICAgIC8vIENocm9tZSAmIEZpcmVmb3ggKERyYWZ0KQ0KICAgICAgICAgICAgICAgIGZpbGVSZWFkZXJJbnVzZSA9IHRydWU7DQogICAgICAgICAgICAgICAgZmlsZVJlYWRlci5yZWFkQXNCaW5hcnlTdHJpbmcobmV3IEJsb2IoW2UuZGF0YV0pKTsNCiAgICAgICAgICAgIH0gZWxzZSBpZiAoZmlsZVJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcikgew0KICAgICAgICAgICAgICAgIC8vIENocm9tZSAmIEZpcmVmb3ggKFNwZWMpDQogICAgICAgICAgICAgICAgZmlsZVJlYWRlckludXNlID0gdHJ1ZTsNCiAgICAgICAgICAgICAgICBmaWxlUmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKGUuZGF0YSk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIC8vIElFMTAsIHJlYWRBc0JpbmFyeVN0cmluZyBkb2VzIG5vdCBleGlzdCwgdXNlIGFuIGFsdGVybmF0aXZlLg0KICAgICAgICAgICAgICAgIHZhciBiaW5hcnkgPSAiIiwgYnl0ZXMgPSBuZXcgVWludDhBcnJheShlLmRhdGEpLCBsZW5ndGggPSBieXRlcy5ieXRlTGVuZ3RoOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsgYmluYXJ5ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0pOyB9DQogICAgICAgICAgICAgICAgX09uU29ja2V0RGF0YShiaW5hcnkpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgX09uU29ja2V0RGF0YShlLmRhdGEpOw0KICAgICAgICB9DQogICAgfTsNCg0KICAgIC8vIFdlYnNvY2tldCByZWxheSBzcGVjaWZpYyBwcml2YXRlIG1ldGhvZA0KICAgIGZ1bmN0aW9uIF9PblNvY2tldERhdGEoZGF0YSkgew0KICAgICAgICAvL29iai5EZWJ1ZygiX09uU29ja2V0RGF0YSAoIiArIGRhdGEubGVuZ3RoICsgIik6ICIgKyBkYXRhKTsNCg0KICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT09ICdvYmplY3QnKSB7DQogICAgICAgICAgICAvLyBUaGlzIGlzIGFuIEFycmF5QnVmZmVyLCBjb252ZXJ0IGl0IHRvIGEgc3RyaW5nIGFycmF5ICh1c2VkIGluIElFKQ0KICAgICAgICAgICAgdmFyIGJpbmFyeSA9ICIiLCBieXRlcyA9IG5ldyBVaW50OEFycmF5KGRhdGEpLCBsZW5ndGggPSBieXRlcy5ieXRlTGVuZ3RoOw0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeyBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7IH0NCiAgICAgICAgICAgIGRhdGEgPSBiaW5hcnk7DQogICAgICAgIH0NCiAgICAgICAgZWxzZSBpZiAodHlwZW9mIGRhdGEgIT09ICdzdHJpbmcnKSByZXR1cm47DQoNCiAgICAgICAgLy9jb25zb2xlLmxvZygiUkVDVigiICsgb2JqLnNvY2tldFBhcnNlU3RhdGUgKyAiKTogIiArIGRhdGEpOyAvLyBERUJVRw0KDQogICAgICAgIG9iai5zb2NrZXRBY2N1bXVsYXRvciArPSBkYXRhOw0KICAgICAgICB3aGlsZSAodHJ1ZSkgew0KICAgICAgICAgICAgaWYgKG9iai5zb2NrZXRQYXJzZVN0YXRlID09IDApIHsNCiAgICAgICAgICAgICAgICB2YXIgaGVhZGVyc2l6ZSA9IG9iai5zb2NrZXRBY2N1bXVsYXRvci5pbmRleE9mKCJcclxuXHJcbiIpOw0KICAgICAgICAgICAgICAgIGlmIChoZWFkZXJzaXplIDwgMCkgcmV0dXJuOw0KICAgICAgICAgICAgICAgIC8vb2JqLkRlYnVnKG9iai5zb2NrZXRBY2N1bXVsYXRvci5zdWJzdHJpbmcoMCwgaGVhZGVyc2l6ZSkpOyAvLyBEaXNwbGF5IHJlY2VpdmVkIEhUVFAgaGVhZGVyDQogICAgICAgICAgICAgICAgb2JqLnNvY2tldEhlYWRlciA9IG9iai5zb2NrZXRBY2N1bXVsYXRvci5zdWJzdHJpbmcoMCwgaGVhZGVyc2l6ZSkuc3BsaXQoIlxyXG4iKTsNCiAgICAgICAgICAgICAgICBpZiAob2JqLmFtdFZlcnNpb24gPT0gbnVsbCkgeyBmb3IgKHZhciBpIGluIG9iai5zb2NrZXRIZWFkZXIpIHsgaWYgKG9iai5zb2NrZXRIZWFkZXJbaV0uaW5kZXhPZignU2VydmVyOiBJbnRlbChSKSBBY3RpdmUgTWFuYWdlbWVudCBUZWNobm9sb2d5ICcpID09IDApIHsgb2JqLmFtdFZlcnNpb24gPSBvYmouc29ja2V0SGVhZGVyW2ldLnN1YnN0cmluZyg0Nik7IH0gfSB9DQogICAgICAgICAgICAgICAgb2JqLnNvY2tldEFjY3VtdWxhdG9yID0gb2JqLnNvY2tldEFjY3VtdWxhdG9yLnN1YnN0cmluZyhoZWFkZXJzaXplICsgNCk7DQogICAgICAgICAgICAgICAgb2JqLnNvY2tldFBhcnNlU3RhdGUgPSAxOw0KICAgICAgICAgICAgICAgIG9iai5zb2NrZXREYXRhID0gJyc7DQogICAgICAgICAgICAgICAgb2JqLnNvY2tldFhIZWFkZXIgPSB7IERpcmVjdGl2ZTogb2JqLnNvY2tldEhlYWRlclswXS5zcGxpdCgnICcpIH07DQogICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZygiSGVhZGVyIiwgb2JqLnNvY2tldFhIZWFkZXIpOw0KICAgICAgICAgICAgICAgIGZvciAoaSBpbiBvYmouc29ja2V0SGVhZGVyKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChpICE9IDApIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4MiA9IG9iai5zb2NrZXRIZWFkZXJbaV0uaW5kZXhPZignOicpOw0KICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnNvY2tldFhIZWFkZXJbb2JqLnNvY2tldEhlYWRlcltpXS5zdWJzdHJpbmcoMCwgeDIpLnRvTG93ZXJDYXNlKCldID0gb2JqLnNvY2tldEhlYWRlcltpXS5zdWJzdHJpbmcoeDIgKyAyKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChvYmouc29ja2V0UGFyc2VTdGF0ZSA9PSAxKSB7DQogICAgICAgICAgICAgICAgdmFyIGNzaXplID0gLTE7DQogICAgICAgICAgICAgICAgaWYgKChvYmouc29ja2V0WEhlYWRlclsiY29ubmVjdGlvbiJdICE9IHVuZGVmaW5lZCkgJiYgKG9iai5zb2NrZXRYSGVhZGVyWyJjb25uZWN0aW9uIl0udG9Mb3dlckNhc2UoKSA9PSAnY2xvc2UnKSAmJiAoKG9iai5zb2NrZXRYSGVhZGVyWyJ0cmFuc2Zlci1lbmNvZGluZyJdID09IHVuZGVmaW5lZCkgfHwgKG9iai5zb2NrZXRYSGVhZGVyWyJ0cmFuc2Zlci1lbmNvZGluZyJdLnRvTG93ZXJDYXNlKCkgIT0gJ2NodW5rZWQnKSkpIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGJvZHkgZW5kcyB3aXRoIGEgY2xvc2UsIGluIHRoaXMgY2FzZSwgd2Ugd2lsbCBvbmx5IHByb2Nlc3MgdGhlIGhlYWRlcg0KICAgICAgICAgICAgICAgICAgICBjc2l6ZSA9IDA7DQogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvYmouc29ja2V0WEhlYWRlclsiY29udGVudC1sZW5ndGgiXSAhPSB1bmRlZmluZWQpIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGJvZHkgbGVuZ3RoIGlzIHNwZWNpZmllZCBieSB0aGUgY29udGVudC1sZW5ndGgNCiAgICAgICAgICAgICAgICAgICAgY3NpemUgPSBwYXJzZUludChvYmouc29ja2V0WEhlYWRlclsiY29udGVudC1sZW5ndGgiXSk7DQogICAgICAgICAgICAgICAgICAgIGlmIChvYmouc29ja2V0QWNjdW11bGF0b3IubGVuZ3RoIDwgY3NpemUpIHJldHVybjsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGRhdGEgPSBvYmouc29ja2V0QWNjdW11bGF0b3Iuc3Vic3RyaW5nKDAsIGNzaXplKTsNCiAgICAgICAgICAgICAgICAgICAgb2JqLnNvY2tldEFjY3VtdWxhdG9yID0gb2JqLnNvY2tldEFjY3VtdWxhdG9yLnN1YnN0cmluZyhjc2l6ZSk7DQogICAgICAgICAgICAgICAgICAgIG9iai5zb2NrZXREYXRhID0gZGF0YTsNCiAgICAgICAgICAgICAgICAgICAgY3NpemUgPSAwOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIC8vIFRoZSBib2R5IGlzIGNodW5rZWQNCiAgICAgICAgICAgICAgICAgICAgdmFyIGNsZW4gPSBvYmouc29ja2V0QWNjdW11bGF0b3IuaW5kZXhPZigiXHJcbiIpOw0KICAgICAgICAgICAgICAgICAgICBpZiAoY2xlbiA8IDApIHJldHVybjsgLy8gQ2h1bmsgbGVuZ3RoIG5vdCBmb3VuZCwgZXhpdCBub3cgYW5kIGdldCBtb3JlIGRhdGEuDQogICAgICAgICAgICAgICAgICAgIC8vIENodW5rIGxlbmd0aCBpZiBmb3VuZCwgbGV0cyBzZWUgaWYgd2UgY2FuIGdldCB0aGUgZGF0YS4NCiAgICAgICAgICAgICAgICAgICAgY3NpemUgPSBwYXJzZUludChvYmouc29ja2V0QWNjdW11bGF0b3Iuc3Vic3RyaW5nKDAsIGNsZW4pLCAxNik7DQogICAgICAgICAgICAgICAgICAgIGlmIChpc05hTihjc2l6ZSkpIHsgaWYgKG9iai53ZWJzb2NrZXQpIHsgb2JqLndlYnNvY2tldC5jbG9zZSgpOyB9IHJldHVybjsgfSAvLyBDcml0aWNhbCBlcnJvciwgY2xvc2UgdGhlIHNvY2tldCBhbmQgZXhpdC4NCiAgICAgICAgICAgICAgICAgICAgaWYgKG9iai5zb2NrZXRBY2N1bXVsYXRvci5sZW5ndGggPCBjbGVuICsgMiArIGNzaXplICsgMikgcmV0dXJuOw0KICAgICAgICAgICAgICAgICAgICAvLyBXZSBnb3QgYSBjaHVuayB3aXRoIGFsbCBvZiB0aGUgZGF0YSwgaGFuZGxlIHRoZSBjaHVuY2sgbm93Lg0KICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IG9iai5zb2NrZXRBY2N1bXVsYXRvci5zdWJzdHJpbmcoY2xlbiArIDIsIGNsZW4gKyAyICsgY3NpemUpOw0KICAgICAgICAgICAgICAgICAgICBvYmouc29ja2V0QWNjdW11bGF0b3IgPSBvYmouc29ja2V0QWNjdW11bGF0b3Iuc3Vic3RyaW5nKGNsZW4gKyAyICsgY3NpemUgKyAyKTsNCiAgICAgICAgICAgICAgICAgICAgb2JqLnNvY2tldERhdGEgKz0gZGF0YTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYgKGNzaXplID09IDApIHsNCiAgICAgICAgICAgICAgICAgICAgLy9vYmouRGVidWcoIl9PblNvY2tldERhdGEgRE9ORTogKCIgKyBvYmouc29ja2V0RGF0YS5sZW5ndGggKyAiKTogIiArIG9iai5zb2NrZXREYXRhKTsNCiAgICAgICAgICAgICAgICAgICAgX1Byb2Nlc3NIdHRwUmVzcG9uc2Uob2JqLnNvY2tldFhIZWFkZXIsIG9iai5zb2NrZXREYXRhKTsNCiAgICAgICAgICAgICAgICAgICAgb2JqLnNvY2tldFBhcnNlU3RhdGUgPSAwOw0KICAgICAgICAgICAgICAgICAgICBvYmouc29ja2V0SGVhZGVyID0gbnVsbDsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQoNCiAgICAvLyBXZWJzb2NrZXQgcmVsYXkgc3BlY2lmaWMgcHJpdmF0ZSBtZXRob2QNCiAgICBmdW5jdGlvbiBfUHJvY2Vzc0h0dHBSZXNwb25zZShoZWFkZXIsIGRhdGEpIHsNCiAgICAgICAgLy9vYmouRGVidWcoIl9Qcm9jZXNzSHR0cFJlc3BvbnNlOiAiICsgaGVhZGVyLkRpcmVjdGl2ZVsxXSk7DQoNCiAgICAgICAgdmFyIHMgPSBwYXJzZUludChoZWFkZXIuRGlyZWN0aXZlWzFdKTsNCiAgICAgICAgaWYgKGlzTmFOKHMpKSB7DQogICAgICAgICAgICBzID0gNjAyOw0KICAgICAgICB9DQogICAgICAgIGlmIChzID09IDQwMSAmJiArKyhvYmouYXV0aGNvdW50ZXIpIDwgMykgew0KICAgICAgICAgICAgb2JqLmNoYWxsZW5nZVBhcmFtcyA9IG9iai5wYXJzZURpZ2VzdChoZWFkZXJbJ3d3dy1hdXRoZW50aWNhdGUnXSk7IC8vIFNldCB0aGUgZGlnZXN0IHBhcmFtZXRlcnMsIGFmdGVyIHRoaXMsIHRoZSBzb2NrZXQgd2lsbCBjbG9zZSBhbmQgd2Ugd2lsbCBhdXRvLXJldHJ5DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICB2YXIgciA9IG9iai5wZW5kaW5nQWpheENhbGwuc2hpZnQoKTsNCiAgICAgICAgICAgIC8vIGlmIChzICE9IDIwMCkgeyBvYmouRGVidWcoIkVycm9yLCBzdGF0dXM9IiArIHMgKyAiXHJcblxyXG5yZXE9IiArIHJbMF0gKyAiXHJcblxyXG5yZXNwPSIgKyBkYXRhKTsgfSAvLyBEZWJ1ZzogRGlzcGxheSB0aGUgcmVxdWVzdCAmIHJlc3BvbnNlIGlmIHNvbWV0aGluZyBkaWQgbm90IHdvcmsuDQogICAgICAgICAgICBvYmouYXV0aGNvdW50ZXIgPSAwOw0KICAgICAgICAgICAgb2JqLkFjdGl2ZUFqYXhDb3VudC0tOw0KICAgICAgICAgICAgb2JqLmdvdE5leHRNZXNzYWdlcyhkYXRhLCAnc3VjY2VzcycsIHsgc3RhdHVzOiBzIH0sIHIpOw0KICAgICAgICAgICAgb2JqLlBlcmZvcm1OZXh0QWpheCgpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgLy8gV2Vic29ja2V0IHJlbGF5IHNwZWNpZmljIHByaXZhdGUgbWV0aG9kDQogICAgZnVuY3Rpb24gX09uU29ja2V0Q2xvc2VkKGRhdGEpIHsNCiAgICAgICAgLy9jb25zb2xlLmxvZygiX09uU29ja2V0Q2xvc2VkIik7DQogICAgICAgIGlmIChvYmouaW5EYXRhQ291bnQgPT0gMCkgeyBvYmoudGxzdjFvbmx5ID0gKDEgLSBvYmoudGxzdjFvbmx5KTsgfQ0KICAgICAgICBvYmouc29ja2V0U3RhdGUgPSAwOw0KICAgICAgICBpZiAob2JqLnNvY2tldCAhPSBudWxsKSB7IG9iai5zb2NrZXQuY2xvc2UoKTsgb2JqLnNvY2tldCA9IG51bGw7IH0NCiAgICAgICAgaWYgKG9iai5wZW5kaW5nQWpheENhbGwubGVuZ3RoID4gMCkgew0KICAgICAgICAgICAgdmFyIHIgPSBvYmoucGVuZGluZ0FqYXhDYWxsLnNoaWZ0KCk7DQogICAgICAgICAgICB2YXIgcmV0cnkgPSByWzVdOw0KICAgICAgICAgICAgb2JqLlBlcmZvcm1BamF4RXhOb2RlSlMyKHJbMF0sIHJbMV0sIHJbMl0sIHJbM10sIHJbNF0sIC0tcmV0cnkpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgLy8gV2Vic29ja2V0IHJlbGF5IHNwZWNpZmljIHByaXZhdGUgbWV0aG9kDQogICAgZnVuY3Rpb24gX1NlbmQoeCkgew0KICAgICAgICAvL2NvbnNvbGUubG9nKCJTRU5EOiAiICsgeCk7IC8vIERFQlVHDQogICAgICAgIGlmIChvYmouc29ja2V0U3RhdGUgPT0gMiAmJiBvYmouc29ja2V0ICE9IG51bGwgJiYgb2JqLnNvY2tldC5yZWFkeVN0YXRlID09IFdlYlNvY2tldC5PUEVOKSB7DQogICAgICAgICAgICB2YXIgYiA9IG5ldyBVaW50OEFycmF5KHgubGVuZ3RoKTsNCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeC5sZW5ndGg7ICsraSkgeyBiW2ldID0geC5jaGFyQ29kZUF0KGkpOyB9DQogICAgICAgICAgICB0cnkgeyBvYmouc29ja2V0LnNlbmQoYi5idWZmZXIpOyB9IGNhdGNoIChlKSB7IH0NCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIC8vIFByaXZhdGUgbWV0aG9kDQogICAgb2JqLmdvdE5leHRNZXNzYWdlcyA9IGZ1bmN0aW9uIChkYXRhLCBzdGF0dXMsIHJlcXVlc3QsIGNhbGxBcmdzKSB7DQogICAgICAgIGlmIChvYmouRmFpbEFsbEVycm9yID09IDk5OSkgcmV0dXJuOw0KICAgICAgICBpZiAob2JqLkZhaWxBbGxFcnJvciAhPSAwKSB7IGNhbGxBcmdzWzFdKG51bGwsIG9iai5GYWlsQWxsRXJyb3IsIGNhbGxBcmdzWzJdKTsgcmV0dXJuOyB9DQogICAgICAgIGlmIChyZXF1ZXN0LnN0YXR1cyAhPSAyMDApIHsgY2FsbEFyZ3NbMV0obnVsbCwgcmVxdWVzdC5zdGF0dXMsIGNhbGxBcmdzWzJdKTsgcmV0dXJuOyB9DQogICAgICAgIGNhbGxBcmdzWzFdKGRhdGEsIDIwMCwgY2FsbEFyZ3NbMl0pOw0KICAgIH0NCg0KICAgIC8vIFByaXZhdGUgbWV0aG9kDQogICAgb2JqLmdvdE5leHRNZXNzYWdlc0Vycm9yID0gZnVuY3Rpb24gKHJlcXVlc3QsIHN0YXR1cywgZXJyb3JUaHJvd24sIGNhbGxBcmdzKSB7DQogICAgICAgIGlmIChvYmouRmFpbEFsbEVycm9yID09IDk5OSkgcmV0dXJuOw0KICAgICAgICBpZiAob2JqLkZhaWxBbGxFcnJvciAhPSAwKSB7IGNhbGxBcmdzWzFdKG51bGwsIG9iai5GYWlsQWxsRXJyb3IsIGNhbGxBcmdzWzJdKTsgcmV0dXJuOyB9DQogICAgICAgIGNhbGxBcmdzWzFdKG9iaiwgbnVsbCwgeyBIZWFkZXI6IHsgSHR0cEVycm9yOiByZXF1ZXN0LnN0YXR1cyB9IH0sIHJlcXVlc3Quc3RhdHVzLCBjYWxsQXJnc1syXSk7DQogICAgfQ0KDQogICAgLy8gQ2FuY2VsIGFsbCBwZW5kaW5nIHF1ZXJpZXMgd2l0aCBnaXZlbiBzdGF0dXMNCiAgICBvYmouQ2FuY2VsQWxsUXVlcmllcyA9IGZ1bmN0aW9uIChzKSB7DQogICAgICAgIHdoaWxlIChvYmouUGVuZGluZ0FqYXgubGVuZ3RoID4gMCkgeyB2YXIgeCA9IG9iai5QZW5kaW5nQWpheC5zaGlmdCgpOyB4WzFdKG51bGwsIHMsIHhbMl0pOyB9DQogICAgICAgIGlmIChvYmoud2Vic29ja2V0ICE9IG51bGwpIHsgb2JqLndlYnNvY2tldC5jbG9zZSgpOyBvYmoud2Vic29ja2V0ID0gbnVsbDsgb2JqLnNvY2tldFN0YXRlID0gMDsgfQ0KICAgIH0NCg0KICAgIHJldHVybiBvYmo7DQp9DQoNCi8qKiANCiogQGRlc2NyaXB0aW9uIEludGVsKHIpIEFNVCBXU01BTiBTdGFjaw0KKiBAYXV0aG9yIFlsaWFuIFNhaW50LUhpbGFpcmUNCiogQHZlcnNpb24gdjAuMi4wDQoqLw0KDQovLyBDb25zdHJ1Y3QgYSBNZXNoU2VydmVyIG9iamVjdA0KdmFyIFdzbWFuU3RhY2tDcmVhdGVTZXJ2aWNlID0gZnVuY3Rpb24gKGhvc3QsIHBvcnQsIHVzZXIsIHBhc3MsIHRscywgZXh0cmEpIHsNCiAgICB2YXIgb2JqID0ge307DQogICAgLy9vYmoub25EZWJ1Z01lc3NhZ2UgPSBudWxsOyAgICAgICAgICAvLyBTZXQgdG8gYSBmdW5jdGlvbiBpZiB5b3Ugd2FudCB0byBnZXQgZGVidWcgbWVzc2FnZXMuDQogICAgb2JqLk5leHRNZXNzYWdlSWQgPSAxOyAgICAgICAgICAgICAgLy8gTmV4dCBtZXNzYWdlIG51bWJlciwgdXNlZCB0byBsYWJlbCBXU01BTiBjYWxscy4NCiAgICBvYmouQWRkcmVzcyA9ICcvd3NtYW4nOw0KICAgIG9iai5jb21tID0gQ3JlYXRlV3NtYW5Db21tKGhvc3QsIHBvcnQsIHVzZXIsIHBhc3MsIHRscywgZXh0cmEpOw0KDQogICAgb2JqLlBlcmZvcm1BamF4ID0gZnVuY3Rpb24gKHBvc3RkYXRhLCBjYWxsYmFjaywgdGFnLCBwcmksIG5hbWVzcGFjZXMpIHsNCiAgICAgICAgaWYgKG5hbWVzcGFjZXMgPT0gbnVsbCkgbmFtZXNwYWNlcyA9ICcnOw0KICAgICAgICBvYmouY29tbS5QZXJmb3JtQWpheCgnPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwidXRmLThcIj8+PEVudmVsb3BlIHhtbG5zOnhzaT1cImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlXCIgeG1sbnM6eHNkPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWFcIiB4bWxuczphPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmciIHhtbG5zOnc9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2QiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMy8wNS9zb2FwLWVudmVsb3BlXCIgJyArIG5hbWVzcGFjZXMgKyAnPjxIZWFkZXI+PGE6QWN0aW9uPicgKyBwb3N0ZGF0YSwgZnVuY3Rpb24gKGRhdGEsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBjYWxsYmFjayhvYmosIG51bGwsIHsgSGVhZGVyOiB7IEh0dHBFcnJvcjogc3RhdHVzIH0gfSwgc3RhdHVzLCB0YWcpOyByZXR1cm47IH0NCiAgICAgICAgICAgIHZhciB3c3Jlc3BvbnNlID0gb2JqLlBhcnNlV3NtYW4oZGF0YSk7DQogICAgICAgICAgICBpZiAoIXdzcmVzcG9uc2UgfHwgd3NyZXNwb25zZSA9PSBudWxsKSB7IGNhbGxiYWNrKG9iaiwgbnVsbCwgeyBIZWFkZXI6IHsgSHR0cEVycm9yOiBzdGF0dXMgfSB9LCA2MDEsIHRhZyk7IH0gZWxzZSB7IGNhbGxiYWNrKG9iaiwgd3NyZXNwb25zZS5IZWFkZXJbIlJlc291cmNlVVJJIl0sIHdzcmVzcG9uc2UsIDIwMCwgdGFnKTsgfQ0KICAgICAgICB9LCB0YWcsIHByaSk7DQogICAgfQ0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICAvL29iai5EZWJ1ZyA9IGZ1bmN0aW9uIChtc2cpIHsgLypjb25zb2xlLmxvZyhtc2cpOyovIH0NCg0KICAgIC8vIENhbmNlbCBhbGwgcGVuZGluZyBxdWVyaWVzIHdpdGggZ2l2ZW4gc3RhdHVzDQogICAgb2JqLkNhbmNlbEFsbFF1ZXJpZXMgPSBmdW5jdGlvbiAocykgeyBvYmouY29tbS5DYW5jZWxBbGxRdWVyaWVzKHMpOyB9DQoNCiAgICAvLyBHZXQgdGhlIGxhc3QgZWxlbWVudCBvZiBhIFVSSSBzdHJpbmcNCiAgICBvYmouR2V0TmFtZUZyb21VcmwgPSBmdW5jdGlvbiAocmVzdXJpKSB7DQogICAgICAgIHZhciB4ID0gcmVzdXJpLmxhc3RJbmRleE9mKCIvIik7DQogICAgICAgIHJldHVybiAoeCA9PSAtMSk/cmVzdXJpOnJlc3VyaS5zdWJzdHJpbmcoeCArIDEpOw0KICAgIH0NCg0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiBTdWJzY3JpYmUgb3BlcmF0aW9uDQogICAgb2JqLkV4ZWNTdWJzY3JpYmUgPSBmdW5jdGlvbiAocmVzdXJpLCBkZWxpdmVyeSwgdXJsLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycywgb3BhcXVlLCB1c2VyLCBwYXNzKSB7DQogICAgICAgIHZhciBkaWdlc3QgPSAiIiwgZGlnZXN0MiA9ICIiLCBvcGFxdWUgPSAiIjsNCiAgICAgICAgaWYgKHVzZXIgIT0gbnVsbCAmJiBwYXNzICE9IG51bGwpIHsgZGlnZXN0ID0gJzx0Oklzc3VlZFRva2VucyB4bWxuczp0PSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzAyL3RydXN0IiB4bWxuczpzZT0iaHR0cDovL2RvY3Mub2FzaXMtb3Blbi5vcmcvd3NzLzIwMDQvMDEvb2FzaXMtMjAwNDAxLXdzcy13c3NlY3VyaXR5LXNlY2V4dC0xLjAueHNkIj48dDpSZXF1ZXN0U2VjdXJpdHlUb2tlblJlc3BvbnNlPjx0OlRva2VuVHlwZT5odHRwOi8vZG9jcy5vYXNpcy1vcGVuLm9yZy93c3MvMjAwNC8wMS9vYXNpcy0yMDA0MDEtd3NzLXVzZXJuYW1lLXRva2VuLXByb2ZpbGUtMS4wI1VzZXJuYW1lVG9rZW48L3Q6VG9rZW5UeXBlPjx0OlJlcXVlc3RlZFNlY3VyaXR5VG9rZW4+PHNlOlVzZXJuYW1lVG9rZW4+PHNlOlVzZXJuYW1lPicgKyB1c2VyICsgJzwvc2U6VXNlcm5hbWU+PHNlOlBhc3N3b3JkIFR5cGU9Imh0dHA6Ly9kb2NzLm9hc2lzLW9wZW4ub3JnL3dzcy8yMDA0LzAxL29hc2lzLTIwMDQwMS13c3Mtd3NzZWN1cml0eS1zZWNleHQtMS4wLnhzZCNQYXNzd29yZFRleHQiPicgKyBwYXNzICsgJzwvc2U6UGFzc3dvcmQ+PC9zZTpVc2VybmFtZVRva2VuPjwvdDpSZXF1ZXN0ZWRTZWN1cml0eVRva2VuPjwvdDpSZXF1ZXN0U2VjdXJpdHlUb2tlblJlc3BvbnNlPjwvdDpJc3N1ZWRUb2tlbnM+JzsgZGlnZXN0MiA9ICc8dzpBdXRoIFByb2ZpbGU9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi9zZWNwcm9maWxlL2h0dHAvZGlnZXN0Ii8+JzsgfQ0KICAgICAgICBpZiAob3BhcXVlICE9IG51bGwpIHsgb3BhcXVlID0gJzxhOlJlZmVyZW5jZVBhcmFtZXRlcnM+PG06YXJnPicgKyBvcGFxdWUgKyAnPC9tOmFyZz48L2E6UmVmZXJlbmNlUGFyYW1ldGVycz4nOyB9DQogICAgICAgIGlmIChkZWxpdmVyeSA9PSAnUHVzaFdpdGhBY2snKSB7IGRlbGl2ZXJ5ID0gJ2RtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi9QdXNoV2l0aEFjayc7IH0gZWxzZSBpZiAoZGVsaXZlcnkgPT0gJ1B1c2gnKSB7IGRlbGl2ZXJ5ID0gJ3htbHNvYXAub3JnL3dzLzIwMDQvMDgvZXZlbnRpbmcvRGVsaXZlcnlNb2Rlcy9QdXNoJzsgfQ0KICAgICAgICB2YXIgZGF0YSA9ICJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2V2ZW50aW5nL1N1YnNjcmliZTwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz4iICsgX1B1dE9ialRvU2VsZWN0b3JzWG1sKHNlbGVjdG9ycykgKyBkaWdlc3QgKyAnPC9IZWFkZXI+PEJvZHk+PGU6U3Vic2NyaWJlPjxlOkRlbGl2ZXJ5IE1vZGU9Imh0dHA6Ly9zY2hlbWFzLicgKyBkZWxpdmVyeSArICciPjxlOk5vdGlmeVRvPjxhOkFkZHJlc3M+JyArIHVybCArICc8L2E6QWRkcmVzcz4nICsgb3BhcXVlICsgJzwvZTpOb3RpZnlUbz4nICsgZGlnZXN0MiArICc8L2U6RGVsaXZlcnk+PC9lOlN1YnNjcmliZT4nOw0KICAgICAgICBvYmouUGVyZm9ybUFqYXgoZGF0YSArICI8L0JvZHk+PC9FbnZlbG9wZT4iLCBjYWxsYmFjaywgdGFnLCBwcmksICd4bWxuczplPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2V2ZW50aW5nIiB4bWxuczptPSJodHRwOi8veC5jb20iJyk7DQogICAgfQ0KDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOIFVuU3Vic2NyaWJlIG9wZXJhdGlvbg0KICAgIG9iai5FeGVjVW5TdWJzY3JpYmUgPSBmdW5jdGlvbiAocmVzdXJpLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycykgew0KICAgICAgICB2YXIgZGF0YSA9ICJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2V2ZW50aW5nL1Vuc3Vic2NyaWJlPC9hOkFjdGlvbj48YTpUbz4iICsgb2JqLkFkZHJlc3MgKyAiPC9hOlRvPjx3OlJlc291cmNlVVJJPiIgKyByZXN1cmkgKyAiPC93OlJlc291cmNlVVJJPjxhOk1lc3NhZ2VJRD4iICsgKG9iai5OZXh0TWVzc2FnZUlkKyspICsgIjwvYTpNZXNzYWdlSUQ+PGE6UmVwbHlUbz48YTpBZGRyZXNzPmh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZy9yb2xlL2Fub255bW91czwvYTpBZGRyZXNzPjwvYTpSZXBseVRvPiIgKyBfUHV0T2JqVG9TZWxlY3RvcnNYbWwoc2VsZWN0b3JzKSArICc8L0hlYWRlcj48Qm9keT48ZTpVbnN1YnNjcmliZS8+JzsNCiAgICAgICAgb2JqLlBlcmZvcm1BamF4KGRhdGEgKyAiPC9Cb2R5PjwvRW52ZWxvcGU+IiwgY2FsbGJhY2ssIHRhZywgcHJpLCAneG1sbnM6ZT0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9ldmVudGluZyInKTsNCiAgICB9DQoNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gUFVUIG9wZXJhdGlvbg0KICAgIG9iai5FeGVjUHV0ID0gZnVuY3Rpb24gKHJlc3VyaSwgcHV0b2JqLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycykgew0KICAgICAgICB2YXIgZGF0YSA9ICJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA5L3RyYW5zZmVyL1B1dDwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjAuMDAwUzwvdzpPcGVyYXRpb25UaW1lb3V0PiIgKyBfUHV0T2JqVG9TZWxlY3RvcnNYbWwoc2VsZWN0b3JzKSArICc8L0hlYWRlcj48Qm9keT4nICsgX1B1dE9ialRvQm9keVhtbChyZXN1cmksIHB1dG9iaik7DQogICAgICAgIG9iai5QZXJmb3JtQWpheChkYXRhICsgIjwvQm9keT48L0VudmVsb3BlPiIsIGNhbGxiYWNrLCB0YWcsIHByaSk7DQogICAgfQ0KCQkNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gQ1JFQVRFIG9wZXJhdGlvbg0KICAgIG9iai5FeGVjQ3JlYXRlID0gZnVuY3Rpb24gKHJlc3VyaSwgcHV0b2JqLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycykgew0KICAgICAgICB2YXIgb2JqbmFtZSA9IG9iai5HZXROYW1lRnJvbVVybChyZXN1cmkpOw0KICAgICAgICB2YXIgZGF0YSA9ICJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA5L3RyYW5zZmVyL0NyZWF0ZTwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjBTPC93Ok9wZXJhdGlvblRpbWVvdXQ+IiArIF9QdXRPYmpUb1NlbGVjdG9yc1htbChzZWxlY3RvcnMpICsgIjwvSGVhZGVyPjxCb2R5PjxnOiIgKyBvYmpuYW1lICsgIiB4bWxuczpnPVwiIiArIHJlc3VyaSArICJcIj4iOw0KICAgICAgICBmb3IgKHZhciBuIGluIHB1dG9iaikgeyBkYXRhICs9ICI8ZzoiICsgbiArICI+IiArIHB1dG9ialtuXSArICI8L2c6IiArIG4gKyAiPiIgfSANCiAgICAgICAgb2JqLlBlcmZvcm1BamF4KGRhdGEgKyAiPC9nOiIgKyBvYmpuYW1lICsgIj48L0JvZHk+PC9FbnZlbG9wZT4iLCBjYWxsYmFjaywgdGFnLCBwcmkpOw0KICAgIH0NCg0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiBERUxFVEUgb3BlcmF0aW9uDQogICAgb2JqLkV4ZWNEZWxldGUgPSBmdW5jdGlvbiAocmVzdXJpLCBwdXRvYmosIGNhbGxiYWNrLCB0YWcsIHByaSkgew0KICAgICAgICB2YXIgZGF0YSA9ICJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA5L3RyYW5zZmVyL0RlbGV0ZTwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjBTPC93Ok9wZXJhdGlvblRpbWVvdXQ+IiArIF9QdXRPYmpUb1NlbGVjdG9yc1htbChwdXRvYmopICsgIjwvSGVhZGVyPjxCb2R5IC8+PC9FbnZlbG9wZT4iOw0KICAgICAgICBvYmouUGVyZm9ybUFqYXgoZGF0YSwgY2FsbGJhY2ssIHRhZywgcHJpKTsNCiAgICB9DQoNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gR0VUIG9wZXJhdGlvbg0KICAgIG9iai5FeGVjR2V0ID0gZnVuY3Rpb24gKHJlc3VyaSwgY2FsbGJhY2ssIHRhZywgcHJpKSB7DQogICAgICAgIG9iai5QZXJmb3JtQWpheCgiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOS90cmFuc2Zlci9HZXQ8L2E6QWN0aW9uPjxhOlRvPiIgKyBvYmouQWRkcmVzcyArICI8L2E6VG8+PHc6UmVzb3VyY2VVUkk+IiArIHJlc3VyaSArICI8L3c6UmVzb3VyY2VVUkk+PGE6TWVzc2FnZUlEPiIgKyAob2JqLk5leHRNZXNzYWdlSWQrKykgKyAiPC9hOk1lc3NhZ2VJRD48YTpSZXBseVRvPjxhOkFkZHJlc3M+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nL3JvbGUvYW5vbnltb3VzPC9hOkFkZHJlc3M+PC9hOlJlcGx5VG8+PHc6T3BlcmF0aW9uVGltZW91dD5QVDYwUzwvdzpPcGVyYXRpb25UaW1lb3V0PjwvSGVhZGVyPjxCb2R5IC8+PC9FbnZlbG9wZT4iLCBjYWxsYmFjaywgdGFnLCBwcmkpOw0KICAgIH0NCg0KCS8vIFBlcmZvcm0gYSBXU01BTiBtZXRob2QgY2FsbCBvcGVyYXRpb24NCiAgICBvYmouRXhlY01ldGhvZCA9IGZ1bmN0aW9uIChyZXN1cmksIG1ldGhvZCwgYXJncywgY2FsbGJhY2ssIHRhZywgcHJpLCBzZWxlY3RvcnMpIHsNCiAgICAgICAgdmFyIGFyZ3N4bWwgPSAiIjsNCiAgICAgICAgZm9yICh2YXIgaSBpbiBhcmdzKSB7IGlmIChhcmdzW2ldICE9IG51bGwpIHsgaWYgKEFycmF5LmlzQXJyYXkoYXJnc1tpXSkpIHsgZm9yICh2YXIgeCBpbiBhcmdzW2ldKSB7IGFyZ3N4bWwgKz0gIjxyOiIgKyBpICsgIj4iICsgYXJnc1tpXVt4XSArICI8L3I6IiArIGkgKyAiPiI7IH0gfSBlbHNlIHsgYXJnc3htbCArPSAiPHI6IiArIGkgKyAiPiIgKyBhcmdzW2ldICsgIjwvcjoiICsgaSArICI+IjsgfSB9IH0NCiAgICAgICAgb2JqLkV4ZWNNZXRob2RYbWwocmVzdXJpLCBtZXRob2QsIGFyZ3N4bWwsIGNhbGxiYWNrLCB0YWcsIHByaSwgc2VsZWN0b3JzKTsNCiAgICB9DQoJDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOIG1ldGhvZCBjYWxsIG9wZXJhdGlvbi4gVGhlIGFyZ3VtZW50cyBhcmUgYWxyZWFkeSBmb3JtYXR0ZWQgaW4gWE1MLg0KICAgIG9iai5FeGVjTWV0aG9kWG1sID0gZnVuY3Rpb24gKHJlc3VyaSwgbWV0aG9kLCBhcmdzeG1sLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycykgew0KICAgICAgICBvYmouUGVyZm9ybUFqYXgocmVzdXJpICsgIi8iICsgbWV0aG9kICsgIjwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjBTPC93Ok9wZXJhdGlvblRpbWVvdXQ+IiArIF9QdXRPYmpUb1NlbGVjdG9yc1htbChzZWxlY3RvcnMpICsgIjwvSGVhZGVyPjxCb2R5PjxyOiIgKyBtZXRob2QgKyAnX0lOUFVUJyArICIgeG1sbnM6cj1cIiIgKyByZXN1cmkgKyAiXCI+IiArIGFyZ3N4bWwgKyAiPC9yOiIgKyBtZXRob2QgKyAiX0lOUFVUPjwvQm9keT48L0VudmVsb3BlPiIsIGNhbGxiYWNrLCB0YWcsIHByaSk7DQogICAgfQ0KDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOIEVOVU0gb3BlcmF0aW9uDQogICAgb2JqLkV4ZWNFbnVtID0gZnVuY3Rpb24gKHJlc3VyaSwgY2FsbGJhY2ssIHRhZywgcHJpKSB7DQogICAgICAgIG9iai5QZXJmb3JtQWpheCgiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOS9lbnVtZXJhdGlvbi9FbnVtZXJhdGU8L2E6QWN0aW9uPjxhOlRvPiIgKyBvYmouQWRkcmVzcyArICI8L2E6VG8+PHc6UmVzb3VyY2VVUkk+IiArIHJlc3VyaSArICI8L3c6UmVzb3VyY2VVUkk+PGE6TWVzc2FnZUlEPiIgKyAob2JqLk5leHRNZXNzYWdlSWQrKykgKyAiPC9hOk1lc3NhZ2VJRD48YTpSZXBseVRvPjxhOkFkZHJlc3M+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nL3JvbGUvYW5vbnltb3VzPC9hOkFkZHJlc3M+PC9hOlJlcGx5VG8+PHc6T3BlcmF0aW9uVGltZW91dD5QVDYwUzwvdzpPcGVyYXRpb25UaW1lb3V0PjwvSGVhZGVyPjxCb2R5PjxFbnVtZXJhdGUgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA5L2VudW1lcmF0aW9uXCIgLz48L0JvZHk+PC9FbnZlbG9wZT4iLCBjYWxsYmFjaywgdGFnLCBwcmkpOw0KICAgIH0NCg0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiBQVUxMIG9wZXJhdGlvbg0KICAgIG9iai5FeGVjUHVsbCA9IGZ1bmN0aW9uIChyZXN1cmksIGVudW1jdHgsIGNhbGxiYWNrLCB0YWcsIHByaSkgew0KICAgICAgICBvYmouUGVyZm9ybUFqYXgoImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDkvZW51bWVyYXRpb24vUHVsbDwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjBTPC93Ok9wZXJhdGlvblRpbWVvdXQ+PC9IZWFkZXI+PEJvZHk+PFB1bGwgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA5L2VudW1lcmF0aW9uXCI+PEVudW1lcmF0aW9uQ29udGV4dD4iICsgZW51bWN0eCArICI8L0VudW1lcmF0aW9uQ29udGV4dD48L1B1bGw+PC9Cb2R5PjwvRW52ZWxvcGU+IiwgY2FsbGJhY2ssIHRhZywgcHJpKTsgLy8gPC9FbnVtZXJhdGlvbkNvbnRleHQ+LS08TWF4RWxlbWVudHM+OTk5PC9NYXhFbGVtZW50cz48TWF4Q2hhcmFjdGVycz45OTk5OTwvTWF4Q2hhcmFjdGVycz4tLTwvUHVsbD4NCiAgICB9DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIG9iai5QYXJzZVdzbWFuID0gZnVuY3Rpb24gKHhtbCkgew0KICAgICAgICB0cnkgew0KICAgICAgICAgICAgaWYgKCF4bWwuY2hpbGROb2RlcykgeG1sID0gX3R1cm5Ub1htbCh4bWwpOw0KICAgICAgICAgICAgdmFyIHIgPSB7IEhlYWRlcjp7fSB9LCBoZWFkZXIgPSB4bWwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIkhlYWRlciIpWzBdLCB0Ow0KICAgICAgICAgICAgaWYgKCFoZWFkZXIpIGhlYWRlciA9IHhtbC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYTpIZWFkZXIiKVswXTsNCiAgICAgICAgICAgIGlmICghaGVhZGVyKSByZXR1cm4gbnVsbDsNCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGVhZGVyLmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgICAgICB2YXIgY2hpbGQgPSBoZWFkZXIuY2hpbGROb2Rlc1tpXTsNCiAgICAgICAgICAgICAgICByLkhlYWRlcltjaGlsZC5sb2NhbE5hbWVdID0gY2hpbGQudGV4dENvbnRlbnQ7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB2YXIgYm9keSA9IHhtbC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiQm9keSIpWzBdOw0KICAgICAgICAgICAgaWYgKCFib2R5KSBib2R5ID0geG1sLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhOkJvZHkiKVswXTsNCiAgICAgICAgICAgIGlmICghYm9keSkgcmV0dXJuIG51bGw7DQogICAgICAgICAgICBpZiAoYm9keS5jaGlsZE5vZGVzLmxlbmd0aCA+IDApIHsNCiAgICAgICAgICAgICAgICB0ID0gYm9keS5jaGlsZE5vZGVzWzBdLmxvY2FsTmFtZTsNCiAgICAgICAgICAgICAgICBpZiAodC5pbmRleE9mKCJfT1VUUFVUIikgPT0gdC5sZW5ndGggLSA3KSB7IHQgPSB0LnN1YnN0cmluZygwLCB0Lmxlbmd0aCAtIDcpOyB9DQogICAgICAgICAgICAgICAgci5IZWFkZXJbJ01ldGhvZCddID0gdDsNCiAgICAgICAgICAgICAgICByLkJvZHkgPSBfUGFyc2VXc21hblJlYyhib2R5LmNoaWxkTm9kZXNbMF0pOw0KCQkgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIHI7DQogICAgICAgIH0gY2F0Y2ggKGUpIHsNCiAgICAgICAgICAgIGNvbnNvbGUubG9nKCJVbmFibGUgdG8gcGFyc2UgWE1MOiAiICsgeG1sKTsNCiAgICAgICAgICAgIHJldHVybiBudWxsOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICBmdW5jdGlvbiBfUGFyc2VXc21hblJlYyhub2RlKSB7DQogICAgICAgIHZhciBkYXRhLCByID0ge307DQogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5jaGlsZE5vZGVzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICB2YXIgY2hpbGQgPSBub2RlLmNoaWxkTm9kZXNbaV07DQogICAgICAgICAgICBpZiAoKGNoaWxkLmNoaWxkRWxlbWVudENvdW50ID09IG51bGwpIHx8IChjaGlsZC5jaGlsZEVsZW1lbnRDb3VudCA9PSAwKSkgeyBkYXRhID0gY2hpbGQudGV4dENvbnRlbnQ7IH0gZWxzZSB7IGRhdGEgPSBfUGFyc2VXc21hblJlYyhjaGlsZCk7IH0NCiAgICAgICAgICAgIGlmIChkYXRhID09ICd0cnVlJykgZGF0YSA9IHRydWU7IC8vIENvbnZlcnQgJ3RydWUnIGludG8gdHJ1ZQ0KICAgICAgICAgICAgaWYgKGRhdGEgPT0gJ2ZhbHNlJykgZGF0YSA9IGZhbHNlOyAvLyBDb252ZXJ0ICdmYWxzZScgaW50byBmYWxzZQ0KICAgICAgICAgICAgaWYgKChwYXJzZUludChkYXRhKSArICcnKSA9PT0gZGF0YSkgZGF0YSA9IHBhcnNlSW50KGRhdGEpOyAvLyBDb252ZXJ0IGludGVnZXJzDQoNCiAgICAgICAgICAgIHZhciBjaGlsZE9iaiA9IGRhdGE7DQogICAgICAgICAgICBpZiAoKGNoaWxkLmF0dHJpYnV0ZXMgIT0gbnVsbCkgJiYgKGNoaWxkLmF0dHJpYnV0ZXMubGVuZ3RoID4gMCkpIHsNCgkJCQljaGlsZE9iaiA9IHsgJ1ZhbHVlJzogZGF0YSB9Ow0KCQkJCWZvcih2YXIgaiA9IDA7IGogPCBjaGlsZC5hdHRyaWJ1dGVzLmxlbmd0aDsgaisrKSB7DQoJCQkJCWNoaWxkT2JqWydAJyArIGNoaWxkLmF0dHJpYnV0ZXNbal0ubmFtZV0gPSBjaGlsZC5hdHRyaWJ1dGVzW2pdLnZhbHVlOw0KCQkJCX0NCgkJCX0NCgkJCQ0KICAgICAgICAgICAgaWYgKHJbY2hpbGQubG9jYWxOYW1lXSBpbnN0YW5jZW9mIEFycmF5KSB7IHJbY2hpbGQubG9jYWxOYW1lXS5wdXNoKGNoaWxkT2JqKTsgfQ0KICAgICAgICAgICAgZWxzZSBpZiAocltjaGlsZC5sb2NhbE5hbWVdID09IG51bGwpIHsgcltjaGlsZC5sb2NhbE5hbWVdID0gY2hpbGRPYmo7IH0NCiAgICAgICAgICAgIGVsc2UgeyByW2NoaWxkLmxvY2FsTmFtZV0gPSBbcltjaGlsZC5sb2NhbE5hbWVdLCBjaGlsZE9ial07IH0NCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gcjsNCiAgICB9DQoNCiAgICBmdW5jdGlvbiBfUHV0T2JqVG9Cb2R5WG1sKHJlc3VyaSwgcHV0T2JqKSB7DQogICAgICAgIGlmICghcmVzdXJpIHx8IHB1dE9iaiA9PSBudWxsKSByZXR1cm4gJyc7DQoJCXZhciBvYmpuYW1lID0gb2JqLkdldE5hbWVGcm9tVXJsKHJlc3VyaSk7DQoJCXZhciByZXN1bHQgPSAnPHI6JyArIG9iam5hbWUgKyAnIHhtbG5zOnI9IicgKyByZXN1cmkgKyAnIj4nOw0KDQoJCWZvciAodmFyIHByb3AgaW4gcHV0T2JqKSB7DQoJCQlpZiAoIXB1dE9iai5oYXNPd25Qcm9wZXJ0eShwcm9wKSB8fCBwcm9wLmluZGV4T2YoJ19fJykgPT09IDAgfHwgcHJvcC5pbmRleE9mKCdAJykgPT09IDApIGNvbnRpbnVlOw0KCQkJaWYgKHB1dE9ialtwcm9wXSA9PSBudWxsIHx8IHR5cGVvZiBwdXRPYmpbcHJvcF0gPT09ICdmdW5jdGlvbicpIGNvbnRpbnVlOw0KCQkJaWYgKHR5cGVvZiBwdXRPYmpbcHJvcF0gPT09ICdvYmplY3QnICYmIHB1dE9ialtwcm9wXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddKSB7DQoJCQkJcmVzdWx0ICs9ICc8cjonICsgcHJvcCArICc+PGE6QWRkcmVzcz4nICsgcHV0T2JqW3Byb3BdLkFkZHJlc3MgKyAnPC9hOkFkZHJlc3M+PGE6UmVmZXJlbmNlUGFyYW1ldGVycz48dzpSZXNvdXJjZVVSST4nICsgcHV0T2JqW3Byb3BdWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bIlJlc291cmNlVVJJIl0gKyAnPC93OlJlc291cmNlVVJJPjx3OlNlbGVjdG9yU2V0Pic7DQoJCQkJdmFyIHNlbGVjdG9yQXJyYXkgPSBwdXRPYmpbcHJvcF1bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXTsNCgkJCQlpZiAoQXJyYXkuaXNBcnJheShzZWxlY3RvckFycmF5KSkgew0KCQkJCQlmb3IgKHZhciBpPTA7IGk8IHNlbGVjdG9yQXJyYXkubGVuZ3RoOyBpKyspIHsNCgkJCQkJCXJlc3VsdCArPSAnPHc6U2VsZWN0b3InICsgX09iamVjdFRvWG1sQXR0cmlidXRlcyhzZWxlY3RvckFycmF5W2ldKSArICc+JyArIHNlbGVjdG9yQXJyYXlbaV1bJ1ZhbHVlJ10gKyAnPC93OlNlbGVjdG9yPic7DQoJCQkJCX0NCgkJCQl9DQoJCQkJZWxzZSB7DQoJCQkJCXJlc3VsdCArPSAnPHc6U2VsZWN0b3InICsgX09iamVjdFRvWG1sQXR0cmlidXRlcyhzZWxlY3RvckFycmF5KSArICc+JyArIHNlbGVjdG9yQXJyYXlbJ1ZhbHVlJ10gKyAnPC93OlNlbGVjdG9yPic7DQoJCQkJfQ0KCQkJCXJlc3VsdCArPSAnPC93OlNlbGVjdG9yU2V0PjwvYTpSZWZlcmVuY2VQYXJhbWV0ZXJzPjwvcjonICsgcHJvcCArICc+JzsNCgkJCX0NCgkJCWVsc2Ugew0KCQkJICAgIGlmIChBcnJheS5pc0FycmF5KHB1dE9ialtwcm9wXSkpIHsNCgkJCSAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwdXRPYmpbcHJvcF0ubGVuZ3RoOyBpKyspIHsNCgkJCSAgICAgICAgICAgIHJlc3VsdCArPSAnPHI6JyArIHByb3AgKyAnPicgKyBwdXRPYmpbcHJvcF1baV0udG9TdHJpbmcoKSArICc8L3I6JyArIHByb3AgKyAnPic7DQoJCQkgICAgICAgIH0NCgkJCSAgICB9IGVsc2Ugew0KCQkJICAgICAgICByZXN1bHQgKz0gJzxyOicgKyBwcm9wICsgJz4nICsgcHV0T2JqW3Byb3BdLnRvU3RyaW5nKCkgKyAnPC9yOicgKyBwcm9wICsgJz4nOw0KCQkJICAgIH0NCgkJCX0NCgkJfQ0KDQoJCXJlc3VsdCArPSAnPC9yOicgKyBvYmpuYW1lICsgJz4nOw0KCQlyZXR1cm4gcmVzdWx0Ow0KCX0NCg0KCS8qIA0KCWNvbnZlcnQgDQoJCXsgQE5hbWU6ICdJbnN0YW5jZUlEJywgQEF0dHJOYW1lOiAnQXR0cmlidXRlIFZhbHVlJ30NCglpbnRvDQoJCScgTmFtZT0iSW5zdGFuY2VJRCIgQXR0ck5hbWU9IkF0dHJpYnV0ZSBWYWx1ZSIgJw0KCSovDQogICAgZnVuY3Rpb24gX09iamVjdFRvWG1sQXR0cmlidXRlcyhvYmpXaXRoQXR0cmlidXRlcykgew0KCQlpZighb2JqV2l0aEF0dHJpYnV0ZXMpIHJldHVybiAnJzsNCgkJdmFyIHJlc3VsdCA9ICcnOw0KCQlmb3IgKHZhciBwcm9wTmFtZSBpbiBvYmpXaXRoQXR0cmlidXRlcykgew0KCQkJaWYgKCFvYmpXaXRoQXR0cmlidXRlcy5oYXNPd25Qcm9wZXJ0eShwcm9wTmFtZSkgfHwgcHJvcE5hbWUuaW5kZXhPZignQCcpICE9PSAwKSBjb250aW51ZTsNCgkJCXJlc3VsdCArPSAnICcgKyBwcm9wTmFtZS5zdWJzdHJpbmcoMSkgKyAnPSInICsgb2JqV2l0aEF0dHJpYnV0ZXNbcHJvcE5hbWVdICsgJyInOw0KCQl9DQoJCXJldHVybiByZXN1bHQ7DQoJfQ0KDQogICAgZnVuY3Rpb24gX1B1dE9ialRvU2VsZWN0b3JzWG1sKHNlbGVjdG9yU2V0KSB7DQogICAgICAgIGlmICghc2VsZWN0b3JTZXQpIHJldHVybiAnJzsNCiAgICAgICAgaWYgKHR5cGVvZiBzZWxlY3RvclNldCA9PSAnc3RyaW5nJykgcmV0dXJuIHNlbGVjdG9yU2V0Ow0KICAgICAgICBpZiAoc2VsZWN0b3JTZXRbJ0luc3RhbmNlSUQnXSkgcmV0dXJuICI8dzpTZWxlY3RvclNldD48dzpTZWxlY3RvciBOYW1lPVwiSW5zdGFuY2VJRFwiPiIgKyBzZWxlY3RvclNldFsnSW5zdGFuY2VJRCddICsgIjwvdzpTZWxlY3Rvcj48L3c6U2VsZWN0b3JTZXQ+IjsNCgkJdmFyIHJlc3VsdCA9ICc8dzpTZWxlY3RvclNldD4nOw0KCQlmb3IodmFyIHByb3BOYW1lIGluIHNlbGVjdG9yU2V0KSB7DQoJCSAgICBpZiAoIXNlbGVjdG9yU2V0Lmhhc093blByb3BlcnR5KHByb3BOYW1lKSkgY29udGludWU7DQoJCSAgICByZXN1bHQgKz0gJzx3OlNlbGVjdG9yIE5hbWU9IicgKyBwcm9wTmFtZSArICciPic7DQoJCSAgICBpZiAoc2VsZWN0b3JTZXRbcHJvcE5hbWVdWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ10pIHsNCgkJICAgICAgICByZXN1bHQgKz0gJzxhOkVuZHBvaW50UmVmZXJlbmNlPic7DQoJCSAgICAgICAgcmVzdWx0ICs9ICc8YTpBZGRyZXNzPicgKyBzZWxlY3RvclNldFtwcm9wTmFtZV1bJ0FkZHJlc3MnXSArICc8L2E6QWRkcmVzcz48YTpSZWZlcmVuY2VQYXJhbWV0ZXJzPjx3OlJlc291cmNlVVJJPicgKyBzZWxlY3RvclNldFtwcm9wTmFtZV1bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnUmVzb3VyY2VVUkknXSArICc8L3c6UmVzb3VyY2VVUkk+PHc6U2VsZWN0b3JTZXQ+JzsNCgkJICAgICAgICB2YXIgc2VsZWN0b3JBcnJheSA9IHNlbGVjdG9yU2V0W3Byb3BOYW1lXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddOw0KCQkgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHNlbGVjdG9yQXJyYXkpKSB7DQoJCSAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2VsZWN0b3JBcnJheS5sZW5ndGg7IGkrKykgew0KCQkgICAgICAgICAgICAgICAgcmVzdWx0ICs9ICc8dzpTZWxlY3RvcicgKyBfT2JqZWN0VG9YbWxBdHRyaWJ1dGVzKHNlbGVjdG9yQXJyYXlbaV0pICsgJz4nICsgc2VsZWN0b3JBcnJheVtpXVsnVmFsdWUnXSArICc8L3c6U2VsZWN0b3I+JzsNCgkJICAgICAgICAgICAgfQ0KCQkgICAgICAgIH0NCgkJICAgICAgICBlbHNlIHsNCgkJICAgICAgICAgICAgcmVzdWx0ICs9ICc8dzpTZWxlY3RvcicgKyBfT2JqZWN0VG9YbWxBdHRyaWJ1dGVzKHNlbGVjdG9yQXJyYXkpICsgJz4nICsgc2VsZWN0b3JBcnJheVsnVmFsdWUnXSArICc8L3c6U2VsZWN0b3I+JzsNCgkJICAgICAgICB9DQoJCSAgICAgICAgcmVzdWx0ICs9ICc8L3c6U2VsZWN0b3JTZXQ+PC9hOlJlZmVyZW5jZVBhcmFtZXRlcnM+PC9hOkVuZHBvaW50UmVmZXJlbmNlPic7DQoJCSAgICB9IGVsc2Ugew0KCQkgICAgICAgIHJlc3VsdCArPSBzZWxlY3RvclNldFtwcm9wTmFtZV07DQoJCSAgICB9DQoJCQlyZXN1bHQgKz0gJzwvdzpTZWxlY3Rvcj4nOw0KCQl9DQoJCXJlc3VsdCArPSAnPC93OlNlbGVjdG9yU2V0Pic7DQoJCXJldHVybiByZXN1bHQ7DQoJfQ0KDQogICAgZnVuY3Rpb24gX3R1cm5Ub1htbCh0ZXh0KSB7DQogICAgICAgIA0KICAgICAgICAvLyBOb2RlSlMgZGV0ZWN0aW9uDQogICAgICAgIHZhciBpc05vZGUgPSBuZXcgRnVuY3Rpb24oInRyeSB7cmV0dXJuIHRoaXM9PT1nbG9iYWw7fWNhdGNoKGUpe3JldHVybiBmYWxzZTt9Iik7DQogICAgICAgIGlmIChpc05vZGUoKSkgew0KICAgICAgICAgICAgdmFyIFhET01QYXJzZXIgPSByZXF1aXJlKCd4bWxkb20nKS5ET01QYXJzZXI7DQogICAgICAgICAgICByZXR1cm4gbmV3IFhET01QYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcodGV4dCwgInRleHQveG1sIik7DQogICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAod2luZG93LkRPTVBhcnNlcikgew0KICAgICAgICAgICAgcmV0dXJuIG5ldyBET01QYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcodGV4dCwgInRleHQveG1sIik7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAvLyBJbnRlcm5ldCBFeHBsb3Jlcg0KICAgICAgICAgICAgdmFyIHhtbERvYyA9IG5ldyBBY3RpdmVYT2JqZWN0KCJNaWNyb3NvZnQuWE1MRE9NIik7DQogICAgICAgICAgICB4bWxEb2MuYXN5bmMgPSBmYWxzZTsNCiAgICAgICAgICAgIHhtbERvYy5sb2FkWE1MKHRleHQpOw0KICAgICAgICAgICAgcmV0dXJuIHhtbERvYzsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIC8qDQogICAgLy8gVGhpcyBpcyBhIGRyb3AtaW4gcmVwbGFjZW1lbnQgdG8gX3R1cm5Ub1htbCgpIHRoYXQgd29ya3Mgd2l0aG91dCB4bWwgcGFyc2VyIGRlcGVuZGVuY3kuDQogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFycmF5LnByb3RvdHlwZSwgInBlZWsiLCB7IHZhbHVlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAodGhpcy5sZW5ndGggPiAwID8gdGhpc1t0aGlzLmxlbmd0aCAtIDFdIDogbnVsbCk7IH0gfSk7CiAgICBmdW5jdGlvbiBfdHJlZUJ1aWxkZXIoKSB7DQogICAgICAgIHRoaXMudHJlZSA9IFtdOwogICAgICAgIHRoaXMucHVzaCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7IHRoaXMudHJlZS5wdXNoKGVsZW1lbnQpOyB9OwogICAgICAgIHRoaXMucG9wID0gZnVuY3Rpb24gKCkgeyB2YXIgZWxlbWVudCA9IHRoaXMudHJlZS5wb3AoKTsgaWYgKHRoaXMudHJlZS5sZW5ndGggPiAwKSB7IHZhciB4ID0gdGhpcy50cmVlLnBlZWsoKTsgeC5jaGlsZE5vZGVzLnB1c2goZWxlbWVudCk7IHguY2hpbGRFbGVtZW50Q291bnQgPSB4LmNoaWxkTm9kZXMubGVuZ3RoOyB9IHJldHVybiAoZWxlbWVudCk7IH07CiAgICAgICAgdGhpcy5wZWVrID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gKHRoaXMudHJlZS5wZWVrKCkpOyB9CiAgICAgICAgdGhpcy5hZGROYW1lc3BhY2UgPSBmdW5jdGlvbiAocHJlZml4LCBuYW1lc3BhY2UpIHsgdGhpcy50cmVlLnBlZWsoKS5uc1RhYmxlW3ByZWZpeF0gPSBuYW1lc3BhY2U7IGlmICh0aGlzLnRyZWUucGVlaygpLmF0dHJpYnV0ZXMubGVuZ3RoID4gMCkgeyBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudHJlZS5wZWVrKCkuYXR0cmlidXRlczsgKytpKSB7IHZhciBhID0gdGhpcy50cmVlLnBlZWsoKS5hdHRyaWJ1dGVzW2ldOyBpZiAocHJlZml4ID09ICcqJyAmJiBhLm5hbWUgPT0gYS5sb2NhbE5hbWUpIHsgYS5uYW1lc3BhY2UgPSBuYW1lc3BhY2U7IH0gZWxzZSBpZiAocHJlZml4ICE9ICcqJyAmJiBhLm5hbWUgIT0gYS5sb2NhbE5hbWUpIHsgdmFyIHBmeCA9IGEubmFtZS5zcGxpdCgnOicpWzBdOyBpZiAocGZ4ID09IHByZWZpeCkgeyBhLm5hbWVzcGFjZSA9IG5hbWVzcGFjZTsgfSB9IH0gfSB9CiAgICAgICAgdGhpcy5nZXROYW1lc3BhY2UgPSBmdW5jdGlvbiAocHJlZml4KSB7IGZvciAodmFyIGkgPSB0aGlzLnRyZWUubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHsgaWYgKHRoaXMudHJlZVtpXS5uc1RhYmxlW3ByZWZpeF0gIT0gbnVsbCkgeyByZXR1cm4gKHRoaXMudHJlZVtpXS5uc1RhYmxlW3ByZWZpeF0pOyB9IH0gcmV0dXJuIG51bGw7IH0NCiAgICB9CiAgICBmdW5jdGlvbiBfdHVyblRvWG1sKHRleHQpIHsgaWYgKHRleHQgPT0gbnVsbCkgcmV0dXJuIG51bGw7IHJldHVybiAoeyBjaGlsZE5vZGVzOiBbX3R1cm5Ub1htbFJlYyh0ZXh0KV0sIGdldEVsZW1lbnRzQnlUYWdOYW1lOiBfZ2V0RWxlbWVudHNCeVRhZ05hbWUsIGdldENoaWxkRWxlbWVudHNCeVRhZ05hbWU6IF9nZXRDaGlsZEVsZW1lbnRzQnlUYWdOYW1lLCBnZXRFbGVtZW50c0J5VGFnTmFtZU5TOiBfZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyB9KTsgfQogICAgZnVuY3Rpb24gX2dldEVsZW1lbnRzQnlUYWdOYW1lTlMobnMsIG5hbWUpIHsgdmFyIHJldCA9IFtdOyBfeG1sVHJhdmVyc2VBbGxSZWModGhpcy5jaGlsZE5vZGVzLCBmdW5jdGlvbiAobm9kZSkgeyBpZiAobm9kZS5sb2NhbE5hbWUgPT0gbmFtZSAmJiAobm9kZS5uYW1lc3BhY2UgPT0gbnMgfHwgbnMgPT0gJyonKSkgeyByZXQucHVzaChub2RlKTsgfSB9KTsgcmV0dXJuIHJldDsgfQogICAgZnVuY3Rpb24gX2dldEVsZW1lbnRzQnlUYWdOYW1lKG5hbWUpIHsgdmFyIHJldCA9IFtdOyBfeG1sVHJhdmVyc2VBbGxSZWModGhpcy5jaGlsZE5vZGVzLCBmdW5jdGlvbiAobm9kZSkgeyBpZiAobm9kZS5sb2NhbE5hbWUgPT0gbmFtZSkgeyByZXQucHVzaChub2RlKTsgfSB9KTsgcmV0dXJuIHJldDsgfQogICAgZnVuY3Rpb24gX2dldENoaWxkRWxlbWVudHNCeVRhZ05hbWUobmFtZSkgeyB2YXIgcmV0ID0gW107IGlmICh0aGlzLmNoaWxkTm9kZXMgIT0gbnVsbCkgeyBmb3IgKHZhciBub2RlIGluIHRoaXMuY2hpbGROb2RlcykgeyBpZiAodGhpcy5jaGlsZE5vZGVzW25vZGVdLmxvY2FsTmFtZSA9PSBuYW1lKSB7IHJldC5wdXNoKHRoaXMuY2hpbGROb2Rlc1tub2RlXSk7IH0gfSB9IHJldHVybiAocmV0KTsgfQogICAgZnVuY3Rpb24gX2dldENoaWxkRWxlbWVudHNCeVRhZ05hbWVOUyhucywgbmFtZSkgeyB2YXIgcmV0ID0gW107IGlmICh0aGlzLmNoaWxkTm9kZXMgIT0gbnVsbCkgeyBmb3IgKHZhciBub2RlIGluIHRoaXMuY2hpbGROb2RlcykgeyBpZiAodGhpcy5jaGlsZE5vZGVzW25vZGVdLmxvY2FsTmFtZSA9PSBuYW1lICYmIChucyA9PSAnKicgfHwgdGhpcy5jaGlsZE5vZGVzW25vZGVdLm5hbWVzcGFjZSA9PSBucykpIHsgcmV0LnB1c2godGhpcy5jaGlsZE5vZGVzW25vZGVdKTsgfSB9IH0gcmV0dXJuIChyZXQpOyB9CiAgICBmdW5jdGlvbiBfeG1sVHJhdmVyc2VBbGxSZWMobm9kZXMsIGZ1bmMpIHsgZm9yICh2YXIgaSBpbiBub2RlcykgeyBmdW5jKG5vZGVzW2ldKTsgaWYgKG5vZGVzW2ldLmNoaWxkTm9kZXMpIHsgX3htbFRyYXZlcnNlQWxsUmVjKG5vZGVzW2ldLmNoaWxkTm9kZXMsIGZ1bmMpOyB9IH0gfQogICAgZnVuY3Rpb24gX3R1cm5Ub1htbFJlYyh0ZXh0KSB7DQogICAgICAgIHZhciBlbGVtZW50U3RhY2sgPSBuZXcgX3RyZWVCdWlsZGVyKCksIGxhc3RFbGVtZW50ID0gbnVsbCwgeDEgPSB0ZXh0LnNwbGl0KCc8JyksIHJldCA9IFtdLCBlbGVtZW50ID0gbnVsbCwgY3VycmVudEVsZW1lbnROYW1lID0gbnVsbDsKICAgICAgICBmb3IgKHZhciBpIGluIHgxKSB7DQogICAgICAgICAgICB2YXIgeDIgPSB4MVtpXS5zcGxpdCgnPicpLCB4MyA9IHgyWzBdLnNwbGl0KCcgJyksIGVsZW1lbnROYW1lID0geDNbMF07CiAgICAgICAgICAgIGlmICgoZWxlbWVudE5hbWUubGVuZ3RoID4gMCkgJiYgKGVsZW1lbnROYW1lWzBdICE9ICc/JykpIHsNCiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudE5hbWVbMF0gIT0gJy8nKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0gW10sIGxvY2FsTmFtZSwgbG9jYWxuYW1lMiA9IGVsZW1lbnROYW1lLnNwbGl0KCcgJylbMF0uc3BsaXQoJzonKSwgbG9jYWxOYW1lID0gKGxvY2FsbmFtZTIubGVuZ3RoID4gMSkgPyBsb2NhbG5hbWUyWzFdIDogbG9jYWxuYW1lMlswXTsKICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYXR0cmlidXRlcywgImdldCIsCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAxKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGEgaW4gdGhpcykgeyBpZiAodGhpc1thXS5uYW1lID09IGFyZ3VtZW50c1swXSkgeyByZXR1cm4gKHRoaXNbYV0pOyB9IH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09IDIpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgYSBpbiB0aGlzKSB7IGlmICh0aGlzW2FdLm5hbWUgPT0gYXJndW1lbnRzWzFdICYmIChhcmd1bWVudHNbMF0gPT0gJyonIHx8IHRoaXNbYV0ubmFtZXNwYWNlID09IGFyZ3VtZW50c1swXSkpIHsgcmV0dXJuICh0aGlzW2FdKTsgfSB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICgnYXR0cmlidXRlcy5nZXQoKTogSW52YWxpZCBudW1iZXIgb2YgcGFyYW1ldGVycycpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudFN0YWNrLnB1c2goeyBuYW1lOiBlbGVtZW50TmFtZSwgbG9jYWxOYW1lOiBsb2NhbE5hbWUsIGdldENoaWxkRWxlbWVudHNCeVRhZ05hbWU6IF9nZXRDaGlsZEVsZW1lbnRzQnlUYWdOYW1lLCBnZXRFbGVtZW50c0J5VGFnTmFtZU5TOiBfZ2V0RWxlbWVudHNCeVRhZ05hbWVOUywgZ2V0Q2hpbGRFbGVtZW50c0J5VGFnTmFtZU5TOiBfZ2V0Q2hpbGRFbGVtZW50c0J5VGFnTmFtZU5TLCBhdHRyaWJ1dGVzOiBhdHRyaWJ1dGVzLCBjaGlsZE5vZGVzOiBbXSwgbnNUYWJsZToge30gfSk7CiAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgQXR0cmlidXRlcwogICAgICAgICAgICAgICAgICAgIGlmICh4My5sZW5ndGggPiAwKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2tpcCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqIGluIHgzKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHgzW2pdID09ICcvJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYW4gZW1wdHkgRWxlbWVudAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTdGFjay5wZWVrKCkubmFtZXNwYWNlID0gZWxlbWVudFN0YWNrLnBlZWsoKS5uYW1lID09IGVsZW1lbnRTdGFjay5wZWVrKCkubG9jYWxOYW1lID8gZWxlbWVudFN0YWNrLmdldE5hbWVzcGFjZSgnKicpIDogZWxlbWVudFN0YWNrLmdldE5hbWVzcGFjZShlbGVtZW50U3RhY2sucGVlaygpLm5hbWUuc3Vic3RyaW5nKDAsIGVsZW1lbnRTdGFjay5wZWVrKCkubmFtZS5pbmRleE9mKCc6JykpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3RhY2sucGVlaygpLnRleHRDb250ZW50ID0gJyc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdEVsZW1lbnQgPSBlbGVtZW50U3RhY2sucG9wKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2tpcCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGsgPSB4M1tqXS5pbmRleE9mKCc9Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoayA+IDApIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHJOYW1lID0geDNbal0uc3Vic3RyaW5nKDAsIGspOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHRyVmFsdWUgPSB4M1tqXS5zdWJzdHJpbmcoayArIDIsIHgzW2pdLmxlbmd0aCAtIDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHRyTlMgPSBlbGVtZW50U3RhY2suZ2V0TmFtZXNwYWNlKCcqJyk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyTmFtZSA9PSAneG1sbnMnKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3RhY2suYWRkTmFtZXNwYWNlKCcqJywgYXR0clZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ck5TID0gYXR0clZhbHVlOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGF0dHJOYW1lLnN0YXJ0c1dpdGgoJ3htbG5zOicpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3RhY2suYWRkTmFtZXNwYWNlKGF0dHJOYW1lLnN1YnN0cmluZyg2KSwgYXR0clZhbHVlKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBheCA9IGF0dHJOYW1lLnNwbGl0KCc6Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChheC5sZW5ndGggPT0gMikgeyBhdHRyTmFtZSA9IGF4WzFdOyBhdHRyTlMgPSBlbGVtZW50U3RhY2suZ2V0TmFtZXNwYWNlKGF4WzBdKTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHggPSB7IG5hbWU6IGF0dHJOYW1lLCB2YWx1ZTogYXR0clZhbHVlIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ck5TICE9IG51bGwpIHgubmFtZXNwYWNlID0gYXR0ck5TOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTdGFjay5wZWVrKCkuYXR0cmlidXRlcy5wdXNoKHgpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNraXApIHsgY29udGludWU7IH0NCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTdGFjay5wZWVrKCkubmFtZXNwYWNlID0gZWxlbWVudFN0YWNrLnBlZWsoKS5uYW1lID09IGVsZW1lbnRTdGFjay5wZWVrKCkubG9jYWxOYW1lID8gZWxlbWVudFN0YWNrLmdldE5hbWVzcGFjZSgnKicpIDogZWxlbWVudFN0YWNrLmdldE5hbWVzcGFjZShlbGVtZW50U3RhY2sucGVlaygpLm5hbWUuc3Vic3RyaW5nKDAsIGVsZW1lbnRTdGFjay5wZWVrKCkubmFtZS5pbmRleE9mKCc6JykpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoeDJbMV0pIHsgZWxlbWVudFN0YWNrLnBlZWsoKS50ZXh0Q29udGVudCA9IHgyWzFdOyB9DQogICAgICAgICAgICAgICAgfSBlbHNlIHsgbGFzdEVsZW1lbnQgPSBlbGVtZW50U3RhY2sucG9wKCk7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQogICAgICAgIHJldHVybiBsYXN0RWxlbWVudDsNCiAgICB9DQogICAgKi8NCg0KICAgIHJldHVybiBvYmo7DQp9DQovKioNCiogQGZpbGVvdmVydmlldyBJbnRlbChyKSBBTVQgQ29tbXVuaWNhdGlvbiBTdGFja1hYDQoqIEBhdXRob3IgWWxpYW4gU2FpbnQtSGlsYWlyZQ0KKiBAdmVyc2lvbiB2MC4yLjBiDQoqLw0KDQovKioNCiAqIENvbnN0cnVjdCBhIEFtdFN0YWNrQ3JlYXRlU2VydmljZSBvYmplY3QsIHRoaXMgaWEgdGhlIG1haW4gSW50ZWwgQU1UIGNvbW11bmljYXRpb24gc3RhY2suDQogKiBAY29uc3RydWN0b3INCiAqLw0KZnVuY3Rpb24gQW10U3RhY2tDcmVhdGVTZXJ2aWNlKHdzbWFuU3RhY2spIHsNCiAgICB2YXIgb2JqID0gbmV3IE9iamVjdCgpOw0KICAgIG9iai53c21hbiA9IHdzbWFuU3RhY2s7DQogICAgb2JqLnBmeCA9IFsiaHR0cDovL2ludGVsLmNvbS93YmVtL3dzY2ltLzEvYW10LXNjaGVtYS8xLyIsICJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yLyIsICJodHRwOi8vaW50ZWwuY29tL3diZW0vd3NjaW0vMS9pcHMtc2NoZW1hLzEvIl07DQogICAgb2JqLlBlbmRpbmdFbnVtcyA9IFtdOw0KICAgIG9iai5QZW5kaW5nQmF0Y2hPcGVyYXRpb25zID0gMDsNCiAgICBvYmouQWN0aXZlRW51bXNDb3VudCA9IDA7DQogICAgb2JqLk1heEFjdGl2ZUVudW1zQ291bnQgPSAxOyAvLyBNYXhpbXVtIG51bWJlciBvZiBlbnVtZXJhdGlvbnMgdGhhdCBjYW4gYmUgZG9uZSBhdCB0aGUgc2FtZSB0aW1lLg0KICAgIG9iai5vblByb2Nlc3NDaGFuZ2VkID0gbnVsbDsNCiAgICB2YXIgX01heFByb2Nlc3MgPSAwOw0KICAgIHZhciBfTGFzdFByb2Nlc3MgPSAwOw0KDQogICAgLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgcGVuZGluZyBhY3Rpb25zDQogICAgb2JqLkdldFBlbmRpbmdBY3Rpb25zID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gKG9iai5QZW5kaW5nRW51bXMubGVuZ3RoICogMikgKyAob2JqLkFjdGl2ZUVudW1zQ291bnQpICsgb2JqLndzbWFuLmNvbW0uUGVuZGluZ0FqYXgubGVuZ3RoICsgb2JqLndzbWFuLmNvbW0uQWN0aXZlQWpheENvdW50ICsgb2JqLlBlbmRpbmdCYXRjaE9wZXJhdGlvbnM7IH0NCg0KICAgIC8vIFByaXZhdGUgTWV0aG9kLCBVcGRhdGUgdGhlIGN1cnJlbnQgcHJvY2Vzc2luZyBzdGF0dXMsIHRoaXMgZ2l2ZXMgdGhlIGFwcGxpY2F0aW9uIGFuIGlkZWEgb2Ygd2hhdCBwcm9ncmVzcyBpcyBiZWluZyBkb25lIGJ5IHRoZSBXU01BTiBzdGFjaw0KICAgIGZ1bmN0aW9uIF91cCgpIHsNCiAgICAgICAgdmFyIHggPSBvYmouR2V0UGVuZGluZ0FjdGlvbnMoKTsNCiAgICAgICAgaWYgKF9NYXhQcm9jZXNzIDwgeCkgX01heFByb2Nlc3MgPSB4Ow0KICAgICAgICBpZiAob2JqLm9uUHJvY2Vzc0NoYW5nZWQgIT0gbnVsbCAmJiBfTGFzdFByb2Nlc3MgIT0geCkgew0KICAgICAgICAgICAgLy9jb25zb2xlLmxvZygiUHJvY2VzcyBPbGQ9IiArIF9MYXN0UHJvY2VzcyArICIsIE5ldz0iICsgeCArICIsIFBFbnVtcz0iICsgb2JqLlBlbmRpbmdFbnVtcy5sZW5ndGggKyAiLCBBRW51bXM9IiArIG9iai5BY3RpdmVFbnVtc0NvdW50ICsgIiwgUEFqYXg9IiArIG9iai53c21hbi5jb21tLlBlbmRpbmdBamF4Lmxlbmd0aCArICIsIEFBamF4PSIgKyBvYmoud3NtYW4uY29tbS5BY3RpdmVBamF4Q291bnQgKyAiLCBQQmF0Y2g9IiArIG9iai5QZW5kaW5nQmF0Y2hPcGVyYXRpb25zKTsNCiAgICAgICAgICAgIF9MYXN0UHJvY2VzcyA9IHg7DQogICAgICAgICAgICBvYmoub25Qcm9jZXNzQ2hhbmdlZCh4LCBfTWF4UHJvY2Vzcyk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKHggPT0gMCkgX01heFByb2Nlc3MgPSAwOw0KICAgIH0NCg0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiAiU1VCU0NSSUJFIiBvcGVyYXRpb24uDQogICAgb2JqLlN1YnNjcmliZSA9IGZ1bmN0aW9uIChuYW1lLCBkZWxpdmVyeSwgdXJsLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycywgb3BhcXVlLCB1c2VyLCBwYXNzKSB7IG9iai53c21hbi5FeGVjU3Vic2NyaWJlKG9iai5Db21wbGV0ZU5hbWUobmFtZSksIGRlbGl2ZXJ5LCB1cmwsIGZ1bmN0aW9uICh3cywgcmVzdXJpLCByZXNwb25zZSwgeHN0YXR1cykgeyBfdXAoKTsgY2FsbGJhY2sob2JqLCBuYW1lLCByZXNwb25zZSwgeHN0YXR1cywgdGFnKTsgfSwgMCwgcHJpLCBzZWxlY3RvcnMsIG9wYXF1ZSwgdXNlciwgcGFzcyk7IF91cCgpOyB9DQoNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gIlVOU1VCU0NSSUJFIiBvcGVyYXRpb24uDQogICAgb2JqLlVuU3Vic2NyaWJlID0gZnVuY3Rpb24gKG5hbWUsIGNhbGxiYWNrLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai53c21hbi5FeGVjVW5TdWJzY3JpYmUob2JqLkNvbXBsZXRlTmFtZShuYW1lKSwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF91cCgpOyBjYWxsYmFjayhvYmosIG5hbWUsIHJlc3BvbnNlLCB4c3RhdHVzLCB0YWcpOyB9LCAwLCBwcmksIHNlbGVjdG9ycyk7IF91cCgpOyB9DQoNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gIkdFVCIgb3BlcmF0aW9uLg0KICAgIG9iai5HZXQgPSBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2ssIHRhZywgcHJpKSB7IG9iai53c21hbi5FeGVjR2V0KG9iai5Db21wbGV0ZU5hbWUobmFtZSksIGZ1bmN0aW9uICh3cywgcmVzdXJpLCByZXNwb25zZSwgeHN0YXR1cykgeyBfdXAoKTsgY2FsbGJhY2sob2JqLCBuYW1lLCByZXNwb25zZSwgeHN0YXR1cywgdGFnKTsgfSwgMCwgcHJpKTsgX3VwKCk7IH0NCg0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiAiUFVUIiBvcGVyYXRpb24uDQogICAgb2JqLlB1dCA9IGZ1bmN0aW9uIChuYW1lLCBwdXRvYmosIGNhbGxiYWNrLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai53c21hbi5FeGVjUHV0KG9iai5Db21wbGV0ZU5hbWUobmFtZSksIHB1dG9iaiwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF91cCgpOyBjYWxsYmFjayhvYmosIG5hbWUsIHJlc3BvbnNlLCB4c3RhdHVzLCB0YWcpOyB9LCAwLCBwcmksIHNlbGVjdG9ycyk7IF91cCgpOyB9DQoJDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOICJDUkVBVEUiIG9wZXJhdGlvbi4NCiAgICBvYmouQ3JlYXRlID0gZnVuY3Rpb24gKG5hbWUsIHB1dG9iaiwgY2FsbGJhY2ssIHRhZywgcHJpKSB7IG9iai53c21hbi5FeGVjQ3JlYXRlKG9iai5Db21wbGV0ZU5hbWUobmFtZSksIHB1dG9iaiwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF91cCgpOyBjYWxsYmFjayhvYmosIG5hbWUsIHJlc3BvbnNlLCB4c3RhdHVzLCB0YWcpOyB9LCAwLCBwcmkpOyBfdXAoKTsgfQ0KDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOICJERUxFVEUiIG9wZXJhdGlvbi4NCiAgICBvYmouRGVsZXRlID0gZnVuY3Rpb24gKG5hbWUsIHB1dG9iaiwgY2FsbGJhY2ssIHRhZywgcHJpKSB7IG9iai53c21hbi5FeGVjRGVsZXRlKG9iai5Db21wbGV0ZU5hbWUobmFtZSksIHB1dG9iaiwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF91cCgpOyBjYWxsYmFjayhvYmosIG5hbWUsIHJlc3BvbnNlLCB4c3RhdHVzLCB0YWcpOyB9LCAwLCBwcmkpOyBfdXAoKTsgfQ0KDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOIG1ldGhvZCBjYWxsIG9wZXJhdGlvbi4NCiAgICBvYmouRXhlYyA9IGZ1bmN0aW9uIChuYW1lLCBtZXRob2QsIGFyZ3MsIGNhbGxiYWNrLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai53c21hbi5FeGVjTWV0aG9kKG9iai5Db21wbGV0ZU5hbWUobmFtZSksIG1ldGhvZCwgYXJncywgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF91cCgpOyBjYWxsYmFjayhvYmosIG5hbWUsIG9iai5Db21wbGV0ZUV4ZWNSZXNwb25zZShyZXNwb25zZSksIHhzdGF0dXMsIHRhZyk7IH0sIDAsIHByaSwgc2VsZWN0b3JzKTsgX3VwKCk7IH0NCgkNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gbWV0aG9kIGNhbGwgb3BlcmF0aW9uLg0KICAgIG9iai5FeGVjV2l0aFhtbCA9IGZ1bmN0aW9uIChuYW1lLCBtZXRob2QsIGFyZ3MsIGNhbGxiYWNrLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai53c21hbi5FeGVjTWV0aG9kWG1sKG9iai5Db21wbGV0ZU5hbWUobmFtZSksIG1ldGhvZCwgZXhlY0FyZ3VtZW50c1RvWG1sKGFyZ3MpLCBmdW5jdGlvbiAod3MsIHJlc3VyaSwgcmVzcG9uc2UsIHhzdGF0dXMpIHsgX3VwKCk7IGNhbGxiYWNrKG9iaiwgbmFtZSwgb2JqLkNvbXBsZXRlRXhlY1Jlc3BvbnNlKHJlc3BvbnNlKSwgeHN0YXR1cywgdGFnKTsgfSwgMCwgcHJpLCBzZWxlY3RvcnMpOyBfdXAoKTsgfQ0KCQ0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiAiRU5VTUVSQVRFIiBvcGVyYXRpb24uDQogICAgb2JqLkVudW0gPSBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2ssIHRhZywgcHJpKSB7DQogICAgICAgIGlmIChvYmouQWN0aXZlRW51bXNDb3VudCA8IG9iai5NYXhBY3RpdmVFbnVtc0NvdW50KSB7DQogICAgICAgICAgICBvYmouQWN0aXZlRW51bXNDb3VudCsrOyBvYmoud3NtYW4uRXhlY0VudW0ob2JqLkNvbXBsZXRlTmFtZShuYW1lKSwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzLCB0YWcwKSB7IF91cCgpOyBfRW51bVN0YXJ0U2luayhuYW1lLCByZXNwb25zZSwgY2FsbGJhY2ssIHJlc3VyaSwgeHN0YXR1cywgdGFnMCk7IH0sIHRhZywgcHJpKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIG9iai5QZW5kaW5nRW51bXMucHVzaChbbmFtZSwgY2FsbGJhY2ssIHRhZywgcHJpXSk7DQogICAgICAgIH0NCiAgICAgICAgX3VwKCk7DQogICAgfQ0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICBmdW5jdGlvbiBfRW51bVN0YXJ0U2luayhuYW1lLCByZXNwb25zZSwgY2FsbGJhY2ssIHJlc3VyaSwgc3RhdHVzLCB0YWcsIHByaSkgew0KICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBjYWxsYmFjayhvYmosIG5hbWUsIG51bGwsIHN0YXR1cywgdGFnKTsgX0VudW1Eb05leHQoMSk7IHJldHVybjsgfQ0KICAgICAgICBpZiAocmVzcG9uc2UgPT0gbnVsbCB8fCByZXNwb25zZS5IZWFkZXJbIk1ldGhvZCJdICE9ICJFbnVtZXJhdGVSZXNwb25zZSIgfHwgIXJlc3BvbnNlLkJvZHlbIkVudW1lcmF0aW9uQ29udGV4dCJdKSB7IGNhbGxiYWNrKG9iaiwgbmFtZSwgbnVsbCwgNjAzLCB0YWcpOyBfRW51bURvTmV4dCgxKTsgcmV0dXJuOyB9DQogICAgICAgIHZhciBlbnVtY3R4ID0gcmVzcG9uc2UuQm9keVsiRW51bWVyYXRpb25Db250ZXh0Il07DQogICAgICAgIG9iai53c21hbi5FeGVjUHVsbChyZXN1cmksIGVudW1jdHgsIGZ1bmN0aW9uICh3cywgcmVzdXJpLCByZXNwb25zZSwgeHN0YXR1cykgeyBfRW51bUNvbnRpbnVlU2luayhuYW1lLCByZXNwb25zZSwgY2FsbGJhY2ssIHJlc3VyaSwgW10sIHhzdGF0dXMsIHRhZywgcHJpKTsgfSk7DQogICAgfQ0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICBmdW5jdGlvbiBfRW51bUNvbnRpbnVlU2luayhuYW1lLCByZXNwb25zZSwgY2FsbGJhY2ssIHJlc3VyaSwgaXRlbXMsIHN0YXR1cywgdGFnLCBwcmkpIHsNCiAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsgY2FsbGJhY2sob2JqLCBuYW1lLCBudWxsLCBzdGF0dXMsIHRhZyk7IF9FbnVtRG9OZXh0KDEpOyByZXR1cm47IH0NCiAgICAgICAgaWYgKHJlc3BvbnNlID09IG51bGwgfHwgcmVzcG9uc2UuSGVhZGVyWyJNZXRob2QiXSAhPSAiUHVsbFJlc3BvbnNlIikgeyBjYWxsYmFjayhvYmosIG5hbWUsIG51bGwsIDYwNCwgdGFnKTsgX0VudW1Eb05leHQoMSk7IHJldHVybjsgfQ0KICAgICAgICBmb3IgKHZhciBpIGluIHJlc3BvbnNlLkJvZHlbIkl0ZW1zIl0pIHsNCiAgICAgICAgICAgIGlmIChyZXNwb25zZS5Cb2R5WyJJdGVtcyJdW2ldIGluc3RhbmNlb2YgQXJyYXkpIHsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBqIGluIHJlc3BvbnNlLkJvZHlbIkl0ZW1zIl1baV0pIHsgaWYgKHR5cGVvZiByZXNwb25zZS5Cb2R5WyJJdGVtcyJdW2ldW2pdICE9ICdmdW5jdGlvbicpIHsgaXRlbXMucHVzaChyZXNwb25zZS5Cb2R5WyJJdGVtcyJdW2ldW2pdKTsgfSB9DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzcG9uc2UuQm9keVsiSXRlbXMiXVtpXSAhPSAnZnVuY3Rpb24nKSB7IGl0ZW1zLnB1c2gocmVzcG9uc2UuQm9keVsiSXRlbXMiXVtpXSk7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBpZiAocmVzcG9uc2UuQm9keVsiRW51bWVyYXRpb25Db250ZXh0Il0pIHsNCiAgICAgICAgICAgIHZhciBlbnVtY3R4ID0gcmVzcG9uc2UuQm9keVsiRW51bWVyYXRpb25Db250ZXh0Il07DQogICAgICAgICAgICBvYmoud3NtYW4uRXhlY1B1bGwocmVzdXJpLCBlbnVtY3R4LCBmdW5jdGlvbiAod3MsIHJlc3VyaSwgcmVzcG9uc2UsIHhzdGF0dXMpIHsgX0VudW1Db250aW51ZVNpbmsobmFtZSwgcmVzcG9uc2UsIGNhbGxiYWNrLCByZXN1cmksIGl0ZW1zLCB4c3RhdHVzLCB0YWcsIDEpOyB9KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIF9FbnVtRG9OZXh0KDEpOw0KICAgICAgICAgICAgY2FsbGJhY2sob2JqLCBuYW1lLCBpdGVtcywgc3RhdHVzLCB0YWcpOw0KICAgICAgICAgICAgX3VwKCk7DQogICAgICAgIH0NCiAgICB9DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIGZ1bmN0aW9uIF9FbnVtRG9OZXh0KGRlYykgew0KICAgICAgICBvYmouQWN0aXZlRW51bXNDb3VudCAtPSBkZWM7DQogICAgICAgIGlmIChvYmouQWN0aXZlRW51bXNDb3VudCA+PSBvYmouTWF4QWN0aXZlRW51bXNDb3VudCB8fCBvYmouUGVuZGluZ0VudW1zLmxlbmd0aCA9PSAwKSB7IF91cCgpOyByZXR1cm47IH0NCiAgICAgICAgdmFyIHggPSBvYmouUGVuZGluZ0VudW1zLnNoaWZ0KCk7DQogICAgICAgIG9iai5FbnVtKHhbMF0sIHhbMV0sIHhbMl0pOw0KICAgICAgICBfRW51bURvTmV4dCgwKTsNCiAgICB9DQoNCiAgICAvLyBQZXJmb3JtIGEgYmF0Y2ggb2YgV1NNQU4gIkVOVU0iIG9wZXJhdGlvbnMuDQogICAgb2JqLkJhdGNoRW51bSA9IGZ1bmN0aW9uIChiYXRjaG5hbWUsIG5hbWVzLCBjYWxsYmFjaywgdGFnLCBjb250aW51ZU9uRXJyb3IsIHByaSkgew0KICAgICAgICBvYmouUGVuZGluZ0JhdGNoT3BlcmF0aW9ucyArPSAobmFtZXMubGVuZ3RoICogMik7DQogICAgICAgIF9CYXRjaE5leHRFbnVtKGJhdGNobmFtZSwgQ2xvbmUobmFtZXMpLCBjYWxsYmFjaywgdGFnLCB7fSwgY29udGludWVPbkVycm9yLCBwcmkpOyBfdXAoKTsNCiAgICB9DQoNCiAgICAvLyBSZXF1ZXN0IGVhY2ggZW51bSBpbiB0aGUgYmF0Y2gsIHN0b3BwaW5nIGlmIHNvbWV0aGluZyBkb2VzIG5vdCByZXR1cm4gc3RhdHVzIDIwMA0KICAgIGZ1bmN0aW9uIF9CYXRjaE5leHRFbnVtKGJhdGNobmFtZSwgbmFtZXMsIGNhbGxiYWNrLCB0YWcsIHJlc3VsdHMsIGNvbnRpbnVlT25FcnJvciwgcHJpKSB7DQogICAgICAgIG9iai5QZW5kaW5nQmF0Y2hPcGVyYXRpb25zIC09IDI7DQogICAgICAgIHZhciBuID0gbmFtZXMuc2hpZnQoKSwgZiA9IG9iai5FbnVtOw0KICAgICAgICBpZiAoblswXSA9PSAnKicpIHsgZiA9IG9iai5HZXQ7IG4gPSBuLnN1YnN0cmluZygxKTsgfSAvLyBJZiB0aGUgbmFtZSBzdGFydHMgd2l0aCBhIHN0YXIsIGRvIGEgR0VUIGluc3RlYWQgb2YgYW4gRU5VTS4gVGhpcyB3aWxsIHJlZHVjZSByb3VuZCB0cmlwcy4NCiAgICAgICAgLy9jb25zb2xlLmxvZygoZiA9PSBvYmouR2V0PydHZXQgJzonRW51bSAnKSArIG4pOw0KICAgICAgICAvLyBQZXJmb3JtIGEgR0VUL0VOVU0gYWN0aW9uDQogICAgICAgIGYobiwgZnVuY3Rpb24gKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cywgdGFnMCkgew0KICAgICAgICAgICAgdGFnMFsyXVtuYW1lXSA9IHsgcmVzcG9uc2U6IChyZXNwb25zZXM9PW51bGw/bnVsbDpyZXNwb25zZXMuQm9keSksIHJlc3BvbnNlczogcmVzcG9uc2VzLCBzdGF0dXM6IHN0YXR1cyB9Ow0KICAgICAgICAgICAgaWYgKHRhZzBbMV0ubGVuZ3RoID09IDAgfHwgc3RhdHVzID09IDQwMSB8fCAoY29udGludWVPbkVycm9yICE9IHRydWUgJiYgc3RhdHVzICE9IDIwMCAmJiBzdGF0dXMgIT0gNDAwKSkgeyBvYmouUGVuZGluZ0JhdGNoT3BlcmF0aW9ucyAtPSAobmFtZXMubGVuZ3RoICogMik7IF91cCgpOyBjYWxsYmFjayhvYmosIGJhdGNobmFtZSwgdGFnMFsyXSwgc3RhdHVzLCB0YWcpOyB9DQogICAgICAgICAgICBlbHNlIHsgX3VwKCk7IF9CYXRjaE5leHRFbnVtKGJhdGNobmFtZSwgbmFtZXMsIGNhbGxiYWNrLCB0YWcsIHRhZzBbMl0sIHByaSk7IH0NCiAgICAgICAgfSwgW2JhdGNobmFtZSwgbmFtZXMsIHJlc3VsdHNdLCBwcmkpOw0KICAgICAgICBfdXAoKTsNCiAgICB9DQoNCiAgICAvLyBQZXJmb3JtIGEgYmF0Y2ggb2YgV1NNQU4gIkdFVCIgb3BlcmF0aW9ucy4NCiAgICBvYmouQmF0Y2hHZXQgPSBmdW5jdGlvbiAoYmF0Y2huYW1lLCBuYW1lcywgY2FsbGJhY2ssIHRhZywgcHJpKSB7DQogICAgICAgIF9GZXRjaE5leHQoeyBuYW1lOiBiYXRjaG5hbWUsIG5hbWVzOiBuYW1lcywgY2FsbGJhY2s6IGNhbGxiYWNrLCBjdXJyZW50OiAwLCByZXNwb25zZXM6IHt9LCB0YWc6IHRhZywgcHJpOiBwcmkgfSk7IF91cCgpOw0KICAgIH0NCg0KICAgIC8vIFByaXZhdGUgbWV0aG9kDQogICAgZnVuY3Rpb24gX0ZldGNoTmV4dChiYXRjaCkgew0KICAgICAgICBpZiAoYmF0Y2gubmFtZXMubGVuZ3RoIDw9IGJhdGNoLmN1cnJlbnQpIHsNCiAgICAgICAgICAgIGJhdGNoLmNhbGxiYWNrKG9iaiwgYmF0Y2gubmFtZSwgYmF0Y2gucmVzcG9uc2VzLCAyMDAsIGJhdGNoLnRhZyk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBvYmoud3NtYW4uRXhlY0dldChvYmouQ29tcGxldGVOYW1lKGJhdGNoLm5hbWVzW2JhdGNoLmN1cnJlbnRdKSwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF9GZXRjaGVkKGJhdGNoLCByZXNwb25zZSwgeHN0YXR1cyk7IH0sIGJhdGNoLnByaSk7DQogICAgICAgICAgICBiYXRjaC5jdXJyZW50Kys7DQogICAgICAgIH0NCiAgICAgICAgX3VwKCk7DQogICAgfQ0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICBmdW5jdGlvbiBfRmV0Y2hlZChiYXRjaCwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICBpZiAocmVzcG9uc2UgPT0gbnVsbCB8fCBzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICBiYXRjaC5jYWxsYmFjayhvYmosIGJhdGNoLm5hbWUsIG51bGwsIHN0YXR1cywgYmF0Y2gudGFnKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGJhdGNoLnJlc3BvbnNlc1tyZXNwb25zZS5IZWFkZXJbIk1ldGhvZCJdXSA9IHJlc3BvbnNlOw0KICAgICAgICAgICAgX0ZldGNoTmV4dChiYXRjaCk7DQogICAgICAgIH0NCiAgICB9DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIG9iai5Db21wbGV0ZU5hbWUgPSBmdW5jdGlvbihuYW1lKSB7DQogICAgICAgIGlmIChuYW1lLmluZGV4T2YoIkFNVF8iKSA9PSAwKSByZXR1cm4gb2JqLnBmeFswXSArIG5hbWU7DQogICAgICAgIGlmIChuYW1lLmluZGV4T2YoIkNJTV8iKSA9PSAwKSByZXR1cm4gb2JqLnBmeFsxXSArIG5hbWU7DQogICAgICAgIGlmIChuYW1lLmluZGV4T2YoIklQU18iKSA9PSAwKSByZXR1cm4gb2JqLnBmeFsyXSArIG5hbWU7DQogICAgfQ0KDQogICAgb2JqLkNvbXBsZXRlRXhlY1Jlc3BvbnNlID0gZnVuY3Rpb24gKHJlc3ApIHsNCiAgICAgICAgaWYgKHJlc3AgJiYgcmVzcCAhPSBudWxsICYmIHJlc3AuQm9keSAmJiAocmVzcC5Cb2R5WyJSZXR1cm5WYWx1ZSJdICE9IHVuZGVmaW5lZCkpIHsgcmVzcC5Cb2R5LlJldHVyblZhbHVlU3RyID0gb2JqLkFtdFN0YXR1c1RvU3RyKHJlc3AuQm9keVsiUmV0dXJuVmFsdWUiXSk7IH0NCiAgICAgICAgcmV0dXJuIHJlc3A7DQogICAgfQ0KDQogICAgb2JqLlJlcXVlc3RQb3dlclN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFBvd2VyU3RhdGUsIGNhbGxiYWNrX2Z1bmMpIHsNCiAgICAgICAgb2JqLkNJTV9Qb3dlck1hbmFnZW1lbnRTZXJ2aWNlX1JlcXVlc3RQb3dlclN0YXRlQ2hhbmdlKFBvd2VyU3RhdGUsICI8QWRkcmVzcyB4bWxucz1cImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZ1wiPmh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZzwvQWRkcmVzcz48UmVmZXJlbmNlUGFyYW1ldGVycyB4bWxucz1cImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZ1wiPjxSZXNvdXJjZVVSSSB4bWxucz1cImh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2RcIj5odHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yL0NJTV9Db21wdXRlclN5c3RlbTwvUmVzb3VyY2VVUkk+PFNlbGVjdG9yU2V0IHhtbG5zPVwiaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZFwiPjxTZWxlY3RvciBOYW1lPVwiQ3JlYXRpb25DbGFzc05hbWVcIj5DSU1fQ29tcHV0ZXJTeXN0ZW08L1NlbGVjdG9yPjxTZWxlY3RvciBOYW1lPVwiTmFtZVwiPk1hbmFnZWRTeXN0ZW08L1NlbGVjdG9yPjwvU2VsZWN0b3JTZXQ+PC9SZWZlcmVuY2VQYXJhbWV0ZXJzPiIsIG51bGwsIG51bGwsIGNhbGxiYWNrX2Z1bmMpOw0KICAgIH0NCg0KICAgIG9iai5TZXRCb290Q29uZmlnUm9sZSA9IGZ1bmN0aW9uIChSb2xlLCBjYWxsYmFja19mdW5jKSB7DQogICAgICAgIG9iai5DSU1fQm9vdFNlcnZpY2VfU2V0Qm9vdENvbmZpZ1JvbGUoIjxBZGRyZXNzIHhtbG5zPVwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nXCI+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nPC9BZGRyZXNzPjxSZWZlcmVuY2VQYXJhbWV0ZXJzIHhtbG5zPVwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nXCI+PFJlc291cmNlVVJJIHhtbG5zPVwiaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZFwiPmh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NjaW0vMS9jaW0tc2NoZW1hLzIvQ0lNX0Jvb3RDb25maWdTZXR0aW5nPC9SZXNvdXJjZVVSST48U2VsZWN0b3JTZXQgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkXCI+PFNlbGVjdG9yIE5hbWU9XCJJbnN0YW5jZUlEXCI+SW50ZWwocikgQU1UOiBCb290IENvbmZpZ3VyYXRpb24gMDwvU2VsZWN0b3I+PC9TZWxlY3RvclNldD48L1JlZmVyZW5jZVBhcmFtZXRlcnM+IiwgUm9sZSwgY2FsbGJhY2tfZnVuYyk7DQogICAgfQ0KDQogICAgLy8gQ2FuY2VsIGFsbCBwZW5kaW5nIHF1ZXJpZXMgd2l0aCBnaXZlbiBzdGF0dXMNCiAgICBvYmouQ2FuY2VsQWxsUXVlcmllcyA9IGZ1bmN0aW9uIChzKSB7DQogICAgICAgIG9iai53c21hbi5DYW5jZWxBbGxRdWVyaWVzKHMpOw0KICAgIH0NCg0KICAgIC8vIEF1dG8gZ2VuZXJhdGVkIG1ldGhvZHMNCiAgICBvYmouQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ19SZWdpc3RlckFnZW50ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2ciLCAiUmVnaXN0ZXJBZ2VudCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nX0Fzc2VydFByZXNlbmNlID0gZnVuY3Rpb24gKFNlcXVlbmNlTnVtYmVyLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nIiwgIkFzc2VydFByZXNlbmNlIiwgeyAiU2VxdWVuY2VOdW1iZXIiOiBTZXF1ZW5jZU51bWJlciB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nX0Fzc2VydFNodXRkb3duID0gZnVuY3Rpb24gKFNlcXVlbmNlTnVtYmVyLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nIiwgIkFzc2VydFNodXRkb3duIiwgeyAiU2VxdWVuY2VOdW1iZXIiOiBTZXF1ZW5jZU51bWJlciB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nX0FkZEFjdGlvbiA9IGZ1bmN0aW9uIChPbGRTdGF0ZSwgTmV3U3RhdGUsIEV2ZW50T25UcmFuc2l0aW9uLCBBY3Rpb25TZCwgQWN0aW9uRWFjLCBjYWxsYmFja19mdW5jLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nIiwgIkFkZEFjdGlvbiIsIHsgIk9sZFN0YXRlIjogT2xkU3RhdGUsICJOZXdTdGF0ZSI6IE5ld1N0YXRlLCAiRXZlbnRPblRyYW5zaXRpb24iOiBFdmVudE9uVHJhbnNpdGlvbiwgIkFjdGlvblNkIjogQWN0aW9uU2QsICJBY3Rpb25FYWMiOiBBY3Rpb25FYWMgfSwgY2FsbGJhY2tfZnVuYywgdGFnLCBwcmksIHNlbGVjdG9ycyk7IH0NCiAgICBvYmouQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ19EZWxldGVBbGxBY3Rpb25zID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMsIHRhZywgcHJpLCBzZWxlY3RvcnMpIHsgb2JqLkV4ZWMoIkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2ciLCAiRGVsZXRlQWxsQWN0aW9ucyIsIHt9LCBjYWxsYmFja19mdW5jLCB0YWcsIHByaSwgc2VsZWN0b3JzKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nQWN0aW9uX0dldEFjdGlvbkVhYyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nQWN0aW9uIiwgIkdldEFjdGlvbkVhYyIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nVkFfUmVnaXN0ZXJBZ2VudCA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nVkEiLCAiUmVnaXN0ZXJBZ2VudCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nVkFfQXNzZXJ0UHJlc2VuY2UgPSBmdW5jdGlvbiAoU2VxdWVuY2VOdW1iZXIsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2dWQSIsICJBc3NlcnRQcmVzZW5jZSIsIHsgIlNlcXVlbmNlTnVtYmVyIjogU2VxdWVuY2VOdW1iZXIgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ1ZBX0Fzc2VydFNodXRkb3duID0gZnVuY3Rpb24gKFNlcXVlbmNlTnVtYmVyLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nVkEiLCAiQXNzZXJ0U2h1dGRvd24iLCB7ICJTZXF1ZW5jZU51bWJlciI6IFNlcXVlbmNlTnVtYmVyIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2dWQV9BZGRBY3Rpb24gPSBmdW5jdGlvbiAoT2xkU3RhdGUsIE5ld1N0YXRlLCBFdmVudE9uVHJhbnNpdGlvbiwgQWN0aW9uU2QsIEFjdGlvbkVhYywgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ1ZBIiwgIkFkZEFjdGlvbiIsIHsgIk9sZFN0YXRlIjogT2xkU3RhdGUsICJOZXdTdGF0ZSI6IE5ld1N0YXRlLCAiRXZlbnRPblRyYW5zaXRpb24iOiBFdmVudE9uVHJhbnNpdGlvbiwgIkFjdGlvblNkIjogQWN0aW9uU2QsICJBY3Rpb25FYWMiOiBBY3Rpb25FYWMgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ1ZBX0RlbGV0ZUFsbEFjdGlvbnMgPSBmdW5jdGlvbiAoX21ldGhvZF9kdW1teSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ1ZBIiwgIkRlbGV0ZUFsbEFjdGlvbnMiLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQXVkaXRMb2dfQ2xlYXJMb2cgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0F1ZGl0TG9nIiwgIkNsZWFyTG9nIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdWRpdExvZ19SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdWRpdExvZyIsICJSZXF1ZXN0U3RhdGVDaGFuZ2UiLCB7ICJSZXF1ZXN0ZWRTdGF0ZSI6IFJlcXVlc3RlZFN0YXRlLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0F1ZGl0TG9nX1JlYWRSZWNvcmRzID0gZnVuY3Rpb24gKFN0YXJ0SW5kZXgsIGNhbGxiYWNrX2Z1bmMsIHRhZykgeyBvYmouRXhlYygiQU1UX0F1ZGl0TG9nIiwgIlJlYWRSZWNvcmRzIiwgeyAiU3RhcnRJbmRleCI6IFN0YXJ0SW5kZXggfSwgY2FsbGJhY2tfZnVuYywgdGFnKTsgfQ0KICAgIG9iai5BTVRfQXVkaXRMb2dfU2V0QXVkaXRMb2NrID0gZnVuY3Rpb24gKExvY2tUaW1lb3V0SW5TZWNvbmRzLCBGbGFnLCBIYW5kbGUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdWRpdExvZyIsICJTZXRBdWRpdExvY2siLCB7ICJMb2NrVGltZW91dEluU2Vjb25kcyI6IExvY2tUaW1lb3V0SW5TZWNvbmRzLCAiRmxhZyI6IEZsYWcsICJIYW5kbGUiOiBIYW5kbGUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0F1ZGl0TG9nX0V4cG9ydEF1ZGl0TG9nU2lnbmF0dXJlID0gZnVuY3Rpb24gKFNpZ25pbmdNZWNoYW5pc20sIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdWRpdExvZyIsICJFeHBvcnRBdWRpdExvZ1NpZ25hdHVyZSIsIHsgIlNpZ25pbmdNZWNoYW5pc20iOiBTaWduaW5nTWVjaGFuaXNtIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdWRpdExvZ19TZXRTaWduaW5nS2V5TWF0ZXJpYWwgPSBmdW5jdGlvbiAoU2lnbmluZ01lY2hhbmlzbVR5cGUsIFNpZ25pbmdLZXksIExlbmd0aE9mQ2VydGlmaWNhdGVzLCBDZXJ0aWZpY2F0ZXMsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdWRpdExvZyIsICJTZXRTaWduaW5nS2V5TWF0ZXJpYWwiLCB7ICJTaWduaW5nTWVjaGFuaXNtVHlwZSI6IFNpZ25pbmdNZWNoYW5pc21UeXBlLCAiU2lnbmluZ0tleSI6IFNpZ25pbmdLZXksICJMZW5ndGhPZkNlcnRpZmljYXRlcyI6IExlbmd0aE9mQ2VydGlmaWNhdGVzLCAiQ2VydGlmaWNhdGVzIjogQ2VydGlmaWNhdGVzIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdWRpdFBvbGljeVJ1bGVfU2V0QXVkaXRQb2xpY3kgPSBmdW5jdGlvbiAoRW5hYmxlLCBBdWRpdGVkQXBwSUQsIEV2ZW50SUQsIFBvbGljeVR5cGUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdWRpdFBvbGljeVJ1bGUiLCAiU2V0QXVkaXRQb2xpY3kiLCB7ICJFbmFibGUiOiBFbmFibGUsICJBdWRpdGVkQXBwSUQiOiBBdWRpdGVkQXBwSUQsICJFdmVudElEIjogRXZlbnRJRCwgIlBvbGljeVR5cGUiOiBQb2xpY3lUeXBlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdWRpdFBvbGljeVJ1bGVfU2V0QXVkaXRQb2xpY3lCdWxrID0gZnVuY3Rpb24gKEVuYWJsZSwgQXVkaXRlZEFwcElELCBFdmVudElELCBQb2xpY3lUeXBlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQXVkaXRQb2xpY3lSdWxlIiwgIlNldEF1ZGl0UG9saWN5QnVsayIsIHsgIkVuYWJsZSI6IEVuYWJsZSwgIkF1ZGl0ZWRBcHBJRCI6IEF1ZGl0ZWRBcHBJRCwgIkV2ZW50SUQiOiBFdmVudElELCAiUG9saWN5VHlwZSI6IFBvbGljeVR5cGUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX0FkZFVzZXJBY2xFbnRyeUV4ID0gZnVuY3Rpb24gKERpZ2VzdFVzZXJuYW1lLCBEaWdlc3RQYXNzd29yZCwgS2VyYmVyb3NVc2VyU2lkLCBBY2Nlc3NQZXJtaXNzaW9uLCBSZWFsbXMsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJBZGRVc2VyQWNsRW50cnlFeCIsIHsgIkRpZ2VzdFVzZXJuYW1lIjogRGlnZXN0VXNlcm5hbWUsICJEaWdlc3RQYXNzd29yZCI6IERpZ2VzdFBhc3N3b3JkLCAiS2VyYmVyb3NVc2VyU2lkIjogS2VyYmVyb3NVc2VyU2lkLCAiQWNjZXNzUGVybWlzc2lvbiI6IEFjY2Vzc1Blcm1pc3Npb24sICJSZWFsbXMiOiBSZWFsbXMgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX0VudW1lcmF0ZVVzZXJBY2xFbnRyaWVzID0gZnVuY3Rpb24gKFN0YXJ0SW5kZXgsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJFbnVtZXJhdGVVc2VyQWNsRW50cmllcyIsIHsgIlN0YXJ0SW5kZXgiOiBTdGFydEluZGV4IH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9HZXRVc2VyQWNsRW50cnlFeCA9IGZ1bmN0aW9uIChIYW5kbGUsIGNhbGxiYWNrX2Z1bmMsIHRhZykgeyBvYmouRXhlYygiQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlIiwgIkdldFVzZXJBY2xFbnRyeUV4IiwgeyAiSGFuZGxlIjogSGFuZGxlIH0sIGNhbGxiYWNrX2Z1bmMsIHRhZyk7IH0NCiAgICBvYmouQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX1VwZGF0ZVVzZXJBY2xFbnRyeUV4ID0gZnVuY3Rpb24gKEhhbmRsZSwgRGlnZXN0VXNlcm5hbWUsIERpZ2VzdFBhc3N3b3JkLCBLZXJiZXJvc1VzZXJTaWQsIEFjY2Vzc1Blcm1pc3Npb24sIFJlYWxtcywgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlIiwgIlVwZGF0ZVVzZXJBY2xFbnRyeUV4IiwgeyAiSGFuZGxlIjogSGFuZGxlLCAiRGlnZXN0VXNlcm5hbWUiOiBEaWdlc3RVc2VybmFtZSwgIkRpZ2VzdFBhc3N3b3JkIjogRGlnZXN0UGFzc3dvcmQsICJLZXJiZXJvc1VzZXJTaWQiOiBLZXJiZXJvc1VzZXJTaWQsICJBY2Nlc3NQZXJtaXNzaW9uIjogQWNjZXNzUGVybWlzc2lvbiwgIlJlYWxtcyI6IFJlYWxtcyB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfUmVtb3ZlVXNlckFjbEVudHJ5ID0gZnVuY3Rpb24gKEhhbmRsZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlIiwgIlJlbW92ZVVzZXJBY2xFbnRyeSIsIHsgIkhhbmRsZSI6IEhhbmRsZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfU2V0QWRtaW5BY2xFbnRyeUV4ID0gZnVuY3Rpb24gKFVzZXJuYW1lLCBEaWdlc3RQYXNzd29yZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlIiwgIlNldEFkbWluQWNsRW50cnlFeCIsIHsgIlVzZXJuYW1lIjogVXNlcm5hbWUsICJEaWdlc3RQYXNzd29yZCI6IERpZ2VzdFBhc3N3b3JkIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9HZXRBZG1pbkFjbEVudHJ5ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJHZXRBZG1pbkFjbEVudHJ5Iiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9HZXRBZG1pbkFjbEVudHJ5U3RhdHVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJHZXRBZG1pbkFjbEVudHJ5U3RhdHVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9HZXRBZG1pbk5ldEFjbEVudHJ5U3RhdHVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJHZXRBZG1pbk5ldEFjbEVudHJ5U3RhdHVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9TZXRBY2xFbmFibGVkU3RhdGUgPSBmdW5jdGlvbiAoSGFuZGxlLCBFbmFibGVkLCBjYWxsYmFja19mdW5jLCB0YWcpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJTZXRBY2xFbmFibGVkU3RhdGUiLCB7ICJIYW5kbGUiOiBIYW5kbGUsICJFbmFibGVkIjogRW5hYmxlZCB9LCBjYWxsYmFja19mdW5jLCB0YWcpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9HZXRBY2xFbmFibGVkU3RhdGUgPSBmdW5jdGlvbiAoSGFuZGxlLCBjYWxsYmFja19mdW5jLCB0YWcpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJHZXRBY2xFbmFibGVkU3RhdGUiLCB7ICJIYW5kbGUiOiBIYW5kbGUgfSwgY2FsbGJhY2tfZnVuYywgdGFnKTsgfQ0KICAgIG9iai5BTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZV9SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9FbmRwb2ludEFjY2Vzc0NvbnRyb2xTZXJ2aWNlIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZV9HZXRQb3N0dXJlID0gZnVuY3Rpb24gKFBvc3R1cmVUeXBlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZSIsICJHZXRQb3N0dXJlIiwgeyAiUG9zdHVyZVR5cGUiOiBQb3N0dXJlVHlwZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZV9HZXRQb3N0dXJlSGFzaCA9IGZ1bmN0aW9uIChQb3N0dXJlVHlwZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0VuZHBvaW50QWNjZXNzQ29udHJvbFNlcnZpY2UiLCAiR2V0UG9zdHVyZUhhc2giLCB7ICJQb3N0dXJlVHlwZSI6IFBvc3R1cmVUeXBlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9FbmRwb2ludEFjY2Vzc0NvbnRyb2xTZXJ2aWNlX1VwZGF0ZVBvc3R1cmVTdGF0ZSA9IGZ1bmN0aW9uIChVcGRhdGVUeXBlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZSIsICJVcGRhdGVQb3N0dXJlU3RhdGUiLCB7ICJVcGRhdGVUeXBlIjogVXBkYXRlVHlwZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZV9HZXRFYWNPcHRpb25zID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9FbmRwb2ludEFjY2Vzc0NvbnRyb2xTZXJ2aWNlIiwgIkdldEVhY09wdGlvbnMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0VuZHBvaW50QWNjZXNzQ29udHJvbFNlcnZpY2VfU2V0RWFjT3B0aW9ucyA9IGZ1bmN0aW9uIChFYWNWZW5kb3JzLCBQb3N0dXJlSGFzaEFsZ29yaXRobSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0VuZHBvaW50QWNjZXNzQ29udHJvbFNlcnZpY2UiLCAiU2V0RWFjT3B0aW9ucyIsIHsgIkVhY1ZlbmRvcnMiOiBFYWNWZW5kb3JzLCAiUG9zdHVyZUhhc2hBbGdvcml0aG0iOiBQb3N0dXJlSGFzaEFsZ29yaXRobSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRW52aXJvbm1lbnREZXRlY3Rpb25TZXR0aW5nRGF0YV9TZXRTeXN0ZW1EZWZlbnNlUG9saWN5ID0gZnVuY3Rpb24gKFBvbGljeSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0Vudmlyb25tZW50RGV0ZWN0aW9uU2V0dGluZ0RhdGEiLCAiU2V0U3lzdGVtRGVmZW5zZVBvbGljeSIsIHsgIlBvbGljeSI6IFBvbGljeSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRW52aXJvbm1lbnREZXRlY3Rpb25TZXR0aW5nRGF0YV9FbmFibGVWcG5Sb3V0aW5nID0gZnVuY3Rpb24gKEVuYWJsZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0Vudmlyb25tZW50RGV0ZWN0aW9uU2V0dGluZ0RhdGEiLCAiRW5hYmxlVnBuUm91dGluZyIsIHsgIkVuYWJsZSI6IEVuYWJsZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRXRoZXJuZXRQb3J0U2V0dGluZ3NfU2V0TGlua1ByZWZlcmVuY2UgPSBmdW5jdGlvbiAoTGlua1ByZWZlcmVuY2UsIFRpbWVvdXQsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyIsICJTZXRMaW5rUHJlZmVyZW5jZSIsIHsgIkxpbmtQcmVmZXJlbmNlIjogTGlua1ByZWZlcmVuY2UsICJUaW1lb3V0IjogVGltZW91dCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfSGV1cmlzdGljUGFja2V0RmlsdGVyU3RhdGlzdGljc19SZXNldFNlbGVjdGVkU3RhdHMgPSBmdW5jdGlvbiAoU2VsZWN0ZWRTdGF0aXN0aWNzLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfSGV1cmlzdGljUGFja2V0RmlsdGVyU3RhdGlzdGljcyIsICJSZXNldFNlbGVjdGVkU3RhdHMiLCB7ICJTZWxlY3RlZFN0YXRpc3RpY3MiOiBTZWxlY3RlZFN0YXRpc3RpY3MgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0tlcmJlcm9zU2V0dGluZ0RhdGFfR2V0Q3JlZGVudGlhbENhY2hlU3RhdGUgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0tlcmJlcm9zU2V0dGluZ0RhdGEiLCAiR2V0Q3JlZGVudGlhbENhY2hlU3RhdGUiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0tlcmJlcm9zU2V0dGluZ0RhdGFfU2V0Q3JlZGVudGlhbENhY2hlU3RhdGUgPSBmdW5jdGlvbiAoRW5hYmxlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfS2VyYmVyb3NTZXR0aW5nRGF0YSIsICJTZXRDcmVkZW50aWFsQ2FjaGVTdGF0ZSIsIHsgIkVuYWJsZSI6IEVuYWJsZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfTWVzc2FnZUxvZ19DYW5jZWxJdGVyYXRpb24gPSBmdW5jdGlvbiAoSXRlcmF0aW9uSWRlbnRpZmllciwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX01lc3NhZ2VMb2ciLCAiQ2FuY2VsSXRlcmF0aW9uIiwgeyAiSXRlcmF0aW9uSWRlbnRpZmllciI6IEl0ZXJhdGlvbklkZW50aWZpZXIgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX01lc3NhZ2VMb2dfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfTWVzc2FnZUxvZyIsICJSZXF1ZXN0U3RhdGVDaGFuZ2UiLCB7ICJSZXF1ZXN0ZWRTdGF0ZSI6IFJlcXVlc3RlZFN0YXRlLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX01lc3NhZ2VMb2dfQ2xlYXJMb2cgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX01lc3NhZ2VMb2ciLCAiQ2xlYXJMb2ciLCB7IH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9NZXNzYWdlTG9nX0dldFJlY29yZHMgPSBmdW5jdGlvbiAoSXRlcmF0aW9uSWRlbnRpZmllciwgTWF4UmVhZFJlY29yZHMsIGNhbGxiYWNrX2Z1bmMsIHRhZykgeyBvYmouRXhlYygiQU1UX01lc3NhZ2VMb2ciLCAiR2V0UmVjb3JkcyIsIHsgIkl0ZXJhdGlvbklkZW50aWZpZXIiOiBJdGVyYXRpb25JZGVudGlmaWVyLCAiTWF4UmVhZFJlY29yZHMiOiBNYXhSZWFkUmVjb3JkcyB9LCBjYWxsYmFja19mdW5jLCB0YWcpOyB9DQogICAgb2JqLkFNVF9NZXNzYWdlTG9nX0dldFJlY29yZCA9IGZ1bmN0aW9uIChJdGVyYXRpb25JZGVudGlmaWVyLCBQb3NpdGlvblRvTmV4dCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX01lc3NhZ2VMb2ciLCAiR2V0UmVjb3JkIiwgeyAiSXRlcmF0aW9uSWRlbnRpZmllciI6IEl0ZXJhdGlvbklkZW50aWZpZXIsICJQb3NpdGlvblRvTmV4dCI6IFBvc2l0aW9uVG9OZXh0IH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9NZXNzYWdlTG9nX1Bvc2l0aW9uQXRSZWNvcmQgPSBmdW5jdGlvbiAoSXRlcmF0aW9uSWRlbnRpZmllciwgTW92ZUFic29sdXRlLCBSZWNvcmROdW1iZXIsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9NZXNzYWdlTG9nIiwgIlBvc2l0aW9uQXRSZWNvcmQiLCB7ICJJdGVyYXRpb25JZGVudGlmaWVyIjogSXRlcmF0aW9uSWRlbnRpZmllciwgIk1vdmVBYnNvbHV0ZSI6IE1vdmVBYnNvbHV0ZSwgIlJlY29yZE51bWJlciI6IFJlY29yZE51bWJlciB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfTWVzc2FnZUxvZ19Qb3NpdGlvblRvRmlyc3RSZWNvcmQgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYywgdGFnKSB7IG9iai5FeGVjKCJBTVRfTWVzc2FnZUxvZyIsICJQb3NpdGlvblRvRmlyc3RSZWNvcmQiLCB7fSwgY2FsbGJhY2tfZnVuYywgdGFnKTsgfQ0KICAgIG9iai5BTVRfTWVzc2FnZUxvZ19GcmVlemVMb2cgPSBmdW5jdGlvbiAoRnJlZXplLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfTWVzc2FnZUxvZyIsICJGcmVlemVMb2ciLCB7ICJGcmVlemUiOiBGcmVlemUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1B1YmxpY0tleU1hbmFnZW1lbnRTZXJ2aWNlX0FkZENSTCA9IGZ1bmN0aW9uIChVcmwsIFNlcmlhbE51bWJlcnMsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZSIsICJBZGRDUkwiLCB7ICJVcmwiOiBVcmwsICJTZXJpYWxOdW1iZXJzIjogU2VyaWFsTnVtYmVycyB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfUmVzZXRDUkxMaXN0ID0gZnVuY3Rpb24gKF9tZXRob2RfZHVtbXksIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZSIsICJSZXNldENSTExpc3QiLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfQWRkQ2VydGlmaWNhdGUgPSBmdW5jdGlvbiAoQ2VydGlmaWNhdGVCbG9iLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2UiLCAiQWRkQ2VydGlmaWNhdGUiLCB7ICJDZXJ0aWZpY2F0ZUJsb2IiOiBDZXJ0aWZpY2F0ZUJsb2IgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1B1YmxpY0tleU1hbmFnZW1lbnRTZXJ2aWNlX0FkZFRydXN0ZWRSb290Q2VydGlmaWNhdGUgPSBmdW5jdGlvbiAoQ2VydGlmaWNhdGVCbG9iLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2UiLCAiQWRkVHJ1c3RlZFJvb3RDZXJ0aWZpY2F0ZSIsIHsgIkNlcnRpZmljYXRlQmxvYiI6IENlcnRpZmljYXRlQmxvYiB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfQWRkS2V5ID0gZnVuY3Rpb24gKEtleUJsb2IsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZSIsICJBZGRLZXkiLCB7ICJLZXlCbG9iIjogS2V5QmxvYiB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfR2VuZXJhdGVQS0NTMTBSZXF1ZXN0ID0gZnVuY3Rpb24gKEtleVBhaXIsIEROTmFtZSwgVXNhZ2UsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZSIsICJHZW5lcmF0ZVBLQ1MxMFJlcXVlc3QiLCB7ICJLZXlQYWlyIjogS2V5UGFpciwgIkROTmFtZSI6IEROTmFtZSwgIlVzYWdlIjogVXNhZ2UgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1B1YmxpY0tleU1hbmFnZW1lbnRTZXJ2aWNlX0dlbmVyYXRlUEtDUzEwUmVxdWVzdEV4ID0gZnVuY3Rpb24gKEtleVBhaXIsIFNpZ25pbmdBbGdvcml0aG0sIE51bGxTaWduZWRDZXJ0aWZpY2F0ZVJlcXVlc3QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZSIsICJHZW5lcmF0ZVBLQ1MxMFJlcXVlc3RFeCIsIHsgIktleVBhaXIiOiBLZXlQYWlyLCAiU2lnbmluZ0FsZ29yaXRobSI6IFNpZ25pbmdBbGdvcml0aG0sICJOdWxsU2lnbmVkQ2VydGlmaWNhdGVSZXF1ZXN0IjogTnVsbFNpZ25lZENlcnRpZmljYXRlUmVxdWVzdCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfR2VuZXJhdGVLZXlQYWlyID0gZnVuY3Rpb24gKEtleUFsZ29yaXRobSwgS2V5TGVuZ3RoLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2UiLCAiR2VuZXJhdGVLZXlQYWlyIiwgeyAiS2V5QWxnb3JpdGhtIjogS2V5QWxnb3JpdGhtLCAiS2V5TGVuZ3RoIjogS2V5TGVuZ3RoIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9SZWRpcmVjdGlvblNlcnZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUmVkaXJlY3Rpb25TZXJ2aWNlIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1JlZGlyZWN0aW9uU2VydmljZV9UZXJtaW5hdGVTZXNzaW9uID0gZnVuY3Rpb24gKFNlc3Npb25UeXBlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUmVkaXJlY3Rpb25TZXJ2aWNlIiwgIlRlcm1pbmF0ZVNlc3Npb24iLCB7ICJTZXNzaW9uVHlwZSI6IFNlc3Npb25UeXBlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9SZW1vdGVBY2Nlc3NTZXJ2aWNlX0FkZE1wU2VydmVyID0gZnVuY3Rpb24gKEFjY2Vzc0luZm8sIEluZm9Gb3JtYXQsIFBvcnQsIEF1dGhNZXRob2QsIENlcnRpZmljYXRlLCBVc2VybmFtZSwgUGFzc3dvcmQsIENOLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUmVtb3RlQWNjZXNzU2VydmljZSIsICJBZGRNcFNlcnZlciIsIHsgIkFjY2Vzc0luZm8iOiBBY2Nlc3NJbmZvLCAiSW5mb0Zvcm1hdCI6IEluZm9Gb3JtYXQsICJQb3J0IjogUG9ydCwgIkF1dGhNZXRob2QiOiBBdXRoTWV0aG9kLCAiQ2VydGlmaWNhdGUiOiBDZXJ0aWZpY2F0ZSwgIlVzZXJuYW1lIjogVXNlcm5hbWUsICJQYXNzd29yZCI6IFBhc3N3b3JkLCAiQ04iOiBDTiB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUmVtb3RlQWNjZXNzU2VydmljZV9BZGRSZW1vdGVBY2Nlc3NQb2xpY3lSdWxlID0gZnVuY3Rpb24gKFRyaWdnZXIsIFR1bm5lbExpZmVUaW1lLCBFeHRlbmRlZERhdGEsIE1wU2VydmVyLCBJbnRlcm5hbE1wU2VydmVyLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUmVtb3RlQWNjZXNzU2VydmljZSIsICJBZGRSZW1vdGVBY2Nlc3NQb2xpY3lSdWxlIiwgeyAiVHJpZ2dlciI6IFRyaWdnZXIsICJUdW5uZWxMaWZlVGltZSI6IFR1bm5lbExpZmVUaW1lLCAiRXh0ZW5kZWREYXRhIjogRXh0ZW5kZWREYXRhLCAiTXBTZXJ2ZXIiOiBNcFNlcnZlciwgIkludGVybmFsTXBTZXJ2ZXIiOiBJbnRlcm5hbE1wU2VydmVyIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9SZW1vdGVBY2Nlc3NTZXJ2aWNlX0Nsb3NlUmVtb3RlQWNjZXNzQ29ubmVjdGlvbiA9IGZ1bmN0aW9uIChfbWV0aG9kX2R1bW15LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUmVtb3RlQWNjZXNzU2VydmljZSIsICJDbG9zZVJlbW90ZUFjY2Vzc0Nvbm5lY3Rpb24iLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9Db21taXRDaGFuZ2VzID0gZnVuY3Rpb24gKF9tZXRob2RfZHVtbXksIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIiwgIkNvbW1pdENoYW5nZXMiLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9VbnByb3Zpc2lvbiA9IGZ1bmN0aW9uIChQcm92aXNpb25pbmdNb2RlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIsICJVbnByb3Zpc2lvbiIsIHsgIlByb3Zpc2lvbmluZ01vZGUiOiBQcm92aXNpb25pbmdNb2RlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlX1BhcnRpYWxVbnByb3Zpc2lvbiA9IGZ1bmN0aW9uIChfbWV0aG9kX2R1bW15LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIsICJQYXJ0aWFsVW5wcm92aXNpb24iLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9SZXNldEZsYXNoV2Vhck91dFByb3RlY3Rpb24gPSBmdW5jdGlvbiAoX21ldGhvZF9kdW1teSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2UiLCAiUmVzZXRGbGFzaFdlYXJPdXRQcm90ZWN0aW9uIiwgeyAiX21ldGhvZF9kdW1teSI6IF9tZXRob2RfZHVtbXkgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2VfRXh0ZW5kUHJvdmlzaW9uaW5nUGVyaW9kID0gZnVuY3Rpb24gKER1cmF0aW9uLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIsICJFeHRlbmRQcm92aXNpb25pbmdQZXJpb2QiLCB7ICJEdXJhdGlvbiI6IER1cmF0aW9uIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlX1NldE1FQnhQYXNzd29yZCA9IGZ1bmN0aW9uIChQYXNzd29yZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2UiLCAiU2V0TUVCeFBhc3N3b3JkIiwgeyAiUGFzc3dvcmQiOiBQYXNzd29yZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9TZXRUTFNQU0sgPSBmdW5jdGlvbiAoUElELCBQUFMsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIiwgIlNldFRMU1BTSyIsIHsgIlBJRCI6IFBJRCwgIlBQUyI6IFBQUyB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9HZXRQcm92aXNpb25pbmdBdWRpdFJlY29yZCA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIsICJHZXRQcm92aXNpb25pbmdBdWRpdFJlY29yZCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9HZXRVdWlkID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIiwgIkdldFV1aWQiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2VfR2V0VW5wcm92aXNpb25CbG9ja2luZ0NvbXBvbmVudHMgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2UiLCAiR2V0VW5wcm92aXNpb25CbG9ja2luZ0NvbXBvbmVudHMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2VfR2V0UHJvdmlzaW9uaW5nQXVkaXRSZWNvcmRWMiA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIsICJHZXRQcm92aXNpb25pbmdBdWRpdFJlY29yZFYyIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9TeXN0ZW1EZWZlbnNlUG9saWN5X0dldFRpbWVvdXQgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX1N5c3RlbURlZmVuc2VQb2xpY3kiLCAiR2V0VGltZW91dCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU3lzdGVtRGVmZW5zZVBvbGljeV9TZXRUaW1lb3V0ID0gZnVuY3Rpb24gKFRpbWVvdXQsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9TeXN0ZW1EZWZlbnNlUG9saWN5IiwgIlNldFRpbWVvdXQiLCB7ICJUaW1lb3V0IjogVGltZW91dCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU3lzdGVtRGVmZW5zZVBvbGljeV9VcGRhdGVTdGF0aXN0aWNzID0gZnVuY3Rpb24gKE5ldHdvcmtJbnRlcmZhY2UsIFJlc2V0T25SZWFkLCBjYWxsYmFja19mdW5jLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai5FeGVjKCJBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSIsICJVcGRhdGVTdGF0aXN0aWNzIiwgeyAiTmV0d29ya0ludGVyZmFjZSI6IE5ldHdvcmtJbnRlcmZhY2UsICJSZXNldE9uUmVhZCI6IFJlc2V0T25SZWFkIH0sIGNhbGxiYWNrX2Z1bmMsIHRhZywgcHJpLCBzZWxlY3RvcnMpOyB9DQogICAgb2JqLkFNVF9TeXN0ZW1Qb3dlclNjaGVtZV9TZXRQb3dlclNjaGVtZSA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jLCBzY2hlbWVJbnN0YW5jZUlkLCB0YWcpIHsgb2JqLkV4ZWMoIkFNVF9TeXN0ZW1Qb3dlclNjaGVtZSIsICJTZXRQb3dlclNjaGVtZSIsIHt9LCBjYWxsYmFja19mdW5jLCB0YWcsIDAsIHsgIkluc3RhbmNlSUQiOiBzY2hlbWVJbnN0YW5jZUlkIH0pOyB9DQogICAgb2JqLkFNVF9UaW1lU3luY2hyb25pemF0aW9uU2VydmljZV9HZXRMb3dBY2N1cmFjeVRpbWVTeW5jaCA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jLCB0YWcpIHsgb2JqLkV4ZWMoIkFNVF9UaW1lU3luY2hyb25pemF0aW9uU2VydmljZSIsICJHZXRMb3dBY2N1cmFjeVRpbWVTeW5jaCIsIHt9LCBjYWxsYmFja19mdW5jLCB0YWcpOyB9DQogICAgb2JqLkFNVF9UaW1lU3luY2hyb25pemF0aW9uU2VydmljZV9TZXRIaWdoQWNjdXJhY3lUaW1lU3luY2ggPSBmdW5jdGlvbiAoVGEwLCBUbTEsIFRtMiwgY2FsbGJhY2tfZnVuYywgdGFnKSB7IG9iai5FeGVjKCJBTVRfVGltZVN5bmNocm9uaXphdGlvblNlcnZpY2UiLCAiU2V0SGlnaEFjY3VyYWN5VGltZVN5bmNoIiwgeyAiVGEwIjogVGEwLCAiVG0xIjogVG0xLCAiVG0yIjogVG0yIH0sIGNhbGxiYWNrX2Z1bmMsIHRhZyk7IH0NCiAgICBvYmouQU1UX1VzZXJJbml0aWF0ZWRDb25uZWN0aW9uU2VydmljZV9SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9Vc2VySW5pdGlhdGVkQ29ubmVjdGlvblNlcnZpY2UiLCAiUmVxdWVzdFN0YXRlQ2hhbmdlIiwgeyAiUmVxdWVzdGVkU3RhdGUiOiBSZXF1ZXN0ZWRTdGF0ZSwgIlRpbWVvdXRQZXJpb2QiOiBUaW1lb3V0UGVyaW9kIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9XZWJVSVNlcnZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfV2ViVUlTZXJ2aWNlIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfV2lGaVBvcnRDb25maWd1cmF0aW9uU2VydmljZV9BZGRXaUZpU2V0dGluZ3MgPSBmdW5jdGlvbiAoV2lGaUVuZHBvaW50LCBXaUZpRW5kcG9pbnRTZXR0aW5nc0lucHV0LCBJRUVFODAyMXhTZXR0aW5nc0lucHV0LCBDbGllbnRDcmVkZW50aWFsLCBDQUNyZWRlbnRpYWwsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWNXaXRoWG1sKCJBTVRfV2lGaVBvcnRDb25maWd1cmF0aW9uU2VydmljZSIsICJBZGRXaUZpU2V0dGluZ3MiLCB7ICJXaUZpRW5kcG9pbnQiOiBXaUZpRW5kcG9pbnQsICJXaUZpRW5kcG9pbnRTZXR0aW5nc0lucHV0IjogV2lGaUVuZHBvaW50U2V0dGluZ3NJbnB1dCwgIklFRUU4MDIxeFNldHRpbmdzSW5wdXQiOiBJRUVFODAyMXhTZXR0aW5nc0lucHV0LCAiQ2xpZW50Q3JlZGVudGlhbCI6IENsaWVudENyZWRlbnRpYWwsICJDQUNyZWRlbnRpYWwiOiBDQUNyZWRlbnRpYWwgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1dpRmlQb3J0Q29uZmlndXJhdGlvblNlcnZpY2VfVXBkYXRlV2lGaVNldHRpbmdzID0gZnVuY3Rpb24gKFdpRmlFbmRwb2ludFNldHRpbmdzLCBXaUZpRW5kcG9pbnRTZXR0aW5nc0lucHV0LCBJRUVFODAyMXhTZXR0aW5nc0lucHV0LCBDbGllbnRDcmVkZW50aWFsLCBDQUNyZWRlbnRpYWwsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWNXaXRoWG1sKCJBTVRfV2lGaVBvcnRDb25maWd1cmF0aW9uU2VydmljZSIsICJVcGRhdGVXaUZpU2V0dGluZ3MiLCB7ICJXaUZpRW5kcG9pbnRTZXR0aW5ncyI6IFdpRmlFbmRwb2ludFNldHRpbmdzLCAiV2lGaUVuZHBvaW50U2V0dGluZ3NJbnB1dCI6IFdpRmlFbmRwb2ludFNldHRpbmdzSW5wdXQsICJJRUVFODAyMXhTZXR0aW5nc0lucHV0IjogSUVFRTgwMjF4U2V0dGluZ3NJbnB1dCwgIkNsaWVudENyZWRlbnRpYWwiOiBDbGllbnRDcmVkZW50aWFsLCAiQ0FDcmVkZW50aWFsIjogQ0FDcmVkZW50aWFsIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9XaUZpUG9ydENvbmZpZ3VyYXRpb25TZXJ2aWNlX0RlbGV0ZUFsbElUUHJvZmlsZXMgPSBmdW5jdGlvbiAoX21ldGhvZF9kdW1teSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX1dpRmlQb3J0Q29uZmlndXJhdGlvblNlcnZpY2UiLCAiRGVsZXRlQWxsSVRQcm9maWxlcyIsIHsgIl9tZXRob2RfZHVtbXkiOiBfbWV0aG9kX2R1bW15IH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9XaUZpUG9ydENvbmZpZ3VyYXRpb25TZXJ2aWNlX0RlbGV0ZUFsbFVzZXJQcm9maWxlcyA9IGZ1bmN0aW9uIChfbWV0aG9kX2R1bW15LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfV2lGaVBvcnRDb25maWd1cmF0aW9uU2VydmljZSIsICJEZWxldGVBbGxVc2VyUHJvZmlsZXMiLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fQWNjb3VudF9SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9BY2NvdW50IiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fQWNjb3VudE1hbmFnZW1lbnRTZXJ2aWNlX0NyZWF0ZUFjY291bnQgPSBmdW5jdGlvbiAoU3lzdGVtLCBBY2NvdW50VGVtcGxhdGUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9BY2NvdW50TWFuYWdlbWVudFNlcnZpY2UiLCAiQ3JlYXRlQWNjb3VudCIsIHsgIlN5c3RlbSI6IFN5c3RlbSwgIkFjY291bnRUZW1wbGF0ZSI6IEFjY291bnRUZW1wbGF0ZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fQm9vdENvbmZpZ1NldHRpbmdfQ2hhbmdlQm9vdE9yZGVyID0gZnVuY3Rpb24gKFNvdXJjZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX0Jvb3RDb25maWdTZXR0aW5nIiwgIkNoYW5nZUJvb3RPcmRlciIsIHsgIlNvdXJjZSI6IFNvdXJjZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fQm9vdFNlcnZpY2VfU2V0Qm9vdENvbmZpZ1JvbGUgPSBmdW5jdGlvbiAoQm9vdENvbmZpZ1NldHRpbmcsIFJvbGUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9Cb290U2VydmljZSIsICJTZXRCb290Q29uZmlnUm9sZSIsIHsgIkJvb3RDb25maWdTZXR0aW5nIjogQm9vdENvbmZpZ1NldHRpbmcsICJSb2xlIjogUm9sZSB9LCBjYWxsYmFja19mdW5jLCAwLCAxKTsgfQ0KICAgIG9iai5DSU1fQ2FyZF9Db25uZWN0b3JQb3dlciA9IGZ1bmN0aW9uIChDb25uZWN0b3IsIFBvd2VyZWRPbiwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX0NhcmQiLCAiQ29ubmVjdG9yUG93ZXIiLCB7ICJDb25uZWN0b3IiOiBDb25uZWN0b3IsICJQb3dlcmVkT24iOiBQb3dlcmVkT24gfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX0NhcmRfSXNDb21wYXRpYmxlID0gZnVuY3Rpb24gKEVsZW1lbnRUb0NoZWNrLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fQ2FyZCIsICJJc0NvbXBhdGlibGUiLCB7ICJFbGVtZW50VG9DaGVjayI6IEVsZW1lbnRUb0NoZWNrIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9DaGFzc2lzX0lzQ29tcGF0aWJsZSA9IGZ1bmN0aW9uIChFbGVtZW50VG9DaGVjaywgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX0NoYXNzaXMiLCAiSXNDb21wYXRpYmxlIiwgeyAiRWxlbWVudFRvQ2hlY2siOiBFbGVtZW50VG9DaGVjayB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fRmFuX1NldFNwZWVkID0gZnVuY3Rpb24gKERlc2lyZWRTcGVlZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX0ZhbiIsICJTZXRTcGVlZCIsIHsgIkRlc2lyZWRTcGVlZCI6IERlc2lyZWRTcGVlZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fS1ZNUmVkaXJlY3Rpb25TQVBfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fS1ZNUmVkaXJlY3Rpb25TQVAiLCAiUmVxdWVzdFN0YXRlQ2hhbmdlIiwgeyAiUmVxdWVzdGVkU3RhdGUiOiBSZXF1ZXN0ZWRTdGF0ZS8qLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgKi99LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfTG9ja01lZGlhID0gZnVuY3Rpb24gKExvY2ssIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9NZWRpYUFjY2Vzc0RldmljZSIsICJMb2NrTWVkaWEiLCB7ICJMb2NrIjogTG9jayB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfU2V0UG93ZXJTdGF0ZSA9IGZ1bmN0aW9uIChQb3dlclN0YXRlLCBUaW1lLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fTWVkaWFBY2Nlc3NEZXZpY2UiLCAiU2V0UG93ZXJTdGF0ZSIsIHsgIlBvd2VyU3RhdGUiOiBQb3dlclN0YXRlLCAiVGltZSI6IFRpbWUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX01lZGlhQWNjZXNzRGV2aWNlX1Jlc2V0ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9NZWRpYUFjY2Vzc0RldmljZSIsICJSZXNldCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfRW5hYmxlRGV2aWNlID0gZnVuY3Rpb24gKEVuYWJsZWQsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9NZWRpYUFjY2Vzc0RldmljZSIsICJFbmFibGVEZXZpY2UiLCB7ICJFbmFibGVkIjogRW5hYmxlZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfT25saW5lRGV2aWNlID0gZnVuY3Rpb24gKE9ubGluZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX01lZGlhQWNjZXNzRGV2aWNlIiwgIk9ubGluZURldmljZSIsIHsgIk9ubGluZSI6IE9ubGluZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfUXVpZXNjZURldmljZSA9IGZ1bmN0aW9uIChRdWllc2NlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fTWVkaWFBY2Nlc3NEZXZpY2UiLCAiUXVpZXNjZURldmljZSIsIHsgIlF1aWVzY2UiOiBRdWllc2NlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9NZWRpYUFjY2Vzc0RldmljZV9TYXZlUHJvcGVydGllcyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fTWVkaWFBY2Nlc3NEZXZpY2UiLCAiU2F2ZVByb3BlcnRpZXMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX01lZGlhQWNjZXNzRGV2aWNlX1Jlc3RvcmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9NZWRpYUFjY2Vzc0RldmljZSIsICJSZXN0b3JlUHJvcGVydGllcyIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fTWVkaWFBY2Nlc3NEZXZpY2UiLCAiUmVxdWVzdFN0YXRlQ2hhbmdlIiwgeyAiUmVxdWVzdGVkU3RhdGUiOiBSZXF1ZXN0ZWRTdGF0ZSwgIlRpbWVvdXRQZXJpb2QiOiBUaW1lb3V0UGVyaW9kIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9QaHlzaWNhbEZyYW1lX0lzQ29tcGF0aWJsZSA9IGZ1bmN0aW9uIChFbGVtZW50VG9DaGVjaywgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1BoeXNpY2FsRnJhbWUiLCAiSXNDb21wYXRpYmxlIiwgeyAiRWxlbWVudFRvQ2hlY2siOiBFbGVtZW50VG9DaGVjayB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUGh5c2ljYWxQYWNrYWdlX0lzQ29tcGF0aWJsZSA9IGZ1bmN0aW9uIChFbGVtZW50VG9DaGVjaywgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1BoeXNpY2FsUGFja2FnZSIsICJJc0NvbXBhdGlibGUiLCB7ICJFbGVtZW50VG9DaGVjayI6IEVsZW1lbnRUb0NoZWNrIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9Qb3dlck1hbmFnZW1lbnRTZXJ2aWNlX1JlcXVlc3RQb3dlclN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFBvd2VyU3RhdGUsIE1hbmFnZWRFbGVtZW50LCBUaW1lLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUG93ZXJNYW5hZ2VtZW50U2VydmljZSIsICJSZXF1ZXN0UG93ZXJTdGF0ZUNoYW5nZSIsIHsgIlBvd2VyU3RhdGUiOiBQb3dlclN0YXRlLCAiTWFuYWdlZEVsZW1lbnQiOiBNYW5hZ2VkRWxlbWVudCwgIlRpbWUiOiBUaW1lLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYywgMCwgMSk7IH0NCiAgICBvYmouQ0lNX1Bvd2VyU3VwcGx5X1NldFBvd2VyU3RhdGUgPSBmdW5jdGlvbiAoUG93ZXJTdGF0ZSwgVGltZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Bvd2VyU3VwcGx5IiwgIlNldFBvd2VyU3RhdGUiLCB7ICJQb3dlclN0YXRlIjogUG93ZXJTdGF0ZSwgIlRpbWUiOiBUaW1lIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9Qb3dlclN1cHBseV9SZXNldCA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUG93ZXJTdXBwbHkiLCAiUmVzZXQiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Bvd2VyU3VwcGx5X0VuYWJsZURldmljZSA9IGZ1bmN0aW9uIChFbmFibGVkLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUG93ZXJTdXBwbHkiLCAiRW5hYmxlRGV2aWNlIiwgeyAiRW5hYmxlZCI6IEVuYWJsZWQgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Bvd2VyU3VwcGx5X09ubGluZURldmljZSA9IGZ1bmN0aW9uIChPbmxpbmUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9Qb3dlclN1cHBseSIsICJPbmxpbmVEZXZpY2UiLCB7ICJPbmxpbmUiOiBPbmxpbmUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Bvd2VyU3VwcGx5X1F1aWVzY2VEZXZpY2UgPSBmdW5jdGlvbiAoUXVpZXNjZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Bvd2VyU3VwcGx5IiwgIlF1aWVzY2VEZXZpY2UiLCB7ICJRdWllc2NlIjogUXVpZXNjZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUG93ZXJTdXBwbHlfU2F2ZVByb3BlcnRpZXMgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Bvd2VyU3VwcGx5IiwgIlNhdmVQcm9wZXJ0aWVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9Qb3dlclN1cHBseV9SZXN0b3JlUHJvcGVydGllcyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUG93ZXJTdXBwbHkiLCAiUmVzdG9yZVByb3BlcnRpZXMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Bvd2VyU3VwcGx5X1JlcXVlc3RTdGF0ZUNoYW5nZSA9IGZ1bmN0aW9uIChSZXF1ZXN0ZWRTdGF0ZSwgVGltZW91dFBlcmlvZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Bvd2VyU3VwcGx5IiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUHJvY2Vzc29yX1NldFBvd2VyU3RhdGUgPSBmdW5jdGlvbiAoUG93ZXJTdGF0ZSwgVGltZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Byb2Nlc3NvciIsICJTZXRQb3dlclN0YXRlIiwgeyAiUG93ZXJTdGF0ZSI6IFBvd2VyU3RhdGUsICJUaW1lIjogVGltZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUHJvY2Vzc29yX1Jlc2V0ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9Qcm9jZXNzb3IiLCAiUmVzZXQiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Byb2Nlc3Nvcl9FbmFibGVEZXZpY2UgPSBmdW5jdGlvbiAoRW5hYmxlZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Byb2Nlc3NvciIsICJFbmFibGVEZXZpY2UiLCB7ICJFbmFibGVkIjogRW5hYmxlZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUHJvY2Vzc29yX09ubGluZURldmljZSA9IGZ1bmN0aW9uIChPbmxpbmUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9Qcm9jZXNzb3IiLCAiT25saW5lRGV2aWNlIiwgeyAiT25saW5lIjogT25saW5lIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9Qcm9jZXNzb3JfUXVpZXNjZURldmljZSA9IGZ1bmN0aW9uIChRdWllc2NlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUHJvY2Vzc29yIiwgIlF1aWVzY2VEZXZpY2UiLCB7ICJRdWllc2NlIjogUXVpZXNjZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUHJvY2Vzc29yX1NhdmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9Qcm9jZXNzb3IiLCAiU2F2ZVByb3BlcnRpZXMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Byb2Nlc3Nvcl9SZXN0b3JlUHJvcGVydGllcyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUHJvY2Vzc29yIiwgIlJlc3RvcmVQcm9wZXJ0aWVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9Qcm9jZXNzb3JfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUHJvY2Vzc29yIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUmVjb3JkTG9nX0NsZWFyTG9nID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9SZWNvcmRMb2ciLCAiQ2xlYXJMb2ciLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1JlY29yZExvZ19SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9SZWNvcmRMb2ciLCAiUmVxdWVzdFN0YXRlQ2hhbmdlIiwgeyAiUmVxdWVzdGVkU3RhdGUiOiBSZXF1ZXN0ZWRTdGF0ZSwgIlRpbWVvdXRQZXJpb2QiOiBUaW1lb3V0UGVyaW9kIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9SZWRpcmVjdGlvblNlcnZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUmVkaXJlY3Rpb25TZXJ2aWNlIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fU2Vuc29yX1NldFBvd2VyU3RhdGUgPSBmdW5jdGlvbiAoUG93ZXJTdGF0ZSwgVGltZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1NlbnNvciIsICJTZXRQb3dlclN0YXRlIiwgeyAiUG93ZXJTdGF0ZSI6IFBvd2VyU3RhdGUsICJUaW1lIjogVGltZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fU2Vuc29yX1Jlc2V0ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9TZW5zb3IiLCAiUmVzZXQiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1NlbnNvcl9FbmFibGVEZXZpY2UgPSBmdW5jdGlvbiAoRW5hYmxlZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1NlbnNvciIsICJFbmFibGVEZXZpY2UiLCB7ICJFbmFibGVkIjogRW5hYmxlZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fU2Vuc29yX09ubGluZURldmljZSA9IGZ1bmN0aW9uIChPbmxpbmUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9TZW5zb3IiLCAiT25saW5lRGV2aWNlIiwgeyAiT25saW5lIjogT25saW5lIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9TZW5zb3JfUXVpZXNjZURldmljZSA9IGZ1bmN0aW9uIChRdWllc2NlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fU2Vuc29yIiwgIlF1aWVzY2VEZXZpY2UiLCB7ICJRdWllc2NlIjogUXVpZXNjZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fU2Vuc29yX1NhdmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9TZW5zb3IiLCAiU2F2ZVByb3BlcnRpZXMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1NlbnNvcl9SZXN0b3JlUHJvcGVydGllcyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fU2Vuc29yIiwgIlJlc3RvcmVQcm9wZXJ0aWVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9TZW5zb3JfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fU2Vuc29yIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fU3RhdGlzdGljYWxEYXRhX1Jlc2V0U2VsZWN0ZWRTdGF0cyA9IGZ1bmN0aW9uIChTZWxlY3RlZFN0YXRpc3RpY3MsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9TdGF0aXN0aWNhbERhdGEiLCAiUmVzZXRTZWxlY3RlZFN0YXRzIiwgeyAiU2VsZWN0ZWRTdGF0aXN0aWNzIjogU2VsZWN0ZWRTdGF0aXN0aWNzIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XYXRjaGRvZ19LZWVwQWxpdmUgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1dhdGNoZG9nIiwgIktlZXBBbGl2ZSIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2F0Y2hkb2dfU2V0UG93ZXJTdGF0ZSA9IGZ1bmN0aW9uIChQb3dlclN0YXRlLCBUaW1lLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fV2F0Y2hkb2ciLCAiU2V0UG93ZXJTdGF0ZSIsIHsgIlBvd2VyU3RhdGUiOiBQb3dlclN0YXRlLCAiVGltZSI6IFRpbWUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1dhdGNoZG9nX1Jlc2V0ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XYXRjaGRvZyIsICJSZXNldCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2F0Y2hkb2dfRW5hYmxlRGV2aWNlID0gZnVuY3Rpb24gKEVuYWJsZWQsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XYXRjaGRvZyIsICJFbmFibGVEZXZpY2UiLCB7ICJFbmFibGVkIjogRW5hYmxlZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2F0Y2hkb2dfT25saW5lRGV2aWNlID0gZnVuY3Rpb24gKE9ubGluZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1dhdGNoZG9nIiwgIk9ubGluZURldmljZSIsIHsgIk9ubGluZSI6IE9ubGluZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2F0Y2hkb2dfUXVpZXNjZURldmljZSA9IGZ1bmN0aW9uIChRdWllc2NlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fV2F0Y2hkb2ciLCAiUXVpZXNjZURldmljZSIsIHsgIlF1aWVzY2UiOiBRdWllc2NlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XYXRjaGRvZ19TYXZlUHJvcGVydGllcyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fV2F0Y2hkb2ciLCAiU2F2ZVByb3BlcnRpZXMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1dhdGNoZG9nX1Jlc3RvcmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XYXRjaGRvZyIsICJSZXN0b3JlUHJvcGVydGllcyIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2F0Y2hkb2dfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fV2F0Y2hkb2ciLCAiUmVxdWVzdFN0YXRlQ2hhbmdlIiwgeyAiUmVxdWVzdGVkU3RhdGUiOiBSZXF1ZXN0ZWRTdGF0ZSwgIlRpbWVvdXRQZXJpb2QiOiBUaW1lb3V0UGVyaW9kIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XaUZpUG9ydF9TZXRQb3dlclN0YXRlID0gZnVuY3Rpb24gKFBvd2VyU3RhdGUsIFRpbWUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XaUZpUG9ydCIsICJTZXRQb3dlclN0YXRlIiwgeyAiUG93ZXJTdGF0ZSI6IFBvd2VyU3RhdGUsICJUaW1lIjogVGltZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2lGaVBvcnRfUmVzZXQgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1dpRmlQb3J0IiwgIlJlc2V0Iiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XaUZpUG9ydF9FbmFibGVEZXZpY2UgPSBmdW5jdGlvbiAoRW5hYmxlZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1dpRmlQb3J0IiwgIkVuYWJsZURldmljZSIsIHsgIkVuYWJsZWQiOiBFbmFibGVkIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XaUZpUG9ydF9PbmxpbmVEZXZpY2UgPSBmdW5jdGlvbiAoT25saW5lLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fV2lGaVBvcnQiLCAiT25saW5lRGV2aWNlIiwgeyAiT25saW5lIjogT25saW5lIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XaUZpUG9ydF9RdWllc2NlRGV2aWNlID0gZnVuY3Rpb24gKFF1aWVzY2UsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XaUZpUG9ydCIsICJRdWllc2NlRGV2aWNlIiwgeyAiUXVpZXNjZSI6IFF1aWVzY2UgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1dpRmlQb3J0X1NhdmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XaUZpUG9ydCIsICJTYXZlUHJvcGVydGllcyIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2lGaVBvcnRfUmVzdG9yZVByb3BlcnRpZXMgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1dpRmlQb3J0IiwgIlJlc3RvcmVQcm9wZXJ0aWVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XaUZpUG9ydF9SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XaUZpUG9ydCIsICJSZXF1ZXN0U3RhdGVDaGFuZ2UiLCB7ICJSZXF1ZXN0ZWRTdGF0ZSI6IFJlcXVlc3RlZFN0YXRlLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX0hvc3RCYXNlZFNldHVwU2VydmljZV9TZXR1cCA9IGZ1bmN0aW9uIChOZXRBZG1pblBhc3NFbmNyeXB0aW9uVHlwZSwgTmV0d29ya0FkbWluUGFzc3dvcmQsIE1jTm9uY2UsIENlcnRpZmljYXRlLCBTaWduaW5nQWxnb3JpdGhtLCBEaWdpdGFsU2lnbmF0dXJlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlIiwgIlNldHVwIiwgeyAiTmV0QWRtaW5QYXNzRW5jcnlwdGlvblR5cGUiOiBOZXRBZG1pblBhc3NFbmNyeXB0aW9uVHlwZSwgIk5ldHdvcmtBZG1pblBhc3N3b3JkIjogTmV0d29ya0FkbWluUGFzc3dvcmQsICJNY05vbmNlIjogTWNOb25jZSwgIkNlcnRpZmljYXRlIjogQ2VydGlmaWNhdGUsICJTaWduaW5nQWxnb3JpdGhtIjogU2lnbmluZ0FsZ29yaXRobSwgIkRpZ2l0YWxTaWduYXR1cmUiOiBEaWdpdGFsU2lnbmF0dXJlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2VfQWRkTmV4dENlcnRJbkNoYWluID0gZnVuY3Rpb24gKE5leHRDZXJ0aWZpY2F0ZSwgSXNMZWFmQ2VydGlmaWNhdGUsIElzUm9vdENlcnRpZmljYXRlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlIiwgIkFkZE5leHRDZXJ0SW5DaGFpbiIsIHsgIk5leHRDZXJ0aWZpY2F0ZSI6IE5leHRDZXJ0aWZpY2F0ZSwgIklzTGVhZkNlcnRpZmljYXRlIjogSXNMZWFmQ2VydGlmaWNhdGUsICJJc1Jvb3RDZXJ0aWZpY2F0ZSI6IElzUm9vdENlcnRpZmljYXRlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2VfQWRtaW5TZXR1cCA9IGZ1bmN0aW9uIChOZXRBZG1pblBhc3NFbmNyeXB0aW9uVHlwZSwgTmV0d29ya0FkbWluUGFzc3dvcmQsIE1jTm9uY2UsIFNpZ25pbmdBbGdvcml0aG0sIERpZ2l0YWxTaWduYXR1cmUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIklQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2UiLCAiQWRtaW5TZXR1cCIsIHsgIk5ldEFkbWluUGFzc0VuY3J5cHRpb25UeXBlIjogTmV0QWRtaW5QYXNzRW5jcnlwdGlvblR5cGUsICJOZXR3b3JrQWRtaW5QYXNzd29yZCI6IE5ldHdvcmtBZG1pblBhc3N3b3JkLCAiTWNOb25jZSI6IE1jTm9uY2UsICJTaWduaW5nQWxnb3JpdGhtIjogU2lnbmluZ0FsZ29yaXRobSwgIkRpZ2l0YWxTaWduYXR1cmUiOiBEaWdpdGFsU2lnbmF0dXJlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2VfVXBncmFkZUNsaWVudFRvQWRtaW4gPSBmdW5jdGlvbiAoTWNOb25jZSwgU2lnbmluZ0FsZ29yaXRobSwgRGlnaXRhbFNpZ25hdHVyZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX0hvc3RCYXNlZFNldHVwU2VydmljZSIsICJVcGdyYWRlQ2xpZW50VG9BZG1pbiIsIHsgIk1jTm9uY2UiOiBNY05vbmNlLCAiU2lnbmluZ0FsZ29yaXRobSI6IFNpZ25pbmdBbGdvcml0aG0sICJEaWdpdGFsU2lnbmF0dXJlIjogRGlnaXRhbFNpZ25hdHVyZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlX0Rpc2FibGVDbGllbnRDb250cm9sTW9kZSA9IGZ1bmN0aW9uIChfbWV0aG9kX2R1bW15LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlIiwgIkRpc2FibGVDbGllbnRDb250cm9sTW9kZSIsIHsgIl9tZXRob2RfZHVtbXkiOiBfbWV0aG9kX2R1bW15IH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19LVk1SZWRpcmVjdGlvblNldHRpbmdEYXRhX1Rlcm1pbmF0ZVNlc3Npb24gPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEiLCAiVGVybWluYXRlU2Vzc2lvbiIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfS1ZNUmVkaXJlY3Rpb25TZXR0aW5nRGF0YV9EYXRhQ2hhbm5lbFJlYWQgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEiLCAiRGF0YUNoYW5uZWxSZWFkIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19LVk1SZWRpcmVjdGlvblNldHRpbmdEYXRhX0RhdGFDaGFubmVsV3JpdGUgPSBmdW5jdGlvbiAoRGF0YSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEiLCAiRGF0YUNoYW5uZWxXcml0ZSIsIHsgIkRhdGFNZXNzYWdlIjogRGF0YSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfT3B0SW5TZXJ2aWNlX1N0YXJ0T3B0SW4gPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX09wdEluU2VydmljZSIsICJTdGFydE9wdEluIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19PcHRJblNlcnZpY2VfQ2FuY2VsT3B0SW4gPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX09wdEluU2VydmljZSIsICJDYW5jZWxPcHRJbiIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfT3B0SW5TZXJ2aWNlX1NlbmRPcHRJbkNvZGUgPSBmdW5jdGlvbiAoT3B0SW5Db2RlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfT3B0SW5TZXJ2aWNlIiwgIlNlbmRPcHRJbkNvZGUiLCB7ICJPcHRJbkNvZGUiOiBPcHRJbkNvZGUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX09wdEluU2VydmljZV9TdGFydFNlcnZpY2UgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX09wdEluU2VydmljZSIsICJTdGFydFNlcnZpY2UiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX09wdEluU2VydmljZV9TdG9wU2VydmljZSA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfT3B0SW5TZXJ2aWNlIiwgIlN0b3BTZXJ2aWNlIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19PcHRJblNlcnZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfT3B0SW5TZXJ2aWNlIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfUHJvdmlzaW9uaW5nUmVjb3JkTG9nX1JlcXVlc3RTdGF0ZUNoYW5nZSA9IGZ1bmN0aW9uIChSZXF1ZXN0ZWRTdGF0ZSwgVGltZW91dFBlcmlvZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX1Byb3Zpc2lvbmluZ1JlY29yZExvZyIsICJSZXF1ZXN0U3RhdGVDaGFuZ2UiLCB7ICJSZXF1ZXN0ZWRTdGF0ZSI6IFJlcXVlc3RlZFN0YXRlLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX1Byb3Zpc2lvbmluZ1JlY29yZExvZ19DbGVhckxvZyA9IGZ1bmN0aW9uIChfbWV0aG9kX2R1bW15LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfUHJvdmlzaW9uaW5nUmVjb3JkTG9nIiwgIkNsZWFyTG9nIiwgeyAiX21ldGhvZF9kdW1teSI6IF9tZXRob2RfZHVtbXkgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX1NjcmVlbkNvbmZpZ3VyYXRpb25TZXJ2aWNlX1NldFNlc3Npb25TdGF0ZSA9IGZ1bmN0aW9uIChTZXNzaW9uU3RhdGUsIENvbnNlY3V0aXZlUmVib290c051bSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX1NjcmVlbkNvbmZpZ3VyYXRpb25TZXJ2aWNlIiwgIlNldFNlc3Npb25TdGF0ZSIsIHsgIlNlc3Npb25TdGF0ZSI6IFNlc3Npb25TdGF0ZSwgIkNvbnNlY3V0aXZlUmVib290c051bSI6IENvbnNlY3V0aXZlUmVib290c051bSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfU2VjSU9TZXJ2aWNlX1JlcXVlc3RTdGF0ZUNoYW5nZSA9IGZ1bmN0aW9uIChSZXF1ZXN0ZWRTdGF0ZSwgVGltZW91dFBlcmlvZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX1NlY0lPU2VydmljZSIsICJSZXF1ZXN0U3RhdGVDaGFuZ2UiLCB7ICJSZXF1ZXN0ZWRTdGF0ZSI6IFJlcXVlc3RlZFN0YXRlLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX0hUVFBQcm94eVNlcnZpY2VfQWRkUHJveHlBY2Nlc3NQb2ludCA9IGZ1bmN0aW9uIChBY2Nlc3NJbmZvLCBJbmZvRm9ybWF0LCBQb3J0LCBOZXR3b3JrRG5zU3VmZml4LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfSFRUUFByb3h5U2VydmljZSIsICJBZGRQcm94eUFjY2Vzc1BvaW50IiwgeyAiQWNjZXNzSW5mbyI6IEFjY2Vzc0luZm8sICJJbmZvRm9ybWF0IjogSW5mb0Zvcm1hdCwgIlBvcnQiOiBQb3J0LCAiTmV0d29ya0Ruc1N1ZmZpeCI6IE5ldHdvcmtEbnNTdWZmaXggfSwgY2FsbGJhY2tfZnVuYyk7IH0NCg0KICAgIG9iai5BbXRTdGF0dXNUb1N0ciA9IGZ1bmN0aW9uIChjb2RlKSB7IGlmIChvYmouQW10U3RhdHVzQ29kZXNbY29kZV0pIHJldHVybiBvYmouQW10U3RhdHVzQ29kZXNbY29kZV07IGVsc2UgcmV0dXJuICJVTktOT1dOX0VSUk9SIiB9DQogICAgb2JqLkFtdFN0YXR1c0NvZGVzID0gew0KICAgICAgICAweDAwMDA6ICJTVUNDRVNTIiwNCiAgICAgICAgMHgwMDAxOiAiSU5URVJOQUxfRVJST1IiLA0KICAgICAgICAweDAwMDI6ICJOT1RfUkVBRFkiLA0KICAgICAgICAweDAwMDM6ICJJTlZBTElEX1BUX01PREUiLA0KICAgICAgICAweDAwMDQ6ICJJTlZBTElEX01FU1NBR0VfTEVOR1RIIiwNCiAgICAgICAgMHgwMDA1OiAiVEFCTEVfRklOR0VSUFJJTlRfTk9UX0FWQUlMQUJMRSIsDQogICAgICAgIDB4MDAwNjogIklOVEVHUklUWV9DSEVDS19GQUlMRUQiLA0KICAgICAgICAweDAwMDc6ICJVTlNVUFBPUlRFRF9JU1ZTX1ZFUlNJT04iLA0KICAgICAgICAweDAwMDg6ICJBUFBMSUNBVElPTl9OT1RfUkVHSVNURVJFRCIsDQogICAgICAgIDB4MDAwOTogIklOVkFMSURfUkVHSVNUUkFUSU9OX0RBVEEiLA0KICAgICAgICAweDAwMEE6ICJBUFBMSUNBVElPTl9ET0VTX05PVF9FWElTVCIsDQogICAgICAgIDB4MDAwQjogIk5PVF9FTk9VR0hfU1RPUkFHRSIsDQogICAgICAgIDB4MDAwQzogIklOVkFMSURfTkFNRSIsDQogICAgICAgIDB4MDAwRDogIkJMT0NLX0RPRVNfTk9UX0VYSVNUIiwNCiAgICAgICAgMHgwMDBFOiAiSU5WQUxJRF9CWVRFX09GRlNFVCIsDQogICAgICAgIDB4MDAwRjogIklOVkFMSURfQllURV9DT1VOVCIsDQogICAgICAgIDB4MDAxMDogIk5PVF9QRVJNSVRURUQiLA0KICAgICAgICAweDAwMTE6ICJOT1RfT1dORVIiLA0KICAgICAgICAweDAwMTI6ICJCTE9DS19MT0NLRURfQllfT1RIRVIiLA0KICAgICAgICAweDAwMTM6ICJCTE9DS19OT1RfTE9DS0VEIiwNCiAgICAgICAgMHgwMDE0OiAiSU5WQUxJRF9HUk9VUF9QRVJNSVNTSU9OUyIsDQogICAgICAgIDB4MDAxNTogIkdST1VQX0RPRVNfTk9UX0VYSVNUIiwNCiAgICAgICAgMHgwMDE2OiAiSU5WQUxJRF9NRU1CRVJfQ09VTlQiLA0KICAgICAgICAweDAwMTc6ICJNQVhfTElNSVRfUkVBQ0hFRCIsDQogICAgICAgIDB4MDAxODogIklOVkFMSURfQVVUSF9UWVBFIiwNCiAgICAgICAgMHgwMDE5OiAiQVVUSEVOVElDQVRJT05fRkFJTEVEIiwNCiAgICAgICAgMHgwMDFBOiAiSU5WQUxJRF9ESENQX01PREUiLA0KICAgICAgICAweDAwMUI6ICJJTlZBTElEX0lQX0FERFJFU1MiLA0KICAgICAgICAweDAwMUM6ICJJTlZBTElEX0RPTUFJTl9OQU1FIiwNCiAgICAgICAgMHgwMDFEOiAiVU5TVVBQT1JURURfVkVSU0lPTiIsDQogICAgICAgIDB4MDAxRTogIlJFUVVFU1RfVU5FWFBFQ1RFRCIsDQogICAgICAgIDB4MDAxRjogIklOVkFMSURfVEFCTEVfVFlQRSIsDQogICAgICAgIDB4MDAyMDogIklOVkFMSURfUFJPVklTSU9OSU5HX1NUQVRFIiwNCiAgICAgICAgMHgwMDIxOiAiVU5TVVBQT1JURURfT0JKRUNUIiwNCiAgICAgICAgMHgwMDIyOiAiSU5WQUxJRF9USU1FIiwNCiAgICAgICAgMHgwMDIzOiAiSU5WQUxJRF9JTkRFWCIsDQogICAgICAgIDB4MDAyNDogIklOVkFMSURfUEFSQU1FVEVSIiwNCiAgICAgICAgMHgwMDI1OiAiSU5WQUxJRF9ORVRNQVNLIiwNCiAgICAgICAgMHgwMDI2OiAiRkxBU0hfV1JJVEVfTElNSVRfRVhDRUVERUQiLA0KICAgICAgICAweDAwMjc6ICJJTlZBTElEX0lNQUdFX0xFTkdUSCIsDQogICAgICAgIDB4MDAyODogIklOVkFMSURfSU1BR0VfU0lHTkFUVVJFIiwNCiAgICAgICAgMHgwMDI5OiAiUFJPUE9TRV9BTk9USEVSX1ZFUlNJT04iLA0KICAgICAgICAweDAwMkE6ICJJTlZBTElEX1BJRF9GT1JNQVQiLA0KICAgICAgICAweDAwMkI6ICJJTlZBTElEX1BQU19GT1JNQVQiLA0KICAgICAgICAweDAwMkM6ICJCSVNUX0NPTU1BTkRfQkxPQ0tFRCIsDQogICAgICAgIDB4MDAyRDogIkNPTk5FQ1RJT05fRkFJTEVEIiwNCiAgICAgICAgMHgwMDJFOiAiQ09OTkVDVElPTl9UT09fTUFOWSIsDQogICAgICAgIDB4MDAyRjogIlJOR19HRU5FUkFUSU9OX0lOX1BST0dSRVNTIiwNCiAgICAgICAgMHgwMDMwOiAiUk5HX05PVF9SRUFEWSIsDQogICAgICAgIDB4MDAzMTogIkNFUlRJRklDQVRFX05PVF9SRUFEWSIsDQogICAgICAgIDB4MDQwMDogIkRJU0FCTEVEX0JZX1BPTElDWSIsDQogICAgICAgIDB4MDgwMDogIk5FVFdPUktfSUZfRVJST1JfQkFTRSIsDQogICAgICAgIDB4MDgwMTogIlVOU1VQUE9SVEVEX09FTV9OVU1CRVIiLA0KICAgICAgICAweDA4MDI6ICJVTlNVUFBPUlRFRF9CT09UX09QVElPTiIsDQogICAgICAgIDB4MDgwMzogIklOVkFMSURfQ09NTUFORCIsDQogICAgICAgIDB4MDgwNDogIklOVkFMSURfU1BFQ0lBTF9DT01NQU5EIiwNCiAgICAgICAgMHgwODA1OiAiSU5WQUxJRF9IQU5ETEUiLA0KICAgICAgICAweDA4MDY6ICJJTlZBTElEX1BBU1NXT1JEIiwNCiAgICAgICAgMHgwODA3OiAiSU5WQUxJRF9SRUFMTSIsDQogICAgICAgIDB4MDgwODogIlNUT1JBR0VfQUNMX0VOVFJZX0lOX1VTRSIsDQogICAgICAgIDB4MDgwOTogIkRBVEFfTUlTU0lORyIsDQogICAgICAgIDB4MDgwQTogIkRVUExJQ0FURSIsDQogICAgICAgIDB4MDgwQjogIkVWRU5UTE9HX0ZST1pFTiIsDQogICAgICAgIDB4MDgwQzogIlBLSV9NSVNTSU5HX0tFWVMiLA0KICAgICAgICAweDA4MEQ6ICJQS0lfR0VORVJBVElOR19LRVlTIiwNCiAgICAgICAgMHgwODBFOiAiSU5WQUxJRF9LRVkiLA0KICAgICAgICAweDA4MEY6ICJJTlZBTElEX0NFUlQiLA0KICAgICAgICAweDA4MTA6ICJDRVJUX0tFWV9OT1RfTUFUQ0giLA0KICAgICAgICAweDA4MTE6ICJNQVhfS0VSQl9ET01BSU5fUkVBQ0hFRCIsDQogICAgICAgIDB4MDgxMjogIlVOU1VQUE9SVEVEIiwNCiAgICAgICAgMHgwODEzOiAiSU5WQUxJRF9QUklPUklUWSIsDQogICAgICAgIDB4MDgxNDogIk5PVF9GT1VORCIsDQogICAgICAgIDB4MDgxNTogIklOVkFMSURfQ1JFREVOVElBTFMiLA0KICAgICAgICAweDA4MTY6ICJJTlZBTElEX1BBU1NQSFJBU0UiLA0KICAgICAgICAweDA4MTg6ICJOT19BU1NPQ0lBVElPTiIsDQogICAgICAgIDB4MDgxQjogIkFVRElUX0ZBSUwiLA0KICAgICAgICAweDA4MUM6ICJCTE9DS0lOR19DT01QT05FTlQiLA0KICAgICAgICAweDA4MjE6ICJVU0VSX0NPTlNFTlRfUkVRVUlSRUQiLA0KICAgICAgICAweDEwMDA6ICJBUFBfSU5URVJOQUxfRVJST1IiLA0KICAgICAgICAweDEwMDE6ICJOT1RfSU5JVElBTElaRUQiLA0KICAgICAgICAweDEwMDI6ICJMSUJfVkVSU0lPTl9VTlNVUFBPUlRFRCIsDQogICAgICAgIDB4MTAwMzogIklOVkFMSURfUEFSQU0iLA0KICAgICAgICAweDEwMDQ6ICJSRVNPVVJDRVMiLA0KICAgICAgICAweDEwMDU6ICJIQVJEV0FSRV9BQ0NFU1NfRVJST1IiLA0KICAgICAgICAweDEwMDY6ICJSRVFVRVNUT1JfTk9UX1JFR0lTVEVSRUQiLA0KICAgICAgICAweDEwMDc6ICJORVRXT1JLX0VSUk9SIiwNCiAgICAgICAgMHgxMDA4OiAiUEFSQU1fQlVGRkVSX1RPT19TSE9SVCIsDQogICAgICAgIDB4MTAwOTogIkNPTV9OT1RfSU5JVElBTElaRURfSU5fVEhSRUFEIiwNCiAgICAgICAgMHgxMDBBOiAiVVJMX1JFUVVJUkVEIg0KICAgIH0NCg0KICAgIC8vDQogICAgLy8gTWV0aG9kcyB1c2VkIGZvciBnZXR0aW5nIHRoZSBldmVudCBsb2cNCiAgICAvLw0KDQogICAgb2JqLkdldE1lc3NhZ2VMb2cgPSBmdW5jdGlvbiAoZnVuYywgdGFnKSB7DQogICAgICAgIG9iai5BTVRfTWVzc2FnZUxvZ19Qb3NpdGlvblRvRmlyc3RSZWNvcmQoX0dldE1lc3NhZ2VMb2cwLCBbZnVuYywgdGFnLCBbXV0pOw0KICAgIH0NCiAgICBmdW5jdGlvbiBfR2V0TWVzc2FnZUxvZzAoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzLCB0YWcpIHsNCiAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDAgfHwgcmVzcG9uc2VzLkJvZHlbIlJldHVyblZhbHVlIl0gIT0gJzAnKSB7IHRhZ1swXShvYmosIG51bGwsIHRhZ1syXSk7IHJldHVybjsgfQ0KICAgICAgICBvYmouQU1UX01lc3NhZ2VMb2dfR2V0UmVjb3JkcyhyZXNwb25zZXMuQm9keVsiSXRlcmF0aW9uSWRlbnRpZmllciJdLCAzOTAsIF9HZXRNZXNzYWdlTG9nMSwgdGFnKTsNCiAgICB9DQogICAgZnVuY3Rpb24gX0dldE1lc3NhZ2VMb2cxKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cywgdGFnKSB7DQogICAgICAgIGlmIChzdGF0dXMgIT0gMjAwIHx8IHJlc3BvbnNlcy5Cb2R5WyJSZXR1cm5WYWx1ZSJdICE9ICcwJykgeyB0YWdbMF0ob2JqLCBudWxsLCB0YWdbMl0pOyByZXR1cm47IH0NCiAgICAgICAgdmFyIGksIGosIHgsIGUsIEFtdE1lc3NhZ2VzID0gdGFnWzJdLCB0ID0gbmV3IERhdGUoKSwgVGltZVN0YW1wLCByYSA9IHJlc3BvbnNlcy5Cb2R5WyJSZWNvcmRBcnJheSJdOw0KICAgICAgICBpZiAodHlwZW9mIHJhID09PSAnc3RyaW5nJykgeyByZXNwb25zZXMuQm9keVsiUmVjb3JkQXJyYXkiXSA9IFtyZXNwb25zZXMuQm9keVsiUmVjb3JkQXJyYXkiXV07IH0NCg0KICAgICAgICBmb3IgKGkgaW4gcmEpIHsNCiAgICAgICAgICAgIGUgPSBudWxsOw0KICAgICAgICAgICAgdHJ5IHsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAvLyBOb2RlSlMgZGV0ZWN0aW9uDQogICAgICAgICAgICAgICAgdmFyIGlzTm9kZSA9IG5ldyBGdW5jdGlvbigidHJ5IHtyZXR1cm4gdGhpcz09PWdsb2JhbDt9Y2F0Y2goZSl7cmV0dXJuIGZhbHNlO30iKTsNCiAgICAgICAgICAgICAgICBpZiAoaXNOb2RlKCkpIHsgZSA9IHJlcXVpcmUoJ2F0b2InKShyYVtpXSk7IH0gZWxzZSB7IGUgPSB3aW5kb3cuYXRvYihyYVtpXSk7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHsgfQ0KICAgICAgICAgICAgaWYgKGUgIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgIFRpbWVTdGFtcCA9IFJlYWRJbnRYKGUsIDApOw0KICAgICAgICAgICAgICAgIGlmICgoVGltZVN0YW1wID4gMCkgJiYgKFRpbWVTdGFtcCA8IDB4RkZGRkZGRkYpKSB7DQogICAgICAgICAgICAgICAgICAgIHggPSB7ICdEZXZpY2VBZGRyZXNzJzogZS5jaGFyQ29kZUF0KDQpLCAnRXZlbnRTZW5zb3JUeXBlJzogZS5jaGFyQ29kZUF0KDUpLCAnRXZlbnRUeXBlJzogZS5jaGFyQ29kZUF0KDYpLCAnRXZlbnRPZmZzZXQnOiBlLmNoYXJDb2RlQXQoNyksICdFdmVudFNvdXJjZVR5cGUnOiBlLmNoYXJDb2RlQXQoOCksICdFdmVudFNldmVyaXR5JzogZS5jaGFyQ29kZUF0KDkpLCAnU2Vuc29yTnVtYmVyJzogZS5jaGFyQ29kZUF0KDEwKSwgJ0VudGl0eSc6IGUuY2hhckNvZGVBdCgxMSksICdFbnRpdHlJbnN0YW5jZSc6IGUuY2hhckNvZGVBdCgxMiksICdFdmVudERhdGEnOiBbXSwgJ1RpbWUnOiBuZXcgRGF0ZSgoVGltZVN0YW1wICsgKHQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwKSkgKiAxMDAwKSB9Ow0KICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAxMzsgaiA8IDIxOyBqKyspIHsgeFsnRXZlbnREYXRhJ10ucHVzaChlLmNoYXJDb2RlQXQoaikpOyB9DQogICAgICAgICAgICAgICAgICAgIHhbJ0VudGl0eVN0ciddID0gX1N5c3RlbUVudGl0eVR5cGVzW3hbJ0VudGl0eSddXTsNCiAgICAgICAgICAgICAgICAgICAgeFsnRGVzYyddID0gX0dldEV2ZW50RGV0YWlsU3RyKHhbJ0V2ZW50U2Vuc29yVHlwZSddLCB4WydFdmVudE9mZnNldCddLCB4WydFdmVudERhdGEnXSwgeFsnRW50aXR5J10pOw0KICAgICAgICAgICAgICAgICAgICBpZiAoIXhbJ0VudGl0eVN0ciddKSB4WydFbnRpdHlTdHInXSA9ICJVbmtub3duIjsNCiAgICAgICAgICAgICAgICAgICAgQW10TWVzc2FnZXMucHVzaCh4KTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBpZiAocmVzcG9uc2VzLkJvZHlbIk5vTW9yZVJlY29yZHMiXSAhPSB0cnVlKSB7IG9iai5BTVRfTWVzc2FnZUxvZ19HZXRSZWNvcmRzKHJlc3BvbnNlcy5Cb2R5WyJJdGVyYXRpb25JZGVudGlmaWVyIl0sIDM5MCwgX0dldE1lc3NhZ2VMb2cxLCBbdGFnWzBdLCBBbXRNZXNzYWdlcywgdGFnWzJdXSk7IH0gZWxzZSB7IHRhZ1swXShvYmosIEFtdE1lc3NhZ2VzLCB0YWdbMl0pOyB9DQogICAgfQ0KDQogICAgdmFyIF9FdmVudFRyYXBTb3VyY2VUeXBlcyA9ICJQbGF0Zm9ybSBmaXJtd2FyZSAoZS5nLiBCSU9TKXxTTUkgaGFuZGxlcnxJU1Ygc3lzdGVtIG1hbmFnZW1lbnQgc29mdHdhcmV8QWxlcnQgQVNJQ3xJUE1JfEJJT1MgdmVuZG9yfFN5c3RlbSBib2FyZCBzZXQgdmVuZG9yfFN5c3RlbSBpbnRlZ3JhdG9yfFRoaXJkIHBhcnR5IGFkZC1pbnxPU1Z8TklDfFN5c3RlbSBtYW5hZ2VtZW50IGNhcmQiLnNwbGl0KCd8Jyk7DQogICAgdmFyIF9TeXN0ZW1GaXJtd2FyZUVycm9yID0gIlVuc3BlY2lmaWVkLnxObyBzeXN0ZW0gbWVtb3J5IGlzIHBoeXNpY2FsbHkgaW5zdGFsbGVkIGluIHRoZSBzeXN0ZW0ufE5vIHVzYWJsZSBzeXN0ZW0gbWVtb3J5LCBhbGwgaW5zdGFsbGVkIG1lbW9yeSBoYXMgZXhwZXJpZW5jZWQgYW4gdW5yZWNvdmVyYWJsZSBmYWlsdXJlLnxVbnJlY292ZXJhYmxlIGhhcmQtZGlzay9BVEFQSS9JREUgZGV2aWNlIGZhaWx1cmUufFVucmVjb3ZlcmFibGUgc3lzdGVtLWJvYXJkIGZhaWx1cmUufFVucmVjb3ZlcmFibGUgZGlza2V0dGUgc3Vic3lzdGVtIGZhaWx1cmUufFVucmVjb3ZlcmFibGUgaGFyZC1kaXNrIGNvbnRyb2xsZXIgZmFpbHVyZS58VW5yZWNvdmVyYWJsZSBQUy8yIG9yIFVTQiBrZXlib2FyZCBmYWlsdXJlLnxSZW1vdmFibGUgYm9vdCBtZWRpYSBub3QgZm91bmQufFVucmVjb3ZlcmFibGUgdmlkZW8gY29udHJvbGxlciBmYWlsdXJlLnxObyB2aWRlbyBkZXZpY2UgZGV0ZWN0ZWQufEZpcm13YXJlIChCSU9TKSBST00gY29ycnVwdGlvbiBkZXRlY3RlZC58Q1BVIHZvbHRhZ2UgbWlzbWF0Y2ggKHByb2Nlc3NvcnMgdGhhdCBzaGFyZSBzYW1lIHN1cHBseSBoYXZlIG1pc21hdGNoZWQgdm9sdGFnZSByZXF1aXJlbWVudHMpfENQVSBzcGVlZCBtYXRjaGluZyBmYWlsdXJlIi5zcGxpdCgnfCcpOw0KICAgIHZhciBfU3lzdGVtRmlybXdhcmVQcm9ncmVzcyA9ICJVbnNwZWNpZmllZC58TWVtb3J5IGluaXRpYWxpemF0aW9uLnxTdGFydGluZyBoYXJkLWRpc2sgaW5pdGlhbGl6YXRpb24gYW5kIHRlc3R8U2Vjb25kYXJ5IHByb2Nlc3NvcihzKSBpbml0aWFsaXphdGlvbnxVc2VyIGF1dGhlbnRpY2F0aW9ufFVzZXItaW5pdGlhdGVkIHN5c3RlbSBzZXR1cHxVU0IgcmVzb3VyY2UgY29uZmlndXJhdGlvbnxQQ0kgcmVzb3VyY2UgY29uZmlndXJhdGlvbnxPcHRpb24gUk9NIGluaXRpYWxpemF0aW9ufFZpZGVvIGluaXRpYWxpemF0aW9ufENhY2hlIGluaXRpYWxpemF0aW9ufFNNIEJ1cyBpbml0aWFsaXphdGlvbnxLZXlib2FyZCBjb250cm9sbGVyIGluaXRpYWxpemF0aW9ufEVtYmVkZGVkIGNvbnRyb2xsZXIvbWFuYWdlbWVudCBjb250cm9sbGVyIGluaXRpYWxpemF0aW9ufERvY2tpbmcgc3RhdGlvbiBhdHRhY2htZW50fEVuYWJsaW5nIGRvY2tpbmcgc3RhdGlvbnxEb2NraW5nIHN0YXRpb24gZWplY3Rpb258RGlzYWJsaW5nIGRvY2tpbmcgc3RhdGlvbnxDYWxsaW5nIG9wZXJhdGluZyBzeXN0ZW0gd2FrZS11cCB2ZWN0b3J8U3RhcnRpbmcgb3BlcmF0aW5nIHN5c3RlbSBib290IHByb2Nlc3N8QmFzZWJvYXJkIG9yIG1vdGhlcmJvYXJkIGluaXRpYWxpemF0aW9ufHJlc2VydmVkfEZsb3BweSBpbml0aWFsaXphdGlvbnxLZXlib2FyZCB0ZXN0fFBvaW50aW5nIGRldmljZSB0ZXN0fFByaW1hcnkgcHJvY2Vzc29yIGluaXRpYWxpemF0aW9uIi5zcGxpdCgnfCcpOw0KICAgIHZhciBfU3lzdGVtRW50aXR5VHlwZXMgPSAiVW5zcGVjaWZpZWR8T3RoZXJ8VW5rbm93bnxQcm9jZXNzb3J8RGlza3xQZXJpcGhlcmFsfFN5c3RlbSBtYW5hZ2VtZW50IG1vZHVsZXxTeXN0ZW0gYm9hcmR8TWVtb3J5IG1vZHVsZXxQcm9jZXNzb3IgbW9kdWxlfFBvd2VyIHN1cHBseXxBZGQgaW4gY2FyZHxGcm9udCBwYW5lbCBib2FyZHxCYWNrIHBhbmVsIGJvYXJkfFBvd2VyIHN5c3RlbSBib2FyZHxEcml2ZSBiYWNrcGxhbmV8U3lzdGVtIGludGVybmFsIGV4cGFuc2lvbiBib2FyZHxPdGhlciBzeXN0ZW0gYm9hcmR8UHJvY2Vzc29yIGJvYXJkfFBvd2VyIHVuaXR8UG93ZXIgbW9kdWxlfFBvd2VyIG1hbmFnZW1lbnQgYm9hcmR8Q2hhc3NpcyBiYWNrIHBhbmVsIGJvYXJkfFN5c3RlbSBjaGFzc2lzfFN1YiBjaGFzc2lzfE90aGVyIGNoYXNzaXMgYm9hcmR8RGlzayBkcml2ZSBiYXl8UGVyaXBoZXJhbCBiYXl8RGV2aWNlIGJheXxGYW4gY29vbGluZ3xDb29saW5nIHVuaXR8Q2FibGUgaW50ZXJjb25uZWN0fE1lbW9yeSBkZXZpY2V8U3lzdGVtIG1hbmFnZW1lbnQgc29mdHdhcmV8QklPU3xJbnRlbChyKSBNRXxTeXN0ZW0gYnVzfEdyb3VwfEludGVsKHIpIE1FfEV4dGVybmFsIGVudmlyb25tZW50fEJhdHRlcnl8UHJvY2Vzc2luZyBibGFkZXxDb25uZWN0aXZpdHkgc3dpdGNofFByb2Nlc3Nvci9tZW1vcnkgbW9kdWxlfEkvTyBtb2R1bGV8UHJvY2Vzc29yIEkvTyBtb2R1bGV8TWFuYWdlbWVudCBjb250cm9sbGVyIGZpcm13YXJlfElQTUkgY2hhbm5lbHxQQ0kgYnVzfFBDSSBleHByZXNzIGJ1c3xTQ1NJIGJ1c3xTQVRBL1NBUyBidXN8UHJvY2Vzc29yIGZyb250IHNpZGUgYnVzIi5zcGxpdCgnfCcpOw0KICAgIG9iai5SZWFsbU5hbWVzID0gInx8UmVkaXJlY3Rpb258fEhhcmR3YXJlIEFzc2V0fFJlbW90ZSBDb250cm9sfFN0b3JhZ2V8RXZlbnQgTWFuYWdlcnxTdG9yYWdlIEFkbWlufEFnZW50IFByZXNlbmNlIExvY2FsfEFnZW50IFByZXNlbmNlIFJlbW90ZXxDaXJjdWl0IEJyZWFrZXJ8TmV0d29yayBUaW1lfEdlbmVyYWwgSW5mb3JtYXRpb258RmlybXdhcmUgVXBkYXRlfEVJVHxMb2NhbFVOfEVuZHBvaW50IEFjY2VzcyBDb250cm9sfEVuZHBvaW50IEFjY2VzcyBDb250cm9sIEFkbWlufEV2ZW50IExvZyBSZWFkZXJ8QXVkaXQgTG9nfEFDTCBSZWFsbXx8fExvY2FsIFN5c3RlbSIuc3BsaXQoJ3wnKTsNCiAgICBvYmouV2F0Y2hkb2dDdXJyZW50U3RhdGVzID0geyAxOiAnTm90IFN0YXJ0ZWQnLCAyOiAnU3RvcHBlZCcsIDQ6ICdSdW5uaW5nJywgODogJ0V4cGlyZWQnLCAxNjogJ1N1c3BlbmRlZCcgfTsNCg0KICAgIGZ1bmN0aW9uIF9HZXRFdmVudERldGFpbFN0cihldmVudFNlbnNvclR5cGUsIGV2ZW50T2Zmc2V0LCBldmVudERhdGFGaWVsZCwgZW50aXR5KSB7DQoNCiAgICAgICAgaWYgKGV2ZW50U2Vuc29yVHlwZSA9PSAxNSkgew0KICAgICAgICAgICAgaWYgKGV2ZW50RGF0YUZpZWxkWzBdID09IDIzNSkgcmV0dXJuICJJbnZhbGlkIERhdGEiOw0KICAgICAgICAgICAgaWYgKGV2ZW50T2Zmc2V0ID09IDApIHJldHVybiBfU3lzdGVtRmlybXdhcmVFcnJvcltldmVudERhdGFGaWVsZFsxXV07DQogICAgICAgICAgICByZXR1cm4gX1N5c3RlbUZpcm13YXJlUHJvZ3Jlc3NbZXZlbnREYXRhRmllbGRbMV1dOw0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKChldmVudFNlbnNvclR5cGUgPT0gMTgpICYmIChldmVudERhdGFGaWVsZFswXSA9PSAxNzApKSB7IC8vIFN5c3RlbSB3YXRjaGRvZyBldmVudA0KICAgICAgICAgICAgcmV0dXJuICJBZ2VudCB3YXRjaGRvZyAiICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbNF0pICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbM10pICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbMl0pICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbMV0pICsgIi0iICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbNl0pICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbNV0pICsgIi0uLi4gY2hhbmdlZCB0byAiICsgb2JqLldhdGNoZG9nQ3VycmVudFN0YXRlc1tldmVudERhdGFGaWVsZFs3XV07DQogICAgICAgIH0NCg0KICAgICAgICBpZiAoKGV2ZW50U2Vuc29yVHlwZSA9PSA1KSAmJiAoZXZlbnRPZmZzZXQgPT0gMCkpIHsgLy8gU3lzdGVtIGNoYXNzaXMNCiAgICAgICAgICAgIHJldHVybiAiQ2FzZSBpbnRydXNpb24iOw0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKChldmVudFNlbnNvclR5cGUgPT0gMTkyKSAmJiAoZXZlbnRPZmZzZXQgPT0gMCkgJiYgKGV2ZW50RGF0YUZpZWxkWzBdID09IDE3MCkgJiYgKGV2ZW50RGF0YUZpZWxkWzFdID09IDQ4KSkNCiAgICAgICAgew0KICAgICAgICAgICAgaWYgKGV2ZW50RGF0YUZpZWxkWzJdID09IDApIHJldHVybiAiQSByZW1vdGUgU2VyaWFsIE92ZXIgTEFOIHNlc3Npb24gd2FzIGVzdGFibGlzaGVkLiI7DQogICAgICAgICAgICBpZiAoZXZlbnREYXRhRmllbGRbMl0gPT0gMSkgcmV0dXJuICJSZW1vdGUgU2VyaWFsIE92ZXIgTEFOIHNlc3Npb24gZmluaXNoZWQuIFVzZXIgY29udHJvbCB3YXMgcmVzdG9yZWQuIjsNCiAgICAgICAgICAgIGlmIChldmVudERhdGFGaWVsZFsyXSA9PSAyKSByZXR1cm4gIkEgcmVtb3RlIElERS1SZWRpcmVjdGlvbiBzZXNzaW9uIHdhcyBlc3RhYmxpc2hlZC4iOw0KICAgICAgICAgICAgaWYgKGV2ZW50RGF0YUZpZWxkWzJdID09IDMpIHJldHVybiAiUmVtb3RlIElERS1SZWRpcmVjdGlvbiBzZXNzaW9uIGZpbmlzaGVkLiBVc2VyIGNvbnRyb2wgd2FzIHJlc3RvcmVkLiI7DQogICAgICAgIH0NCg0KICAgICAgICBpZiAoZXZlbnRTZW5zb3JUeXBlID09IDM2KSB7DQogICAgICAgICAgICB2YXIgaGFuZGxlID0gKGV2ZW50RGF0YUZpZWxkWzFdIDw8IDI0KSArIChldmVudERhdGFGaWVsZFsyXSA8PCAxNikgKyAoZXZlbnREYXRhRmllbGRbM10gPDwgOCkgKyBldmVudERhdGFGaWVsZFs0XTsNCiAgICAgICAgICAgIHZhciBuaWMgPSAiIyIgKyBldmVudERhdGFGaWVsZFswXTsNCiAgICAgICAgICAgIGlmIChldmVudERhdGFGaWVsZFswXSA9PSAweEFBKSBuaWMgPSAid2lyZWQiOyAvLyBUT0RPOiBBZGQgd2lyZWxlc3MgKioqKioNCiAgICAgICAgICAgIC8vaWYgKGV2ZW50RGF0YUZpZWxkWzBdID09IDB4QUEpIG5pYyA9ICJ3aXJlbGVzcyI7DQoNCiAgICAgICAgICAgIGlmIChoYW5kbGUgPT0gNDI5NDk2NzI5MykgeyByZXR1cm4gIkFsbCByZWNlaXZlZCBwYWNrZXQgZmlsdGVyIHdhcyBtYXRjaGVkIG9uICIgKyBuaWMgKyAiIGludGVyZmFjZS4iOyB9DQogICAgICAgICAgICBpZiAoaGFuZGxlID09IDQyOTQ5NjcyOTIpIHsgcmV0dXJuICJBbGwgb3V0Ym91bmQgcGFja2V0IGZpbHRlciB3YXMgbWF0Y2hlZCBvbiAiICsgbmljICsgIiBpbnRlcmZhY2UuIjsgfQ0KICAgICAgICAgICAgaWYgKGhhbmRsZSA9PSA0Mjk0OTY3MjkwKSB7IHJldHVybiAiU3Bvb2ZlZCBwYWNrZXQgZmlsdGVyIHdhcyBtYXRjaGVkIG9uICIgKyBuaWMgKyAiIGludGVyZmFjZS4iOyB9DQogICAgICAgICAgICByZXR1cm4gIkZpbHRlciAiICsgaGFuZGxlICsgIiB3YXMgbWF0Y2hlZCBvbiAiICsgbmljICsgIiBpbnRlcmZhY2UuIjsNCiAgICAgICAgfQ0KDQogICAgICAgIGlmIChldmVudFNlbnNvclR5cGUgPT0gMTkyKSB7DQogICAgICAgICAgICBpZiAoZXZlbnREYXRhRmllbGRbMl0gPT0gMCkgcmV0dXJuICJTZWN1cml0eSBwb2xpY3kgaW52b2tlZC4gU29tZSBvciBhbGwgbmV0d29yayB0cmFmZmljIChUWCkgd2FzIHN0b3BwZWQuIjsNCiAgICAgICAgICAgIGlmIChldmVudERhdGFGaWVsZFsyXSA9PSAyKSByZXR1cm4gIlNlY3VyaXR5IHBvbGljeSBpbnZva2VkLiBTb21lIG9yIGFsbCBuZXR3b3JrIHRyYWZmaWMgKFJYKSB3YXMgc3RvcHBlZC4iOw0KICAgICAgICAgICAgcmV0dXJuICJTZWN1cml0eSBwb2xpY3kgaW52b2tlZC4iOw0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKGV2ZW50U2Vuc29yVHlwZSA9PSAxOTMpIHsNCiAgICAgICAgICAgIGlmICgoZXZlbnREYXRhRmllbGRbMF0gPT0gMHhBQSkgJiYgKGV2ZW50RGF0YUZpZWxkWzFdID09IDB4MzApICYmIChldmVudERhdGFGaWVsZFsyXSA9PSAweDAwKSAmJiAoZXZlbnREYXRhRmllbGRbM10gPT0gMHgwMCkpIHsgcmV0dXJuICJVc2VyIHJlcXVlc3QgZm9yIHJlbW90ZSBjb25uZWN0aW9uLiI7IH0NCiAgICAgICAgICAgIGlmICgoZXZlbnREYXRhRmllbGRbMF0gPT0gMHhBQSkgJiYgKGV2ZW50RGF0YUZpZWxkWzFdID09IDB4MjApICYmIChldmVudERhdGFGaWVsZFsyXSA9PSAweDAzKSAmJiAoZXZlbnREYXRhRmllbGRbM10gPT0gMHgwMSkpIHsgcmV0dXJuICJFQUMgZXJyb3I6IGF0dGVtcHQgdG8gZ2V0IHBvc3R1cmUgd2hpbGUgTkFDIGluIEludGVs77+9IEFNVCBpcyBkaXNhYmxlZC4iOyB9IC8vIGV2ZW50RGF0YUZpZWxkID0gMHhBQTIwMDMwMTAwMDAwMDAwDQogICAgICAgICAgICBpZiAoKGV2ZW50RGF0YUZpZWxkWzBdID09IDB4QUEpICYmIChldmVudERhdGFGaWVsZFsxXSA9PSAweDIwKSAmJiAoZXZlbnREYXRhRmllbGRbMl0gPT0gMHgwNCkgJiYgKGV2ZW50RGF0YUZpZWxkWzNdID09IDB4MDApKSB7IHJldHVybiAiQ2VydGlmaWNhdGUgcmV2b2tlZC4gIjsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKGV2ZW50U2Vuc29yVHlwZSA9PSA2KSByZXR1cm4gIkF1dGhlbnRpY2F0aW9uIGZhaWxlZCAiICsgKGV2ZW50RGF0YUZpZWxkWzFdICsgKGV2ZW50RGF0YUZpZWxkWzJdIDw8IDgpKSArICIgdGltZXMuIFRoZSBzeXN0ZW0gbWF5IGJlIHVuZGVyIGF0dGFjay4iOw0KICAgICAgICBpZiAoZXZlbnRTZW5zb3JUeXBlID09IDMwKSByZXR1cm4gIk5vIGJvb3RhYmxlIG1lZGlhIjsNCiAgICAgICAgaWYgKGV2ZW50U2Vuc29yVHlwZSA9PSAzMikgcmV0dXJuICJPcGVyYXRpbmcgc3lzdGVtIGxvY2t1cCBvciBwb3dlciBpbnRlcnJ1cHQiOw0KICAgICAgICBpZiAoZXZlbnRTZW5zb3JUeXBlID09IDM1KSByZXR1cm4gIlN5c3RlbSBib290IGZhaWx1cmUiOw0KICAgICAgICBpZiAoZXZlbnRTZW5zb3JUeXBlID09IDM3KSByZXR1cm4gIlN5c3RlbSBmaXJtd2FyZSBzdGFydGVkIChhdCBsZWFzdCBvbmUgQ1BVIGlzIHByb3Blcmx5IGV4ZWN1dGluZykuIjsNCiAgICAgICAgcmV0dXJuICJVbmtub3duIFNlbnNvciBUeXBlICMiICsgZXZlbnRTZW5zb3JUeXBlOw0KICAgIH0NCg0KDQoNCiAgICAvLyBVc2VmdWwgbGluazogaHR0cHM6Ly9zb2Z0d2FyZS5pbnRlbC5jb20vc2l0ZXMvbWFuYWdlYWJpbGl0eS9BTVRfSW1wbGVtZW50YXRpb25fYW5kX1JlZmVyZW5jZV9HdWlkZS9kZWZhdWx0Lmh0bT90dXJsPVdvcmREb2N1bWVudHMlMkZzZWN1cml0eWFkbWluZXZlbnRzLmh0bQ0KDQogICAgdmFyIF9BbXRBdWRpdFN0cmluZ1RhYmxlID0NCiAgICB7DQogICAgICAgIDE2OiAnU2VjdXJpdHkgQWRtaW4nLA0KICAgICAgICAxNzogJ1JDTycsDQogICAgICAgIDE4OiAnUmVkaXJlY3Rpb24gTWFuYWdlcicsDQogICAgICAgIDE5OiAnRmlybXdhcmUgVXBkYXRlIE1hbmFnZXInLA0KICAgICAgICAyMDogJ1NlY3VyaXR5IEF1ZGl0IExvZycsDQogICAgICAgIDIxOiAnTmV0d29yayBUaW1lJywNCiAgICAgICAgMjI6ICdOZXR3b3JrIEFkbWluaXN0cmF0aW9uJywNCiAgICAgICAgMjM6ICdTdG9yYWdlIEFkbWluaXN0cmF0aW9uJywNCiAgICAgICAgMjQ6ICdFdmVudCBNYW5hZ2VyJywNCiAgICAgICAgMjU6ICdDaXJjdWl0IEJyZWFrZXIgTWFuYWdlcicsDQogICAgICAgIDI2OiAnQWdlbnQgUHJlc2VuY2UgTWFuYWdlcicsDQogICAgICAgIDI3OiAnV2lyZWxlc3MgQ29uZmlndXJhdGlvbicsDQogICAgICAgIDI4OiAnRUFDJywNCiAgICAgICAgMjk6ICdLVk0nLA0KICAgICAgICAzMDogJ1VzZXIgT3B0LUluIEV2ZW50cycsDQogICAgICAgIDMyOiAnU2NyZWVuIEJsYW5raW5nJywNCiAgICAgICAgMzM6ICdXYXRjaGRvZyBFdmVudHMnLA0KICAgICAgICAxNjAwOiAnUHJvdmlzaW9uaW5nIFN0YXJ0ZWQnLA0KICAgICAgICAxNjAxOiAnUHJvdmlzaW9uaW5nIENvbXBsZXRlZCcsDQogICAgICAgIDE2MDI6ICdBQ0wgRW50cnkgQWRkZWQnLA0KICAgICAgICAxNjAzOiAnQUNMIEVudHJ5IE1vZGlmaWVkJywNCiAgICAgICAgMTYwNDogJ0FDTCBFbnRyeSBSZW1vdmVkJywNCiAgICAgICAgMTYwNTogJ0FDTCBBY2Nlc3Mgd2l0aCBJbnZhbGlkIENyZWRlbnRpYWxzJywNCiAgICAgICAgMTYwNjogJ0FDTCBFbnRyeSBTdGF0ZScsDQogICAgICAgIDE2MDc6ICdUTFMgU3RhdGUgQ2hhbmdlZCcsDQogICAgICAgIDE2MDg6ICdUTFMgU2VydmVyIENlcnRpZmljYXRlIFNldCcsDQogICAgICAgIDE2MDk6ICdUTFMgU2VydmVyIENlcnRpZmljYXRlIFJlbW92ZScsDQogICAgICAgIDE2MTA6ICdUTFMgVHJ1c3RlZCBSb290IENlcnRpZmljYXRlIEFkZGVkJywNCiAgICAgICAgMTYxMTogJ1RMUyBUcnVzdGVkIFJvb3QgQ2VydGlmaWNhdGUgUmVtb3ZlZCcsDQogICAgICAgIDE2MTI6ICdUTFMgUHJlc2hhcmVkIEtleSBTZXQnLA0KICAgICAgICAxNjEzOiAnS2VyYmVyb3MgU2V0dGluZ3MgTW9kaWZpZWQnLA0KICAgICAgICAxNjE0OiAnS2VyYmVyb3MgTWFzdGVyIEtleSBNb2RpZmllZCcsDQogICAgICAgIDE2MTU6ICdGbGFzaCBXZWFyIG91dCBDb3VudGVycyBSZXNldCcsDQogICAgICAgIDE2MTY6ICdQb3dlciBQYWNrYWdlIE1vZGlmaWVkJywNCiAgICAgICAgMTYxNzogJ1NldCBSZWFsbSBBdXRoZW50aWNhdGlvbiBNb2RlJywNCiAgICAgICAgMTYxODogJ1VwZ3JhZGUgQ2xpZW50IHRvIEFkbWluIENvbnRyb2wgTW9kZScsDQogICAgICAgIDE2MTk6ICdVbnByb3Zpc2lvbmluZyBTdGFydGVkJywNCiAgICAgICAgMTcwMDogJ1BlcmZvcm1lZCBQb3dlciBVcCcsDQogICAgICAgIDE3MDE6ICdQZXJmb3JtZWQgUG93ZXIgRG93bicsDQogICAgICAgIDE3MDI6ICdQZXJmb3JtZWQgUG93ZXIgQ3ljbGUnLA0KICAgICAgICAxNzAzOiAnUGVyZm9ybWVkIFJlc2V0JywNCiAgICAgICAgMTcwNDogJ1NldCBCb290IE9wdGlvbnMnLA0KICAgICAgICAxODAwOiAnSURFUiBTZXNzaW9uIE9wZW5lZCcsDQogICAgICAgIDE4MDE6ICdJREVSIFNlc3Npb24gQ2xvc2VkJywNCiAgICAgICAgMTgwMjogJ0lERVIgRW5hYmxlZCcsDQogICAgICAgIDE4MDM6ICdJREVSIERpc2FibGVkJywNCiAgICAgICAgMTgwNDogJ1NvTCBTZXNzaW9uIE9wZW5lZCcsDQogICAgICAgIDE4MDU6ICdTb0wgU2Vzc2lvbiBDbG9zZWQnLA0KICAgICAgICAxODA2OiAnU29MIEVuYWJsZWQnLA0KICAgICAgICAxODA3OiAnU29MIERpc2FibGVkJywNCiAgICAgICAgMTgwODogJ0tWTSBTZXNzaW9uIFN0YXJ0ZWQnLA0KICAgICAgICAxODA5OiAnS1ZNIFNlc3Npb24gRW5kZWQnLA0KICAgICAgICAxODEwOiAnS1ZNIEVuYWJsZWQnLA0KICAgICAgICAxODExOiAnS1ZNIERpc2FibGVkJywNCiAgICAgICAgMTgxMjogJ1ZOQyBQYXNzd29yZCBGYWlsZWQgMyBUaW1lcycsDQogICAgICAgIDE5MDA6ICdGaXJtd2FyZSBVcGRhdGVkJywNCiAgICAgICAgMTkwMTogJ0Zpcm13YXJlIFVwZGF0ZSBGYWlsZWQnLA0KICAgICAgICAyMDAwOiAnU2VjdXJpdHkgQXVkaXQgTG9nIENsZWFyZWQnLA0KICAgICAgICAyMDAxOiAnU2VjdXJpdHkgQXVkaXQgUG9saWN5IE1vZGlmaWVkJywNCiAgICAgICAgMjAwMjogJ1NlY3VyaXR5IEF1ZGl0IExvZyBEaXNhYmxlZCcsDQogICAgICAgIDIwMDM6ICdTZWN1cml0eSBBdWRpdCBMb2cgRW5hYmxlZCcsDQogICAgICAgIDIwMDQ6ICdTZWN1cml0eSBBdWRpdCBMb2cgRXhwb3J0ZWQnLA0KICAgICAgICAyMDA1OiAnU2VjdXJpdHkgQXVkaXQgTG9nIFJlY292ZXJlZCcsDQogICAgICAgIDIxMDA6ICdJbnRlbCZyZWc7IE1FIFRpbWUgU2V0JywNCiAgICAgICAgMjIwMDogJ1RDUElQIFBhcmFtZXRlcnMgU2V0JywNCiAgICAgICAgMjIwMTogJ0hvc3QgTmFtZSBTZXQnLA0KICAgICAgICAyMjAyOiAnRG9tYWluIE5hbWUgU2V0JywNCiAgICAgICAgMjIwMzogJ1ZMQU4gUGFyYW1ldGVycyBTZXQnLA0KICAgICAgICAyMjA0OiAnTGluayBQb2xpY3kgU2V0JywNCiAgICAgICAgMjIwNTogJ0lQdjYgUGFyYW1ldGVycyBTZXQnLA0KICAgICAgICAyMzAwOiAnR2xvYmFsIFN0b3JhZ2UgQXR0cmlidXRlcyBTZXQnLA0KICAgICAgICAyMzAxOiAnU3RvcmFnZSBFQUNMIE1vZGlmaWVkJywNCiAgICAgICAgMjMwMjogJ1N0b3JhZ2UgRlBBQ0wgTW9kaWZpZWQnLA0KICAgICAgICAyMzAzOiAnU3RvcmFnZSBXcml0ZSBPcGVyYXRpb24nLA0KICAgICAgICAyNDAwOiAnQWxlcnQgU3Vic2NyaWJlZCcsDQogICAgICAgIDI0MDE6ICdBbGVydCBVbnN1YnNjcmliZWQnLA0KICAgICAgICAyNDAyOiAnRXZlbnQgTG9nIENsZWFyZWQnLA0KICAgICAgICAyNDAzOiAnRXZlbnQgTG9nIEZyb3plbicsDQogICAgICAgIDI1MDA6ICdDQiBGaWx0ZXIgQWRkZWQnLA0KICAgICAgICAyNTAxOiAnQ0IgRmlsdGVyIFJlbW92ZWQnLA0KICAgICAgICAyNTAyOiAnQ0IgUG9saWN5IEFkZGVkJywNCiAgICAgICAgMjUwMzogJ0NCIFBvbGljeSBSZW1vdmVkJywNCiAgICAgICAgMjUwNDogJ0NCIERlZmF1bHQgUG9saWN5IFNldCcsDQogICAgICAgIDI1MDU6ICdDQiBIZXVyaXN0aWNzIE9wdGlvbiBTZXQnLA0KICAgICAgICAyNTA2OiAnQ0IgSGV1cmlzdGljcyBTdGF0ZSBDbGVhcmVkJywNCiAgICAgICAgMjYwMDogJ0FnZW50IFdhdGNoZG9nIEFkZGVkJywNCiAgICAgICAgMjYwMTogJ0FnZW50IFdhdGNoZG9nIFJlbW92ZWQnLA0KICAgICAgICAyNjAyOiAnQWdlbnQgV2F0Y2hkb2cgQWN0aW9uIFNldCcsDQogICAgICAgIDI3MDA6ICdXaXJlbGVzcyBQcm9maWxlIEFkZGVkJywNCiAgICAgICAgMjcwMTogJ1dpcmVsZXNzIFByb2ZpbGUgUmVtb3ZlZCcsDQogICAgICAgIDI3MDI6ICdXaXJlbGVzcyBQcm9maWxlIFVwZGF0ZWQnLA0KICAgICAgICAyODAwOiAnRUFDIFBvc3R1cmUgU2lnbmVyIFNFVCcsDQogICAgICAgIDI4MDE6ICdFQUMgRW5hYmxlZCcsDQogICAgICAgIDI4MDI6ICdFQUMgRGlzYWJsZWQnLA0KICAgICAgICAyODAzOiAnRUFDIFBvc3R1cmUgU3RhdGUnLA0KICAgICAgICAyODA0OiAnRUFDIFNldCBPcHRpb25zJywNCiAgICAgICAgMjkwMDogJ0tWTSBPcHQtaW4gRW5hYmxlZCcsDQogICAgICAgIDI5MDE6ICdLVk0gT3B0LWluIERpc2FibGVkJywNCiAgICAgICAgMjkwMjogJ0tWTSBQYXNzd29yZCBDaGFuZ2VkJywNCiAgICAgICAgMjkwMzogJ0tWTSBDb25zZW50IFN1Y2NlZWRlZCcsDQogICAgICAgIDI5MDQ6ICdLVk0gQ29uc2VudCBGYWlsZWQnLA0KICAgICAgICAzMDAwOiAnT3B0LUluIFBvbGljeSBDaGFuZ2UnLA0KICAgICAgICAzMDAxOiAnU2VuZCBDb25zZW50IENvZGUgRXZlbnQnLA0KICAgICAgICAzMDAyOiAnU3RhcnQgT3B0LUluIEJsb2NrZWQgRXZlbnQnDQogICAgfQ0KDQogICAgLy8gUmV0dXJuIGh1bWFuIHJlYWRhYmxlIGV4dGVuZGVkIGF1ZGl0IGxvZyBkYXRhDQogICAgLy8gVE9ETzogSnVzdCBwdXQgc29tZSBvZiB0aGVtIGhlcmUsIGJ1dCBtYW55IG1vcmUgc3RpbGwgbmVlZCB0byBiZSBhZGRlZCwgaGVscGZ1bCBsaW5rIGhlcmU6DQogICAgLy8gaHR0cHM6Ly9zb2Z0d2FyZS5pbnRlbC5jb20vc2l0ZXMvbWFuYWdlYWJpbGl0eS9BTVRfSW1wbGVtZW50YXRpb25fYW5kX1JlZmVyZW5jZV9HdWlkZS9kZWZhdWx0Lmh0bT90dXJsPVdvcmREb2N1bWVudHMlMkZzZWN1cml0eWFkbWluZXZlbnRzLmh0bQ0KICAgIG9iai5HZXRBdWRpdExvZ0V4dGVuZGVkRGF0YVN0ciA9IGZ1bmN0aW9uIChpZCwgZGF0YSkgew0KICAgICAgICBpZiAoKGlkID09IDE2MDIgfHwgaWQgPT0gMTYwNCkgJiYgZGF0YS5jaGFyQ29kZUF0KDApID09IDApIHsgcmV0dXJuIGRhdGEuc3Vic3RyaW5nKDIsIDIgKyBkYXRhLmNoYXJDb2RlQXQoMSkpOyB9IC8vIEFDTCBFbnRyeSBBZGRlZC9SZW1vdmVkIChEaWdlc3QpDQogICAgICAgIGlmIChpZCA9PSAxNjAzKSB7IGlmIChkYXRhLmNoYXJDb2RlQXQoMSkgPT0gMCkgeyByZXR1cm4gZGF0YS5zdWJzdHJpbmcoMyk7IH0gcmV0dXJuIG51bGw7IH0gLy8gQUNMIEVudHJ5IE1vZGlmaWVkDQogICAgICAgIGlmIChpZCA9PSAxNjA1KSB7IHJldHVybiBbIkludmFsaWQgTUUgYWNjZXNzIiwgIkludmFsaWQgTUVCeCBhY2Nlc3MiXVtkYXRhLmNoYXJDb2RlQXQoMCldOyB9IC8vIEFDTCBBY2Nlc3Mgd2l0aCBJbnZhbGlkIENyZWRlbnRpYWxzDQogICAgICAgIGlmIChpZCA9PSAxNjA2KSB7IHZhciByID0gWyJEaXNhYmxlZCIsICJFbmFibGVkIl1bZGF0YS5jaGFyQ29kZUF0KDApXTsgaWYgKGRhdGEuY2hhckNvZGVBdCgxKSA9PSAwKSB7IHIgKz0gIiwgIiArIGRhdGEuc3Vic3RyaW5nKDMpOyB9IHJldHVybiByO30gLy8gQUNMIEVudHJ5IFN0YXRlDQogICAgICAgIGlmIChpZCA9PSAxNjA3KSB7IHJldHVybiAiUmVtb3RlICIgKyBbIk5vQXV0aCIsICJTZXJ2ZXJBdXRoIiwgIk11dHVhbEF1dGgiXVtkYXRhLmNoYXJDb2RlQXQoMCldICsgIiwgTG9jYWwgIiArIFsiTm9BdXRoIiwgIlNlcnZlckF1dGgiLCAiTXV0dWFsQXV0aCJdW2RhdGEuY2hhckNvZGVBdCgxKV07IH0gLy8gVExTIFN0YXRlIENoYW5nZWQNCiAgICAgICAgaWYgKGlkID09IDE2MTcpIHsgcmV0dXJuIG9iai5SZWFsbU5hbWVzW1JlYWRJbnQoZGF0YSwgMCldICsgIiwgIiArIFsiTm9BdXRoIiwgIkF1dGgiLCAiRGlzYWJsZWQiXVtkYXRhLmNoYXJDb2RlQXQoNCldOyB9IC8vIFNldCBSZWFsbSBBdXRoZW50aWNhdGlvbiBNb2RlDQogICAgICAgIGlmIChpZCA9PSAxNjE5KSB7IHJldHVybiBbIkJJT1MiLCAiTUVCeCIsICJMb2NhbCBNRUkiLCAiTG9jYWwgV1NNQU4iLCAiUmVtb3RlIFdTQU1OIl1bZGF0YS5jaGFyQ29kZUF0KDApXTsgfSAvLyBJbnRlbCBBTVQgVW5wcm92aXNpb25pbmcgU3RhcnRlZA0KICAgICAgICBpZiAoaWQgPT0gMTkwMCkgeyByZXR1cm4gIkZyb20gIiArIFJlYWRTaG9ydChkYXRhLCAwKSArICIuIiArIFJlYWRTaG9ydChkYXRhLCAyKSArICIuIiArIFJlYWRTaG9ydChkYXRhLCA0KSArICIuIiArIFJlYWRTaG9ydChkYXRhLCA2KSArICIgdG8gIiArIFJlYWRTaG9ydChkYXRhLCA4KSArICIuIiArIFJlYWRTaG9ydChkYXRhLCAxMCkgKyAiLiIgKyBSZWFkU2hvcnQoZGF0YSwgMTIpICsgIi4iICsgUmVhZFNob3J0KGRhdGEsIDE0KTsgfSAvLyBGaXJtd2FyZSBVcGRhdGVkDQogICAgICAgIGlmIChpZCA9PSAyMTAwKSB7IHZhciB0NCA9IG5ldyBEYXRlKCk7IHQ0LnNldFRpbWUoUmVhZEludChkYXRhLCAwKSAqIDEwMDAgKyAobmV3IERhdGUoKS5nZXRUaW1lem9uZU9mZnNldCgpICogNjAwMDApKTsgcmV0dXJuIHQ0LnRvTG9jYWxlU3RyaW5nKCk7IH0gLy8gSW50ZWwgQU1UIFRpbWUgU2V0DQogICAgICAgIGlmIChpZCA9PSAzMDAwKSB7IHJldHVybiAiRnJvbSAiICsgWyJOb25lIiwgIktWTSIsICJBbGwiXVtkYXRhLmNoYXJDb2RlQXQoMCldICsgIiB0byAiICsgWyJOb25lIiwgIktWTSIsICJBbGwiXVtkYXRhLmNoYXJDb2RlQXQoMSldOyB9IC8vIE9wdC1JbiBQb2xpY3kgQ2hhbmdlDQogICAgICAgIGlmIChpZCA9PSAzMDAxKSB7IHJldHVybiBbIlN1Y2Nlc3MiLCAiRmFpbGVkIDMgdGltZXMiXVtkYXRhLmNoYXJDb2RlQXQoMCldOyB9IC8vIFNlbmQgQ29uc2VudCBDb2RlIEV2ZW50DQogICAgICAgIHJldHVybiBudWxsOw0KICAgIH0NCg0KICAgIG9iai5HZXRBdWRpdExvZyA9IGZ1bmN0aW9uIChmdW5jKSB7DQogICAgICAgIG9iai5BTVRfQXVkaXRMb2dfUmVhZFJlY29yZHMoMSwgX0dldEF1ZGl0TG9nMCwgW2Z1bmMsIFtdXSk7DQogICAgfQ0KDQogICAgZnVuY3Rpb24gX0dldEF1ZGl0TG9nMChzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMsIHRhZykgew0KICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyB0YWdbMF0ob2JqLCBbXSwgc3RhdHVzKTsgcmV0dXJuOyB9DQogICAgICAgIHZhciBwdHIsIGksIGUsIHgsIHIgPSB0YWdbMV0sIHQgPSBuZXcgRGF0ZSgpLCBUaW1lU3RhbXA7DQoNCiAgICAgICAgaWYgKHJlc3BvbnNlcy5Cb2R5WydSZWNvcmRzUmV0dXJuZWQnXSA+IDApIHsNCiAgICAgICAgICAgIHJlc3BvbnNlcy5Cb2R5WydFdmVudFJlY29yZHMnXSA9IE1ha2VUb0FycmF5KHJlc3BvbnNlcy5Cb2R5WydFdmVudFJlY29yZHMnXSk7DQoNCiAgICAgICAgICAgIGZvciAoaSBpbiByZXNwb25zZXMuQm9keVsnRXZlbnRSZWNvcmRzJ10pIHsNCiAgICAgICAgICAgICAgICBlID0gbnVsbDsNCiAgICAgICAgICAgICAgICB0cnkgew0KICAgICAgICAgICAgICAgICAgICBlID0gd2luZG93LmF0b2IocmVzcG9uc2VzLkJvZHlbJ0V2ZW50UmVjb3JkcyddW2ldKTsNCiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7DQogICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGUgKyAiICIgKyByZXNwb25zZXMuQm9keVsnRXZlbnRSZWNvcmRzJ11baV0pDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHggPSB7ICdBdWRpdEFwcElEJzogUmVhZFNob3J0KGUsIDApLCAnRXZlbnRJRCc6IFJlYWRTaG9ydChlLCAyKSwgJ0luaXRpYXRvclR5cGUnOiBlLmNoYXJDb2RlQXQoNCkgfTsNCiAgICAgICAgICAgICAgICB4WydBdWRpdEFwcCddID0gX0FtdEF1ZGl0U3RyaW5nVGFibGVbeFsnQXVkaXRBcHBJRCddXTsNCiAgICAgICAgICAgICAgICB4WydFdmVudCddID0gX0FtdEF1ZGl0U3RyaW5nVGFibGVbKHhbJ0F1ZGl0QXBwSUQnXSAqIDEwMCkgKyB4WydFdmVudElEJ11dOw0KICAgICAgICAgICAgICAgIGlmICgheFsnRXZlbnQnXSkgeFsnRXZlbnQnXSA9ICcjJyArIHhbJ0V2ZW50SUQnXTsNCg0KICAgICAgICAgICAgICAgIC8vIFJlYWQgYW5kIHByb2Nlc3MgdGhlIGluaXRpYXRvcg0KICAgICAgICAgICAgICAgIGlmICh4WydJbml0aWF0b3JUeXBlJ10gPT0gMCkgew0KICAgICAgICAgICAgICAgICAgICAvLyBIVFRQIGRpZ2VzdA0KICAgICAgICAgICAgICAgICAgICB2YXIgdXNlcmxlbiA9IGUuY2hhckNvZGVBdCg1KTsNCiAgICAgICAgICAgICAgICAgICAgeFsnSW5pdGlhdG9yJ10gPSBlLnN1YnN0cmluZyg2LCA2ICsgdXNlcmxlbik7DQogICAgICAgICAgICAgICAgICAgIHB0ciA9IDYgKyB1c2VybGVuOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAoeFsnSW5pdGlhdG9yVHlwZSddID09IDEpIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gS2VyYmVyb3MNCiAgICAgICAgICAgICAgICAgICAgeFsnS2VyYmVyb3NVc2VySW5Eb21haW4nXSA9IFJlYWRJbnQoZSwgNSk7DQogICAgICAgICAgICAgICAgICAgIHZhciB1c2VybGVuID0gZS5jaGFyQ29kZUF0KDkpOw0KICAgICAgICAgICAgICAgICAgICB4WydJbml0aWF0b3InXSA9IEdldFNpZFN0cmluZyhlLnN1YnN0cmluZygxMCwgMTAgKyB1c2VybGVuKSk7DQogICAgICAgICAgICAgICAgICAgIHB0ciA9IDEwICsgdXNlcmxlbjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYgKHhbJ0luaXRpYXRvclR5cGUnXSA9PSAyKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIExvY2FsDQogICAgICAgICAgICAgICAgICAgIHhbJ0luaXRpYXRvciddID0gJzxpPkxvY2FsPC9pPic7DQogICAgICAgICAgICAgICAgICAgIHB0ciA9IDU7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmICh4WydJbml0aWF0b3JUeXBlJ10gPT0gMykgew0KICAgICAgICAgICAgICAgICAgICAvLyBLVk0gRGVmYXVsdCBQb3J0DQogICAgICAgICAgICAgICAgICAgIHhbJ0luaXRpYXRvciddID0gJzxpPktWTSBEZWZhdWx0IFBvcnQ8L2k+JzsNCiAgICAgICAgICAgICAgICAgICAgcHRyID0gNTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAvLyBSZWFkIHRpbWVzdGFtcA0KICAgICAgICAgICAgICAgIFRpbWVTdGFtcCA9IFJlYWRJbnQoZSwgcHRyKTsNCiAgICAgICAgICAgICAgICB4WydUaW1lJ10gPSBuZXcgRGF0ZSgoVGltZVN0YW1wICsgKHQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwKSkgKiAxMDAwKTsNCiAgICAgICAgICAgICAgICBwdHIgKz0gNDsNCg0KICAgICAgICAgICAgICAgIC8vIFJlYWQgbmV0d29yayBhY2Nlc3MNCiAgICAgICAgICAgICAgICB4WydNQ0xvY2F0aW9uVHlwZSddID0gZS5jaGFyQ29kZUF0KHB0cisrKTsNCiAgICAgICAgICAgICAgICB2YXIgbmV0bGVuID0gZS5jaGFyQ29kZUF0KHB0cisrKTsNCiAgICAgICAgICAgICAgICB4WydOZXRBZGRyZXNzJ10gPSBlLnN1YnN0cmluZyhwdHIsIHB0ciArIG5ldGxlbik7DQoNCiAgICAgICAgICAgICAgICAvLyBSZWFkIGV4dGVuZGVkIGRhdGENCiAgICAgICAgICAgICAgICBwdHIgKz0gbmV0bGVuOw0KICAgICAgICAgICAgICAgIHZhciBleGxlbiA9IGUuY2hhckNvZGVBdChwdHIrKyk7DQogICAgICAgICAgICAgICAgeFsnRXgnXSA9IGUuc3Vic3RyaW5nKHB0ciwgcHRyICsgZXhsZW4pOw0KICAgICAgICAgICAgICAgIHhbJ0V4U3RyJ10gPSBvYmouR2V0QXVkaXRMb2dFeHRlbmRlZERhdGFTdHIoKHhbJ0F1ZGl0QXBwSUQnXSAqIDEwMCkgKyB4WydFdmVudElEJ10sIHhbJ0V4J10pOw0KDQogICAgICAgICAgICAgICAgci5wdXNoKHgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChyZXNwb25zZXMuQm9keVsnVG90YWxSZWNvcmRDb3VudCddID4gci5sZW5ndGgpIHsNCiAgICAgICAgICAgIG9iai5BTVRfQXVkaXRMb2dfUmVhZFJlY29yZHMoci5sZW5ndGggKyAxLCBfR2V0QXVkaXRMb2cwLCBbdGFnWzBdLCByXSk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICB0YWdbMF0ob2JqLCByLCBzdGF0dXMpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgDQogICAgcmV0dXJuIG9iajsNCn0NCg0KDQoNCg0KLy8gRm9yZ2UgTUQ1DQpmdW5jdGlvbiBoZXhfbWQ1KHN0cikgeyByZXR1cm4gZm9yZ2UubWQubWQ1LmNyZWF0ZSgpLnVwZGF0ZShzdHIpLmRpZ2VzdCgpLnRvSGV4KCk7IH0NCg0KDQoNCi8vIFBlcmZvcm0gTUQ1IG9uIHJhdyBzdHJpbmcgYW5kIHJldHVybiByYXcgc3RyaW5nIHJlc3VsdA0KZnVuY3Rpb24gcnN0cl9tZDUoc3RyKSB7IHJldHVybiBoZXgycnN0cihoZXhfbWQ1KHN0cikpOyB9DQoNCi8qDQpDb252ZXJ0IGFyZ3VtZW50cyBpbnRvIHNlbGVjdG9yIHNldCBhbmQgYm9keSBYTUwuIFVzZWQgYnkgQU1UX1dpRmlQb3J0Q29uZmlndXJhdGlvblNlcnZpY2VfVXBkYXRlV2lGaVNldHRpbmdzLg0KYXJncyA9IHsgDQoJIldpRmlFbmRwb2ludCI6IHsNCgkJX19wYXJhbWV0ZXJUeXBlOiAncmVmZXJlbmNlJywNCgkJX19yZXNvdXJjZVVyaTogJ2h0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NjaW0vMS9jaW0tc2NoZW1hLzIvQ0lNX1dpRmlFbmRwb2ludCcsDQoJCU5hbWU6ICdXaUZpIEVuZHBvaW50IDAnDQoJfSwgDQoJIldpRmlFbmRwb2ludFNldHRpbmdzSW5wdXQiOiANCgl7DQoJCV9fcGFyYW1ldGVyVHlwZTogJ2luc3RhbmNlJywNCgkJX19uYW1lc3BhY2U6ICdodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yL0NJTV9XaUZpRW5kcG9pbnRTZXR0aW5ncycsDQoJCUVsZW1lbnROYW1lOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZWRpdFByb2ZpbGUtcHJvZmlsZU5hbWUnKS52YWx1ZSwNCgkJSW5zdGFuY2VJRDogJ0ludGVsKHIpIEFNVDpXaUZpIEVuZHBvaW50IFNldHRpbmdzICcgKyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZWRpdFByb2ZpbGUtcHJvZmlsZU5hbWUnKS52YWx1ZSwNCgkJQXV0aGVudGljYXRpb25NZXRob2Q6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNlZGl0UHJvZmlsZS1uZXR3b3JrQXV0aGVudGljYXRpb24nKS52YWx1ZSwNCgkJLy9CU1NUeXBlOiAzLCAvLyBJbnRlbChyKSBBTVQgc3VwcG9ydHMgb25seSBpbmZyYXN0cnVjdHVyZSBuZXR3b3Jrcw0KCQlFbmNyeXB0aW9uTWV0aG9kOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZWRpdFByb2ZpbGUtZW5jcnlwdGlvbicpLnZhbHVlLA0KCQlTU0lEOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZWRpdFByb2ZpbGUtbmV0d29ya05hbWUnKS52YWx1ZSwNCgkJUHJpb3JpdHk6IDEwMCwNCgkJUFNLUGFzc1BocmFzZTogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2VkaXRQcm9maWxlLXBhc3NQaHJhc2UnKS52YWx1ZQ0KCX0sIA0KCSJJRUVFODAyMXhTZXR0aW5nc0lucHV0IjogbnVsbCwgDQoJIkNsaWVudENyZWRlbnRpYWwiOiBudWxsLCANCgkiQ0FDcmVkZW50aWFsIjogbnVsbCANCn0sIA0KKi8NCmZ1bmN0aW9uIGV4ZWNBcmd1bWVudHNUb1htbChhcmdzKSB7DQoJaWYoYXJncyA9PT0gdW5kZWZpbmVkIHx8IGFyZ3MgPT09IG51bGwpIHJldHVybiBudWxsOw0KCQ0KCXZhciByZXN1bHQgPSAnJzsNCglmb3IodmFyIGFyZ05hbWUgaW4gYXJncykgew0KCQl2YXIgYXJnID0gYXJnc1thcmdOYW1lXTsNCgkJaWYoIWFyZykgY29udGludWU7DQoJCWlmKGFyZ1snX19wYXJhbWV0ZXJUeXBlJ10gPT09ICdyZWZlcmVuY2UnKSByZXN1bHQgKz0gcmVmZXJlbmNlVG9YbWwoYXJnTmFtZSwgYXJnKTsNCgkJZWxzZSByZXN1bHQgKz0gaW5zdGFuY2VUb1htbChhcmdOYW1lLCBhcmcpOw0KCQkvL2lmKGFyZ1snX19pc0luc3RhbmNlJ10pIHJlc3VsdCArPSBpbnN0YW5jZVRvWG1sKGFyZ05hbWUsIGFyZyk7DQoJfQ0KCXJldHVybiByZXN1bHQ7DQp9DQoNCi8qKg0KICogQ29udmVydCBKYXZhU2NyaXB0IG9iamVjdCBpbnRvIFhNTA0KIA0KCTxyOldpRmlFbmRwb2ludFNldHRpbmdzSW5wdXQgeG1sbnM6cT0iaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NpbS1zY2hlbWEvMi9DSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MiPg0KCQk8cTpFbGVtZW50TmFtZT5XaXJlbGVzcy1Qcm9maWxlLUFkbWluPC9xOkVsZW1lbnROYW1lPg0KCQk8cTpJbnN0YW5jZUlEPkludGVsKHIpIEFNVDpXaUZpIEVuZHBvaW50IFNldHRpbmdzIFdpcmVsZXNzLVByb2ZpbGUtQWRtaW48L3E6SW5zdGFuY2VJRD4NCgkJPHE6QXV0aGVudGljYXRpb25NZXRob2Q+NjwvcTpBdXRoZW50aWNhdGlvbk1ldGhvZD4NCgkJPHE6RW5jcnlwdGlvbk1ldGhvZD40PC9xOkVuY3J5cHRpb25NZXRob2Q+DQoJCTxxOlByaW9yaXR5PjEwMDwvcTpQcmlvcml0eT4NCgkJPHE6UFNLUGFzc1BocmFzZT54eHh4eHh4eDwvcTpQU0tQYXNzUGhyYXNlPg0KCTwvcjpXaUZpRW5kcG9pbnRTZXR0aW5nc0lucHV0Pg0KICovDQpmdW5jdGlvbiBpbnN0YW5jZVRvWG1sKGluc3RhbmNlTmFtZSwgaW5JbnN0YW5jZSkgew0KCWlmKGluSW5zdGFuY2UgPT09IHVuZGVmaW5lZCB8fCBpbkluc3RhbmNlID09PSBudWxsKSByZXR1cm4gbnVsbDsNCgkNCgl2YXIgaGFzTmFtZXNwYWNlID0gISFpbkluc3RhbmNlWydfX25hbWVzcGFjZSddOw0KCXZhciBzdGFydFRhZyA9IGhhc05hbWVzcGFjZSA/ICc8cTonIDogJzwnOw0KCXZhciBlbmRUYWcgPSBoYXNOYW1lc3BhY2UgPyAnPC9xOicgOiAnPC8nOw0KCXZhciBuYW1lc3BhY2VEZWYgPSBoYXNOYW1lc3BhY2UgPyAoJyB4bWxuczpxPSInICsgaW5JbnN0YW5jZVsnX19uYW1lc3BhY2UnXSArICciJyApOiAnJzsNCgl2YXIgcmVzdWx0ID0gJzxyOicgKyBpbnN0YW5jZU5hbWUgKyBuYW1lc3BhY2VEZWYgKyAnPic7DQoJZm9yKHZhciBwcm9wIGluIGluSW5zdGFuY2UpIHsNCgkJaWYgKCFpbkluc3RhbmNlLmhhc093blByb3BlcnR5KHByb3ApIHx8IHByb3AuaW5kZXhPZignX18nKSA9PT0gMCkgY29udGludWU7DQoJCQ0KCQlpZiAodHlwZW9mIGluSW5zdGFuY2VbcHJvcF0gPT09ICdmdW5jdGlvbicgfHwgQXJyYXkuaXNBcnJheShpbkluc3RhbmNlW3Byb3BdKSApIGNvbnRpbnVlOw0KCQkNCgkJaWYgKHR5cGVvZiBpbkluc3RhbmNlW3Byb3BdID09PSAnb2JqZWN0Jykgew0KCQkJLy9yZXN1bHQgKz0gc3RhcnRUYWcgKyBwcm9wICsnPicgKyBpbnN0YW5jZVRvWG1sKCdwcm9wJywgaW5JbnN0YW5jZVtwcm9wXSkgKyBlbmRUYWcgKyBwcm9wICsnPic7DQoJCQljb25zb2xlLmVycm9yKCdvbmx5IGNvbnZlcnQgb25lIGxldmVsIGRvd24uLi4nKTsNCgkJfQ0KCQllbHNlIHsNCgkJCXJlc3VsdCArPSBzdGFydFRhZyArIHByb3AgKyc+JyArIGluSW5zdGFuY2VbcHJvcF0udG9TdHJpbmcoKSArIGVuZFRhZyArIHByb3AgKyc+JzsNCgkJfQ0KCX0NCglyZXN1bHQgKz0gJzwvcjonICsgaW5zdGFuY2VOYW1lICsgJz4nOw0KCXJldHVybiByZXN1bHQ7DQp9DQoNCg0KLyoqDQogKiBDb252ZXJ0IGEgc2VsZWN0b3Igc2V0IGludG8gWE1MLiBFeHBlY3Qgbm8gbmVzdGluZy4NCiAqIHsNCiAqIAlzZWxlY3Rvck5hbWUgOiBzZWxlY3RvclZhbHVlLA0KICogCXNlbGVjdG9yTmFtZSA6IHNlbGVjdG9yVmFsdWUsDQogKgkuLi4gLi4uDQogKiB9DQogDQoJPHI6V2lGaUVuZHBvaW50Pg0KCQk8YTpBZGRyZXNzPmh0dHA6Ly8xOTIuMTY4LjEuMTAzOjE2OTkyL3dzbWFuPC9hOkFkZHJlc3M+DQoJCTxhOlJlZmVyZW5jZVBhcmFtZXRlcnM+DQoJCQk8dzpSZXNvdXJjZVVSST5odHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yL0NJTV9XaUZpRW5kcG9pbnQ8L3c6UmVzb3VyY2VVUkk+DQoJCQk8dzpTZWxlY3RvclNldD4NCgkJCQk8dzpTZWxlY3RvciBOYW1lPSJOYW1lIj5XaUZpIEVuZHBvaW50IDA8L3c6U2VsZWN0b3I+DQoJCQk8L3c6U2VsZWN0b3JTZXQ+DQoJCTwvYTpSZWZlcmVuY2VQYXJhbWV0ZXJzPg0KCTwvcjpXaUZpRW5kcG9pbnQ+DQoJCQkNCiAqLw0KZnVuY3Rpb24gcmVmZXJlbmNlVG9YbWwocmVmZXJlbmNlTmFtZSwgaW5SZWZlcmVuY2UpIHsNCglpZihpblJlZmVyZW5jZSA9PT0gdW5kZWZpbmVkIHx8IGluUmVmZXJlbmNlID09PSBudWxsICkgcmV0dXJuIG51bGw7DQoJDQoJdmFyIHJlc3VsdCA9ICc8cjonICsgcmVmZXJlbmNlTmFtZSArICc+PGE6QWRkcmVzcz4vd3NtYW48L2E6QWRkcmVzcz48YTpSZWZlcmVuY2VQYXJhbWV0ZXJzPjx3OlJlc291cmNlVVJJPicrIGluUmVmZXJlbmNlWydfX3Jlc291cmNlVXJpJ10rJzwvdzpSZXNvdXJjZVVSST48dzpTZWxlY3RvclNldD4nOw0KCWZvcih2YXIgc2VsZWN0b3JOYW1lIGluIGluUmVmZXJlbmNlKSB7DQoJCWlmICghaW5SZWZlcmVuY2UuaGFzT3duUHJvcGVydHkoc2VsZWN0b3JOYW1lKSB8fCBzZWxlY3Rvck5hbWUuaW5kZXhPZignX18nKSA9PT0gMCkgY29udGludWU7DQoJCQ0KCQlpZiAodHlwZW9mIGluUmVmZXJlbmNlW3NlbGVjdG9yTmFtZV0gPT09ICdmdW5jdGlvbicgfHwgDQoJCQl0eXBlb2YgaW5SZWZlcmVuY2Vbc2VsZWN0b3JOYW1lXSA9PT0gJ29iamVjdCcgfHwNCgkJCUFycmF5LmlzQXJyYXkoaW5SZWZlcmVuY2Vbc2VsZWN0b3JOYW1lXSkgKQ0KCQkJY29udGludWU7DQoJCQ0KCQlyZXN1bHQgKz0gJzx3OlNlbGVjdG9yIE5hbWU9IicgKyBzZWxlY3Rvck5hbWUgKyciPicgKyBpblJlZmVyZW5jZVtzZWxlY3Rvck5hbWVdLnRvU3RyaW5nKCkgKyAnPC93OlNlbGVjdG9yPic7DQoJfQ0KCQ0KCXJlc3VsdCArPSAnPC93OlNlbGVjdG9yU2V0PjwvYTpSZWZlcmVuY2VQYXJhbWV0ZXJzPjwvcjonICsgcmVmZXJlbmNlTmFtZSArICc+JzsNCglyZXR1cm4gcmVzdWx0Ow0KfQ0KDQovLyBDb252ZXJ0IGEgYnl0ZSBhcnJheSBvZiBTSUQgaW50byBzdHJpbmcNCmZ1bmN0aW9uIEdldFNpZFN0cmluZyhzaWQpIHsNCiAgICB2YXIgciA9ICJTLSIgKyBzaWQuY2hhckNvZGVBdCgwKSArICItIiArIHNpZC5jaGFyQ29kZUF0KDcpOw0KICAgIGZvciAodmFyIGkgPSAyOyBpIDwgKHNpZC5sZW5ndGggLyA0KSA7IGkrKykgciArPSAiLSIgKyBSZWFkSW50WChzaWQsIGkgKiA0KTsNCiAgICByZXR1cm4gcjsNCn0NCg0KLy8gQ29udmVydCBhIFNJRCByZWFkYWJsZSBzdHJpbmcgaW50byBieXRlcw0KZnVuY3Rpb24gR2V0U2lkQnl0ZUFycmF5KHNpZFN0cmluZykgew0KICAgIGlmICghc2lkU3RyaW5nIHx8IHNpZFN0cmluZyA9PSBudWxsKSByZXR1cm4gbnVsbDsNCiAgICB2YXIgc2lkUGFydHMgPSBzaWRTdHJpbmcuc3BsaXQoJy0nKTsNCg0KICAgIC8vIE1ha2Ugc3VyZSB0aGUgU0lEIGhhcyBhdCBsZWFzdCA0IHBhcnRzIGFuZCBzdGFydHMgd2l0aCAnUycNCiAgICBpZiAoc2lkUGFydHMubGVuZ3RoIDwgNCB8fCAoc2lkUGFydHNbMF0gIT0gJ3MnICYmIHNpZFBhcnRzWzBdICE9ICdTJykpIHJldHVybiBudWxsOw0KDQogICAgLy8gQ2hlY2sgdGhhdCBlYWNoIHBhcnQgb2YgdGhlIFNJRCBpcyByZWFsbHkgYW4gaW50ZWdlcg0KICAgIGZvciAodmFyIGkgPSAxOyBpIDwgc2lkUGFydHMubGVuZ3RoOyBpKyspIHsgdmFyIHkgPSBwYXJzZUludChzaWRQYXJ0c1tpXSk7IGlmICh5ICE9IHNpZFBhcnRzW2ldKSByZXR1cm4gbnVsbDsgc2lkUGFydHNbaV0gPSB5OyB9DQoNCiAgICAvLyBWZXJzaW9uICg4IGJpdCkgKyBJZCBjb3VudCAoOCBiaXQpICsgNDggYml0IGluIGJpZyBlbmRpYW4gLS0gRE8gTk9UIHVzZSBiaXR3aXNlIHJpZ2h0IHNoaWZ0IG9wZXJhdG9yLiBKYXZhU2NyaXB0IGNvbnZlcnRzIHRoZSBudW1iZXIgaW50byBhIDMyIGJpdCBpbnRlZ2VyIGJlZm9yZSBzaGlmdGluZy4gSW4gcmVhbCB3b3JsZCwgaXQncyBoaWdobHkgbGlrZWx5IHRoaXMgcGFydCBpcyBhbHdheXMgMC4NCiAgICB2YXIgciA9IFN0cmluZy5mcm9tQ2hhckNvZGUoc2lkUGFydHNbMV0pICsgU3RyaW5nLmZyb21DaGFyQ29kZShzaWRQYXJ0cy5sZW5ndGggLSAzKSArIFNob3J0VG9TdHIoTWF0aC5mbG9vcihzaWRQYXJ0c1syXSAvIE1hdGgucG93KDIsIDMyKSkpICsgSW50VG9TdHIoKHNpZFBhcnRzWzJdKSAmIDB4RkZGRik7DQoNCiAgICAvLyB0aGUgcmVzdCBhcmUgaW4gMzIgYml0IGluIGxpdHRsZSBlbmRpYW4NCiAgICBmb3IgKHZhciBpID0gMzsgaSA8IHNpZFBhcnRzLmxlbmd0aDsgaSsrKSByICs9IEludFRvU3RyWChzaWRQYXJ0c1tpXSk7DQogICAgcmV0dXJuIHI7DQp9DQooZnVuY3Rpb24ocm9vdCwgZmFjdG9yeSkgewogIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkgewogICAgZGVmaW5lKFtdLCBmYWN0b3J5KTsKICB9IGVsc2UgewogICAgcm9vdC5mb3JnZSA9IGZhY3RvcnkoKTsKICB9Cn0pKHRoaXMsIGZ1bmN0aW9uKCkgewovKioKICogbGljZW5zZSBhbG1vbmQgMC4yLjkgQ29weXJpZ2h0IChjKSAyMDExLTIwMTQsIFRoZSBEb2pvIEZvdW5kYXRpb24gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogQXZhaWxhYmxlIHZpYSB0aGUgTUlUIG9yIG5ldyBCU0QgbGljZW5zZS4KICogc2VlOiBodHRwOi8vZ2l0aHViLmNvbS9qcmJ1cmtlL2FsbW9uZCBmb3IgZGV0YWlscwogKi8KLy9Hb2luZyBzbG9wcHkgdG8gYXZvaWQgJ3VzZSBzdHJpY3QnIHN0cmluZyBjb3N0LCBidXQgc3RyaWN0IHByYWN0aWNlcyBzaG91bGQKLy9iZSBmb2xsb3dlZC4KLypqc2xpbnQgc2xvcHB5OiB0cnVlICovCi8qZ2xvYmFsIHNldFRpbWVvdXQ6IGZhbHNlICovCgp2YXIgcmVxdWlyZWpzLCByZXF1aXJlLCBkZWZpbmU7CihmdW5jdGlvbiAodW5kZWYpIHsKICAgIHZhciBtYWluLCByZXEsIG1ha2VNYXAsIGhhbmRsZXJzLAogICAgICAgIGRlZmluZWQgPSB7fSwKICAgICAgICB3YWl0aW5nID0ge30sCiAgICAgICAgY29uZmlnID0ge30sCiAgICAgICAgZGVmaW5pbmcgPSB7fSwKICAgICAgICBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LAogICAgICAgIGFwcyA9IFtdLnNsaWNlLAogICAgICAgIGpzU3VmZml4UmVnRXhwID0gL1wuanMkLzsKCiAgICBmdW5jdGlvbiBoYXNQcm9wKG9iaiwgcHJvcCkgewogICAgICAgIHJldHVybiBoYXNPd24uY2FsbChvYmosIHByb3ApOwogICAgfQoKICAgIC8qKgogICAgICogR2l2ZW4gYSByZWxhdGl2ZSBtb2R1bGUgbmFtZSwgbGlrZSAuL3NvbWV0aGluZywgbm9ybWFsaXplIGl0IHRvCiAgICAgKiBhIHJlYWwgbmFtZSB0aGF0IGNhbiBiZSBtYXBwZWQgdG8gYSBwYXRoLgogICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgdGhlIHJlbGF0aXZlIG5hbWUKICAgICAqIEBwYXJhbSB7U3RyaW5nfSBiYXNlTmFtZSBhIHJlYWwgbmFtZSB0aGF0IHRoZSBuYW1lIGFyZyBpcyByZWxhdGl2ZQogICAgICogdG8uCiAgICAgKiBAcmV0dXJucyB7U3RyaW5nfSBub3JtYWxpemVkIG5hbWUKICAgICAqLwogICAgZnVuY3Rpb24gbm9ybWFsaXplKG5hbWUsIGJhc2VOYW1lKSB7CiAgICAgICAgdmFyIG5hbWVQYXJ0cywgbmFtZVNlZ21lbnQsIG1hcFZhbHVlLCBmb3VuZE1hcCwgbGFzdEluZGV4LAogICAgICAgICAgICBmb3VuZEksIGZvdW5kU3Rhck1hcCwgc3RhckksIGksIGosIHBhcnQsCiAgICAgICAgICAgIGJhc2VQYXJ0cyA9IGJhc2VOYW1lICYmIGJhc2VOYW1lLnNwbGl0KCIvIiksCiAgICAgICAgICAgIG1hcCA9IGNvbmZpZy5tYXAsCiAgICAgICAgICAgIHN0YXJNYXAgPSAobWFwICYmIG1hcFsnKiddKSB8fCB7fTsKCiAgICAgICAgLy9BZGp1c3QgYW55IHJlbGF0aXZlIHBhdGhzLgogICAgICAgIGlmIChuYW1lICYmIG5hbWUuY2hhckF0KDApID09PSAiLiIpIHsKICAgICAgICAgICAgLy9JZiBoYXZlIGEgYmFzZSBuYW1lLCB0cnkgdG8gbm9ybWFsaXplIGFnYWluc3QgaXQsCiAgICAgICAgICAgIC8vb3RoZXJ3aXNlLCBhc3N1bWUgaXQgaXMgYSB0b3AtbGV2ZWwgcmVxdWlyZSB0aGF0IHdpbGwKICAgICAgICAgICAgLy9iZSByZWxhdGl2ZSB0byBiYXNlVXJsIGluIHRoZSBlbmQuCiAgICAgICAgICAgIGlmIChiYXNlTmFtZSkgewogICAgICAgICAgICAgICAgLy9Db252ZXJ0IGJhc2VOYW1lIHRvIGFycmF5LCBhbmQgbG9wIG9mZiB0aGUgbGFzdCBwYXJ0LAogICAgICAgICAgICAgICAgLy9zbyB0aGF0IC4gbWF0Y2hlcyB0aGF0ICJkaXJlY3RvcnkiIGFuZCBub3QgbmFtZSBvZiB0aGUgYmFzZU5hbWUncwogICAgICAgICAgICAgICAgLy9tb2R1bGUuIEZvciBpbnN0YW5jZSwgYmFzZU5hbWUgb2YgIm9uZS90d28vdGhyZWUiLCBtYXBzIHRvCiAgICAgICAgICAgICAgICAvLyJvbmUvdHdvL3RocmVlLmpzIiwgYnV0IHdlIHdhbnQgdGhlIGRpcmVjdG9yeSwgIm9uZS90d28iIGZvcgogICAgICAgICAgICAgICAgLy90aGlzIG5vcm1hbGl6YXRpb24uCiAgICAgICAgICAgICAgICBiYXNlUGFydHMgPSBiYXNlUGFydHMuc2xpY2UoMCwgYmFzZVBhcnRzLmxlbmd0aCAtIDEpOwogICAgICAgICAgICAgICAgbmFtZSA9IG5hbWUuc3BsaXQoJy8nKTsKICAgICAgICAgICAgICAgIGxhc3RJbmRleCA9IG5hbWUubGVuZ3RoIC0gMTsKCiAgICAgICAgICAgICAgICAvLyBOb2RlIC5qcyBhbGxvd2FuY2U6CiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLm5vZGVJZENvbXBhdCAmJiBqc1N1ZmZpeFJlZ0V4cC50ZXN0KG5hbWVbbGFzdEluZGV4XSkpIHsKICAgICAgICAgICAgICAgICAgICBuYW1lW2xhc3RJbmRleF0gPSBuYW1lW2xhc3RJbmRleF0ucmVwbGFjZShqc1N1ZmZpeFJlZ0V4cCwgJycpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIG5hbWUgPSBiYXNlUGFydHMuY29uY2F0KG5hbWUpOwoKICAgICAgICAgICAgICAgIC8vc3RhcnQgdHJpbURvdHMKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBuYW1lLmxlbmd0aDsgaSArPSAxKSB7CiAgICAgICAgICAgICAgICAgICAgcGFydCA9IG5hbWVbaV07CiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnQgPT09ICIuIikgewogICAgICAgICAgICAgICAgICAgICAgICBuYW1lLnNwbGljZShpLCAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgaSAtPSAxOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFydCA9PT0gIi4uIikgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PT0gMSAmJiAobmFtZVsyXSA9PT0gJy4uJyB8fCBuYW1lWzBdID09PSAnLi4nKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9FbmQgb2YgdGhlIGxpbmUuIEtlZXAgYXQgbGVhc3Qgb25lIG5vbi1kb3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vcGF0aCBzZWdtZW50IGF0IHRoZSBmcm9udCBzbyBpdCBjYW4gYmUgbWFwcGVkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2NvcnJlY3RseSB0byBkaXNrLiBPdGhlcndpc2UsIHRoZXJlIGlzIGxpa2VseQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9ubyBwYXRoIG1hcHBpbmcgZm9yIGEgcGF0aCBzdGFydGluZyB3aXRoICcuLicuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1RoaXMgY2FuIHN0aWxsIGZhaWwsIGJ1dCBjYXRjaGVzIHRoZSBtb3N0IHJlYXNvbmFibGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdXNlcyBvZiAuLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUuc3BsaWNlKGkgLSAxLCAyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgLT0gMjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vZW5kIHRyaW1Eb3RzCgogICAgICAgICAgICAgICAgbmFtZSA9IG5hbWUuam9pbigiLyIpOwogICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWUuaW5kZXhPZignLi8nKSA9PT0gMCkgewogICAgICAgICAgICAgICAgLy8gTm8gYmFzZU5hbWUsIHNvIHRoaXMgaXMgSUQgaXMgcmVzb2x2ZWQgcmVsYXRpdmUKICAgICAgICAgICAgICAgIC8vIHRvIGJhc2VVcmwsIHB1bGwgb2ZmIHRoZSBsZWFkaW5nIGRvdC4KICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cmluZygyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy9BcHBseSBtYXAgY29uZmlnIGlmIGF2YWlsYWJsZS4KICAgICAgICBpZiAoKGJhc2VQYXJ0cyB8fCBzdGFyTWFwKSAmJiBtYXApIHsKICAgICAgICAgICAgbmFtZVBhcnRzID0gbmFtZS5zcGxpdCgnLycpOwoKICAgICAgICAgICAgZm9yIChpID0gbmFtZVBhcnRzLmxlbmd0aDsgaSA+IDA7IGkgLT0gMSkgewogICAgICAgICAgICAgICAgbmFtZVNlZ21lbnQgPSBuYW1lUGFydHMuc2xpY2UoMCwgaSkuam9pbigiLyIpOwoKICAgICAgICAgICAgICAgIGlmIChiYXNlUGFydHMpIHsKICAgICAgICAgICAgICAgICAgICAvL0ZpbmQgdGhlIGxvbmdlc3QgYmFzZU5hbWUgc2VnbWVudCBtYXRjaCBpbiB0aGUgY29uZmlnLgogICAgICAgICAgICAgICAgICAgIC8vU28sIGRvIGpvaW5zIG9uIHRoZSBiaWdnZXN0IHRvIHNtYWxsZXN0IGxlbmd0aHMgb2YgYmFzZVBhcnRzLgogICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IGJhc2VQYXJ0cy5sZW5ndGg7IGogPiAwOyBqIC09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbWFwVmFsdWUgPSBtYXBbYmFzZVBhcnRzLnNsaWNlKDAsIGopLmpvaW4oJy8nKV07CgogICAgICAgICAgICAgICAgICAgICAgICAvL2Jhc2VOYW1lIHNlZ21lbnQgaGFzICBjb25maWcsIGZpbmQgaWYgaXQgaGFzIG9uZSBmb3IKICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzIG5hbWUuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtYXBWYWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwVmFsdWUgPSBtYXBWYWx1ZVtuYW1lU2VnbWVudF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWFwVmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL01hdGNoLCB1cGRhdGUgbmFtZSB0byB0aGUgbmV3IHZhbHVlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kTWFwID0gbWFwVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRJID0gaTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoZm91bmRNYXApIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvL0NoZWNrIGZvciBhIHN0YXIgbWFwIG1hdGNoLCBidXQganVzdCBob2xkIG9uIHRvIGl0LAogICAgICAgICAgICAgICAgLy9pZiB0aGVyZSBpcyBhIHNob3J0ZXIgc2VnbWVudCBtYXRjaCBsYXRlciBpbiBhIG1hdGNoaW5nCiAgICAgICAgICAgICAgICAvL2NvbmZpZywgdGhlbiBmYXZvciBvdmVyIHRoaXMgc3RhciBtYXAuCiAgICAgICAgICAgICAgICBpZiAoIWZvdW5kU3Rhck1hcCAmJiBzdGFyTWFwICYmIHN0YXJNYXBbbmFtZVNlZ21lbnRdKSB7CiAgICAgICAgICAgICAgICAgICAgZm91bmRTdGFyTWFwID0gc3Rhck1hcFtuYW1lU2VnbWVudF07CiAgICAgICAgICAgICAgICAgICAgc3RhckkgPSBpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWZvdW5kTWFwICYmIGZvdW5kU3Rhck1hcCkgewogICAgICAgICAgICAgICAgZm91bmRNYXAgPSBmb3VuZFN0YXJNYXA7CiAgICAgICAgICAgICAgICBmb3VuZEkgPSBzdGFySTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGZvdW5kTWFwKSB7CiAgICAgICAgICAgICAgICBuYW1lUGFydHMuc3BsaWNlKDAsIGZvdW5kSSwgZm91bmRNYXApOwogICAgICAgICAgICAgICAgbmFtZSA9IG5hbWVQYXJ0cy5qb2luKCcvJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBuYW1lOwogICAgfQoKICAgIGZ1bmN0aW9uIG1ha2VSZXF1aXJlKHJlbE5hbWUsIGZvcmNlU3luYykgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vQSB2ZXJzaW9uIG9mIGEgcmVxdWlyZSBmdW5jdGlvbiB0aGF0IHBhc3NlcyBhIG1vZHVsZU5hbWUKICAgICAgICAgICAgLy92YWx1ZSBmb3IgaXRlbXMgdGhhdCBtYXkgbmVlZCB0bwogICAgICAgICAgICAvL2xvb2sgdXAgcGF0aHMgcmVsYXRpdmUgdG8gdGhlIG1vZHVsZU5hbWUKICAgICAgICAgICAgcmV0dXJuIHJlcS5hcHBseSh1bmRlZiwgYXBzLmNhbGwoYXJndW1lbnRzLCAwKS5jb25jYXQoW3JlbE5hbWUsIGZvcmNlU3luY10pKTsKICAgICAgICB9OwogICAgfQoKICAgIGZ1bmN0aW9uIG1ha2VOb3JtYWxpemUocmVsTmFtZSkgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAobmFtZSkgewogICAgICAgICAgICByZXR1cm4gbm9ybWFsaXplKG5hbWUsIHJlbE5hbWUpOwogICAgICAgIH07CiAgICB9CgogICAgZnVuY3Rpb24gbWFrZUxvYWQoZGVwTmFtZSkgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgZGVmaW5lZFtkZXBOYW1lXSA9IHZhbHVlOwogICAgICAgIH07CiAgICB9CgogICAgZnVuY3Rpb24gY2FsbERlcChuYW1lKSB7CiAgICAgICAgaWYgKGhhc1Byb3Aod2FpdGluZywgbmFtZSkpIHsKICAgICAgICAgICAgdmFyIGFyZ3MgPSB3YWl0aW5nW25hbWVdOwogICAgICAgICAgICBkZWxldGUgd2FpdGluZ1tuYW1lXTsKICAgICAgICAgICAgZGVmaW5pbmdbbmFtZV0gPSB0cnVlOwogICAgICAgICAgICBtYWluLmFwcGx5KHVuZGVmLCBhcmdzKTsKICAgICAgICB9CgogICAgICAgIGlmICghaGFzUHJvcChkZWZpbmVkLCBuYW1lKSAmJiAhaGFzUHJvcChkZWZpbmluZywgbmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyAnICsgbmFtZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBkZWZpbmVkW25hbWVdOwogICAgfQoKICAgIC8vVHVybnMgYSBwbHVnaW4hcmVzb3VyY2UgdG8gW3BsdWdpbiwgcmVzb3VyY2VdCiAgICAvL3dpdGggdGhlIHBsdWdpbiBiZWluZyB1bmRlZmluZWQgaWYgdGhlIG5hbWUKICAgIC8vZGlkIG5vdCBoYXZlIGEgcGx1Z2luIHByZWZpeC4KICAgIGZ1bmN0aW9uIHNwbGl0UHJlZml4KG5hbWUpIHsKICAgICAgICB2YXIgcHJlZml4LAogICAgICAgICAgICBpbmRleCA9IG5hbWUgPyBuYW1lLmluZGV4T2YoJyEnKSA6IC0xOwogICAgICAgIGlmIChpbmRleCA+IC0xKSB7CiAgICAgICAgICAgIHByZWZpeCA9IG5hbWUuc3Vic3RyaW5nKDAsIGluZGV4KTsKICAgICAgICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSwgbmFtZS5sZW5ndGgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gW3ByZWZpeCwgbmFtZV07CiAgICB9CgogICAgLyoqCiAgICAgKiBNYWtlcyBhIG5hbWUgbWFwLCBub3JtYWxpemluZyB0aGUgbmFtZSwgYW5kIHVzaW5nIGEgcGx1Z2luCiAgICAgKiBmb3Igbm9ybWFsaXphdGlvbiBpZiBuZWNlc3NhcnkuIEdyYWJzIGEgcmVmIHRvIHBsdWdpbgogICAgICogdG9vLCBhcyBhbiBvcHRpbWl6YXRpb24uCiAgICAgKi8KICAgIG1ha2VNYXAgPSBmdW5jdGlvbiAobmFtZSwgcmVsTmFtZSkgewogICAgICAgIHZhciBwbHVnaW4sCiAgICAgICAgICAgIHBhcnRzID0gc3BsaXRQcmVmaXgobmFtZSksCiAgICAgICAgICAgIHByZWZpeCA9IHBhcnRzWzBdOwoKICAgICAgICBuYW1lID0gcGFydHNbMV07CgogICAgICAgIGlmIChwcmVmaXgpIHsKICAgICAgICAgICAgcHJlZml4ID0gbm9ybWFsaXplKHByZWZpeCwgcmVsTmFtZSk7CiAgICAgICAgICAgIHBsdWdpbiA9IGNhbGxEZXAocHJlZml4KTsKICAgICAgICB9CgogICAgICAgIC8vTm9ybWFsaXplIGFjY29yZGluZwogICAgICAgIGlmIChwcmVmaXgpIHsKICAgICAgICAgICAgaWYgKHBsdWdpbiAmJiBwbHVnaW4ubm9ybWFsaXplKSB7CiAgICAgICAgICAgICAgICBuYW1lID0gcGx1Z2luLm5vcm1hbGl6ZShuYW1lLCBtYWtlTm9ybWFsaXplKHJlbE5hbWUpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG5hbWUgPSBub3JtYWxpemUobmFtZSwgcmVsTmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBuYW1lID0gbm9ybWFsaXplKG5hbWUsIHJlbE5hbWUpOwogICAgICAgICAgICBwYXJ0cyA9IHNwbGl0UHJlZml4KG5hbWUpOwogICAgICAgICAgICBwcmVmaXggPSBwYXJ0c1swXTsKICAgICAgICAgICAgbmFtZSA9IHBhcnRzWzFdOwogICAgICAgICAgICBpZiAocHJlZml4KSB7CiAgICAgICAgICAgICAgICBwbHVnaW4gPSBjYWxsRGVwKHByZWZpeCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vVXNpbmcgcmlkaWN1bG91cyBwcm9wZXJ0eSBuYW1lcyBmb3Igc3BhY2UgcmVhc29ucwogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIGY6IHByZWZpeCA/IHByZWZpeCArICchJyArIG5hbWUgOiBuYW1lLCAvL2Z1bGxOYW1lCiAgICAgICAgICAgIG46IG5hbWUsCiAgICAgICAgICAgIHByOiBwcmVmaXgsCiAgICAgICAgICAgIHA6IHBsdWdpbgogICAgICAgIH07CiAgICB9OwoKICAgIGZ1bmN0aW9uIG1ha2VDb25maWcobmFtZSkgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAoY29uZmlnICYmIGNvbmZpZy5jb25maWcgJiYgY29uZmlnLmNvbmZpZ1tuYW1lXSkgfHwge307CiAgICAgICAgfTsKICAgIH0KCiAgICBoYW5kbGVycyA9IHsKICAgICAgICByZXF1aXJlOiBmdW5jdGlvbiAobmFtZSkgewogICAgICAgICAgICByZXR1cm4gbWFrZVJlcXVpcmUobmFtZSk7CiAgICAgICAgfSwKICAgICAgICBleHBvcnRzOiBmdW5jdGlvbiAobmFtZSkgewogICAgICAgICAgICB2YXIgZSA9IGRlZmluZWRbbmFtZV07CiAgICAgICAgICAgIGlmICh0eXBlb2YgZSAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICAgICAgICAgIHJldHVybiBlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIChkZWZpbmVkW25hbWVdID0ge30pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtb2R1bGU6IGZ1bmN0aW9uIChuYW1lKSB7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICBpZDogbmFtZSwKICAgICAgICAgICAgICAgIHVyaTogJycsCiAgICAgICAgICAgICAgICBleHBvcnRzOiBkZWZpbmVkW25hbWVdLAogICAgICAgICAgICAgICAgY29uZmlnOiBtYWtlQ29uZmlnKG5hbWUpCiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfTsKCiAgICBtYWluID0gZnVuY3Rpb24gKG5hbWUsIGRlcHMsIGNhbGxiYWNrLCByZWxOYW1lKSB7CiAgICAgICAgdmFyIGNqc01vZHVsZSwgZGVwTmFtZSwgcmV0LCBtYXAsIGksCiAgICAgICAgICAgIGFyZ3MgPSBbXSwKICAgICAgICAgICAgY2FsbGJhY2tUeXBlID0gdHlwZW9mIGNhbGxiYWNrLAogICAgICAgICAgICB1c2luZ0V4cG9ydHM7CgogICAgICAgIC8vVXNlIG5hbWUgaWYgbm8gcmVsTmFtZQogICAgICAgIHJlbE5hbWUgPSByZWxOYW1lIHx8IG5hbWU7CgogICAgICAgIC8vQ2FsbCB0aGUgY2FsbGJhY2sgdG8gZGVmaW5lIHRoZSBtb2R1bGUsIGlmIG5lY2Vzc2FyeS4KICAgICAgICBpZiAoY2FsbGJhY2tUeXBlID09PSAndW5kZWZpbmVkJyB8fCBjYWxsYmFja1R5cGUgPT09ICdmdW5jdGlvbicpIHsKICAgICAgICAgICAgLy9QdWxsIG91dCB0aGUgZGVmaW5lZCBkZXBlbmRlbmNpZXMgYW5kIHBhc3MgdGhlIG9yZGVyZWQKICAgICAgICAgICAgLy92YWx1ZXMgdG8gdGhlIGNhbGxiYWNrLgogICAgICAgICAgICAvL0RlZmF1bHQgdG8gW3JlcXVpcmUsIGV4cG9ydHMsIG1vZHVsZV0gaWYgbm8gZGVwcwogICAgICAgICAgICBkZXBzID0gIWRlcHMubGVuZ3RoICYmIGNhbGxiYWNrLmxlbmd0aCA/IFsncmVxdWlyZScsICdleHBvcnRzJywgJ21vZHVsZSddIDogZGVwczsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGRlcHMubGVuZ3RoOyBpICs9IDEpIHsKICAgICAgICAgICAgICAgIG1hcCA9IG1ha2VNYXAoZGVwc1tpXSwgcmVsTmFtZSk7CiAgICAgICAgICAgICAgICBkZXBOYW1lID0gbWFwLmY7CgogICAgICAgICAgICAgICAgLy9GYXN0IHBhdGggQ29tbW9uSlMgc3RhbmRhcmQgZGVwZW5kZW5jaWVzLgogICAgICAgICAgICAgICAgaWYgKGRlcE5hbWUgPT09ICJyZXF1aXJlIikgewogICAgICAgICAgICAgICAgICAgIGFyZ3NbaV0gPSBoYW5kbGVycy5yZXF1aXJlKG5hbWUpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkZXBOYW1lID09PSAiZXhwb3J0cyIpIHsKICAgICAgICAgICAgICAgICAgICAvL0NvbW1vbkpTIG1vZHVsZSBzcGVjIDEuMQogICAgICAgICAgICAgICAgICAgIGFyZ3NbaV0gPSBoYW5kbGVycy5leHBvcnRzKG5hbWUpOwogICAgICAgICAgICAgICAgICAgIHVzaW5nRXhwb3J0cyA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRlcE5hbWUgPT09ICJtb2R1bGUiKSB7CiAgICAgICAgICAgICAgICAgICAgLy9Db21tb25KUyBtb2R1bGUgc3BlYyAxLjEKICAgICAgICAgICAgICAgICAgICBjanNNb2R1bGUgPSBhcmdzW2ldID0gaGFuZGxlcnMubW9kdWxlKG5hbWUpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChoYXNQcm9wKGRlZmluZWQsIGRlcE5hbWUpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc1Byb3Aod2FpdGluZywgZGVwTmFtZSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzUHJvcChkZWZpbmluZywgZGVwTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICBhcmdzW2ldID0gY2FsbERlcChkZXBOYW1lKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobWFwLnApIHsKICAgICAgICAgICAgICAgICAgICBtYXAucC5sb2FkKG1hcC5uLCBtYWtlUmVxdWlyZShyZWxOYW1lLCB0cnVlKSwgbWFrZUxvYWQoZGVwTmFtZSksIHt9KTsKICAgICAgICAgICAgICAgICAgICBhcmdzW2ldID0gZGVmaW5lZFtkZXBOYW1lXTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG5hbWUgKyAnIG1pc3NpbmcgJyArIGRlcE5hbWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXQgPSBjYWxsYmFjayA/IGNhbGxiYWNrLmFwcGx5KGRlZmluZWRbbmFtZV0sIGFyZ3MpIDogdW5kZWZpbmVkOwoKICAgICAgICAgICAgaWYgKG5hbWUpIHsKICAgICAgICAgICAgICAgIC8vSWYgc2V0dGluZyBleHBvcnRzIHZpYSAibW9kdWxlIiBpcyBpbiBwbGF5LAogICAgICAgICAgICAgICAgLy9mYXZvciB0aGF0IG92ZXIgcmV0dXJuIHZhbHVlIGFuZCBleHBvcnRzLiBBZnRlciB0aGF0LAogICAgICAgICAgICAgICAgLy9mYXZvciBhIG5vbi11bmRlZmluZWQgcmV0dXJuIHZhbHVlIG92ZXIgZXhwb3J0cyB1c2UuCiAgICAgICAgICAgICAgICBpZiAoY2pzTW9kdWxlICYmIGNqc01vZHVsZS5leHBvcnRzICE9PSB1bmRlZiAmJgogICAgICAgICAgICAgICAgICAgICAgICBjanNNb2R1bGUuZXhwb3J0cyAhPT0gZGVmaW5lZFtuYW1lXSkgewogICAgICAgICAgICAgICAgICAgIGRlZmluZWRbbmFtZV0gPSBjanNNb2R1bGUuZXhwb3J0czsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmV0ICE9PSB1bmRlZiB8fCAhdXNpbmdFeHBvcnRzKSB7CiAgICAgICAgICAgICAgICAgICAgLy9Vc2UgdGhlIHJldHVybiB2YWx1ZSBmcm9tIHRoZSBmdW5jdGlvbi4KICAgICAgICAgICAgICAgICAgICBkZWZpbmVkW25hbWVdID0gcmV0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChuYW1lKSB7CiAgICAgICAgICAgIC8vTWF5IGp1c3QgYmUgYW4gb2JqZWN0IGRlZmluaXRpb24gZm9yIHRoZSBtb2R1bGUuIE9ubHkKICAgICAgICAgICAgLy93b3JyeSBhYm91dCBkZWZpbmluZyBpZiBoYXZlIGEgbW9kdWxlIG5hbWUuCiAgICAgICAgICAgIGRlZmluZWRbbmFtZV0gPSBjYWxsYmFjazsKICAgICAgICB9CiAgICB9OwoKICAgIHJlcXVpcmVqcyA9IHJlcXVpcmUgPSByZXEgPSBmdW5jdGlvbiAoZGVwcywgY2FsbGJhY2ssIHJlbE5hbWUsIGZvcmNlU3luYywgYWx0KSB7CiAgICAgICAgaWYgKHR5cGVvZiBkZXBzID09PSAic3RyaW5nIikgewogICAgICAgICAgICBpZiAoaGFuZGxlcnNbZGVwc10pIHsKICAgICAgICAgICAgICAgIC8vY2FsbGJhY2sgaW4gdGhpcyBjYXNlIGlzIHJlYWxseSByZWxOYW1lCiAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlcnNbZGVwc10oY2FsbGJhY2spOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vSnVzdCByZXR1cm4gdGhlIG1vZHVsZSB3YW50ZWQuIEluIHRoaXMgc2NlbmFyaW8sIHRoZQogICAgICAgICAgICAvL2RlcHMgYXJnIGlzIHRoZSBtb2R1bGUgbmFtZSwgYW5kIHNlY29uZCBhcmcgKGlmIHBhc3NlZCkKICAgICAgICAgICAgLy9pcyBqdXN0IHRoZSByZWxOYW1lLgogICAgICAgICAgICAvL05vcm1hbGl6ZSBtb2R1bGUgbmFtZSwgaWYgaXQgY29udGFpbnMgLiBvciAuLgogICAgICAgICAgICByZXR1cm4gY2FsbERlcChtYWtlTWFwKGRlcHMsIGNhbGxiYWNrKS5mKTsKICAgICAgICB9IGVsc2UgaWYgKCFkZXBzLnNwbGljZSkgewogICAgICAgICAgICAvL2RlcHMgaXMgYSBjb25maWcgb2JqZWN0LCBub3QgYW4gYXJyYXkuCiAgICAgICAgICAgIGNvbmZpZyA9IGRlcHM7CiAgICAgICAgICAgIGlmIChjb25maWcuZGVwcykgewogICAgICAgICAgICAgICAgcmVxKGNvbmZpZy5kZXBzLCBjb25maWcuY2FsbGJhY2spOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghY2FsbGJhY2spIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNhbGxiYWNrLnNwbGljZSkgewogICAgICAgICAgICAgICAgLy9jYWxsYmFjayBpcyBhbiBhcnJheSwgd2hpY2ggbWVhbnMgaXQgaXMgYSBkZXBlbmRlbmN5IGxpc3QuCiAgICAgICAgICAgICAgICAvL0FkanVzdCBhcmdzIGlmIHRoZXJlIGFyZSBkZXBlbmRlbmNpZXMKICAgICAgICAgICAgICAgIGRlcHMgPSBjYWxsYmFjazsKICAgICAgICAgICAgICAgIGNhbGxiYWNrID0gcmVsTmFtZTsKICAgICAgICAgICAgICAgIHJlbE5hbWUgPSBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZGVwcyA9IHVuZGVmOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvL1N1cHBvcnQgcmVxdWlyZShbJ2EnXSkKICAgICAgICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IGZ1bmN0aW9uICgpIHt9OwoKICAgICAgICAvL0lmIHJlbE5hbWUgaXMgYSBmdW5jdGlvbiwgaXQgaXMgYW4gZXJyYmFjayBoYW5kbGVyLAogICAgICAgIC8vc28gcmVtb3ZlIGl0LgogICAgICAgIGlmICh0eXBlb2YgcmVsTmFtZSA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgICByZWxOYW1lID0gZm9yY2VTeW5jOwogICAgICAgICAgICBmb3JjZVN5bmMgPSBhbHQ7CiAgICAgICAgfQoKICAgICAgICAvL1NpbXVsYXRlIGFzeW5jIGNhbGxiYWNrOwogICAgICAgIGlmIChmb3JjZVN5bmMpIHsKICAgICAgICAgICAgbWFpbih1bmRlZiwgZGVwcywgY2FsbGJhY2ssIHJlbE5hbWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vVXNpbmcgYSBub24temVybyB2YWx1ZSBiZWNhdXNlIG9mIGNvbmNlcm4gZm9yIHdoYXQgb2xkIGJyb3dzZXJzCiAgICAgICAgICAgIC8vZG8sIGFuZCBsYXRlc3QgYnJvd3NlcnMgInVwZ3JhZGUiIHRvIDQgaWYgbG93ZXIgdmFsdWUgaXMgdXNlZDoKICAgICAgICAgICAgLy9odHRwOi8vd3d3LndoYXR3Zy5vcmcvc3BlY3Mvd2ViLWFwcHMvY3VycmVudC13b3JrL211bHRpcGFnZS90aW1lcnMuaHRtbCNkb20td2luZG93dGltZXJzLXNldHRpbWVvdXQ6CiAgICAgICAgICAgIC8vSWYgd2FudCBhIHZhbHVlIGltbWVkaWF0ZWx5LCB1c2UgcmVxdWlyZSgnaWQnKSBpbnN0ZWFkIC0tIHNvbWV0aGluZwogICAgICAgICAgICAvL3RoYXQgd29ya3MgaW4gYWxtb25kIG9uIHRoZSBnbG9iYWwgbGV2ZWwsIGJ1dCBub3QgZ3VhcmFudGVlZCBhbmQKICAgICAgICAgICAgLy91bmxpa2VseSB0byB3b3JrIGluIG90aGVyIEFNRCBpbXBsZW1lbnRhdGlvbnMuCiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgbWFpbih1bmRlZiwgZGVwcywgY2FsbGJhY2ssIHJlbE5hbWUpOwogICAgICAgICAgICB9LCA0KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXE7CiAgICB9OwoKICAgIC8qKgogICAgICogSnVzdCBkcm9wcyB0aGUgY29uZmlnIG9uIHRoZSBmbG9vciwgYnV0IHJldHVybnMgcmVxIGluIGNhc2UKICAgICAqIHRoZSBjb25maWcgcmV0dXJuIHZhbHVlIGlzIHVzZWQuCiAgICAgKi8KICAgIHJlcS5jb25maWcgPSBmdW5jdGlvbiAoY2ZnKSB7CiAgICAgICAgcmV0dXJuIHJlcShjZmcpOwogICAgfTsKCiAgICAvKioKICAgICAqIEV4cG9zZSBtb2R1bGUgcmVnaXN0cnkgZm9yIGRlYnVnZ2luZyBhbmQgdG9vbGluZwogICAgICovCiAgICByZXF1aXJlanMuX2RlZmluZWQgPSBkZWZpbmVkOwoKICAgIGRlZmluZSA9IGZ1bmN0aW9uIChuYW1lLCBkZXBzLCBjYWxsYmFjaykgewoKICAgICAgICAvL1RoaXMgbW9kdWxlIG1heSBub3QgaGF2ZSBkZXBlbmRlbmNpZXMKICAgICAgICBpZiAoIWRlcHMuc3BsaWNlKSB7CiAgICAgICAgICAgIC8vZGVwcyBpcyBub3QgYW4gYXJyYXksIHNvIHByb2JhYmx5IG1lYW5zCiAgICAgICAgICAgIC8vYW4gb2JqZWN0IGxpdGVyYWwgb3IgZmFjdG9yeSBmdW5jdGlvbiBmb3IKICAgICAgICAgICAgLy90aGUgdmFsdWUuIEFkanVzdCBhcmdzLgogICAgICAgICAgICBjYWxsYmFjayA9IGRlcHM7CiAgICAgICAgICAgIGRlcHMgPSBbXTsKICAgICAgICB9CgogICAgICAgIGlmICghaGFzUHJvcChkZWZpbmVkLCBuYW1lKSAmJiAhaGFzUHJvcCh3YWl0aW5nLCBuYW1lKSkgewogICAgICAgICAgICB3YWl0aW5nW25hbWVdID0gW25hbWUsIGRlcHMsIGNhbGxiYWNrXTsKICAgICAgICB9CiAgICB9OwoKICAgIGRlZmluZS5hbWQgPSB7CiAgICAgICAgalF1ZXJ5OiB0cnVlCiAgICB9Owp9KCkpOwoKZGVmaW5lKCJub2RlX21vZHVsZXMvYWxtb25kL2FsbW9uZCIsIGZ1bmN0aW9uKCl7fSk7CgovKioKICogVXRpbGl0eSBmdW5jdGlvbnMgZm9yIHdlYiBhcHBsaWNhdGlvbnMuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKLyogVXRpbGl0aWVzIEFQSSAqLwp2YXIgdXRpbCA9IGZvcmdlLnV0aWwgPSBmb3JnZS51dGlsIHx8IHt9OwoKLy8gZGVmaW5lIHNldEltbWVkaWF0ZSBhbmQgbmV4dFRpY2sKKGZ1bmN0aW9uKCkgewogIC8vIHVzZSBuYXRpdmUgbmV4dFRpY2sKICBpZih0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvY2Vzcy5uZXh0VGljaykgewogICAgdXRpbC5uZXh0VGljayA9IHByb2Nlc3MubmV4dFRpY2s7CiAgICBpZih0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSAnZnVuY3Rpb24nKSB7CiAgICAgIHV0aWwuc2V0SW1tZWRpYXRlID0gc2V0SW1tZWRpYXRlOwogICAgfSBlbHNlIHsKICAgICAgLy8gcG9seWZpbGwgc2V0SW1tZWRpYXRlIHdpdGggbmV4dFRpY2ssIG9sZGVyIHZlcnNpb25zIG9mIG5vZGUKICAgICAgLy8gKHRob3NlIHcvbyBzZXRJbW1lZGlhdGUpIHdvbid0IHRvdGFsbHkgc3RhcnZlIElPCiAgICAgIHV0aWwuc2V0SW1tZWRpYXRlID0gdXRpbC5uZXh0VGljazsKICAgIH0KICAgIHJldHVybjsKICB9CgogIC8vIHBvbHlmaWxsIG5leHRUaWNrIHdpdGggbmF0aXZlIHNldEltbWVkaWF0ZQogIGlmKHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09ICdmdW5jdGlvbicpIHsKICAgIHV0aWwuc2V0SW1tZWRpYXRlID0gc2V0SW1tZWRpYXRlOwogICAgdXRpbC5uZXh0VGljayA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7CiAgICAgIHJldHVybiBzZXRJbW1lZGlhdGUoY2FsbGJhY2spOwogICAgfTsKICAgIHJldHVybjsKICB9CgogIC8qIE5vdGU6IEEgcG9seWZpbGwgdXBncmFkZSBwYXR0ZXJuIGlzIHVzZWQgaGVyZSB0byBhbGxvdyBjb21iaW5pbmcKICBwb2x5ZmlsbHMuIEZvciBleGFtcGxlLCBNdXRhdGlvbk9ic2VydmVyIGlzIGZhc3QsIGJ1dCBibG9ja3MgVUkgdXBkYXRlcywKICBzbyBpdCBuZWVkcyB0byBhbGxvdyBVSSB1cGRhdGVzIHBlcmlvZGljYWxseSwgc28gaXQgZmFsbHMgYmFjayBvbgogIHBvc3RNZXNzYWdlIG9yIHNldFRpbWVvdXQuICovCgogIC8vIHBvbHlmaWxsIHdpdGggc2V0VGltZW91dAogIHV0aWwuc2V0SW1tZWRpYXRlID0gZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgIHNldFRpbWVvdXQoY2FsbGJhY2ssIDApOwogIH07CgogIC8vIHVwZ3JhZGUgcG9seWZpbGwgdG8gdXNlIHBvc3RNZXNzYWdlCiAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYKICAgIHR5cGVvZiB3aW5kb3cucG9zdE1lc3NhZ2UgPT09ICdmdW5jdGlvbicpIHsKICAgIHZhciBtc2cgPSAnZm9yZ2Uuc2V0SW1tZWRpYXRlJzsKICAgIHZhciBjYWxsYmFja3MgPSBbXTsKICAgIHV0aWwuc2V0SW1tZWRpYXRlID0gZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgICAgY2FsbGJhY2tzLnB1c2goY2FsbGJhY2spOwogICAgICAvLyBvbmx5IHNlbmQgbWVzc2FnZSB3aGVuIG9uZSBoYXNuJ3QgYmVlbiBzZW50IGluCiAgICAgIC8vIHRoZSBjdXJyZW50IHR1cm4gb2YgdGhlIGV2ZW50IGxvb3AKICAgICAgaWYoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMSkgewogICAgICAgIHdpbmRvdy5wb3N0TWVzc2FnZShtc2csICcqJyk7CiAgICAgIH0KICAgIH07CiAgICBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50KSB7CiAgICAgIGlmKGV2ZW50LnNvdXJjZSA9PT0gd2luZG93ICYmIGV2ZW50LmRhdGEgPT09IG1zZykgewogICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwogICAgICAgIHZhciBjb3B5ID0gY2FsbGJhY2tzLnNsaWNlKCk7CiAgICAgICAgY2FsbGJhY2tzLmxlbmd0aCA9IDA7CiAgICAgICAgY29weS5mb3JFYWNoKGZ1bmN0aW9uKGNhbGxiYWNrKSB7CiAgICAgICAgICBjYWxsYmFjaygpOwogICAgICAgIH0pOwogICAgICB9CiAgICB9CiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGhhbmRsZXIsIHRydWUpOwogIH0KCiAgLy8gdXBncmFkZSBwb2x5ZmlsbCB0byB1c2UgTXV0YXRpb25PYnNlcnZlcgogIGlmKHR5cGVvZiBNdXRhdGlvbk9ic2VydmVyICE9PSAndW5kZWZpbmVkJykgewogICAgLy8gcG9seWZpbGwgd2l0aCBNdXRhdGlvbk9ic2VydmVyCiAgICB2YXIgbm93ID0gRGF0ZS5ub3coKTsKICAgIHZhciBhdHRyID0gdHJ1ZTsKICAgIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKICAgIHZhciBjYWxsYmFja3MgPSBbXTsKICAgIG5ldyBNdXRhdGlvbk9ic2VydmVyKGZ1bmN0aW9uKCkgewogICAgICB2YXIgY29weSA9IGNhbGxiYWNrcy5zbGljZSgpOwogICAgICBjYWxsYmFja3MubGVuZ3RoID0gMDsKICAgICAgY29weS5mb3JFYWNoKGZ1bmN0aW9uKGNhbGxiYWNrKSB7CiAgICAgICAgY2FsbGJhY2soKTsKICAgICAgfSk7CiAgICB9KS5vYnNlcnZlKGRpdiwge2F0dHJpYnV0ZXM6IHRydWV9KTsKICAgIHZhciBvbGRTZXRJbW1lZGlhdGUgPSB1dGlsLnNldEltbWVkaWF0ZTsKICAgIHV0aWwuc2V0SW1tZWRpYXRlID0gZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgICAgaWYoRGF0ZS5ub3coKSAtIG5vdyA+IDE1KSB7CiAgICAgICAgbm93ID0gRGF0ZS5ub3coKTsKICAgICAgICBvbGRTZXRJbW1lZGlhdGUoY2FsbGJhY2spOwogICAgICB9IGVsc2UgewogICAgICAgIGNhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKTsKICAgICAgICAvLyBvbmx5IHRyaWdnZXIgb2JzZXJ2ZXIgd2hlbiBpdCBoYXNuJ3QgYmVlbiB0cmlnZ2VyZWQgaW4KICAgICAgICAvLyB0aGUgY3VycmVudCB0dXJuIG9mIHRoZSBldmVudCBsb29wCiAgICAgICAgaWYoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMSkgewogICAgICAgICAgZGl2LnNldEF0dHJpYnV0ZSgnYScsIGF0dHIgPSAhYXR0cik7CiAgICAgICAgfQogICAgICB9CiAgICB9OwogIH0KCiAgdXRpbC5uZXh0VGljayA9IHV0aWwuc2V0SW1tZWRpYXRlOwp9KSgpOwoKLy8gZGVmaW5lIGlzQXJyYXkKdXRpbC5pc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbih4KSB7CiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh4KSA9PT0gJ1tvYmplY3QgQXJyYXldJzsKfTsKCi8vIGRlZmluZSBpc0FycmF5QnVmZmVyCnV0aWwuaXNBcnJheUJ1ZmZlciA9IGZ1bmN0aW9uKHgpIHsKICByZXR1cm4gdHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB4IGluc3RhbmNlb2YgQXJyYXlCdWZmZXI7Cn07CgovLyBkZWZpbmUgaXNBcnJheUJ1ZmZlclZpZXcKdXRpbC5pc0FycmF5QnVmZmVyVmlldyA9IGZ1bmN0aW9uKHgpIHsKICByZXR1cm4geCAmJiB1dGlsLmlzQXJyYXlCdWZmZXIoeC5idWZmZXIpICYmIHguYnl0ZUxlbmd0aCAhPT0gdW5kZWZpbmVkOwp9OwoKLy8gVE9ETzogc2V0IEJ5dGVCdWZmZXIgdG8gYmVzdCBhdmFpbGFibGUgYmFja2luZwp1dGlsLkJ5dGVCdWZmZXIgPSBCeXRlU3RyaW5nQnVmZmVyOwoKLyoqIEJ1ZmZlciB3L0JpbmFyeVN0cmluZyBiYWNraW5nICovCgovKioKICogQ29uc3RydWN0b3IgZm9yIGEgYmluYXJ5IHN0cmluZyBiYWNrZWQgYnl0ZSBidWZmZXIuCiAqCiAqIEBwYXJhbSBbYl0gdGhlIGJ5dGVzIHRvIHdyYXAgKGVpdGhlciBlbmNvZGVkIGFzIHN0cmluZywgb25lIGJ5dGUgcGVyCiAqICAgICAgICAgIGNoYXJhY3Rlciwgb3IgYXMgYW4gQXJyYXlCdWZmZXIgb3IgVHlwZWQgQXJyYXkpLgogKi8KZnVuY3Rpb24gQnl0ZVN0cmluZ0J1ZmZlcihiKSB7CiAgLy8gVE9ETzogdXBkYXRlIHRvIG1hdGNoIERhdGFCdWZmZXIgQVBJCgogIC8vIHRoZSBkYXRhIGluIHRoaXMgYnVmZmVyCiAgdGhpcy5kYXRhID0gJyc7CiAgLy8gdGhlIHBvaW50ZXIgZm9yIHJlYWRpbmcgZnJvbSB0aGlzIGJ1ZmZlcgogIHRoaXMucmVhZCA9IDA7CgogIGlmKHR5cGVvZiBiID09PSAnc3RyaW5nJykgewogICAgdGhpcy5kYXRhID0gYjsKICB9IGVsc2UgaWYodXRpbC5pc0FycmF5QnVmZmVyKGIpIHx8IHV0aWwuaXNBcnJheUJ1ZmZlclZpZXcoYikpIHsKICAgIC8vIGNvbnZlcnQgbmF0aXZlIGJ1ZmZlciB0byBmb3JnZSBidWZmZXIKICAgIC8vIEZJWE1FOiBzdXBwb3J0IG5hdGl2ZSBidWZmZXJzIGludGVybmFsbHkgaW5zdGVhZAogICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KGIpOwogICAgdHJ5IHsKICAgICAgdGhpcy5kYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBhcnIpOwogICAgfSBjYXRjaChlKSB7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyArK2kpIHsKICAgICAgICB0aGlzLnB1dEJ5dGUoYXJyW2ldKTsKICAgICAgfQogICAgfQogIH0gZWxzZSBpZihiIGluc3RhbmNlb2YgQnl0ZVN0cmluZ0J1ZmZlciB8fAogICAgKHR5cGVvZiBiID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgYi5kYXRhID09PSAnc3RyaW5nJyAmJgogICAgdHlwZW9mIGIucmVhZCA9PT0gJ251bWJlcicpKSB7CiAgICAvLyBjb3B5IGV4aXN0aW5nIGJ1ZmZlcgogICAgdGhpcy5kYXRhID0gYi5kYXRhOwogICAgdGhpcy5yZWFkID0gYi5yZWFkOwogIH0KCiAgLy8gdXNlZCBmb3Igdjggb3B0aW1pemF0aW9uCiAgdGhpcy5fY29uc3RydWN0ZWRTdHJpbmdMZW5ndGggPSAwOwp9CnV0aWwuQnl0ZVN0cmluZ0J1ZmZlciA9IEJ5dGVTdHJpbmdCdWZmZXI7CgovKiBOb3RlOiBUaGlzIGlzIGFuIG9wdGltaXphdGlvbiBmb3IgVjgtYmFzZWQgYnJvd3NlcnMuIFdoZW4gVjggY29uY2F0ZW5hdGVzCiAgYSBzdHJpbmcsIHRoZSBzdHJpbmdzIGFyZSBvbmx5IGpvaW5lZCBsb2dpY2FsbHkgdXNpbmcgYSAiY29ucyBzdHJpbmciIG9yCiAgImNvbnN0cnVjdGVkL2NvbmNhdGVuYXRlZCBzdHJpbmciLiBUaGVzZSBjb250YWluZXJzIGtlZXAgcmVmZXJlbmNlcyB0byBvbmUKICBhbm90aGVyIGFuZCBjYW4gcmVzdWx0IGluIHZlcnkgbGFyZ2UgbWVtb3J5IHVzYWdlLiBGb3IgZXhhbXBsZSwgaWYgYSAyTUIKICBzdHJpbmcgaXMgY29uc3RydWN0ZWQgYnkgY29uY2F0ZW5hdGluZyA0IGJ5dGVzIHRvZ2V0aGVyIGF0IGEgdGltZSwgdGhlCiAgbWVtb3J5IHVzYWdlIHdpbGwgYmUgfjQ0TUI7IHNvIH4yMnggaW5jcmVhc2UuIFRoZSBzdHJpbmdzIGFyZSBvbmx5IGpvaW5lZAogIHRvZ2V0aGVyIHdoZW4gYW4gb3BlcmF0aW9uIHJlcXVpcmluZyB0aGVpciBqb2luaW5nIHRha2VzIHBsYWNlLCBzdWNoIGFzCiAgc3Vic3RyKCkuIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW4gYWRkaW5nIGRhdGEgdG8gdGhpcyBidWZmZXIgdG8gZW5zdXJlCiAgdGhlc2UgdHlwZXMgb2Ygc3RyaW5ncyBhcmUgcGVyaW9kaWNhbGx5IGpvaW5lZCB0byByZWR1Y2UgdGhlIG1lbW9yeQogIGZvb3RwcmludC4gKi8KdmFyIF9NQVhfQ09OU1RSVUNURURfU1RSSU5HX0xFTkdUSCA9IDQwOTY7CnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUuX29wdGltaXplQ29uc3RydWN0ZWRTdHJpbmcgPSBmdW5jdGlvbih4KSB7CiAgdGhpcy5fY29uc3RydWN0ZWRTdHJpbmdMZW5ndGggKz0geDsKICBpZih0aGlzLl9jb25zdHJ1Y3RlZFN0cmluZ0xlbmd0aCA+IF9NQVhfQ09OU1RSVUNURURfU1RSSU5HX0xFTkdUSCkgewogICAgLy8gdGhpcyBzdWJzdHIoKSBzaG91bGQgY2F1c2UgdGhlIGNvbnN0cnVjdGVkIHN0cmluZyB0byBqb2luCiAgICB0aGlzLmRhdGEuc3Vic3RyKDAsIDEpOwogICAgdGhpcy5fY29uc3RydWN0ZWRTdHJpbmdMZW5ndGggPSAwOwogIH0KfTsKCi8qKgogKiBHZXRzIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhpcyBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBpbiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUubGVuZ3RoID0gZnVuY3Rpb24oKSB7CiAgcmV0dXJuIHRoaXMuZGF0YS5sZW5ndGggLSB0aGlzLnJlYWQ7Cn07CgovKioKICogR2V0cyB3aGV0aGVyIG9yIG5vdCB0aGlzIGJ1ZmZlciBpcyBlbXB0eS4KICoKICogQHJldHVybiB0cnVlIGlmIHRoaXMgYnVmZmVyIGlzIGVtcHR5LCBmYWxzZSBpZiBub3QuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmlzRW1wdHkgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gdGhpcy5sZW5ndGgoKSA8PSAwOwp9OwoKLyoqCiAqIFB1dHMgYSBieXRlIGluIHRoaXMgYnVmZmVyLgogKgogKiBAcGFyYW0gYiB0aGUgYnl0ZSB0byBwdXQuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnB1dEJ5dGUgPSBmdW5jdGlvbihiKSB7CiAgcmV0dXJuIHRoaXMucHV0Qnl0ZXMoU3RyaW5nLmZyb21DaGFyQ29kZShiKSk7Cn07CgovKioKICogUHV0cyBhIGJ5dGUgaW4gdGhpcyBidWZmZXIgTiB0aW1lcy4KICoKICogQHBhcmFtIGIgdGhlIGJ5dGUgdG8gcHV0LgogKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJ5dGVzIG9mIHZhbHVlIGIgdG8gcHV0LgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5maWxsV2l0aEJ5dGUgPSBmdW5jdGlvbihiLCBuKSB7CiAgYiA9IFN0cmluZy5mcm9tQ2hhckNvZGUoYik7CiAgdmFyIGQgPSB0aGlzLmRhdGE7CiAgd2hpbGUobiA+IDApIHsKICAgIGlmKG4gJiAxKSB7CiAgICAgIGQgKz0gYjsKICAgIH0KICAgIG4gPj4+PSAxOwogICAgaWYobiA+IDApIHsKICAgICAgYiArPSBiOwogICAgfQogIH0KICB0aGlzLmRhdGEgPSBkOwogIHRoaXMuX29wdGltaXplQ29uc3RydWN0ZWRTdHJpbmcobik7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBieXRlcyBpbiB0aGlzIGJ1ZmZlci4KICoKICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyAoYXMgYSBVVEYtOCBlbmNvZGVkIHN0cmluZykgdG8gcHV0LgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5wdXRCeXRlcyA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgdGhpcy5kYXRhICs9IGJ5dGVzOwogIHRoaXMuX29wdGltaXplQ29uc3RydWN0ZWRTdHJpbmcoYnl0ZXMubGVuZ3RoKTsKICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBQdXRzIGEgVVRGLTE2IGVuY29kZWQgc3RyaW5nIGludG8gdGhpcyBidWZmZXIuCiAqCiAqIEBwYXJhbSBzdHIgdGhlIHN0cmluZyB0byBwdXQuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnB1dFN0cmluZyA9IGZ1bmN0aW9uKHN0cikgewogIHJldHVybiB0aGlzLnB1dEJ5dGVzKHV0aWwuZW5jb2RlVXRmOChzdHIpKTsKfTsKCi8qKgogKiBQdXRzIGEgMTYtYml0IGludGVnZXIgaW4gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlci4KICoKICogQHBhcmFtIGkgdGhlIDE2LWJpdCBpbnRlZ2VyLgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5wdXRJbnQxNiA9IGZ1bmN0aW9uKGkpIHsKICByZXR1cm4gdGhpcy5wdXRCeXRlcygKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiA4ICYgMHhGRikgKwogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpICYgMHhGRikpOwp9OwoKLyoqCiAqIFB1dHMgYSAyNC1iaXQgaW50ZWdlciBpbiB0aGlzIGJ1ZmZlciBpbiBiaWctZW5kaWFuIG9yZGVyLgogKgogKiBAcGFyYW0gaSB0aGUgMjQtYml0IGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnB1dEludDI0ID0gZnVuY3Rpb24oaSkgewogIHJldHVybiB0aGlzLnB1dEJ5dGVzKAogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpID4+IDE2ICYgMHhGRikgKwogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpID4+IDggJiAweEZGKSArCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgJiAweEZGKSk7Cn07CgovKioKICogUHV0cyBhIDMyLWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAzMi1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUucHV0SW50MzIgPSBmdW5jdGlvbihpKSB7CiAgcmV0dXJuIHRoaXMucHV0Qnl0ZXMoCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgPj4gMjQgJiAweEZGKSArCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgPj4gMTYgJiAweEZGKSArCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgPj4gOCAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSAmIDB4RkYpKTsKfTsKCi8qKgogKiBQdXRzIGEgMTYtYml0IGludGVnZXIgaW4gdGhpcyBidWZmZXIgaW4gbGl0dGxlLWVuZGlhbiBvcmRlci4KICoKICogQHBhcmFtIGkgdGhlIDE2LWJpdCBpbnRlZ2VyLgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5wdXRJbnQxNkxlID0gZnVuY3Rpb24oaSkgewogIHJldHVybiB0aGlzLnB1dEJ5dGVzKAogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpICYgMHhGRikgKwogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpID4+IDggJiAweEZGKSk7Cn07CgovKioKICogUHV0cyBhIDI0LWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAyNC1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUucHV0SW50MjRMZSA9IGZ1bmN0aW9uKGkpIHsKICByZXR1cm4gdGhpcy5wdXRCeXRlcygKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiA4ICYgMHhGRikgKwogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpID4+IDE2ICYgMHhGRikpOwp9OwoKLyoqCiAqIFB1dHMgYSAzMi1iaXQgaW50ZWdlciBpbiB0aGlzIGJ1ZmZlciBpbiBsaXR0bGUtZW5kaWFuIG9yZGVyLgogKgogKiBAcGFyYW0gaSB0aGUgMzItYml0IGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnB1dEludDMyTGUgPSBmdW5jdGlvbihpKSB7CiAgcmV0dXJuIHRoaXMucHV0Qnl0ZXMoCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgJiAweEZGKSArCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgPj4gOCAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiAxNiAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiAyNCAmIDB4RkYpKTsKfTsKCi8qKgogKiBQdXRzIGFuIG4tYml0IGludGVnZXIgaW4gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlci4KICoKICogQHBhcmFtIGkgdGhlIG4tYml0IGludGVnZXIuCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUucHV0SW50ID0gZnVuY3Rpb24oaSwgbikgewogIHZhciBieXRlcyA9ICcnOwogIGRvIHsKICAgIG4gLT0gODsKICAgIGJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGkgPj4gbikgJiAweEZGKTsKICB9IHdoaWxlKG4gPiAwKTsKICByZXR1cm4gdGhpcy5wdXRCeXRlcyhieXRlcyk7Cn07CgovKioKICogUHV0cyBhIHNpZ25lZCBuLWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIuIFR3bydzCiAqIGNvbXBsZW1lbnQgcmVwcmVzZW50YXRpb24gaXMgdXNlZC4KICoKICogQHBhcmFtIGkgdGhlIG4tYml0IGludGVnZXIuCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUucHV0U2lnbmVkSW50ID0gZnVuY3Rpb24oaSwgbikgewogIGlmKGkgPCAwKSB7CiAgICBpICs9IDIgPDwgKG4gLSAxKTsKICB9CiAgcmV0dXJuIHRoaXMucHV0SW50KGksIG4pOwp9OwoKLyoqCiAqIFB1dHMgdGhlIGdpdmVuIGJ1ZmZlciBpbnRvIHRoaXMgYnVmZmVyLgogKgogKiBAcGFyYW0gYnVmZmVyIHRoZSBidWZmZXIgdG8gcHV0IGludG8gdGhpcyBvbmUuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnB1dEJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikgewogIHJldHVybiB0aGlzLnB1dEJ5dGVzKGJ1ZmZlci5nZXRCeXRlcygpKTsKfTsKCi8qKgogKiBHZXRzIGEgYnl0ZSBmcm9tIHRoaXMgYnVmZmVyIGFuZCBhZHZhbmNlcyB0aGUgcmVhZCBwb2ludGVyIGJ5IDEuCiAqCiAqIEByZXR1cm4gdGhlIGJ5dGUuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmdldEJ5dGUgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkKyspOwp9OwoKLyoqCiAqIEdldHMgYSB1aW50MTYgZnJvbSB0aGlzIGJ1ZmZlciBpbiBiaWctZW5kaWFuIG9yZGVyIGFuZCBhZHZhbmNlcyB0aGUgcmVhZAogKiBwb2ludGVyIGJ5IDIuCiAqCiAqIEByZXR1cm4gdGhlIHVpbnQxNi4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUuZ2V0SW50MTYgPSBmdW5jdGlvbigpIHsKICB2YXIgcnZhbCA9ICgKICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCkgPDwgOCBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAxKSk7CiAgdGhpcy5yZWFkICs9IDI7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHVpbnQyNCBmcm9tIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgMy4KICoKICogQHJldHVybiB0aGUgdWludDI0LgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQyNCA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gKAogICAgdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkKSA8PCAxNiBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAxKSA8PCA4IF4KICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCArIDIpKTsKICB0aGlzLnJlYWQgKz0gMzsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGEgdWludDMyIGZyb20gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlciBhbmQgYWR2YW5jZXMgdGhlIHJlYWQKICogcG9pbnRlciBieSA0LgogKgogKiBAcmV0dXJuIHRoZSB3b3JkLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQzMiA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gKAogICAgdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkKSA8PCAyNCBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAxKSA8PCAxNiBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAyKSA8PCA4IF4KICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCArIDMpKTsKICB0aGlzLnJlYWQgKz0gNDsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGEgdWludDE2IGZyb20gdGhpcyBidWZmZXIgaW4gbGl0dGxlLWVuZGlhbiBvcmRlciBhbmQgYWR2YW5jZXMgdGhlIHJlYWQKICogcG9pbnRlciBieSAyLgogKgogKiBAcmV0dXJuIHRoZSB1aW50MTYuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmdldEludDE2TGUgPSBmdW5jdGlvbigpIHsKICB2YXIgcnZhbCA9ICgKICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCkgXgogICAgdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkICsgMSkgPDwgOCk7CiAgdGhpcy5yZWFkICs9IDI7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHVpbnQyNCBmcm9tIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgMy4KICoKICogQHJldHVybiB0aGUgdWludDI0LgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQyNExlID0gZnVuY3Rpb24oKSB7CiAgdmFyIHJ2YWwgPSAoCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQpIF4KICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCArIDEpIDw8IDggXgogICAgdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkICsgMikgPDwgMTYpOwogIHRoaXMucmVhZCArPSAzOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIEdldHMgYSB1aW50MzIgZnJvbSB0aGlzIGJ1ZmZlciBpbiBsaXR0bGUtZW5kaWFuIG9yZGVyIGFuZCBhZHZhbmNlcyB0aGUgcmVhZAogKiBwb2ludGVyIGJ5IDQuCiAqCiAqIEByZXR1cm4gdGhlIHdvcmQuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmdldEludDMyTGUgPSBmdW5jdGlvbigpIHsKICB2YXIgcnZhbCA9ICgKICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCkgXgogICAgdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkICsgMSkgPDwgOCBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAyKSA8PCAxNiBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAzKSA8PCAyNCk7CiAgdGhpcy5yZWFkICs9IDQ7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhbiBuLWJpdCBpbnRlZ2VyIGZyb20gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlciBhbmQgYWR2YW5jZXMgdGhlCiAqIHJlYWQgcG9pbnRlciBieSBuLzguCiAqCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICoKICogQHJldHVybiB0aGUgaW50ZWdlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUuZ2V0SW50ID0gZnVuY3Rpb24obikgewogIHZhciBydmFsID0gMDsKICBkbyB7CiAgICBydmFsID0gKHJ2YWwgPDwgOCkgKyB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQrKyk7CiAgICBuIC09IDg7CiAgfSB3aGlsZShuID4gMCk7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHNpZ25lZCBuLWJpdCBpbnRlZ2VyIGZyb20gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlciwgdXNpbmcKICogdHdvJ3MgY29tcGxlbWVudCwgYW5kIGFkdmFuY2VzIHRoZSByZWFkIHBvaW50ZXIgYnkgbi84LgogKgogKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJpdHMgaW4gdGhlIGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhlIGludGVnZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmdldFNpZ25lZEludCA9IGZ1bmN0aW9uKG4pIHsKICB2YXIgeCA9IHRoaXMuZ2V0SW50KG4pOwogIHZhciBtYXggPSAyIDw8IChuIC0gMik7CiAgaWYoeCA+PSBtYXgpIHsKICAgIHggLT0gbWF4IDw8IDE7CiAgfQogIHJldHVybiB4Owp9OwoKLyoqCiAqIFJlYWRzIGJ5dGVzIG91dCBpbnRvIGEgVVRGLTggc3RyaW5nIGFuZCBjbGVhcnMgdGhlbSBmcm9tIHRoZSBidWZmZXIuCiAqCiAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWQsIHVuZGVmaW5lZCBvciBudWxsIGZvciBhbGwuCiAqCiAqIEByZXR1cm4gYSBVVEYtOCBzdHJpbmcgb2YgYnl0ZXMuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmdldEJ5dGVzID0gZnVuY3Rpb24oY291bnQpIHsKICB2YXIgcnZhbDsKICBpZihjb3VudCkgewogICAgLy8gcmVhZCBjb3VudCBieXRlcwogICAgY291bnQgPSBNYXRoLm1pbih0aGlzLmxlbmd0aCgpLCBjb3VudCk7CiAgICBydmFsID0gdGhpcy5kYXRhLnNsaWNlKHRoaXMucmVhZCwgdGhpcy5yZWFkICsgY291bnQpOwogICAgdGhpcy5yZWFkICs9IGNvdW50OwogIH0gZWxzZSBpZihjb3VudCA9PT0gMCkgewogICAgcnZhbCA9ICcnOwogIH0gZWxzZSB7CiAgICAvLyByZWFkIGFsbCBieXRlcywgb3B0aW1pemUgdG8gb25seSBjb3B5IHdoZW4gbmVlZGVkCiAgICBydmFsID0gKHRoaXMucmVhZCA9PT0gMCkgPyB0aGlzLmRhdGEgOiB0aGlzLmRhdGEuc2xpY2UodGhpcy5yZWFkKTsKICAgIHRoaXMuY2xlYXIoKTsKICB9CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIFVURi04IGVuY29kZWQgc3RyaW5nIG9mIHRoZSBieXRlcyBmcm9tIHRoaXMgYnVmZmVyIHdpdGhvdXQgbW9kaWZ5aW5nCiAqIHRoZSByZWFkIHBvaW50ZXIuCiAqCiAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGdldCwgb21pdCB0byBnZXQgYWxsLgogKgogKiBAcmV0dXJuIGEgc3RyaW5nIGZ1bGwgb2YgVVRGLTggZW5jb2RlZCBjaGFyYWN0ZXJzLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5ieXRlcyA9IGZ1bmN0aW9uKGNvdW50KSB7CiAgcmV0dXJuICh0eXBlb2YoY291bnQpID09PSAndW5kZWZpbmVkJyA/CiAgICB0aGlzLmRhdGEuc2xpY2UodGhpcy5yZWFkKSA6CiAgICB0aGlzLmRhdGEuc2xpY2UodGhpcy5yZWFkLCB0aGlzLnJlYWQgKyBjb3VudCkpOwp9OwoKLyoqCiAqIEdldHMgYSBieXRlIGF0IHRoZSBnaXZlbiBpbmRleCB3aXRob3V0IG1vZGlmeWluZyB0aGUgcmVhZCBwb2ludGVyLgogKgogKiBAcGFyYW0gaSB0aGUgYnl0ZSBpbmRleC4KICoKICogQHJldHVybiB0aGUgYnl0ZS4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUuYXQgPSBmdW5jdGlvbihpKSB7CiAgcmV0dXJuIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCArIGkpOwp9OwoKLyoqCiAqIFB1dHMgYSBieXRlIGF0IHRoZSBnaXZlbiBpbmRleCB3aXRob3V0IG1vZGlmeWluZyB0aGUgcmVhZCBwb2ludGVyLgogKgogKiBAcGFyYW0gaSB0aGUgYnl0ZSBpbmRleC4KICogQHBhcmFtIGIgdGhlIGJ5dGUgdG8gcHV0LgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5zZXRBdCA9IGZ1bmN0aW9uKGksIGIpIHsKICB0aGlzLmRhdGEgPSB0aGlzLmRhdGEuc3Vic3RyKDAsIHRoaXMucmVhZCArIGkpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoYikgKwogICAgdGhpcy5kYXRhLnN1YnN0cih0aGlzLnJlYWQgKyBpICsgMSk7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogR2V0cyB0aGUgbGFzdCBieXRlIHdpdGhvdXQgbW9kaWZ5aW5nIHRoZSByZWFkIHBvaW50ZXIuCiAqCiAqIEByZXR1cm4gdGhlIGxhc3QgYnl0ZS4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUubGFzdCA9IGZ1bmN0aW9uKCkgewogIHJldHVybiB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLmRhdGEubGVuZ3RoIC0gMSk7Cn07CgovKioKICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhlIGNvcHkuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbigpIHsKICB2YXIgYyA9IHV0aWwuY3JlYXRlQnVmZmVyKHRoaXMuZGF0YSk7CiAgYy5yZWFkID0gdGhpcy5yZWFkOwogIHJldHVybiBjOwp9OwoKLyoqCiAqIENvbXBhY3RzIHRoaXMgYnVmZmVyLgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5jb21wYWN0ID0gZnVuY3Rpb24oKSB7CiAgaWYodGhpcy5yZWFkID4gMCkgewogICAgdGhpcy5kYXRhID0gdGhpcy5kYXRhLnNsaWNlKHRoaXMucmVhZCk7CiAgICB0aGlzLnJlYWQgPSAwOwogIH0KICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBDbGVhcnMgdGhpcyBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7CiAgdGhpcy5kYXRhID0gJyc7CiAgdGhpcy5yZWFkID0gMDsKICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBTaG9ydGVucyB0aGlzIGJ1ZmZlciBieSB0cmltaW5nIGJ5dGVzIG9mZiBvZiB0aGUgZW5kIG9mIHRoaXMgYnVmZmVyLgogKgogKiBAcGFyYW0gY291bnQgdGhlIG51bWJlciBvZiBieXRlcyB0byB0cmltIG9mZi4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUudHJ1bmNhdGUgPSBmdW5jdGlvbihjb3VudCkgewogIHZhciBsZW4gPSBNYXRoLm1heCgwLCB0aGlzLmxlbmd0aCgpIC0gY291bnQpOwogIHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5zdWJzdHIodGhpcy5yZWFkLCBsZW4pOwogIHRoaXMucmVhZCA9IDA7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogQ29udmVydHMgdGhpcyBidWZmZXIgdG8gYSBoZXhhZGVjaW1hbCBzdHJpbmcuCiAqCiAqIEByZXR1cm4gYSBoZXhhZGVjaW1hbCBzdHJpbmcuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnRvSGV4ID0gZnVuY3Rpb24oKSB7CiAgdmFyIHJ2YWwgPSAnJzsKICBmb3IodmFyIGkgPSB0aGlzLnJlYWQ7IGkgPCB0aGlzLmRhdGEubGVuZ3RoOyArK2kpIHsKICAgIHZhciBiID0gdGhpcy5kYXRhLmNoYXJDb2RlQXQoaSk7CiAgICBpZihiIDwgMTYpIHsKICAgICAgcnZhbCArPSAnMCc7CiAgICB9CiAgICBydmFsICs9IGIudG9TdHJpbmcoMTYpOwogIH0KICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDb252ZXJ0cyB0aGlzIGJ1ZmZlciB0byBhIFVURi0xNiBzdHJpbmcgKHN0YW5kYXJkIEphdmFTY3JpcHQgc3RyaW5nKS4KICoKICogQHJldHVybiBhIFVURi0xNiBzdHJpbmcuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7CiAgcmV0dXJuIHV0aWwuZGVjb2RlVXRmOCh0aGlzLmJ5dGVzKCkpOwp9OwoKLyoqIEVuZCBCdWZmZXIgdy9CaW5hcnlTdHJpbmcgYmFja2luZyAqLwoKCi8qKiBCdWZmZXIgdy9VSW50OEFycmF5IGJhY2tpbmcgKi8KCi8qKgogKiBGSVhNRTogRXhwZXJpbWVudGFsLiBEbyBub3QgdXNlIHlldC4KICoKICogQ29uc3RydWN0b3IgZm9yIGFuIEFycmF5QnVmZmVyLWJhY2tlZCBieXRlIGJ1ZmZlci4KICoKICogVGhlIGJ1ZmZlciBtYXkgYmUgY29uc3RydWN0ZWQgZnJvbSBhIHN0cmluZywgYW4gQXJyYXlCdWZmZXIsIERhdGFWaWV3LCBvciBhCiAqIFR5cGVkQXJyYXkuCiAqCiAqIElmIGEgc3RyaW5nIGlzIGdpdmVuLCBpdHMgZW5jb2Rpbmcgc2hvdWxkIGJlIHByb3ZpZGVkIGFzIGFuIG9wdGlvbiwKICogb3RoZXJ3aXNlIGl0IHdpbGwgZGVmYXVsdCB0byAnYmluYXJ5Jy4gQSAnYmluYXJ5JyBzdHJpbmcgaXMgZW5jb2RlZCBzdWNoCiAqIHRoYXQgZWFjaCBjaGFyYWN0ZXIgaXMgb25lIGJ5dGUgaW4gbGVuZ3RoIGFuZCBzaXplLgogKgogKiBJZiBhbiBBcnJheUJ1ZmZlciwgRGF0YVZpZXcsIG9yIFR5cGVkQXJyYXkgaXMgZ2l2ZW4sIGl0IHdpbGwgYmUgdXNlZAogKiAqZGlyZWN0bHkqIHdpdGhvdXQgYW55IGNvcHlpbmcuIE5vdGUgdGhhdCwgaWYgYSB3cml0ZSB0byB0aGUgYnVmZmVyIHJlcXVpcmVzCiAqIG1vcmUgc3BhY2UsIHRoZSBidWZmZXIgd2lsbCBhbGxvY2F0ZSBhIG5ldyBiYWNraW5nIEFycmF5QnVmZmVyIHRvCiAqIGFjY29tbW9kYXRlLiBUaGUgc3RhcnRpbmcgcmVhZCBhbmQgd3JpdGUgb2Zmc2V0cyBmb3IgdGhlIGJ1ZmZlciBtYXkgYmUKICogZ2l2ZW4gYXMgb3B0aW9ucy4KICoKICogQHBhcmFtIFtiXSB0aGUgaW5pdGlhbCBieXRlcyBmb3IgdGhpcyBidWZmZXIuCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgW3JlYWRPZmZzZXRdIHRoZSBzdGFydGluZyByZWFkIG9mZnNldCB0byB1c2UgKGRlZmF1bHQ6IDApLgogKiAgICAgICAgICBbd3JpdGVPZmZzZXRdIHRoZSBzdGFydGluZyB3cml0ZSBvZmZzZXQgdG8gdXNlIChkZWZhdWx0OiB0aGUKICogICAgICAgICAgICBsZW5ndGggb2YgdGhlIGZpcnN0IHBhcmFtZXRlcikuCiAqICAgICAgICAgIFtncm93U2l6ZV0gdGhlIG1pbmltdW0gYW1vdW50LCBpbiBieXRlcywgdG8gZ3JvdyB0aGUgYnVmZmVyIGJ5IHRvCiAqICAgICAgICAgICAgYWNjb21tb2RhdGUgd3JpdGVzIChkZWZhdWx0OiAxMDI0KS4KICogICAgICAgICAgW2VuY29kaW5nXSB0aGUgZW5jb2RpbmcgKCdiaW5hcnknLCAndXRmOCcsICd1dGYxNicsICdoZXgnKSBmb3IgdGhlCiAqICAgICAgICAgICAgZmlyc3QgcGFyYW1ldGVyLCBpZiBpdCBpcyBhIHN0cmluZyAoZGVmYXVsdDogJ2JpbmFyeScpLgogKi8KZnVuY3Rpb24gRGF0YUJ1ZmZlcihiLCBvcHRpb25zKSB7CiAgLy8gZGVmYXVsdCBvcHRpb25zCiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CgogIC8vIHBvaW50ZXJzIGZvciByZWFkIGZyb20vd3JpdGUgdG8gYnVmZmVyCiAgdGhpcy5yZWFkID0gb3B0aW9ucy5yZWFkT2Zmc2V0IHx8IDA7CiAgdGhpcy5ncm93U2l6ZSA9IG9wdGlvbnMuZ3Jvd1NpemUgfHwgMTAyNDsKCiAgdmFyIGlzQXJyYXlCdWZmZXIgPSB1dGlsLmlzQXJyYXlCdWZmZXIoYik7CiAgdmFyIGlzQXJyYXlCdWZmZXJWaWV3ID0gdXRpbC5pc0FycmF5QnVmZmVyVmlldyhiKTsKICBpZihpc0FycmF5QnVmZmVyIHx8IGlzQXJyYXlCdWZmZXJWaWV3KSB7CiAgICAvLyB1c2UgQXJyYXlCdWZmZXIgZGlyZWN0bHkKICAgIGlmKGlzQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5kYXRhID0gbmV3IERhdGFWaWV3KGIpOwogICAgfSBlbHNlIHsKICAgICAgLy8gVE9ETzogYWRqdXN0IHJlYWQvd3JpdGUgb2Zmc2V0IGJhc2VkIG9uIHRoZSB0eXBlIG9mIHZpZXcKICAgICAgLy8gb3Igc3BlY2lmeSB0aGF0IHRoaXMgbXVzdCBiZSBkb25lIGluIHRoZSBvcHRpb25zIC4uLiB0aGF0IHRoZQogICAgICAvLyBvZmZzZXRzIGFyZSBieXRlLWJhc2VkCiAgICAgIHRoaXMuZGF0YSA9IG5ldyBEYXRhVmlldyhiLmJ1ZmZlciwgYi5ieXRlT2Zmc2V0LCBiLmJ5dGVMZW5ndGgpOwogICAgfQogICAgdGhpcy53cml0ZSA9ICgnd3JpdGVPZmZzZXQnIGluIG9wdGlvbnMgPwogICAgICBvcHRpb25zLndyaXRlT2Zmc2V0IDogdGhpcy5kYXRhLmJ5dGVMZW5ndGgpOwogICAgcmV0dXJuOwogIH0KCiAgLy8gaW5pdGlhbGl6ZSB0byBlbXB0eSBhcnJheSBidWZmZXIgYW5kIGFkZCBhbnkgZ2l2ZW4gYnl0ZXMgdXNpbmcgcHV0Qnl0ZXMKICB0aGlzLmRhdGEgPSBuZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDApKTsKICB0aGlzLndyaXRlID0gMDsKCiAgaWYoYiAhPT0gbnVsbCAmJiBiICE9PSB1bmRlZmluZWQpIHsKICAgIHRoaXMucHV0Qnl0ZXMoYik7CiAgfQoKICBpZignd3JpdGVPZmZzZXQnIGluIG9wdGlvbnMpIHsKICAgIHRoaXMud3JpdGUgPSBvcHRpb25zLndyaXRlT2Zmc2V0OwogIH0KfQp1dGlsLkRhdGFCdWZmZXIgPSBEYXRhQnVmZmVyOwoKLyoqCiAqIEdldHMgdGhlIG51bWJlciBvZiBieXRlcyBpbiB0aGlzIGJ1ZmZlci4KICoKICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGluIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbigpIHsKICByZXR1cm4gdGhpcy53cml0ZSAtIHRoaXMucmVhZDsKfTsKCi8qKgogKiBHZXRzIHdoZXRoZXIgb3Igbm90IHRoaXMgYnVmZmVyIGlzIGVtcHR5LgogKgogKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBidWZmZXIgaXMgZW1wdHksIGZhbHNlIGlmIG5vdC4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uKCkgewogIHJldHVybiB0aGlzLmxlbmd0aCgpIDw9IDA7Cn07CgovKioKICogRW5zdXJlcyB0aGlzIGJ1ZmZlciBoYXMgZW5vdWdoIGVtcHR5IHNwYWNlIHRvIGFjY29tbW9kYXRlIHRoZSBnaXZlbiBudW1iZXIKICogb2YgYnl0ZXMuIEFuIG9wdGlvbmFsIHBhcmFtZXRlciBtYXkgYmUgZ2l2ZW4gdGhhdCBpbmRpY2F0ZXMgYSBtaW5pbXVtCiAqIGFtb3VudCB0byBncm93IHRoZSBidWZmZXIgaWYgbmVjZXNzYXJ5LiBJZiB0aGUgcGFyYW1ldGVyIGlzIG5vdCBnaXZlbiwKICogdGhlIGJ1ZmZlciB3aWxsIGJlIGdyb3duIGJ5IHNvbWUgcHJldmlvdXNseS1zcGVjaWZpZWQgZGVmYXVsdCBhbW91bnQKICogb3IgaGV1cmlzdGljLgogKgogKiBAcGFyYW0gYW1vdW50IHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gYWNjb21tb2RhdGUuCiAqIEBwYXJhbSBbZ3Jvd1NpemVdIHRoZSBtaW5pbXVtIGFtb3VudCwgaW4gYnl0ZXMsIHRvIGdyb3cgdGhlIGJ1ZmZlciBieSBpZgogKiAgICAgICAgICBuZWNlc3NhcnkuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLmFjY29tbW9kYXRlID0gZnVuY3Rpb24oYW1vdW50LCBncm93U2l6ZSkgewogIGlmKHRoaXMubGVuZ3RoKCkgPj0gYW1vdW50KSB7CiAgICByZXR1cm4gdGhpczsKICB9CiAgZ3Jvd1NpemUgPSBNYXRoLm1heChncm93U2l6ZSB8fCB0aGlzLmdyb3dTaXplLCBhbW91bnQpOwoKICAvLyBncm93IGJ1ZmZlcgogIHZhciBzcmMgPSBuZXcgVWludDhBcnJheSgKICAgIHRoaXMuZGF0YS5idWZmZXIsIHRoaXMuZGF0YS5ieXRlT2Zmc2V0LCB0aGlzLmRhdGEuYnl0ZUxlbmd0aCk7CiAgdmFyIGRzdCA9IG5ldyBVaW50OEFycmF5KHRoaXMubGVuZ3RoKCkgKyBncm93U2l6ZSk7CiAgZHN0LnNldChzcmMpOwogIHRoaXMuZGF0YSA9IG5ldyBEYXRhVmlldyhkc3QuYnVmZmVyKTsKCiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhIGJ5dGUgaW4gdGhpcyBidWZmZXIuCiAqCiAqIEBwYXJhbSBiIHRoZSBieXRlIHRvIHB1dC4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0Qnl0ZSA9IGZ1bmN0aW9uKGIpIHsKICB0aGlzLmFjY29tbW9kYXRlKDEpOwogIHRoaXMuZGF0YS5zZXRVaW50OCh0aGlzLndyaXRlKyssIGIpOwogIHJldHVybiB0aGlzOwp9OwoKLyoqCiAqIFB1dHMgYSBieXRlIGluIHRoaXMgYnVmZmVyIE4gdGltZXMuCiAqCiAqIEBwYXJhbSBiIHRoZSBieXRlIHRvIHB1dC4KICogQHBhcmFtIG4gdGhlIG51bWJlciBvZiBieXRlcyBvZiB2YWx1ZSBiIHRvIHB1dC4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZmlsbFdpdGhCeXRlID0gZnVuY3Rpb24oYiwgbikgewogIHRoaXMuYWNjb21tb2RhdGUobik7CiAgZm9yKHZhciBpID0gMDsgaSA8IG47ICsraSkgewogICAgdGhpcy5kYXRhLnNldFVpbnQ4KGIpOwogIH0KICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBQdXRzIGJ5dGVzIGluIHRoaXMgYnVmZmVyLiBUaGUgYnl0ZXMgbWF5IGJlIGdpdmVuIGFzIGEgc3RyaW5nLCBhbgogKiBBcnJheUJ1ZmZlciwgYSBEYXRhVmlldywgb3IgYSBUeXBlZEFycmF5LgogKgogKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGVzIHRvIHB1dC4KICogQHBhcmFtIFtlbmNvZGluZ10gdGhlIGVuY29kaW5nIGZvciB0aGUgZmlyc3QgcGFyYW1ldGVyICgnYmluYXJ5JywgJ3V0ZjgnLAogKiAgICAgICAgICAndXRmMTYnLCAnaGV4JyksIGlmIGl0IGlzIGEgc3RyaW5nIChkZWZhdWx0OiAnYmluYXJ5JykuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnB1dEJ5dGVzID0gZnVuY3Rpb24oYnl0ZXMsIGVuY29kaW5nKSB7CiAgaWYodXRpbC5pc0FycmF5QnVmZmVyVmlldyhieXRlcykpIHsKICAgIHZhciBzcmMgPSBuZXcgVWludDhBcnJheShieXRlcy5idWZmZXIsIGJ5dGVzLmJ5dGVPZmZzZXQsIGJ5dGVzLmJ5dGVMZW5ndGgpOwogICAgdmFyIGxlbiA9IHNyYy5ieXRlTGVuZ3RoIC0gc3JjLmJ5dGVPZmZzZXQ7CiAgICB0aGlzLmFjY29tbW9kYXRlKGxlbik7CiAgICB2YXIgZHN0ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5kYXRhLmJ1ZmZlciwgdGhpcy53cml0ZSk7CiAgICBkc3Quc2V0KHNyYyk7CiAgICB0aGlzLndyaXRlICs9IGxlbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgaWYodXRpbC5pc0FycmF5QnVmZmVyKGJ5dGVzKSkgewogICAgdmFyIHNyYyA9IG5ldyBVaW50OEFycmF5KGJ5dGVzKTsKICAgIHRoaXMuYWNjb21tb2RhdGUoc3JjLmJ5dGVMZW5ndGgpOwogICAgdmFyIGRzdCA9IG5ldyBVaW50OEFycmF5KHRoaXMuZGF0YS5idWZmZXIpOwogICAgZHN0LnNldChzcmMsIHRoaXMud3JpdGUpOwogICAgdGhpcy53cml0ZSArPSBzcmMuYnl0ZUxlbmd0aDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLy8gYnl0ZXMgaXMgYSB1dGlsLkRhdGFCdWZmZXIgb3IgZXF1aXZhbGVudAogIGlmKGJ5dGVzIGluc3RhbmNlb2YgdXRpbC5EYXRhQnVmZmVyIHx8CiAgICAodHlwZW9mIGJ5dGVzID09PSAnb2JqZWN0JyAmJgogICAgdHlwZW9mIGJ5dGVzLnJlYWQgPT09ICdudW1iZXInICYmIHR5cGVvZiBieXRlcy53cml0ZSA9PT0gJ251bWJlcicgJiYKICAgIHV0aWwuaXNBcnJheUJ1ZmZlclZpZXcoYnl0ZXMuZGF0YSkpKSB7CiAgICB2YXIgc3JjID0gbmV3IFVpbnQ4QXJyYXkoYnl0ZXMuZGF0YS5ieXRlTGVuZ3RoLCBieXRlcy5yZWFkLCBieXRlcy5sZW5ndGgoKSk7CiAgICB0aGlzLmFjY29tbW9kYXRlKHNyYy5ieXRlTGVuZ3RoKTsKICAgIHZhciBkc3QgPSBuZXcgVWludDhBcnJheShieXRlcy5kYXRhLmJ5dGVMZW5ndGgsIHRoaXMud3JpdGUpOwogICAgZHN0LnNldChzcmMpOwogICAgdGhpcy53cml0ZSArPSBzcmMuYnl0ZUxlbmd0aDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgaWYoYnl0ZXMgaW5zdGFuY2VvZiB1dGlsLkJ5dGVTdHJpbmdCdWZmZXIpIHsKICAgIC8vIGNvcHkgYmluYXJ5IHN0cmluZyBhbmQgcHJvY2VzcyBhcyB0aGUgc2FtZSBhcyBhIHN0cmluZyBwYXJhbWV0ZXIgYmVsb3cKICAgIGJ5dGVzID0gYnl0ZXMuZGF0YTsKICAgIGVuY29kaW5nID0gJ2JpbmFyeSc7CiAgfQoKICAvLyBzdHJpbmcgY29udmVyc2lvbgogIGVuY29kaW5nID0gZW5jb2RpbmcgfHwgJ2JpbmFyeSc7CiAgaWYodHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJykgewogICAgdmFyIHZpZXc7CgogICAgLy8gZGVjb2RlIGZyb20gc3RyaW5nCiAgICBpZihlbmNvZGluZyA9PT0gJ2hleCcpIHsKICAgICAgdGhpcy5hY2NvbW1vZGF0ZShNYXRoLmNlaWwoYnl0ZXMubGVuZ3RoIC8gMikpOwogICAgICB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5kYXRhLmJ1ZmZlciwgdGhpcy53cml0ZSk7CiAgICAgIHRoaXMud3JpdGUgKz0gdXRpbC5iaW5hcnkuaGV4LmRlY29kZShieXRlcywgdmlldywgdGhpcy53cml0ZSk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgaWYoZW5jb2RpbmcgPT09ICdiYXNlNjQnKSB7CiAgICAgIHRoaXMuYWNjb21tb2RhdGUoTWF0aC5jZWlsKGJ5dGVzLmxlbmd0aCAvIDQpICogMyk7CiAgICAgIHZpZXcgPSBuZXcgVWludDhBcnJheSh0aGlzLmRhdGEuYnVmZmVyLCB0aGlzLndyaXRlKTsKICAgICAgdGhpcy53cml0ZSArPSB1dGlsLmJpbmFyeS5iYXNlNjQuZGVjb2RlKGJ5dGVzLCB2aWV3LCB0aGlzLndyaXRlKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgLy8gZW5jb2RlIHRleHQgYXMgVVRGLTggYnl0ZXMKICAgIGlmKGVuY29kaW5nID09PSAndXRmOCcpIHsKICAgICAgLy8gZW5jb2RlIGFzIFVURi04IHRoZW4gZGVjb2RlIHN0cmluZyBhcyByYXcgYmluYXJ5CiAgICAgIGJ5dGVzID0gdXRpbC5lbmNvZGVVdGY4KGJ5dGVzKTsKICAgICAgZW5jb2RpbmcgPSAnYmluYXJ5JzsKICAgIH0KCiAgICAvLyBkZWNvZGUgc3RyaW5nIGFzIHJhdyBiaW5hcnkKICAgIGlmKGVuY29kaW5nID09PSAnYmluYXJ5JyB8fCBlbmNvZGluZyA9PT0gJ3JhdycpIHsKICAgICAgLy8gb25lIGJ5dGUgcGVyIGNoYXJhY3RlcgogICAgICB0aGlzLmFjY29tbW9kYXRlKGJ5dGVzLmxlbmd0aCk7CiAgICAgIHZpZXcgPSBuZXcgVWludDhBcnJheSh0aGlzLmRhdGEuYnVmZmVyLCB0aGlzLndyaXRlKTsKICAgICAgdGhpcy53cml0ZSArPSB1dGlsLmJpbmFyeS5yYXcuZGVjb2RlKHZpZXcpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICAvLyBlbmNvZGUgdGV4dCBhcyBVVEYtMTYgYnl0ZXMKICAgIGlmKGVuY29kaW5nID09PSAndXRmMTYnKSB7CiAgICAgIC8vIHR3byBieXRlcyBwZXIgY2hhcmFjdGVyCiAgICAgIHRoaXMuYWNjb21tb2RhdGUoYnl0ZXMubGVuZ3RoICogMik7CiAgICAgIHZpZXcgPSBuZXcgVWludDE2QXJyYXkodGhpcy5kYXRhLmJ1ZmZlciwgdGhpcy53cml0ZSk7CiAgICAgIHRoaXMud3JpdGUgKz0gdXRpbC50ZXh0LnV0ZjE2LmVuY29kZSh2aWV3KTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpOwogIH0KCiAgdGhyb3cgRXJyb3IoJ0ludmFsaWQgcGFyYW1ldGVyOiAnICsgYnl0ZXMpOwp9OwoKLyoqCiAqIFB1dHMgdGhlIGdpdmVuIGJ1ZmZlciBpbnRvIHRoaXMgYnVmZmVyLgogKgogKiBAcGFyYW0gYnVmZmVyIHRoZSBidWZmZXIgdG8gcHV0IGludG8gdGhpcyBvbmUuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnB1dEJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikgewogIHRoaXMucHV0Qnl0ZXMoYnVmZmVyKTsKICBidWZmZXIuY2xlYXIoKTsKICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBQdXRzIGEgc3RyaW5nIGludG8gdGhpcyBidWZmZXIuCiAqCiAqIEBwYXJhbSBzdHIgdGhlIHN0cmluZyB0byBwdXQuCiAqIEBwYXJhbSBbZW5jb2RpbmddIHRoZSBlbmNvZGluZyBmb3IgdGhlIHN0cmluZyAoZGVmYXVsdDogJ3V0ZjE2JykuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnB1dFN0cmluZyA9IGZ1bmN0aW9uKHN0cikgewogIHJldHVybiB0aGlzLnB1dEJ5dGVzKHN0ciwgJ3V0ZjE2Jyk7Cn07CgovKioKICogUHV0cyBhIDE2LWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAxNi1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0SW50MTYgPSBmdW5jdGlvbihpKSB7CiAgdGhpcy5hY2NvbW1vZGF0ZSgyKTsKICB0aGlzLmRhdGEuc2V0SW50MTYodGhpcy53cml0ZSwgaSk7CiAgdGhpcy53cml0ZSArPSAyOwogIHJldHVybiB0aGlzOwp9OwoKLyoqCiAqIFB1dHMgYSAyNC1iaXQgaW50ZWdlciBpbiB0aGlzIGJ1ZmZlciBpbiBiaWctZW5kaWFuIG9yZGVyLgogKgogKiBAcGFyYW0gaSB0aGUgMjQtYml0IGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnB1dEludDI0ID0gZnVuY3Rpb24oaSkgewogIHRoaXMuYWNjb21tb2RhdGUoMyk7CiAgdGhpcy5kYXRhLnNldEludDE2KHRoaXMud3JpdGUsIGkgPj4gOCAmIDB4RkZGRik7CiAgdGhpcy5kYXRhLnNldEludDgodGhpcy53cml0ZSwgaSA+PiAxNiAmIDB4RkYpOwogIHRoaXMud3JpdGUgKz0gMzsKICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBQdXRzIGEgMzItYml0IGludGVnZXIgaW4gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlci4KICoKICogQHBhcmFtIGkgdGhlIDMyLWJpdCBpbnRlZ2VyLgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5wdXRJbnQzMiA9IGZ1bmN0aW9uKGkpIHsKICB0aGlzLmFjY29tbW9kYXRlKDQpOwogIHRoaXMuZGF0YS5zZXRJbnQzMih0aGlzLndyaXRlLCBpKTsKICB0aGlzLndyaXRlICs9IDQ7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhIDE2LWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAxNi1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0SW50MTZMZSA9IGZ1bmN0aW9uKGkpIHsKICB0aGlzLmFjY29tbW9kYXRlKDIpOwogIHRoaXMuZGF0YS5zZXRJbnQxNih0aGlzLndyaXRlLCBpLCB0cnVlKTsKICB0aGlzLndyaXRlICs9IDI7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhIDI0LWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAyNC1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0SW50MjRMZSA9IGZ1bmN0aW9uKGkpIHsKICB0aGlzLmFjY29tbW9kYXRlKDMpOwogIHRoaXMuZGF0YS5zZXRJbnQ4KHRoaXMud3JpdGUsIGkgPj4gMTYgJiAweEZGKTsKICB0aGlzLmRhdGEuc2V0SW50MTYodGhpcy53cml0ZSwgaSA+PiA4ICYgMHhGRkZGLCB0cnVlKTsKICB0aGlzLndyaXRlICs9IDM7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhIDMyLWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAzMi1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0SW50MzJMZSA9IGZ1bmN0aW9uKGkpIHsKICB0aGlzLmFjY29tbW9kYXRlKDQpOwogIHRoaXMuZGF0YS5zZXRJbnQzMih0aGlzLndyaXRlLCBpLCB0cnVlKTsKICB0aGlzLndyaXRlICs9IDQ7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhbiBuLWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSBuLWJpdCBpbnRlZ2VyLgogKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJpdHMgaW4gdGhlIGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnB1dEludCA9IGZ1bmN0aW9uKGksIG4pIHsKICB0aGlzLmFjY29tbW9kYXRlKG4gLyA4KTsKICBkbyB7CiAgICBuIC09IDg7CiAgICB0aGlzLmRhdGEuc2V0SW50OCh0aGlzLndyaXRlKyssIChpID4+IG4pICYgMHhGRik7CiAgfSB3aGlsZShuID4gMCk7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhIHNpZ25lZCBuLWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIuIFR3bydzCiAqIGNvbXBsZW1lbnQgcmVwcmVzZW50YXRpb24gaXMgdXNlZC4KICoKICogQHBhcmFtIGkgdGhlIG4tYml0IGludGVnZXIuCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0U2lnbmVkSW50ID0gZnVuY3Rpb24oaSwgbikgewogIHRoaXMuYWNjb21tb2RhdGUobiAvIDgpOwogIGlmKGkgPCAwKSB7CiAgICBpICs9IDIgPDwgKG4gLSAxKTsKICB9CiAgcmV0dXJuIHRoaXMucHV0SW50KGksIG4pOwp9OwoKLyoqCiAqIEdldHMgYSBieXRlIGZyb20gdGhpcyBidWZmZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkIHBvaW50ZXIgYnkgMS4KICoKICogQHJldHVybiB0aGUgYnl0ZS4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZ2V0Qnl0ZSA9IGZ1bmN0aW9uKCkgewogIHJldHVybiB0aGlzLmRhdGEuZ2V0SW50OCh0aGlzLnJlYWQrKyk7Cn07CgovKioKICogR2V0cyBhIHVpbnQxNiBmcm9tIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgMi4KICoKICogQHJldHVybiB0aGUgdWludDE2LgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQxNiA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gdGhpcy5kYXRhLmdldEludDE2KHRoaXMucmVhZCk7CiAgdGhpcy5yZWFkICs9IDI7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHVpbnQyNCBmcm9tIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgMy4KICoKICogQHJldHVybiB0aGUgdWludDI0LgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQyNCA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gKAogICAgdGhpcy5kYXRhLmdldEludDE2KHRoaXMucmVhZCkgPDwgOCBeCiAgICB0aGlzLmRhdGEuZ2V0SW50OCh0aGlzLnJlYWQgKyAyKSk7CiAgdGhpcy5yZWFkICs9IDM7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHVpbnQzMiBmcm9tIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgNC4KICoKICogQHJldHVybiB0aGUgd29yZC4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZ2V0SW50MzIgPSBmdW5jdGlvbigpIHsKICB2YXIgcnZhbCA9IHRoaXMuZGF0YS5nZXRJbnQzMih0aGlzLnJlYWQpOwogIHRoaXMucmVhZCArPSA0OwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIEdldHMgYSB1aW50MTYgZnJvbSB0aGlzIGJ1ZmZlciBpbiBsaXR0bGUtZW5kaWFuIG9yZGVyIGFuZCBhZHZhbmNlcyB0aGUgcmVhZAogKiBwb2ludGVyIGJ5IDIuCiAqCiAqIEByZXR1cm4gdGhlIHVpbnQxNi4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZ2V0SW50MTZMZSA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gdGhpcy5kYXRhLmdldEludDE2KHRoaXMucmVhZCwgdHJ1ZSk7CiAgdGhpcy5yZWFkICs9IDI7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHVpbnQyNCBmcm9tIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgMy4KICoKICogQHJldHVybiB0aGUgdWludDI0LgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQyNExlID0gZnVuY3Rpb24oKSB7CiAgdmFyIHJ2YWwgPSAoCiAgICB0aGlzLmRhdGEuZ2V0SW50OCh0aGlzLnJlYWQpIF4KICAgIHRoaXMuZGF0YS5nZXRJbnQxNih0aGlzLnJlYWQgKyAxLCB0cnVlKSA8PCA4KTsKICB0aGlzLnJlYWQgKz0gMzsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGEgdWludDMyIGZyb20gdGhpcyBidWZmZXIgaW4gbGl0dGxlLWVuZGlhbiBvcmRlciBhbmQgYWR2YW5jZXMgdGhlIHJlYWQKICogcG9pbnRlciBieSA0LgogKgogKiBAcmV0dXJuIHRoZSB3b3JkLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQzMkxlID0gZnVuY3Rpb24oKSB7CiAgdmFyIHJ2YWwgPSB0aGlzLmRhdGEuZ2V0SW50MzIodGhpcy5yZWFkLCB0cnVlKTsKICB0aGlzLnJlYWQgKz0gNDsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGFuIG4tYml0IGludGVnZXIgZnJvbSB0aGlzIGJ1ZmZlciBpbiBiaWctZW5kaWFuIG9yZGVyIGFuZCBhZHZhbmNlcyB0aGUKICogcmVhZCBwb2ludGVyIGJ5IG4vOC4KICoKICogQHBhcmFtIG4gdGhlIG51bWJlciBvZiBiaXRzIGluIHRoZSBpbnRlZ2VyLgogKgogKiBAcmV0dXJuIHRoZSBpbnRlZ2VyLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQgPSBmdW5jdGlvbihuKSB7CiAgdmFyIHJ2YWwgPSAwOwogIGRvIHsKICAgIHJ2YWwgPSAocnZhbCA8PCA4KSArIHRoaXMuZGF0YS5nZXRJbnQ4KHRoaXMucmVhZCsrKTsKICAgIG4gLT0gODsKICB9IHdoaWxlKG4gPiAwKTsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGEgc2lnbmVkIG4tYml0IGludGVnZXIgZnJvbSB0aGlzIGJ1ZmZlciBpbiBiaWctZW5kaWFuIG9yZGVyLCB1c2luZwogKiB0d28ncyBjb21wbGVtZW50LCBhbmQgYWR2YW5jZXMgdGhlIHJlYWQgcG9pbnRlciBieSBuLzguCiAqCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICoKICogQHJldHVybiB0aGUgaW50ZWdlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZ2V0U2lnbmVkSW50ID0gZnVuY3Rpb24obikgewogIHZhciB4ID0gdGhpcy5nZXRJbnQobik7CiAgdmFyIG1heCA9IDIgPDwgKG4gLSAyKTsKICBpZih4ID49IG1heCkgewogICAgeCAtPSBtYXggPDwgMTsKICB9CiAgcmV0dXJuIHg7Cn07CgovKioKICogUmVhZHMgYnl0ZXMgb3V0IGludG8gYSBVVEYtOCBzdHJpbmcgYW5kIGNsZWFycyB0aGVtIGZyb20gdGhlIGJ1ZmZlci4KICoKICogQHBhcmFtIGNvdW50IHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZCwgdW5kZWZpbmVkIG9yIG51bGwgZm9yIGFsbC4KICoKICogQHJldHVybiBhIFVURi04IHN0cmluZyBvZiBieXRlcy4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZ2V0Qnl0ZXMgPSBmdW5jdGlvbihjb3VudCkgewogIC8vIFRPRE86IGRlcHJlY2F0ZSB0aGlzIG1ldGhvZCwgaXQgaXMgcG9vcmx5IG5hbWVkIGFuZAogIC8vIHRoaXMudG9TdHJpbmcoJ2JpbmFyeScpIHJlcGxhY2VzIGl0CiAgLy8gYWRkIGEgdG9UeXBlZEFycmF5KCkvdG9BcnJheUJ1ZmZlcigpIGZ1bmN0aW9uCiAgdmFyIHJ2YWw7CiAgaWYoY291bnQpIHsKICAgIC8vIHJlYWQgY291bnQgYnl0ZXMKICAgIGNvdW50ID0gTWF0aC5taW4odGhpcy5sZW5ndGgoKSwgY291bnQpOwogICAgcnZhbCA9IHRoaXMuZGF0YS5zbGljZSh0aGlzLnJlYWQsIHRoaXMucmVhZCArIGNvdW50KTsKICAgIHRoaXMucmVhZCArPSBjb3VudDsKICB9IGVsc2UgaWYoY291bnQgPT09IDApIHsKICAgIHJ2YWwgPSAnJzsKICB9IGVsc2UgewogICAgLy8gcmVhZCBhbGwgYnl0ZXMsIG9wdGltaXplIHRvIG9ubHkgY29weSB3aGVuIG5lZWRlZAogICAgcnZhbCA9ICh0aGlzLnJlYWQgPT09IDApID8gdGhpcy5kYXRhIDogdGhpcy5kYXRhLnNsaWNlKHRoaXMucmVhZCk7CiAgICB0aGlzLmNsZWFyKCk7CiAgfQogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIEdldHMgYSBVVEYtOCBlbmNvZGVkIHN0cmluZyBvZiB0aGUgYnl0ZXMgZnJvbSB0aGlzIGJ1ZmZlciB3aXRob3V0IG1vZGlmeWluZwogKiB0aGUgcmVhZCBwb2ludGVyLgogKgogKiBAcGFyYW0gY291bnQgdGhlIG51bWJlciBvZiBieXRlcyB0byBnZXQsIG9taXQgdG8gZ2V0IGFsbC4KICoKICogQHJldHVybiBhIHN0cmluZyBmdWxsIG9mIFVURi04IGVuY29kZWQgY2hhcmFjdGVycy4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuYnl0ZXMgPSBmdW5jdGlvbihjb3VudCkgewogIC8vIFRPRE86IGRlcHJlY2F0ZSB0aGlzIG1ldGhvZCwgaXQgaXMgcG9vcmx5IG5hbWVkLCBhZGQgImdldFN0cmluZygpIgogIHJldHVybiAodHlwZW9mKGNvdW50KSA9PT0gJ3VuZGVmaW5lZCcgPwogICAgdGhpcy5kYXRhLnNsaWNlKHRoaXMucmVhZCkgOgogICAgdGhpcy5kYXRhLnNsaWNlKHRoaXMucmVhZCwgdGhpcy5yZWFkICsgY291bnQpKTsKfTsKCi8qKgogKiBHZXRzIGEgYnl0ZSBhdCB0aGUgZ2l2ZW4gaW5kZXggd2l0aG91dCBtb2RpZnlpbmcgdGhlIHJlYWQgcG9pbnRlci4KICoKICogQHBhcmFtIGkgdGhlIGJ5dGUgaW5kZXguCiAqCiAqIEByZXR1cm4gdGhlIGJ5dGUuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLmF0ID0gZnVuY3Rpb24oaSkgewogIHJldHVybiB0aGlzLmRhdGEuZ2V0VWludDgodGhpcy5yZWFkICsgaSk7Cn07CgovKioKICogUHV0cyBhIGJ5dGUgYXQgdGhlIGdpdmVuIGluZGV4IHdpdGhvdXQgbW9kaWZ5aW5nIHRoZSByZWFkIHBvaW50ZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSBieXRlIGluZGV4LgogKiBAcGFyYW0gYiB0aGUgYnl0ZSB0byBwdXQuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnNldEF0ID0gZnVuY3Rpb24oaSwgYikgewogIHRoaXMuZGF0YS5zZXRVaW50OChpLCBiKTsKICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBHZXRzIHRoZSBsYXN0IGJ5dGUgd2l0aG91dCBtb2RpZnlpbmcgdGhlIHJlYWQgcG9pbnRlci4KICoKICogQHJldHVybiB0aGUgbGFzdCBieXRlLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5sYXN0ID0gZnVuY3Rpb24oKSB7CiAgcmV0dXJuIHRoaXMuZGF0YS5nZXRVaW50OCh0aGlzLndyaXRlIC0gMSk7Cn07CgovKioKICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhlIGNvcHkuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gbmV3IHV0aWwuRGF0YUJ1ZmZlcih0aGlzKTsKfTsKCi8qKgogKiBDb21wYWN0cyB0aGlzIGJ1ZmZlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuY29tcGFjdCA9IGZ1bmN0aW9uKCkgewogIGlmKHRoaXMucmVhZCA+IDApIHsKICAgIHZhciBzcmMgPSBuZXcgVWludDhBcnJheSh0aGlzLmRhdGEuYnVmZmVyLCB0aGlzLnJlYWQpOwogICAgdmFyIGRzdCA9IG5ldyBVaW50OEFycmF5KHNyYy5ieXRlTGVuZ3RoKTsKICAgIGRzdC5zZXQoc3JjKTsKICAgIHRoaXMuZGF0YSA9IG5ldyBEYXRhVmlldyhkc3QpOwogICAgdGhpcy53cml0ZSAtPSB0aGlzLnJlYWQ7CiAgICB0aGlzLnJlYWQgPSAwOwogIH0KICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBDbGVhcnMgdGhpcyBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7CiAgdGhpcy5kYXRhID0gbmV3IERhdGFWaWV3KG5ldyBBcnJheUJ1ZmZlcigwKSk7CiAgdGhpcy5yZWFkID0gdGhpcy53cml0ZSA9IDA7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogU2hvcnRlbnMgdGhpcyBidWZmZXIgYnkgdHJpbWluZyBieXRlcyBvZmYgb2YgdGhlIGVuZCBvZiB0aGlzIGJ1ZmZlci4KICoKICogQHBhcmFtIGNvdW50IHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gdHJpbSBvZmYuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnRydW5jYXRlID0gZnVuY3Rpb24oY291bnQpIHsKICB0aGlzLndyaXRlID0gTWF0aC5tYXgoMCwgdGhpcy5sZW5ndGgoKSAtIGNvdW50KTsKICB0aGlzLnJlYWQgPSBNYXRoLm1pbih0aGlzLnJlYWQsIHRoaXMud3JpdGUpOwogIHJldHVybiB0aGlzOwp9OwoKLyoqCiAqIENvbnZlcnRzIHRoaXMgYnVmZmVyIHRvIGEgaGV4YWRlY2ltYWwgc3RyaW5nLgogKgogKiBAcmV0dXJuIGEgaGV4YWRlY2ltYWwgc3RyaW5nLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS50b0hleCA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gJyc7CiAgZm9yKHZhciBpID0gdGhpcy5yZWFkOyBpIDwgdGhpcy5kYXRhLmJ5dGVMZW5ndGg7ICsraSkgewogICAgdmFyIGIgPSB0aGlzLmRhdGEuZ2V0VWludDgoaSk7CiAgICBpZihiIDwgMTYpIHsKICAgICAgcnZhbCArPSAnMCc7CiAgICB9CiAgICBydmFsICs9IGIudG9TdHJpbmcoMTYpOwogIH0KICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDb252ZXJ0cyB0aGlzIGJ1ZmZlciB0byBhIHN0cmluZywgdXNpbmcgdGhlIGdpdmVuIGVuY29kaW5nLiBJZiBubwogKiBlbmNvZGluZyBpcyBnaXZlbiwgJ3V0ZjgnIChVVEYtOCkgaXMgdXNlZC4KICoKICogQHBhcmFtIFtlbmNvZGluZ10gdGhlIGVuY29kaW5nIHRvIHVzZTogJ2JpbmFyeScsICd1dGY4JywgJ3V0ZjE2JywgJ2hleCcsCiAqICAgICAgICAgICdiYXNlNjQnIChkZWZhdWx0OiAndXRmOCcpLgogKgogKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBieXRlcyBpbiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbihlbmNvZGluZykgewogIHZhciB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5kYXRhLCB0aGlzLnJlYWQsIHRoaXMubGVuZ3RoKCkpOwogIGVuY29kaW5nID0gZW5jb2RpbmcgfHwgJ3V0ZjgnOwoKICAvLyBlbmNvZGUgdG8gc3RyaW5nCiAgaWYoZW5jb2RpbmcgPT09ICdiaW5hcnknIHx8IGVuY29kaW5nID09PSAncmF3JykgewogICAgcmV0dXJuIHV0aWwuYmluYXJ5LnJhdy5lbmNvZGUodmlldyk7CiAgfQogIGlmKGVuY29kaW5nID09PSAnaGV4JykgewogICAgcmV0dXJuIHV0aWwuYmluYXJ5LmhleC5lbmNvZGUodmlldyk7CiAgfQogIGlmKGVuY29kaW5nID09PSAnYmFzZTY0JykgewogICAgcmV0dXJuIHV0aWwuYmluYXJ5LmJhc2U2NC5lbmNvZGUodmlldyk7CiAgfQoKICAvLyBkZWNvZGUgdG8gdGV4dAogIGlmKGVuY29kaW5nID09PSAndXRmOCcpIHsKICAgIHJldHVybiB1dGlsLnRleHQudXRmOC5kZWNvZGUodmlldyk7CiAgfQogIGlmKGVuY29kaW5nID09PSAndXRmMTYnKSB7CiAgICByZXR1cm4gdXRpbC50ZXh0LnV0ZjE2LmRlY29kZSh2aWV3KTsKICB9CgogIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBlbmNvZGluZzogJyArIGVuY29kaW5nKTsKfTsKCi8qKiBFbmQgQnVmZmVyIHcvVUludDhBcnJheSBiYWNraW5nICovCgoKLyoqCiAqIENyZWF0ZXMgYSBidWZmZXIgdGhhdCBzdG9yZXMgYnl0ZXMuIEEgdmFsdWUgbWF5IGJlIGdpdmVuIHRvIHB1dCBpbnRvIHRoZQogKiBidWZmZXIgdGhhdCBpcyBlaXRoZXIgYSBzdHJpbmcgb2YgYnl0ZXMgb3IgYSBVVEYtMTYgc3RyaW5nIHRoYXQgd2lsbAogKiBiZSBlbmNvZGVkIHVzaW5nIFVURi04ICh0byBkbyB0aGUgbGF0dGVyLCBzcGVjaWZ5ICd1dGY4JyBhcyB0aGUgZW5jb2RpbmcpLgogKgogKiBAcGFyYW0gW2lucHV0XSB0aGUgYnl0ZXMgdG8gd3JhcCAoYXMgYSBzdHJpbmcpIG9yIGEgVVRGLTE2IHN0cmluZyB0byBlbmNvZGUKICogICAgICAgICAgYXMgVVRGLTguCiAqIEBwYXJhbSBbZW5jb2RpbmddIChkZWZhdWx0OiAncmF3Jywgb3RoZXI6ICd1dGY4JykuCiAqLwp1dGlsLmNyZWF0ZUJ1ZmZlciA9IGZ1bmN0aW9uKGlucHV0LCBlbmNvZGluZykgewogIC8vIFRPRE86IGRlcHJlY2F0ZSwgdXNlIG5ldyBCeXRlQnVmZmVyKCkgaW5zdGVhZAogIGVuY29kaW5nID0gZW5jb2RpbmcgfHwgJ3Jhdyc7CiAgaWYoaW5wdXQgIT09IHVuZGVmaW5lZCAmJiBlbmNvZGluZyA9PT0gJ3V0ZjgnKSB7CiAgICBpbnB1dCA9IHV0aWwuZW5jb2RlVXRmOChpbnB1dCk7CiAgfQogIHJldHVybiBuZXcgdXRpbC5CeXRlQnVmZmVyKGlucHV0KTsKfTsKCi8qKgogKiBGaWxscyBhIHN0cmluZyB3aXRoIGEgcGFydGljdWxhciB2YWx1ZS4gSWYgeW91IHdhbnQgdGhlIHN0cmluZyB0byBiZSBhIGJ5dGUKICogc3RyaW5nLCBwYXNzIGluIFN0cmluZy5mcm9tQ2hhckNvZGUodGhlQnl0ZSkuCiAqCiAqIEBwYXJhbSBjIHRoZSBjaGFyYWN0ZXIgdG8gZmlsbCB0aGUgc3RyaW5nIHdpdGgsIHVzZSBTdHJpbmcuZnJvbUNoYXJDb2RlCiAqICAgICAgICAgIHRvIGZpbGwgdGhlIHN0cmluZyB3aXRoIGEgYnl0ZSB2YWx1ZS4KICogQHBhcmFtIG4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIG9mIHZhbHVlIGMgdG8gZmlsbCB3aXRoLgogKgogKiBAcmV0dXJuIHRoZSBmaWxsZWQgc3RyaW5nLgogKi8KdXRpbC5maWxsU3RyaW5nID0gZnVuY3Rpb24oYywgbikgewogIHZhciBzID0gJyc7CiAgd2hpbGUobiA+IDApIHsKICAgIGlmKG4gJiAxKSB7CiAgICAgIHMgKz0gYzsKICAgIH0KICAgIG4gPj4+PSAxOwogICAgaWYobiA+IDApIHsKICAgICAgYyArPSBjOwogICAgfQogIH0KICByZXR1cm4gczsKfTsKCi8qKgogKiBQZXJmb3JtcyBhIHBlciBieXRlIFhPUiBiZXR3ZWVuIHR3byBieXRlIHN0cmluZ3MgYW5kIHJldHVybnMgdGhlIHJlc3VsdCBhcyBhCiAqIHN0cmluZyBvZiBieXRlcy4KICoKICogQHBhcmFtIHMxIGZpcnN0IHN0cmluZyBvZiBieXRlcy4KICogQHBhcmFtIHMyIHNlY29uZCBzdHJpbmcgb2YgYnl0ZXMuCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gWE9SLgogKgogKiBAcmV0dXJuIHRoZSBYT1InZCByZXN1bHQuCiAqLwp1dGlsLnhvckJ5dGVzID0gZnVuY3Rpb24oczEsIHMyLCBuKSB7CiAgdmFyIHMzID0gJyc7CiAgdmFyIGIgPSAnJzsKICB2YXIgdCA9ICcnOwogIHZhciBpID0gMDsKICB2YXIgYyA9IDA7CiAgZm9yKDsgbiA+IDA7IC0tbiwgKytpKSB7CiAgICBiID0gczEuY2hhckNvZGVBdChpKSBeIHMyLmNoYXJDb2RlQXQoaSk7CiAgICBpZihjID49IDEwKSB7CiAgICAgIHMzICs9IHQ7CiAgICAgIHQgPSAnJzsKICAgICAgYyA9IDA7CiAgICB9CiAgICB0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYik7CiAgICArK2M7CiAgfQogIHMzICs9IHQ7CiAgcmV0dXJuIHMzOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgaGV4IHN0cmluZyBpbnRvIGEgJ2JpbmFyeScgZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMuCiAqCiAqIEBwYXJhbSBoZXggdGhlIGhleGFkZWNpbWFsIHN0cmluZyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMuCiAqLwp1dGlsLmhleFRvQnl0ZXMgPSBmdW5jdGlvbihoZXgpIHsKICAvLyBUT0RPOiBkZXByZWNhdGU6ICJEZXByZWNhdGVkLiBVc2UgdXRpbC5iaW5hcnkuaGV4LmRlY29kZSBpbnN0ZWFkLiIKICB2YXIgcnZhbCA9ICcnOwogIHZhciBpID0gMDsKICBpZihoZXgubGVuZ3RoICYgMSA9PSAxKSB7CiAgICAvLyBvZGQgbnVtYmVyIG9mIGNoYXJhY3RlcnMsIGNvbnZlcnQgZmlyc3QgY2hhcmFjdGVyIGFsb25lCiAgICBpID0gMTsKICAgIHJ2YWwgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChoZXhbMF0sIDE2KSk7CiAgfQogIC8vIGNvbnZlcnQgMiBjaGFyYWN0ZXJzICgxIGJ5dGUpIGF0IGEgdGltZQogIGZvcig7IGkgPCBoZXgubGVuZ3RoOyBpICs9IDIpIHsKICAgIHJ2YWwgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChoZXguc3Vic3RyKGksIDIpLCAxNikpOwogIH0KICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDb252ZXJ0cyBhICdiaW5hcnknIGVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzIHRvIGhleC4KICoKICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlIHN0cmluZyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBzdHJpbmcgb2YgaGV4YWRlY2ltYWwgY2hhcmFjdGVycy4KICovCnV0aWwuYnl0ZXNUb0hleCA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgLy8gVE9ETzogZGVwcmVjYXRlOiAiRGVwcmVjYXRlZC4gVXNlIHV0aWwuYmluYXJ5LmhleC5lbmNvZGUgaW5zdGVhZC4iCiAgcmV0dXJuIHV0aWwuY3JlYXRlQnVmZmVyKGJ5dGVzKS50b0hleCgpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIDMyLWJpdCBpbnRlZ2VyIHRvIDQtYmlnLWVuZGlhbiBieXRlIHN0cmluZy4KICoKICogQHBhcmFtIGkgdGhlIGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhlIGJ5dGUgc3RyaW5nLgogKi8KdXRpbC5pbnQzMlRvQnl0ZXMgPSBmdW5jdGlvbihpKSB7CiAgcmV0dXJuICgKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiAyNCAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiAxNiAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiA4ICYgMHhGRikgKwogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpICYgMHhGRikpOwp9OwoKLy8gYmFzZTY0IGNoYXJhY3RlcnMsIHJldmVyc2UgbWFwcGluZwp2YXIgX2Jhc2U2NCA9CiAgJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89JzsKdmFyIF9iYXNlNjRJZHggPSBbCi8qNDMgLTQzID0gMCovCi8qJysnLCAgMSwgIDIsICAzLCcvJyAqLwogICA2MiwgLTEsIC0xLCAtMSwgNjMsCgovKicwJywnMScsJzInLCczJywnNCcsJzUnLCc2JywnNycsJzgnLCc5JyAqLwogICA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwKCi8qMTUsIDE2LCAxNywnPScsIDE5LCAyMCwgMjEgKi8KICAtMSwgLTEsIC0xLCA2NCwgLTEsIC0xLCAtMSwKCi8qNjUgLSA0MyA9IDIyKi8KLyonQScsJ0InLCdDJywnRCcsJ0UnLCdGJywnRycsJ0gnLCdJJywnSicsJ0snLCdMJywnTScsICovCiAgIDAsICAxLCAgMiwgIDMsICA0LCAgNSwgIDYsICA3LCAgOCwgIDksIDEwLCAxMSwgMTIsCgovKidOJywnTycsJ1AnLCdRJywnUicsJ1MnLCdUJywnVScsJ1YnLCdXJywnWCcsJ1knLCdaJyAqLwogICAxMywgMTQsIDE1LCAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwKCi8qOTEgLSA0MyA9IDQ4ICovCi8qNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MyAqLwogIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsCgovKjk3IC0gNDMgPSA1NCovCi8qJ2EnLCdiJywnYycsJ2QnLCdlJywnZicsJ2cnLCdoJywnaScsJ2onLCdrJywnbCcsJ20nICovCiAgIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LAoKLyonbicsJ28nLCdwJywncScsJ3InLCdzJywndCcsJ3UnLCd2JywndycsJ3gnLCd5JywneicgKi8KICAgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywgNDgsIDQ5LCA1MCwgNTEKXTsKCi8qKgogKiBCYXNlNjQgZW5jb2RlcyBhICdiaW5hcnknIGVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzLgogKgogKiBAcGFyYW0gaW5wdXQgdGhlIGJpbmFyeSBlbmNvZGVkIHN0cmluZyBvZiBieXRlcyB0byBiYXNlNjQtZW5jb2RlLgogKiBAcGFyYW0gbWF4bGluZSB0aGUgbWF4aW11bSBudW1iZXIgb2YgZW5jb2RlZCBjaGFyYWN0ZXJzIHBlciBsaW5lIHRvIHVzZSwKICogICAgICAgICAgZGVmYXVsdHMgdG8gbm9uZS4KICoKICogQHJldHVybiB0aGUgYmFzZTY0LWVuY29kZWQgb3V0cHV0LgogKi8KdXRpbC5lbmNvZGU2NCA9IGZ1bmN0aW9uKGlucHV0LCBtYXhsaW5lKSB7CiAgLy8gVE9ETzogZGVwcmVjYXRlOiAiRGVwcmVjYXRlZC4gVXNlIHV0aWwuYmluYXJ5LmJhc2U2NC5lbmNvZGUgaW5zdGVhZC4iCiAgdmFyIGxpbmUgPSAnJzsKICB2YXIgb3V0cHV0ID0gJyc7CiAgdmFyIGNocjEsIGNocjIsIGNocjM7CiAgdmFyIGkgPSAwOwogIHdoaWxlKGkgPCBpbnB1dC5sZW5ndGgpIHsKICAgIGNocjEgPSBpbnB1dC5jaGFyQ29kZUF0KGkrKyk7CiAgICBjaHIyID0gaW5wdXQuY2hhckNvZGVBdChpKyspOwogICAgY2hyMyA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTsKCiAgICAvLyBlbmNvZGUgNCBjaGFyYWN0ZXIgZ3JvdXAKICAgIGxpbmUgKz0gX2Jhc2U2NC5jaGFyQXQoY2hyMSA+PiAyKTsKICAgIGxpbmUgKz0gX2Jhc2U2NC5jaGFyQXQoKChjaHIxICYgMykgPDwgNCkgfCAoY2hyMiA+PiA0KSk7CiAgICBpZihpc05hTihjaHIyKSkgewogICAgICBsaW5lICs9ICc9PSc7CiAgICB9IGVsc2UgewogICAgICBsaW5lICs9IF9iYXNlNjQuY2hhckF0KCgoY2hyMiAmIDE1KSA8PCAyKSB8IChjaHIzID4+IDYpKTsKICAgICAgbGluZSArPSBpc05hTihjaHIzKSA/ICc9JyA6IF9iYXNlNjQuY2hhckF0KGNocjMgJiA2Myk7CiAgICB9CgogICAgaWYobWF4bGluZSAmJiBsaW5lLmxlbmd0aCA+IG1heGxpbmUpIHsKICAgICAgb3V0cHV0ICs9IGxpbmUuc3Vic3RyKDAsIG1heGxpbmUpICsgJ1xyXG4nOwogICAgICBsaW5lID0gbGluZS5zdWJzdHIobWF4bGluZSk7CiAgICB9CiAgfQogIG91dHB1dCArPSBsaW5lOwogIHJldHVybiBvdXRwdXQ7Cn07CgovKioKICogQmFzZTY0IGRlY29kZXMgYSBzdHJpbmcgaW50byBhICdiaW5hcnknIGVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzLgogKgogKiBAcGFyYW0gaW5wdXQgdGhlIGJhc2U2NC1lbmNvZGVkIGlucHV0LgogKgogKiBAcmV0dXJuIHRoZSBiaW5hcnkgZW5jb2RlZCBzdHJpbmcuCiAqLwp1dGlsLmRlY29kZTY0ID0gZnVuY3Rpb24oaW5wdXQpIHsKICAvLyBUT0RPOiBkZXByZWNhdGU6ICJEZXByZWNhdGVkLiBVc2UgdXRpbC5iaW5hcnkuYmFzZTY0LmRlY29kZSBpbnN0ZWFkLiIKCiAgLy8gcmVtb3ZlIGFsbCBub24tYmFzZTY0IGNoYXJhY3RlcnMKICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL1teQS1aYS16MC05XCtcL1w9XS9nLCAnJyk7CgogIHZhciBvdXRwdXQgPSAnJzsKICB2YXIgZW5jMSwgZW5jMiwgZW5jMywgZW5jNDsKICB2YXIgaSA9IDA7CgogIHdoaWxlKGkgPCBpbnB1dC5sZW5ndGgpIHsKICAgIGVuYzEgPSBfYmFzZTY0SWR4W2lucHV0LmNoYXJDb2RlQXQoaSsrKSAtIDQzXTsKICAgIGVuYzIgPSBfYmFzZTY0SWR4W2lucHV0LmNoYXJDb2RlQXQoaSsrKSAtIDQzXTsKICAgIGVuYzMgPSBfYmFzZTY0SWR4W2lucHV0LmNoYXJDb2RlQXQoaSsrKSAtIDQzXTsKICAgIGVuYzQgPSBfYmFzZTY0SWR4W2lucHV0LmNoYXJDb2RlQXQoaSsrKSAtIDQzXTsKCiAgICBvdXRwdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoZW5jMSA8PCAyKSB8IChlbmMyID4+IDQpKTsKICAgIGlmKGVuYzMgIT09IDY0KSB7CiAgICAgIC8vIGRlY29kZWQgYXQgbGVhc3QgMiBieXRlcwogICAgICBvdXRwdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGVuYzIgJiAxNSkgPDwgNCkgfCAoZW5jMyA+PiAyKSk7CiAgICAgIGlmKGVuYzQgIT09IDY0KSB7CiAgICAgICAgLy8gZGVjb2RlZCAzIGJ5dGVzCiAgICAgICAgb3V0cHV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChlbmMzICYgMykgPDwgNikgfCBlbmM0KTsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIG91dHB1dDsKfTsKCi8qKgogKiBVVEYtOCBlbmNvZGVzIHRoZSBnaXZlbiBVVEYtMTYgZW5jb2RlZCBzdHJpbmcgKGEgc3RhbmRhcmQgSmF2YVNjcmlwdAogKiBzdHJpbmcpLiBOb24tQVNDSUkgY2hhcmFjdGVycyB3aWxsIGJlIGVuY29kZWQgYXMgbXVsdGlwbGUgYnl0ZXMgYWNjb3JkaW5nCiAqIHRvIFVURi04LgogKgogKiBAcGFyYW0gc3RyIHRoZSBzdHJpbmcgdG8gZW5jb2RlLgogKgogKiBAcmV0dXJuIHRoZSBVVEYtOCBlbmNvZGVkIHN0cmluZy4KICovCnV0aWwuZW5jb2RlVXRmOCA9IGZ1bmN0aW9uKHN0cikgewogIHJldHVybiB1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoc3RyKSk7Cn07CgovKioKICogRGVjb2RlcyBhIFVURi04IGVuY29kZWQgc3RyaW5nIGludG8gYSBVVEYtMTYgc3RyaW5nLgogKgogKiBAcGFyYW0gc3RyIHRoZSBzdHJpbmcgdG8gZGVjb2RlLgogKgogKiBAcmV0dXJuIHRoZSBVVEYtMTYgZW5jb2RlZCBzdHJpbmcgKHN0YW5kYXJkIEphdmFTY3JpcHQgc3RyaW5nKS4KICovCnV0aWwuZGVjb2RlVXRmOCA9IGZ1bmN0aW9uKHN0cikgewogIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKHN0cikpOwp9OwoKLy8gYmluYXJ5IGVuY29kaW5nL2RlY29kaW5nIHRvb2xzCi8vIEZJWE1FOiBFeHBlcmltZW50YWwuIERvIG5vdCB1c2UgeWV0Lgp1dGlsLmJpbmFyeSA9IHsKICByYXc6IHt9LAogIGhleDoge30sCiAgYmFzZTY0OiB7fQp9OwoKLyoqCiAqIEVuY29kZXMgYSBVaW50OEFycmF5IGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nLiBUaGlzIGVuY29kaW5nIHVzZXMKICogYSB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDI1NSBmb3IgZWFjaCBjaGFyYWN0ZXIuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgVWludDhBcnJheSB0byBlbmNvZGUuCiAqCiAqIEByZXR1cm4gdGhlIGJpbmFyeS1lbmNvZGVkIHN0cmluZy4KICovCnV0aWwuYmluYXJ5LnJhdy5lbmNvZGUgPSBmdW5jdGlvbihieXRlcykgewogIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGJ5dGVzKTsKfTsKCi8qKgogKiBEZWNvZGVzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIHRvIGEgVWludDhBcnJheS4gVGhpcyBlbmNvZGluZyB1c2VzCiAqIGEgdmFsdWUgYmV0d2VlbiAwIGFuZCAyNTUgZm9yIGVhY2ggY2hhcmFjdGVyLgogKgogKiBAcGFyYW0gc3RyIHRoZSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgdG8gZGVjb2RlLgogKiBAcGFyYW0gW291dHB1dF0gYW4gb3B0aW9uYWwgVWludDhBcnJheSB0byB3cml0ZSB0aGUgb3V0cHV0IHRvOyBpZiBpdAogKiAgICAgICAgICBpcyB0b28gc21hbGwsIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi4KICogQHBhcmFtIFtvZmZzZXRdIHRoZSBzdGFydCBvZmZzZXQgZm9yIHdyaXRpbmcgdG8gdGhlIG91dHB1dCAoZGVmYXVsdDogMCkuCiAqCiAqIEByZXR1cm4gdGhlIFVpbnQ4QXJyYXkgb3IgdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuIGlmIG91dHB1dCB3YXMgZ2l2ZW4uCiAqLwp1dGlsLmJpbmFyeS5yYXcuZGVjb2RlID0gZnVuY3Rpb24oc3RyLCBvdXRwdXQsIG9mZnNldCkgewogIHZhciBvdXQgPSBvdXRwdXQ7CiAgaWYoIW91dCkgewogICAgb3V0ID0gbmV3IFVpbnQ4QXJyYXkoc3RyLmxlbmd0aCk7CiAgfQogIG9mZnNldCA9IG9mZnNldCB8fCAwOwogIHZhciBqID0gb2Zmc2V0OwogIGZvcih2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHsKICAgIG91dFtqKytdID0gc3RyLmNoYXJDb2RlQXQoaSk7CiAgfQogIHJldHVybiBvdXRwdXQgPyAoaiAtIG9mZnNldCkgOiBvdXQ7Cn07CgovKioKICogRW5jb2RlcyBhICdiaW5hcnknIHN0cmluZywgQXJyYXlCdWZmZXIsIERhdGFWaWV3LCBUeXBlZEFycmF5LCBvcgogKiBCeXRlQnVmZmVyIGFzIGEgc3RyaW5nIG9mIGhleGFkZWNpbWFsIGNoYXJhY3RlcnMuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZXMgdG8gY29udmVydC4KICoKICogQHJldHVybiB0aGUgc3RyaW5nIG9mIGhleGFkZWNpbWFsIGNoYXJhY3RlcnMuCiAqLwp1dGlsLmJpbmFyeS5oZXguZW5jb2RlID0gdXRpbC5ieXRlc1RvSGV4OwoKLyoqCiAqIERlY29kZXMgYSBoZXgtZW5jb2RlZCBzdHJpbmcgdG8gYSBVaW50OEFycmF5LgogKgogKiBAcGFyYW0gaGV4IHRoZSBoZXhhZGVjaW1hbCBzdHJpbmcgdG8gY29udmVydC4KICogQHBhcmFtIFtvdXRwdXRdIGFuIG9wdGlvbmFsIFVpbnQ4QXJyYXkgdG8gd3JpdGUgdGhlIG91dHB1dCB0bzsgaWYgaXQKICogICAgICAgICAgaXMgdG9vIHNtYWxsLCBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCiAqIEBwYXJhbSBbb2Zmc2V0XSB0aGUgc3RhcnQgb2Zmc2V0IGZvciB3cml0aW5nIHRvIHRoZSBvdXRwdXQgKGRlZmF1bHQ6IDApLgogKgogKiBAcmV0dXJuIHRoZSBVaW50OEFycmF5IG9yIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiBpZiBvdXRwdXQgd2FzIGdpdmVuLgogKi8KdXRpbC5iaW5hcnkuaGV4LmRlY29kZSA9IGZ1bmN0aW9uKGhleCwgb3V0cHV0LCBvZmZzZXQpIHsKICB2YXIgb3V0ID0gb3V0cHV0OwogIGlmKCFvdXQpIHsKICAgIG91dCA9IG5ldyBVaW50OEFycmF5KE1hdGguY2VpbChoZXgubGVuZ3RoIC8gMikpOwogIH0KICBvZmZzZXQgPSBvZmZzZXQgfHwgMDsKICB2YXIgaSA9IDAsIGogPSBvZmZzZXQ7CiAgaWYoaGV4Lmxlbmd0aCAmIDEpIHsKICAgIC8vIG9kZCBudW1iZXIgb2YgY2hhcmFjdGVycywgY29udmVydCBmaXJzdCBjaGFyYWN0ZXIgYWxvbmUKICAgIGkgPSAxOwogICAgb3V0W2orK10gPSBwYXJzZUludChoZXhbMF0sIDE2KTsKICB9CiAgLy8gY29udmVydCAyIGNoYXJhY3RlcnMgKDEgYnl0ZSkgYXQgYSB0aW1lCiAgZm9yKDsgaSA8IGhleC5sZW5ndGg7IGkgKz0gMikgewogICAgb3V0W2orK10gPSBwYXJzZUludChoZXguc3Vic3RyKGksIDIpLCAxNik7CiAgfQogIHJldHVybiBvdXRwdXQgPyAoaiAtIG9mZnNldCkgOiBvdXQ7Cn07CgovKioKICogQmFzZTY0LWVuY29kZXMgYSBVaW50OEFycmF5LgogKgogKiBAcGFyYW0gaW5wdXQgdGhlIFVpbnQ4QXJyYXkgdG8gZW5jb2RlLgogKiBAcGFyYW0gbWF4bGluZSB0aGUgbWF4aW11bSBudW1iZXIgb2YgZW5jb2RlZCBjaGFyYWN0ZXJzIHBlciBsaW5lIHRvIHVzZSwKICogICAgICAgICAgZGVmYXVsdHMgdG8gbm9uZS4KICoKICogQHJldHVybiB0aGUgYmFzZTY0LWVuY29kZWQgb3V0cHV0IHN0cmluZy4KICovCnV0aWwuYmluYXJ5LmJhc2U2NC5lbmNvZGUgPSBmdW5jdGlvbihpbnB1dCwgbWF4bGluZSkgewogIHZhciBsaW5lID0gJyc7CiAgdmFyIG91dHB1dCA9ICcnOwogIHZhciBjaHIxLCBjaHIyLCBjaHIzOwogIHZhciBpID0gMDsKICB3aGlsZShpIDwgaW5wdXQuYnl0ZUxlbmd0aCkgewogICAgY2hyMSA9IGlucHV0W2krK107CiAgICBjaHIyID0gaW5wdXRbaSsrXTsKICAgIGNocjMgPSBpbnB1dFtpKytdOwoKICAgIC8vIGVuY29kZSA0IGNoYXJhY3RlciBncm91cAogICAgbGluZSArPSBfYmFzZTY0LmNoYXJBdChjaHIxID4+IDIpOwogICAgbGluZSArPSBfYmFzZTY0LmNoYXJBdCgoKGNocjEgJiAzKSA8PCA0KSB8IChjaHIyID4+IDQpKTsKICAgIGlmKGlzTmFOKGNocjIpKSB7CiAgICAgIGxpbmUgKz0gJz09JzsKICAgIH0gZWxzZSB7CiAgICAgIGxpbmUgKz0gX2Jhc2U2NC5jaGFyQXQoKChjaHIyICYgMTUpIDw8IDIpIHwgKGNocjMgPj4gNikpOwogICAgICBsaW5lICs9IGlzTmFOKGNocjMpID8gJz0nIDogX2Jhc2U2NC5jaGFyQXQoY2hyMyAmIDYzKTsKICAgIH0KCiAgICBpZihtYXhsaW5lICYmIGxpbmUubGVuZ3RoID4gbWF4bGluZSkgewogICAgICBvdXRwdXQgKz0gbGluZS5zdWJzdHIoMCwgbWF4bGluZSkgKyAnXHJcbic7CiAgICAgIGxpbmUgPSBsaW5lLnN1YnN0cihtYXhsaW5lKTsKICAgIH0KICB9CiAgb3V0cHV0ICs9IGxpbmU7CiAgcmV0dXJuIG91dHB1dDsKfTsKCi8qKgogKiBEZWNvZGVzIGEgYmFzZTY0LWVuY29kZWQgc3RyaW5nIHRvIGEgVWludDhBcnJheS4KICoKICogQHBhcmFtIGlucHV0IHRoZSBiYXNlNjQtZW5jb2RlZCBpbnB1dCBzdHJpbmcuCiAqIEBwYXJhbSBbb3V0cHV0XSBhbiBvcHRpb25hbCBVaW50OEFycmF5IHRvIHdyaXRlIHRoZSBvdXRwdXQgdG87IGlmIGl0CiAqICAgICAgICAgIGlzIHRvbyBzbWFsbCwgYW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLgogKiBAcGFyYW0gW29mZnNldF0gdGhlIHN0YXJ0IG9mZnNldCBmb3Igd3JpdGluZyB0byB0aGUgb3V0cHV0IChkZWZhdWx0OiAwKS4KICoKICogQHJldHVybiB0aGUgVWludDhBcnJheSBvciB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gaWYgb3V0cHV0IHdhcyBnaXZlbi4KICovCnV0aWwuYmluYXJ5LmJhc2U2NC5kZWNvZGUgPSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBvZmZzZXQpIHsKICB2YXIgb3V0ID0gb3V0cHV0OwogIGlmKCFvdXQpIHsKICAgIG91dCA9IG5ldyBVaW50OEFycmF5KE1hdGguY2VpbChpbnB1dC5sZW5ndGggLyA0KSAqIDMpOwogIH0KCiAgLy8gcmVtb3ZlIGFsbCBub24tYmFzZTY0IGNoYXJhY3RlcnMKICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL1teQS1aYS16MC05XCtcL1w9XS9nLCAnJyk7CgogIG9mZnNldCA9IG9mZnNldCB8fCAwOwogIHZhciBlbmMxLCBlbmMyLCBlbmMzLCBlbmM0OwogIHZhciBpID0gMCwgaiA9IG9mZnNldDsKCiAgd2hpbGUoaSA8IGlucHV0Lmxlbmd0aCkgewogICAgZW5jMSA9IF9iYXNlNjRJZHhbaW5wdXQuY2hhckNvZGVBdChpKyspIC0gNDNdOwogICAgZW5jMiA9IF9iYXNlNjRJZHhbaW5wdXQuY2hhckNvZGVBdChpKyspIC0gNDNdOwogICAgZW5jMyA9IF9iYXNlNjRJZHhbaW5wdXQuY2hhckNvZGVBdChpKyspIC0gNDNdOwogICAgZW5jNCA9IF9iYXNlNjRJZHhbaW5wdXQuY2hhckNvZGVBdChpKyspIC0gNDNdOwoKICAgIG91dFtqKytdID0gKGVuYzEgPDwgMikgfCAoZW5jMiA+PiA0KTsKICAgIGlmKGVuYzMgIT09IDY0KSB7CiAgICAgIC8vIGRlY29kZWQgYXQgbGVhc3QgMiBieXRlcwogICAgICBvdXRbaisrXSA9ICgoZW5jMiAmIDE1KSA8PCA0KSB8IChlbmMzID4+IDIpOwogICAgICBpZihlbmM0ICE9PSA2NCkgewogICAgICAgIC8vIGRlY29kZWQgMyBieXRlcwogICAgICAgIG91dFtqKytdID0gKChlbmMzICYgMykgPDwgNikgfCBlbmM0OwogICAgICB9CiAgICB9CiAgfQoKICAvLyBtYWtlIHN1cmUgcmVzdWx0IGlzIHRoZSBleGFjdCBkZWNvZGVkIGxlbmd0aAogIHJldHVybiBvdXRwdXQgPwogICAgICAgICAoaiAtIG9mZnNldCkgOgogICAgICAgICBvdXQuc3ViYXJyYXkoMCwgaik7Cn07CgovLyB0ZXh0IGVuY29kaW5nL2RlY29kaW5nIHRvb2xzCi8vIEZJWE1FOiBFeHBlcmltZW50YWwuIERvIG5vdCB1c2UgeWV0Lgp1dGlsLnRleHQgPSB7CiAgdXRmODoge30sCiAgdXRmMTY6IHt9Cn07CgovKioKICogRW5jb2RlcyB0aGUgZ2l2ZW4gc3RyaW5nIGFzIFVURi04IGluIGEgVWludDhBcnJheS4KICoKICogQHBhcmFtIHN0ciB0aGUgc3RyaW5nIHRvIGVuY29kZS4KICogQHBhcmFtIFtvdXRwdXRdIGFuIG9wdGlvbmFsIFVpbnQ4QXJyYXkgdG8gd3JpdGUgdGhlIG91dHB1dCB0bzsgaWYgaXQKICogICAgICAgICAgaXMgdG9vIHNtYWxsLCBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCiAqIEBwYXJhbSBbb2Zmc2V0XSB0aGUgc3RhcnQgb2Zmc2V0IGZvciB3cml0aW5nIHRvIHRoZSBvdXRwdXQgKGRlZmF1bHQ6IDApLgogKgogKiBAcmV0dXJuIHRoZSBVaW50OEFycmF5IG9yIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiBpZiBvdXRwdXQgd2FzIGdpdmVuLgogKi8KdXRpbC50ZXh0LnV0ZjguZW5jb2RlID0gZnVuY3Rpb24oc3RyLCBvdXRwdXQsIG9mZnNldCkgewogIHN0ciA9IHV0aWwuZW5jb2RlVXRmOChzdHIpOwogIHZhciBvdXQgPSBvdXRwdXQ7CiAgaWYoIW91dCkgewogICAgb3V0ID0gbmV3IFVpbnQ4QXJyYXkoc3RyLmxlbmd0aCk7CiAgfQogIG9mZnNldCA9IG9mZnNldCB8fCAwOwogIHZhciBqID0gb2Zmc2V0OwogIGZvcih2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHsKICAgIG91dFtqKytdID0gc3RyLmNoYXJDb2RlQXQoaSk7CiAgfQogIHJldHVybiBvdXRwdXQgPyAoaiAtIG9mZnNldCkgOiBvdXQ7Cn07CgovKioKICogRGVjb2RlcyB0aGUgVVRGLTggY29udGVudHMgZnJvbSBhIFVpbnQ4QXJyYXkuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgVWludDhBcnJheSB0byBkZWNvZGUuCiAqCiAqIEByZXR1cm4gdGhlIHJlc3VsdGluZyBzdHJpbmcuCiAqLwp1dGlsLnRleHQudXRmOC5kZWNvZGUgPSBmdW5jdGlvbihieXRlcykgewogIHJldHVybiB1dGlsLmRlY29kZVV0ZjgoU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBieXRlcykpOwp9OwoKLyoqCiAqIEVuY29kZXMgdGhlIGdpdmVuIHN0cmluZyBhcyBVVEYtMTYgaW4gYSBVaW50OEFycmF5LgogKgogKiBAcGFyYW0gc3RyIHRoZSBzdHJpbmcgdG8gZW5jb2RlLgogKiBAcGFyYW0gW291dHB1dF0gYW4gb3B0aW9uYWwgVWludDhBcnJheSB0byB3cml0ZSB0aGUgb3V0cHV0IHRvOyBpZiBpdAogKiAgICAgICAgICBpcyB0b28gc21hbGwsIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi4KICogQHBhcmFtIFtvZmZzZXRdIHRoZSBzdGFydCBvZmZzZXQgZm9yIHdyaXRpbmcgdG8gdGhlIG91dHB1dCAoZGVmYXVsdDogMCkuCiAqCiAqIEByZXR1cm4gdGhlIFVpbnQ4QXJyYXkgb3IgdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuIGlmIG91dHB1dCB3YXMgZ2l2ZW4uCiAqLwp1dGlsLnRleHQudXRmMTYuZW5jb2RlID0gZnVuY3Rpb24oc3RyLCBvdXRwdXQsIG9mZnNldCkgewogIHZhciBvdXQgPSBvdXRwdXQ7CiAgaWYoIW91dCkgewogICAgb3V0ID0gbmV3IFVpbnQ4QXJyYXkoc3RyLmxlbmd0aCAqIDIpOwogIH0KICB2YXIgdmlldyA9IG5ldyBVaW50MTZBcnJheShvdXQuYnVmZmVyKTsKICBvZmZzZXQgPSBvZmZzZXQgfHwgMDsKICB2YXIgaiA9IG9mZnNldDsKICB2YXIgayA9IG9mZnNldDsKICBmb3IodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7CiAgICB2aWV3W2srK10gPSBzdHIuY2hhckNvZGVBdChpKTsKICAgIGogKz0gMjsKICB9CiAgcmV0dXJuIG91dHB1dCA/IChqIC0gb2Zmc2V0KSA6IG91dDsKfTsKCi8qKgogKiBEZWNvZGVzIHRoZSBVVEYtMTYgY29udGVudHMgZnJvbSBhIFVpbnQ4QXJyYXkuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgVWludDhBcnJheSB0byBkZWNvZGUuCiAqCiAqIEByZXR1cm4gdGhlIHJlc3VsdGluZyBzdHJpbmcuCiAqLwp1dGlsLnRleHQudXRmMTYuZGVjb2RlID0gZnVuY3Rpb24oYnl0ZXMpIHsKICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBuZXcgVWludDE2QXJyYXkoYnl0ZXMuYnVmZmVyKSk7Cn07CgovKioKICogRGVmbGF0ZXMgdGhlIGdpdmVuIGRhdGEgdXNpbmcgYSBmbGFzaCBpbnRlcmZhY2UuCiAqCiAqIEBwYXJhbSBhcGkgdGhlIGZsYXNoIGludGVyZmFjZS4KICogQHBhcmFtIGJ5dGVzIHRoZSBkYXRhLgogKiBAcGFyYW0gcmF3IHRydWUgdG8gcmV0dXJuIG9ubHkgcmF3IGRlZmxhdGUgZGF0YSwgZmFsc2UgdG8gaW5jbHVkZSB6bGliCiAqICAgICAgICAgIGhlYWRlciBhbmQgdHJhaWxlci4KICoKICogQHJldHVybiB0aGUgZGVmbGF0ZWQgZGF0YSBhcyBhIHN0cmluZy4KICovCnV0aWwuZGVmbGF0ZSA9IGZ1bmN0aW9uKGFwaSwgYnl0ZXMsIHJhdykgewogIGJ5dGVzID0gdXRpbC5kZWNvZGU2NChhcGkuZGVmbGF0ZSh1dGlsLmVuY29kZTY0KGJ5dGVzKSkucnZhbCk7CgogIC8vIHN0cmlwIHpsaWIgaGVhZGVyIGFuZCB0cmFpbGVyIGlmIG5lY2Vzc2FyeQogIGlmKHJhdykgewogICAgLy8gemxpYiBoZWFkZXIgaXMgMiBieXRlcyAoQ01GLEZMRykgd2hlcmUgRkxHIGluZGljYXRlcyB0aGF0CiAgICAvLyB0aGVyZSBpcyBhIDQtYnl0ZSBESUNUIChhbGRlci0zMikgYmxvY2sgYmVmb3JlIHRoZSBkYXRhIGlmCiAgICAvLyBpdHMgNXRoIGJpdCBpcyBzZXQKICAgIHZhciBzdGFydCA9IDI7CiAgICB2YXIgZmxnID0gYnl0ZXMuY2hhckNvZGVBdCgxKTsKICAgIGlmKGZsZyAmIDB4MjApIHsKICAgICAgc3RhcnQgPSA2OwogICAgfQogICAgLy8gemxpYiB0cmFpbGVyIGlzIDQgYnl0ZXMgb2YgYWRsZXItMzIKICAgIGJ5dGVzID0gYnl0ZXMuc3Vic3RyaW5nKHN0YXJ0LCBieXRlcy5sZW5ndGggLSA0KTsKICB9CgogIHJldHVybiBieXRlczsKfTsKCi8qKgogKiBJbmZsYXRlcyB0aGUgZ2l2ZW4gZGF0YSB1c2luZyBhIGZsYXNoIGludGVyZmFjZS4KICoKICogQHBhcmFtIGFwaSB0aGUgZmxhc2ggaW50ZXJmYWNlLgogKiBAcGFyYW0gYnl0ZXMgdGhlIGRhdGEuCiAqIEBwYXJhbSByYXcgdHJ1ZSBpZiB0aGUgaW5jb21pbmcgZGF0YSBoYXMgbm8gemxpYiBoZWFkZXIgb3IgdHJhaWxlciBhbmQgaXMKICogICAgICAgICAgcmF3IERFRkxBVEUgZGF0YS4KICoKICogQHJldHVybiB0aGUgaW5mbGF0ZWQgZGF0YSBhcyBhIHN0cmluZywgbnVsbCBvbiBlcnJvci4KICovCnV0aWwuaW5mbGF0ZSA9IGZ1bmN0aW9uKGFwaSwgYnl0ZXMsIHJhdykgewogIC8vIFRPRE86IGFkZCB6bGliIGhlYWRlciBhbmQgdHJhaWxlciBpZiBuZWNlc3NhcnkvcG9zc2libGUKICB2YXIgcnZhbCA9IGFwaS5pbmZsYXRlKHV0aWwuZW5jb2RlNjQoYnl0ZXMpKS5ydmFsOwogIHJldHVybiAocnZhbCA9PT0gbnVsbCkgPyBudWxsIDogdXRpbC5kZWNvZGU2NChydmFsKTsKfTsKCi8qKgogKiBTZXRzIGEgc3RvcmFnZSBvYmplY3QuCiAqCiAqIEBwYXJhbSBhcGkgdGhlIHN0b3JhZ2UgaW50ZXJmYWNlLgogKiBAcGFyYW0gaWQgdGhlIHN0b3JhZ2UgSUQgdG8gdXNlLgogKiBAcGFyYW0gb2JqIHRoZSBzdG9yYWdlIG9iamVjdCwgbnVsbCB0byByZW1vdmUuCiAqLwp2YXIgX3NldFN0b3JhZ2VPYmplY3QgPSBmdW5jdGlvbihhcGksIGlkLCBvYmopIHsKICBpZighYXBpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYlN0b3JhZ2Ugbm90IGF2YWlsYWJsZS4nKTsKICB9CgogIHZhciBydmFsOwogIGlmKG9iaiA9PT0gbnVsbCkgewogICAgcnZhbCA9IGFwaS5yZW1vdmVJdGVtKGlkKTsKICB9IGVsc2UgewogICAgLy8ganNvbi1lbmNvZGUgYW5kIGJhc2U2NC1lbmNvZGUgb2JqZWN0CiAgICBvYmogPSB1dGlsLmVuY29kZTY0KEpTT04uc3RyaW5naWZ5KG9iaikpOwogICAgcnZhbCA9IGFwaS5zZXRJdGVtKGlkLCBvYmopOwogIH0KCiAgLy8gaGFuZGxlIHBvdGVudGlhbCBmbGFzaCBlcnJvcgogIGlmKHR5cGVvZihydmFsKSAhPT0gJ3VuZGVmaW5lZCcgJiYgcnZhbC5ydmFsICE9PSB0cnVlKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IocnZhbC5lcnJvci5tZXNzYWdlKTsKICAgIGVycm9yLmlkID0gcnZhbC5lcnJvci5pZDsKICAgIGVycm9yLm5hbWUgPSBydmFsLmVycm9yLm5hbWU7CiAgICB0aHJvdyBlcnJvcjsKICB9Cn07CgovKioKICogR2V0cyBhIHN0b3JhZ2Ugb2JqZWN0LgogKgogKiBAcGFyYW0gYXBpIHRoZSBzdG9yYWdlIGludGVyZmFjZS4KICogQHBhcmFtIGlkIHRoZSBzdG9yYWdlIElEIHRvIHVzZS4KICoKICogQHJldHVybiB0aGUgc3RvcmFnZSBvYmplY3QgZW50cnkgb3IgbnVsbCBpZiBub25lIGV4aXN0cy4KICovCnZhciBfZ2V0U3RvcmFnZU9iamVjdCA9IGZ1bmN0aW9uKGFwaSwgaWQpIHsKICBpZighYXBpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYlN0b3JhZ2Ugbm90IGF2YWlsYWJsZS4nKTsKICB9CgogIC8vIGdldCB0aGUgZXhpc3RpbmcgZW50cnkKICB2YXIgcnZhbCA9IGFwaS5nZXRJdGVtKGlkKTsKCiAgLyogTm90ZTogV2UgY2hlY2sgYXBpLmluaXQgYmVjYXVzZSB3ZSBjYW4ndCBkbyAoYXBpID09IGxvY2FsU3RvcmFnZSkKICAgIG9uIElFIGJlY2F1c2Ugb2YgIkNsYXNzIGRvZXNuJ3Qgc3VwcG9ydCBBdXRvbWF0aW9uIiBleGNlcHRpb24uIE9ubHkKICAgIHRoZSBmbGFzaCBhcGkgaGFzIGFuIGluaXQgbWV0aG9kIHNvIHRoaXMgd29ya3MgdG9vLCBidXQgd2UgbmVlZCBhCiAgICBiZXR0ZXIgc29sdXRpb24gaW4gdGhlIGZ1dHVyZS4gKi8KCiAgLy8gZmxhc2ggcmV0dXJucyBpdGVtIHdyYXBwZWQgaW4gYW4gb2JqZWN0LCBoYW5kbGUgc3BlY2lhbCBjYXNlCiAgaWYoYXBpLmluaXQpIHsKICAgIGlmKHJ2YWwucnZhbCA9PT0gbnVsbCkgewogICAgICBpZihydmFsLmVycm9yKSB7CiAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKHJ2YWwuZXJyb3IubWVzc2FnZSk7CiAgICAgICAgZXJyb3IuaWQgPSBydmFsLmVycm9yLmlkOwogICAgICAgIGVycm9yLm5hbWUgPSBydmFsLmVycm9yLm5hbWU7CiAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgIH0KICAgICAgLy8gbm8gZXJyb3IsIGJ1dCBhbHNvIG5vIGl0ZW0KICAgICAgcnZhbCA9IG51bGw7CiAgICB9IGVsc2UgewogICAgICBydmFsID0gcnZhbC5ydmFsOwogICAgfQogIH0KCiAgLy8gaGFuZGxlIGRlY29kaW5nCiAgaWYocnZhbCAhPT0gbnVsbCkgewogICAgLy8gYmFzZTY0LWRlY29kZSBhbmQganNvbi1kZWNvZGUgZGF0YQogICAgcnZhbCA9IEpTT04ucGFyc2UodXRpbC5kZWNvZGU2NChydmFsKSk7CiAgfQoKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBTdG9yZXMgYW4gaXRlbSBpbiBsb2NhbCBzdG9yYWdlLgogKgogKiBAcGFyYW0gYXBpIHRoZSBzdG9yYWdlIGludGVyZmFjZS4KICogQHBhcmFtIGlkIHRoZSBzdG9yYWdlIElEIHRvIHVzZS4KICogQHBhcmFtIGtleSB0aGUga2V5IGZvciB0aGUgaXRlbS4KICogQHBhcmFtIGRhdGEgdGhlIGRhdGEgZm9yIHRoZSBpdGVtIChhbnkgamF2YXNjcmlwdCBvYmplY3QvcHJpbWl0aXZlKS4KICovCnZhciBfc2V0SXRlbSA9IGZ1bmN0aW9uKGFwaSwgaWQsIGtleSwgZGF0YSkgewogIC8vIGdldCBzdG9yYWdlIG9iamVjdAogIHZhciBvYmogPSBfZ2V0U3RvcmFnZU9iamVjdChhcGksIGlkKTsKICBpZihvYmogPT09IG51bGwpIHsKICAgIC8vIGNyZWF0ZSBhIG5ldyBzdG9yYWdlIG9iamVjdAogICAgb2JqID0ge307CiAgfQogIC8vIHVwZGF0ZSBrZXkKICBvYmpba2V5XSA9IGRhdGE7CgogIC8vIHNldCBzdG9yYWdlIG9iamVjdAogIF9zZXRTdG9yYWdlT2JqZWN0KGFwaSwgaWQsIG9iaik7Cn07CgovKioKICogR2V0cyBhbiBpdGVtIGZyb20gbG9jYWwgc3RvcmFnZS4KICoKICogQHBhcmFtIGFwaSB0aGUgc3RvcmFnZSBpbnRlcmZhY2UuCiAqIEBwYXJhbSBpZCB0aGUgc3RvcmFnZSBJRCB0byB1c2UuCiAqIEBwYXJhbSBrZXkgdGhlIGtleSBmb3IgdGhlIGl0ZW0uCiAqCiAqIEByZXR1cm4gdGhlIGl0ZW0uCiAqLwp2YXIgX2dldEl0ZW0gPSBmdW5jdGlvbihhcGksIGlkLCBrZXkpIHsKICAvLyBnZXQgc3RvcmFnZSBvYmplY3QKICB2YXIgcnZhbCA9IF9nZXRTdG9yYWdlT2JqZWN0KGFwaSwgaWQpOwogIGlmKHJ2YWwgIT09IG51bGwpIHsKICAgIC8vIHJldHVybiBkYXRhIGF0IGtleQogICAgcnZhbCA9IChrZXkgaW4gcnZhbCkgPyBydmFsW2tleV0gOiBudWxsOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogUmVtb3ZlcyBhbiBpdGVtIGZyb20gbG9jYWwgc3RvcmFnZS4KICoKICogQHBhcmFtIGFwaSB0aGUgc3RvcmFnZSBpbnRlcmZhY2UuCiAqIEBwYXJhbSBpZCB0aGUgc3RvcmFnZSBJRCB0byB1c2UuCiAqIEBwYXJhbSBrZXkgdGhlIGtleSBmb3IgdGhlIGl0ZW0uCiAqLwp2YXIgX3JlbW92ZUl0ZW0gPSBmdW5jdGlvbihhcGksIGlkLCBrZXkpIHsKICAvLyBnZXQgc3RvcmFnZSBvYmplY3QKICB2YXIgb2JqID0gX2dldFN0b3JhZ2VPYmplY3QoYXBpLCBpZCk7CiAgaWYob2JqICE9PSBudWxsICYmIGtleSBpbiBvYmopIHsKICAgIC8vIHJlbW92ZSBrZXkKICAgIGRlbGV0ZSBvYmpba2V5XTsKCiAgICAvLyBzZWUgaWYgZW50cnkgaGFzIG5vIGtleXMgcmVtYWluaW5nCiAgICB2YXIgZW1wdHkgPSB0cnVlOwogICAgZm9yKHZhciBwcm9wIGluIG9iaikgewogICAgICBlbXB0eSA9IGZhbHNlOwogICAgICBicmVhazsKICAgIH0KICAgIGlmKGVtcHR5KSB7CiAgICAgIC8vIHJlbW92ZSBlbnRyeSBlbnRpcmVseSBpZiBubyBrZXlzIGFyZSBsZWZ0CiAgICAgIG9iaiA9IG51bGw7CiAgICB9CgogICAgLy8gc2V0IHN0b3JhZ2Ugb2JqZWN0CiAgICBfc2V0U3RvcmFnZU9iamVjdChhcGksIGlkLCBvYmopOwogIH0KfTsKCi8qKgogKiBDbGVhcnMgdGhlIGxvY2FsIGRpc2sgc3RvcmFnZSBpZGVudGlmaWVkIGJ5IHRoZSBnaXZlbiBJRC4KICoKICogQHBhcmFtIGFwaSB0aGUgc3RvcmFnZSBpbnRlcmZhY2UuCiAqIEBwYXJhbSBpZCB0aGUgc3RvcmFnZSBJRCB0byB1c2UuCiAqLwp2YXIgX2NsZWFySXRlbXMgPSBmdW5jdGlvbihhcGksIGlkKSB7CiAgX3NldFN0b3JhZ2VPYmplY3QoYXBpLCBpZCwgbnVsbCk7Cn07CgovKioKICogQ2FsbHMgYSBzdG9yYWdlIGZ1bmN0aW9uLgogKgogKiBAcGFyYW0gZnVuYyB0aGUgZnVuY3Rpb24gdG8gY2FsbC4KICogQHBhcmFtIGFyZ3MgdGhlIGFyZ3VtZW50cyBmb3IgdGhlIGZ1bmN0aW9uLgogKiBAcGFyYW0gbG9jYXRpb24gdGhlIGxvY2F0aW9uIGFyZ3VtZW50LgogKgogKiBAcmV0dXJuIHRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgZnVuY3Rpb24uCiAqLwp2YXIgX2NhbGxTdG9yYWdlRnVuY3Rpb24gPSBmdW5jdGlvbihmdW5jLCBhcmdzLCBsb2NhdGlvbikgewogIHZhciBydmFsID0gbnVsbDsKCiAgLy8gZGVmYXVsdCBzdG9yYWdlIHR5cGVzCiAgaWYodHlwZW9mKGxvY2F0aW9uKSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIGxvY2F0aW9uID0gWyd3ZWInLCAnZmxhc2gnXTsKICB9CgogIC8vIGFwcGx5IHN0b3JhZ2UgdHlwZXMgaW4gb3JkZXIgb2YgcHJlZmVyZW5jZQogIHZhciB0eXBlOwogIHZhciBkb25lID0gZmFsc2U7CiAgdmFyIGV4Y2VwdGlvbiA9IG51bGw7CiAgZm9yKHZhciBpZHggaW4gbG9jYXRpb24pIHsKICAgIHR5cGUgPSBsb2NhdGlvbltpZHhdOwogICAgdHJ5IHsKICAgICAgaWYodHlwZSA9PT0gJ2ZsYXNoJyB8fCB0eXBlID09PSAnYm90aCcpIHsKICAgICAgICBpZihhcmdzWzBdID09PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZsYXNoIGxvY2FsIHN0b3JhZ2Ugbm90IGF2YWlsYWJsZS4nKTsKICAgICAgICB9CiAgICAgICAgcnZhbCA9IGZ1bmMuYXBwbHkodGhpcywgYXJncyk7CiAgICAgICAgZG9uZSA9ICh0eXBlID09PSAnZmxhc2gnKTsKICAgICAgfQogICAgICBpZih0eXBlID09PSAnd2ViJyB8fCB0eXBlID09PSAnYm90aCcpIHsKICAgICAgICBhcmdzWzBdID0gbG9jYWxTdG9yYWdlOwogICAgICAgIHJ2YWwgPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpOwogICAgICAgIGRvbmUgPSB0cnVlOwogICAgICB9CiAgICB9IGNhdGNoKGV4KSB7CiAgICAgIGV4Y2VwdGlvbiA9IGV4OwogICAgfQogICAgaWYoZG9uZSkgewogICAgICBicmVhazsKICAgIH0KICB9CgogIGlmKCFkb25lKSB7CiAgICB0aHJvdyBleGNlcHRpb247CiAgfQoKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBTdG9yZXMgYW4gaXRlbSBvbiBsb2NhbCBkaXNrLgogKgogKiBUaGUgYXZhaWxhYmxlIHR5cGVzIG9mIGxvY2FsIHN0b3JhZ2UgaW5jbHVkZSAnZmxhc2gnLCAnd2ViJywgYW5kICdib3RoJy4KICoKICogVGhlIHR5cGUgJ2ZsYXNoJyByZWZlcnMgdG8gZmxhc2ggbG9jYWwgc3RvcmFnZSAoU2hhcmVkT2JqZWN0KS4gSW4gb3JkZXIKICogdG8gdXNlIGZsYXNoIGxvY2FsIHN0b3JhZ2UsIHRoZSAnYXBpJyBwYXJhbWV0ZXIgbXVzdCBiZSB2YWxpZC4gVGhlIHR5cGUKICogJ3dlYicgcmVmZXJzIHRvIFdlYlN0b3JhZ2UsIGlmIHN1cHBvcnRlZCBieSB0aGUgYnJvd3Nlci4gVGhlIHR5cGUgJ2JvdGgnCiAqIHJlZmVycyB0byBzdG9yaW5nIHVzaW5nIGJvdGggJ2ZsYXNoJyBhbmQgJ3dlYicsIG5vdCBqdXN0IG9uZSBvciB0aGUKICogb3RoZXIuCiAqCiAqIFRoZSBsb2NhdGlvbiBhcnJheSBzaG91bGQgbGlzdCB0aGUgc3RvcmFnZSB0eXBlcyB0byB1c2UgaW4gb3JkZXIgb2YKICogcHJlZmVyZW5jZToKICoKICogWydmbGFzaCddOiBmbGFzaCBvbmx5IHN0b3JhZ2UKICogWyd3ZWInXTogd2ViIG9ubHkgc3RvcmFnZQogKiBbJ2JvdGgnXTogdHJ5IHRvIHN0b3JlIGluIGJvdGgKICogWydmbGFzaCcsJ3dlYiddOiBzdG9yZSBpbiBmbGFzaCBmaXJzdCwgYnV0IGlmIG5vdCBhdmFpbGFibGUsICd3ZWInCiAqIFsnd2ViJywnZmxhc2gnXTogc3RvcmUgaW4gd2ViIGZpcnN0LCBidXQgaWYgbm90IGF2YWlsYWJsZSwgJ2ZsYXNoJwogKgogKiBUaGUgbG9jYXRpb24gYXJyYXkgZGVmYXVsdHMgdG86IFsnd2ViJywgJ2ZsYXNoJ10KICoKICogQHBhcmFtIGFwaSB0aGUgZmxhc2ggaW50ZXJmYWNlLCBudWxsIHRvIHVzZSBvbmx5IFdlYlN0b3JhZ2UuCiAqIEBwYXJhbSBpZCB0aGUgc3RvcmFnZSBJRCB0byB1c2UuCiAqIEBwYXJhbSBrZXkgdGhlIGtleSBmb3IgdGhlIGl0ZW0uCiAqIEBwYXJhbSBkYXRhIHRoZSBkYXRhIGZvciB0aGUgaXRlbSAoYW55IGphdmFzY3JpcHQgb2JqZWN0L3ByaW1pdGl2ZSkuCiAqIEBwYXJhbSBsb2NhdGlvbiBhbiBhcnJheSB3aXRoIHRoZSBwcmVmZXJyZWQgdHlwZXMgb2Ygc3RvcmFnZSB0byB1c2UuCiAqLwp1dGlsLnNldEl0ZW0gPSBmdW5jdGlvbihhcGksIGlkLCBrZXksIGRhdGEsIGxvY2F0aW9uKSB7CiAgX2NhbGxTdG9yYWdlRnVuY3Rpb24oX3NldEl0ZW0sIGFyZ3VtZW50cywgbG9jYXRpb24pOwp9OwoKLyoqCiAqIEdldHMgYW4gaXRlbSBvbiBsb2NhbCBkaXNrLgogKgogKiBTZXQgc2V0SXRlbSgpIGZvciBkZXRhaWxzIG9uIHN0b3JhZ2UgdHlwZXMuCiAqCiAqIEBwYXJhbSBhcGkgdGhlIGZsYXNoIGludGVyZmFjZSwgbnVsbCB0byB1c2Ugb25seSBXZWJTdG9yYWdlLgogKiBAcGFyYW0gaWQgdGhlIHN0b3JhZ2UgSUQgdG8gdXNlLgogKiBAcGFyYW0ga2V5IHRoZSBrZXkgZm9yIHRoZSBpdGVtLgogKiBAcGFyYW0gbG9jYXRpb24gYW4gYXJyYXkgd2l0aCB0aGUgcHJlZmVycmVkIHR5cGVzIG9mIHN0b3JhZ2UgdG8gdXNlLgogKgogKiBAcmV0dXJuIHRoZSBpdGVtLgogKi8KdXRpbC5nZXRJdGVtID0gZnVuY3Rpb24oYXBpLCBpZCwga2V5LCBsb2NhdGlvbikgewogIHJldHVybiBfY2FsbFN0b3JhZ2VGdW5jdGlvbihfZ2V0SXRlbSwgYXJndW1lbnRzLCBsb2NhdGlvbik7Cn07CgovKioKICogUmVtb3ZlcyBhbiBpdGVtIG9uIGxvY2FsIGRpc2suCiAqCiAqIFNldCBzZXRJdGVtKCkgZm9yIGRldGFpbHMgb24gc3RvcmFnZSB0eXBlcy4KICoKICogQHBhcmFtIGFwaSB0aGUgZmxhc2ggaW50ZXJmYWNlLgogKiBAcGFyYW0gaWQgdGhlIHN0b3JhZ2UgSUQgdG8gdXNlLgogKiBAcGFyYW0ga2V5IHRoZSBrZXkgZm9yIHRoZSBpdGVtLgogKiBAcGFyYW0gbG9jYXRpb24gYW4gYXJyYXkgd2l0aCB0aGUgcHJlZmVycmVkIHR5cGVzIG9mIHN0b3JhZ2UgdG8gdXNlLgogKi8KdXRpbC5yZW1vdmVJdGVtID0gZnVuY3Rpb24oYXBpLCBpZCwga2V5LCBsb2NhdGlvbikgewogIF9jYWxsU3RvcmFnZUZ1bmN0aW9uKF9yZW1vdmVJdGVtLCBhcmd1bWVudHMsIGxvY2F0aW9uKTsKfTsKCi8qKgogKiBDbGVhcnMgdGhlIGxvY2FsIGRpc2sgc3RvcmFnZSBpZGVudGlmaWVkIGJ5IHRoZSBnaXZlbiBJRC4KICoKICogU2V0IHNldEl0ZW0oKSBmb3IgZGV0YWlscyBvbiBzdG9yYWdlIHR5cGVzLgogKgogKiBAcGFyYW0gYXBpIHRoZSBmbGFzaCBpbnRlcmZhY2UgaWYgZmxhc2ggaXMgYXZhaWxhYmxlLgogKiBAcGFyYW0gaWQgdGhlIHN0b3JhZ2UgSUQgdG8gdXNlLgogKiBAcGFyYW0gbG9jYXRpb24gYW4gYXJyYXkgd2l0aCB0aGUgcHJlZmVycmVkIHR5cGVzIG9mIHN0b3JhZ2UgdG8gdXNlLgogKi8KdXRpbC5jbGVhckl0ZW1zID0gZnVuY3Rpb24oYXBpLCBpZCwgbG9jYXRpb24pIHsKICBfY2FsbFN0b3JhZ2VGdW5jdGlvbihfY2xlYXJJdGVtcywgYXJndW1lbnRzLCBsb2NhdGlvbik7Cn07CgovKioKICogUGFyc2VzIHRoZSBzY2hlbWUsIGhvc3QsIGFuZCBwb3J0IGZyb20gYW4gaHR0cChzKSB1cmwuCiAqCiAqIEBwYXJhbSBzdHIgdGhlIHVybCBzdHJpbmcuCiAqCiAqIEByZXR1cm4gdGhlIHBhcnNlZCB1cmwgb2JqZWN0IG9yIG51bGwgaWYgdGhlIHVybCBpcyBpbnZhbGlkLgogKi8KdXRpbC5wYXJzZVVybCA9IGZ1bmN0aW9uKHN0cikgewogIC8vIEZJWE1FOiB0aGlzIHJlZ2V4IGxvb2tzIGEgYml0IGJyb2tlbgogIHZhciByZWdleCA9IC9eKGh0dHBzPyk6XC9cLyhbXjomXlwvXSopOj8oXGQqKSguKikkL2c7CiAgcmVnZXgubGFzdEluZGV4ID0gMDsKICB2YXIgbSA9IHJlZ2V4LmV4ZWMoc3RyKTsKICB2YXIgdXJsID0gKG0gPT09IG51bGwpID8gbnVsbCA6IHsKICAgIGZ1bGw6IHN0ciwKICAgIHNjaGVtZTogbVsxXSwKICAgIGhvc3Q6IG1bMl0sCiAgICBwb3J0OiBtWzNdLAogICAgcGF0aDogbVs0XQogIH07CiAgaWYodXJsKSB7CiAgICB1cmwuZnVsbEhvc3QgPSB1cmwuaG9zdDsKICAgIGlmKHVybC5wb3J0KSB7CiAgICAgIGlmKHVybC5wb3J0ICE9PSA4MCAmJiB1cmwuc2NoZW1lID09PSAnaHR0cCcpIHsKICAgICAgICB1cmwuZnVsbEhvc3QgKz0gJzonICsgdXJsLnBvcnQ7CiAgICAgIH0gZWxzZSBpZih1cmwucG9ydCAhPT0gNDQzICYmIHVybC5zY2hlbWUgPT09ICdodHRwcycpIHsKICAgICAgICB1cmwuZnVsbEhvc3QgKz0gJzonICsgdXJsLnBvcnQ7CiAgICAgIH0KICAgIH0gZWxzZSBpZih1cmwuc2NoZW1lID09PSAnaHR0cCcpIHsKICAgICAgdXJsLnBvcnQgPSA4MDsKICAgIH0gZWxzZSBpZih1cmwuc2NoZW1lID09PSAnaHR0cHMnKSB7CiAgICAgIHVybC5wb3J0ID0gNDQzOwogICAgfQogICAgdXJsLmZ1bGwgPSB1cmwuc2NoZW1lICsgJzovLycgKyB1cmwuZnVsbEhvc3Q7CiAgfQogIHJldHVybiB1cmw7Cn07CgovKiBTdG9yYWdlIGZvciBxdWVyeSB2YXJpYWJsZXMgKi8KdmFyIF9xdWVyeVZhcmlhYmxlcyA9IG51bGw7CgovKioKICogUmV0dXJucyB0aGUgd2luZG93IGxvY2F0aW9uIHF1ZXJ5IHZhcmlhYmxlcy4gUXVlcnkgaXMgcGFyc2VkIG9uIHRoZSBmaXJzdAogKiBjYWxsIGFuZCB0aGUgc2FtZSBvYmplY3QgaXMgcmV0dXJuZWQgb24gc3Vic2VxdWVudCBjYWxscy4gVGhlIG1hcHBpbmcKICogaXMgZnJvbSBrZXlzIHRvIGFuIGFycmF5IG9mIHZhbHVlcy4gUGFyYW1ldGVycyB3aXRob3V0IHZhbHVlcyB3aWxsIGhhdmUKICogYW4gb2JqZWN0IGtleSBzZXQgYnV0IG5vIHZhbHVlIGFkZGVkIHRvIHRoZSB2YWx1ZSBhcnJheS4gVmFsdWVzIGFyZQogKiB1bmVzY2FwZWQuCiAqCiAqIC4uLj9rMT12MSZrMj12MjoKICogewogKiAgICJrMSI6IFsidjEiXSwKICogICAiazIiOiBbInYyIl0KICogfQogKgogKiAuLi4/azE9djEmazE9djI6CiAqIHsKICogICAiazEiOiBbInYxIiwgInYyIl0KICogfQogKgogKiAuLi4/azE9djEmazI6CiAqIHsKICogICAiazEiOiBbInYxIl0sCiAqICAgImsyIjogW10KICogfQogKgogKiAuLi4/azE9djEmazE6CiAqIHsKICogICAiazEiOiBbInYxIl0KICogfQogKgogKiAuLi4/azEmazE6CiAqIHsKICogICAiazEiOiBbXQogKiB9CiAqCiAqIEBwYXJhbSBxdWVyeSB0aGUgcXVlcnkgc3RyaW5nIHRvIHBhcnNlIChvcHRpb25hbCwgZGVmYXVsdCB0byBjYWNoZWQKICogICAgICAgICAgcmVzdWx0cyBmcm9tIHBhcnNpbmcgd2luZG93IGxvY2F0aW9uIHNlYXJjaCBxdWVyeSkuCiAqCiAqIEByZXR1cm4gb2JqZWN0IG1hcHBpbmcga2V5cyB0byB2YXJpYWJsZXMuCiAqLwp1dGlsLmdldFF1ZXJ5VmFyaWFibGVzID0gZnVuY3Rpb24ocXVlcnkpIHsKICB2YXIgcGFyc2UgPSBmdW5jdGlvbihxKSB7CiAgICB2YXIgcnZhbCA9IHt9OwogICAgdmFyIGt2cGFpcnMgPSBxLnNwbGl0KCcmJyk7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwga3ZwYWlycy5sZW5ndGg7IGkrKykgewogICAgICB2YXIgcG9zID0ga3ZwYWlyc1tpXS5pbmRleE9mKCc9Jyk7CiAgICAgIHZhciBrZXk7CiAgICAgIHZhciB2YWw7CiAgICAgIGlmKHBvcyA+IDApIHsKICAgICAgICBrZXkgPSBrdnBhaXJzW2ldLnN1YnN0cmluZygwLCBwb3MpOwogICAgICAgIHZhbCA9IGt2cGFpcnNbaV0uc3Vic3RyaW5nKHBvcyArIDEpOwogICAgICB9IGVsc2UgewogICAgICAgIGtleSA9IGt2cGFpcnNbaV07CiAgICAgICAgdmFsID0gbnVsbDsKICAgICAgfQogICAgICBpZighKGtleSBpbiBydmFsKSkgewogICAgICAgIHJ2YWxba2V5XSA9IFtdOwogICAgICB9CiAgICAgIC8vIGRpc2FsbG93IG92ZXJyaWRpbmcgb2JqZWN0IHByb3RvdHlwZSBrZXlzCiAgICAgIGlmKCEoa2V5IGluIE9iamVjdC5wcm90b3R5cGUpICYmIHZhbCAhPT0gbnVsbCkgewogICAgICAgIHJ2YWxba2V5XS5wdXNoKHVuZXNjYXBlKHZhbCkpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gcnZhbDsKICB9OwoKICAgdmFyIHJ2YWw7CiAgIGlmKHR5cGVvZihxdWVyeSkgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgLy8gc2V0IGNhY2hlZCB2YXJpYWJsZXMgaWYgbmVlZGVkCiAgICAgaWYoX3F1ZXJ5VmFyaWFibGVzID09PSBudWxsKSB7CiAgICAgICBpZih0eXBlb2Yod2luZG93KSAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93LmxvY2F0aW9uICYmIHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpIHsKICAgICAgICAgIC8vIHBhcnNlIHdpbmRvdyBzZWFyY2ggcXVlcnkKICAgICAgICAgIF9xdWVyeVZhcmlhYmxlcyA9IHBhcnNlKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2guc3Vic3RyaW5nKDEpKTsKICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBubyBxdWVyeSB2YXJpYWJsZXMgYXZhaWxhYmxlCiAgICAgICAgICBfcXVlcnlWYXJpYWJsZXMgPSB7fTsKICAgICAgIH0KICAgICB9CiAgICAgcnZhbCA9IF9xdWVyeVZhcmlhYmxlczsKICAgfSBlbHNlIHsKICAgICAvLyBwYXJzZSBnaXZlbiBxdWVyeQogICAgIHJ2YWwgPSBwYXJzZShxdWVyeSk7CiAgIH0KICAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogUGFyc2VzIGEgZnJhZ21lbnQgaW50byBhIHBhdGggYW5kIHF1ZXJ5LiBUaGlzIG1ldGhvZCB3aWxsIHRha2UgYSBVUkkKICogZnJhZ21lbnQgYW5kIGJyZWFrIGl0IHVwIGFzIGlmIGl0IHdlcmUgdGhlIG1haW4gVVJJLiBGb3IgZXhhbXBsZToKICogICAgL2Jhci9iYXo/YT0xJmI9MgogKiByZXN1bHRzIGluOgogKiAgICB7CiAqICAgICAgIHBhdGg6IFsiYmFyIiwgImJheiJdLAogKiAgICAgICBxdWVyeTogeyJrMSI6IFsidjEiXSwgImsyIjogWyJ2MiJdfQogKiAgICB9CiAqCiAqIEByZXR1cm4gb2JqZWN0IHdpdGggYSBwYXRoIGFycmF5IGFuZCBxdWVyeSBvYmplY3QuCiAqLwp1dGlsLnBhcnNlRnJhZ21lbnQgPSBmdW5jdGlvbihmcmFnbWVudCkgewogIC8vIGRlZmF1bHQgdG8gd2hvbGUgZnJhZ21lbnQKICB2YXIgZnAgPSBmcmFnbWVudDsKICB2YXIgZnEgPSAnJzsKICAvLyBzcGxpdCBpbnRvIHBhdGggYW5kIHF1ZXJ5IGlmIHBvc3NpYmxlIGF0IHRoZSBmaXJzdCAnPycKICB2YXIgcG9zID0gZnJhZ21lbnQuaW5kZXhPZignPycpOwogIGlmKHBvcyA+IDApIHsKICAgIGZwID0gZnJhZ21lbnQuc3Vic3RyaW5nKDAsIHBvcyk7CiAgICBmcSA9IGZyYWdtZW50LnN1YnN0cmluZyhwb3MgKyAxKTsKICB9CiAgLy8gc3BsaXQgcGF0aCBiYXNlZCBvbiAnLycgYW5kIGlnbm9yZSBmaXJzdCBlbGVtZW50IGlmIGVtcHR5CiAgdmFyIHBhdGggPSBmcC5zcGxpdCgnLycpOwogIGlmKHBhdGgubGVuZ3RoID4gMCAmJiBwYXRoWzBdID09PSAnJykgewogICAgcGF0aC5zaGlmdCgpOwogIH0KICAvLyBjb252ZXJ0IHF1ZXJ5IGludG8gb2JqZWN0CiAgdmFyIHF1ZXJ5ID0gKGZxID09PSAnJykgPyB7fSA6IHV0aWwuZ2V0UXVlcnlWYXJpYWJsZXMoZnEpOwoKICByZXR1cm4gewogICAgcGF0aFN0cmluZzogZnAsCiAgICBxdWVyeVN0cmluZzogZnEsCiAgICBwYXRoOiBwYXRoLAogICAgcXVlcnk6IHF1ZXJ5CiAgfTsKfTsKCi8qKgogKiBNYWtlcyBhIHJlcXVlc3Qgb3V0IG9mIGEgVVJJLWxpa2UgcmVxdWVzdCBzdHJpbmcuIFRoaXMgaXMgaW50ZW5kZWQgdG8KICogYmUgdXNlZCB3aGVyZSBhIGZyYWdtZW50IGlkIChhZnRlciBhIFVSSSAnIycpIGlzIHBhcnNlZCBhcyBhIFVSSSB3aXRoCiAqIHBhdGggYW5kIHF1ZXJ5IHBhcnRzLiBUaGUgc3RyaW5nIHNob3VsZCBoYXZlIGEgcGF0aCBiZWdpbm5pbmcgYW5kCiAqIGRlbGltaXRlZCBieSAnLycgYW5kIG9wdGlvbmFsIHF1ZXJ5IHBhcmFtZXRlcnMgZm9sbG93aW5nIGEgJz8nLiBUaGUKICogcXVlcnkgc2hvdWxkIGJlIGEgc3RhbmRhcmQgVVJMIHNldCBvZiBrZXkgdmFsdWUgcGFpcnMgZGVsaW1pdGVkIGJ5CiAqICcmJy4gRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHRoZSBpbml0aWFsICcvJyBvbiB0aGUgcGF0aCBpcyBub3QKICogcmVxdWlyZWQuIFRoZSByZXF1ZXN0IG9iamVjdCBoYXMgdGhlIGZvbGxvd2luZyBBUEksIChmdWxseSBkZXNjcmliZWQKICogaW4gdGhlIG1ldGhvZCBjb2RlKToKICogICAgewogKiAgICAgICBwYXRoOiA8dGhlIHBhdGggc3RyaW5nIHBhcnQ+LgogKiAgICAgICBxdWVyeTogPHRoZSBxdWVyeSBzdHJpbmcgcGFydD4sCiAqICAgICAgIGdldFBhdGgoaSk6IGdldCBwYXJ0IG9yIGFsbCBvZiB0aGUgc3BsaXQgcGF0aCBhcnJheSwKICogICAgICAgZ2V0UXVlcnkoaywgaSk6IGdldCBwYXJ0IG9yIGFsbCBvZiBhIHF1ZXJ5IGtleSBhcnJheSwKICogICAgICAgZ2V0UXVlcnlMYXN0KGssIF9kZWZhdWx0KTogZ2V0IGxhc3QgZWxlbWVudCBvZiBhIHF1ZXJ5IGtleSBhcnJheS4KICogICAgfQogKgogKiBAcmV0dXJuIG9iamVjdCB3aXRoIHJlcXVlc3QgcGFyYW1ldGVycy4KICovCnV0aWwubWFrZVJlcXVlc3QgPSBmdW5jdGlvbihyZXFTdHJpbmcpIHsKICB2YXIgZnJhZyA9IHV0aWwucGFyc2VGcmFnbWVudChyZXFTdHJpbmcpOwogIHZhciByZXEgPSB7CiAgICAvLyBmdWxsIHBhdGggc3RyaW5nCiAgICBwYXRoOiBmcmFnLnBhdGhTdHJpbmcsCiAgICAvLyBmdWxsIHF1ZXJ5IHN0cmluZwogICAgcXVlcnk6IGZyYWcucXVlcnlTdHJpbmcsCiAgICAvKioKICAgICAqIEdldCBwYXRoIG9yIGVsZW1lbnQgaW4gcGF0aC4KICAgICAqCiAgICAgKiBAcGFyYW0gaSBvcHRpb25hbCBwYXRoIGluZGV4LgogICAgICoKICAgICAqIEByZXR1cm4gcGF0aCBvciBwYXJ0IG9mIHBhdGggaWYgaSBwcm92aWRlZC4KICAgICAqLwogICAgZ2V0UGF0aDogZnVuY3Rpb24oaSkgewogICAgICByZXR1cm4gKHR5cGVvZihpKSA9PT0gJ3VuZGVmaW5lZCcpID8gZnJhZy5wYXRoIDogZnJhZy5wYXRoW2ldOwogICAgfSwKICAgIC8qKgogICAgICogR2V0IHF1ZXJ5LCB2YWx1ZXMgZm9yIGEga2V5LCBvciB2YWx1ZSBmb3IgYSBrZXkgaW5kZXguCiAgICAgKgogICAgICogQHBhcmFtIGsgb3B0aW9uYWwgcXVlcnkga2V5LgogICAgICogQHBhcmFtIGkgb3B0aW9uYWwgcXVlcnkga2V5IGluZGV4LgogICAgICoKICAgICAqIEByZXR1cm4gcXVlcnksIHZhbHVlcyBmb3IgYSBrZXksIG9yIHZhbHVlIGZvciBhIGtleSBpbmRleC4KICAgICAqLwogICAgZ2V0UXVlcnk6IGZ1bmN0aW9uKGssIGkpIHsKICAgICAgdmFyIHJ2YWw7CiAgICAgIGlmKHR5cGVvZihrKSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICBydmFsID0gZnJhZy5xdWVyeTsKICAgICAgfSBlbHNlIHsKICAgICAgICBydmFsID0gZnJhZy5xdWVyeVtrXTsKICAgICAgICBpZihydmFsICYmIHR5cGVvZihpKSAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICAgICBydmFsID0gcnZhbFtpXTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIHJ2YWw7CiAgICB9LAogICAgZ2V0UXVlcnlMYXN0OiBmdW5jdGlvbihrLCBfZGVmYXVsdCkgewogICAgICB2YXIgcnZhbDsKICAgICAgdmFyIHZhbHMgPSByZXEuZ2V0UXVlcnkoayk7CiAgICAgIGlmKHZhbHMpIHsKICAgICAgICBydmFsID0gdmFsc1t2YWxzLmxlbmd0aCAtIDFdOwogICAgICB9IGVsc2UgewogICAgICAgIHJ2YWwgPSBfZGVmYXVsdDsKICAgICAgfQogICAgICByZXR1cm4gcnZhbDsKICAgIH0KICB9OwogIHJldHVybiByZXE7Cn07CgovKioKICogTWFrZXMgYSBVUkkgb3V0IG9mIGEgcGF0aCwgYW4gb2JqZWN0IHdpdGggcXVlcnkgcGFyYW1ldGVycywgYW5kIGEKICogZnJhZ21lbnQuIFVzZXMgalF1ZXJ5LnBhcmFtKCkgaW50ZXJuYWxseSBmb3IgcXVlcnkgc3RyaW5nIGNyZWF0aW9uLgogKiBJZiB0aGUgcGF0aCBpcyBhbiBhcnJheSwgaXQgd2lsbCBiZSBqb2luZWQgd2l0aCAnLycuCiAqCiAqIEBwYXJhbSBwYXRoIHN0cmluZyBwYXRoIG9yIGFycmF5IG9mIHN0cmluZ3MuCiAqIEBwYXJhbSBxdWVyeSBvYmplY3Qgd2l0aCBxdWVyeSBwYXJhbWV0ZXJzLiAob3B0aW9uYWwpCiAqIEBwYXJhbSBmcmFnbWVudCBmcmFnbWVudCBzdHJpbmcuIChvcHRpb25hbCkKICoKICogQHJldHVybiBzdHJpbmcgb2JqZWN0IHdpdGggcmVxdWVzdCBwYXJhbWV0ZXJzLgogKi8KdXRpbC5tYWtlTGluayA9IGZ1bmN0aW9uKHBhdGgsIHF1ZXJ5LCBmcmFnbWVudCkgewogIC8vIGpvaW4gcGF0aCBwYXJ0cyBpZiBuZWVkZWQKICBwYXRoID0galF1ZXJ5LmlzQXJyYXkocGF0aCkgPyBwYXRoLmpvaW4oJy8nKSA6IHBhdGg7CgogIHZhciBxc3RyID0galF1ZXJ5LnBhcmFtKHF1ZXJ5IHx8IHt9KTsKICBmcmFnbWVudCA9IGZyYWdtZW50IHx8ICcnOwogIHJldHVybiBwYXRoICsKICAgICgocXN0ci5sZW5ndGggPiAwKSA/ICgnPycgKyBxc3RyKSA6ICcnKSArCiAgICAoKGZyYWdtZW50Lmxlbmd0aCA+IDApID8gKCcjJyArIGZyYWdtZW50KSA6ICcnKTsKfTsKCi8qKgogKiBGb2xsb3dzIGEgcGF0aCBvZiBrZXlzIGRlZXAgaW50byBhbiBvYmplY3QgaGllcmFyY2h5IGFuZCBzZXQgYSB2YWx1ZS4KICogSWYgYSBrZXkgZG9lcyBub3QgZXhpc3Qgb3IgaXQncyB2YWx1ZSBpcyBub3QgYW4gb2JqZWN0LCBjcmVhdGUgYW4KICogb2JqZWN0IGluIGl0J3MgcGxhY2UuIFRoaXMgY2FuIGJlIGRlc3RydWN0aXZlIHRvIGEgb2JqZWN0IHRyZWUgaWYKICogbGVhZiBub2RlcyBhcmUgZ2l2ZW4gYXMgbm9uLWZpbmFsIHBhdGgga2V5cy4KICogVXNlZCB0byBhdm9pZCBleGNlcHRpb25zIGZyb20gbWlzc2luZyBwYXJ0cyBvZiB0aGUgcGF0aC4KICoKICogQHBhcmFtIG9iamVjdCB0aGUgc3RhcnRpbmcgb2JqZWN0LgogKiBAcGFyYW0ga2V5cyBhbiBhcnJheSBvZiBzdHJpbmcga2V5cy4KICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSB0byBzZXQuCiAqLwp1dGlsLnNldFBhdGggPSBmdW5jdGlvbihvYmplY3QsIGtleXMsIHZhbHVlKSB7CiAgLy8gbmVlZCB0byBzdGFydCBhdCBhbiBvYmplY3QKICBpZih0eXBlb2Yob2JqZWN0KSA9PT0gJ29iamVjdCcgJiYgb2JqZWN0ICE9PSBudWxsKSB7CiAgICB2YXIgaSA9IDA7CiAgICB2YXIgbGVuID0ga2V5cy5sZW5ndGg7CiAgICB3aGlsZShpIDwgbGVuKSB7CiAgICAgIHZhciBuZXh0ID0ga2V5c1tpKytdOwogICAgICBpZihpID09IGxlbikgewogICAgICAgIC8vIGxhc3QKICAgICAgICBvYmplY3RbbmV4dF0gPSB2YWx1ZTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBtb3JlCiAgICAgICAgdmFyIGhhc05leHQgPSAobmV4dCBpbiBvYmplY3QpOwogICAgICAgIGlmKCFoYXNOZXh0IHx8CiAgICAgICAgICAoaGFzTmV4dCAmJiB0eXBlb2Yob2JqZWN0W25leHRdKSAhPT0gJ29iamVjdCcpIHx8CiAgICAgICAgICAoaGFzTmV4dCAmJiBvYmplY3RbbmV4dF0gPT09IG51bGwpKSB7CiAgICAgICAgICBvYmplY3RbbmV4dF0gPSB7fTsKICAgICAgICB9CiAgICAgICAgb2JqZWN0ID0gb2JqZWN0W25leHRdOwogICAgICB9CiAgICB9CiAgfQp9OwoKLyoqCiAqIEZvbGxvd3MgYSBwYXRoIG9mIGtleXMgZGVlcCBpbnRvIGFuIG9iamVjdCBoaWVyYXJjaHkgYW5kIHJldHVybiBhIHZhbHVlLgogKiBJZiBhIGtleSBkb2VzIG5vdCBleGlzdCwgY3JlYXRlIGFuIG9iamVjdCBpbiBpdCdzIHBsYWNlLgogKiBVc2VkIHRvIGF2b2lkIGV4Y2VwdGlvbnMgZnJvbSBtaXNzaW5nIHBhcnRzIG9mIHRoZSBwYXRoLgogKgogKiBAcGFyYW0gb2JqZWN0IHRoZSBzdGFydGluZyBvYmplY3QuCiAqIEBwYXJhbSBrZXlzIGFuIGFycmF5IG9mIHN0cmluZyBrZXlzLgogKiBAcGFyYW0gX2RlZmF1bHQgdmFsdWUgdG8gcmV0dXJuIGlmIHBhdGggbm90IGZvdW5kLgogKgogKiBAcmV0dXJuIHRoZSB2YWx1ZSBhdCB0aGUgcGF0aCBpZiBmb3VuZCwgZWxzZSBkZWZhdWx0IGlmIGdpdmVuLCBlbHNlCiAqICAgICAgICAgdW5kZWZpbmVkLgogKi8KdXRpbC5nZXRQYXRoID0gZnVuY3Rpb24ob2JqZWN0LCBrZXlzLCBfZGVmYXVsdCkgewogIHZhciBpID0gMDsKICB2YXIgbGVuID0ga2V5cy5sZW5ndGg7CiAgdmFyIGhhc05leHQgPSB0cnVlOwogIHdoaWxlKGhhc05leHQgJiYgaSA8IGxlbiAmJgogICAgdHlwZW9mKG9iamVjdCkgPT09ICdvYmplY3QnICYmIG9iamVjdCAhPT0gbnVsbCkgewogICAgdmFyIG5leHQgPSBrZXlzW2krK107CiAgICBoYXNOZXh0ID0gbmV4dCBpbiBvYmplY3Q7CiAgICBpZihoYXNOZXh0KSB7CiAgICAgIG9iamVjdCA9IG9iamVjdFtuZXh0XTsKICAgIH0KICB9CiAgcmV0dXJuIChoYXNOZXh0ID8gb2JqZWN0IDogX2RlZmF1bHQpOwp9OwoKLyoqCiAqIEZvbGxvdyBhIHBhdGggb2Yga2V5cyBkZWVwIGludG8gYW4gb2JqZWN0IGhpZXJhcmNoeSBhbmQgZGVsZXRlIHRoZQogKiBsYXN0IG9uZS4gSWYgYSBrZXkgZG9lcyBub3QgZXhpc3QsIGRvIG5vdGhpbmcuCiAqIFVzZWQgdG8gYXZvaWQgZXhjZXB0aW9ucyBmcm9tIG1pc3NpbmcgcGFydHMgb2YgdGhlIHBhdGguCiAqCiAqIEBwYXJhbSBvYmplY3QgdGhlIHN0YXJ0aW5nIG9iamVjdC4KICogQHBhcmFtIGtleXMgYW4gYXJyYXkgb2Ygc3RyaW5nIGtleXMuCiAqLwp1dGlsLmRlbGV0ZVBhdGggPSBmdW5jdGlvbihvYmplY3QsIGtleXMpIHsKICAvLyBuZWVkIHRvIHN0YXJ0IGF0IGFuIG9iamVjdAogIGlmKHR5cGVvZihvYmplY3QpID09PSAnb2JqZWN0JyAmJiBvYmplY3QgIT09IG51bGwpIHsKICAgIHZhciBpID0gMDsKICAgIHZhciBsZW4gPSBrZXlzLmxlbmd0aDsKICAgIHdoaWxlKGkgPCBsZW4pIHsKICAgICAgdmFyIG5leHQgPSBrZXlzW2krK107CiAgICAgIGlmKGkgPT0gbGVuKSB7CiAgICAgICAgLy8gbGFzdAogICAgICAgIGRlbGV0ZSBvYmplY3RbbmV4dF07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gbW9yZQogICAgICAgIGlmKCEobmV4dCBpbiBvYmplY3QpIHx8CiAgICAgICAgICAodHlwZW9mKG9iamVjdFtuZXh0XSkgIT09ICdvYmplY3QnKSB8fAogICAgICAgICAgKG9iamVjdFtuZXh0XSA9PT0gbnVsbCkpIHsKICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgb2JqZWN0ID0gb2JqZWN0W25leHRdOwogICAgICB9CiAgICB9CiAgfQp9OwoKLyoqCiAqIENoZWNrIGlmIGFuIG9iamVjdCBpcyBlbXB0eS4KICoKICogVGFrZW4gZnJvbToKICogaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82Nzk5MTUvaG93LWRvLWktdGVzdC1mb3ItYW4tZW1wdHktamF2YXNjcmlwdC1vYmplY3QtZnJvbS1qc29uLzY3OTkzNyM2Nzk5MzcKICoKICogQHBhcmFtIG9iamVjdCB0aGUgb2JqZWN0IHRvIGNoZWNrLgogKi8KdXRpbC5pc0VtcHR5ID0gZnVuY3Rpb24ob2JqKSB7CiAgZm9yKHZhciBwcm9wIGluIG9iaikgewogICAgaWYob2JqLmhhc093blByb3BlcnR5KHByb3ApKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9CiAgcmV0dXJuIHRydWU7Cn07CgovKioKICogRm9ybWF0IHdpdGggc2ltcGxlIHByaW50Zi1zdHlsZSBpbnRlcnBvbGF0aW9uLgogKgogKiAlJTogbGl0ZXJhbCAnJScKICogJXMsJW86IGNvbnZlcnQgbmV4dCBhcmd1bWVudCBpbnRvIGEgc3RyaW5nLgogKgogKiBAcGFyYW0gZm9ybWF0IHRoZSBzdHJpbmcgdG8gZm9ybWF0LgogKiBAcGFyYW0gLi4uIGFyZ3VtZW50cyB0byBpbnRlcnBvbGF0ZSBpbnRvIHRoZSBmb3JtYXQgc3RyaW5nLgogKi8KdXRpbC5mb3JtYXQgPSBmdW5jdGlvbihmb3JtYXQpIHsKICB2YXIgcmUgPSAvJS4vZzsKICAvLyBjdXJyZW50IG1hdGNoCiAgdmFyIG1hdGNoOwogIC8vIGN1cnJlbnQgcGFydAogIHZhciBwYXJ0OwogIC8vIGN1cnJlbnQgYXJnIGluZGV4CiAgdmFyIGFyZ2kgPSAwOwogIC8vIGNvbGxlY3RlZCBwYXJ0cyB0byByZWNvbWJpbmUgbGF0ZXIKICB2YXIgcGFydHMgPSBbXTsKICAvLyBsYXN0IGluZGV4IGZvdW5kCiAgdmFyIGxhc3QgPSAwOwogIC8vIGxvb3Agd2hpbGUgbWF0Y2hlcyByZW1haW4KICB3aGlsZSgobWF0Y2ggPSByZS5leGVjKGZvcm1hdCkpKSB7CiAgICBwYXJ0ID0gZm9ybWF0LnN1YnN0cmluZyhsYXN0LCByZS5sYXN0SW5kZXggLSAyKTsKICAgIC8vIGRvbid0IGFkZCBlbXB0eSBzdHJpbmdzIChpZSwgcGFydHMgYmV0d2VlbiAlcyVzKQogICAgaWYocGFydC5sZW5ndGggPiAwKSB7CiAgICAgIHBhcnRzLnB1c2gocGFydCk7CiAgICB9CiAgICBsYXN0ID0gcmUubGFzdEluZGV4OwogICAgLy8gc3dpdGNoIG9uICUgY29kZQogICAgdmFyIGNvZGUgPSBtYXRjaFswXVsxXTsKICAgIHN3aXRjaChjb2RlKSB7CiAgICBjYXNlICdzJzoKICAgIGNhc2UgJ28nOgogICAgICAvLyBjaGVjayBpZiBlbm91Z2ggYXJndW1lbnRzIHdlcmUgZ2l2ZW4KICAgICAgaWYoYXJnaSA8IGFyZ3VtZW50cy5sZW5ndGgpIHsKICAgICAgICBwYXJ0cy5wdXNoKGFyZ3VtZW50c1thcmdpKysgKyAxXSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcGFydHMucHVzaCgnPD8+Jyk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICAvLyBGSVhNRTogZG8gcHJvcGVyIGZvcm1hdGluZyBmb3IgbnVtYmVycywgZXRjCiAgICAvL2Nhc2UgJ2YnOgogICAgLy9jYXNlICdkJzoKICAgIGNhc2UgJyUnOgogICAgICBwYXJ0cy5wdXNoKCclJyk7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgLy9wYXJ0cy5wdXNoKCc8JyArICclJyArIGNvZGUgKyAnPz4nKTsKICAgICAgcGFydHMucHVzaCgnPFx1MDAyMycgKyBjb2RlICsgJz8+Jyk7IC8vIE5lZWQgdG8gZXNjYXBlIHRoaXMgbGluZSBmb3IgQVNQLm5ldAogICAgfQogIH0KICAvLyBhZGQgdHJhaWxpbmcgcGFydCBvZiBmb3JtYXQgc3RyaW5nCiAgcGFydHMucHVzaChmb3JtYXQuc3Vic3RyaW5nKGxhc3QpKTsKICByZXR1cm4gcGFydHMuam9pbignJyk7Cn07CgovKioKICogRm9ybWF0cyBhIG51bWJlci4KICoKICogaHR0cDovL3NuaXBwbHIuY29tL3ZpZXcvNTk0NS9qYXZhc2NyaXB0LW51bWJlcmZvcm1hdC0tcG9ydGVkLWZyb20tcGhwLwogKi8KdXRpbC5mb3JtYXROdW1iZXIgPSBmdW5jdGlvbihudW1iZXIsIGRlY2ltYWxzLCBkZWNfcG9pbnQsIHRob3VzYW5kc19zZXApIHsKICAvLyBodHRwOi8va2V2aW4udmFuem9ubmV2ZWxkLm5ldAogIC8vICsgICBvcmlnaW5hbCBieTogSm9uYXMgUmFvbmkgU29hcmVzIFNpbHZhIChodHRwOi8vd3d3LmpzZnJvbWhlbGwuY29tKQogIC8vICsgICBpbXByb3ZlZCBieTogS2V2aW4gdmFuIFpvbm5ldmVsZCAoaHR0cDovL2tldmluLnZhbnpvbm5ldmVsZC5uZXQpCiAgLy8gKyAgICAgYnVnZml4IGJ5OiBNaWNoYWVsIFdoaXRlIChodHRwOi8vY3Jlc3RpZGcuY29tKQogIC8vICsgICAgIGJ1Z2ZpeCBieTogQmVuamFtaW4gTHVwdG9uCiAgLy8gKyAgICAgYnVnZml4IGJ5OiBBbGxhbiBKZW5zZW4gKGh0dHA6Ly93d3cud2ludGVybmV0Lm5vKQogIC8vICsgICAgcmV2aXNlZCBieTogSm9uYXMgUmFvbmkgU29hcmVzIFNpbHZhIChodHRwOi8vd3d3LmpzZnJvbWhlbGwuY29tKQogIC8vICogICAgIGV4YW1wbGUgMTogbnVtYmVyX2Zvcm1hdCgxMjM0LjU2NzgsIDIsICcuJywgJycpOwogIC8vICogICAgIHJldHVybnMgMTogMTIzNC41NwoKICB2YXIgbiA9IG51bWJlciwgYyA9IGlzTmFOKGRlY2ltYWxzID0gTWF0aC5hYnMoZGVjaW1hbHMpKSA/IDIgOiBkZWNpbWFsczsKICB2YXIgZCA9IGRlY19wb2ludCA9PT0gdW5kZWZpbmVkID8gJywnIDogZGVjX3BvaW50OwogIHZhciB0ID0gdGhvdXNhbmRzX3NlcCA9PT0gdW5kZWZpbmVkID8KICAgJy4nIDogdGhvdXNhbmRzX3NlcCwgcyA9IG4gPCAwID8gJy0nIDogJyc7CiAgdmFyIGkgPSBwYXJzZUludCgobiA9IE1hdGguYWJzKCtuIHx8IDApLnRvRml4ZWQoYykpLCAxMCkgKyAnJzsKICB2YXIgaiA9IChpLmxlbmd0aCA+IDMpID8gaS5sZW5ndGggJSAzIDogMDsKICByZXR1cm4gcyArIChqID8gaS5zdWJzdHIoMCwgaikgKyB0IDogJycpICsKICAgIGkuc3Vic3RyKGopLnJlcGxhY2UoLyhcZHszfSkoPz1cZCkvZywgJyQxJyArIHQpICsKICAgIChjID8gZCArIE1hdGguYWJzKG4gLSBpKS50b0ZpeGVkKGMpLnNsaWNlKDIpIDogJycpOwp9OwoKLyoqCiAqIEZvcm1hdHMgYSBieXRlIHNpemUuCiAqCiAqIGh0dHA6Ly9zbmlwcGxyLmNvbS92aWV3LzU5NDkvZm9ybWF0LWh1bWFuaXplLWZpbGUtYnl0ZS1zaXplLXByZXNlbnRhdGlvbi1pbi1qYXZhc2NyaXB0LwogKi8KdXRpbC5mb3JtYXRTaXplID0gZnVuY3Rpb24oc2l6ZSkgewogIGlmKHNpemUgPj0gMTA3Mzc0MTgyNCkgewogICAgc2l6ZSA9IHV0aWwuZm9ybWF0TnVtYmVyKHNpemUgLyAxMDczNzQxODI0LCAyLCAnLicsICcnKSArICcgR2lCJzsKICB9IGVsc2UgaWYoc2l6ZSA+PSAxMDQ4NTc2KSB7CiAgICBzaXplID0gdXRpbC5mb3JtYXROdW1iZXIoc2l6ZSAvIDEwNDg1NzYsIDIsICcuJywgJycpICsgJyBNaUInOwogIH0gZWxzZSBpZihzaXplID49IDEwMjQpIHsKICAgIHNpemUgPSB1dGlsLmZvcm1hdE51bWJlcihzaXplIC8gMTAyNCwgMCkgKyAnIEtpQic7CiAgfSBlbHNlIHsKICAgIHNpemUgPSB1dGlsLmZvcm1hdE51bWJlcihzaXplLCAwKSArICcgYnl0ZXMnOwogIH0KICByZXR1cm4gc2l6ZTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhbiBJUHY0IG9yIElQdjYgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGludG8gYnl0ZXMgKGluIG5ldHdvcmsgb3JkZXIpLgogKgogKiBAcGFyYW0gaXAgdGhlIElQdjQgb3IgSVB2NiBhZGRyZXNzIHRvIGNvbnZlcnQuCiAqCiAqIEByZXR1cm4gdGhlIDQtYnl0ZSBJUHY2IG9yIDE2LWJ5dGUgSVB2NiBhZGRyZXNzIG9yIG51bGwgaWYgdGhlIGFkZHJlc3MgY2FuJ3QKICogICAgICAgICBiZSBwYXJzZWQuCiAqLwp1dGlsLmJ5dGVzRnJvbUlQID0gZnVuY3Rpb24oaXApIHsKICBpZihpcC5pbmRleE9mKCcuJykgIT09IC0xKSB7CiAgICByZXR1cm4gdXRpbC5ieXRlc0Zyb21JUHY0KGlwKTsKICB9CiAgaWYoaXAuaW5kZXhPZignOicpICE9PSAtMSkgewogICAgcmV0dXJuIHV0aWwuYnl0ZXNGcm9tSVB2NihpcCk7CiAgfQogIHJldHVybiBudWxsOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIElQdjQgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGludG8gYnl0ZXMgKGluIG5ldHdvcmsgb3JkZXIpLgogKgogKiBAcGFyYW0gaXAgdGhlIElQdjQgYWRkcmVzcyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSA0LWJ5dGUgYWRkcmVzcyBvciBudWxsIGlmIHRoZSBhZGRyZXNzIGNhbid0IGJlIHBhcnNlZC4KICovCnV0aWwuYnl0ZXNGcm9tSVB2NCA9IGZ1bmN0aW9uKGlwKSB7CiAgaXAgPSBpcC5zcGxpdCgnLicpOwogIGlmKGlwLmxlbmd0aCAhPT0gNCkgewogICAgcmV0dXJuIG51bGw7CiAgfQogIHZhciBiID0gdXRpbC5jcmVhdGVCdWZmZXIoKTsKICBmb3IodmFyIGkgPSAwOyBpIDwgaXAubGVuZ3RoOyArK2kpIHsKICAgIHZhciBudW0gPSBwYXJzZUludChpcFtpXSwgMTApOwogICAgaWYoaXNOYU4obnVtKSkgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIGIucHV0Qnl0ZShudW0pOwogIH0KICByZXR1cm4gYi5nZXRCeXRlcygpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIElQdjYgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGludG8gYnl0ZXMgKGluIG5ldHdvcmsgb3JkZXIpLgogKgogKiBAcGFyYW0gaXAgdGhlIElQdjYgYWRkcmVzcyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSAxNi1ieXRlIGFkZHJlc3Mgb3IgbnVsbCBpZiB0aGUgYWRkcmVzcyBjYW4ndCBiZSBwYXJzZWQuCiAqLwp1dGlsLmJ5dGVzRnJvbUlQdjYgPSBmdW5jdGlvbihpcCkgewogIHZhciBibGFua3MgPSAwOwogIGlwID0gaXAuc3BsaXQoJzonKS5maWx0ZXIoZnVuY3Rpb24oZSkgewogICAgaWYoZS5sZW5ndGggPT09IDApICsrYmxhbmtzOwogICAgcmV0dXJuIHRydWU7CiAgfSk7CiAgdmFyIHplcm9zID0gKDggLSBpcC5sZW5ndGggKyBibGFua3MpICogMjsKICB2YXIgYiA9IHV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgZm9yKHZhciBpID0gMDsgaSA8IDg7ICsraSkgewogICAgaWYoIWlwW2ldIHx8IGlwW2ldLmxlbmd0aCA9PT0gMCkgewogICAgICBiLmZpbGxXaXRoQnl0ZSgwLCB6ZXJvcyk7CiAgICAgIHplcm9zID0gMDsKICAgICAgY29udGludWU7CiAgICB9CiAgICB2YXIgYnl0ZXMgPSB1dGlsLmhleFRvQnl0ZXMoaXBbaV0pOwogICAgaWYoYnl0ZXMubGVuZ3RoIDwgMikgewogICAgICBiLnB1dEJ5dGUoMCk7CiAgICB9CiAgICBiLnB1dEJ5dGVzKGJ5dGVzKTsKICB9CiAgcmV0dXJuIGIuZ2V0Qnl0ZXMoKTsKfTsKCi8qKgogKiBDb252ZXJ0cyA0LWJ5dGVzIGludG8gYW4gSVB2NCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb3IgMTYtYnl0ZXMgaW50bwogKiBhbiBJUHY2IHN0cmluZyByZXByZXNlbnRhdGlvbi4gVGhlIGJ5dGVzIG11c3QgYmUgaW4gbmV0d29yayBvcmRlci4KICoKICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBJUHY0IG9yIElQdjYgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGlmIDQgb3IgMTYgYnl0ZXMsCiAqICAgICAgICAgcmVzcGVjdGl2ZWx5LCBhcmUgZ2l2ZW4sIG90aGVyd2lzZSBudWxsLgogKi8KdXRpbC5ieXRlc1RvSVAgPSBmdW5jdGlvbihieXRlcykgewogIGlmKGJ5dGVzLmxlbmd0aCA9PT0gNCkgewogICAgcmV0dXJuIHV0aWwuYnl0ZXNUb0lQdjQoYnl0ZXMpOwogIH0KICBpZihieXRlcy5sZW5ndGggPT09IDE2KSB7CiAgICByZXR1cm4gdXRpbC5ieXRlc1RvSVB2NihieXRlcyk7CiAgfQogIHJldHVybiBudWxsOwp9OwoKLyoqCiAqIENvbnZlcnRzIDQtYnl0ZXMgaW50byBhbiBJUHY0IHN0cmluZyByZXByZXNlbnRhdGlvbi4gVGhlIGJ5dGVzIG11c3QgYmUKICogaW4gbmV0d29yayBvcmRlci4KICoKICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBJUHY0IHN0cmluZyByZXByZXNlbnRhdGlvbiBvciBudWxsIGZvciBhbiBpbnZhbGlkICMgb2YgYnl0ZXMuCiAqLwp1dGlsLmJ5dGVzVG9JUHY0ID0gZnVuY3Rpb24oYnl0ZXMpIHsKICBpZihieXRlcy5sZW5ndGggIT09IDQpIHsKICAgIHJldHVybiBudWxsOwogIH0KICB2YXIgaXAgPSBbXTsKICBmb3IodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyArK2kpIHsKICAgIGlwLnB1c2goYnl0ZXMuY2hhckNvZGVBdChpKSk7CiAgfQogIHJldHVybiBpcC5qb2luKCcuJyk7Cn07CgovKioKICogQ29udmVydHMgMTYtYnl0ZXMgaW50byBhbiBJUHYxNiBzdHJpbmcgcmVwcmVzZW50YXRpb24uIFRoZSBieXRlcyBtdXN0IGJlCiAqIGluIG5ldHdvcmsgb3JkZXIuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZXMgdG8gY29udmVydC4KICoKICogQHJldHVybiB0aGUgSVB2MTYgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9yIG51bGwgZm9yIGFuIGludmFsaWQgIyBvZiBieXRlcy4KICovCnV0aWwuYnl0ZXNUb0lQdjYgPSBmdW5jdGlvbihieXRlcykgewogIGlmKGJ5dGVzLmxlbmd0aCAhPT0gMTYpIHsKICAgIHJldHVybiBudWxsOwogIH0KICB2YXIgaXAgPSBbXTsKICB2YXIgemVyb0dyb3VwcyA9IFtdOwogIHZhciB6ZXJvTWF4R3JvdXAgPSAwOwogIGZvcih2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikgewogICAgdmFyIGhleCA9IHV0aWwuYnl0ZXNUb0hleChieXRlc1tpXSArIGJ5dGVzW2kgKyAxXSk7CiAgICAvLyBjYW5vbmljYWxpemUgemVybyByZXByZXNlbnRhdGlvbgogICAgd2hpbGUoaGV4WzBdID09PSAnMCcgJiYgaGV4ICE9PSAnMCcpIHsKICAgICAgaGV4ID0gaGV4LnN1YnN0cigxKTsKICAgIH0KICAgIGlmKGhleCA9PT0gJzAnKSB7CiAgICAgIHZhciBsYXN0ID0gemVyb0dyb3Vwc1t6ZXJvR3JvdXBzLmxlbmd0aCAtIDFdOwogICAgICB2YXIgaWR4ID0gaXAubGVuZ3RoOwogICAgICBpZighbGFzdCB8fCBpZHggIT09IGxhc3QuZW5kICsgMSkgewogICAgICAgIHplcm9Hcm91cHMucHVzaCh7c3RhcnQ6IGlkeCwgZW5kOiBpZHh9KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBsYXN0LmVuZCA9IGlkeDsKICAgICAgICBpZigobGFzdC5lbmQgLSBsYXN0LnN0YXJ0KSA+CiAgICAgICAgICAoemVyb0dyb3Vwc1t6ZXJvTWF4R3JvdXBdLmVuZCAtIHplcm9Hcm91cHNbemVyb01heEdyb3VwXS5zdGFydCkpIHsKICAgICAgICAgIHplcm9NYXhHcm91cCA9IHplcm9Hcm91cHMubGVuZ3RoIC0gMTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGlwLnB1c2goaGV4KTsKICB9CiAgaWYoemVyb0dyb3Vwcy5sZW5ndGggPiAwKSB7CiAgICB2YXIgZ3JvdXAgPSB6ZXJvR3JvdXBzW3plcm9NYXhHcm91cF07CiAgICAvLyBvbmx5IHNob3J0ZW4gZ3JvdXAgb2YgbGVuZ3RoID4gMAogICAgaWYoZ3JvdXAuZW5kIC0gZ3JvdXAuc3RhcnQgPiAwKSB7CiAgICAgIGlwLnNwbGljZShncm91cC5zdGFydCwgZ3JvdXAuZW5kIC0gZ3JvdXAuc3RhcnQgKyAxLCAnJyk7CiAgICAgIGlmKGdyb3VwLnN0YXJ0ID09PSAwKSB7CiAgICAgICAgaXAudW5zaGlmdCgnJyk7CiAgICAgIH0KICAgICAgaWYoZ3JvdXAuZW5kID09PSA3KSB7CiAgICAgICAgaXAucHVzaCgnJyk7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIGlwLmpvaW4oJzonKTsKfTsKCi8qKgogKiBFc3RpbWF0ZXMgdGhlIG51bWJlciBvZiBwcm9jZXNzZXMgdGhhdCBjYW4gYmUgcnVuIGNvbmN1cnJlbnRseS4gSWYKICogY3JlYXRpbmcgV2ViIFdvcmtlcnMsIGtlZXAgaW4gbWluZCB0aGF0IHRoZSBtYWluIEphdmFTY3JpcHQgcHJvY2VzcyBuZWVkcwogKiBpdHMgb3duIGNvcmUuCiAqCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgdXBkYXRlIHRydWUgdG8gZm9yY2UgYW4gdXBkYXRlIChub3QgdXNlIHRoZSBjYWNoZWQgdmFsdWUpLgogKiBAcGFyYW0gY2FsbGJhY2soZXJyLCBtYXgpIGNhbGxlZCBvbmNlIHRoZSBvcGVyYXRpb24gY29tcGxldGVzLgogKi8KdXRpbC5lc3RpbWF0ZUNvcmVzID0gZnVuY3Rpb24ob3B0aW9ucywgY2FsbGJhY2spIHsKICBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykgewogICAgY2FsbGJhY2sgPSBvcHRpb25zOwogICAgb3B0aW9ucyA9IHt9OwogIH0KICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICBpZignY29yZXMnIGluIHV0aWwgJiYgIW9wdGlvbnMudXBkYXRlKSB7CiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgdXRpbC5jb3Jlcyk7CiAgfQogIGlmKHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmCiAgICAnaGFyZHdhcmVDb25jdXJyZW5jeScgaW4gbmF2aWdhdG9yICYmCiAgICBuYXZpZ2F0b3IuaGFyZHdhcmVDb25jdXJyZW5jeSA+IDApIHsKICAgIHV0aWwuY29yZXMgPSBuYXZpZ2F0b3IuaGFyZHdhcmVDb25jdXJyZW5jeTsKICAgIHJldHVybiBjYWxsYmFjayhudWxsLCB1dGlsLmNvcmVzKTsKICB9CiAgaWYodHlwZW9mIFdvcmtlciA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIC8vIHdvcmtlcnMgbm90IGF2YWlsYWJsZQogICAgdXRpbC5jb3JlcyA9IDE7CiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgdXRpbC5jb3Jlcyk7CiAgfQogIGlmKHR5cGVvZiBCbG9iID09PSAndW5kZWZpbmVkJykgewogICAgLy8gY2FuJ3QgZXN0aW1hdGUsIGRlZmF1bHQgdG8gMgogICAgdXRpbC5jb3JlcyA9IDI7CiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgdXRpbC5jb3Jlcyk7CiAgfQoKICAvLyBjcmVhdGUgd29ya2VyIGNvbmN1cnJlbmN5IGVzdGltYXRpb24gY29kZSBhcyBibG9iCiAgdmFyIGJsb2JVcmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKG5ldyBCbG9iKFsnKCcsCiAgICBmdW5jdGlvbigpIHsKICAgICAgc2VsZi5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24oZSkgewogICAgICAgIC8vIHJ1biB3b3JrZXIgZm9yIDQgbXMKICAgICAgICB2YXIgc3QgPSBEYXRlLm5vdygpOwogICAgICAgIHZhciBldCA9IHN0ICsgNDsKICAgICAgICB3aGlsZShEYXRlLm5vdygpIDwgZXQpOwogICAgICAgIHNlbGYucG9zdE1lc3NhZ2Uoe3N0OiBzdCwgZXQ6IGV0fSk7CiAgICAgIH0pOwogICAgfS50b1N0cmluZygpLAogICcpKCknXSwge3R5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0J30pKTsKCiAgLy8gdGFrZSA1IHNhbXBsZXMgdXNpbmcgMTYgd29ya2VycwogIHNhbXBsZShbXSwgNSwgMTYpOwoKICBmdW5jdGlvbiBzYW1wbGUobWF4LCBzYW1wbGVzLCBudW1Xb3JrZXJzKSB7CiAgICBpZihzYW1wbGVzID09PSAwKSB7CiAgICAgIC8vIGdldCBvdmVybGFwIGF2ZXJhZ2UKICAgICAgdmFyIGF2ZyA9IE1hdGguZmxvb3IobWF4LnJlZHVjZShmdW5jdGlvbihhdmcsIHgpIHsKICAgICAgICByZXR1cm4gYXZnICsgeDsKICAgICAgfSwgMCkgLyBtYXgubGVuZ3RoKTsKICAgICAgdXRpbC5jb3JlcyA9IE1hdGgubWF4KDEsIGF2Zyk7CiAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwoYmxvYlVybCk7CiAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCB1dGlsLmNvcmVzKTsKICAgIH0KICAgIG1hcChudW1Xb3JrZXJzLCBmdW5jdGlvbihlcnIsIHJlc3VsdHMpIHsKICAgICAgbWF4LnB1c2gocmVkdWNlKG51bVdvcmtlcnMsIHJlc3VsdHMpKTsKICAgICAgc2FtcGxlKG1heCwgc2FtcGxlcyAtIDEsIG51bVdvcmtlcnMpOwogICAgfSk7CiAgfQoKICBmdW5jdGlvbiBtYXAobnVtV29ya2VycywgY2FsbGJhY2spIHsKICAgIHZhciB3b3JrZXJzID0gW107CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG51bVdvcmtlcnM7ICsraSkgewogICAgICB2YXIgd29ya2VyID0gbmV3IFdvcmtlcihibG9iVXJsKTsKICAgICAgd29ya2VyLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbihlKSB7CiAgICAgICAgcmVzdWx0cy5wdXNoKGUuZGF0YSk7CiAgICAgICAgaWYocmVzdWx0cy5sZW5ndGggPT09IG51bVdvcmtlcnMpIHsKICAgICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBudW1Xb3JrZXJzOyArK2kpIHsKICAgICAgICAgICAgd29ya2Vyc1tpXS50ZXJtaW5hdGUoKTsKICAgICAgICAgIH0KICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHJlc3VsdHMpOwogICAgICAgIH0KICAgICAgfSk7CiAgICAgIHdvcmtlcnMucHVzaCh3b3JrZXIpOwogICAgfQogICAgZm9yKHZhciBpID0gMDsgaSA8IG51bVdvcmtlcnM7ICsraSkgewogICAgICB3b3JrZXJzW2ldLnBvc3RNZXNzYWdlKGkpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gcmVkdWNlKG51bVdvcmtlcnMsIHJlc3VsdHMpIHsKICAgIC8vIGZpbmQgb3ZlcmxhcHBpbmcgdGltZSB3aW5kb3dzCiAgICB2YXIgb3ZlcmxhcHMgPSBbXTsKICAgIGZvcih2YXIgbiA9IDA7IG4gPCBudW1Xb3JrZXJzOyArK24pIHsKICAgICAgdmFyIHIxID0gcmVzdWx0c1tuXTsKICAgICAgdmFyIG92ZXJsYXAgPSBvdmVybGFwc1tuXSA9IFtdOwogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgbnVtV29ya2VyczsgKytpKSB7CiAgICAgICAgaWYobiA9PT0gaSkgewogICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIHZhciByMiA9IHJlc3VsdHNbaV07CiAgICAgICAgaWYoKHIxLnN0ID4gcjIuc3QgJiYgcjEuc3QgPCByMi5ldCkgfHwKICAgICAgICAgIChyMi5zdCA+IHIxLnN0ICYmIHIyLnN0IDwgcjEuZXQpKSB7CiAgICAgICAgICBvdmVybGFwLnB1c2goaSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICAvLyBnZXQgbWF4aW11bSBvdmVybGFwcyAuLi4gZG9uJ3QgaW5jbHVkZSBvdmVybGFwcGluZyB3b3JrZXIgaXRzZWxmCiAgICAvLyBhcyB0aGUgbWFpbiBKUyBwcm9jZXNzIHdhcyBhbHNvIGJlaW5nIHNjaGVkdWxlZCBkdXJpbmcgdGhlIHdvcmsgYW5kCiAgICAvLyB3b3VsZCBoYXZlIHRvIGJlIHN1YnRyYWN0ZWQgZnJvbSB0aGUgZXN0aW1hdGUgYW55d2F5CiAgICByZXR1cm4gb3ZlcmxhcHMucmVkdWNlKGZ1bmN0aW9uKG1heCwgb3ZlcmxhcCkgewogICAgICByZXR1cm4gTWF0aC5tYXgobWF4LCBvdmVybGFwLmxlbmd0aCk7CiAgICB9LCAwKTsKICB9Cn07Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICd1dGlsJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3V0aWwnLFsncmVxdWlyZScsICdtb2R1bGUnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogQ2lwaGVyIGJhc2UgQVBJLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCmZvcmdlLmNpcGhlciA9IGZvcmdlLmNpcGhlciB8fCB7fTsKCi8vIHJlZ2lzdGVyZWQgYWxnb3JpdGhtcwpmb3JnZS5jaXBoZXIuYWxnb3JpdGhtcyA9IGZvcmdlLmNpcGhlci5hbGdvcml0aG1zIHx8IHt9OwoKLyoqCiAqIENyZWF0ZXMgYSBjaXBoZXIgb2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgdG8gZW5jcnlwdCBkYXRhIHVzaW5nIHRoZSBnaXZlbgogKiBhbGdvcml0aG0gYW5kIGtleS4gVGhlIGFsZ29yaXRobSBtYXkgYmUgcHJvdmlkZWQgYXMgYSBzdHJpbmcgdmFsdWUgZm9yIGEKICogcHJldmlvdXNseSByZWdpc3RlcmVkIGFsZ29yaXRobSBvciBpdCBtYXkgYmUgZ2l2ZW4gYXMgYSBjaXBoZXIgYWxnb3JpdGhtCiAqIEFQSSBvYmplY3QuCiAqCiAqIEBwYXJhbSBhbGdvcml0aG0gdGhlIGFsZ29yaXRobSB0byB1c2UsIGVpdGhlciBhIHN0cmluZyBvciBhbiBhbGdvcml0aG0gQVBJCiAqICAgICAgICAgIG9iamVjdC4KICogQHBhcmFtIGtleSB0aGUga2V5IHRvIHVzZSwgYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMgb3IgYQogKiAgICAgICAgICBieXRlIGJ1ZmZlci4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZm9yZ2UuY2lwaGVyLmNyZWF0ZUNpcGhlciA9IGZ1bmN0aW9uKGFsZ29yaXRobSwga2V5KSB7CiAgdmFyIGFwaSA9IGFsZ29yaXRobTsKICBpZih0eXBlb2YgYXBpID09PSAnc3RyaW5nJykgewogICAgYXBpID0gZm9yZ2UuY2lwaGVyLmdldEFsZ29yaXRobShhcGkpOwogICAgaWYoYXBpKSB7CiAgICAgIGFwaSA9IGFwaSgpOwogICAgfQogIH0KICBpZighYXBpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGFsZ29yaXRobTogJyArIGFsZ29yaXRobSk7CiAgfQoKICAvLyBhc3N1bWUgYmxvY2sgY2lwaGVyCiAgcmV0dXJuIG5ldyBmb3JnZS5jaXBoZXIuQmxvY2tDaXBoZXIoewogICAgYWxnb3JpdGhtOiBhcGksCiAgICBrZXk6IGtleSwKICAgIGRlY3J5cHQ6IGZhbHNlCiAgfSk7Cn07CgovKioKICogQ3JlYXRlcyBhIGRlY2lwaGVyIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIGRlY3J5cHQgZGF0YSB1c2luZyB0aGUgZ2l2ZW4KICogYWxnb3JpdGhtIGFuZCBrZXkuIFRoZSBhbGdvcml0aG0gbWF5IGJlIHByb3ZpZGVkIGFzIGEgc3RyaW5nIHZhbHVlIGZvciBhCiAqIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCBhbGdvcml0aG0gb3IgaXQgbWF5IGJlIGdpdmVuIGFzIGEgY2lwaGVyIGFsZ29yaXRobQogKiBBUEkgb2JqZWN0LgogKgogKiBAcGFyYW0gYWxnb3JpdGhtIHRoZSBhbGdvcml0aG0gdG8gdXNlLCBlaXRoZXIgYSBzdHJpbmcgb3IgYW4gYWxnb3JpdGhtIEFQSQogKiAgICAgICAgICBvYmplY3QuCiAqIEBwYXJhbSBrZXkgdGhlIGtleSB0byB1c2UsIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzIG9yIGEKICogICAgICAgICAgYnl0ZSBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLmNpcGhlci5jcmVhdGVEZWNpcGhlciA9IGZ1bmN0aW9uKGFsZ29yaXRobSwga2V5KSB7CiAgdmFyIGFwaSA9IGFsZ29yaXRobTsKICBpZih0eXBlb2YgYXBpID09PSAnc3RyaW5nJykgewogICAgYXBpID0gZm9yZ2UuY2lwaGVyLmdldEFsZ29yaXRobShhcGkpOwogICAgaWYoYXBpKSB7CiAgICAgIGFwaSA9IGFwaSgpOwogICAgfQogIH0KICBpZighYXBpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGFsZ29yaXRobTogJyArIGFsZ29yaXRobSk7CiAgfQoKICAvLyBhc3N1bWUgYmxvY2sgY2lwaGVyCiAgcmV0dXJuIG5ldyBmb3JnZS5jaXBoZXIuQmxvY2tDaXBoZXIoewogICAgYWxnb3JpdGhtOiBhcGksCiAgICBrZXk6IGtleSwKICAgIGRlY3J5cHQ6IHRydWUKICB9KTsKfTsKCi8qKgogKiBSZWdpc3RlcnMgYW4gYWxnb3JpdGhtIGJ5IG5hbWUuIElmIHRoZSBuYW1lIHdhcyBhbHJlYWR5IHJlZ2lzdGVyZWQsIHRoZQogKiBhbGdvcml0aG0gQVBJIG9iamVjdCB3aWxsIGJlIG92ZXJ3cml0dGVuLgogKgogKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtLgogKiBAcGFyYW0gYWxnb3JpdGhtIHRoZSBhbGdvcml0aG0gQVBJIG9iamVjdC4KICovCmZvcmdlLmNpcGhlci5yZWdpc3RlckFsZ29yaXRobSA9IGZ1bmN0aW9uKG5hbWUsIGFsZ29yaXRobSkgewogIG5hbWUgPSBuYW1lLnRvVXBwZXJDYXNlKCk7CiAgZm9yZ2UuY2lwaGVyLmFsZ29yaXRobXNbbmFtZV0gPSBhbGdvcml0aG07Cn07CgovKioKICogR2V0cyBhIHJlZ2lzdGVyZWQgYWxnb3JpdGhtIGJ5IG5hbWUuCiAqCiAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0uCiAqCiAqIEByZXR1cm4gdGhlIGFsZ29yaXRobSwgaWYgZm91bmQsIG51bGwgaWYgbm90LgogKi8KZm9yZ2UuY2lwaGVyLmdldEFsZ29yaXRobSA9IGZ1bmN0aW9uKG5hbWUpIHsKICBuYW1lID0gbmFtZS50b1VwcGVyQ2FzZSgpOwogIGlmKG5hbWUgaW4gZm9yZ2UuY2lwaGVyLmFsZ29yaXRobXMpIHsKICAgIHJldHVybiBmb3JnZS5jaXBoZXIuYWxnb3JpdGhtc1tuYW1lXTsKICB9CiAgcmV0dXJuIG51bGw7Cn07Cgp2YXIgQmxvY2tDaXBoZXIgPSBmb3JnZS5jaXBoZXIuQmxvY2tDaXBoZXIgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgdGhpcy5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobTsKICB0aGlzLm1vZGUgPSB0aGlzLmFsZ29yaXRobS5tb2RlOwogIHRoaXMuYmxvY2tTaXplID0gdGhpcy5tb2RlLmJsb2NrU2l6ZTsKICB0aGlzLl9maW5pc2ggPSBmYWxzZTsKICB0aGlzLl9pbnB1dCA9IG51bGw7CiAgdGhpcy5vdXRwdXQgPSBudWxsOwogIHRoaXMuX29wID0gb3B0aW9ucy5kZWNyeXB0ID8gdGhpcy5tb2RlLmRlY3J5cHQgOiB0aGlzLm1vZGUuZW5jcnlwdDsKICB0aGlzLl9kZWNyeXB0ID0gb3B0aW9ucy5kZWNyeXB0OwogIHRoaXMuYWxnb3JpdGhtLmluaXRpYWxpemUob3B0aW9ucyk7Cn07CgovKioKICogU3RhcnRzIG9yIHJlc3RhcnRzIHRoZSBlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24gcHJvY2Vzcywgd2hpY2hldmVyCiAqIHdhcyBwcmV2aW91c2x5IGNvbmZpZ3VyZWQuCiAqCiAqIEZvciBub24tR0NNIG1vZGUsIHRoZSBJViBtYXkgYmUgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMsIGFuIGFycmF5CiAqIG9mIGJ5dGVzLCBhIGJ5dGUgYnVmZmVyLCBvciBhbiBhcnJheSBvZiAzMi1iaXQgaW50ZWdlcnMuIElmIHRoZSBJViBpcyBpbgogKiBieXRlcywgdGhlbiBpdCBtdXN0IGJlIE5iICgxNikgYnl0ZXMgaW4gbGVuZ3RoLiBJZiB0aGUgSVYgaXMgZ2l2ZW4gaW4gYXMKICogMzItYml0IGludGVnZXJzLCB0aGVuIGl0IG11c3QgYmUgNCBpbnRlZ2VycyBsb25nLgogKgogKiBOb3RlOiBhbiBJViBpcyBub3QgcmVxdWlyZWQgb3IgdXNlZCBpbiBFQ0IgbW9kZS4KICoKICogRm9yIEdDTS1tb2RlLCB0aGUgSVYgbXVzdCBiZSBnaXZlbiBhcyBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZyBvZiBieXRlcyBvcgogKiBhIGJ5dGUgYnVmZmVyLiBUaGUgbnVtYmVyIG9mIGJ5dGVzIHNob3VsZCBiZSAxMiAoOTYgYml0cykgYXMgcmVjb21tZW5kZWQKICogYnkgTklTVCBTUC04MDAtMzhEIGJ1dCBhbm90aGVyIGxlbmd0aCBtYXkgYmUgZ2l2ZW4uCiAqCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgaXYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciB0byB1c2UgYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YKICogICAgICAgICAgICBieXRlcywgbnVsbCB0byByZXVzZSB0aGUgbGFzdCBjaXBoZXJlZCBibG9jayBmcm9tIGEgcHJldmlvdXMKICogICAgICAgICAgICB1cGRhdGUoKSAodGhpcyAicmVzaWR1ZSIgbWV0aG9kIGlzIGZvciBsZWdhY3kgc3VwcG9ydCBvbmx5KS4KICogICAgICAgICAgYWRkaXRpb25hbERhdGEgYWRkaXRpb25hbCBhdXRoZW50aWNhdGlvbiBkYXRhIGFzIGEgYmluYXJ5LWVuY29kZWQKICogICAgICAgICAgICBzdHJpbmcgb2YgYnl0ZXMsIGZvciAnR0NNJyBtb2RlLCAoZGVmYXVsdDogbm9uZSkuCiAqICAgICAgICAgIHRhZ0xlbmd0aCBkZXNpcmVkIGxlbmd0aCBvZiBhdXRoZW50aWNhdGlvbiB0YWcsIGluIGJpdHMsIGZvcgogKiAgICAgICAgICAgICdHQ00nIG1vZGUgKDAtMTI4LCBkZWZhdWx0OiAxMjgpLgogKiAgICAgICAgICB0YWcgdGhlIGF1dGhlbnRpY2F0aW9uIHRhZyB0byBjaGVjayBpZiBkZWNyeXB0aW5nLCBhcyBhCiAqICAgICAgICAgICAgIGJpbmFyeS1lbmNvZGVkIHN0cmluZyBvZiBieXRlcy4KICogICAgICAgICAgb3V0cHV0IHRoZSBvdXRwdXQgdGhlIGJ1ZmZlciB0byB3cml0ZSB0bywgbnVsbCB0byBjcmVhdGUgb25lLgogKi8KQmxvY2tDaXBoZXIucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24ob3B0aW9ucykgewogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIHZhciBvcHRzID0ge307CiAgZm9yKHZhciBrZXkgaW4gb3B0aW9ucykgewogICAgb3B0c1trZXldID0gb3B0aW9uc1trZXldOwogIH0KICBvcHRzLmRlY3J5cHQgPSB0aGlzLl9kZWNyeXB0OwogIHRoaXMuX2ZpbmlzaCA9IGZhbHNlOwogIHRoaXMuX2lucHV0ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICB0aGlzLm91dHB1dCA9IG9wdGlvbnMub3V0cHV0IHx8IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdGhpcy5tb2RlLnN0YXJ0KG9wdHMpOwp9OwoKLyoqCiAqIFVwZGF0ZXMgdGhlIG5leHQgYmxvY2sgYWNjb3JkaW5nIHRvIHRoZSBjaXBoZXIgbW9kZS4KICoKICogQHBhcmFtIGlucHV0IHRoZSBidWZmZXIgdG8gcmVhZCBmcm9tLgogKi8KQmxvY2tDaXBoZXIucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKGlucHV0KSB7CiAgaWYoaW5wdXQpIHsKICAgIC8vIGlucHV0IGdpdmVuLCBzbyBlbXB0eSBpdCBpbnRvIHRoZSBpbnB1dCBidWZmZXIKICAgIHRoaXMuX2lucHV0LnB1dEJ1ZmZlcihpbnB1dCk7CiAgfQoKICAvLyBkbyBjaXBoZXIgb3BlcmF0aW9uIHVudGlsIGl0IG5lZWRzIG1vcmUgaW5wdXQgYW5kIG5vdCBmaW5pc2hlZAogIHdoaWxlKCF0aGlzLl9vcC5jYWxsKHRoaXMubW9kZSwgdGhpcy5faW5wdXQsIHRoaXMub3V0cHV0LCB0aGlzLl9maW5pc2gpICYmCiAgICAhdGhpcy5fZmluaXNoKSB7fQoKICAvLyBmcmVlIGNvbnN1bWVkIG1lbW9yeSBmcm9tIGlucHV0IGJ1ZmZlcgogIHRoaXMuX2lucHV0LmNvbXBhY3QoKTsKfTsKCi8qKgogKiBGaW5pc2hlcyBlbmNyeXB0aW5nIG9yIGRlY3J5cHRpbmcuCiAqCiAqIEBwYXJhbSBwYWQgYSBwYWRkaW5nIGZ1bmN0aW9uIHRvIHVzZSBpbiBDQkMgbW9kZSwgbnVsbCBmb3IgZGVmYXVsdCwKICogICAgICAgICAgc2lnbmF0dXJlKGJsb2NrU2l6ZSwgYnVmZmVyLCBkZWNyeXB0KS4KICoKICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwsIGZhbHNlIG9uIGVycm9yLgogKi8KQmxvY2tDaXBoZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uKHBhZCkgewogIC8vIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5IHcvZGVwcmVjYXRlZCBwYWRkaW5nIEFQSQogIC8vIE5vdGU6IHdpbGwgb3ZlcndyaXRlIHBhZGRpbmcgZnVuY3Rpb25zIGV2ZW4gYWZ0ZXIgYW5vdGhlciBzdGFydCgpIGNhbGwKICBpZihwYWQgJiYgKHRoaXMubW9kZS5uYW1lID09PSAnRUNCJyB8fCB0aGlzLm1vZGUubmFtZSA9PT0gJ0NCQycpKSB7CiAgICB0aGlzLm1vZGUucGFkID0gZnVuY3Rpb24oaW5wdXQpIHsKICAgICAgcmV0dXJuIHBhZCh0aGlzLmJsb2NrU2l6ZSwgaW5wdXQsIGZhbHNlKTsKICAgIH07CiAgICB0aGlzLm1vZGUudW5wYWQgPSBmdW5jdGlvbihvdXRwdXQpIHsKICAgICAgcmV0dXJuIHBhZCh0aGlzLmJsb2NrU2l6ZSwgb3V0cHV0LCB0cnVlKTsKICAgIH07CiAgfQoKICAvLyBidWlsZCBvcHRpb25zIGZvciBwYWRkaW5nIGFuZCBhZnRlckZpbmlzaCBmdW5jdGlvbnMKICB2YXIgb3B0aW9ucyA9IHt9OwogIG9wdGlvbnMuZGVjcnlwdCA9IHRoaXMuX2RlY3J5cHQ7CgogIC8vIGdldCAjIG9mIGJ5dGVzIHRoYXQgd29uJ3QgZmlsbCBhIGJsb2NrCiAgb3B0aW9ucy5vdmVyZmxvdyA9IHRoaXMuX2lucHV0Lmxlbmd0aCgpICUgdGhpcy5ibG9ja1NpemU7CgogIGlmKCF0aGlzLl9kZWNyeXB0ICYmIHRoaXMubW9kZS5wYWQpIHsKICAgIGlmKCF0aGlzLm1vZGUucGFkKHRoaXMuX2lucHV0LCBvcHRpb25zKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfQoKICAvLyBkbyBmaW5hbCB1cGRhdGUKICB0aGlzLl9maW5pc2ggPSB0cnVlOwogIHRoaXMudXBkYXRlKCk7CgogIGlmKHRoaXMuX2RlY3J5cHQgJiYgdGhpcy5tb2RlLnVucGFkKSB7CiAgICBpZighdGhpcy5tb2RlLnVucGFkKHRoaXMub3V0cHV0LCBvcHRpb25zKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfQoKICBpZih0aGlzLm1vZGUuYWZ0ZXJGaW5pc2gpIHsKICAgIGlmKCF0aGlzLm1vZGUuYWZ0ZXJGaW5pc2godGhpcy5vdXRwdXQsIG9wdGlvbnMpKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9CgogIHJldHVybiB0cnVlOwp9OwoKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ2NpcGhlcic7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9jaXBoZXInLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFN1cHBvcnRlZCBjaXBoZXIgbW9kZXMuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKZm9yZ2UuY2lwaGVyID0gZm9yZ2UuY2lwaGVyIHx8IHt9OwoKLy8gc3VwcG9ydGVkIGNpcGhlciBtb2Rlcwp2YXIgbW9kZXMgPSBmb3JnZS5jaXBoZXIubW9kZXMgPSBmb3JnZS5jaXBoZXIubW9kZXMgfHwge307CgoKLyoqIEVsZWN0cm9uaWMgY29kZWJvb2sgKEVDQikgKERvbid0IHVzZSB0aGlzOyBpdCdzIG5vdCBzZWN1cmUpICoqLwoKbW9kZXMuZWNiID0gZnVuY3Rpb24ob3B0aW9ucykgewogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIHRoaXMubmFtZSA9ICdFQ0InOwogIHRoaXMuY2lwaGVyID0gb3B0aW9ucy5jaXBoZXI7CiAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLmJsb2NrU2l6ZSB8fCAxNjsKICB0aGlzLl9pbnRzID0gdGhpcy5ibG9ja1NpemUgLyA0OwogIHRoaXMuX2luQmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5fb3V0QmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7Cn07Cgptb2Rlcy5lY2IucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24ob3B0aW9ucykge307Cgptb2Rlcy5lY2IucHJvdG90eXBlLmVuY3J5cHQgPSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBmaW5pc2gpIHsKICAvLyBub3QgZW5vdWdoIGlucHV0IHRvIGVuY3J5cHQKICBpZihpbnB1dC5sZW5ndGgoKSA8IHRoaXMuYmxvY2tTaXplICYmICEoZmluaXNoICYmIGlucHV0Lmxlbmd0aCgpID4gMCkpIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZ2V0IG5leHQgYmxvY2sKICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICB0aGlzLl9pbkJsb2NrW2ldID0gaW5wdXQuZ2V0SW50MzIoKTsKICB9CgogIC8vIGVuY3J5cHQgYmxvY2sKICB0aGlzLmNpcGhlci5lbmNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gd3JpdGUgb3V0cHV0CiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX291dEJsb2NrW2ldKTsKICB9Cn07Cgptb2Rlcy5lY2IucHJvdG90eXBlLmRlY3J5cHQgPSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBmaW5pc2gpIHsKICAvLyBub3QgZW5vdWdoIGlucHV0IHRvIGRlY3J5cHQKICBpZihpbnB1dC5sZW5ndGgoKSA8IHRoaXMuYmxvY2tTaXplICYmICEoZmluaXNoICYmIGlucHV0Lmxlbmd0aCgpID4gMCkpIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZ2V0IG5leHQgYmxvY2sKICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICB0aGlzLl9pbkJsb2NrW2ldID0gaW5wdXQuZ2V0SW50MzIoKTsKICB9CgogIC8vIGRlY3J5cHQgYmxvY2sKICB0aGlzLmNpcGhlci5kZWNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gd3JpdGUgb3V0cHV0CiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX291dEJsb2NrW2ldKTsKICB9Cn07Cgptb2Rlcy5lY2IucHJvdG90eXBlLnBhZCA9IGZ1bmN0aW9uKGlucHV0LCBvcHRpb25zKSB7CiAgLy8gYWRkIFBLQ1MjNyBwYWRkaW5nIHRvIGJsb2NrIChlYWNoIHBhZCBieXRlIGlzIHRoZQogIC8vIHZhbHVlIG9mIHRoZSBudW1iZXIgb2YgcGFkIGJ5dGVzKQogIHZhciBwYWRkaW5nID0gKGlucHV0Lmxlbmd0aCgpID09PSB0aGlzLmJsb2NrU2l6ZSA/CiAgICB0aGlzLmJsb2NrU2l6ZSA6ICh0aGlzLmJsb2NrU2l6ZSAtIGlucHV0Lmxlbmd0aCgpKSk7CiAgaW5wdXQuZmlsbFdpdGhCeXRlKHBhZGRpbmcsIHBhZGRpbmcpOwogIHJldHVybiB0cnVlOwp9OwoKbW9kZXMuZWNiLnByb3RvdHlwZS51bnBhZCA9IGZ1bmN0aW9uKG91dHB1dCwgb3B0aW9ucykgewogIC8vIGNoZWNrIGZvciBlcnJvcjogaW5wdXQgZGF0YSBub3QgYSBtdWx0aXBsZSBvZiBibG9ja1NpemUKICBpZihvcHRpb25zLm92ZXJmbG93ID4gMCkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgLy8gZW5zdXJlIHBhZGRpbmcgYnl0ZSBjb3VudCBpcyB2YWxpZAogIHZhciBsZW4gPSBvdXRwdXQubGVuZ3RoKCk7CiAgdmFyIGNvdW50ID0gb3V0cHV0LmF0KGxlbiAtIDEpOwogIGlmKGNvdW50ID4gKHRoaXMuYmxvY2tTaXplIDw8IDIpKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQoKICAvLyB0cmltIG9mZiBwYWRkaW5nIGJ5dGVzCiAgb3V0cHV0LnRydW5jYXRlKGNvdW50KTsKICByZXR1cm4gdHJ1ZTsKfTsKCgovKiogQ2lwaGVyLWJsb2NrIENoYWluaW5nIChDQkMpICoqLwoKbW9kZXMuY2JjID0gZnVuY3Rpb24ob3B0aW9ucykgewogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIHRoaXMubmFtZSA9ICdDQkMnOwogIHRoaXMuY2lwaGVyID0gb3B0aW9ucy5jaXBoZXI7CiAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLmJsb2NrU2l6ZSB8fCAxNjsKICB0aGlzLl9pbnRzID0gdGhpcy5ibG9ja1NpemUgLyA0OwogIHRoaXMuX2luQmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5fb3V0QmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7Cn07Cgptb2Rlcy5jYmMucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24ob3B0aW9ucykgewogIC8vIE5vdGU6IGxlZ2FjeSBzdXBwb3J0IGZvciB1c2luZyBJViByZXNpZHVlIChoYXMgc2VjdXJpdHkgZmxhd3MpCiAgLy8gaWYgSVYgaXMgbnVsbCwgcmV1c2UgYmxvY2sgZnJvbSBwcmV2aW91cyBwcm9jZXNzaW5nCiAgaWYob3B0aW9ucy5pdiA9PT0gbnVsbCkgewogICAgLy8gbXVzdCBoYXZlIGEgcHJldmlvdXMgYmxvY2sKICAgIGlmKCF0aGlzLl9wcmV2KSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBJViBwYXJhbWV0ZXIuJyk7CiAgICB9CiAgICB0aGlzLl9pdiA9IHRoaXMuX3ByZXYuc2xpY2UoMCk7CiAgfSBlbHNlIGlmKCEoJ2l2JyBpbiBvcHRpb25zKSkgewogICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIElWIHBhcmFtZXRlci4nKTsKICB9IGVsc2UgewogICAgLy8gc2F2ZSBJViBhcyAicHJldmlvdXMiIGJsb2NrCiAgICB0aGlzLl9pdiA9IHRyYW5zZm9ybUlWKG9wdGlvbnMuaXYpOwogICAgdGhpcy5fcHJldiA9IHRoaXMuX2l2LnNsaWNlKDApOwogIH0KfTsKCm1vZGVzLmNiYy5wcm90b3R5cGUuZW5jcnlwdCA9IGZ1bmN0aW9uKGlucHV0LCBvdXRwdXQsIGZpbmlzaCkgewogIC8vIG5vdCBlbm91Z2ggaW5wdXQgdG8gZW5jcnlwdAogIGlmKGlucHV0Lmxlbmd0aCgpIDwgdGhpcy5ibG9ja1NpemUgJiYgIShmaW5pc2ggJiYgaW5wdXQubGVuZ3RoKCkgPiAwKSkgewogICAgcmV0dXJuIHRydWU7CiAgfQoKICAvLyBnZXQgbmV4dCBibG9jawogIC8vIENCQyBYT1IncyBJViAob3IgcHJldmlvdXMgYmxvY2spIHdpdGggcGxhaW50ZXh0CiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgdGhpcy5faW5CbG9ja1tpXSA9IHRoaXMuX3ByZXZbaV0gXiBpbnB1dC5nZXRJbnQzMigpOwogIH0KCiAgLy8gZW5jcnlwdCBibG9jawogIHRoaXMuY2lwaGVyLmVuY3J5cHQodGhpcy5faW5CbG9jaywgdGhpcy5fb3V0QmxvY2spOwoKICAvLyB3cml0ZSBvdXRwdXQsIHNhdmUgcHJldmlvdXMgYmxvY2sKICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICBvdXRwdXQucHV0SW50MzIodGhpcy5fb3V0QmxvY2tbaV0pOwogIH0KICB0aGlzLl9wcmV2ID0gdGhpcy5fb3V0QmxvY2s7Cn07Cgptb2Rlcy5jYmMucHJvdG90eXBlLmRlY3J5cHQgPSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBmaW5pc2gpIHsKICAvLyBub3QgZW5vdWdoIGlucHV0IHRvIGRlY3J5cHQKICBpZihpbnB1dC5sZW5ndGgoKSA8IHRoaXMuYmxvY2tTaXplICYmICEoZmluaXNoICYmIGlucHV0Lmxlbmd0aCgpID4gMCkpIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZ2V0IG5leHQgYmxvY2sKICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICB0aGlzLl9pbkJsb2NrW2ldID0gaW5wdXQuZ2V0SW50MzIoKTsKICB9CgogIC8vIGRlY3J5cHQgYmxvY2sKICB0aGlzLmNpcGhlci5kZWNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gd3JpdGUgb3V0cHV0LCBzYXZlIHByZXZpb3VzIGNpcGhlcmVkIGJsb2NrCiAgLy8gQ0JDIFhPUidzIElWIChvciBwcmV2aW91cyBibG9jaykgd2l0aCBjaXBoZXJ0ZXh0CiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX3ByZXZbaV0gXiB0aGlzLl9vdXRCbG9ja1tpXSk7CiAgfQogIHRoaXMuX3ByZXYgPSB0aGlzLl9pbkJsb2NrLnNsaWNlKDApOwp9OwoKbW9kZXMuY2JjLnByb3RvdHlwZS5wYWQgPSBmdW5jdGlvbihpbnB1dCwgb3B0aW9ucykgewogIC8vIGFkZCBQS0NTIzcgcGFkZGluZyB0byBibG9jayAoZWFjaCBwYWQgYnl0ZSBpcyB0aGUKICAvLyB2YWx1ZSBvZiB0aGUgbnVtYmVyIG9mIHBhZCBieXRlcykKICB2YXIgcGFkZGluZyA9IChpbnB1dC5sZW5ndGgoKSA9PT0gdGhpcy5ibG9ja1NpemUgPwogICAgdGhpcy5ibG9ja1NpemUgOiAodGhpcy5ibG9ja1NpemUgLSBpbnB1dC5sZW5ndGgoKSkpOwogIGlucHV0LmZpbGxXaXRoQnl0ZShwYWRkaW5nLCBwYWRkaW5nKTsKICByZXR1cm4gdHJ1ZTsKfTsKCm1vZGVzLmNiYy5wcm90b3R5cGUudW5wYWQgPSBmdW5jdGlvbihvdXRwdXQsIG9wdGlvbnMpIHsKICAvLyBjaGVjayBmb3IgZXJyb3I6IGlucHV0IGRhdGEgbm90IGEgbXVsdGlwbGUgb2YgYmxvY2tTaXplCiAgaWYob3B0aW9ucy5vdmVyZmxvdyA+IDApIHsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIC8vIGVuc3VyZSBwYWRkaW5nIGJ5dGUgY291bnQgaXMgdmFsaWQKICB2YXIgbGVuID0gb3V0cHV0Lmxlbmd0aCgpOwogIHZhciBjb3VudCA9IG91dHB1dC5hdChsZW4gLSAxKTsKICBpZihjb3VudCA+ICh0aGlzLmJsb2NrU2l6ZSA8PCAyKSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgLy8gdHJpbSBvZmYgcGFkZGluZyBieXRlcwogIG91dHB1dC50cnVuY2F0ZShjb3VudCk7CiAgcmV0dXJuIHRydWU7Cn07CgoKLyoqIENpcGhlciBmZWVkYmFjayAoQ0ZCKSAqKi8KCm1vZGVzLmNmYiA9IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICB0aGlzLm5hbWUgPSAnQ0ZCJzsKICB0aGlzLmNpcGhlciA9IG9wdGlvbnMuY2lwaGVyOwogIHRoaXMuYmxvY2tTaXplID0gb3B0aW9ucy5ibG9ja1NpemUgfHwgMTY7CiAgdGhpcy5faW50cyA9IHRoaXMuYmxvY2tTaXplIC8gNDsKICB0aGlzLl9pbkJsb2NrID0gbnVsbDsKICB0aGlzLl9vdXRCbG9jayA9IG5ldyBBcnJheSh0aGlzLl9pbnRzKTsKICB0aGlzLl9wYXJ0aWFsQmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5fcGFydGlhbE91dHB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKfTsKCm1vZGVzLmNmYi5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgaWYoISgnaXYnIGluIG9wdGlvbnMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgSVYgcGFyYW1ldGVyLicpOwogIH0KICAvLyB1c2UgSVYgYXMgZmlyc3QgaW5wdXQKICB0aGlzLl9pdiA9IHRyYW5zZm9ybUlWKG9wdGlvbnMuaXYpOwogIHRoaXMuX2luQmxvY2sgPSB0aGlzLl9pdi5zbGljZSgwKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwp9OwoKbW9kZXMuY2ZiLnByb3RvdHlwZS5lbmNyeXB0ID0gZnVuY3Rpb24oaW5wdXQsIG91dHB1dCwgZmluaXNoKSB7CiAgLy8gbm90IGVub3VnaCBpbnB1dCB0byBlbmNyeXB0CiAgdmFyIGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoKCk7CiAgaWYoaW5wdXRMZW5ndGggPT09IDApIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZW5jcnlwdCBibG9jawogIHRoaXMuY2lwaGVyLmVuY3J5cHQodGhpcy5faW5CbG9jaywgdGhpcy5fb3V0QmxvY2spOwoKICAvLyBoYW5kbGUgZnVsbCBibG9jawogIGlmKHRoaXMuX3BhcnRpYWxCeXRlcyA9PT0gMCAmJiBpbnB1dExlbmd0aCA+PSB0aGlzLmJsb2NrU2l6ZSkgewogICAgLy8gWE9SIGlucHV0IHdpdGggb3V0cHV0LCB3cml0ZSBpbnB1dCBhcyBvdXRwdXQKICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgICAgdGhpcy5faW5CbG9ja1tpXSA9IGlucHV0LmdldEludDMyKCkgXiB0aGlzLl9vdXRCbG9ja1tpXTsKICAgICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX2luQmxvY2tbaV0pOwogICAgfQogICAgcmV0dXJuOwogIH0KCiAgLy8gaGFuZGxlIHBhcnRpYWwgYmxvY2sKICB2YXIgcGFydGlhbEJ5dGVzID0gKHRoaXMuYmxvY2tTaXplIC0gaW5wdXRMZW5ndGgpICUgdGhpcy5ibG9ja1NpemU7CiAgaWYocGFydGlhbEJ5dGVzID4gMCkgewogICAgcGFydGlhbEJ5dGVzID0gdGhpcy5ibG9ja1NpemUgLSBwYXJ0aWFsQnl0ZXM7CiAgfQoKICAvLyBYT1IgaW5wdXQgd2l0aCBvdXRwdXQsIHdyaXRlIGlucHV0IGFzIHBhcnRpYWwgb3V0cHV0CiAgdGhpcy5fcGFydGlhbE91dHB1dC5jbGVhcigpOwogIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgIHRoaXMuX3BhcnRpYWxCbG9ja1tpXSA9IGlucHV0LmdldEludDMyKCkgXiB0aGlzLl9vdXRCbG9ja1tpXTsKICAgIHRoaXMuX3BhcnRpYWxPdXRwdXQucHV0SW50MzIodGhpcy5fcGFydGlhbEJsb2NrW2ldKTsKICB9CgogIGlmKHBhcnRpYWxCeXRlcyA+IDApIHsKICAgIC8vIGJsb2NrIHN0aWxsIGluY29tcGxldGUsIHJlc3RvcmUgaW5wdXQgYnVmZmVyCiAgICBpbnB1dC5yZWFkIC09IHRoaXMuYmxvY2tTaXplOwogIH0gZWxzZSB7CiAgICAvLyBibG9jayBjb21wbGV0ZSwgdXBkYXRlIGlucHV0IGJsb2NrCiAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICAgIHRoaXMuX2luQmxvY2tbaV0gPSB0aGlzLl9wYXJ0aWFsQmxvY2tbaV07CiAgICB9CiAgfQoKICAvLyBza2lwIGFueSBwcmV2aW91cyBwYXJ0aWFsIGJ5dGVzCiAgaWYodGhpcy5fcGFydGlhbEJ5dGVzID4gMCkgewogICAgdGhpcy5fcGFydGlhbE91dHB1dC5nZXRCeXRlcyh0aGlzLl9wYXJ0aWFsQnl0ZXMpOwogIH0KCiAgaWYocGFydGlhbEJ5dGVzID4gMCAmJiAhZmluaXNoKSB7CiAgICBvdXRwdXQucHV0Qnl0ZXModGhpcy5fcGFydGlhbE91dHB1dC5nZXRCeXRlcygKICAgICAgcGFydGlhbEJ5dGVzIC0gdGhpcy5fcGFydGlhbEJ5dGVzKSk7CiAgICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSBwYXJ0aWFsQnl0ZXM7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgaW5wdXRMZW5ndGggLSB0aGlzLl9wYXJ0aWFsQnl0ZXMpKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwp9OwoKbW9kZXMuY2ZiLnByb3RvdHlwZS5kZWNyeXB0ID0gZnVuY3Rpb24oaW5wdXQsIG91dHB1dCwgZmluaXNoKSB7CiAgLy8gbm90IGVub3VnaCBpbnB1dCB0byBkZWNyeXB0CiAgdmFyIGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoKCk7CiAgaWYoaW5wdXRMZW5ndGggPT09IDApIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZW5jcnlwdCBibG9jayAoQ0ZCIGFsd2F5cyB1c2VzIGVuY3J5cHRpb24gbW9kZSkKICB0aGlzLmNpcGhlci5lbmNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gaGFuZGxlIGZ1bGwgYmxvY2sKICBpZih0aGlzLl9wYXJ0aWFsQnl0ZXMgPT09IDAgJiYgaW5wdXRMZW5ndGggPj0gdGhpcy5ibG9ja1NpemUpIHsKICAgIC8vIFhPUiBpbnB1dCB3aXRoIG91dHB1dCwgd3JpdGUgaW5wdXQgYXMgb3V0cHV0CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICAgIHRoaXMuX2luQmxvY2tbaV0gPSBpbnB1dC5nZXRJbnQzMigpOwogICAgICBvdXRwdXQucHV0SW50MzIodGhpcy5faW5CbG9ja1tpXSBeIHRoaXMuX291dEJsb2NrW2ldKTsKICAgIH0KICAgIHJldHVybjsKICB9CgogIC8vIGhhbmRsZSBwYXJ0aWFsIGJsb2NrCiAgdmFyIHBhcnRpYWxCeXRlcyA9ICh0aGlzLmJsb2NrU2l6ZSAtIGlucHV0TGVuZ3RoKSAlIHRoaXMuYmxvY2tTaXplOwogIGlmKHBhcnRpYWxCeXRlcyA+IDApIHsKICAgIHBhcnRpYWxCeXRlcyA9IHRoaXMuYmxvY2tTaXplIC0gcGFydGlhbEJ5dGVzOwogIH0KCiAgLy8gWE9SIGlucHV0IHdpdGggb3V0cHV0LCB3cml0ZSBpbnB1dCBhcyBwYXJ0aWFsIG91dHB1dAogIHRoaXMuX3BhcnRpYWxPdXRwdXQuY2xlYXIoKTsKICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICB0aGlzLl9wYXJ0aWFsQmxvY2tbaV0gPSBpbnB1dC5nZXRJbnQzMigpOwogICAgdGhpcy5fcGFydGlhbE91dHB1dC5wdXRJbnQzMih0aGlzLl9wYXJ0aWFsQmxvY2tbaV0gXiB0aGlzLl9vdXRCbG9ja1tpXSk7CiAgfQoKICBpZihwYXJ0aWFsQnl0ZXMgPiAwKSB7CiAgICAvLyBibG9jayBzdGlsbCBpbmNvbXBsZXRlLCByZXN0b3JlIGlucHV0IGJ1ZmZlcgogICAgaW5wdXQucmVhZCAtPSB0aGlzLmJsb2NrU2l6ZTsKICB9IGVsc2UgewogICAgLy8gYmxvY2sgY29tcGxldGUsIHVwZGF0ZSBpbnB1dCBibG9jawogICAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgICB0aGlzLl9pbkJsb2NrW2ldID0gdGhpcy5fcGFydGlhbEJsb2NrW2ldOwogICAgfQogIH0KCiAgLy8gc2tpcCBhbnkgcHJldmlvdXMgcGFydGlhbCBieXRlcwogIGlmKHRoaXMuX3BhcnRpYWxCeXRlcyA+IDApIHsKICAgIHRoaXMuX3BhcnRpYWxPdXRwdXQuZ2V0Qnl0ZXModGhpcy5fcGFydGlhbEJ5dGVzKTsKICB9CgogIGlmKHBhcnRpYWxCeXRlcyA+IDAgJiYgIWZpbmlzaCkgewogICAgb3V0cHV0LnB1dEJ5dGVzKHRoaXMuX3BhcnRpYWxPdXRwdXQuZ2V0Qnl0ZXMoCiAgICAgIHBhcnRpYWxCeXRlcyAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogICAgdGhpcy5fcGFydGlhbEJ5dGVzID0gcGFydGlhbEJ5dGVzOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICBvdXRwdXQucHV0Qnl0ZXModGhpcy5fcGFydGlhbE91dHB1dC5nZXRCeXRlcygKICAgIGlucHV0TGVuZ3RoIC0gdGhpcy5fcGFydGlhbEJ5dGVzKSk7CiAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKfTsKCi8qKiBPdXRwdXQgZmVlZGJhY2sgKE9GQikgKiovCgptb2Rlcy5vZmIgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdGhpcy5uYW1lID0gJ09GQic7CiAgdGhpcy5jaXBoZXIgPSBvcHRpb25zLmNpcGhlcjsKICB0aGlzLmJsb2NrU2l6ZSA9IG9wdGlvbnMuYmxvY2tTaXplIHx8IDE2OwogIHRoaXMuX2ludHMgPSB0aGlzLmJsb2NrU2l6ZSAvIDQ7CiAgdGhpcy5faW5CbG9jayA9IG51bGw7CiAgdGhpcy5fb3V0QmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5fcGFydGlhbE91dHB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKfTsKCm1vZGVzLm9mYi5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgaWYoISgnaXYnIGluIG9wdGlvbnMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgSVYgcGFyYW1ldGVyLicpOwogIH0KICAvLyB1c2UgSVYgYXMgZmlyc3QgaW5wdXQKICB0aGlzLl9pdiA9IHRyYW5zZm9ybUlWKG9wdGlvbnMuaXYpOwogIHRoaXMuX2luQmxvY2sgPSB0aGlzLl9pdi5zbGljZSgwKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwp9OwoKbW9kZXMub2ZiLnByb3RvdHlwZS5lbmNyeXB0ID0gZnVuY3Rpb24oaW5wdXQsIG91dHB1dCwgZmluaXNoKSB7CiAgLy8gbm90IGVub3VnaCBpbnB1dCB0byBlbmNyeXB0CiAgdmFyIGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoKCk7CiAgaWYoaW5wdXQubGVuZ3RoKCkgPT09IDApIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZW5jcnlwdCBibG9jayAoT0ZCIGFsd2F5cyB1c2VzIGVuY3J5cHRpb24gbW9kZSkKICB0aGlzLmNpcGhlci5lbmNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gaGFuZGxlIGZ1bGwgYmxvY2sKICBpZih0aGlzLl9wYXJ0aWFsQnl0ZXMgPT09IDAgJiYgaW5wdXRMZW5ndGggPj0gdGhpcy5ibG9ja1NpemUpIHsKICAgIC8vIFhPUiBpbnB1dCB3aXRoIG91dHB1dCBhbmQgdXBkYXRlIG5leHQgaW5wdXQKICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgICAgb3V0cHV0LnB1dEludDMyKGlucHV0LmdldEludDMyKCkgXiB0aGlzLl9vdXRCbG9ja1tpXSk7CiAgICAgIHRoaXMuX2luQmxvY2tbaV0gPSB0aGlzLl9vdXRCbG9ja1tpXTsKICAgIH0KICAgIHJldHVybjsKICB9CgogIC8vIGhhbmRsZSBwYXJ0aWFsIGJsb2NrCiAgdmFyIHBhcnRpYWxCeXRlcyA9ICh0aGlzLmJsb2NrU2l6ZSAtIGlucHV0TGVuZ3RoKSAlIHRoaXMuYmxvY2tTaXplOwogIGlmKHBhcnRpYWxCeXRlcyA+IDApIHsKICAgIHBhcnRpYWxCeXRlcyA9IHRoaXMuYmxvY2tTaXplIC0gcGFydGlhbEJ5dGVzOwogIH0KCiAgLy8gWE9SIGlucHV0IHdpdGggb3V0cHV0CiAgdGhpcy5fcGFydGlhbE91dHB1dC5jbGVhcigpOwogIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgIHRoaXMuX3BhcnRpYWxPdXRwdXQucHV0SW50MzIoaW5wdXQuZ2V0SW50MzIoKSBeIHRoaXMuX291dEJsb2NrW2ldKTsKICB9CgogIGlmKHBhcnRpYWxCeXRlcyA+IDApIHsKICAgIC8vIGJsb2NrIHN0aWxsIGluY29tcGxldGUsIHJlc3RvcmUgaW5wdXQgYnVmZmVyCiAgICBpbnB1dC5yZWFkIC09IHRoaXMuYmxvY2tTaXplOwogIH0gZWxzZSB7CiAgICAvLyBibG9jayBjb21wbGV0ZSwgdXBkYXRlIGlucHV0IGJsb2NrCiAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICAgIHRoaXMuX2luQmxvY2tbaV0gPSB0aGlzLl9vdXRCbG9ja1tpXTsKICAgIH0KICB9CgogIC8vIHNraXAgYW55IHByZXZpb3VzIHBhcnRpYWwgYnl0ZXMKICBpZih0aGlzLl9wYXJ0aWFsQnl0ZXMgPiAwKSB7CiAgICB0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKHRoaXMuX3BhcnRpYWxCeXRlcyk7CiAgfQoKICBpZihwYXJ0aWFsQnl0ZXMgPiAwICYmICFmaW5pc2gpIHsKICAgIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgICBwYXJ0aWFsQnl0ZXMgLSB0aGlzLl9wYXJ0aWFsQnl0ZXMpKTsKICAgIHRoaXMuX3BhcnRpYWxCeXRlcyA9IHBhcnRpYWxCeXRlczsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgb3V0cHV0LnB1dEJ5dGVzKHRoaXMuX3BhcnRpYWxPdXRwdXQuZ2V0Qnl0ZXMoCiAgICBpbnB1dExlbmd0aCAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogIHRoaXMuX3BhcnRpYWxCeXRlcyA9IDA7Cn07Cgptb2Rlcy5vZmIucHJvdG90eXBlLmRlY3J5cHQgPSBtb2Rlcy5vZmIucHJvdG90eXBlLmVuY3J5cHQ7CgoKLyoqIENvdW50ZXIgKENUUikgKiovCgptb2Rlcy5jdHIgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdGhpcy5uYW1lID0gJ0NUUic7CiAgdGhpcy5jaXBoZXIgPSBvcHRpb25zLmNpcGhlcjsKICB0aGlzLmJsb2NrU2l6ZSA9IG9wdGlvbnMuYmxvY2tTaXplIHx8IDE2OwogIHRoaXMuX2ludHMgPSB0aGlzLmJsb2NrU2l6ZSAvIDQ7CiAgdGhpcy5faW5CbG9jayA9IG51bGw7CiAgdGhpcy5fb3V0QmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5fcGFydGlhbE91dHB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKfTsKCm1vZGVzLmN0ci5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgaWYoISgnaXYnIGluIG9wdGlvbnMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgSVYgcGFyYW1ldGVyLicpOwogIH0KICAvLyB1c2UgSVYgYXMgZmlyc3QgaW5wdXQKICB0aGlzLl9pdiA9IHRyYW5zZm9ybUlWKG9wdGlvbnMuaXYpOwogIHRoaXMuX2luQmxvY2sgPSB0aGlzLl9pdi5zbGljZSgwKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwp9OwoKbW9kZXMuY3RyLnByb3RvdHlwZS5lbmNyeXB0ID0gZnVuY3Rpb24oaW5wdXQsIG91dHB1dCwgZmluaXNoKSB7CiAgLy8gbm90IGVub3VnaCBpbnB1dCB0byBlbmNyeXB0CiAgdmFyIGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoKCk7CiAgaWYoaW5wdXRMZW5ndGggPT09IDApIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZW5jcnlwdCBibG9jayAoQ1RSIGFsd2F5cyB1c2VzIGVuY3J5cHRpb24gbW9kZSkKICB0aGlzLmNpcGhlci5lbmNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gaGFuZGxlIGZ1bGwgYmxvY2sKICBpZih0aGlzLl9wYXJ0aWFsQnl0ZXMgPT09IDAgJiYgaW5wdXRMZW5ndGggPj0gdGhpcy5ibG9ja1NpemUpIHsKICAgIC8vIFhPUiBpbnB1dCB3aXRoIG91dHB1dAogICAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgICBvdXRwdXQucHV0SW50MzIoaW5wdXQuZ2V0SW50MzIoKSBeIHRoaXMuX291dEJsb2NrW2ldKTsKICAgIH0KICB9IGVsc2UgewogICAgLy8gaGFuZGxlIHBhcnRpYWwgYmxvY2sKICAgIHZhciBwYXJ0aWFsQnl0ZXMgPSAodGhpcy5ibG9ja1NpemUgLSBpbnB1dExlbmd0aCkgJSB0aGlzLmJsb2NrU2l6ZTsKICAgIGlmKHBhcnRpYWxCeXRlcyA+IDApIHsKICAgICAgcGFydGlhbEJ5dGVzID0gdGhpcy5ibG9ja1NpemUgLSBwYXJ0aWFsQnl0ZXM7CiAgICB9CgogICAgLy8gWE9SIGlucHV0IHdpdGggb3V0cHV0CiAgICB0aGlzLl9wYXJ0aWFsT3V0cHV0LmNsZWFyKCk7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICAgIHRoaXMuX3BhcnRpYWxPdXRwdXQucHV0SW50MzIoaW5wdXQuZ2V0SW50MzIoKSBeIHRoaXMuX291dEJsb2NrW2ldKTsKICAgIH0KCiAgICBpZihwYXJ0aWFsQnl0ZXMgPiAwKSB7CiAgICAgIC8vIGJsb2NrIHN0aWxsIGluY29tcGxldGUsIHJlc3RvcmUgaW5wdXQgYnVmZmVyCiAgICAgIGlucHV0LnJlYWQgLT0gdGhpcy5ibG9ja1NpemU7CiAgICB9CgogICAgLy8gc2tpcCBhbnkgcHJldmlvdXMgcGFydGlhbCBieXRlcwogICAgaWYodGhpcy5fcGFydGlhbEJ5dGVzID4gMCkgewogICAgICB0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKHRoaXMuX3BhcnRpYWxCeXRlcyk7CiAgICB9CgogICAgaWYocGFydGlhbEJ5dGVzID4gMCAmJiAhZmluaXNoKSB7CiAgICAgIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgICAgIHBhcnRpYWxCeXRlcyAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogICAgICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSBwYXJ0aWFsQnl0ZXM7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgICBpbnB1dExlbmd0aCAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogICAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKICB9CgogIC8vIGJsb2NrIGNvbXBsZXRlLCBpbmNyZW1lbnQgY291bnRlciAoaW5wdXQgYmxvY2spCiAgaW5jMzIodGhpcy5faW5CbG9jayk7Cn07Cgptb2Rlcy5jdHIucHJvdG90eXBlLmRlY3J5cHQgPSBtb2Rlcy5jdHIucHJvdG90eXBlLmVuY3J5cHQ7CgoKLyoqIEdhbG9pcy9Db3VudGVyIE1vZGUgKEdDTSkgKiovCgptb2Rlcy5nY20gPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdGhpcy5uYW1lID0gJ0dDTSc7CiAgdGhpcy5jaXBoZXIgPSBvcHRpb25zLmNpcGhlcjsKICB0aGlzLmJsb2NrU2l6ZSA9IG9wdGlvbnMuYmxvY2tTaXplIHx8IDE2OwogIHRoaXMuX2ludHMgPSB0aGlzLmJsb2NrU2l6ZSAvIDQ7CiAgdGhpcy5faW5CbG9jayA9IG5ldyBBcnJheSh0aGlzLl9pbnRzKTsKICB0aGlzLl9vdXRCbG9jayA9IG5ldyBBcnJheSh0aGlzLl9pbnRzKTsKICB0aGlzLl9wYXJ0aWFsT3V0cHV0ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwoKICAvLyBSIGlzIGFjdHVhbGx5IHRoaXMgdmFsdWUgY29uY2F0ZW5hdGVkIHdpdGggMTIwIG1vcmUgemVybyBiaXRzLCBidXQKICAvLyB3ZSBvbmx5IFhPUiBhZ2FpbnN0IFIgc28gdGhlIG90aGVyIHplcm9zIGhhdmUgbm8gZWZmZWN0IC0tIHdlIGp1c3QKICAvLyBhcHBseSB0aGlzIHZhbHVlIHRvIHRoZSBmaXJzdCBpbnRlZ2VyIGluIGEgYmxvY2sKICB0aGlzLl9SID0gMHhFMTAwMDAwMDsKfTsKCm1vZGVzLmdjbS5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgaWYoISgnaXYnIGluIG9wdGlvbnMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgSVYgcGFyYW1ldGVyLicpOwogIH0KICAvLyBlbnN1cmUgSVYgaXMgYSBieXRlIGJ1ZmZlcgogIHZhciBpdiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKG9wdGlvbnMuaXYpOwoKICAvLyBubyBjaXBoZXJlZCBkYXRhIHByb2Nlc3NlZCB5ZXQKICB0aGlzLl9jaXBoZXJMZW5ndGggPSAwOwoKICAvLyBkZWZhdWx0IGFkZGl0aW9uYWwgZGF0YSBpcyBub25lCiAgdmFyIGFkZGl0aW9uYWxEYXRhOwogIGlmKCdhZGRpdGlvbmFsRGF0YScgaW4gb3B0aW9ucykgewogICAgYWRkaXRpb25hbERhdGEgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihvcHRpb25zLmFkZGl0aW9uYWxEYXRhKTsKICB9IGVsc2UgewogICAgYWRkaXRpb25hbERhdGEgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIH0KCiAgLy8gZGVmYXVsdCB0YWcgbGVuZ3RoIGlzIDEyOCBiaXRzCiAgaWYoJ3RhZ0xlbmd0aCcgaW4gb3B0aW9ucykgewogICAgdGhpcy5fdGFnTGVuZ3RoID0gb3B0aW9ucy50YWdMZW5ndGg7CiAgfSBlbHNlIHsKICAgIHRoaXMuX3RhZ0xlbmd0aCA9IDEyODsKICB9CgogIC8vIGlmIHRhZyBpcyBnaXZlbiwgZW5zdXJlIHRhZyBtYXRjaGVzIHRhZyBsZW5ndGgKICB0aGlzLl90YWcgPSBudWxsOwogIGlmKG9wdGlvbnMuZGVjcnlwdCkgewogICAgLy8gc2F2ZSB0YWcgdG8gY2hlY2sgbGF0ZXIKICAgIHRoaXMuX3RhZyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKG9wdGlvbnMudGFnKS5nZXRCeXRlcygpOwogICAgaWYodGhpcy5fdGFnLmxlbmd0aCAhPT0gKHRoaXMuX3RhZ0xlbmd0aCAvIDgpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignQXV0aGVudGljYXRpb24gdGFnIGRvZXMgbm90IG1hdGNoIHRhZyBsZW5ndGguJyk7CiAgICB9CiAgfQoKICAvLyBjcmVhdGUgdG1wIHN0b3JhZ2UgZm9yIGhhc2ggY2FsY3VsYXRpb24KICB0aGlzLl9oYXNoQmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CgogIC8vIG5vIHRhZyBnZW5lcmF0ZWQgeWV0CiAgdGhpcy50YWcgPSBudWxsOwoKICAvLyBnZW5lcmF0ZSBoYXNoIHN1YmtleQogIC8vIChhcHBseSBibG9jayBjaXBoZXIgdG8gInplcm8iIGJsb2NrKQogIHRoaXMuX2hhc2hTdWJrZXkgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5jaXBoZXIuZW5jcnlwdChbMCwgMCwgMCwgMF0sIHRoaXMuX2hhc2hTdWJrZXkpOwoKICAvLyBnZW5lcmF0ZSB0YWJsZSBNCiAgLy8gdXNlIDQtYml0IHRhYmxlcyAoMzIgY29tcG9uZW50IGRlY29tcG9zaXRpb24gb2YgYSAxNiBieXRlIHZhbHVlKQogIC8vIDgtYml0IHRhYmxlcyB0YWtlIG1vcmUgc3BhY2UgYW5kIGFyZSBrbm93biB0byBoYXZlIHNlY3VyaXR5CiAgLy8gdnVsbmVyYWJpbGl0aWVzIChpbiBuYXRpdmUgaW1wbGVtZW50YXRpb25zKQogIHRoaXMuY29tcG9uZW50Qml0cyA9IDQ7CiAgdGhpcy5fbSA9IHRoaXMuZ2VuZXJhdGVIYXNoVGFibGUodGhpcy5faGFzaFN1YmtleSwgdGhpcy5jb21wb25lbnRCaXRzKTsKCiAgLy8gTm90ZTogc3VwcG9ydCBJViBsZW5ndGggZGlmZmVyZW50IGZyb20gOTYgYml0cz8gKG9ubHkgc3VwcG9ydGluZwogIC8vIDk2IGJpdHMgaXMgcmVjb21tZW5kZWQgYnkgTklTVCBTUC04MDAtMzhEKQogIC8vIGdlbmVyYXRlIEpfMAogIHZhciBpdkxlbmd0aCA9IGl2Lmxlbmd0aCgpOwogIGlmKGl2TGVuZ3RoID09PSAxMikgewogICAgLy8gOTYtYml0IElWCiAgICB0aGlzLl9qMCA9IFtpdi5nZXRJbnQzMigpLCBpdi5nZXRJbnQzMigpLCBpdi5nZXRJbnQzMigpLCAxXTsKICB9IGVsc2UgewogICAgLy8gSVYgaXMgTk9UIDk2LWJpdHMKICAgIHRoaXMuX2owID0gWzAsIDAsIDAsIDBdOwogICAgd2hpbGUoaXYubGVuZ3RoKCkgPiAwKSB7CiAgICAgIHRoaXMuX2owID0gdGhpcy5naGFzaCgKICAgICAgICB0aGlzLl9oYXNoU3Via2V5LCB0aGlzLl9qMCwKICAgICAgICBbaXYuZ2V0SW50MzIoKSwgaXYuZ2V0SW50MzIoKSwgaXYuZ2V0SW50MzIoKSwgaXYuZ2V0SW50MzIoKV0pOwogICAgfQogICAgdGhpcy5fajAgPSB0aGlzLmdoYXNoKAogICAgICB0aGlzLl9oYXNoU3Via2V5LCB0aGlzLl9qMCwgWzAsIDBdLmNvbmNhdChmcm9tNjRUbzMyKGl2TGVuZ3RoICogOCkpKTsKICB9CgogIC8vIGdlbmVyYXRlIElDQiAoaW5pdGlhbCBjb3VudGVyIGJsb2NrKQogIHRoaXMuX2luQmxvY2sgPSB0aGlzLl9qMC5zbGljZSgwKTsKICBpbmMzMih0aGlzLl9pbkJsb2NrKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwoKICAvLyBjb25zdW1lIGF1dGhlbnRpY2F0aW9uIGRhdGEKICBhZGRpdGlvbmFsRGF0YSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGFkZGl0aW9uYWxEYXRhKTsKICAvLyBzYXZlIGFkZGl0aW9uYWwgZGF0YSBsZW5ndGggYXMgYSBCRSA2NC1iaXQgbnVtYmVyCiAgdGhpcy5fYURhdGFMZW5ndGggPSBmcm9tNjRUbzMyKGFkZGl0aW9uYWxEYXRhLmxlbmd0aCgpICogOCk7CiAgLy8gcGFkIGFkZGl0aW9uYWwgZGF0YSB0byAxMjggYml0ICgxNiBieXRlKSBibG9jayBzaXplCiAgdmFyIG92ZXJmbG93ID0gYWRkaXRpb25hbERhdGEubGVuZ3RoKCkgJSB0aGlzLmJsb2NrU2l6ZTsKICBpZihvdmVyZmxvdykgewogICAgYWRkaXRpb25hbERhdGEuZmlsbFdpdGhCeXRlKDAsIHRoaXMuYmxvY2tTaXplIC0gb3ZlcmZsb3cpOwogIH0KICB0aGlzLl9zID0gWzAsIDAsIDAsIDBdOwogIHdoaWxlKGFkZGl0aW9uYWxEYXRhLmxlbmd0aCgpID4gMCkgewogICAgdGhpcy5fcyA9IHRoaXMuZ2hhc2godGhpcy5faGFzaFN1YmtleSwgdGhpcy5fcywgWwogICAgICBhZGRpdGlvbmFsRGF0YS5nZXRJbnQzMigpLAogICAgICBhZGRpdGlvbmFsRGF0YS5nZXRJbnQzMigpLAogICAgICBhZGRpdGlvbmFsRGF0YS5nZXRJbnQzMigpLAogICAgICBhZGRpdGlvbmFsRGF0YS5nZXRJbnQzMigpCiAgICBdKTsKICB9Cn07Cgptb2Rlcy5nY20ucHJvdG90eXBlLmVuY3J5cHQgPSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBmaW5pc2gpIHsKICAvLyBub3QgZW5vdWdoIGlucHV0IHRvIGVuY3J5cHQKICB2YXIgaW5wdXRMZW5ndGggPSBpbnB1dC5sZW5ndGgoKTsKICBpZihpbnB1dExlbmd0aCA9PT0gMCkgewogICAgcmV0dXJuIHRydWU7CiAgfQoKICAvLyBlbmNyeXB0IGJsb2NrCiAgdGhpcy5jaXBoZXIuZW5jcnlwdCh0aGlzLl9pbkJsb2NrLCB0aGlzLl9vdXRCbG9jayk7CgogIC8vIGhhbmRsZSBmdWxsIGJsb2NrCiAgaWYodGhpcy5fcGFydGlhbEJ5dGVzID09PSAwICYmIGlucHV0TGVuZ3RoID49IHRoaXMuYmxvY2tTaXplKSB7CiAgICAvLyBYT1IgaW5wdXQgd2l0aCBvdXRwdXQKICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX291dEJsb2NrW2ldIF49IGlucHV0LmdldEludDMyKCkpOwogICAgfQogICAgdGhpcy5fY2lwaGVyTGVuZ3RoICs9IHRoaXMuYmxvY2tTaXplOwogIH0gZWxzZSB7CiAgICAvLyBoYW5kbGUgcGFydGlhbCBibG9jawogICAgdmFyIHBhcnRpYWxCeXRlcyA9ICh0aGlzLmJsb2NrU2l6ZSAtIGlucHV0TGVuZ3RoKSAlIHRoaXMuYmxvY2tTaXplOwogICAgaWYocGFydGlhbEJ5dGVzID4gMCkgewogICAgICBwYXJ0aWFsQnl0ZXMgPSB0aGlzLmJsb2NrU2l6ZSAtIHBhcnRpYWxCeXRlczsKICAgIH0KCiAgICAvLyBYT1IgaW5wdXQgd2l0aCBvdXRwdXQKICAgIHRoaXMuX3BhcnRpYWxPdXRwdXQuY2xlYXIoKTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgICAgdGhpcy5fcGFydGlhbE91dHB1dC5wdXRJbnQzMihpbnB1dC5nZXRJbnQzMigpIF4gdGhpcy5fb3V0QmxvY2tbaV0pOwogICAgfQoKICAgIGlmKHBhcnRpYWxCeXRlcyA9PT0gMCB8fCBmaW5pc2gpIHsKICAgICAgLy8gaGFuZGxlIG92ZXJmbG93IHByaW9yIHRvIGhhc2hpbmcKICAgICAgaWYoZmluaXNoKSB7CiAgICAgICAgLy8gZ2V0IGJsb2NrIG92ZXJmbG93CiAgICAgICAgdmFyIG92ZXJmbG93ID0gaW5wdXRMZW5ndGggJSB0aGlzLmJsb2NrU2l6ZTsKICAgICAgICB0aGlzLl9jaXBoZXJMZW5ndGggKz0gb3ZlcmZsb3c7CiAgICAgICAgLy8gdHJ1bmNhdGUgZm9yIGhhc2ggZnVuY3Rpb24KICAgICAgICB0aGlzLl9wYXJ0aWFsT3V0cHV0LnRydW5jYXRlKHRoaXMuYmxvY2tTaXplIC0gb3ZlcmZsb3cpOwogICAgICB9IGVsc2UgewogICAgICAgIHRoaXMuX2NpcGhlckxlbmd0aCArPSB0aGlzLmJsb2NrU2l6ZTsKICAgICAgfQoKICAgICAgLy8gZ2V0IG91dHB1dCBibG9jayBmb3IgaGFzaGluZwogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICAgICAgdGhpcy5fb3V0QmxvY2tbaV0gPSB0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEludDMyKCk7CiAgICAgIH0KICAgICAgdGhpcy5fcGFydGlhbE91dHB1dC5yZWFkIC09IHRoaXMuYmxvY2tTaXplOwogICAgfQoKICAgIC8vIHNraXAgYW55IHByZXZpb3VzIHBhcnRpYWwgYnl0ZXMKICAgIGlmKHRoaXMuX3BhcnRpYWxCeXRlcyA+IDApIHsKICAgICAgdGhpcy5fcGFydGlhbE91dHB1dC5nZXRCeXRlcyh0aGlzLl9wYXJ0aWFsQnl0ZXMpOwogICAgfQoKICAgIGlmKHBhcnRpYWxCeXRlcyA+IDAgJiYgIWZpbmlzaCkgewogICAgICAvLyBibG9jayBzdGlsbCBpbmNvbXBsZXRlLCByZXN0b3JlIGlucHV0IGJ1ZmZlciwgZ2V0IHBhcnRpYWwgb3V0cHV0LAogICAgICAvLyBhbmQgcmV0dXJuIGVhcmx5CiAgICAgIGlucHV0LnJlYWQgLT0gdGhpcy5ibG9ja1NpemU7CiAgICAgIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgICAgIHBhcnRpYWxCeXRlcyAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogICAgICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSBwYXJ0aWFsQnl0ZXM7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgICBpbnB1dExlbmd0aCAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogICAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKICB9CgogIC8vIHVwZGF0ZSBoYXNoIGJsb2NrIFMKICB0aGlzLl9zID0gdGhpcy5naGFzaCh0aGlzLl9oYXNoU3Via2V5LCB0aGlzLl9zLCB0aGlzLl9vdXRCbG9jayk7CgogIC8vIGluY3JlbWVudCBjb3VudGVyIChpbnB1dCBibG9jaykKICBpbmMzMih0aGlzLl9pbkJsb2NrKTsKfTsKCm1vZGVzLmdjbS5wcm90b3R5cGUuZGVjcnlwdCA9IGZ1bmN0aW9uKGlucHV0LCBvdXRwdXQsIGZpbmlzaCkgewogIC8vIG5vdCBlbm91Z2ggaW5wdXQgdG8gZGVjcnlwdAogIHZhciBpbnB1dExlbmd0aCA9IGlucHV0Lmxlbmd0aCgpOwogIGlmKGlucHV0TGVuZ3RoIDwgdGhpcy5ibG9ja1NpemUgJiYgIShmaW5pc2ggJiYgaW5wdXRMZW5ndGggPiAwKSkgewogICAgcmV0dXJuIHRydWU7CiAgfQoKICAvLyBlbmNyeXB0IGJsb2NrIChHQ00gYWx3YXlzIHVzZXMgZW5jcnlwdGlvbiBtb2RlKQogIHRoaXMuY2lwaGVyLmVuY3J5cHQodGhpcy5faW5CbG9jaywgdGhpcy5fb3V0QmxvY2spOwoKICAvLyBpbmNyZW1lbnQgY291bnRlciAoaW5wdXQgYmxvY2spCiAgaW5jMzIodGhpcy5faW5CbG9jayk7CgogIC8vIHVwZGF0ZSBoYXNoIGJsb2NrIFMKICB0aGlzLl9oYXNoQmxvY2tbMF0gPSBpbnB1dC5nZXRJbnQzMigpOwogIHRoaXMuX2hhc2hCbG9ja1sxXSA9IGlucHV0LmdldEludDMyKCk7CiAgdGhpcy5faGFzaEJsb2NrWzJdID0gaW5wdXQuZ2V0SW50MzIoKTsKICB0aGlzLl9oYXNoQmxvY2tbM10gPSBpbnB1dC5nZXRJbnQzMigpOwogIHRoaXMuX3MgPSB0aGlzLmdoYXNoKHRoaXMuX2hhc2hTdWJrZXksIHRoaXMuX3MsIHRoaXMuX2hhc2hCbG9jayk7CgogIC8vIFhPUiBoYXNoIGlucHV0IHdpdGggb3V0cHV0CiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX291dEJsb2NrW2ldIF4gdGhpcy5faGFzaEJsb2NrW2ldKTsKICB9CgogIC8vIGluY3JlbWVudCBjaXBoZXIgZGF0YSBsZW5ndGgKICBpZihpbnB1dExlbmd0aCA8IHRoaXMuYmxvY2tTaXplKSB7CiAgICB0aGlzLl9jaXBoZXJMZW5ndGggKz0gaW5wdXRMZW5ndGggJSB0aGlzLmJsb2NrU2l6ZTsKICB9IGVsc2UgewogICAgdGhpcy5fY2lwaGVyTGVuZ3RoICs9IHRoaXMuYmxvY2tTaXplOwogIH0KfTsKCm1vZGVzLmdjbS5wcm90b3R5cGUuYWZ0ZXJGaW5pc2ggPSBmdW5jdGlvbihvdXRwdXQsIG9wdGlvbnMpIHsKICB2YXIgcnZhbCA9IHRydWU7CgogIC8vIGhhbmRsZSBvdmVyZmxvdwogIGlmKG9wdGlvbnMuZGVjcnlwdCAmJiBvcHRpb25zLm92ZXJmbG93KSB7CiAgICBvdXRwdXQudHJ1bmNhdGUodGhpcy5ibG9ja1NpemUgLSBvcHRpb25zLm92ZXJmbG93KTsKICB9CgogIC8vIGhhbmRsZSBhdXRoZW50aWNhdGlvbiB0YWcKICB0aGlzLnRhZyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIGNvbmNhdGVuYXRlIGFkZGl0aW9uYWwgZGF0YSBsZW5ndGggd2l0aCBjaXBoZXIgbGVuZ3RoCiAgdmFyIGxlbmd0aHMgPSB0aGlzLl9hRGF0YUxlbmd0aC5jb25jYXQoZnJvbTY0VG8zMih0aGlzLl9jaXBoZXJMZW5ndGggKiA4KSk7CgogIC8vIGluY2x1ZGUgbGVuZ3RocyBpbiBoYXNoCiAgdGhpcy5fcyA9IHRoaXMuZ2hhc2godGhpcy5faGFzaFN1YmtleSwgdGhpcy5fcywgbGVuZ3Rocyk7CgogIC8vIGRvIEdDVFIoSl8wLCBTKQogIHZhciB0YWcgPSBbXTsKICB0aGlzLmNpcGhlci5lbmNyeXB0KHRoaXMuX2owLCB0YWcpOwogIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgIHRoaXMudGFnLnB1dEludDMyKHRoaXMuX3NbaV0gXiB0YWdbaV0pOwogIH0KCiAgLy8gdHJpbSB0YWcgdG8gbGVuZ3RoCiAgdGhpcy50YWcudHJ1bmNhdGUodGhpcy50YWcubGVuZ3RoKCkgJSAodGhpcy5fdGFnTGVuZ3RoIC8gOCkpOwoKICAvLyBjaGVjayBhdXRoZW50aWNhdGlvbiB0YWcKICBpZihvcHRpb25zLmRlY3J5cHQgJiYgdGhpcy50YWcuYnl0ZXMoKSAhPT0gdGhpcy5fdGFnKSB7CiAgICBydmFsID0gZmFsc2U7CiAgfQoKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBTZWUgTklTVCBTUC04MDAtMzhEIDYuMyAoQWxnb3JpdGhtIDEpLiBUaGlzIGZ1bmN0aW9uIHBlcmZvcm1zIEdhbG9pcwogKiBmaWVsZCBtdWx0aXBsaWNhdGlvbi4gVGhlIGZpZWxkLCBHRigyXjEyOCksIGlzIGRlZmluZWQgYnkgdGhlIHBvbHlub21pYWw6CiAqCiAqIHheMTI4ICsgeF43ICsgeF4yICsgeCArIDEKICoKICogV2hpY2ggaXMgcmVwcmVzZW50ZWQgaW4gbGl0dGxlLWVuZGlhbiBiaW5hcnkgZm9ybSBhczogMTExMDAwMDEgKDB4ZTEpLiBXaGVuCiAqIHRoZSB2YWx1ZSBvZiBhIGNvZWZmaWNpZW50IGlzIDEsIGEgYml0IGlzIHNldC4gVGhlIHZhbHVlIFIsIGlzIHRoZQogKiBjb25jYXRlbmF0aW9uIG9mIHRoaXMgdmFsdWUgYW5kIDEyMCB6ZXJvIGJpdHMsIHlpZWxkaW5nIGEgMTI4LWJpdCB2YWx1ZQogKiB3aGljaCBtYXRjaGVzIHRoZSBibG9jayBzaXplLgogKgogKiBUaGlzIGZ1bmN0aW9uIHdpbGwgbXVsdGlwbHkgdHdvIGVsZW1lbnRzICh2ZWN0b3JzIG9mIGJ5dGVzKSwgWCBhbmQgWSwgaW4KICogdGhlIGZpZWxkIEdGKDJeMTI4KS4gVGhlIHJlc3VsdCBpcyBpbml0aWFsaXplZCB0byB6ZXJvLiBGb3IgZWFjaCBiaXQgb2YKICogWCAob3V0IG9mIDEyOCksIHhfaSwgaWYgeF9pIGlzIHNldCwgdGhlbiB0aGUgcmVzdWx0IGlzIG11bHRpcGxpZWQgKFhPUidkKQogKiBieSB0aGUgY3VycmVudCB2YWx1ZSBvZiBZLiBGb3IgZWFjaCBiaXQsIHRoZSB2YWx1ZSBvZiBZIHdpbGwgYmUgcmFpc2VkIGJ5CiAqIGEgcG93ZXIgb2YgeCAobXVsdGlwbGllZCBieSB0aGUgcG9seW5vbWlhbCB4KS4gVGhpcyBjYW4gYmUgYWNoaWV2ZWQgYnkKICogc2hpZnRpbmcgWSBvbmNlIHRvIHRoZSByaWdodC4gSWYgdGhlIGN1cnJlbnQgdmFsdWUgb2YgWSwgcHJpb3IgdG8gYmVpbmcKICogbXVsdGlwbGllZCBieSB4LCBoYXMgMCBhcyBpdHMgTFNCLCB0aGVuIGl0IGlzIGEgMTI3dGggZGVncmVlIHBvbHlub21pYWwuCiAqIE90aGVyd2lzZSwgd2UgbXVzdCBkaXZpZGUgYnkgUiBhZnRlciBzaGlmdGluZyB0byBmaW5kIHRoZSByZW1haW5kZXIuCiAqCiAqIEBwYXJhbSB4IHRoZSBmaXJzdCBibG9jayB0byBtdWx0aXBseSBieSB0aGUgc2Vjb25kLgogKiBAcGFyYW0geSB0aGUgc2Vjb25kIGJsb2NrIHRvIG11bHRpcGx5IGJ5IHRoZSBmaXJzdC4KICoKICogQHJldHVybiB0aGUgYmxvY2sgcmVzdWx0IG9mIHRoZSBtdWx0aXBsaWNhdGlvbi4KICovCm1vZGVzLmdjbS5wcm90b3R5cGUubXVsdGlwbHkgPSBmdW5jdGlvbih4LCB5KSB7CiAgdmFyIHpfaSA9IFswLCAwLCAwLCAwXTsKICB2YXIgdl9pID0geS5zbGljZSgwKTsKCiAgLy8gY2FsY3VsYXRlIFpfMTI4IChibG9jayBoYXMgMTI4IGJpdHMpCiAgZm9yKHZhciBpID0gMDsgaSA8IDEyODsgKytpKSB7CiAgICAvLyBpZiB4X2kgaXMgMCwgWl97aSsxfSA9IFpfaSAodW5jaGFuZ2VkKQogICAgLy8gZWxzZSBaX3tpKzF9ID0gWl9pIF4gVl9pCiAgICAvLyBnZXQgeF9pIGJ5IGZpbmRpbmcgMzItYml0IGludCBwb3NpdGlvbiwgdGhlbiBsZWZ0IHNoaWZ0IDEgYnkgcmVtYWluZGVyCiAgICB2YXIgeF9pID0geFsoaSAvIDMyKSB8IDBdICYgKDEgPDwgKDMxIC0gaSAlIDMyKSk7CiAgICBpZih4X2kpIHsKICAgICAgel9pWzBdIF49IHZfaVswXTsKICAgICAgel9pWzFdIF49IHZfaVsxXTsKICAgICAgel9pWzJdIF49IHZfaVsyXTsKICAgICAgel9pWzNdIF49IHZfaVszXTsKICAgIH0KCiAgICAvLyBpZiBMU0IoVl9pKSBpcyAxLCBWX2kgPSBWX2kgPj4gMQogICAgLy8gZWxzZSBWX2kgPSAoVl9pID4+IDEpIF4gUgogICAgdGhpcy5wb3codl9pLCB2X2kpOwogIH0KCiAgcmV0dXJuIHpfaTsKfTsKCm1vZGVzLmdjbS5wcm90b3R5cGUucG93ID0gZnVuY3Rpb24oeCwgb3V0KSB7CiAgLy8gaWYgTFNCKHgpIGlzIDEsIHggPSB4ID4+PiAxCiAgLy8gZWxzZSB4ID0gKHggPj4+IDEpIF4gUgogIHZhciBsc2IgPSB4WzNdICYgMTsKCiAgLy8gYWx3YXlzIGRvIHggPj4+IDE6CiAgLy8gc3RhcnRpbmcgd2l0aCB0aGUgcmlnaHRtb3N0IGludGVnZXIsIHNoaWZ0IGVhY2ggaW50ZWdlciB0byB0aGUgcmlnaHQKICAvLyBvbmUgYml0LCBwdWxsaW5nIGluIHRoZSBiaXQgZnJvbSB0aGUgaW50ZWdlciB0byB0aGUgbGVmdCBhcyBpdHMgdG9wCiAgLy8gbW9zdCBiaXQgKGRvIHRoaXMgZm9yIHRoZSBsYXN0IDMgaW50ZWdlcnMpCiAgZm9yKHZhciBpID0gMzsgaSA+IDA7IC0taSkgewogICAgb3V0W2ldID0gKHhbaV0gPj4+IDEpIHwgKCh4W2kgLSAxXSAmIDEpIDw8IDMxKTsKICB9CiAgLy8gc2hpZnQgdGhlIGZpcnN0IGludGVnZXIgbm9ybWFsbHkKICBvdXRbMF0gPSB4WzBdID4+PiAxOwoKICAvLyBpZiBsc2Igd2FzIG5vdCBzZXQsIHRoZW4gcG9seW5vbWlhbCBoYWQgYSBkZWdyZWUgb2YgMTI3IGFuZCBkb2Vzbid0CiAgLy8gbmVlZCB0byBkaXZpZGVkOyBvdGhlcndpc2UsIFhPUiB3aXRoIFIgdG8gZmluZCB0aGUgcmVtYWluZGVyOyB3ZSBvbmx5CiAgLy8gbmVlZCB0byBYT1IgdGhlIGZpcnN0IGludGVnZXIgc2luY2UgUiB0ZWNobmljYWxseSBlbmRzIHcvMTIwIHplcm8gYml0cwogIGlmKGxzYikgewogICAgb3V0WzBdIF49IHRoaXMuX1I7CiAgfQp9OwoKbW9kZXMuZ2NtLnByb3RvdHlwZS50YWJsZU11bHRpcGx5ID0gZnVuY3Rpb24oeCkgewogIC8vIGFzc3VtZXMgNC1iaXQgdGFibGVzIGFyZSB1c2VkCiAgdmFyIHogPSBbMCwgMCwgMCwgMF07CiAgZm9yKHZhciBpID0gMDsgaSA8IDMyOyArK2kpIHsKICAgIHZhciBpZHggPSAoaSAvIDgpIHwgMDsKICAgIHZhciB4X2kgPSAoeFtpZHhdID4+PiAoKDcgLSAoaSAlIDgpKSAqIDQpKSAmIDB4RjsKICAgIHZhciBhaCA9IHRoaXMuX21baV1beF9pXTsKICAgIHpbMF0gXj0gYWhbMF07CiAgICB6WzFdIF49IGFoWzFdOwogICAgelsyXSBePSBhaFsyXTsKICAgIHpbM10gXj0gYWhbM107CiAgfQogIHJldHVybiB6Owp9OwoKLyoqCiAqIEEgY29udGludWluZyB2ZXJzaW9uIG9mIHRoZSBHSEFTSCBhbGdvcml0aG0gdGhhdCBvcGVyYXRlcyBvbiBhIHNpbmdsZQogKiBibG9jay4gVGhlIGhhc2ggYmxvY2ssIGxhc3QgaGFzaCB2YWx1ZSAoWW0pIGFuZCB0aGUgbmV3IGJsb2NrIHRvIGhhc2gKICogYXJlIGdpdmVuLgogKgogKiBAcGFyYW0gaCB0aGUgaGFzaCBibG9jay4KICogQHBhcmFtIHkgdGhlIHByZXZpb3VzIHZhbHVlIGZvciBZbSwgdXNlIFswLCAwLCAwLCAwXSBmb3IgYSBuZXcgaGFzaC4KICogQHBhcmFtIHggdGhlIGJsb2NrIHRvIGhhc2guCiAqCiAqIEByZXR1cm4gdGhlIGhhc2hlZCB2YWx1ZSAoWW0pLgogKi8KbW9kZXMuZ2NtLnByb3RvdHlwZS5naGFzaCA9IGZ1bmN0aW9uKGgsIHksIHgpIHsKICB5WzBdIF49IHhbMF07CiAgeVsxXSBePSB4WzFdOwogIHlbMl0gXj0geFsyXTsKICB5WzNdIF49IHhbM107CiAgcmV0dXJuIHRoaXMudGFibGVNdWx0aXBseSh5KTsKICAvL3JldHVybiB0aGlzLm11bHRpcGx5KHksIGgpOwp9OwoKLyoqCiAqIFByZWNvbXB1dGVzIGEgdGFibGUgZm9yIG11bHRpcGx5aW5nIGFnYWluc3QgdGhlIGhhc2ggc3Via2V5LiBUaGlzCiAqIG1lY2hhbmlzbSBwcm92aWRlcyBhIHN1YnN0YW50aWFsIHNwZWVkIGluY3JlYXNlIG92ZXIgbXVsdGlwbGljYXRpb24KICogcGVyZm9ybWVkIHdpdGhvdXQgYSB0YWJsZS4gVGhlIHRhYmxlLWJhc2VkIG11bHRpcGxpY2F0aW9uIHRoaXMgdGFibGUgaXMKICogZm9yIHNvbHZlcyBYICogSCBieSBtdWx0aXBseWluZyBlYWNoIGNvbXBvbmVudCBvZiBYIGJ5IEggYW5kIHRoZW4KICogY29tcG9zaW5nIHRoZSByZXN1bHRzIHRvZ2V0aGVyIHVzaW5nIFhPUi4KICoKICogVGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZW5lcmF0ZSB0YWJsZXMgd2l0aCBkaWZmZXJlbnQgYml0IHNpemVzCiAqIGZvciB0aGUgY29tcG9uZW50cywgaG93ZXZlciwgdGhpcyBpbXBsZW1lbnRhdGlvbiBhc3N1bWVzIHRoZXJlIGFyZQogKiAzMiBjb21wb25lbnRzIG9mIFggKHdoaWNoIGlzIGEgMTYgYnl0ZSB2ZWN0b3IpLCB0aGVyZWZvcmUgZWFjaCBjb21wb25lbnQKICogdGFrZXMgNC1iaXRzIChzbyB0aGUgdGFibGUgaXMgY29uc3RydWN0ZWQgd2l0aCBiaXRzPTQpLgogKgogKiBAcGFyYW0gaCB0aGUgaGFzaCBzdWJrZXkuCiAqIEBwYXJhbSBiaXRzIHRoZSBiaXQgc2l6ZSBmb3IgYSBjb21wb25lbnQuCiAqLwptb2Rlcy5nY20ucHJvdG90eXBlLmdlbmVyYXRlSGFzaFRhYmxlID0gZnVuY3Rpb24oaCwgYml0cykgewogIC8vIFRPRE86IFRoZXJlIGFyZSBmdXJ0aGVyIG9wdGltaXphdGlvbnMgdGhhdCB3b3VsZCB1c2Ugb25seSB0aGUKICAvLyBmaXJzdCB0YWJsZSBNXzAgKG9yIHNvbWUgdmFyaWFudCkgYWxvbmcgd2l0aCBhIHJlbWFpbmRlciB0YWJsZTsKICAvLyB0aGlzIGNhbiBiZSBleHBsb3JlZCBpbiB0aGUgZnV0dXJlCiAgdmFyIG11bHRpcGxpZXIgPSA4IC8gYml0czsKICB2YXIgcGVySW50ID0gNCAqIG11bHRpcGxpZXI7CiAgdmFyIHNpemUgPSAxNiAqIG11bHRpcGxpZXI7CiAgdmFyIG0gPSBuZXcgQXJyYXkoc2l6ZSk7CiAgZm9yKHZhciBpID0gMDsgaSA8IHNpemU7ICsraSkgewogICAgdmFyIHRtcCA9IFswLCAwLCAwLCAwXTsKICAgIHZhciBpZHggPSAoaSAvIHBlckludCkgfCAwOwogICAgdmFyIHNoZnQgPSAoKHBlckludCAtIDEgLSAoaSAlIHBlckludCkpICogYml0cyk7CiAgICB0bXBbaWR4XSA9ICgxIDw8IChiaXRzIC0gMSkpIDw8IHNoZnQ7CiAgICBtW2ldID0gdGhpcy5nZW5lcmF0ZVN1Ykhhc2hUYWJsZSh0aGlzLm11bHRpcGx5KHRtcCwgaCksIGJpdHMpOwogIH0KICByZXR1cm4gbTsKfTsKCi8qKgogKiBHZW5lcmF0ZXMgYSB0YWJsZSBmb3IgbXVsdGlwbHlpbmcgYWdhaW5zdCB0aGUgaGFzaCBzdWJrZXkgZm9yIG9uZQogKiBwYXJ0aWN1bGFyIGNvbXBvbmVudCAob3V0IG9mIGFsbCBwb3NzaWJsZSBjb21wb25lbnQgdmFsdWVzKS4KICoKICogQHBhcmFtIG1pZCB0aGUgcHJlLW11bHRpcGxpZWQgdmFsdWUgZm9yIHRoZSBtaWRkbGUga2V5IG9mIHRoZSB0YWJsZS4KICogQHBhcmFtIGJpdHMgdGhlIGJpdCBzaXplIGZvciBhIGNvbXBvbmVudC4KICovCm1vZGVzLmdjbS5wcm90b3R5cGUuZ2VuZXJhdGVTdWJIYXNoVGFibGUgPSBmdW5jdGlvbihtaWQsIGJpdHMpIHsKICAvLyBjb21wdXRlIHRoZSB0YWJsZSBxdWlja2x5IGJ5IG1pbmltaXppbmcgdGhlIG51bWJlciBvZgogIC8vIFBPVyBvcGVyYXRpb25zIC0tIHRoZXkgb25seSBuZWVkIHRvIGJlIHBlcmZvcm1lZCBmb3IgcG93ZXJzIG9mIDIsCiAgLy8gYWxsIG90aGVyIGVudHJpZXMgY2FuIGJlIGNvbXBvc2VkIGZyb20gdGhvc2UgcG93ZXJzIHVzaW5nIFhPUgogIHZhciBzaXplID0gMSA8PCBiaXRzOwogIHZhciBoYWxmID0gc2l6ZSA+Pj4gMTsKICB2YXIgbSA9IG5ldyBBcnJheShzaXplKTsKICBtW2hhbGZdID0gbWlkLnNsaWNlKDApOwogIHZhciBpID0gaGFsZiA+Pj4gMTsKICB3aGlsZShpID4gMCkgewogICAgLy8gcmFpc2UgbTBbMiAqIGldIGFuZCBzdG9yZSBpbiBtMFtpXQogICAgdGhpcy5wb3cobVsyICogaV0sIG1baV0gPSBbXSk7CiAgICBpID4+PSAxOwogIH0KICBpID0gMjsKICB3aGlsZShpIDwgaGFsZikgewogICAgZm9yKHZhciBqID0gMTsgaiA8IGk7ICsraikgewogICAgICB2YXIgbV9pID0gbVtpXTsKICAgICAgdmFyIG1faiA9IG1bal07CiAgICAgIG1baSArIGpdID0gWwogICAgICAgIG1faVswXSBeIG1falswXSwKICAgICAgICBtX2lbMV0gXiBtX2pbMV0sCiAgICAgICAgbV9pWzJdIF4gbV9qWzJdLAogICAgICAgIG1faVszXSBeIG1falszXQogICAgICBdOwogICAgfQogICAgaSAqPSAyOwogIH0KICBtWzBdID0gWzAsIDAsIDAsIDBdOwogIC8qIE5vdGU6IFdlIGNvdWxkIGF2b2lkIHN0b3JpbmcgdGhlc2UgYnkgZG9pbmcgY29tcG9zaXRpb24gZHVyaW5nIG11bHRpcGx5CiAgY2FsY3VsYXRlIHRvcCBoYWxmIHVzaW5nIGNvbXBvc2l0aW9uIGJ5IHNwZWVkIGlzIHByZWZlcnJlZC4gKi8KICBmb3IoaSA9IGhhbGYgKyAxOyBpIDwgc2l6ZTsgKytpKSB7CiAgICB2YXIgYyA9IG1baSBeIGhhbGZdOwogICAgbVtpXSA9IFttaWRbMF0gXiBjWzBdLCBtaWRbMV0gXiBjWzFdLCBtaWRbMl0gXiBjWzJdLCBtaWRbM10gXiBjWzNdXTsKICB9CiAgcmV0dXJuIG07Cn07CgoKLyoqIFV0aWxpdHkgZnVuY3Rpb25zICovCgpmdW5jdGlvbiB0cmFuc2Zvcm1JVihpdikgewogIGlmKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIHsKICAgIC8vIGNvbnZlcnQgaXYgc3RyaW5nIGludG8gYnl0ZSBidWZmZXIKICAgIGl2ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoaXYpOwogIH0KCiAgaWYoZm9yZ2UudXRpbC5pc0FycmF5KGl2KSAmJiBpdi5sZW5ndGggPiA0KSB7CiAgICAvLyBjb252ZXJ0IGl2IGJ5dGUgYXJyYXkgaW50byBieXRlIGJ1ZmZlcgogICAgdmFyIHRtcCA9IGl2OwogICAgaXYgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgZm9yKHZhciBpID0gMDsgaSA8IHRtcC5sZW5ndGg7ICsraSkgewogICAgICBpdi5wdXRCeXRlKHRtcFtpXSk7CiAgICB9CiAgfQogIGlmKCFmb3JnZS51dGlsLmlzQXJyYXkoaXYpKSB7CiAgICAvLyBjb252ZXJ0IGl2IGJ5dGUgYnVmZmVyIGludG8gMzItYml0IGludGVnZXIgYXJyYXkKICAgIGl2ID0gW2l2LmdldEludDMyKCksIGl2LmdldEludDMyKCksIGl2LmdldEludDMyKCksIGl2LmdldEludDMyKCldOwogIH0KCiAgcmV0dXJuIGl2Owp9CgpmdW5jdGlvbiBpbmMzMihibG9jaykgewogIC8vIGluY3JlbWVudCBsYXN0IDMyIGJpdHMgb2YgYmxvY2sgb25seQogIGJsb2NrW2Jsb2NrLmxlbmd0aCAtIDFdID0gKGJsb2NrW2Jsb2NrLmxlbmd0aCAtIDFdICsgMSkgJiAweEZGRkZGRkZGOwp9CgpmdW5jdGlvbiBmcm9tNjRUbzMyKG51bSkgewogIC8vIGNvbnZlcnQgNjQtYml0IG51bWJlciB0byB0d28gQkUgSW50MzJzCiAgcmV0dXJuIFsobnVtIC8gMHgxMDAwMDAwMDApIHwgMCwgbnVtICYgMHhGRkZGRkZGRl07Cn0KCgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdjaXBoZXJNb2Rlcyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9jaXBoZXJNb2RlcycsWydyZXF1aXJlJywgJ21vZHVsZScsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogQWR2YW5jZWQgRW5jcnlwdGlvbiBTdGFuZGFyZCAoQUVTKSBpbXBsZW1lbnRhdGlvbi4KICoKICogVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBiYXNlZCBvbiB0aGUgcHVibGljIGRvbWFpbiBsaWJyYXJ5ICdqc2NyeXB0bycgd2hpY2gKICogd2FzIHdyaXR0ZW4gYnk6CiAqCiAqIEVtaWx5IFN0YXJrIChlc3RhcmtAc3RhbmZvcmQuZWR1KQogKiBNaWtlIEhhbWJ1cmcgKG1oYW1idXJnQHN0YW5mb3JkLmVkdSkKICogRGFuIEJvbmVoIChkYWJvQGNzLnN0YW5mb3JkLmVkdSkKICoKICogUGFydHMgb2YgdGhpcyBjb2RlIGFyZSBiYXNlZCBvbiB0aGUgT3BlblNTTCBpbXBsZW1lbnRhdGlvbiBvZiBBRVM6CiAqIGh0dHA6Ly93d3cub3BlbnNzbC5vcmcKICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovKiBBRVMgQVBJICovCmZvcmdlLmFlcyA9IGZvcmdlLmFlcyB8fCB7fTsKCi8qKgogKiBEZXByZWNhdGVkLiBJbnN0ZWFkLCB1c2U6CiAqCiAqIHZhciBjaXBoZXIgPSBmb3JnZS5jaXBoZXIuY3JlYXRlQ2lwaGVyKCdBRVMtPG1vZGU+Jywga2V5KTsKICogY2lwaGVyLnN0YXJ0KHtpdjogaXZ9KTsKICoKICogQ3JlYXRlcyBhbiBBRVMgY2lwaGVyIG9iamVjdCB0byBlbmNyeXB0IGRhdGEgdXNpbmcgdGhlIGdpdmVuIHN5bW1ldHJpYyBrZXkuCiAqIFRoZSBvdXRwdXQgd2lsbCBiZSBzdG9yZWQgaW4gdGhlICdvdXRwdXQnIG1lbWJlciBvZiB0aGUgcmV0dXJuZWQgY2lwaGVyLgogKgogKiBUaGUga2V5IGFuZCBpdiBtYXkgYmUgZ2l2ZW4gYXMgYSBzdHJpbmcgb2YgYnl0ZXMsIGFuIGFycmF5IG9mIGJ5dGVzLAogKiBhIGJ5dGUgYnVmZmVyLCBvciBhbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKiBAcGFyYW0gaXYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciB0byB1c2UuCiAqIEBwYXJhbSBvdXRwdXQgdGhlIGJ1ZmZlciB0byB3cml0ZSB0bywgbnVsbCB0byBjcmVhdGUgb25lLgogKiBAcGFyYW0gbW9kZSB0aGUgY2lwaGVyIG1vZGUgdG8gdXNlIChkZWZhdWx0OiAnQ0JDJykuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLmFlcy5zdGFydEVuY3J5cHRpbmcgPSBmdW5jdGlvbihrZXksIGl2LCBvdXRwdXQsIG1vZGUpIHsKICB2YXIgY2lwaGVyID0gX2NyZWF0ZUNpcGhlcih7CiAgICBrZXk6IGtleSwKICAgIG91dHB1dDogb3V0cHV0LAogICAgZGVjcnlwdDogZmFsc2UsCiAgICBtb2RlOiBtb2RlCiAgfSk7CiAgY2lwaGVyLnN0YXJ0KGl2KTsKICByZXR1cm4gY2lwaGVyOwp9OwoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogdmFyIGNpcGhlciA9IGZvcmdlLmNpcGhlci5jcmVhdGVDaXBoZXIoJ0FFUy08bW9kZT4nLCBrZXkpOwogKgogKiBDcmVhdGVzIGFuIEFFUyBjaXBoZXIgb2JqZWN0IHRvIGVuY3J5cHQgZGF0YSB1c2luZyB0aGUgZ2l2ZW4gc3ltbWV0cmljIGtleS4KICoKICogVGhlIGtleSBtYXkgYmUgZ2l2ZW4gYXMgYSBzdHJpbmcgb2YgYnl0ZXMsIGFuIGFycmF5IG9mIGJ5dGVzLCBhCiAqIGJ5dGUgYnVmZmVyLCBvciBhbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKiBAcGFyYW0gbW9kZSB0aGUgY2lwaGVyIG1vZGUgdG8gdXNlIChkZWZhdWx0OiAnQ0JDJykuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLmFlcy5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyID0gZnVuY3Rpb24oa2V5LCBtb2RlKSB7CiAgcmV0dXJuIF9jcmVhdGVDaXBoZXIoewogICAga2V5OiBrZXksCiAgICBvdXRwdXQ6IG51bGwsCiAgICBkZWNyeXB0OiBmYWxzZSwKICAgIG1vZGU6IG1vZGUKICB9KTsKfTsKCi8qKgogKiBEZXByZWNhdGVkLiBJbnN0ZWFkLCB1c2U6CiAqCiAqIHZhciBkZWNpcGhlciA9IGZvcmdlLmNpcGhlci5jcmVhdGVEZWNpcGhlcignQUVTLTxtb2RlPicsIGtleSk7CiAqIGRlY2lwaGVyLnN0YXJ0KHtpdjogaXZ9KTsKICoKICogQ3JlYXRlcyBhbiBBRVMgY2lwaGVyIG9iamVjdCB0byBkZWNyeXB0IGRhdGEgdXNpbmcgdGhlIGdpdmVuIHN5bW1ldHJpYyBrZXkuCiAqIFRoZSBvdXRwdXQgd2lsbCBiZSBzdG9yZWQgaW4gdGhlICdvdXRwdXQnIG1lbWJlciBvZiB0aGUgcmV0dXJuZWQgY2lwaGVyLgogKgogKiBUaGUga2V5IGFuZCBpdiBtYXkgYmUgZ2l2ZW4gYXMgYSBzdHJpbmcgb2YgYnl0ZXMsIGFuIGFycmF5IG9mIGJ5dGVzLAogKiBhIGJ5dGUgYnVmZmVyLCBvciBhbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKiBAcGFyYW0gaXYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciB0byB1c2UuCiAqIEBwYXJhbSBvdXRwdXQgdGhlIGJ1ZmZlciB0byB3cml0ZSB0bywgbnVsbCB0byBjcmVhdGUgb25lLgogKiBAcGFyYW0gbW9kZSB0aGUgY2lwaGVyIG1vZGUgdG8gdXNlIChkZWZhdWx0OiAnQ0JDJykuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLmFlcy5zdGFydERlY3J5cHRpbmcgPSBmdW5jdGlvbihrZXksIGl2LCBvdXRwdXQsIG1vZGUpIHsKICB2YXIgY2lwaGVyID0gX2NyZWF0ZUNpcGhlcih7CiAgICBrZXk6IGtleSwKICAgIG91dHB1dDogb3V0cHV0LAogICAgZGVjcnlwdDogdHJ1ZSwKICAgIG1vZGU6IG1vZGUKICB9KTsKICBjaXBoZXIuc3RhcnQoaXYpOwogIHJldHVybiBjaXBoZXI7Cn07CgovKioKICogRGVwcmVjYXRlZC4gSW5zdGVhZCwgdXNlOgogKgogKiB2YXIgZGVjaXBoZXIgPSBmb3JnZS5jaXBoZXIuY3JlYXRlRGVjaXBoZXIoJ0FFUy08bW9kZT4nLCBrZXkpOwogKgogKiBDcmVhdGVzIGFuIEFFUyBjaXBoZXIgb2JqZWN0IHRvIGRlY3J5cHQgZGF0YSB1c2luZyB0aGUgZ2l2ZW4gc3ltbWV0cmljIGtleS4KICoKICogVGhlIGtleSBtYXkgYmUgZ2l2ZW4gYXMgYSBzdHJpbmcgb2YgYnl0ZXMsIGFuIGFycmF5IG9mIGJ5dGVzLCBhCiAqIGJ5dGUgYnVmZmVyLCBvciBhbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKiBAcGFyYW0gbW9kZSB0aGUgY2lwaGVyIG1vZGUgdG8gdXNlIChkZWZhdWx0OiAnQ0JDJykuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLmFlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyID0gZnVuY3Rpb24oa2V5LCBtb2RlKSB7CiAgcmV0dXJuIF9jcmVhdGVDaXBoZXIoewogICAga2V5OiBrZXksCiAgICBvdXRwdXQ6IG51bGwsCiAgICBkZWNyeXB0OiB0cnVlLAogICAgbW9kZTogbW9kZQogIH0pOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgQUVTIGNpcGhlciBhbGdvcml0aG0gb2JqZWN0LgogKgogKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtLgogKiBAcGFyYW0gbW9kZSB0aGUgbW9kZSBmYWN0b3J5IGZ1bmN0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBBRVMgYWxnb3JpdGhtIG9iamVjdC4KICovCmZvcmdlLmFlcy5BbGdvcml0aG0gPSBmdW5jdGlvbihuYW1lLCBtb2RlKSB7CiAgaWYoIWluaXQpIHsKICAgIGluaXRpYWxpemUoKTsKICB9CiAgdmFyIHNlbGYgPSB0aGlzOwogIHNlbGYubmFtZSA9IG5hbWU7CiAgc2VsZi5tb2RlID0gbmV3IG1vZGUoewogICAgYmxvY2tTaXplOiAxNiwKICAgIGNpcGhlcjogewogICAgICBlbmNyeXB0OiBmdW5jdGlvbihpbkJsb2NrLCBvdXRCbG9jaykgewogICAgICAgIHJldHVybiBfdXBkYXRlQmxvY2soc2VsZi5fdywgaW5CbG9jaywgb3V0QmxvY2ssIGZhbHNlKTsKICAgICAgfSwKICAgICAgZGVjcnlwdDogZnVuY3Rpb24oaW5CbG9jaywgb3V0QmxvY2spIHsKICAgICAgICByZXR1cm4gX3VwZGF0ZUJsb2NrKHNlbGYuX3csIGluQmxvY2ssIG91dEJsb2NrLCB0cnVlKTsKICAgICAgfQogICAgfQogIH0pOwogIHNlbGYuX2luaXQgPSBmYWxzZTsKfTsKCi8qKgogKiBJbml0aWFsaXplcyB0aGlzIEFFUyBhbGdvcml0aG0gYnkgZXhwYW5kaW5nIGl0cyBrZXkuCiAqCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZS4KICogICAgICAgICAga2V5IHRoZSBrZXkgdG8gdXNlIHdpdGggdGhpcyBhbGdvcml0aG0uCiAqICAgICAgICAgIGRlY3J5cHQgdHJ1ZSBpZiB0aGUgYWxnb3JpdGhtIHNob3VsZCBiZSBpbml0aWFsaXplZCBmb3IgZGVjcnlwdGlvbiwKICogICAgICAgICAgICBmYWxzZSBmb3IgZW5jcnlwdGlvbi4KICovCmZvcmdlLmFlcy5BbGdvcml0aG0ucHJvdG90eXBlLmluaXRpYWxpemUgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgaWYodGhpcy5faW5pdCkgewogICAgcmV0dXJuOwogIH0KCiAgdmFyIGtleSA9IG9wdGlvbnMua2V5OwogIHZhciB0bXA7CgogIC8qIE5vdGU6IFRoZSBrZXkgbWF5IGJlIGEgc3RyaW5nIG9mIGJ5dGVzLCBhbiBhcnJheSBvZiBieXRlcywgYSBieXRlCiAgICBidWZmZXIsIG9yIGFuIGFycmF5IG9mIDMyLWJpdCBpbnRlZ2Vycy4gSWYgdGhlIGtleSBpcyBpbiBieXRlcywgdGhlbgogICAgaXQgbXVzdCBiZSAxNiwgMjQsIG9yIDMyIGJ5dGVzIGluIGxlbmd0aC4gSWYgaXQgaXMgaW4gMzItYml0CiAgICBpbnRlZ2VycywgaXQgbXVzdCBiZSA0LCA2LCBvciA4IGludGVnZXJzIGxvbmcuICovCgogIGlmKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnICYmCiAgICAoa2V5Lmxlbmd0aCA9PT0gMTYgfHwga2V5Lmxlbmd0aCA9PT0gMjQgfHwga2V5Lmxlbmd0aCA9PT0gMzIpKSB7CiAgICAvLyBjb252ZXJ0IGtleSBzdHJpbmcgaW50byBieXRlIGJ1ZmZlcgogICAga2V5ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoa2V5KTsKICB9IGVsc2UgaWYoZm9yZ2UudXRpbC5pc0FycmF5KGtleSkgJiYKICAgIChrZXkubGVuZ3RoID09PSAxNiB8fCBrZXkubGVuZ3RoID09PSAyNCB8fCBrZXkubGVuZ3RoID09PSAzMikpIHsKICAgIC8vIGNvbnZlcnQga2V5IGludGVnZXIgYXJyYXkgaW50byBieXRlIGJ1ZmZlcgogICAgdG1wID0ga2V5OwogICAga2V5ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0bXAubGVuZ3RoOyArK2kpIHsKICAgICAga2V5LnB1dEJ5dGUodG1wW2ldKTsKICAgIH0KICB9CgogIC8vIGNvbnZlcnQga2V5IGJ5dGUgYnVmZmVyIGludG8gMzItYml0IGludGVnZXIgYXJyYXkKICBpZighZm9yZ2UudXRpbC5pc0FycmF5KGtleSkpIHsKICAgIHRtcCA9IGtleTsKICAgIGtleSA9IFtdOwoKICAgIC8vIGtleSBsZW5ndGhzIG9mIDE2LCAyNCwgMzIgYnl0ZXMgYWxsb3dlZAogICAgdmFyIGxlbiA9IHRtcC5sZW5ndGgoKTsKICAgIGlmKGxlbiA9PT0gMTYgfHwgbGVuID09PSAyNCB8fCBsZW4gPT09IDMyKSB7CiAgICAgIGxlbiA9IGxlbiA+Pj4gMjsKICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7CiAgICAgICAga2V5LnB1c2godG1wLmdldEludDMyKCkpOwogICAgICB9CiAgICB9CiAgfQoKICAvLyBrZXkgbXVzdCBiZSBhbiBhcnJheSBvZiAzMi1iaXQgaW50ZWdlcnMgYnkgbm93CiAgaWYoIWZvcmdlLnV0aWwuaXNBcnJheShrZXkpIHx8CiAgICAhKGtleS5sZW5ndGggPT09IDQgfHwga2V5Lmxlbmd0aCA9PT0gNiB8fCBrZXkubGVuZ3RoID09PSA4KSkgewogICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGtleSBwYXJhbWV0ZXIuJyk7CiAgfQoKICAvLyBlbmNyeXB0aW9uIG9wZXJhdGlvbiBpcyBhbHdheXMgdXNlZCBmb3IgdGhlc2UgbW9kZXMKICB2YXIgbW9kZSA9IHRoaXMubW9kZS5uYW1lOwogIHZhciBlbmNyeXB0T3AgPSAoWydDRkInLCAnT0ZCJywgJ0NUUicsICdHQ00nXS5pbmRleE9mKG1vZGUpICE9PSAtMSk7CgogIC8vIGRvIGtleSBleHBhbnNpb24KICB0aGlzLl93ID0gX2V4cGFuZEtleShrZXksIG9wdGlvbnMuZGVjcnlwdCAmJiAhZW5jcnlwdE9wKTsKICB0aGlzLl9pbml0ID0gdHJ1ZTsKfTsKCi8qKgogKiBFeHBhbmRzIGEga2V5LiBUeXBpY2FsbHkgb25seSB1c2VkIGZvciB0ZXN0aW5nLgogKgogKiBAcGFyYW0ga2V5IHRoZSBzeW1tZXRyaWMga2V5IHRvIGV4cGFuZCwgYXMgYW4gYXJyYXkgb2YgMzItYml0IHdvcmRzLgogKiBAcGFyYW0gZGVjcnlwdCB0cnVlIHRvIGV4cGFuZCBmb3IgZGVjcnlwdGlvbiwgZmFsc2UgZm9yIGVuY3J5cHRpb24uCiAqCiAqIEByZXR1cm4gdGhlIGV4cGFuZGVkIGtleS4KICovCmZvcmdlLmFlcy5fZXhwYW5kS2V5ID0gZnVuY3Rpb24oa2V5LCBkZWNyeXB0KSB7CiAgaWYoIWluaXQpIHsKICAgIGluaXRpYWxpemUoKTsKICB9CiAgcmV0dXJuIF9leHBhbmRLZXkoa2V5LCBkZWNyeXB0KTsKfTsKCi8qKgogKiBVcGRhdGVzIGEgc2luZ2xlIGJsb2NrLiBUeXBpY2FsbHkgb25seSB1c2VkIGZvciB0ZXN0aW5nLgogKgogKiBAcGFyYW0gdyB0aGUgZXhwYW5kZWQga2V5IHRvIHVzZS4KICogQHBhcmFtIGlucHV0IGFuIGFycmF5IG9mIGJsb2NrLXNpemUgMzItYml0IHdvcmRzLgogKiBAcGFyYW0gb3V0cHV0IGFuIGFycmF5IG9mIGJsb2NrLXNpemUgMzItYml0IHdvcmRzLgogKiBAcGFyYW0gZGVjcnlwdCB0cnVlIHRvIGRlY3J5cHQsIGZhbHNlIHRvIGVuY3J5cHQuCiAqLwpmb3JnZS5hZXMuX3VwZGF0ZUJsb2NrID0gX3VwZGF0ZUJsb2NrOwoKCi8qKiBSZWdpc3RlciBBRVMgYWxnb3JpdGhtcyAqKi8KCnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtRUNCJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmVjYik7CnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtQ0JDJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmNiYyk7CnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtQ0ZCJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmNmYik7CnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtT0ZCJywgZm9yZ2UuY2lwaGVyLm1vZGVzLm9mYik7CnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtQ1RSJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmN0cik7CnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtR0NNJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmdjbSk7CgpmdW5jdGlvbiByZWdpc3RlckFsZ29yaXRobShuYW1lLCBtb2RlKSB7CiAgdmFyIGZhY3RvcnkgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBuZXcgZm9yZ2UuYWVzLkFsZ29yaXRobShuYW1lLCBtb2RlKTsKICB9OwogIGZvcmdlLmNpcGhlci5yZWdpc3RlckFsZ29yaXRobShuYW1lLCBmYWN0b3J5KTsKfQoKCi8qKiBBRVMgaW1wbGVtZW50YXRpb24gKiovCgp2YXIgaW5pdCA9IGZhbHNlOyAvLyBub3QgeWV0IGluaXRpYWxpemVkCnZhciBOYiA9IDQ7ICAgICAgIC8vIG51bWJlciBvZiB3b3JkcyBjb21wcmlzaW5nIHRoZSBzdGF0ZSAoQUVTID0gNCkKdmFyIHNib3g7ICAgICAgICAgLy8gbm9uLWxpbmVhciBzdWJzdGl0dXRpb24gdGFibGUgdXNlZCBpbiBrZXkgZXhwYW5zaW9uCnZhciBpc2JveDsgICAgICAgIC8vIGludmVyc2lvbiBvZiBzYm94CnZhciByY29uOyAgICAgICAgIC8vIHJvdW5kIGNvbnN0YW50IHdvcmQgYXJyYXkKdmFyIG1peDsgICAgICAgICAgLy8gbWl4LWNvbHVtbnMgdGFibGUKdmFyIGltaXg7ICAgICAgICAgLy8gaW52ZXJzZSBtaXgtY29sdW1ucyB0YWJsZQoKLyoqCiAqIFBlcmZvcm1zIGluaXRpYWxpemF0aW9uLCBpZTogcHJlY29tcHV0ZXMgdGFibGVzIHRvIG9wdGltaXplIGZvciBzcGVlZC4KICoKICogT25lIHdheSB0byB1bmRlcnN0YW5kIGhvdyBBRVMgd29ya3MgaXMgdG8gaW1hZ2luZSB0aGF0ICdhZGRpdGlvbicgYW5kCiAqICdtdWx0aXBsaWNhdGlvbicgYXJlIGludGVyZmFjZXMgdGhhdCByZXF1aXJlIGNlcnRhaW4gbWF0aGVtYXRpY2FsCiAqIHByb3BlcnRpZXMgdG8gaG9sZCB0cnVlIChpZTogdGhleSBhcmUgYXNzb2NpYXRpdmUpIGJ1dCB0aGV5IG1pZ2h0IGhhdmUKICogZGlmZmVyZW50IGltcGxlbWVudGF0aW9ucyBhbmQgcHJvZHVjZSBkaWZmZXJlbnQga2luZHMgb2YgcmVzdWx0cyAuLi4KICogcHJvdmlkZWQgdGhhdCB0aGVpciBtYXRoZW1hdGljYWwgcHJvcGVydGllcyByZW1haW4gdHJ1ZS4gQUVTIGRlZmluZXMKICogaXRzIG93biBtZXRob2RzIG9mIGFkZGl0aW9uIGFuZCBtdWx0aXBsaWNhdGlvbiBidXQga2VlcHMgc29tZSBpbXBvcnRhbnQKICogcHJvcGVydGllcyB0aGUgc2FtZSwgaWU6IGFzc29jaWF0aXZpdHkgYW5kIGRpc3RyaWJ1dGl2aXR5LiBUaGUKICogZXhwbGFuYXRpb24gYmVsb3cgdHJpZXMgdG8gc2hlZCBzb21lIGxpZ2h0IG9uIGhvdyBBRVMgZGVmaW5lcyBhZGRpdGlvbgogKiBhbmQgbXVsdGlwbGljYXRpb24gb2YgYnl0ZXMgYW5kIDMyLWJpdCB3b3JkcyBpbiBvcmRlciB0byBwZXJmb3JtIGl0cwogKiBlbmNyeXB0aW9uIGFuZCBkZWNyeXB0aW9uIGFsZ29yaXRobXMuCiAqCiAqIFRoZSBiYXNpY3M6CiAqCiAqIFRoZSBBRVMgYWxnb3JpdGhtIHZpZXdzIGJ5dGVzIGFzIGJpbmFyeSByZXByZXNlbnRhdGlvbnMgb2YgcG9seW5vbWlhbHMKICogdGhhdCBoYXZlIGVpdGhlciAxIG9yIDAgYXMgdGhlIGNvZWZmaWNpZW50cy4gSXQgZGVmaW5lcyB0aGUgYWRkaXRpb24KICogb3Igc3VidHJhY3Rpb24gb2YgdHdvIGJ5dGVzIGFzIHRoZSBYT1Igb3BlcmF0aW9uLiBJdCBhbHNvIGRlZmluZXMgdGhlCiAqIG11bHRpcGxpY2F0aW9uIG9mIHR3byBieXRlcyBhcyBhIGZpbml0ZSBmaWVsZCByZWZlcnJlZCB0byBhcyBHRigyXjgpCiAqIChOb3RlOiAnR0YnIG1lYW5zICJHYWxvaXMgRmllbGQiIHdoaWNoIGlzIGEgZmllbGQgdGhhdCBjb250YWlucyBhIGZpbml0ZQogKiBudW1iZXIgb2YgZWxlbWVudHMgc28gR0YoMl44KSBoYXMgMjU2IGVsZW1lbnRzKS4KICoKICogVGhpcyBtZWFucyB0aGF0IGFueSB0d28gYnl0ZXMgY2FuIGJlIHJlcHJlc2VudGVkIGFzIGJpbmFyeSBwb2x5bm9taWFsczsKICogd2hlbiB0aGV5IG11bHRpcGxpZWQgdG9nZXRoZXIgYW5kIG1vZHVsYXJseSByZWR1Y2VkIGJ5IGFuIGlycmVkdWNpYmxlCiAqIHBvbHlub21pYWwgb2YgdGhlIDh0aCBkZWdyZWUsIHRoZSByZXN1bHRzIGFyZSB0aGUgZmllbGQgR0YoMl44KS4gVGhlCiAqIHNwZWNpZmljIGlycmVkdWNpYmxlIHBvbHlub21pYWwgdGhhdCBBRVMgdXNlcyBpbiBoZXhhZGVjaW1hbCBpcyAweDExYi4KICogVGhpcyBtdWx0aXBsaWNhdGlvbiBpcyBhc3NvY2lhdGl2ZSB3aXRoIDB4MDEgYXMgdGhlIGlkZW50aXR5OgogKgogKiAoYiAqIDB4MDEgPSBHRihiLCAweDAxKSA9IGIpLgogKgogKiBUaGUgb3BlcmF0aW9uIEdGKGIsIDB4MDIpIGNhbiBiZSBwZXJmb3JtZWQgYXQgdGhlIGJ5dGUgbGV2ZWwgYnkgbGVmdAogKiBzaGlmdGluZyBiIG9uY2UgYW5kIHRoZW4gWE9SJ2luZyBpdCAodG8gcGVyZm9ybSB0aGUgbW9kdWxhciByZWR1Y3Rpb24pCiAqIHdpdGggMHgxMWIgaWYgYiBpcyA+PSAxMjguIFJlcGVhdGVkIGFwcGxpY2F0aW9uIG9mIHRoZSBtdWx0aXBsaWNhdGlvbgogKiBvZiAweDAyIGNhbiBiZSB1c2VkIHRvIGltcGxlbWVudCB0aGUgbXVsdGlwbGljYXRpb24gb2YgYW55IHR3byBieXRlcy4KICoKICogRm9yIGluc3RhbmNlLCBtdWx0aXBseWluZyAweDU3IGFuZCAweDEzLCBkZW5vdGVkIGFzIEdGKDB4NTcsIDB4MTMpLCBjYW4KICogYmUgcGVyZm9ybWVkIGJ5IGZhY3RvcmluZyAweDEzIGludG8gMHgwMSwgMHgwMiwgYW5kIDB4MTAuIFRoZW4gdGhlc2UKICogZmFjdG9ycyBjYW4gZWFjaCBiZSBtdWx0aXBsaWVkIGJ5IDB4NTcgYW5kIHRoZW4gYWRkZWQgdG9nZXRoZXIuIFRvIGRvCiAqIHRoZSBtdWx0aXBsaWNhdGlvbiwgdmFsdWVzIGZvciAweDU3IG11bHRpcGxpZWQgYnkgZWFjaCBvZiB0aGVzZSAzIGZhY3RvcnMKICogY2FuIGJlIHByZWNvbXB1dGVkIGFuZCBzdG9yZWQgaW4gYSB0YWJsZS4gVG8gYWRkIHRoZW0sIHRoZSB2YWx1ZXMgZnJvbQogKiB0aGUgdGFibGUgYXJlIFhPUidkIHRvZ2V0aGVyLgogKgogKiBBRVMgYWxzbyBkZWZpbmVzIGFkZGl0aW9uIGFuZCBtdWx0aXBsaWNhdGlvbiBvZiB3b3JkcywgdGhhdCBpcyA0LWJ5dGUKICogbnVtYmVycyByZXByZXNlbnRlZCBhcyBwb2x5bm9taWFscyBvZiAzIGRlZ3JlZXMgd2hlcmUgdGhlIGNvZWZmaWNpZW50cwogKiBhcmUgdGhlIHZhbHVlcyBvZiB0aGUgYnl0ZXMuCiAqCiAqIFRoZSB3b3JkIFthMCwgYTEsIGEyLCBhM10gaXMgYSBwb2x5bm9taWFsIGEzeF4zICsgYTJ4XjIgKyBhMXggKyBhMC4KICoKICogQWRkaXRpb24gaXMgcGVyZm9ybWVkIGJ5IFhPUidpbmcgbGlrZSBwb3dlcnMgb2YgeC4gTXVsdGlwbGljYXRpb24KICogaXMgcGVyZm9ybWVkIGluIHR3byBzdGVwcywgdGhlIGZpcnN0IGlzIGFuIGFsZ2VicmlhYyBleHBhbnNpb24gYXMKICogeW91IHdvdWxkIGRvIG5vcm1hbGx5ICh3aGVyZSBhZGRpdGlvbiBpcyBYT1IpLiBCdXQgdGhlIHJlc3VsdCBpcwogKiBhIHBvbHlub21pYWwgbGFyZ2VyIHRoYW4gMyBkZWdyZWVzIGFuZCB0aHVzIGl0IGNhbm5vdCBmaXQgaW4gYSB3b3JkLiBTbwogKiBuZXh0IHRoZSByZXN1bHQgaXMgbW9kdWxhcmx5IHJlZHVjZWQgYnkgYW4gQUVTLXNwZWNpZmljIHBvbHlub21pYWwgb2YKICogZGVncmVlIDQgd2hpY2ggd2lsbCBhbHdheXMgcHJvZHVjZSBhIHBvbHlub21pYWwgb2YgbGVzcyB0aGFuIDQgZGVncmVlcwogKiBzdWNoIHRoYXQgaXQgd2lsbCBmaXQgaW4gYSB3b3JkLiBJbiBBRVMsIHRoaXMgcG9seW5vbWlhbCBpcyB4XjQgKyAxLgogKgogKiBUaGUgbW9kdWxhciBwcm9kdWN0IG9mIHR3byBwb2x5bm9taWFscyAnYScgYW5kICdiJyBpcyB0aHVzOgogKgogKiBkKHgpID0gZDN4XjMgKyBkMnheMiArIGQxeCArIGQwCiAqIHdpdGgKICogZDAgPSBHRihhMCwgYjApIF4gR0YoYTMsIGIxKSBeIEdGKGEyLCBiMikgXiBHRihhMSwgYjMpCiAqIGQxID0gR0YoYTEsIGIwKSBeIEdGKGEwLCBiMSkgXiBHRihhMywgYjIpIF4gR0YoYTIsIGIzKQogKiBkMiA9IEdGKGEyLCBiMCkgXiBHRihhMSwgYjEpIF4gR0YoYTAsIGIyKSBeIEdGKGEzLCBiMykKICogZDMgPSBHRihhMywgYjApIF4gR0YoYTIsIGIxKSBeIEdGKGExLCBiMikgXiBHRihhMCwgYjMpCiAqCiAqIEFzIGEgbWF0cml4OgogKgogKiBbZDBdID0gW2EwIGEzIGEyIGExXVtiMF0KICogW2QxXSAgIFthMSBhMCBhMyBhMl1bYjFdCiAqIFtkMl0gICBbYTIgYTEgYTAgYTNdW2IyXQogKiBbZDNdICAgW2EzIGEyIGExIGEwXVtiM10KICoKICogU3BlY2lhbCBwb2x5bm9taWFscyBkZWZpbmVkIGJ5IEFFUyAoMHgwMiA9PSB7MDJ9KToKICogYSh4KSAgICA9IHswM314XjMgKyB7MDF9eF4yICsgezAxfXggKyB7MDJ9CiAqIGFeLTEoeCkgPSB7MGJ9eF4zICsgezBkfXheMiArIHswOX14ICsgezBlfS4KICoKICogVGhlc2UgcG9seW5vbWlhbHMgYXJlIHVzZWQgaW4gdGhlIE1peENvbHVtbnMoKSBhbmQgSW52ZXJzZU1peENvbHVtbnMoKQogKiBvcGVyYXRpb25zLCByZXNwZWN0aXZlbHksIHRvIGNhdXNlIGVhY2ggZWxlbWVudCBpbiB0aGUgc3RhdGUgdG8gYWZmZWN0CiAqIHRoZSBvdXRwdXQgKHJlZmVycmVkIHRvIGFzIGRpZmZ1c2luZykuCiAqCiAqIFJvdFdvcmQoKSB1c2VzOiBhMCA9IGExID0gYTIgPSB7MDB9IGFuZCBhMyA9IHswMX0sIHdoaWNoIGlzIHRoZQogKiBwb2x5bm9taWFsIHgzLgogKgogKiBUaGUgU2hpZnRSb3dzKCkgbWV0aG9kIG1vZGlmaWVzIHRoZSBsYXN0IDMgcm93cyBpbiB0aGUgc3RhdGUgKHdoZXJlCiAqIHRoZSBzdGF0ZSBpcyA0IHdvcmRzIHdpdGggNCBieXRlcyBwZXIgd29yZCkgYnkgc2hpZnRpbmcgYnl0ZXMgY3ljbGljYWxseS4KICogVGhlIDFzdCBieXRlIGluIHRoZSBzZWNvbmQgcm93IGlzIG1vdmVkIHRvIHRoZSBlbmQgb2YgdGhlIHJvdy4gVGhlIDFzdAogKiBhbmQgMm5kIGJ5dGVzIGluIHRoZSB0aGlyZCByb3cgYXJlIG1vdmVkIHRvIHRoZSBlbmQgb2YgdGhlIHJvdy4gVGhlIDFzdCwKICogMm5kLCBhbmQgM3JkIGJ5dGVzIGFyZSBtb3ZlZCBpbiB0aGUgZm91cnRoIHJvdy4KICoKICogTW9yZSBkZXRhaWxzIG9uIGhvdyBBRVMgYXJpdGhtZXRpYyB3b3JrczoKICoKICogSW4gdGhlIHBvbHlub21pYWwgcmVwcmVzZW50YXRpb24gb2YgYmluYXJ5IG51bWJlcnMsIFhPUiBwZXJmb3JtcyBhZGRpdGlvbgogKiBhbmQgc3VidHJhY3Rpb24gYW5kIG11bHRpcGxpY2F0aW9uIGluIEdGKDJeOCkgZGVub3RlZCBhcyBHRihhLCBiKQogKiBjb3JyZXNwb25kcyB3aXRoIHRoZSBtdWx0aXBsaWNhdGlvbiBvZiBwb2x5bm9taWFscyBtb2R1bG8gYW4gaXJyZWR1Y2libGUKICogcG9seW5vbWlhbCBvZiBkZWdyZWUgOC4gSW4gb3RoZXIgd29yZHMsIGZvciBBRVMsIEdGKGEsIGIpIHdpbGwgbXVsdGlwbHkKICogcG9seW5vbWlhbCAnYScgd2l0aCBwb2x5bm9taWFsICdiJyBhbmQgdGhlbiBkbyBhIG1vZHVsYXIgcmVkdWN0aW9uIGJ5CiAqIGFuIEFFUy1zcGVjaWZpYyBpcnJlZHVjaWJsZSBwb2x5bm9taWFsIG9mIGRlZ3JlZSA4LgogKgogKiBBIHBvbHlub21pYWwgaXMgaXJyZWR1Y2libGUgaWYgaXRzIG9ubHkgZGl2aXNvcnMgYXJlIG9uZSBhbmQgaXRzZWxmLiBGb3IKICogdGhlIEFFUyBhbGdvcml0aG0sIHRoaXMgaXJyZWR1Y2libGUgcG9seW5vbWlhbCBpczoKICoKICogbSh4KSA9IHheOCArIHheNCArIHheMyArIHggKyAxLAogKgogKiBvciB7MDF9ezFifSBpbiBoZXhhZGVjaW1hbCBub3RhdGlvbiwgd2hlcmUgZWFjaCBjb2VmZmljaWVudCBpcyBhIGJpdDoKICogMTAwMDExMDExID0gMjgzID0gMHgxMWIuCiAqCiAqIEZvciBleGFtcGxlLCBHRigweDU3LCAweDgzKSA9IDB4YzEgYmVjYXVzZQogKgogKiAweDU3ID0gODcgID0gMDEwMTAxMTEgPSB4XjYgKyB4XjQgKyB4XjIgKyB4ICsgMQogKiAweDg1ID0gMTMxID0gMTAwMDAxMDEgPSB4XjcgKyB4ICsgMQogKgogKiAoeF42ICsgeF40ICsgeF4yICsgeCArIDEpICogKHheNyArIHggKyAxKQogKiA9ICB4XjEzICsgeF4xMSArIHheOSArIHheOCArIHheNyArCiAqICAgIHheNyArIHheNSArIHheMyArIHheMiArIHggKwogKiAgICB4XjYgKyB4XjQgKyB4XjIgKyB4ICsgMQogKiA9ICB4XjEzICsgeF4xMSArIHheOSArIHheOCArIHheNiArIHheNSArIHheNCArIHheMyArIDEgPSB5CiAqICAgIHkgbW9kdWxvICh4XjggKyB4XjQgKyB4XjMgKyB4ICsgMSkKICogPSAgeF43ICsgeF42ICsgMS4KICoKICogVGhlIG1vZHVsYXIgcmVkdWN0aW9uIGJ5IG0oeCkgZ3VhcmFudGVlcyB0aGUgcmVzdWx0IHdpbGwgYmUgYSBiaW5hcnkKICogcG9seW5vbWlhbCBvZiBsZXNzIHRoYW4gZGVncmVlIDgsIHNvIHRoYXQgaXQgY2FuIGZpdCBpbiBhIGJ5dGUuCiAqCiAqIFRoZSBvcGVyYXRpb24gdG8gbXVsdGlwbHkgYSBiaW5hcnkgcG9seW5vbWlhbCBiIHdpdGggeCAodGhlIHBvbHlub21pYWwKICogeCBpbiBiaW5hcnkgcmVwcmVzZW50YXRpb24gaXMgMDAwMDAwMTApIGlzOgogKgogKiBiXzd4XjggKyBiXzZ4XjcgKyBiXzV4XjYgKyBiXzR4XjUgKyBiXzN4XjQgKyBiXzJ4XjMgKyBiXzF4XjIgKyBiXzB4XjEKICoKICogVG8gZ2V0IEdGKGIsIHgpIHdlIG11c3QgcmVkdWNlIHRoYXQgYnkgbSh4KS4gSWYgYl83IGlzIDAgKHRoYXQgaXMgdGhlCiAqIG1vc3Qgc2lnbmlmaWNhbnQgYml0IGlzIDAgaW4gYikgdGhlbiB0aGUgcmVzdWx0IGlzIGFscmVhZHkgcmVkdWNlZC4gSWYKICogaXQgaXMgMSwgdGhlbiB3ZSBjYW4gcmVkdWNlIGl0IGJ5IHN1YnRyYWN0aW5nIG0oeCkgdmlhIGFuIFhPUi4KICoKICogSXQgZm9sbG93cyB0aGF0IG11bHRpcGxpY2F0aW9uIGJ5IHggKDAwMDAwMDEwIG9yIDB4MDIpIGNhbiBiZSBpbXBsZW1lbnRlZAogKiBieSBwZXJmb3JtaW5nIGEgbGVmdCBzaGlmdCBmb2xsb3dlZCBieSBhIGNvbmRpdGlvbmFsIGJpdHdpc2UgWE9SIHdpdGgKICogMHgxYi4gVGhpcyBvcGVyYXRpb24gb24gYnl0ZXMgaXMgZGVub3RlZCBieSB4dGltZSgpLiBNdWx0aXBsaWNhdGlvbiBieQogKiBoaWdoZXIgcG93ZXJzIG9mIHggY2FuIGJlIGltcGxlbWVudGVkIGJ5IHJlcGVhdGVkIGFwcGxpY2F0aW9uIG9mIHh0aW1lKCkuCiAqCiAqIEJ5IGFkZGluZyBpbnRlcm1lZGlhdGUgcmVzdWx0cywgbXVsdGlwbGljYXRpb24gYnkgYW55IGNvbnN0YW50IGNhbiBiZQogKiBpbXBsZW1lbnRlZC4gRm9yIGluc3RhbmNlOgogKgogKiBHRigweDU3LCAweDEzKSA9IDB4ZmUgYmVjYXVzZToKICoKICogeHRpbWUoYikgPSAoYiAmIDEyOCkgPyAoYiA8PCAxIF4gMHgxMWIpIDogKGIgPDwgMSkKICoKICogTm90ZTogV2UgWE9SIHdpdGggMHgxMWIgaW5zdGVhZCBvZiAweDFiIGJlY2F1c2UgaW4gamF2YXNjcmlwdCBvdXIKICogZGF0YXR5cGUgZm9yIGIgY2FuIGJlIGxhcmdlciB0aGFuIDEgYnl0ZSwgc28gYSBsZWZ0IHNoaWZ0IHdpbGwgbm90CiAqIGF1dG9tYXRpY2FsbHkgZWxpbWluYXRlIGJpdHMgdGhhdCBvdmVyZmxvdyBhIGJ5dGUgLi4uIGJ5IFhPUidpbmcgdGhlCiAqIG92ZXJmbG93IGJpdCB3aXRoIDEgKHRoZSBleHRyYSBvbmUgZnJvbSAweDExYikgd2UgemVybyBpdCBvdXQuCiAqCiAqIEdGKDB4NTcsIDB4MDIpID0geHRpbWUoMHg1NykgPSAweGFlCiAqIEdGKDB4NTcsIDB4MDQpID0geHRpbWUoMHhhZSkgPSAweDQ3CiAqIEdGKDB4NTcsIDB4MDgpID0geHRpbWUoMHg0NykgPSAweDhlCiAqIEdGKDB4NTcsIDB4MTApID0geHRpbWUoMHg4ZSkgPSAweDA3CiAqCiAqIEdGKDB4NTcsIDB4MTMpID0gR0YoMHg1NywgKDB4MDEgXiAweDAyIF4gMHgxMCkpCiAqCiAqIEFuZCBieSB0aGUgZGlzdHJpYnV0aXZlIHByb3BlcnR5IChzaW5jZSBYT1IgaXMgYWRkaXRpb24gYW5kIEdGKCkgaXMKICogbXVsdGlwbGljYXRpb24pOgogKgogKiA9IEdGKDB4NTcsIDB4MDEpIF4gR0YoMHg1NywgMHgwMikgXiBHRigweDU3LCAweDEwKQogKiA9IDB4NTcgXiAweGFlIF4gMHgwNwogKiA9IDB4ZmUuCiAqLwpmdW5jdGlvbiBpbml0aWFsaXplKCkgewogIGluaXQgPSB0cnVlOwoKICAvKiBQb3B1bGF0ZSB0aGUgUmNvbiB0YWJsZS4gVGhlc2UgYXJlIHRoZSB2YWx1ZXMgZ2l2ZW4gYnkKICAgIFt4XihpLTEpLHswMH0sezAwfSx7MDB9XSB3aGVyZSB4XihpLTEpIGFyZSBwb3dlcnMgb2YgeCAoYW5kIHggPSAweDAyKQogICAgaW4gdGhlIGZpZWxkIG9mIEdGKDJeOCksIHdoZXJlIGkgc3RhcnRzIGF0IDEuCgogICAgcmNvblswXSA9IFsweDAwLCAweDAwLCAweDAwLCAweDAwXQogICAgcmNvblsxXSA9IFsweDAxLCAweDAwLCAweDAwLCAweDAwXSAyXigxLTEpID0gMl4wID0gMQogICAgcmNvblsyXSA9IFsweDAyLCAweDAwLCAweDAwLCAweDAwXSAyXigyLTEpID0gMl4xID0gMgogICAgLi4uCiAgICByY29uWzldICA9IFsweDFCLCAweDAwLCAweDAwLCAweDAwXSAyXig5LTEpICA9IDJeOCA9IDB4MUIKICAgIHJjb25bMTBdID0gWzB4MzYsIDB4MDAsIDB4MDAsIDB4MDBdIDJeKDEwLTEpID0gMl45ID0gMHgzNgoKICAgIFdlIG9ubHkgc3RvcmUgdGhlIGZpcnN0IGJ5dGUgYmVjYXVzZSBpdCBpcyB0aGUgb25seSBvbmUgdXNlZC4KICAqLwogIHJjb24gPSBbMHgwMCwgMHgwMSwgMHgwMiwgMHgwNCwgMHgwOCwgMHgxMCwgMHgyMCwgMHg0MCwgMHg4MCwgMHgxQiwgMHgzNl07CgogIC8vIGNvbXB1dGUgeHRpbWUgdGFibGUgd2hpY2ggbWFwcyBpIG9udG8gR0YoaSwgMHgwMikKICB2YXIgeHRpbWUgPSBuZXcgQXJyYXkoMjU2KTsKICBmb3IodmFyIGkgPSAwOyBpIDwgMTI4OyArK2kpIHsKICAgIHh0aW1lW2ldID0gaSA8PCAxOwogICAgeHRpbWVbaSArIDEyOF0gPSAoaSArIDEyOCkgPDwgMSBeIDB4MTFCOwogIH0KCiAgLy8gY29tcHV0ZSBhbGwgb3RoZXIgdGFibGVzCiAgc2JveCA9IG5ldyBBcnJheSgyNTYpOwogIGlzYm94ID0gbmV3IEFycmF5KDI1Nik7CiAgbWl4ID0gbmV3IEFycmF5KDQpOwogIGltaXggPSBuZXcgQXJyYXkoNCk7CiAgZm9yKHZhciBpID0gMDsgaSA8IDQ7ICsraSkgewogICAgbWl4W2ldID0gbmV3IEFycmF5KDI1Nik7CiAgICBpbWl4W2ldID0gbmV3IEFycmF5KDI1Nik7CiAgfQogIHZhciBlID0gMCwgZWkgPSAwLCBlMiwgZTQsIGU4LCBzeCwgc3gyLCBtZSwgaW1lOwogIGZvcih2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkgewogICAgLyogV2UgbmVlZCB0byBnZW5lcmF0ZSB0aGUgU3ViQnl0ZXMoKSBzYm94IGFuZCBpc2JveCB0YWJsZXMgc28gdGhhdAogICAgICB3ZSBjYW4gcGVyZm9ybSBieXRlIHN1YnN0aXR1dGlvbnMuIFRoaXMgcmVxdWlyZXMgdXMgdG8gdHJhdmVyc2UKICAgICAgYWxsIG9mIHRoZSBlbGVtZW50cyBpbiBHRiwgZmluZCB0aGVpciBtdWx0aXBsaWNhdGl2ZSBpbnZlcnNlcywKICAgICAgYW5kIGFwcGx5IHRvIGVhY2ggdGhlIGZvbGxvd2luZyBhZmZpbmUgdHJhbnNmb3JtYXRpb246CgogICAgICBiaScgPSBiaSBeIGIoaSArIDQpIG1vZCA4IF4gYihpICsgNSkgbW9kIDggXiBiKGkgKyA2KSBtb2QgOCBeCiAgICAgICAgICAgIGIoaSArIDcpIG1vZCA4IF4gY2kKICAgICAgZm9yIDAgPD0gaSA8IDgsIHdoZXJlIGJpIGlzIHRoZSBpdGggYml0IG9mIHRoZSBieXRlLCBhbmQgY2kgaXMgdGhlCiAgICAgIGl0aCBiaXQgb2YgYSBieXRlIGMgd2l0aCB0aGUgdmFsdWUgezYzfSBvciB7MDExMDAwMTF9LgoKICAgICAgSXQgaXMgcG9zc2libGUgdG8gdHJhdmVyc2UgZXZlcnkgcG9zc2libGUgdmFsdWUgaW4gYSBHYWxvaXMgZmllbGQKICAgICAgdXNpbmcgd2hhdCBpcyByZWZlcnJlZCB0byBhcyBhICdnZW5lcmF0b3InLiBUaGVyZSBhcmUgbWFueQogICAgICBnZW5lcmF0b3JzICgxMjggb3V0IG9mIDI1Nik6IDMsNSw2LDksMTEsODIgdG8gbmFtZSBhIGZldy4gVG8gZnVsbHkKICAgICAgdHJhdmVyc2UgR0Ygd2UgaXRlcmF0ZSAyNTUgdGltZXMsIG11bHRpcGx5aW5nIGJ5IG91ciBnZW5lcmF0b3IKICAgICAgZWFjaCB0aW1lLgoKICAgICAgT24gZWFjaCBpdGVyYXRpb24gd2UgY2FuIGRldGVybWluZSB0aGUgbXVsdGlwbGljYXRpdmUgaW52ZXJzZSBmb3IKICAgICAgdGhlIGN1cnJlbnQgZWxlbWVudC4KCiAgICAgIFN1cHBvc2UgdGhlcmUgaXMgYW4gZWxlbWVudCBpbiBHRiAnZScuIEZvciBhIGdpdmVuIGdlbmVyYXRvciAnZycsCiAgICAgIGUgPSBnXnguIFRoZSBtdWx0aXBsaWNhdGl2ZSBpbnZlcnNlIG9mIGUgaXMgZ14oMjU1IC0geCkuIEl0IHR1cm5zCiAgICAgIG91dCB0aGF0IGlmIHVzZSB0aGUgaW52ZXJzZSBvZiBhIGdlbmVyYXRvciBhcyBhbm90aGVyIGdlbmVyYXRvcgogICAgICBpdCB3aWxsIHByb2R1Y2UgYWxsIG9mIHRoZSBjb3JyZXNwb25kaW5nIG11bHRpcGxpY2F0aXZlIGludmVyc2VzCiAgICAgIGF0IHRoZSBzYW1lIHRpbWUuIEZvciB0aGlzIHJlYXNvbiwgd2UgY2hvb3NlIDUgYXMgb3VyIGludmVyc2UKICAgICAgZ2VuZXJhdG9yIGJlY2F1c2UgaXQgb25seSByZXF1aXJlcyAyIG11bHRpcGxpZXMgYW5kIDEgYWRkIGFuZCBpdHMKICAgICAgaW52ZXJzZSwgODIsIHJlcXVpcmVzIHJlbGF0aXZlbHkgZmV3IG9wZXJhdGlvbnMgYXMgd2VsbC4KCiAgICAgIEluIG9yZGVyIHRvIGFwcGx5IHRoZSBhZmZpbmUgdHJhbnNmb3JtYXRpb24sIHRoZSBtdWx0aXBsaWNhdGl2ZQogICAgICBpbnZlcnNlICdlaScgb2YgJ2UnIGNhbiBiZSByZXBlYXRlZGx5IFhPUidkICg0IHRpbWVzKSB3aXRoIGEKICAgICAgYml0LWN5Y2xpbmcgb2YgJ2VpJy4gVG8gZG8gdGhpcyAnZWknIGlzIGZpcnN0IHN0b3JlZCBpbiAncycgYW5kCiAgICAgICd4Jy4gVGhlbiAncycgaXMgbGVmdCBzaGlmdGVkIGFuZCB0aGUgaGlnaCBiaXQgb2YgJ3MnIGlzIG1hZGUgdGhlCiAgICAgIGxvdyBiaXQuIFRoZSByZXN1bHRpbmcgdmFsdWUgaXMgc3RvcmVkIGluICdzJy4gVGhlbiAneCcgaXMgWE9SJ2QKICAgICAgd2l0aCAncycgYW5kIHN0b3JlZCBpbiAneCcuIE9uIGVhY2ggc3Vic2VxdWVudCBpdGVyYXRpb24gdGhlIHNhbWUKICAgICAgb3BlcmF0aW9uIGlzIHBlcmZvcm1lZC4gV2hlbiA0IGl0ZXJhdGlvbnMgYXJlIGNvbXBsZXRlLCAneCcgaXMKICAgICAgWE9SJ2Qgd2l0aCAnYycgKDB4NjMpIGFuZCB0aGUgdHJhbnNmb3JtZWQgdmFsdWUgaXMgc3RvcmVkIGluICd4Jy4KICAgICAgRm9yIGV4YW1wbGU6CgogICAgICBzID0gMDEwMDAwMDEKICAgICAgeCA9IDAxMDAwMDAxCgogICAgICBpdGVyYXRpb24gMTogcyA9IDEwMDAwMDEwLCB4IF49IHMKICAgICAgaXRlcmF0aW9uIDI6IHMgPSAwMDAwMDEwMSwgeCBePSBzCiAgICAgIGl0ZXJhdGlvbiAzOiBzID0gMDAwMDEwMTAsIHggXj0gcwogICAgICBpdGVyYXRpb24gNDogcyA9IDAwMDEwMTAwLCB4IF49IHMKICAgICAgeCBePSAweDYzCgogICAgICBUaGlzIGNhbiBiZSBkb25lIHdpdGggYSBsb29wIHdoZXJlIHMgPSAocyA8PCAxKSB8IChzID4+IDcpLiBIb3dldmVyLAogICAgICBpdCBjYW4gYWxzbyBiZSBkb25lIGJ5IHVzaW5nIGEgc2luZ2xlIDE2LWJpdCAoaW4gdGhpcyBjYXNlIDMyLWJpdCkKICAgICAgbnVtYmVyICdzeCcuIFNpbmNlIFhPUiBpcyBhbiBhc3NvY2lhdGl2ZSBvcGVyYXRpb24sIHdlIGNhbiBzZXQgJ3N4JwogICAgICB0byAnZWknIGFuZCB0aGVuIFhPUiBpdCB3aXRoICdzeCcgbGVmdC1zaGlmdGVkIDEsMiwzLCBhbmQgNCB0aW1lcy4KICAgICAgVGhlIG1vc3Qgc2lnbmlmaWNhbnQgYml0cyB3aWxsIGZsb3cgaW50byB0aGUgaGlnaCA4IGJpdCBwb3NpdGlvbnMKICAgICAgYW5kIGJlIGNvcnJlY3RseSBYT1InZCB3aXRoIG9uZSBhbm90aGVyLiBBbGwgdGhhdCByZW1haW5zIHdpbGwgYmUKICAgICAgdG8gY3ljbGUgdGhlIGhpZ2ggOCBiaXRzIGJ5IFhPUidpbmcgdGhlbSBhbGwgd2l0aCB0aGUgbG93ZXIgOCBiaXRzCiAgICAgIGFmdGVyd2FyZHMuCgogICAgICBBdCB0aGUgc2FtZSB0aW1lIHdlJ3JlIHBvcHVsYXRpbmcgc2JveCBhbmQgaXNib3ggd2UgY2FuIHByZWNvbXB1dGUKICAgICAgdGhlIG11bHRpcGxpY2F0aW9uIHdlJ2xsIG5lZWQgdG8gZG8gdG8gZG8gTWl4Q29sdW1ucygpIGxhdGVyLgogICAgKi8KCiAgICAvLyBhcHBseSBhZmZpbmUgdHJhbnNmb3JtYXRpb24KICAgIHN4ID0gZWkgXiAoZWkgPDwgMSkgXiAoZWkgPDwgMikgXiAoZWkgPDwgMykgXiAoZWkgPDwgNCk7CiAgICBzeCA9IChzeCA+PiA4KSBeIChzeCAmIDI1NSkgXiAweDYzOwoKICAgIC8vIHVwZGF0ZSB0YWJsZXMKICAgIHNib3hbZV0gPSBzeDsKICAgIGlzYm94W3N4XSA9IGU7CgogICAgLyogTWl4aW5nIGNvbHVtbnMgaXMgZG9uZSB1c2luZyBtYXRyaXggbXVsdGlwbGljYXRpb24uIFRoZSBjb2x1bW5zCiAgICAgIHRoYXQgYXJlIHRvIGJlIG1peGVkIGFyZSBlYWNoIGEgc2luZ2xlIHdvcmQgaW4gdGhlIGN1cnJlbnQgc3RhdGUuCiAgICAgIFRoZSBzdGF0ZSBoYXMgTmIgY29sdW1ucyAoNCBjb2x1bW5zKS4gVGhlcmVmb3JlIGVhY2ggY29sdW1uIGlzIGEKICAgICAgNCBieXRlIHdvcmQuIFNvIHRvIG1peCB0aGUgY29sdW1ucyBpbiBhIHNpbmdsZSBjb2x1bW4gJ2MnIHdoZXJlCiAgICAgIGl0cyByb3dzIGFyZSByMCwgcjEsIHIyLCBhbmQgcjMsIHdlIHVzZSB0aGUgZm9sbG93aW5nIG1hdHJpeAogICAgICBtdWx0aXBsaWNhdGlvbjoKCiAgICAgIFsyIDMgMSAxXSpbcjAsY109W3InMCxjXQogICAgICBbMSAyIDMgMV0gW3IxLGNdIFtyJzEsY10KICAgICAgWzEgMSAyIDNdIFtyMixjXSBbcicyLGNdCiAgICAgIFszIDEgMSAyXSBbcjMsY10gW3InMyxjXQoKICAgICAgcjAsIHIxLCByMiwgYW5kIHIzIGFyZSBlYWNoIDEgYnl0ZSBvZiBvbmUgb2YgdGhlIHdvcmRzIGluIHRoZQogICAgICBzdGF0ZSAoYSBjb2x1bW4pLiBUbyBkbyBtYXRyaXggbXVsdGlwbGljYXRpb24gZm9yIGVhY2ggbWl4ZWQKICAgICAgY29sdW1uIGMnIHdlIG11bHRpcGx5IHRoZSBjb3JyZXNwb25kaW5nIHJvdyBmcm9tIHRoZSBsZWZ0IG1hdHJpeAogICAgICB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIGNvbHVtbiBmcm9tIHRoZSByaWdodCBtYXRyaXguIEluIHRvdGFsLCB3ZQogICAgICBnZXQgNCBlcXVhdGlvbnM6CgogICAgICByMCxjJyA9IDIqcjAsYyArIDMqcjEsYyArIDEqcjIsYyArIDEqcjMsYwogICAgICByMSxjJyA9IDEqcjAsYyArIDIqcjEsYyArIDMqcjIsYyArIDEqcjMsYwogICAgICByMixjJyA9IDEqcjAsYyArIDEqcjEsYyArIDIqcjIsYyArIDMqcjMsYwogICAgICByMyxjJyA9IDMqcjAsYyArIDEqcjEsYyArIDEqcjIsYyArIDIqcjMsYwoKICAgICAgQXMgdXN1YWwsIHRoZSBtdWx0aXBsaWNhdGlvbiBpcyBhcyBwcmV2aW91c2x5IGRlZmluZWQgYW5kIHRoZQogICAgICBhZGRpdGlvbiBpcyBYT1IuIEluIG9yZGVyIHRvIG9wdGltaXplIG1peGluZyBjb2x1bW5zIHdlIGNhbiBzdG9yZQogICAgICB0aGUgbXVsdGlwbGljYXRpb24gcmVzdWx0cyBpbiB0YWJsZXMuIElmIHlvdSB0aGluayBvZiB0aGUgd2hvbGUKICAgICAgY29sdW1uIGFzIGEgd29yZCAoaXQgbWlnaHQgaGVscCB0byB2aXN1YWxpemUgYnkgbWVudGFsbHkgcm90YXRpbmcKICAgICAgdGhlIGVxdWF0aW9ucyBhYm92ZSBieSBjb3VudGVyY2xvY2t3aXNlIDkwIGRlZ3JlZXMpIHRoZW4geW91IGNhbgogICAgICBzZWUgdGhhdCBpdCB3b3VsZCBiZSB1c2VmdWwgdG8gbWFwIHRoZSBtdWx0aXBsaWNhdGlvbnMgcGVyZm9ybWVkIG9uCiAgICAgIGVhY2ggYnl0ZSAocjAsIHIxLCByMiwgcjMpIG9udG8gYSB3b3JkIGFzIHdlbGwuIEZvciBpbnN0YW5jZSwgd2UKICAgICAgY291bGQgbWFwIDIqcjAsMSpyMCwxKnIwLDMqcjAgb250byBhIHdvcmQgYnkgc3RvcmluZyAyKnIwIGluIHRoZQogICAgICBoaWdoZXN0IDggYml0cyBhbmQgMypyMCBpbiB0aGUgbG93ZXN0IDggYml0cyAod2l0aCB0aGUgb3RoZXIgdHdvCiAgICAgIHJlc3BlY3RpdmVseSBpbiB0aGUgbWlkZGxlKS4gVGhpcyBtZWFucyB0aGF0IGEgdGFibGUgY2FuIGJlCiAgICAgIGNvbnN0cnVjdGVkIHRoYXQgdXNlcyByMCBhcyBhbiBpbmRleCB0byB0aGUgd29yZC4gV2UgY2FuIGRvIHRoZQogICAgICBzYW1lIHdpdGggcjEsIHIyLCBhbmQgcjMsIGNyZWF0aW5nIGEgdG90YWwgb2YgNCB0YWJsZXMuCgogICAgICBUbyBjb25zdHJ1Y3QgYSBmdWxsIGMnLCB3ZSBjYW4ganVzdCBsb29rIHVwIGVhY2ggYnl0ZSBvZiBjIGluCiAgICAgIHRoZWlyIHJlc3BlY3RpdmUgdGFibGVzIGFuZCBYT1IgdGhlIHJlc3VsdHMgdG9nZXRoZXIuCgogICAgICBBbHNvLCB0byBidWlsZCBlYWNoIHRhYmxlIHdlIG9ubHkgaGF2ZSB0byBjYWxjdWxhdGUgdGhlIHdvcmQKICAgICAgZm9yIDIsMSwxLDMgZm9yIGV2ZXJ5IGJ5dGUgLi4uIHdoaWNoIHdlIGNhbiBkbyBvbiBlYWNoIGl0ZXJhdGlvbgogICAgICBvZiB0aGlzIGxvb3Agc2luY2Ugd2Ugd2lsbCBpdGVyYXRlIG92ZXIgZXZlcnkgYnl0ZS4gQWZ0ZXIgd2UgaGF2ZQogICAgICBjYWxjdWxhdGVkIDIsMSwxLDMgd2UgY2FuIGdldCB0aGUgcmVzdWx0cyBmb3IgdGhlIG90aGVyIHRhYmxlcwogICAgICBieSBjeWNsaW5nIHRoZSBieXRlIGF0IHRoZSBlbmQgdG8gdGhlIGJlZ2lubmluZy4gRm9yIGluc3RhbmNlCiAgICAgIHdlIGNhbiB0YWtlIHRoZSByZXN1bHQgb2YgdGFibGUgMiwxLDEsMyBhbmQgcHJvZHVjZSB0YWJsZSAzLDIsMSwxCiAgICAgIGJ5IG1vdmluZyB0aGUgcmlnaHQgbW9zdCBieXRlIHRvIHRoZSBsZWZ0IG1vc3QgcG9zaXRpb24ganVzdCBsaWtlCiAgICAgIGhvdyB5b3UgY2FuIGltYWdpbmUgdGhlIDMgbW92ZWQgb3V0IG9mIDIsMSwxLDMgYW5kIHRvIHRoZSBmcm9udAogICAgICB0byBwcm9kdWNlIDMsMiwxLDEuCgogICAgICBUaGVyZSBpcyBhbm90aGVyIG9wdGltaXphdGlvbiBpbiB0aGF0IHRoZSBzYW1lIG11bHRpcGxlcyBvZgogICAgICB0aGUgY3VycmVudCBlbGVtZW50IHdlIG5lZWQgaW4gb3JkZXIgdG8gYWR2YW5jZSBvdXIgZ2VuZXJhdG9yCiAgICAgIHRvIHRoZSBuZXh0IGl0ZXJhdGlvbiBjYW4gYmUgcmV1c2VkIGluIHBlcmZvcm1pbmcgdGhlIDIsMSwxLDMKICAgICAgY2FsY3VsYXRpb24uIFdlIGFsc28gY2FsY3VsYXRlIHRoZSBpbnZlcnNlIG1peCBjb2x1bW4gdGFibGVzLAogICAgICB3aXRoIGUsOSxkLGIgYmVpbmcgdGhlIGludmVyc2Ugb2YgMiwxLDEsMy4KCiAgICAgIFdoZW4gd2UncmUgZG9uZSwgYW5kIHdlIG5lZWQgdG8gYWN0dWFsbHkgbWl4IGNvbHVtbnMsIHRoZSBmaXJzdAogICAgICBieXRlIG9mIGVhY2ggc3RhdGUgd29yZCBzaG91bGQgYmUgcHV0IHRocm91Z2ggbWl4WzBdICgyLDEsMSwzKSwKICAgICAgdGhlIHNlY29uZCB0aHJvdWdoIG1peFsxXSAoMywyLDEsMSkgYW5kIHNvIGZvcnRoLiBUaGVuIHRoZXkgc2hvdWxkCiAgICAgIGJlIFhPUidkIHRvZ2V0aGVyIHRvIHByb2R1Y2UgdGhlIGZ1bGx5IG1peGVkIGNvbHVtbi4KICAgICovCgogICAgLy8gY2FsY3VsYXRlIG1peCBhbmQgaW1peCB0YWJsZSB2YWx1ZXMKICAgIHN4MiA9IHh0aW1lW3N4XTsKICAgIGUyID0geHRpbWVbZV07CiAgICBlNCA9IHh0aW1lW2UyXTsKICAgIGU4ID0geHRpbWVbZTRdOwogICAgbWUgPQogICAgICAoc3gyIDw8IDI0KSBeICAvLyAyCiAgICAgIChzeCA8PCAxNikgXiAgIC8vIDEKICAgICAgKHN4IDw8IDgpIF4gICAgLy8gMQogICAgICAoc3ggXiBzeDIpOyAgICAvLyAzCiAgICBpbWUgPQogICAgICAoZTIgXiBlNCBeIGU4KSA8PCAyNCBeICAvLyBFICgxNCkKICAgICAgKGUgXiBlOCkgPDwgMTYgXiAgICAgICAgLy8gOQogICAgICAoZSBeIGU0IF4gZTgpIDw8IDggXiAgICAvLyBEICgxMykKICAgICAgKGUgXiBlMiBeIGU4KTsgICAgICAgICAgLy8gQiAoMTEpCiAgICAvLyBwcm9kdWNlIGVhY2ggb2YgdGhlIG1peCB0YWJsZXMgYnkgcm90YXRpbmcgdGhlIDIsMSwxLDMgdmFsdWUKICAgIGZvcih2YXIgbiA9IDA7IG4gPCA0OyArK24pIHsKICAgICAgbWl4W25dW2VdID0gbWU7CiAgICAgIGltaXhbbl1bc3hdID0gaW1lOwogICAgICAvLyBjeWNsZSB0aGUgcmlnaHQgbW9zdCBieXRlIHRvIHRoZSBsZWZ0IG1vc3QgcG9zaXRpb24KICAgICAgLy8gaWU6IDIsMSwxLDMgYmVjb21lcyAzLDIsMSwxCiAgICAgIG1lID0gbWUgPDwgMjQgfCBtZSA+Pj4gODsKICAgICAgaW1lID0gaW1lIDw8IDI0IHwgaW1lID4+PiA4OwogICAgfQoKICAgIC8vIGdldCBuZXh0IGVsZW1lbnQgYW5kIGludmVyc2UKICAgIGlmKGUgPT09IDApIHsKICAgICAgLy8gMSBpcyB0aGUgaW52ZXJzZSBvZiAxCiAgICAgIGUgPSBlaSA9IDE7CiAgICB9IGVsc2UgewogICAgICAvLyBlID0gMmUgKyAyKjIqMiooMTBlKSkgPSBtdWx0aXBseSBlIGJ5IDgyIChjaG9zZW4gZ2VuZXJhdG9yKQogICAgICAvLyBlaSA9IGVpICsgMioyKmVpID0gbXVsdGlwbHkgZWkgYnkgNSAoaW52ZXJzZSBnZW5lcmF0b3IpCiAgICAgIGUgPSBlMiBeIHh0aW1lW3h0aW1lW3h0aW1lW2UyIF4gZThdXV07CiAgICAgIGVpIF49IHh0aW1lW3h0aW1lW2VpXV07CiAgICB9CiAgfQp9CgovKioKICogR2VuZXJhdGVzIGEga2V5IHNjaGVkdWxlIHVzaW5nIHRoZSBBRVMga2V5IGV4cGFuc2lvbiBhbGdvcml0aG0uCiAqCiAqIFRoZSBBRVMgYWxnb3JpdGhtIHRha2VzIHRoZSBDaXBoZXIgS2V5LCBLLCBhbmQgcGVyZm9ybXMgYSBLZXkgRXhwYW5zaW9uCiAqIHJvdXRpbmUgdG8gZ2VuZXJhdGUgYSBrZXkgc2NoZWR1bGUuIFRoZSBLZXkgRXhwYW5zaW9uIGdlbmVyYXRlcyBhIHRvdGFsCiAqIG9mIE5iKihOciArIDEpIHdvcmRzOiB0aGUgYWxnb3JpdGhtIHJlcXVpcmVzIGFuIGluaXRpYWwgc2V0IG9mIE5iIHdvcmRzLAogKiBhbmQgZWFjaCBvZiB0aGUgTnIgcm91bmRzIHJlcXVpcmVzIE5iIHdvcmRzIG9mIGtleSBkYXRhLiBUaGUgcmVzdWx0aW5nCiAqIGtleSBzY2hlZHVsZSBjb25zaXN0cyBvZiBhIGxpbmVhciBhcnJheSBvZiA0LWJ5dGUgd29yZHMsIGRlbm90ZWQgW3dpIF0sCiAqIHdpdGggaSBpbiB0aGUgcmFuZ2UgMCDiiaQgaSA8IE5iKE5yICsgMSkuCiAqCiAqIEtleUV4cGFuc2lvbihieXRlIGtleVs0Kk5rXSwgd29yZCB3W05iKihOcisxKV0sIE5rKQogKiBBRVMtMTI4IChOYj00LCBOaz00LCBOcj0xMCkKICogQUVTLTE5MiAoTmI9NCwgTms9NiwgTnI9MTIpCiAqIEFFUy0yNTYgKE5iPTQsIE5rPTgsIE5yPTE0KQogKiBOb3RlOiBOcj1Oays2LgogKgogKiBOYiBpcyB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgKDMyLWJpdCB3b3JkcykgY29tcHJpc2luZyB0aGUgU3RhdGUgKG9yCiAqIG51bWJlciBvZiBieXRlcyBpbiBhIGJsb2NrKS4gRm9yIEFFUywgTmI9NC4KICoKICogQHBhcmFtIGtleSB0aGUga2V5IHRvIHNjaGVkdWxlIChhcyBhbiBhcnJheSBvZiAzMi1iaXQgd29yZHMpLgogKiBAcGFyYW0gZGVjcnlwdCB0cnVlIHRvIG1vZGlmeSB0aGUga2V5IHNjaGVkdWxlIHRvIGRlY3J5cHQsIGZhbHNlIG5vdCB0by4KICoKICogQHJldHVybiB0aGUgZ2VuZXJhdGVkIGtleSBzY2hlZHVsZS4KICovCmZ1bmN0aW9uIF9leHBhbmRLZXkoa2V5LCBkZWNyeXB0KSB7CiAgLy8gY29weSB0aGUga2V5J3Mgd29yZHMgdG8gaW5pdGlhbGl6ZSB0aGUga2V5IHNjaGVkdWxlCiAgdmFyIHcgPSBrZXkuc2xpY2UoMCk7CgogIC8qIFJvdFdvcmQoKSB3aWxsIHJvdGF0ZSBhIHdvcmQsIG1vdmluZyB0aGUgZmlyc3QgYnl0ZSB0byB0aGUgbGFzdAogICAgYnl0ZSdzIHBvc2l0aW9uIChzaGlmdGluZyB0aGUgb3RoZXIgYnl0ZXMgbGVmdCkuCgogICAgV2Ugd2lsbCBiZSBnZXR0aW5nIHRoZSB2YWx1ZSBvZiBSY29uIGF0IGkgLyBOay4gJ2knIHdpbGwgaXRlcmF0ZQogICAgZnJvbSBOayB0byAoTmIgKiBOcisxKS4gTmsgPSA0ICg0IGJ5dGUga2V5KSwgTmIgPSA0ICg0IHdvcmRzIGluCiAgICBhIGJsb2NrKSwgTnIgPSBOayArIDYgKDEwKS4gVGhlcmVmb3JlICdpJyB3aWxsIGl0ZXJhdGUgZnJvbQogICAgNCB0byA0NCAoZXhjbHVzaXZlKS4gRWFjaCB0aW1lIHdlIGl0ZXJhdGUgNCB0aW1lcywgaSAvIE5rIHdpbGwKICAgIGluY3JlYXNlIGJ5IDEuIFdlIHVzZSBhIGNvdW50ZXIgaU5rIHRvIGtlZXAgdHJhY2sgb2YgdGhpcy4KICAgKi8KCiAgLy8gZ28gdGhyb3VnaCB0aGUgcm91bmRzIGV4cGFuZGluZyB0aGUga2V5CiAgdmFyIHRlbXAsIGlOayA9IDE7CiAgdmFyIE5rID0gdy5sZW5ndGg7CiAgdmFyIE5yMSA9IE5rICsgNiArIDE7CiAgdmFyIGVuZCA9IE5iICogTnIxOwogIGZvcih2YXIgaSA9IE5rOyBpIDwgZW5kOyArK2kpIHsKICAgIHRlbXAgPSB3W2kgLSAxXTsKICAgIGlmKGkgJSBOayA9PT0gMCkgewogICAgICAvLyB0ZW1wID0gU3ViV29yZChSb3RXb3JkKHRlbXApKSBeIFJjb25baSAvIE5rXQogICAgICB0ZW1wID0KICAgICAgICBzYm94W3RlbXAgPj4+IDE2ICYgMjU1XSA8PCAyNCBeCiAgICAgICAgc2JveFt0ZW1wID4+PiA4ICYgMjU1XSA8PCAxNiBeCiAgICAgICAgc2JveFt0ZW1wICYgMjU1XSA8PCA4IF4KICAgICAgICBzYm94W3RlbXAgPj4+IDI0XSBeIChyY29uW2lOa10gPDwgMjQpOwogICAgICBpTmsrKzsKICAgIH0gZWxzZSBpZihOayA+IDYgJiYgKGkgJSBOayA9PT0gNCkpIHsKICAgICAgLy8gdGVtcCA9IFN1YldvcmQodGVtcCkKICAgICAgdGVtcCA9CiAgICAgICAgc2JveFt0ZW1wID4+PiAyNF0gPDwgMjQgXgogICAgICAgIHNib3hbdGVtcCA+Pj4gMTYgJiAyNTVdIDw8IDE2IF4KICAgICAgICBzYm94W3RlbXAgPj4+IDggJiAyNTVdIDw8IDggXgogICAgICAgIHNib3hbdGVtcCAmIDI1NV07CiAgICB9CiAgICB3W2ldID0gd1tpIC0gTmtdIF4gdGVtcDsKICB9CgogICAvKiBXaGVuIHdlIGFyZSB1cGRhdGluZyBhIGNpcGhlciBibG9jayB3ZSBhbHdheXMgdXNlIHRoZSBjb2RlIHBhdGggZm9yCiAgICAgZW5jcnlwdGlvbiB3aGV0aGVyIHdlIGFyZSBkZWNyeXB0aW5nIG9yIG5vdCAodG8gc2hvcnRlbiBjb2RlIGFuZAogICAgIHNpbXBsaWZ5IHRoZSBnZW5lcmF0aW9uIG9mIGxvb2sgdXAgdGFibGVzKS4gSG93ZXZlciwgYmVjYXVzZSB0aGVyZQogICAgIGFyZSBkaWZmZXJlbmNlcyBpbiB0aGUgZGVjcnlwdGlvbiBhbGdvcml0aG0sIG90aGVyIHRoYW4ganVzdCBzd2FwcGluZwogICAgIGluIGRpZmZlcmVudCBsb29rIHVwIHRhYmxlcywgd2UgbXVzdCB0cmFuc2Zvcm0gb3VyIGtleSBzY2hlZHVsZSB0bwogICAgIGFjY291bnQgZm9yIHRoZXNlIGNoYW5nZXM6CgogICAgIDEuIFRoZSBkZWNyeXB0aW9uIGFsZ29yaXRobSBnZXRzIGl0cyBrZXkgcm91bmRzIGluIHJldmVyc2Ugb3JkZXIuCiAgICAgMi4gVGhlIGRlY3J5cHRpb24gYWxnb3JpdGhtIGFkZHMgdGhlIHJvdW5kIGtleSBiZWZvcmUgbWl4aW5nIGNvbHVtbnMKICAgICAgIGluc3RlYWQgb2YgYWZ0ZXJ3YXJkcy4KCiAgICAgV2UgZG9uJ3QgbmVlZCB0byBtb2RpZnkgb3VyIGtleSBzY2hlZHVsZSB0byBoYW5kbGUgdGhlIGZpcnN0IGNhc2UsCiAgICAgd2UgY2FuIGp1c3QgdHJhdmVyc2UgdGhlIGtleSBzY2hlZHVsZSBpbiByZXZlcnNlIG9yZGVyIHdoZW4gZGVjcnlwdGluZy4KCiAgICAgVGhlIHNlY29uZCBjYXNlIHJlcXVpcmVzIGEgbGl0dGxlIHdvcmsuCgogICAgIFRoZSB0YWJsZXMgd2UgYnVpbHQgZm9yIHBlcmZvcm1pbmcgcm91bmRzIHdpbGwgdGFrZSBhbiBpbnB1dCBhbmQgdGhlbgogICAgIHBlcmZvcm0gU3ViQnl0ZXMoKSBhbmQgTWl4Q29sdW1ucygpIG9yLCBmb3IgdGhlIGRlY3J5cHQgdmVyc2lvbiwKICAgICBJbnZTdWJCeXRlcygpIGFuZCBJbnZNaXhDb2x1bW5zKCkuIEJ1dCB0aGUgZGVjcnlwdCBhbGdvcml0aG0gcmVxdWlyZXMKICAgICB1cyB0byBBZGRSb3VuZEtleSgpIGJlZm9yZSBJbnZNaXhDb2x1bW5zKCkuIFRoaXMgbWVhbnMgd2UnbGwgbmVlZCB0bwogICAgIGFwcGx5IHNvbWUgdHJhbnNmb3JtYXRpb25zIHRvIHRoZSByb3VuZCBrZXkgdG8gaW52ZXJzZS1taXggaXRzIGNvbHVtbnMKICAgICBzbyB0aGV5J2xsIGJlIGNvcnJlY3QgZm9yIG1vdmluZyBBZGRSb3VuZEtleSgpIHRvIGFmdGVyIHRoZSBzdGF0ZSBoYXMKICAgICBoYWQgaXRzIGNvbHVtbnMgaW52ZXJzZS1taXhlZC4KCiAgICAgVG8gaW52ZXJzZS1taXggdGhlIGNvbHVtbnMgb2YgdGhlIHN0YXRlIHdoZW4gd2UncmUgZGVjcnlwdGluZyB3ZSB1c2UgYQogICAgIGxvb2t1cCB0YWJsZSB0aGF0IHdpbGwgYXBwbHkgSW52U3ViQnl0ZXMoKSBhbmQgSW52TWl4Q29sdW1ucygpIGF0IHRoZQogICAgIHNhbWUgdGltZS4gSG93ZXZlciwgdGhlIHJvdW5kIGtleSdzIGJ5dGVzIGFyZSBub3QgaW52ZXJzZS1zdWJzdGl0dXRlZAogICAgIGluIHRoZSBkZWNyeXB0aW9uIGFsZ29yaXRobS4gVG8gZ2V0IGFyb3VuZCB0aGlzIHByb2JsZW0sIHdlIGNhbiBmaXJzdAogICAgIHN1YnN0aXR1dGUgdGhlIGJ5dGVzIGluIHRoZSByb3VuZCBrZXkgc28gdGhhdCB3aGVuIHdlIGFwcGx5IHRoZQogICAgIHRyYW5zZm9ybWF0aW9uIHZpYSB0aGUgSW52U3ViQnl0ZXMoKStJbnZNaXhDb2x1bW5zKCkgdGFibGUsIGl0IHdpbGwKICAgICB1bmRvIG91ciBzdWJzdGl0dXRpb24gbGVhdmluZyB1cyB3aXRoIHRoZSBvcmlnaW5hbCB2YWx1ZSB0aGF0IHdlCiAgICAgd2FudCAtLSBhbmQgdGhlbiBpbnZlcnNlLW1peCB0aGF0IHZhbHVlLgoKICAgICBUaGlzIGNoYW5nZSB3aWxsIGNvcnJlY3RseSBhbHRlciBvdXIga2V5IHNjaGVkdWxlIHNvIHRoYXQgd2UgY2FuIFhPUgogICAgIGVhY2ggcm91bmQga2V5IHdpdGggb3VyIGFscmVhZHkgdHJhbnNmb3JtZWQgZGVjcnlwdGlvbiBzdGF0ZS4gVGhpcwogICAgIGFsbG93cyB1cyB0byB1c2UgdGhlIHNhbWUgY29kZSBwYXRoIGFzIHRoZSBlbmNyeXB0aW9uIGFsZ29yaXRobS4KCiAgICAgV2UgbWFrZSBvbmUgbW9yZSBjaGFuZ2UgdG8gdGhlIGRlY3J5cHRpb24ga2V5LiBTaW5jZSB0aGUgZGVjcnlwdGlvbgogICAgIGFsZ29yaXRobSBydW5zIGluIHJldmVyc2UgZnJvbSB0aGUgZW5jcnlwdGlvbiBhbGdvcml0aG0sIHdlIHJldmVyc2UKICAgICB0aGUgb3JkZXIgb2YgdGhlIHJvdW5kIGtleXMgdG8gYXZvaWQgaGF2aW5nIHRvIGl0ZXJhdGUgb3ZlciB0aGUga2V5CiAgICAgc2NoZWR1bGUgYmFja3dhcmRzIHdoZW4gcnVubmluZyB0aGUgZW5jcnlwdGlvbiBhbGdvcml0aG0gbGF0ZXIgaW4KICAgICBkZWNyeXB0aW9uIG1vZGUuIEluIGFkZGl0aW9uIHRvIHJldmVyc2luZyB0aGUgb3JkZXIgb2YgdGhlIHJvdW5kIGtleXMsCiAgICAgd2UgYWxzbyBzd2FwIGVhY2ggcm91bmQga2V5J3MgMm5kIGFuZCA0dGggcm93cy4gU2VlIHRoZSBjb21tZW50cwogICAgIHNlY3Rpb24gd2hlcmUgcm91bmRzIGFyZSBwZXJmb3JtZWQgZm9yIG1vcmUgZGV0YWlscyBhYm91dCB3aHkgdGhpcyBpcwogICAgIGRvbmUuIFRoZXNlIGNoYW5nZXMgYXJlIGRvbmUgaW5saW5lIHdpdGggdGhlIG90aGVyIHN1YnN0aXR1dGlvbgogICAgIGRlc2NyaWJlZCBhYm92ZS4KICAqLwogIGlmKGRlY3J5cHQpIHsKICAgIHZhciB0bXA7CiAgICB2YXIgbTAgPSBpbWl4WzBdOwogICAgdmFyIG0xID0gaW1peFsxXTsKICAgIHZhciBtMiA9IGltaXhbMl07CiAgICB2YXIgbTMgPSBpbWl4WzNdOwogICAgdmFyIHduZXcgPSB3LnNsaWNlKDApOwogICAgZW5kID0gdy5sZW5ndGg7CiAgICBmb3IodmFyIGkgPSAwLCB3aSA9IGVuZCAtIE5iOyBpIDwgZW5kOyBpICs9IE5iLCB3aSAtPSBOYikgewogICAgICAvLyBkbyBub3Qgc3ViIHRoZSBmaXJzdCBvciBsYXN0IHJvdW5kIGtleSAocm91bmQga2V5cyBhcmUgTmIKICAgICAgLy8gd29yZHMpIGFzIG5vIGNvbHVtbiBtaXhpbmcgaXMgcGVyZm9ybWVkIGJlZm9yZSB0aGV5IGFyZSBhZGRlZCwKICAgICAgLy8gYnV0IGRvIGNoYW5nZSB0aGUga2V5IG9yZGVyCiAgICAgIGlmKGkgPT09IDAgfHwgaSA9PT0gKGVuZCAtIE5iKSkgewogICAgICAgIHduZXdbaV0gPSB3W3dpXTsKICAgICAgICB3bmV3W2kgKyAxXSA9IHdbd2kgKyAzXTsKICAgICAgICB3bmV3W2kgKyAyXSA9IHdbd2kgKyAyXTsKICAgICAgICB3bmV3W2kgKyAzXSA9IHdbd2kgKyAxXTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBzdWJzdGl0dXRlIGVhY2ggcm91bmQga2V5IGJ5dGUgYmVjYXVzZSB0aGUgaW52ZXJzZS1taXgKICAgICAgICAvLyB0YWJsZSB3aWxsIGludmVyc2Utc3Vic3RpdHV0ZSBpdCAoZWZmZWN0aXZlbHkgY2FuY2VsIHRoZQogICAgICAgIC8vIHN1YnN0aXR1dGlvbiBiZWNhdXNlIHJvdW5kIGtleSBieXRlcyBhcmVuJ3Qgc3ViJ2QgaW4KICAgICAgICAvLyBkZWNyeXB0aW9uIG1vZGUpIGFuZCBzd2FwIGluZGV4ZXMgMyBhbmQgMQogICAgICAgIGZvcih2YXIgbiA9IDA7IG4gPCBOYjsgKytuKSB7CiAgICAgICAgICB0bXAgPSB3W3dpICsgbl07CiAgICAgICAgICB3bmV3W2kgKyAoMyYtbildID0KICAgICAgICAgICAgbTBbc2JveFt0bXAgPj4+IDI0XV0gXgogICAgICAgICAgICBtMVtzYm94W3RtcCA+Pj4gMTYgJiAyNTVdXSBeCiAgICAgICAgICAgIG0yW3Nib3hbdG1wID4+PiA4ICYgMjU1XV0gXgogICAgICAgICAgICBtM1tzYm94W3RtcCAmIDI1NV1dOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgdyA9IHduZXc7CiAgfQoKICByZXR1cm4gdzsKfQoKLyoqCiAqIFVwZGF0ZXMgYSBzaW5nbGUgYmxvY2sgKDE2IGJ5dGVzKSB1c2luZyBBRVMuIFRoZSB1cGRhdGUgd2lsbCBlaXRoZXIKICogZW5jcnlwdCBvciBkZWNyeXB0IHRoZSBibG9jay4KICoKICogQHBhcmFtIHcgdGhlIGtleSBzY2hlZHVsZS4KICogQHBhcmFtIGlucHV0IHRoZSBpbnB1dCBibG9jayAoYW4gYXJyYXkgb2YgMzItYml0IHdvcmRzKS4KICogQHBhcmFtIG91dHB1dCB0aGUgdXBkYXRlZCBvdXRwdXQgYmxvY2suCiAqIEBwYXJhbSBkZWNyeXB0IHRydWUgdG8gZGVjcnlwdCB0aGUgYmxvY2ssIGZhbHNlIHRvIGVuY3J5cHQgaXQuCiAqLwpmdW5jdGlvbiBfdXBkYXRlQmxvY2sodywgaW5wdXQsIG91dHB1dCwgZGVjcnlwdCkgewogIC8qCiAgQ2lwaGVyKGJ5dGUgaW5bNCpOYl0sIGJ5dGUgb3V0WzQqTmJdLCB3b3JkIHdbTmIqKE5yKzEpXSkKICBiZWdpbgogICAgYnl0ZSBzdGF0ZVs0LE5iXQogICAgc3RhdGUgPSBpbgogICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbMCwgTmItMV0pCiAgICBmb3Igcm91bmQgPSAxIHN0ZXAgMSB0byBOcuKAkzEKICAgICAgU3ViQnl0ZXMoc3RhdGUpCiAgICAgIFNoaWZ0Um93cyhzdGF0ZSkKICAgICAgTWl4Q29sdW1ucyhzdGF0ZSkKICAgICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbcm91bmQqTmIsIChyb3VuZCsxKSpOYi0xXSkKICAgIGVuZCBmb3IKICAgIFN1YkJ5dGVzKHN0YXRlKQogICAgU2hpZnRSb3dzKHN0YXRlKQogICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbTnIqTmIsIChOcisxKSpOYi0xXSkKICAgIG91dCA9IHN0YXRlCiAgZW5kCgogIEludkNpcGhlcihieXRlIGluWzQqTmJdLCBieXRlIG91dFs0Kk5iXSwgd29yZCB3W05iKihOcisxKV0pCiAgYmVnaW4KICAgIGJ5dGUgc3RhdGVbNCxOYl0KICAgIHN0YXRlID0gaW4KICAgIEFkZFJvdW5kS2V5KHN0YXRlLCB3W05yKk5iLCAoTnIrMSkqTmItMV0pCiAgICBmb3Igcm91bmQgPSBOci0xIHN0ZXAgLTEgZG93bnRvIDEKICAgICAgSW52U2hpZnRSb3dzKHN0YXRlKQogICAgICBJbnZTdWJCeXRlcyhzdGF0ZSkKICAgICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbcm91bmQqTmIsIChyb3VuZCsxKSpOYi0xXSkKICAgICAgSW52TWl4Q29sdW1ucyhzdGF0ZSkKICAgIGVuZCBmb3IKICAgIEludlNoaWZ0Um93cyhzdGF0ZSkKICAgIEludlN1YkJ5dGVzKHN0YXRlKQogICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbMCwgTmItMV0pCiAgICBvdXQgPSBzdGF0ZQogIGVuZAogICovCgogIC8vIEVuY3J5cHQ6IEFkZFJvdW5kS2V5KHN0YXRlLCB3WzAsIE5iLTFdKQogIC8vIERlY3J5cHQ6IEFkZFJvdW5kS2V5KHN0YXRlLCB3W05yKk5iLCAoTnIrMSkqTmItMV0pCiAgdmFyIE5yID0gdy5sZW5ndGggLyA0IC0gMTsKICB2YXIgbTAsIG0xLCBtMiwgbTMsIHN1YjsKICBpZihkZWNyeXB0KSB7CiAgICBtMCA9IGltaXhbMF07CiAgICBtMSA9IGltaXhbMV07CiAgICBtMiA9IGltaXhbMl07CiAgICBtMyA9IGltaXhbM107CiAgICBzdWIgPSBpc2JveDsKICB9IGVsc2UgewogICAgbTAgPSBtaXhbMF07CiAgICBtMSA9IG1peFsxXTsKICAgIG0yID0gbWl4WzJdOwogICAgbTMgPSBtaXhbM107CiAgICBzdWIgPSBzYm94OwogIH0KICB2YXIgYSwgYiwgYywgZCwgYTIsIGIyLCBjMjsKICBhID0gaW5wdXRbMF0gXiB3WzBdOwogIGIgPSBpbnB1dFtkZWNyeXB0ID8gMyA6IDFdIF4gd1sxXTsKICBjID0gaW5wdXRbMl0gXiB3WzJdOwogIGQgPSBpbnB1dFtkZWNyeXB0ID8gMSA6IDNdIF4gd1szXTsKICB2YXIgaSA9IDM7CgogIC8qIEluIG9yZGVyIHRvIHNoYXJlIGNvZGUgd2UgZm9sbG93IHRoZSBlbmNyeXB0aW9uIGFsZ29yaXRobSB3aGVuIGJvdGgKICAgIGVuY3J5cHRpbmcgYW5kIGRlY3J5cHRpbmcuIFRvIGFjY291bnQgZm9yIHRoZSBjaGFuZ2VzIHJlcXVpcmVkIGluIHRoZQogICAgZGVjcnlwdGlvbiBhbGdvcml0aG0sIHdlIHVzZSBkaWZmZXJlbnQgbG9va3VwIHRhYmxlcyB3aGVuIGRlY3J5cHRpbmcKICAgIGFuZCB1c2UgYSBtb2RpZmllZCBrZXkgc2NoZWR1bGUgdG8gYWNjb3VudCBmb3IgdGhlIGRpZmZlcmVuY2UgaW4gdGhlCiAgICBvcmRlciBvZiB0cmFuc2Zvcm1hdGlvbnMgYXBwbGllZCB3aGVuIHBlcmZvcm1pbmcgcm91bmRzLiBXZSBhbHNvIGdldAogICAga2V5IHJvdW5kcyBpbiByZXZlcnNlIG9yZGVyIChyZWxhdGl2ZSB0byBlbmNyeXB0aW9uKS4gKi8KICBmb3IodmFyIHJvdW5kID0gMTsgcm91bmQgPCBOcjsgKytyb3VuZCkgewogICAgLyogQXMgZGVzY3JpYmVkIGFib3ZlLCB3ZSdsbCBiZSB1c2luZyB0YWJsZSBsb29rdXBzIHRvIHBlcmZvcm0gdGhlCiAgICAgIGNvbHVtbiBtaXhpbmcuIEVhY2ggY29sdW1uIGlzIHN0b3JlZCBhcyBhIHdvcmQgaW4gdGhlIHN0YXRlICh0aGUKICAgICAgYXJyYXkgJ2lucHV0JyBoYXMgb25lIGNvbHVtbiBhcyBhIHdvcmQgYXQgZWFjaCBpbmRleCkuIEluIG9yZGVyIHRvCiAgICAgIG1peCBhIGNvbHVtbiwgd2UgcGVyZm9ybSB0aGVzZSB0cmFuc2Zvcm1hdGlvbnMgb24gZWFjaCByb3cgaW4gYywKICAgICAgd2hpY2ggaXMgMSBieXRlIGluIGVhY2ggd29yZC4gVGhlIG5ldyBjb2x1bW4gZm9yIGMwIGlzIGMnMDoKCiAgICAgICAgICAgICAgIG0wICAgICAgbTEgICAgICBtMiAgICAgIG0zCiAgICAgIHIwLGMnMCA9IDIqcjAsYzAgKyAzKnIxLGMwICsgMSpyMixjMCArIDEqcjMsYzAKICAgICAgcjEsYycwID0gMSpyMCxjMCArIDIqcjEsYzAgKyAzKnIyLGMwICsgMSpyMyxjMAogICAgICByMixjJzAgPSAxKnIwLGMwICsgMSpyMSxjMCArIDIqcjIsYzAgKyAzKnIzLGMwCiAgICAgIHIzLGMnMCA9IDMqcjAsYzAgKyAxKnIxLGMwICsgMSpyMixjMCArIDIqcjMsYzAKCiAgICAgIFNvIHVzaW5nIG1peCB0YWJsZXMgd2hlcmUgYzAgaXMgYSB3b3JkIHdpdGggcjAgYmVpbmcgaXRzIHVwcGVyCiAgICAgIDggYml0cyBhbmQgcjMgYmVpbmcgaXRzIGxvd2VyIDggYml0czoKCiAgICAgIG0wW2MwID4+IDI0XSB3aWxsIHlpZWxkIHRoaXMgd29yZDogWzIqcjAsMSpyMCwxKnIwLDMqcjBdCiAgICAgIC4uLgogICAgICBtM1tjMCAmIDI1NV0gd2lsbCB5aWVsZCB0aGlzIHdvcmQ6IFsxKnIzLDEqcjMsMypyMywyKnIzXQoKICAgICAgVGhlcmVmb3JlIHRvIG1peCB0aGUgY29sdW1ucyBpbiBlYWNoIHdvcmQgaW4gdGhlIHN0YXRlIHdlCiAgICAgIGRvIHRoZSBmb2xsb3dpbmcgKCYgMjU1IG9taXR0ZWQgZm9yIGJyZXZpdHkpOgogICAgICBjJzAscjAgPSBtMFtjMCA+PiAyNF0gXiBtMVtjMSA+PiAxNl0gXiBtMltjMiA+PiA4XSBeIG0zW2MzXQogICAgICBjJzAscjEgPSBtMFtjMCA+PiAyNF0gXiBtMVtjMSA+PiAxNl0gXiBtMltjMiA+PiA4XSBeIG0zW2MzXQogICAgICBjJzAscjIgPSBtMFtjMCA+PiAyNF0gXiBtMVtjMSA+PiAxNl0gXiBtMltjMiA+PiA4XSBeIG0zW2MzXQogICAgICBjJzAscjMgPSBtMFtjMCA+PiAyNF0gXiBtMVtjMSA+PiAxNl0gXiBtMltjMiA+PiA4XSBeIG0zW2MzXQoKICAgICAgSG93ZXZlciwgYmVmb3JlIG1peGluZywgdGhlIGFsZ29yaXRobSByZXF1aXJlcyB1cyB0byBwZXJmb3JtCiAgICAgIFNoaWZ0Um93cygpLiBUaGUgU2hpZnRSb3dzKCkgdHJhbnNmb3JtYXRpb24gY3ljbGljYWxseSBzaGlmdHMgdGhlCiAgICAgIGxhc3QgMyByb3dzIG9mIHRoZSBzdGF0ZSBvdmVyIGRpZmZlcmVudCBvZmZzZXRzLiBUaGUgZmlyc3Qgcm93CiAgICAgIChyID0gMCkgaXMgbm90IHNoaWZ0ZWQuCgogICAgICBzJ19yLGMgPSBzX3IsKGMgKyBzaGlmdChyLCBOYikgbW9kIE5iCiAgICAgIGZvciAwIDwgciA8IDQgYW5kIDAgPD0gYyA8IE5iIGFuZAogICAgICBzaGlmdCgxLCA0KSA9IDEKICAgICAgc2hpZnQoMiwgNCkgPSAyCiAgICAgIHNoaWZ0KDMsIDQpID0gMy4KCiAgICAgIFRoaXMgY2F1c2VzIHRoZSBmaXJzdCBieXRlIGluIHIgPSAxIHRvIGJlIG1vdmVkIHRvIHRoZSBlbmQgb2YKICAgICAgdGhlIHJvdywgdGhlIGZpcnN0IDIgYnl0ZXMgaW4gciA9IDIgdG8gYmUgbW92ZWQgdG8gdGhlIGVuZCBvZgogICAgICB0aGUgcm93LCB0aGUgZmlyc3QgMyBieXRlcyBpbiByID0gMyB0byBiZSBtb3ZlZCB0byB0aGUgZW5kIG9mCiAgICAgIHRoZSByb3c6CgogICAgICByMTogW2MwIGMxIGMyIGMzXSA9PiBbYzEgYzIgYzMgYzBdCiAgICAgIHIyOiBbYzAgYzEgYzIgYzNdICAgIFtjMiBjMyBjMCBjMV0KICAgICAgcjM6IFtjMCBjMSBjMiBjM10gICAgW2MzIGMwIGMxIGMyXQoKICAgICAgV2UgY2FuIG1ha2UgdGhlc2Ugc3Vic3RpdHV0aW9ucyBpbmxpbmUgd2l0aCBvdXIgY29sdW1uIG1peGluZyB0bwogICAgICBnZW5lcmF0ZSBhbiB1cGRhdGVkIHNldCBvZiBlcXVhdGlvbnMgdG8gcHJvZHVjZSBlYWNoIHdvcmQgaW4gdGhlCiAgICAgIHN0YXRlIChub3RlIHRoZSBjb2x1bW5zIGhhdmUgY2hhbmdlZCBwb3NpdGlvbnMpOgoKICAgICAgYzAgYzEgYzIgYzMgPT4gYzAgYzEgYzIgYzMKICAgICAgYzAgYzEgYzIgYzMgICAgYzEgYzIgYzMgYzAgIChjeWNsZWQgMSBieXRlKQogICAgICBjMCBjMSBjMiBjMyAgICBjMiBjMyBjMCBjMSAgKGN5Y2xlZCAyIGJ5dGVzKQogICAgICBjMCBjMSBjMiBjMyAgICBjMyBjMCBjMSBjMiAgKGN5Y2xlZCAzIGJ5dGVzKQoKICAgICAgVGhlcmVmb3JlOgoKICAgICAgYycwID0gMipyMCxjMCArIDMqcjEsYzEgKyAxKnIyLGMyICsgMSpyMyxjMwogICAgICBjJzAgPSAxKnIwLGMwICsgMipyMSxjMSArIDMqcjIsYzIgKyAxKnIzLGMzCiAgICAgIGMnMCA9IDEqcjAsYzAgKyAxKnIxLGMxICsgMipyMixjMiArIDMqcjMsYzMKICAgICAgYycwID0gMypyMCxjMCArIDEqcjEsYzEgKyAxKnIyLGMyICsgMipyMyxjMwoKICAgICAgYycxID0gMipyMCxjMSArIDMqcjEsYzIgKyAxKnIyLGMzICsgMSpyMyxjMAogICAgICBjJzEgPSAxKnIwLGMxICsgMipyMSxjMiArIDMqcjIsYzMgKyAxKnIzLGMwCiAgICAgIGMnMSA9IDEqcjAsYzEgKyAxKnIxLGMyICsgMipyMixjMyArIDMqcjMsYzAKICAgICAgYycxID0gMypyMCxjMSArIDEqcjEsYzIgKyAxKnIyLGMzICsgMipyMyxjMAoKICAgICAgLi4uIGFuZCBzbyBmb3J0aCBmb3IgYycyIGFuZCBjJzMuIFRoZSBpbXBvcnRhbnQgZGlzdGluY3Rpb24gaXMKICAgICAgdGhhdCB0aGUgY29sdW1ucyBhcmUgY3ljbGluZywgd2l0aCBjMCBiZWluZyB1c2VkIHdpdGggdGhlIG0wCiAgICAgIG1hcCB3aGVuIGNhbGN1bGF0aW5nIGMwLCBidXQgYzEgYmVpbmcgdXNlZCB3aXRoIHRoZSBtMCBtYXAgd2hlbgogICAgICBjYWxjdWxhdGluZyBjMSAuLi4gYW5kIHNvIGZvcnRoLgoKICAgICAgV2hlbiBwZXJmb3JtaW5nIHRoZSBpbnZlcnNlIHdlIHRyYW5zZm9ybSB0aGUgbWlycm9yIGltYWdlIGFuZAogICAgICBza2lwIHRoZSBib3R0b20gcm93LCBpbnN0ZWFkIG9mIHRoZSB0b3Agb25lLCBhbmQgbW92ZSB1cHdhcmRzOgoKICAgICAgYzMgYzIgYzEgYzAgPT4gYzAgYzMgYzIgYzEgIChjeWNsZWQgMyBieXRlcykgKnNhbWUgYXMgZW5jcnlwdGlvbgogICAgICBjMyBjMiBjMSBjMCAgICBjMSBjMCBjMyBjMiAgKGN5Y2xlZCAyIGJ5dGVzKQogICAgICBjMyBjMiBjMSBjMCAgICBjMiBjMSBjMCBjMyAgKGN5Y2xlZCAxIGJ5dGUpICAqc2FtZSBhcyBlbmNyeXB0aW9uCiAgICAgIGMzIGMyIGMxIGMwICAgIGMzIGMyIGMxIGMwCgogICAgICBJZiB5b3UgY29tcGFyZSB0aGUgcmVzdWx0aW5nIG1hdHJpY2VzIGZvciBTaGlmdFJvd3MoKStNaXhDb2x1bW5zKCkKICAgICAgYW5kIGZvciBJbnZTaGlmdFJvd3MoKStJbnZNaXhDb2x1bW5zKCkgdGhlIDJuZCBhbmQgNHRoIGNvbHVtbnMgYXJlCiAgICAgIGRpZmZlcmVudCAoaW4gZW5jcnlwdCBtb2RlIHZzLiBkZWNyeXB0IG1vZGUpLiBTbyBpbiBvcmRlciB0byB1c2UKICAgICAgdGhlIHNhbWUgY29kZSB0byBoYW5kbGUgYm90aCBlbmNyeXB0aW9uIGFuZCBkZWNyeXB0aW9uLCB3ZSB3aWxsCiAgICAgIG5lZWQgdG8gZG8gc29tZSBtYXBwaW5nLgoKICAgICAgSWYgaW4gZW5jcnlwdGlvbiBtb2RlIHdlIGxldCBhPWMwLCBiPWMxLCBjPWMyLCBkPWMzLCBhbmQgcjxOPiBiZQogICAgICBhIHJvdyBudW1iZXIgaW4gdGhlIHN0YXRlLCB0aGVuIHRoZSByZXN1bHRpbmcgbWF0cml4IGluIGVuY3J5cHRpb24KICAgICAgbW9kZSBmb3IgYXBwbHlpbmcgdGhlIGFib3ZlIHRyYW5zZm9ybWF0aW9ucyB3b3VsZCBiZToKCiAgICAgIHIxOiBhIGIgYyBkCiAgICAgIHIyOiBiIGMgZCBhCiAgICAgIHIzOiBjIGQgYSBiCiAgICAgIHI0OiBkIGEgYiBjCgogICAgICBJZiB3ZSBkaWQgdGhlIHNhbWUgaW4gZGVjcnlwdGlvbiBtb2RlIHdlIHdvdWxkIGdldDoKCiAgICAgIHIxOiBhIGQgYyBiCiAgICAgIHIyOiBiIGEgZCBjCiAgICAgIHIzOiBjIGIgYSBkCiAgICAgIHI0OiBkIGMgYiBhCgogICAgICBJZiBpbnN0ZWFkIHdlIHN3YXAgZCBhbmQgYiAoc2V0IGI9YzMgYW5kIGQ9YzEpLCB0aGVuIHdlIGdldDoKCiAgICAgIHIxOiBhIGIgYyBkCiAgICAgIHIyOiBkIGEgYiBjCiAgICAgIHIzOiBjIGQgYSBiCiAgICAgIHI0OiBiIGMgZCBhCgogICAgICBOb3cgdGhlIDFzdCBhbmQgM3JkIHJvd3MgYXJlIHRoZSBzYW1lIGFzIHRoZSBlbmNyeXB0aW9uIG1hdHJpeC4gQWxsCiAgICAgIHdlIG5lZWQgdG8gZG8gdGhlbiB0byBtYWtlIHRoZSBtYXBwaW5nIGV4YWN0bHkgdGhlIHNhbWUgaXMgdG8gc3dhcAogICAgICB0aGUgMm5kIGFuZCA0dGggcm93cyB3aGVuIGluIGRlY3J5cHRpb24gbW9kZS4gVG8gZG8gdGhpcyB3aXRob3V0CiAgICAgIGhhdmluZyB0byBkbyBpdCBvbiBlYWNoIGl0ZXJhdGlvbiwgd2Ugc3dhcHBlZCB0aGUgMm5kIGFuZCA0dGggcm93cwogICAgICBpbiB0aGUgZGVjcnlwdGlvbiBrZXkgc2NoZWR1bGUuIFdlIGFsc28gaGF2ZSB0byBkbyB0aGUgc3dhcCBhYm92ZQogICAgICB3aGVuIHdlIGZpcnN0IHB1bGwgaW4gdGhlIGlucHV0IGFuZCB3aGVuIHdlIHNldCB0aGUgZmluYWwgb3V0cHV0LiAqLwogICAgYTIgPQogICAgICBtMFthID4+PiAyNF0gXgogICAgICBtMVtiID4+PiAxNiAmIDI1NV0gXgogICAgICBtMltjID4+PiA4ICYgMjU1XSBeCiAgICAgIG0zW2QgJiAyNTVdIF4gd1srK2ldOwogICAgYjIgPQogICAgICBtMFtiID4+PiAyNF0gXgogICAgICBtMVtjID4+PiAxNiAmIDI1NV0gXgogICAgICBtMltkID4+PiA4ICYgMjU1XSBeCiAgICAgIG0zW2EgJiAyNTVdIF4gd1srK2ldOwogICAgYzIgPQogICAgICBtMFtjID4+PiAyNF0gXgogICAgICBtMVtkID4+PiAxNiAmIDI1NV0gXgogICAgICBtMlthID4+PiA4ICYgMjU1XSBeCiAgICAgIG0zW2IgJiAyNTVdIF4gd1srK2ldOwogICAgZCA9CiAgICAgIG0wW2QgPj4+IDI0XSBeCiAgICAgIG0xW2EgPj4+IDE2ICYgMjU1XSBeCiAgICAgIG0yW2IgPj4+IDggJiAyNTVdIF4KICAgICAgbTNbYyAmIDI1NV0gXiB3WysraV07CiAgICBhID0gYTI7CiAgICBiID0gYjI7CiAgICBjID0gYzI7CiAgfQoKICAvKgogICAgRW5jcnlwdDoKICAgIFN1YkJ5dGVzKHN0YXRlKQogICAgU2hpZnRSb3dzKHN0YXRlKQogICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbTnIqTmIsIChOcisxKSpOYi0xXSkKCiAgICBEZWNyeXB0OgogICAgSW52U2hpZnRSb3dzKHN0YXRlKQogICAgSW52U3ViQnl0ZXMoc3RhdGUpCiAgICBBZGRSb3VuZEtleShzdGF0ZSwgd1swLCBOYi0xXSkKICAgKi8KICAgLy8gTm90ZTogcm93cyBhcmUgc2hpZnRlZCBpbmxpbmUKICBvdXRwdXRbMF0gPQogICAgKHN1YlthID4+PiAyNF0gPDwgMjQpIF4KICAgIChzdWJbYiA+Pj4gMTYgJiAyNTVdIDw8IDE2KSBeCiAgICAoc3ViW2MgPj4+IDggJiAyNTVdIDw8IDgpIF4KICAgIChzdWJbZCAmIDI1NV0pIF4gd1srK2ldOwogIG91dHB1dFtkZWNyeXB0ID8gMyA6IDFdID0KICAgIChzdWJbYiA+Pj4gMjRdIDw8IDI0KSBeCiAgICAoc3ViW2MgPj4+IDE2ICYgMjU1XSA8PCAxNikgXgogICAgKHN1YltkID4+PiA4ICYgMjU1XSA8PCA4KSBeCiAgICAoc3ViW2EgJiAyNTVdKSBeIHdbKytpXTsKICBvdXRwdXRbMl0gPQogICAgKHN1YltjID4+PiAyNF0gPDwgMjQpIF4KICAgIChzdWJbZCA+Pj4gMTYgJiAyNTVdIDw8IDE2KSBeCiAgICAoc3ViW2EgPj4+IDggJiAyNTVdIDw8IDgpIF4KICAgIChzdWJbYiAmIDI1NV0pIF4gd1srK2ldOwogIG91dHB1dFtkZWNyeXB0ID8gMSA6IDNdID0KICAgIChzdWJbZCA+Pj4gMjRdIDw8IDI0KSBeCiAgICAoc3ViW2EgPj4+IDE2ICYgMjU1XSA8PCAxNikgXgogICAgKHN1YltiID4+PiA4ICYgMjU1XSA8PCA4KSBeCiAgICAoc3ViW2MgJiAyNTVdKSBeIHdbKytpXTsKfQoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogZm9yZ2UuY2lwaGVyLmNyZWF0ZUNpcGhlcignQUVTLTxtb2RlPicsIGtleSk7CiAqIGZvcmdlLmNpcGhlci5jcmVhdGVEZWNpcGhlcignQUVTLTxtb2RlPicsIGtleSk7CiAqCiAqIENyZWF0ZXMgYSBkZXByZWNhdGVkIEFFUyBjaXBoZXIgb2JqZWN0LiBUaGlzIG9iamVjdCdzIG1vZGUgd2lsbCBkZWZhdWx0IHRvCiAqIENCQyAoY2lwaGVyLWJsb2NrLWNoYWluaW5nKS4KICoKICogVGhlIGtleSBhbmQgaXYgbWF5IGJlIGdpdmVuIGFzIGEgc3RyaW5nIG9mIGJ5dGVzLCBhbiBhcnJheSBvZiBieXRlcywgYQogKiBieXRlIGJ1ZmZlciwgb3IgYW4gYXJyYXkgb2YgMzItYml0IHdvcmRzLgogKgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2UuCiAqICAgICAgICAgIGtleSB0aGUgc3ltbWV0cmljIGtleSB0byB1c2UuCiAqICAgICAgICAgIG91dHB1dCB0aGUgYnVmZmVyIHRvIHdyaXRlIHRvLgogKiAgICAgICAgICBkZWNyeXB0IHRydWUgZm9yIGRlY3J5cHRpb24sIGZhbHNlIGZvciBlbmNyeXB0aW9uLgogKiAgICAgICAgICBtb2RlIHRoZSBjaXBoZXIgbW9kZSB0byB1c2UgKGRlZmF1bHQ6ICdDQkMnKS4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZnVuY3Rpb24gX2NyZWF0ZUNpcGhlcihvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdmFyIG1vZGUgPSAob3B0aW9ucy5tb2RlIHx8ICdDQkMnKS50b1VwcGVyQ2FzZSgpOwogIHZhciBhbGdvcml0aG0gPSAnQUVTLScgKyBtb2RlOwoKICB2YXIgY2lwaGVyOwogIGlmKG9wdGlvbnMuZGVjcnlwdCkgewogICAgY2lwaGVyID0gZm9yZ2UuY2lwaGVyLmNyZWF0ZURlY2lwaGVyKGFsZ29yaXRobSwgb3B0aW9ucy5rZXkpOwogIH0gZWxzZSB7CiAgICBjaXBoZXIgPSBmb3JnZS5jaXBoZXIuY3JlYXRlQ2lwaGVyKGFsZ29yaXRobSwgb3B0aW9ucy5rZXkpOwogIH0KCiAgLy8gYmFja3dhcmRzIGNvbXBhdGlibGUgc3RhcnQgQVBJCiAgdmFyIHN0YXJ0ID0gY2lwaGVyLnN0YXJ0OwogIGNpcGhlci5zdGFydCA9IGZ1bmN0aW9uKGl2LCBvcHRpb25zKSB7CiAgICAvLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eTogc3VwcG9ydCBzZWNvbmQgYXJnIGFzIG91dHB1dCBidWZmZXIKICAgIHZhciBvdXRwdXQgPSBudWxsOwogICAgaWYob3B0aW9ucyBpbnN0YW5jZW9mIGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcikgewogICAgICBvdXRwdXQgPSBvcHRpb25zOwogICAgICBvcHRpb25zID0ge307CiAgICB9CiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICAgIG9wdGlvbnMub3V0cHV0ID0gb3V0cHV0OwogICAgb3B0aW9ucy5pdiA9IGl2OwogICAgc3RhcnQuY2FsbChjaXBoZXIsIG9wdGlvbnMpOwogIH07CgogIHJldHVybiBjaXBoZXI7Cn0KCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ2Flcyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKAogICdqcy9hZXMnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9jaXBoZXInLCAnLi9jaXBoZXJNb2RlcycsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogT2JqZWN0IElEcyBmb3IgQVNOLjEuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDEzIERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKZm9yZ2UucGtpID0gZm9yZ2UucGtpIHx8IHt9Owp2YXIgb2lkcyA9IGZvcmdlLnBraS5vaWRzID0gZm9yZ2Uub2lkcyA9IGZvcmdlLm9pZHMgfHwge307CgovLyBhbGdvcml0aG0gT0lEcwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEuMSddID0gJ3JzYUVuY3J5cHRpb24nOwpvaWRzWydyc2FFbmNyeXB0aW9uJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xLjEnOwovLyBOb3RlOiBtZDIgJiBtZDQgbm90IGltcGxlbWVudGVkCi8vb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xLjInXSA9ICdtZDJXaXRoUlNBRW5jcnlwdGlvbic7Ci8vb2lkc1snbWQyV2l0aFJTQUVuY3J5cHRpb24nXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuMic7Ci8vb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xLjMnXSA9ICdtZDRXaXRoUlNBRW5jcnlwdGlvbic7Ci8vb2lkc1snbWQ0V2l0aFJTQUVuY3J5cHRpb24nXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuMyc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS40J10gPSAnbWQ1V2l0aFJTQUVuY3J5cHRpb24nOwpvaWRzWydtZDVXaXRoUlNBRW5jcnlwdGlvbiddID0gJzEuMi44NDAuMTEzNTQ5LjEuMS40JzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xLjUnXSA9ICdzaGExV2l0aFJTQUVuY3J5cHRpb24nOwpvaWRzWydzaGExV2l0aFJTQUVuY3J5cHRpb24nXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuNSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS43J10gPSAnUlNBRVMtT0FFUCc7Cm9pZHNbJ1JTQUVTLU9BRVAnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuNyc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS44J10gPSAnbWdmMSc7Cm9pZHNbJ21nZjEnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuOCc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS45J10gPSAncFNwZWNpZmllZCc7Cm9pZHNbJ3BTcGVjaWZpZWQnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuOSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS4xMCddID0gJ1JTQVNTQS1QU1MnOwpvaWRzWydSU0FTU0EtUFNTJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xLjEwJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xLjExJ10gPSAnc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24nOwpvaWRzWydzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbiddID0gJzEuMi44NDAuMTEzNTQ5LjEuMS4xMSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS4xMiddID0gJ3NoYTM4NFdpdGhSU0FFbmNyeXB0aW9uJzsKb2lkc1snc2hhMzg0V2l0aFJTQUVuY3J5cHRpb24nXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuMTInOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEuMTMnXSA9ICdzaGE1MTJXaXRoUlNBRW5jcnlwdGlvbic7Cm9pZHNbJ3NoYTUxMldpdGhSU0FFbmNyeXB0aW9uJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xLjEzJzsKCm9pZHNbJzEuMy4xNC4zLjIuNyddID0gJ2Rlc0NCQyc7Cm9pZHNbJ2Rlc0NCQyddID0gJzEuMy4xNC4zLjIuNyc7CgpvaWRzWycxLjMuMTQuMy4yLjI2J10gPSAnc2hhMSc7Cm9pZHNbJ3NoYTEnXSA9ICcxLjMuMTQuMy4yLjI2JzsKb2lkc1snMi4xNi44NDAuMS4xMDEuMy40LjIuMSddID0gJ3NoYTI1Nic7Cm9pZHNbJ3NoYTI1NiddID0gJzIuMTYuODQwLjEuMTAxLjMuNC4yLjEnOwpvaWRzWycyLjE2Ljg0MC4xLjEwMS4zLjQuMi4yJ10gPSAnc2hhMzg0JzsKb2lkc1snc2hhMzg0J10gPSAnMi4xNi44NDAuMS4xMDEuMy40LjIuMic7Cm9pZHNbJzIuMTYuODQwLjEuMTAxLjMuNC4yLjMnXSA9ICdzaGE1MTInOwpvaWRzWydzaGE1MTInXSA9ICcyLjE2Ljg0MC4xLjEwMS4zLjQuMi4zJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMi41J10gPSAnbWQ1JzsKb2lkc1snbWQ1J10gPSAnMS4yLjg0MC4xMTM1NDkuMi41JzsKCi8vIHBrY3MjNyBjb250ZW50IHR5cGVzCm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuNy4xJ10gPSAnZGF0YSc7Cm9pZHNbJ2RhdGEnXSA9ICcxLjIuODQwLjExMzU0OS4xLjcuMSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuNy4yJ10gPSAnc2lnbmVkRGF0YSc7Cm9pZHNbJ3NpZ25lZERhdGEnXSA9ICcxLjIuODQwLjExMzU0OS4xLjcuMic7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuNy4zJ10gPSAnZW52ZWxvcGVkRGF0YSc7Cm9pZHNbJ2VudmVsb3BlZERhdGEnXSA9ICcxLjIuODQwLjExMzU0OS4xLjcuMyc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuNy40J10gPSAnc2lnbmVkQW5kRW52ZWxvcGVkRGF0YSc7Cm9pZHNbJ3NpZ25lZEFuZEVudmVsb3BlZERhdGEnXSA9ICcxLjIuODQwLjExMzU0OS4xLjcuNCc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuNy41J10gPSAnZGlnZXN0ZWREYXRhJzsKb2lkc1snZGlnZXN0ZWREYXRhJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS43LjUnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjcuNiddID0gJ2VuY3J5cHRlZERhdGEnOwpvaWRzWydlbmNyeXB0ZWREYXRhJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS43LjYnOwoKLy8gcGtjcyM5IG9pZHMKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS45LjEnXSA9ICdlbWFpbEFkZHJlc3MnOwpvaWRzWydlbWFpbEFkZHJlc3MnXSA9ICcxLjIuODQwLjExMzU0OS4xLjkuMSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS4yJ10gPSAndW5zdHJ1Y3R1cmVkTmFtZSc7Cm9pZHNbJ3Vuc3RydWN0dXJlZE5hbWUnXSA9ICcxLjIuODQwLjExMzU0OS4xLjkuMic7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS4zJ10gPSAnY29udGVudFR5cGUnOwpvaWRzWydjb250ZW50VHlwZSddID0gJzEuMi44NDAuMTEzNTQ5LjEuOS4zJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS45LjQnXSA9ICdtZXNzYWdlRGlnZXN0JzsKb2lkc1snbWVzc2FnZURpZ2VzdCddID0gJzEuMi44NDAuMTEzNTQ5LjEuOS40JzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS45LjUnXSA9ICdzaWduaW5nVGltZSc7Cm9pZHNbJ3NpZ25pbmdUaW1lJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS45LjUnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjkuNiddID0gJ2NvdW50ZXJTaWduYXR1cmUnOwpvaWRzWydjb3VudGVyU2lnbmF0dXJlJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS45LjYnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjkuNyddID0gJ2NoYWxsZW5nZVBhc3N3b3JkJzsKb2lkc1snY2hhbGxlbmdlUGFzc3dvcmQnXSA9ICcxLjIuODQwLjExMzU0OS4xLjkuNyc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS44J10gPSAndW5zdHJ1Y3R1cmVkQWRkcmVzcyc7Cm9pZHNbJ3Vuc3RydWN0dXJlZEFkZHJlc3MnXSA9ICcxLjIuODQwLjExMzU0OS4xLjkuOCc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS4xNCddID0gJ2V4dGVuc2lvblJlcXVlc3QnOwpvaWRzWydleHRlbnNpb25SZXF1ZXN0J10gPSAnMS4yLjg0MC4xMTM1NDkuMS45LjE0JzsKCm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS4yMCddID0gJ2ZyaWVuZGx5TmFtZSc7Cm9pZHNbJ2ZyaWVuZGx5TmFtZSddID0gJzEuMi44NDAuMTEzNTQ5LjEuOS4yMCc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS4yMSddID0gJ2xvY2FsS2V5SWQnOwpvaWRzWydsb2NhbEtleUlkJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS45LjIxJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS45LjIyLjEnXSA9ICd4NTA5Q2VydGlmaWNhdGUnOwpvaWRzWyd4NTA5Q2VydGlmaWNhdGUnXSA9ICcxLjIuODQwLjExMzU0OS4xLjkuMjIuMSc7CgovLyBwa2NzIzEyIHNhZmUgYmFncwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEyLjEwLjEuMSddID0gJ2tleUJhZyc7Cm9pZHNbJ2tleUJhZyddID0gJzEuMi44NDAuMTEzNTQ5LjEuMTIuMTAuMS4xJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xMi4xMC4xLjInXSA9ICdwa2NzOFNocm91ZGVkS2V5QmFnJzsKb2lkc1sncGtjczhTaHJvdWRlZEtleUJhZyddID0gJzEuMi44NDAuMTEzNTQ5LjEuMTIuMTAuMS4yJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xMi4xMC4xLjMnXSA9ICdjZXJ0QmFnJzsKb2lkc1snY2VydEJhZyddID0gJzEuMi44NDAuMTEzNTQ5LjEuMTIuMTAuMS4zJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xMi4xMC4xLjQnXSA9ICdjcmxCYWcnOwpvaWRzWydjcmxCYWcnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEyLjEwLjEuNCc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMTIuMTAuMS41J10gPSAnc2VjcmV0QmFnJzsKb2lkc1snc2VjcmV0QmFnJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xMi4xMC4xLjUnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEyLjEwLjEuNiddID0gJ3NhZmVDb250ZW50c0JhZyc7Cm9pZHNbJ3NhZmVDb250ZW50c0JhZyddID0gJzEuMi44NDAuMTEzNTQ5LjEuMTIuMTAuMS42JzsKCi8vIHBhc3N3b3JkLWJhc2VkLWVuY3J5cHRpb24gZm9yIHBrY3MjMTIKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS41LjEzJ10gPSAncGtjczVQQkVTMic7Cm9pZHNbJ3BrY3M1UEJFUzInXSA9ICcxLjIuODQwLjExMzU0OS4xLjUuMTMnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjUuMTInXSA9ICdwa2NzNVBCS0RGMic7Cm9pZHNbJ3BrY3M1UEJLREYyJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS41LjEyJzsKCm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMTIuMS4xJ10gPSAncGJlV2l0aFNIQUFuZDEyOEJpdFJDNCc7Cm9pZHNbJ3BiZVdpdGhTSEFBbmQxMjhCaXRSQzQnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEyLjEuMSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMTIuMS4yJ10gPSAncGJlV2l0aFNIQUFuZDQwQml0UkM0JzsKb2lkc1sncGJlV2l0aFNIQUFuZDQwQml0UkM0J10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xMi4xLjInOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEyLjEuMyddID0gJ3BiZVdpdGhTSEFBbmQzLUtleVRyaXBsZURFUy1DQkMnOwpvaWRzWydwYmVXaXRoU0hBQW5kMy1LZXlUcmlwbGVERVMtQ0JDJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xMi4xLjMnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEyLjEuNCddID0gJ3BiZVdpdGhTSEFBbmQyLUtleVRyaXBsZURFUy1DQkMnOwpvaWRzWydwYmVXaXRoU0hBQW5kMi1LZXlUcmlwbGVERVMtQ0JDJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xMi4xLjQnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEyLjEuNSddID0gJ3BiZVdpdGhTSEFBbmQxMjhCaXRSQzItQ0JDJzsKb2lkc1sncGJlV2l0aFNIQUFuZDEyOEJpdFJDMi1DQkMnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEyLjEuNSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMTIuMS42J10gPSAncGJld2l0aFNIQUFuZDQwQml0UkMyLUNCQyc7Cm9pZHNbJ3BiZXdpdGhTSEFBbmQ0MEJpdFJDMi1DQkMnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEyLjEuNic7CgovLyBzeW1tZXRyaWMga2V5IGFsZ29yaXRobSBvaWRzCm9pZHNbJzEuMi44NDAuMTEzNTQ5LjMuNyddID0gJ2Rlcy1FREUzLUNCQyc7Cm9pZHNbJ2Rlcy1FREUzLUNCQyddID0gJzEuMi44NDAuMTEzNTQ5LjMuNyc7Cm9pZHNbJzIuMTYuODQwLjEuMTAxLjMuNC4xLjInXSA9ICdhZXMxMjgtQ0JDJzsKb2lkc1snYWVzMTI4LUNCQyddID0gJzIuMTYuODQwLjEuMTAxLjMuNC4xLjInOwpvaWRzWycyLjE2Ljg0MC4xLjEwMS4zLjQuMS4yMiddID0gJ2FlczE5Mi1DQkMnOwpvaWRzWydhZXMxOTItQ0JDJ10gPSAnMi4xNi44NDAuMS4xMDEuMy40LjEuMjInOwpvaWRzWycyLjE2Ljg0MC4xLjEwMS4zLjQuMS40MiddID0gJ2FlczI1Ni1DQkMnOwpvaWRzWydhZXMyNTYtQ0JDJ10gPSAnMi4xNi44NDAuMS4xMDEuMy40LjEuNDInOwoKLy8gY2VydGlmaWNhdGUgaXNzdWVyL3N1YmplY3QgT0lEcwpvaWRzWycyLjUuNC4zJ10gPSAnY29tbW9uTmFtZSc7Cm9pZHNbJ2NvbW1vbk5hbWUnXSA9ICcyLjUuNC4zJzsKb2lkc1snMi41LjQuNSddID0gJ3NlcmlhbE5hbWUnOwpvaWRzWydzZXJpYWxOYW1lJ10gPSAnMi41LjQuNSc7Cm9pZHNbJzIuNS40LjYnXSA9ICdjb3VudHJ5TmFtZSc7Cm9pZHNbJ2NvdW50cnlOYW1lJ10gPSAnMi41LjQuNic7Cm9pZHNbJzIuNS40LjcnXSA9ICdsb2NhbGl0eU5hbWUnOwpvaWRzWydsb2NhbGl0eU5hbWUnXSA9ICcyLjUuNC43JzsKb2lkc1snMi41LjQuOCddID0gJ3N0YXRlT3JQcm92aW5jZU5hbWUnOwpvaWRzWydzdGF0ZU9yUHJvdmluY2VOYW1lJ10gPSAnMi41LjQuOCc7Cm9pZHNbJzIuNS40LjEwJ10gPSAnb3JnYW5pemF0aW9uTmFtZSc7Cm9pZHNbJ29yZ2FuaXphdGlvbk5hbWUnXSA9ICcyLjUuNC4xMCc7Cm9pZHNbJzIuNS40LjExJ10gPSAnb3JnYW5pemF0aW9uYWxVbml0TmFtZSc7Cm9pZHNbJ29yZ2FuaXphdGlvbmFsVW5pdE5hbWUnXSA9ICcyLjUuNC4xMSc7CgovLyBYLjUwOSBleHRlbnNpb24gT0lEcwpvaWRzWycyLjE2Ljg0MC4xLjExMzczMC4xLjEnXSA9ICduc0NlcnRUeXBlJzsKb2lkc1snbnNDZXJ0VHlwZSddID0gJzIuMTYuODQwLjEuMTEzNzMwLjEuMSc7Cm9pZHNbJzIuNS4yOS4xJ10gPSAnYXV0aG9yaXR5S2V5SWRlbnRpZmllcic7IC8vIGRlcHJlY2F0ZWQsIHVzZSAuMzUKb2lkc1snMi41LjI5LjInXSA9ICdrZXlBdHRyaWJ1dGVzJzsgLy8gb2Jzb2xldGUgdXNlIC4zNyBvciAuMTUKb2lkc1snMi41LjI5LjMnXSA9ICdjZXJ0aWZpY2F0ZVBvbGljaWVzJzsgLy8gZGVwcmVjYXRlZCwgdXNlIC4zMgpvaWRzWycyLjUuMjkuNCddID0gJ2tleVVzYWdlUmVzdHJpY3Rpb24nOyAvLyBvYnNvbGV0ZSB1c2UgLjM3IG9yIC4xNQpvaWRzWycyLjUuMjkuNSddID0gJ3BvbGljeU1hcHBpbmcnOyAvLyBkZXByZWNhdGVkIHVzZSAuMzMKb2lkc1snMi41LjI5LjYnXSA9ICdzdWJ0cmVlc0NvbnN0cmFpbnQnOyAvLyBvYnNvbGV0ZSB1c2UgLjMwCm9pZHNbJzIuNS4yOS43J10gPSAnc3ViamVjdEFsdE5hbWUnOyAvLyBkZXByZWNhdGVkIHVzZSAuMTcKb2lkc1snMi41LjI5LjgnXSA9ICdpc3N1ZXJBbHROYW1lJzsgLy8gZGVwcmVjYXRlZCB1c2UgLjE4Cm9pZHNbJzIuNS4yOS45J10gPSAnc3ViamVjdERpcmVjdG9yeUF0dHJpYnV0ZXMnOwpvaWRzWycyLjUuMjkuMTAnXSA9ICdiYXNpY0NvbnN0cmFpbnRzJzsgLy8gZGVwcmVjYXRlZCB1c2UgLjE5Cm9pZHNbJzIuNS4yOS4xMSddID0gJ25hbWVDb25zdHJhaW50cyc7IC8vIGRlcHJlY2F0ZWQgdXNlIC4zMApvaWRzWycyLjUuMjkuMTInXSA9ICdwb2xpY3lDb25zdHJhaW50cyc7IC8vIGRlcHJlY2F0ZWQgdXNlIC4zNgpvaWRzWycyLjUuMjkuMTMnXSA9ICdiYXNpY0NvbnN0cmFpbnRzJzsgLy8gZGVwcmVjYXRlZCB1c2UgLjE5Cm9pZHNbJzIuNS4yOS4xNCddID0gJ3N1YmplY3RLZXlJZGVudGlmaWVyJzsKb2lkc1snc3ViamVjdEtleUlkZW50aWZpZXInXSA9ICcyLjUuMjkuMTQnOwpvaWRzWycyLjUuMjkuMTUnXSA9ICdrZXlVc2FnZSc7Cm9pZHNbJ2tleVVzYWdlJ10gPSAnMi41LjI5LjE1JzsKb2lkc1snMi41LjI5LjE2J10gPSAncHJpdmF0ZUtleVVzYWdlUGVyaW9kJzsKb2lkc1snMi41LjI5LjE3J10gPSAnc3ViamVjdEFsdE5hbWUnOwpvaWRzWydzdWJqZWN0QWx0TmFtZSddID0gJzIuNS4yOS4xNyc7Cm9pZHNbJzIuNS4yOS4xOCddID0gJ2lzc3VlckFsdE5hbWUnOwpvaWRzWydpc3N1ZXJBbHROYW1lJ10gPSAnMi41LjI5LjE4JzsKb2lkc1snMi41LjI5LjE5J10gPSAnYmFzaWNDb25zdHJhaW50cyc7Cm9pZHNbJ2Jhc2ljQ29uc3RyYWludHMnXSA9ICcyLjUuMjkuMTknOwpvaWRzWycyLjUuMjkuMjAnXSA9ICdjUkxOdW1iZXInOwpvaWRzWycyLjUuMjkuMjEnXSA9ICdjUkxSZWFzb24nOwpvaWRzWycyLjUuMjkuMjInXSA9ICdleHBpcmF0aW9uRGF0ZSc7Cm9pZHNbJzIuNS4yOS4yMyddID0gJ2luc3RydWN0aW9uQ29kZSc7Cm9pZHNbJzIuNS4yOS4yNCddID0gJ2ludmFsaWRpdHlEYXRlJzsKb2lkc1snMi41LjI5LjI1J10gPSAnY1JMRGlzdHJpYnV0aW9uUG9pbnRzJzsgLy8gZGVwcmVjYXRlZCB1c2UgLjMxCm9pZHNbJzIuNS4yOS4yNiddID0gJ2lzc3VpbmdEaXN0cmlidXRpb25Qb2ludCc7IC8vIGRlcHJlY2F0ZWQgdXNlIC4yOApvaWRzWycyLjUuMjkuMjcnXSA9ICdkZWx0YUNSTEluZGljYXRvcic7Cm9pZHNbJzIuNS4yOS4yOCddID0gJ2lzc3VpbmdEaXN0cmlidXRpb25Qb2ludCc7Cm9pZHNbJzIuNS4yOS4yOSddID0gJ2NlcnRpZmljYXRlSXNzdWVyJzsKb2lkc1snMi41LjI5LjMwJ10gPSAnbmFtZUNvbnN0cmFpbnRzJzsKb2lkc1snMi41LjI5LjMxJ10gPSAnY1JMRGlzdHJpYnV0aW9uUG9pbnRzJzsKb2lkc1snMi41LjI5LjMyJ10gPSAnY2VydGlmaWNhdGVQb2xpY2llcyc7Cm9pZHNbJzIuNS4yOS4zMyddID0gJ3BvbGljeU1hcHBpbmdzJzsKb2lkc1snMi41LjI5LjM0J10gPSAncG9saWN5Q29uc3RyYWludHMnOyAvLyBkZXByZWNhdGVkIHVzZSAuMzYKb2lkc1snMi41LjI5LjM1J10gPSAnYXV0aG9yaXR5S2V5SWRlbnRpZmllcic7Cm9pZHNbJzIuNS4yOS4zNiddID0gJ3BvbGljeUNvbnN0cmFpbnRzJzsKb2lkc1snMi41LjI5LjM3J10gPSAnZXh0S2V5VXNhZ2UnOwpvaWRzWydleHRLZXlVc2FnZSddID0gJzIuNS4yOS4zNyc7Cm9pZHNbJzIuNS4yOS40NiddID0gJ2ZyZXNoZXN0Q1JMJzsKb2lkc1snMi41LjI5LjU0J10gPSAnaW5oaWJpdEFueVBvbGljeSc7CgovLyBleHRLZXlVc2FnZSBwdXJwb3NlcwpvaWRzWycxLjMuNi4xLjUuNS43LjMuMSddID0gJ3NlcnZlckF1dGgnOwpvaWRzWydzZXJ2ZXJBdXRoJ10gPSAnMS4zLjYuMS41LjUuNy4zLjEnOwpvaWRzWycxLjMuNi4xLjUuNS43LjMuMiddID0gJ2NsaWVudEF1dGgnOwpvaWRzWydjbGllbnRBdXRoJ10gPSAnMS4zLjYuMS41LjUuNy4zLjInOwpvaWRzWycxLjMuNi4xLjUuNS43LjMuMyddID0gJ2NvZGVTaWduaW5nJzsKb2lkc1snY29kZVNpZ25pbmcnXSA9ICcxLjMuNi4xLjUuNS43LjMuMyc7Cm9pZHNbJzEuMy42LjEuNS41LjcuMy40J10gPSAnZW1haWxQcm90ZWN0aW9uJzsKb2lkc1snZW1haWxQcm90ZWN0aW9uJ10gPSAnMS4zLjYuMS41LjUuNy4zLjQnOwpvaWRzWycxLjMuNi4xLjUuNS43LjMuOCddID0gJ3RpbWVTdGFtcGluZyc7Cm9pZHNbJ3RpbWVTdGFtcGluZyddID0gJzEuMy42LjEuNS41LjcuMy44JzsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ29pZHMnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvb2lkcycsWydyZXF1aXJlJywgJ21vZHVsZSddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIEFic3RyYWN0IFN5bnRheCBOb3RhdGlvbiBOdW1iZXIgT25lLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNSBEaWdpdGFsIEJhemFhciwgSW5jLgogKgogKiBBbiBBUEkgZm9yIHN0b3JpbmcgZGF0YSB1c2luZyB0aGUgQWJzdHJhY3QgU3ludGF4IE5vdGF0aW9uIE51bWJlciBPbmUKICogZm9ybWF0IHVzaW5nIERFUiAoRGlzdGluZ3Vpc2hlZCBFbmNvZGluZyBSdWxlcykgZW5jb2RpbmcuIFRoaXMgZW5jb2RpbmcgaXMKICogY29tbW9ubHkgdXNlZCB0byBzdG9yZSBkYXRhIGZvciBQS0ksIGkuZS4gWC41MDkgQ2VydGlmaWNhdGVzLCBhbmQgdGhpcwogKiBpbXBsZW1lbnRhdGlvbiBleGlzdHMgZm9yIHRoYXQgcHVycG9zZS4KICoKICogQWJzdHJhY3QgU3ludGF4IE5vdGF0aW9uIE51bWJlciBPbmUgKEFTTi4xKSBpcyB1c2VkIHRvIGRlZmluZSB0aGUgYWJzdHJhY3QKICogc3ludGF4IG9mIGluZm9ybWF0aW9uIHdpdGhvdXQgcmVzdHJpY3RpbmcgdGhlIHdheSB0aGUgaW5mb3JtYXRpb24gaXMgZW5jb2RlZAogKiBmb3IgdHJhbnNtaXNzaW9uLiBJdCBwcm92aWRlcyBhIHN0YW5kYXJkIHRoYXQgYWxsb3dzIGZvciBvcGVuIHN5c3RlbXMKICogY29tbXVuaWNhdGlvbi4gQVNOLjEgZGVmaW5lcyB0aGUgc3ludGF4IG9mIGluZm9ybWF0aW9uIGRhdGEgYW5kIGEgbnVtYmVyIG9mCiAqIHNpbXBsZSBkYXRhIHR5cGVzIGFzIHdlbGwgYXMgYSBub3RhdGlvbiBmb3IgZGVzY3JpYmluZyB0aGVtIGFuZCBzcGVjaWZ5aW5nCiAqIHZhbHVlcyBmb3IgdGhlbS4KICoKICogVGhlIFJTQSBhbGdvcml0aG0gY3JlYXRlcyBwdWJsaWMgYW5kIHByaXZhdGUga2V5cyB0aGF0IGFyZSBvZnRlbiBzdG9yZWQgaW4KICogWC41MDkgb3IgUEtDUyNYIGZvcm1hdHMgLS0gd2hpY2ggdXNlIEFTTi4xIChlbmNvZGVkIGluIERFUiBmb3JtYXQpLiBUaGlzCiAqIGNsYXNzIHByb3ZpZGVzIHRoZSBtb3N0IGJhc2ljIGZ1bmN0aW9uYWxpdHkgcmVxdWlyZWQgdG8gc3RvcmUgYW5kIGxvYWQgRFNBCiAqIGtleXMgdGhhdCBhcmUgZW5jb2RlZCBhY2NvcmRpbmcgdG8gQVNOLjEuCiAqCiAqIFRoZSBtb3N0IGNvbW1vbiBiaW5hcnkgZW5jb2RpbmdzIGZvciBBU04uMSBhcmUgQkVSIChCYXNpYyBFbmNvZGluZyBSdWxlcykKICogYW5kIERFUiAoRGlzdGluZ3Vpc2hlZCBFbmNvZGluZyBSdWxlcykuIERFUiBpcyBqdXN0IGEgc3Vic2V0IG9mIEJFUiB0aGF0CiAqIGhhcyBzdHJpY3RlciByZXF1aXJlbWVudHMgZm9yIGhvdyBkYXRhIG11c3QgYmUgZW5jb2RlZC4KICoKICogRWFjaCBBU04uMSBzdHJ1Y3R1cmUgaGFzIGEgdGFnIChhIGJ5dGUgaWRlbnRpZnlpbmcgdGhlIEFTTi4xIHN0cnVjdHVyZSB0eXBlKQogKiBhbmQgYSBieXRlIGFycmF5IGZvciB0aGUgdmFsdWUgb2YgdGhpcyBBU04xIHN0cnVjdHVyZSB3aGljaCBtYXkgYmUgZGF0YSBvciBhCiAqIGxpc3Qgb2YgQVNOLjEgc3RydWN0dXJlcy4KICoKICogRWFjaCBBU04uMSBzdHJ1Y3R1cmUgdXNpbmcgQkVSIGlzIChUYWctTGVuZ3RoLVZhbHVlKToKICoKICogfCBieXRlIDAgfCBieXRlcyBYIHwgYnl0ZXMgWSB8CiAqIHwtLS0tLS0tLXwtLS0tLS0tLS18LS0tLS0tLS0tLQogKiB8ICB0YWcgICB8IGxlbmd0aCAgfCAgdmFsdWUgIHwKICoKICogQVNOLjEgYWxsb3dzIGZvciB0YWdzIHRvIGJlIG9mICJIaWdoLXRhZy1udW1iZXIgZm9ybSIgd2hpY2ggYWxsb3dzIGEgdGFnIHRvCiAqIGJlIHR3byBvciBtb3JlIG9jdGV0cywgYnV0IHRoYXQgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIGNsYXNzLiBBIHRhZyBpcwogKiBvbmx5IDEgYnl0ZS4gQml0cyAxLTUgZ2l2ZSB0aGUgdGFnIG51bWJlciAoaWUgdGhlIGRhdGEgdHlwZSB3aXRoaW4gYQogKiBwYXJ0aWN1bGFyICdjbGFzcycpLCA2IGluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgQVNOLjEgdmFsdWUgaXMKICogY29uc3RydWN0ZWQgZnJvbSBvdGhlciBBU04uMSB2YWx1ZXMsIGFuZCBiaXRzIDcgYW5kIDggZ2l2ZSB0aGUgJ2NsYXNzJy4gSWYKICogYml0cyA3IGFuZCA4IGFyZSBib3RoIHplcm8sIHRoZSBjbGFzcyBpcyBVTklWRVJTQUwuIElmIG9ubHkgYml0IDcgaXMgc2V0LAogKiB0aGVuIHRoZSBjbGFzcyBpcyBBUFBMSUNBVElPTi4gSWYgb25seSBiaXQgOCBpcyBzZXQsIHRoZW4gdGhlIGNsYXNzIGlzCiAqIENPTlRFWFRfU1BFQ0lGSUMuIElmIGJvdGggYml0cyA3IGFuZCA4IGFyZSBzZXQsIHRoZW4gdGhlIGNsYXNzIGlzIFBSSVZBVEUuCiAqIFRoZSB0YWcgbnVtYmVycyBmb3IgdGhlIGRhdGEgdHlwZXMgZm9yIHRoZSBjbGFzcyBVTklWRVJTQUwgYXJlIGxpc3RlZCBiZWxvdzoKICoKICogVU5JVkVSU0FMIDAgUmVzZXJ2ZWQgZm9yIHVzZSBieSB0aGUgZW5jb2RpbmcgcnVsZXMKICogVU5JVkVSU0FMIDEgQm9vbGVhbiB0eXBlCiAqIFVOSVZFUlNBTCAyIEludGVnZXIgdHlwZQogKiBVTklWRVJTQUwgMyBCaXRzdHJpbmcgdHlwZQogKiBVTklWRVJTQUwgNCBPY3RldHN0cmluZyB0eXBlCiAqIFVOSVZFUlNBTCA1IE51bGwgdHlwZQogKiBVTklWRVJTQUwgNiBPYmplY3QgaWRlbnRpZmllciB0eXBlCiAqIFVOSVZFUlNBTCA3IE9iamVjdCBkZXNjcmlwdG9yIHR5cGUKICogVU5JVkVSU0FMIDggRXh0ZXJuYWwgdHlwZSBhbmQgSW5zdGFuY2Utb2YgdHlwZQogKiBVTklWRVJTQUwgOSBSZWFsIHR5cGUKICogVU5JVkVSU0FMIDEwIEVudW1lcmF0ZWQgdHlwZQogKiBVTklWRVJTQUwgMTEgRW1iZWRkZWQtcGR2IHR5cGUKICogVU5JVkVSU0FMIDEyIFVURjhTdHJpbmcgdHlwZQogKiBVTklWRVJTQUwgMTMgUmVsYXRpdmUgb2JqZWN0IGlkZW50aWZpZXIgdHlwZQogKiBVTklWRVJTQUwgMTQtMTUgUmVzZXJ2ZWQgZm9yIGZ1dHVyZSBlZGl0aW9ucwogKiBVTklWRVJTQUwgMTYgU2VxdWVuY2UgYW5kIFNlcXVlbmNlLW9mIHR5cGVzCiAqIFVOSVZFUlNBTCAxNyBTZXQgYW5kIFNldC1vZiB0eXBlcwogKiBVTklWRVJTQUwgMTgtMjIsIDI1LTMwIENoYXJhY3RlciBzdHJpbmcgdHlwZXMKICogVU5JVkVSU0FMIDIzLTI0IFRpbWUgdHlwZXMKICoKICogVGhlIGxlbmd0aCBvZiBhbiBBU04uMSBzdHJ1Y3R1cmUgaXMgc3BlY2lmaWVkIGFmdGVyIHRoZSB0YWcgaWRlbnRpZmllci4KICogVGhlcmUgaXMgYSBkZWZpbml0ZSBmb3JtIGFuZCBhbiBpbmRlZmluaXRlIGZvcm0uIFRoZSBpbmRlZmluaXRlIGZvcm0gbWF5CiAqIGJlIHVzZWQgaWYgdGhlIGVuY29kaW5nIGlzIGNvbnN0cnVjdGVkIGFuZCBub3QgYWxsIGltbWVkaWF0ZWx5IGF2YWlsYWJsZS4KICogVGhlIGluZGVmaW5pdGUgZm9ybSBpcyBlbmNvZGVkIHVzaW5nIGEgbGVuZ3RoIGJ5dGUgd2l0aCBvbmx5IHRoZSA4dGggYml0CiAqIHNldC4gVGhlIGVuZCBvZiB0aGUgY29uc3RydWN0ZWQgb2JqZWN0IGlzIG1hcmtlZCB1c2luZyBlbmQtb2YtY29udGVudHMKICogb2N0ZXRzICh0d28gemVybyBieXRlcykuCiAqCiAqIFRoZSBkZWZpbml0ZSBmb3JtIGxvb2tzIGxpa2UgdGhpczoKICoKICogVGhlIGxlbmd0aCBtYXkgdGFrZSB1cCAxIG9yIG1vcmUgYnl0ZXMsIGl0IGRlcGVuZHMgb24gdGhlIGxlbmd0aCBvZiB0aGUKICogdmFsdWUgb2YgdGhlIEFTTi4xIHN0cnVjdHVyZS4gREVSIGVuY29kaW5nIHJlcXVpcmVzIHRoYXQgaWYgdGhlIEFTTi4xCiAqIHN0cnVjdHVyZSBoYXMgYSB2YWx1ZSB0aGF0IGhhcyBhIGxlbmd0aCBncmVhdGVyIHRoYW4gMTI3LCBtb3JlIHRoYW4gMSBieXRlCiAqIHdpbGwgYmUgdXNlZCB0byBzdG9yZSBpdHMgbGVuZ3RoLCBvdGhlcndpc2UganVzdCBvbmUgYnl0ZSB3aWxsIGJlIHVzZWQuCiAqIFRoaXMgaXMgc3RyaWN0LgogKgogKiBJbiB0aGUgY2FzZSB0aGF0IHRoZSBsZW5ndGggb2YgdGhlIEFTTi4xIHZhbHVlIGlzIGxlc3MgdGhhbiAxMjcsIDEgb2N0ZXQKICogKGJ5dGUpIGlzIHVzZWQgdG8gc3RvcmUgdGhlICJzaG9ydCBmb3JtIiBsZW5ndGguIFRoZSA4dGggYml0IGhhcyBhIHZhbHVlIG9mCiAqIDAgaW5kaWNhdGluZyB0aGUgbGVuZ3RoIGlzICJzaG9ydCBmb3JtIiBhbmQgbm90ICJsb25nIGZvcm0iIGFuZCBiaXRzIDctMQogKiBnaXZlIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEuIChUaGUgOHRoIGJpdCBpcyB0aGUgbGVmdC1tb3N0LCBtb3N0IHNpZ25pZmljYW50CiAqIGJpdDogYWxzbyBrbm93biBhcyBiaWcgZW5kaWFuIG9yIG5ldHdvcmsgZm9ybWF0KS4KICoKICogSW4gdGhlIGNhc2UgdGhhdCB0aGUgbGVuZ3RoIG9mIHRoZSBBU04uMSB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gMTI3LCAyIHRvCiAqIDEyNyBvY3RldHMgKGJ5dGVzKSBhcmUgdXNlZCB0byBzdG9yZSB0aGUgImxvbmcgZm9ybSIgbGVuZ3RoLiBUaGUgZmlyc3QKICogYnl0ZSdzIDh0aCBiaXQgaXMgc2V0IHRvIDEgdG8gaW5kaWNhdGUgdGhlIGxlbmd0aCBpcyAibG9uZyBmb3JtLiIgQml0cyA3LTEKICogZ2l2ZSB0aGUgbnVtYmVyIG9mIGFkZGl0aW9uYWwgb2N0ZXRzLiBBbGwgZm9sbG93aW5nIG9jdGV0cyBhcmUgaW4gYmFzZSAyNTYKICogd2l0aCB0aGUgbW9zdCBzaWduaWZpY2FudCBkaWdpdCBmaXJzdCAodHlwaWNhbCBiaWctZW5kaWFuIGJpbmFyeSB1bnNpZ25lZAogKiBpbnRlZ2VyIHN0b3JhZ2UpLiBTbywgZm9yIGluc3RhbmNlLCBpZiB0aGUgbGVuZ3RoIG9mIGEgdmFsdWUgd2FzIDI1NywgdGhlCiAqIGZpcnN0IGJ5dGUgd291bGQgYmUgc2V0IHRvOgogKgogKiAxMDAwMDAxMCA9IDEzMCA9IDB4ODIuCiAqCiAqIFRoaXMgaW5kaWNhdGVzIHRoZXJlIGFyZSAyIG9jdGV0cyAoYmFzZSAyNTYpIGZvciB0aGUgbGVuZ3RoLiBUaGUgc2Vjb25kIGFuZAogKiB0aGlyZCBieXRlcyAodGhlIG9jdGV0cyBqdXN0IG1lbnRpb25lZCkgd291bGQgc3RvcmUgdGhlIGxlbmd0aCBpbiBiYXNlIDI1NjoKICoKICogb2N0ZXQgMjogMDAwMDAwMDEgPSAxICogMjU2XjEgPSAyNTYKICogb2N0ZXQgMzogMDAwMDAwMDEgPSAxICogMjU2XjAgPSAxCiAqIHRvdGFsID0gMjU3CiAqCiAqIFRoZSBhbGdvcml0aG0gZm9yIGNvbnZlcnRpbmcgYSBqcyBpbnRlZ2VyIHZhbHVlIG9mIDI1NyB0byBiYXNlLTI1NiBpczoKICoKICogdmFyIHZhbHVlID0gMjU3OwogKiB2YXIgYnl0ZXMgPSBbXTsKICogYnl0ZXNbMF0gPSAodmFsdWUgPj4+IDgpICYgMHhGRjsgLy8gbW9zdCBzaWduaWZpY2FudCBieXRlIGZpcnN0CiAqIGJ5dGVzWzFdID0gdmFsdWUgJiAweEZGOyAgICAgICAgLy8gbGVhc3Qgc2lnbmlmaWNhbnQgYnl0ZSBsYXN0CiAqCiAqIE9uIHRoZSBBU04uMSBVTklWRVJTQUwgT2JqZWN0IElkZW50aWZpZXIgKE9JRCkgdHlwZToKICoKICogQW4gT0lEIGNhbiBiZSB3cml0dGVuIGxpa2U6ICJ2YWx1ZTEudmFsdWUyLnZhbHVlMy4uLnZhbHVlTiIKICoKICogVGhlIERFUiBlbmNvZGluZyBydWxlczoKICoKICogVGhlIGZpcnN0IGJ5dGUgaGFzIHRoZSB2YWx1ZSA0MCAqIHZhbHVlMSArIHZhbHVlMi4KICogVGhlIGZvbGxvd2luZyBieXRlcywgaWYgYW55LCBlbmNvZGUgdGhlIHJlbWFpbmluZyB2YWx1ZXMuIEVhY2ggdmFsdWUgaXMKICogZW5jb2RlZCBpbiBiYXNlIDEyOCwgbW9zdCBzaWduaWZpY2FudCBkaWdpdCBmaXJzdCAoYmlnIGVuZGlhbiksIHdpdGggYXMKICogZmV3IGRpZ2l0cyBhcyBwb3NzaWJsZSwgYW5kIHRoZSBtb3N0IHNpZ25pZmljYW50IGJpdCBvZiBlYWNoIGJ5dGUgc2V0CiAqIHRvIDEgZXhjZXB0IHRoZSBsYXN0IGluIGVhY2ggdmFsdWUncyBlbmNvZGluZy4gRm9yIGV4YW1wbGU6IEdpdmVuIHRoZQogKiBPSUQgIjEuMi44NDAuMTEzNTQ5IiwgaXRzIERFUiBlbmNvZGluZyBpcyAocmVtZW1iZXIgZWFjaCBieXRlIGV4Y2VwdCB0aGUKICogbGFzdCBvbmUgaW4gZWFjaCBlbmNvZGluZyBpcyBPUidkIHdpdGggMHg4MCk6CiAqCiAqIGJ5dGUgMTogNDAgKiAxICsgMiA9IDQyID0gMHgyQS4KICogYnl0ZXMgMi0zOiAxMjggKiA2ICsgNzIgPSA4NDAgPSA2IDcyID0gNiA3MiA9IDB4MDY0OCA9IDB4ODY0OAogKiBieXRlcyA0LTY6IDE2Mzg0ICogNiArIDEyOCAqIDExOSArIDEzID0gNiAxMTkgMTMgPSAweDA2NzcwRCA9IDB4ODZGNzBECiAqCiAqIFRoZSBmaW5hbCB2YWx1ZSBpczogMHgyQTg2NDg4NkY3MEQuCiAqIFRoZSBmdWxsIE9JRCAoaW5jbHVkaW5nIEFTTi4xIHRhZyBhbmQgbGVuZ3RoIG9mIDYgYnl0ZXMpIGlzOgogKiAweDA2MDYyQTg2NDg4NkY3MEQKICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovKiBBU04uMSBBUEkgKi8KdmFyIGFzbjEgPSBmb3JnZS5hc24xID0gZm9yZ2UuYXNuMSB8fCB7fTsKCi8qKgogKiBBU04uMSBjbGFzc2VzLgogKi8KYXNuMS5DbGFzcyA9IHsKICBVTklWRVJTQUw6ICAgICAgICAweDAwLAogIEFQUExJQ0FUSU9OOiAgICAgIDB4NDAsCiAgQ09OVEVYVF9TUEVDSUZJQzogMHg4MCwKICBQUklWQVRFOiAgICAgICAgICAweEMwCn07CgovKioKICogQVNOLjEgdHlwZXMuIE5vdCBhbGwgdHlwZXMgYXJlIHN1cHBvcnRlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uLCBvbmx5CiAqIHRob3NlIG5lY2Vzc2FyeSB0byBpbXBsZW1lbnQgYSBzaW1wbGUgUEtJIGFyZSBpbXBsZW1lbnRlZC4KICovCmFzbjEuVHlwZSA9IHsKICBOT05FOiAgICAgICAgICAgICAwLAogIEJPT0xFQU46ICAgICAgICAgIDEsCiAgSU5URUdFUjogICAgICAgICAgMiwKICBCSVRTVFJJTkc6ICAgICAgICAzLAogIE9DVEVUU1RSSU5HOiAgICAgIDQsCiAgTlVMTDogICAgICAgICAgICAgNSwKICBPSUQ6ICAgICAgICAgICAgICA2LAogIE9ERVNDOiAgICAgICAgICAgIDcsCiAgRVhURVJOQUw6ICAgICAgICAgOCwKICBSRUFMOiAgICAgICAgICAgICA5LAogIEVOVU1FUkFURUQ6ICAgICAgMTAsCiAgRU1CRURERUQ6ICAgICAgICAxMSwKICBVVEY4OiAgICAgICAgICAgIDEyLAogIFJPSUQ6ICAgICAgICAgICAgMTMsCiAgU0VRVUVOQ0U6ICAgICAgICAxNiwKICBTRVQ6ICAgICAgICAgICAgIDE3LAogIFBSSU5UQUJMRVNUUklORzogMTksCiAgSUE1U1RSSU5HOiAgICAgICAyMiwKICBVVENUSU1FOiAgICAgICAgIDIzLAogIEdFTkVSQUxJWkVEVElNRTogMjQsCiAgQk1QU1RSSU5HOiAgICAgICAzMAp9OwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgYXNuMSBvYmplY3QuCiAqCiAqIEBwYXJhbSB0YWdDbGFzcyB0aGUgdGFnIGNsYXNzIGZvciB0aGUgb2JqZWN0LgogKiBAcGFyYW0gdHlwZSB0aGUgZGF0YSB0eXBlICh0YWcgbnVtYmVyKSBmb3IgdGhlIG9iamVjdC4KICogQHBhcmFtIGNvbnN0cnVjdGVkIHRydWUgaWYgdGhlIGFzbjEgb2JqZWN0IGlzIGluIGNvbnN0cnVjdGVkIGZvcm0uCiAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgZm9yIHRoZSBvYmplY3QsIGlmIGl0IGlzIG5vdCBjb25zdHJ1Y3RlZC4KICoKICogQHJldHVybiB0aGUgYXNuMSBvYmplY3QuCiAqLwphc24xLmNyZWF0ZSA9IGZ1bmN0aW9uKHRhZ0NsYXNzLCB0eXBlLCBjb25zdHJ1Y3RlZCwgdmFsdWUpIHsKICAvKiBBbiBhc24xIG9iamVjdCBoYXMgYSB0YWdDbGFzcywgYSB0eXBlLCBhIGNvbnN0cnVjdGVkIGZsYWcsIGFuZCBhCiAgICB2YWx1ZS4gVGhlIHZhbHVlJ3MgdHlwZSBkZXBlbmRzIG9uIHRoZSBjb25zdHJ1Y3RlZCBmbGFnLiBJZgogICAgY29uc3RydWN0ZWQsIGl0IHdpbGwgY29udGFpbiBhIGxpc3Qgb2Ygb3RoZXIgYXNuMSBvYmplY3RzLiBJZiBub3QsCiAgICBpdCB3aWxsIGNvbnRhaW4gdGhlIEFTTi4xIHZhbHVlIGFzIGFuIGFycmF5IG9mIGJ5dGVzIGZvcm1hdHRlZAogICAgYWNjb3JkaW5nIHRvIHRoZSBBU04uMSBkYXRhIHR5cGUuICovCgogIC8vIHJlbW92ZSB1bmRlZmluZWQgdmFsdWVzCiAgaWYoZm9yZ2UudXRpbC5pc0FycmF5KHZhbHVlKSkgewogICAgdmFyIHRtcCA9IFtdOwogICAgZm9yKHZhciBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgKytpKSB7CiAgICAgIGlmKHZhbHVlW2ldICE9PSB1bmRlZmluZWQpIHsKICAgICAgICB0bXAucHVzaCh2YWx1ZVtpXSk7CiAgICAgIH0KICAgIH0KICAgIHZhbHVlID0gdG1wOwogIH0KCiAgcmV0dXJuIHsKICAgIHRhZ0NsYXNzOiB0YWdDbGFzcywKICAgIHR5cGU6IHR5cGUsCiAgICBjb25zdHJ1Y3RlZDogY29uc3RydWN0ZWQsCiAgICBjb21wb3NlZDogY29uc3RydWN0ZWQgfHwgZm9yZ2UudXRpbC5pc0FycmF5KHZhbHVlKSwKICAgIHZhbHVlOiB2YWx1ZQogIH07Cn07CgovKioKICogR2V0cyB0aGUgbGVuZ3RoIG9mIGEgQkVSLWVuY29kZWQgQVNOLjEgdmFsdWUuCiAqCiAqIEluIGNhc2UgdGhlIGxlbmd0aCBpcyBub3Qgc3BlY2lmaWVkLCB1bmRlZmluZWQgaXMgcmV0dXJuZWQuCiAqCiAqIEBwYXJhbSBiIHRoZSBCRVItZW5jb2RlZCBBU04uMSBieXRlIGJ1ZmZlciwgc3RhcnRpbmcgd2l0aCB0aGUgZmlyc3QKICogICAgICAgICAgbGVuZ3RoIGJ5dGUuCiAqCiAqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgQkVSLWVuY29kZWQgQVNOLjEgdmFsdWUgb3IgdW5kZWZpbmVkLgogKi8KdmFyIF9nZXRWYWx1ZUxlbmd0aCA9IGFzbjEuZ2V0QmVyVmFsdWVMZW5ndGggPSBmdW5jdGlvbihiKSB7CiAgLy8gVE9ETzogbW92ZSB0aGlzIGZ1bmN0aW9uIGFuZCByZWxhdGVkIERFUi9CRVIgZnVuY3Rpb25zIHRvIGEgZGVyLmpzCiAgLy8gZmlsZTsgYmV0dGVyIGFic3RyYWN0IEFTTi4xIGF3YXkgZnJvbSBkZXIvYmVyLgogIHZhciBiMiA9IGIuZ2V0Qnl0ZSgpOwogIGlmKGIyID09PSAweDgwKSB7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0KCiAgLy8gc2VlIGlmIHRoZSBsZW5ndGggaXMgInNob3J0IGZvcm0iIG9yICJsb25nIGZvcm0iIChiaXQgOCBzZXQpCiAgdmFyIGxlbmd0aDsKICB2YXIgbG9uZ0Zvcm0gPSBiMiAmIDB4ODA7CiAgaWYoIWxvbmdGb3JtKSB7CiAgICAvLyBsZW5ndGggaXMganVzdCB0aGUgZmlyc3QgYnl0ZQogICAgbGVuZ3RoID0gYjI7CiAgfSBlbHNlIHsKICAgIC8vIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhlIGxlbmd0aCBpcyBzcGVjaWZpZWQgaW4gYml0cyA3IHRocm91Z2ggMQogICAgLy8gYW5kIGVhY2ggbGVuZ3RoIGJ5dGUgaXMgaW4gYmlnLWVuZGlhbiBiYXNlLTI1NgogICAgbGVuZ3RoID0gYi5nZXRJbnQoKGIyICYgMHg3RikgPDwgMyk7CiAgfQogIHJldHVybiBsZW5ndGg7Cn07CgovKioKICogUGFyc2VzIGFuIGFzbjEgb2JqZWN0IGZyb20gYSBieXRlIGJ1ZmZlciBpbiBERVIgZm9ybWF0LgogKgogKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGUgYnVmZmVyIHRvIHBhcnNlIGZyb20uCiAqIEBwYXJhbSBzdHJpY3QgdHJ1ZSB0byBiZSBzdHJpY3Qgd2hlbiBjaGVja2luZyB2YWx1ZSBsZW5ndGhzLCBmYWxzZSB0bwogKiAgICAgICAgICBhbGxvdyB0cnVuY2F0ZWQgdmFsdWVzIChkZWZhdWx0OiB0cnVlKS4KICoKICogQHJldHVybiB0aGUgcGFyc2VkIGFzbjEgb2JqZWN0LgogKi8KYXNuMS5mcm9tRGVyID0gZnVuY3Rpb24oYnl0ZXMsIHN0cmljdCkgewogIGlmKHN0cmljdCA9PT0gdW5kZWZpbmVkKSB7CiAgICBzdHJpY3QgPSB0cnVlOwogIH0KCiAgLy8gd3JhcCBpbiBidWZmZXIgaWYgbmVlZGVkCiAgaWYodHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJykgewogICAgYnl0ZXMgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihieXRlcyk7CiAgfQoKICAvLyBtaW5pbXVtIGxlbmd0aCBmb3IgQVNOLjEgREVSIHN0cnVjdHVyZSBpcyAyCiAgaWYoYnl0ZXMubGVuZ3RoKCkgPCAyKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1RvbyBmZXcgYnl0ZXMgdG8gcGFyc2UgREVSLicpOwogICAgZXJyb3IuYnl0ZXMgPSBieXRlcy5sZW5ndGgoKTsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gZ2V0IHRoZSBmaXJzdCBieXRlCiAgdmFyIGIxID0gYnl0ZXMuZ2V0Qnl0ZSgpOwoKICAvLyBnZXQgdGhlIHRhZyBjbGFzcwogIHZhciB0YWdDbGFzcyA9IChiMSAmIDB4QzApOwoKICAvLyBnZXQgdGhlIHR5cGUgKGJpdHMgMS01KQogIHZhciB0eXBlID0gYjEgJiAweDFGOwoKICAvLyBnZXQgdGhlIHZhbHVlIGxlbmd0aAogIHZhciBsZW5ndGggPSBfZ2V0VmFsdWVMZW5ndGgoYnl0ZXMpOwoKICAvLyBlbnN1cmUgdGhlcmUgYXJlIGVub3VnaCBieXRlcyB0byBnZXQgdGhlIHZhbHVlCiAgaWYoYnl0ZXMubGVuZ3RoKCkgPCBsZW5ndGgpIHsKICAgIGlmKHN0cmljdCkgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1RvbyBmZXcgYnl0ZXMgdG8gcmVhZCBBU04uMSB2YWx1ZS4nKTsKICAgICAgZXJyb3IuZGV0YWlsID0gYnl0ZXMubGVuZ3RoKCkgKyAnIDwgJyArIGxlbmd0aDsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CiAgICAvLyBOb3RlOiBiZSBsZW5pZW50IHdpdGggdHJ1bmNhdGVkIHZhbHVlcwogICAgbGVuZ3RoID0gYnl0ZXMubGVuZ3RoKCk7CiAgfQoKICAvLyBwcmVwYXJlIHRvIGdldCB2YWx1ZQogIHZhciB2YWx1ZTsKCiAgLy8gY29uc3RydWN0ZWQgZmxhZyBpcyBiaXQgNiAoMzIgPSAweDIwKSBvZiB0aGUgZmlyc3QgYnl0ZQogIHZhciBjb25zdHJ1Y3RlZCA9ICgoYjEgJiAweDIwKSA9PT0gMHgyMCk7CgogIC8vIGRldGVybWluZSBpZiB0aGUgdmFsdWUgaXMgY29tcG9zZWQgb2Ygb3RoZXIgQVNOLjEgb2JqZWN0cyAoaWYgaXRzCiAgLy8gY29uc3RydWN0ZWQgaXQgd2lsbCBiZSBhbmQgaWYgaXRzIGEgQklUU1RSSU5HIGl0IG1heSBiZSkKICB2YXIgY29tcG9zZWQgPSBjb25zdHJ1Y3RlZDsKICBpZighY29tcG9zZWQgJiYgdGFnQ2xhc3MgPT09IGFzbjEuQ2xhc3MuVU5JVkVSU0FMICYmCiAgICB0eXBlID09PSBhc24xLlR5cGUuQklUU1RSSU5HICYmIGxlbmd0aCA+IDEpIHsKICAgIC8qIFRoZSBmaXJzdCBvY3RldCBnaXZlcyB0aGUgbnVtYmVyIG9mIGJpdHMgYnkgd2hpY2ggdGhlIGxlbmd0aCBvZiB0aGUKICAgICAgYml0IHN0cmluZyBpcyBsZXNzIHRoYW4gdGhlIG5leHQgbXVsdGlwbGUgb2YgZWlnaHQgKHRoaXMgaXMgY2FsbGVkCiAgICAgIHRoZSAibnVtYmVyIG9mIHVudXNlZCBiaXRzIikuCgogICAgICBUaGUgc2Vjb25kIGFuZCBmb2xsb3dpbmcgb2N0ZXRzIGdpdmUgdGhlIHZhbHVlIG9mIHRoZSBiaXQgc3RyaW5nCiAgICAgIGNvbnZlcnRlZCB0byBhbiBvY3RldCBzdHJpbmcuICovCiAgICAvLyBpZiB0aGVyZSBhcmUgbm8gdW51c2VkIGJpdHMsIG1heWJlIHRoZSBiaXRzdHJpbmcgaG9sZHMgQVNOLjEgb2JqcwogICAgdmFyIHJlYWQgPSBieXRlcy5yZWFkOwogICAgdmFyIHVudXNlZCA9IGJ5dGVzLmdldEJ5dGUoKTsKICAgIGlmKHVudXNlZCA9PT0gMCkgewogICAgICAvLyBpZiB0aGUgZmlyc3QgYnl0ZSBpbmRpY2F0ZXMgVU5JVkVSU0FMIG9yIENPTlRFWFRfU1BFQ0lGSUMsCiAgICAgIC8vIGFuZCB0aGUgbGVuZ3RoIGlzIHZhbGlkLCBhc3N1bWUgd2UndmUgZ290IGFuIEFTTi4xIG9iamVjdAogICAgICBiMSA9IGJ5dGVzLmdldEJ5dGUoKTsKICAgICAgdmFyIHRjID0gKGIxICYgMHhDMCk7CiAgICAgIGlmKHRjID09PSBhc24xLkNsYXNzLlVOSVZFUlNBTCB8fCB0YyA9PT0gYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHZhciBsZW4gPSBfZ2V0VmFsdWVMZW5ndGgoYnl0ZXMpOwogICAgICAgICAgY29tcG9zZWQgPSAobGVuID09PSBsZW5ndGggLSAoYnl0ZXMucmVhZCAtIHJlYWQpKTsKICAgICAgICAgIGlmKGNvbXBvc2VkKSB7CiAgICAgICAgICAgIC8vIGFkanVzdCByZWFkL2xlbmd0aCB0byBhY2NvdW50IGZvciB1bnVzZWQgYml0cyBieXRlCiAgICAgICAgICAgICsrcmVhZDsKICAgICAgICAgICAgLS1sZW5ndGg7CiAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaChleCkge30KICAgICAgfQogICAgfQogICAgLy8gcmVzdG9yZSByZWFkIHBvaW50ZXIKICAgIGJ5dGVzLnJlYWQgPSByZWFkOwogIH0KCiAgaWYoY29tcG9zZWQpIHsKICAgIC8vIHBhcnNlIGNoaWxkIGFzbjEgb2JqZWN0cyBmcm9tIHRoZSB2YWx1ZQogICAgdmFsdWUgPSBbXTsKICAgIGlmKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIC8vIGFzbjEgb2JqZWN0IG9mIGluZGVmaW5pdGUgbGVuZ3RoLCByZWFkIHVudGlsIGVuZCB0YWcKICAgICAgZm9yKDs7KSB7CiAgICAgICAgaWYoYnl0ZXMuYnl0ZXMoMikgPT09IFN0cmluZy5mcm9tQ2hhckNvZGUoMCwgMCkpIHsKICAgICAgICAgIGJ5dGVzLmdldEJ5dGVzKDIpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHZhbHVlLnB1c2goYXNuMS5mcm9tRGVyKGJ5dGVzLCBzdHJpY3QpKTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgLy8gcGFyc2luZyBhc24xIG9iamVjdCBvZiBkZWZpbml0ZSBsZW5ndGgKICAgICAgdmFyIHN0YXJ0ID0gYnl0ZXMubGVuZ3RoKCk7CiAgICAgIHdoaWxlKGxlbmd0aCA+IDApIHsKICAgICAgICB2YWx1ZS5wdXNoKGFzbjEuZnJvbURlcihieXRlcywgc3RyaWN0KSk7CiAgICAgICAgbGVuZ3RoIC09IHN0YXJ0IC0gYnl0ZXMubGVuZ3RoKCk7CiAgICAgICAgc3RhcnQgPSBieXRlcy5sZW5ndGgoKTsKICAgICAgfQogICAgfQogIH0gZWxzZSB7CiAgICAvLyBhc24xIG5vdCBjb21wb3NlZCwgZ2V0IHJhdyB2YWx1ZQogICAgLy8gVE9ETzogZG8gREVSIHRvIE9JRCBjb252ZXJzaW9uIGFuZCB2aWNlLXZlcnNhIGluIC50b0Rlcj8KCiAgICBpZihsZW5ndGggPT09IHVuZGVmaW5lZCkgewogICAgICBpZihzdHJpY3QpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vbi1jb25zdHJ1Y3RlZCBBU04uMSBvYmplY3Qgb2YgaW5kZWZpbml0ZSBsZW5ndGguJyk7CiAgICAgIH0KICAgICAgLy8gYmUgbGVuaWVudCBhbmQgdXNlIHJlbWFpbmluZyBieXRlcwogICAgICBsZW5ndGggPSBieXRlcy5sZW5ndGgoKTsKICAgIH0KCiAgICBpZih0eXBlID09PSBhc24xLlR5cGUuQk1QU1RSSU5HKSB7CiAgICAgIHZhbHVlID0gJyc7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMikgewogICAgICAgIHZhbHVlICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXMuZ2V0SW50MTYoKSk7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHZhbHVlID0gYnl0ZXMuZ2V0Qnl0ZXMobGVuZ3RoKTsKICAgIH0KICB9CgogIC8vIGNyZWF0ZSBhbmQgcmV0dXJuIGFzbjEgb2JqZWN0CiAgcmV0dXJuIGFzbjEuY3JlYXRlKHRhZ0NsYXNzLCB0eXBlLCBjb25zdHJ1Y3RlZCwgdmFsdWUpOwp9OwoKLyoqCiAqIENvbnZlcnRzIHRoZSBnaXZlbiBhc24xIG9iamVjdCB0byBhIGJ1ZmZlciBvZiBieXRlcyBpbiBERVIgZm9ybWF0LgogKgogKiBAcGFyYW0gYXNuMSB0aGUgYXNuMSBvYmplY3QgdG8gY29udmVydCB0byBieXRlcy4KICoKICogQHJldHVybiB0aGUgYnVmZmVyIG9mIGJ5dGVzLgogKi8KYXNuMS50b0RlciA9IGZ1bmN0aW9uKG9iaikgewogIHZhciBieXRlcyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIGJ1aWxkIHRoZSBmaXJzdCBieXRlCiAgdmFyIGIxID0gb2JqLnRhZ0NsYXNzIHwgb2JqLnR5cGU7CgogIC8vIGZvciBzdG9yaW5nIHRoZSBBU04uMSB2YWx1ZQogIHZhciB2YWx1ZSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIGlmIGNvbXBvc2VkLCB1c2UgZWFjaCBjaGlsZCBhc24xIG9iamVjdCdzIERFUiBieXRlcyBhcyB2YWx1ZQogIGlmKG9iai5jb21wb3NlZCkgewogICAgLy8gdHVybiBvbiA2dGggYml0ICgweDIwID0gMzIpIHRvIGluZGljYXRlIGFzbjEgaXMgY29uc3RydWN0ZWQKICAgIC8vIGZyb20gb3RoZXIgYXNuMSBvYmplY3RzCiAgICBpZihvYmouY29uc3RydWN0ZWQpIHsKICAgICAgYjEgfD0gMHgyMDsKICAgIH0gZWxzZSB7CiAgICAgIC8vIHR5cGUgaXMgYSBiaXQgc3RyaW5nLCBhZGQgdW51c2VkIGJpdHMgb2YgMHgwMAogICAgICB2YWx1ZS5wdXRCeXRlKDB4MDApOwogICAgfQoKICAgIC8vIGFkZCBhbGwgb2YgdGhlIGNoaWxkIERFUiBieXRlcyB0b2dldGhlcgogICAgZm9yKHZhciBpID0gMDsgaSA8IG9iai52YWx1ZS5sZW5ndGg7ICsraSkgewogICAgICBpZihvYmoudmFsdWVbaV0gIT09IHVuZGVmaW5lZCkgewogICAgICAgIHZhbHVlLnB1dEJ1ZmZlcihhc24xLnRvRGVyKG9iai52YWx1ZVtpXSkpOwogICAgICB9CiAgICB9CiAgfSBlbHNlIHsKICAgIC8vIHVzZSBhc24xLnZhbHVlIGRpcmVjdGx5CiAgICBpZihvYmoudHlwZSA9PT0gYXNuMS5UeXBlLkJNUFNUUklORykgewogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgb2JqLnZhbHVlLmxlbmd0aDsgKytpKSB7CiAgICAgICAgdmFsdWUucHV0SW50MTYob2JqLnZhbHVlLmNoYXJDb2RlQXQoaSkpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICB2YWx1ZS5wdXRCeXRlcyhvYmoudmFsdWUpOwogICAgfQogIH0KCiAgLy8gYWRkIHRhZyBieXRlCiAgYnl0ZXMucHV0Qnl0ZShiMSk7CgogIC8vIHVzZSAic2hvcnQgZm9ybSIgZW5jb2RpbmcKICBpZih2YWx1ZS5sZW5ndGgoKSA8PSAxMjcpIHsKICAgIC8vIG9uZSBieXRlIGRlc2NyaWJlcyB0aGUgbGVuZ3RoCiAgICAvLyBiaXQgOCA9IDAgYW5kIGJpdHMgNy0xID0gbGVuZ3RoCiAgICBieXRlcy5wdXRCeXRlKHZhbHVlLmxlbmd0aCgpICYgMHg3Rik7CiAgfSBlbHNlIHsKICAgIC8vIHVzZSAibG9uZyBmb3JtIiBlbmNvZGluZwogICAgLy8gMiB0byAxMjcgYnl0ZXMgZGVzY3JpYmUgdGhlIGxlbmd0aAogICAgLy8gZmlyc3QgYnl0ZTogYml0IDggPSAxIGFuZCBiaXRzIDctMSA9ICMgb2YgYWRkaXRpb25hbCBieXRlcwogICAgLy8gb3RoZXIgYnl0ZXM6IGxlbmd0aCBpbiBiYXNlIDI1NiwgYmlnLWVuZGlhbgogICAgdmFyIGxlbiA9IHZhbHVlLmxlbmd0aCgpOwogICAgdmFyIGxlbkJ5dGVzID0gJyc7CiAgICBkbyB7CiAgICAgIGxlbkJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUobGVuICYgMHhGRik7CiAgICAgIGxlbiA9IGxlbiA+Pj4gODsKICAgIH0gd2hpbGUobGVuID4gMCk7CgogICAgLy8gc2V0IGZpcnN0IGJ5dGUgdG8gIyBieXRlcyB1c2VkIHRvIHN0b3JlIHRoZSBsZW5ndGggYW5kIHR1cm4gb24KICAgIC8vIGJpdCA4IHRvIGluZGljYXRlIGxvbmctZm9ybSBsZW5ndGggaXMgdXNlZAogICAgYnl0ZXMucHV0Qnl0ZShsZW5CeXRlcy5sZW5ndGggfCAweDgwKTsKCiAgICAvLyBjb25jYXRlbmF0ZSBsZW5ndGggYnl0ZXMgaW4gcmV2ZXJzZSBzaW5jZSB0aGV5IHdlcmUgZ2VuZXJhdGVkCiAgICAvLyBsaXR0bGUgZW5kaWFuIGFuZCB3ZSBuZWVkIGJpZyBlbmRpYW4KICAgIGZvcih2YXIgaSA9IGxlbkJ5dGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7CiAgICAgIGJ5dGVzLnB1dEJ5dGUobGVuQnl0ZXMuY2hhckNvZGVBdChpKSk7CiAgICB9CiAgfQoKICAvLyBjb25jYXRlbmF0ZSB2YWx1ZSBieXRlcwogIGJ5dGVzLnB1dEJ1ZmZlcih2YWx1ZSk7CiAgcmV0dXJuIGJ5dGVzOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIE9JRCBkb3Qtc2VwYXJhdGVkIHN0cmluZyB0byBhIGJ5dGUgYnVmZmVyLiBUaGUgYnl0ZSBidWZmZXIKICogY29udGFpbnMgb25seSB0aGUgREVSLWVuY29kZWQgdmFsdWUsIG5vdCBhbnkgdGFnIG9yIGxlbmd0aCBieXRlcy4KICoKICogQHBhcmFtIG9pZCB0aGUgT0lEIGRvdC1zZXBhcmF0ZWQgc3RyaW5nLgogKgogKiBAcmV0dXJuIHRoZSBieXRlIGJ1ZmZlci4KICovCmFzbjEub2lkVG9EZXIgPSBmdW5jdGlvbihvaWQpIHsKICAvLyBzcGxpdCBPSUQgaW50byBpbmRpdmlkdWFsIHZhbHVlcwogIHZhciB2YWx1ZXMgPSBvaWQuc3BsaXQoJy4nKTsKICB2YXIgYnl0ZXMgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwoKICAvLyBmaXJzdCBieXRlIGlzIDQwICogdmFsdWUxICsgdmFsdWUyCiAgYnl0ZXMucHV0Qnl0ZSg0MCAqIHBhcnNlSW50KHZhbHVlc1swXSwgMTApICsgcGFyc2VJbnQodmFsdWVzWzFdLCAxMCkpOwogIC8vIG90aGVyIGJ5dGVzIGFyZSBlYWNoIHZhbHVlIGluIGJhc2UgMTI4IHdpdGggOHRoIGJpdCBzZXQgZXhjZXB0IGZvcgogIC8vIHRoZSBsYXN0IGJ5dGUgZm9yIGVhY2ggdmFsdWUKICB2YXIgbGFzdCwgdmFsdWVCeXRlcywgdmFsdWUsIGI7CiAgZm9yKHZhciBpID0gMjsgaSA8IHZhbHVlcy5sZW5ndGg7ICsraSkgewogICAgLy8gcHJvZHVjZSB2YWx1ZSBieXRlcyBpbiByZXZlcnNlIGJlY2F1c2Ugd2UgZG9uJ3Qga25vdyBob3cgbWFueQogICAgLy8gYnl0ZXMgaXQgd2lsbCB0YWtlIHRvIHN0b3JlIHRoZSB2YWx1ZQogICAgbGFzdCA9IHRydWU7CiAgICB2YWx1ZUJ5dGVzID0gW107CiAgICB2YWx1ZSA9IHBhcnNlSW50KHZhbHVlc1tpXSwgMTApOwogICAgZG8gewogICAgICBiID0gdmFsdWUgJiAweDdGOwogICAgICB2YWx1ZSA9IHZhbHVlID4+PiA3OwogICAgICAvLyBpZiB2YWx1ZSBpcyBub3QgbGFzdCwgdGhlbiB0dXJuIG9uIDh0aCBiaXQKICAgICAgaWYoIWxhc3QpIHsKICAgICAgICBiIHw9IDB4ODA7CiAgICAgIH0KICAgICAgdmFsdWVCeXRlcy5wdXNoKGIpOwogICAgICBsYXN0ID0gZmFsc2U7CiAgICB9IHdoaWxlKHZhbHVlID4gMCk7CgogICAgLy8gYWRkIHZhbHVlIGJ5dGVzIGluIHJldmVyc2UgKG5lZWRzIHRvIGJlIGluIGJpZyBlbmRpYW4pCiAgICBmb3IodmFyIG4gPSB2YWx1ZUJ5dGVzLmxlbmd0aCAtIDE7IG4gPj0gMDsgLS1uKSB7CiAgICAgIGJ5dGVzLnB1dEJ5dGUodmFsdWVCeXRlc1tuXSk7CiAgICB9CiAgfQoKICByZXR1cm4gYnl0ZXM7Cn07CgovKioKICogQ29udmVydHMgYSBERVItZW5jb2RlZCBieXRlIGJ1ZmZlciB0byBhbiBPSUQgZG90LXNlcGFyYXRlZCBzdHJpbmcuIFRoZQogKiBieXRlIGJ1ZmZlciBzaG91bGQgY29udGFpbiBvbmx5IHRoZSBERVItZW5jb2RlZCB2YWx1ZSwgbm90IGFueSB0YWcgb3IKICogbGVuZ3RoIGJ5dGVzLgogKgogKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGUgYnVmZmVyLgogKgogKiBAcmV0dXJuIHRoZSBPSUQgZG90LXNlcGFyYXRlZCBzdHJpbmcuCiAqLwphc24xLmRlclRvT2lkID0gZnVuY3Rpb24oYnl0ZXMpIHsKICB2YXIgb2lkOwoKICAvLyB3cmFwIGluIGJ1ZmZlciBpZiBuZWVkZWQKICBpZih0eXBlb2YgYnl0ZXMgPT09ICdzdHJpbmcnKSB7CiAgICBieXRlcyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGJ5dGVzKTsKICB9CgogIC8vIGZpcnN0IGJ5dGUgaXMgNDAgKiB2YWx1ZTEgKyB2YWx1ZTIKICB2YXIgYiA9IGJ5dGVzLmdldEJ5dGUoKTsKICBvaWQgPSBNYXRoLmZsb29yKGIgLyA0MCkgKyAnLicgKyAoYiAlIDQwKTsKCiAgLy8gb3RoZXIgYnl0ZXMgYXJlIGVhY2ggdmFsdWUgaW4gYmFzZSAxMjggd2l0aCA4dGggYml0IHNldCBleGNlcHQgZm9yCiAgLy8gdGhlIGxhc3QgYnl0ZSBmb3IgZWFjaCB2YWx1ZQogIHZhciB2YWx1ZSA9IDA7CiAgd2hpbGUoYnl0ZXMubGVuZ3RoKCkgPiAwKSB7CiAgICBiID0gYnl0ZXMuZ2V0Qnl0ZSgpOwogICAgdmFsdWUgPSB2YWx1ZSA8PCA3OwogICAgLy8gbm90IHRoZSBsYXN0IGJ5dGUgZm9yIHRoZSB2YWx1ZQogICAgaWYoYiAmIDB4ODApIHsKICAgICAgdmFsdWUgKz0gYiAmIDB4N0Y7CiAgICB9IGVsc2UgewogICAgICAvLyBsYXN0IGJ5dGUKICAgICAgb2lkICs9ICcuJyArICh2YWx1ZSArIGIpOwogICAgICB2YWx1ZSA9IDA7CiAgICB9CiAgfQoKICByZXR1cm4gb2lkOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgVVRDVGltZSB2YWx1ZSB0byBhIGRhdGUuCiAqCiAqIE5vdGU6IEdlbmVyYWxpemVkVGltZSBoYXMgNCBkaWdpdHMgZm9yIHRoZSB5ZWFyIGFuZCBpcyB1c2VkIGZvciBYLjUwOQogKiBkYXRlcyBwYXNzZWQgMjA0OS4gUGFyc2luZyB0aGF0IHN0cnVjdHVyZSBoYXNuJ3QgYmVlbiBpbXBsZW1lbnRlZCB5ZXQuCiAqCiAqIEBwYXJhbSB1dGMgdGhlIFVUQ1RpbWUgdmFsdWUgdG8gY29udmVydC4KICoKICogQHJldHVybiB0aGUgZGF0ZS4KICovCmFzbjEudXRjVGltZVRvRGF0ZSA9IGZ1bmN0aW9uKHV0YykgewogIC8qIFRoZSBmb2xsb3dpbmcgZm9ybWF0cyBjYW4gYmUgdXNlZDoKCiAgICBZWU1NRERoaG1tWgogICAgWVlNTUREaGhtbStoaCdtbScKICAgIFlZTU1ERGhobW0taGgnbW0nCiAgICBZWU1NRERoaG1tc3NaCiAgICBZWU1NRERoaG1tc3MraGgnbW0nCiAgICBZWU1NRERoaG1tc3MtaGgnbW0nCgogICAgV2hlcmU6CgogICAgWVkgaXMgdGhlIGxlYXN0IHNpZ25pZmljYW50IHR3byBkaWdpdHMgb2YgdGhlIHllYXIKICAgIE1NIGlzIHRoZSBtb250aCAoMDEgdG8gMTIpCiAgICBERCBpcyB0aGUgZGF5ICgwMSB0byAzMSkKICAgIGhoIGlzIHRoZSBob3VyICgwMCB0byAyMykKICAgIG1tIGFyZSB0aGUgbWludXRlcyAoMDAgdG8gNTkpCiAgICBzcyBhcmUgdGhlIHNlY29uZHMgKDAwIHRvIDU5KQogICAgWiBpbmRpY2F0ZXMgdGhhdCBsb2NhbCB0aW1lIGlzIEdNVCwgKyBpbmRpY2F0ZXMgdGhhdCBsb2NhbCB0aW1lIGlzCiAgICBsYXRlciB0aGFuIEdNVCwgYW5kIC0gaW5kaWNhdGVzIHRoYXQgbG9jYWwgdGltZSBpcyBlYXJsaWVyIHRoYW4gR01UCiAgICBoaCcgaXMgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoZSBvZmZzZXQgZnJvbSBHTVQgaW4gaG91cnMKICAgIG1tJyBpcyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIG9mZnNldCBmcm9tIEdNVCBpbiBtaW51dGVzICovCiAgdmFyIGRhdGUgPSBuZXcgRGF0ZSgpOwoKICAvLyBpZiBZWSA+PSA1MCB1c2UgMTl4eCwgaWYgWVkgPCA1MCB1c2UgMjB4eAogIHZhciB5ZWFyID0gcGFyc2VJbnQodXRjLnN1YnN0cigwLCAyKSwgMTApOwogIHllYXIgPSAoeWVhciA+PSA1MCkgPyAxOTAwICsgeWVhciA6IDIwMDAgKyB5ZWFyOwogIHZhciBNTSA9IHBhcnNlSW50KHV0Yy5zdWJzdHIoMiwgMiksIDEwKSAtIDE7IC8vIHVzZSAwLTExIGZvciBtb250aAogIHZhciBERCA9IHBhcnNlSW50KHV0Yy5zdWJzdHIoNCwgMiksIDEwKTsKICB2YXIgaGggPSBwYXJzZUludCh1dGMuc3Vic3RyKDYsIDIpLCAxMCk7CiAgdmFyIG1tID0gcGFyc2VJbnQodXRjLnN1YnN0cig4LCAyKSwgMTApOwogIHZhciBzcyA9IDA7CgogIC8vIG5vdCBqdXN0IFlZTU1ERGhobW1aCiAgaWYodXRjLmxlbmd0aCA+IDExKSB7CiAgICAvLyBnZXQgY2hhcmFjdGVyIGFmdGVyIG1pbnV0ZXMKICAgIHZhciBjID0gdXRjLmNoYXJBdCgxMCk7CiAgICB2YXIgZW5kID0gMTA7CgogICAgLy8gc2VlIGlmIHNlY29uZHMgYXJlIHByZXNlbnQKICAgIGlmKGMgIT09ICcrJyAmJiBjICE9PSAnLScpIHsKICAgICAgLy8gZ2V0IHNlY29uZHMKICAgICAgc3MgPSBwYXJzZUludCh1dGMuc3Vic3RyKDEwLCAyKSwgMTApOwogICAgICBlbmQgKz0gMjsKICAgIH0KICB9CgogIC8vIHVwZGF0ZSBkYXRlCiAgZGF0ZS5zZXRVVENGdWxsWWVhcih5ZWFyLCBNTSwgREQpOwogIGRhdGUuc2V0VVRDSG91cnMoaGgsIG1tLCBzcywgMCk7CgogIGlmKGVuZCkgewogICAgLy8gZ2V0ICsvLSBhZnRlciBlbmQgb2YgdGltZQogICAgYyA9IHV0Yy5jaGFyQXQoZW5kKTsKICAgIGlmKGMgPT09ICcrJyB8fCBjID09PSAnLScpIHsKICAgICAgLy8gZ2V0IGhvdXJzK21pbnV0ZXMgb2Zmc2V0CiAgICAgIHZhciBoaG9mZnNldCA9IHBhcnNlSW50KHV0Yy5zdWJzdHIoZW5kICsgMSwgMiksIDEwKTsKICAgICAgdmFyIG1tb2Zmc2V0ID0gcGFyc2VJbnQodXRjLnN1YnN0cihlbmQgKyA0LCAyKSwgMTApOwoKICAgICAgLy8gY2FsY3VsYXRlIG9mZnNldCBpbiBtaWxsaXNlY29uZHMKICAgICAgdmFyIG9mZnNldCA9IGhob2Zmc2V0ICogNjAgKyBtbW9mZnNldDsKICAgICAgb2Zmc2V0ICo9IDYwMDAwOwoKICAgICAgLy8gYXBwbHkgb2Zmc2V0CiAgICAgIGlmKGMgPT09ICcrJykgewogICAgICAgIGRhdGUuc2V0VGltZSgrZGF0ZSAtIG9mZnNldCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGF0ZS5zZXRUaW1lKCtkYXRlICsgb2Zmc2V0KTsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIGRhdGU7Cn07CgovKioKICogQ29udmVydHMgYSBHZW5lcmFsaXplZFRpbWUgdmFsdWUgdG8gYSBkYXRlLgogKgogKiBAcGFyYW0gZ2VudGltZSB0aGUgR2VuZXJhbGl6ZWRUaW1lIHZhbHVlIHRvIGNvbnZlcnQuCiAqCiAqIEByZXR1cm4gdGhlIGRhdGUuCiAqLwphc24xLmdlbmVyYWxpemVkVGltZVRvRGF0ZSA9IGZ1bmN0aW9uKGdlbnRpbWUpIHsKICAvKiBUaGUgZm9sbG93aW5nIGZvcm1hdHMgY2FuIGJlIHVzZWQ6CgogICAgWVlZWU1NRERISE1NU1MKICAgIFlZWVlNTURESEhNTVNTLmZmZgogICAgWVlZWU1NRERISE1NU1NaCiAgICBZWVlZTU1EREhITU1TUy5mZmZaCiAgICBZWVlZTU1EREhITU1TUytoaCdtbScKICAgIFlZWVlNTURESEhNTVNTLmZmZitoaCdtbScKICAgIFlZWVlNTURESEhNTVNTLWhoJ21tJwogICAgWVlZWU1NRERISE1NU1MuZmZmLWhoJ21tJwoKICAgIFdoZXJlOgoKICAgIFlZWVkgaXMgdGhlIHllYXIKICAgIE1NIGlzIHRoZSBtb250aCAoMDEgdG8gMTIpCiAgICBERCBpcyB0aGUgZGF5ICgwMSB0byAzMSkKICAgIGhoIGlzIHRoZSBob3VyICgwMCB0byAyMykKICAgIG1tIGFyZSB0aGUgbWludXRlcyAoMDAgdG8gNTkpCiAgICBzcyBhcmUgdGhlIHNlY29uZHMgKDAwIHRvIDU5KQogICAgLmZmZiBpcyB0aGUgc2Vjb25kIGZyYWN0aW9uLCBhY2N1cmF0ZSB0byB0aHJlZSBkZWNpbWFsIHBsYWNlcwogICAgWiBpbmRpY2F0ZXMgdGhhdCBsb2NhbCB0aW1lIGlzIEdNVCwgKyBpbmRpY2F0ZXMgdGhhdCBsb2NhbCB0aW1lIGlzCiAgICBsYXRlciB0aGFuIEdNVCwgYW5kIC0gaW5kaWNhdGVzIHRoYXQgbG9jYWwgdGltZSBpcyBlYXJsaWVyIHRoYW4gR01UCiAgICBoaCcgaXMgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoZSBvZmZzZXQgZnJvbSBHTVQgaW4gaG91cnMKICAgIG1tJyBpcyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIG9mZnNldCBmcm9tIEdNVCBpbiBtaW51dGVzICovCiAgdmFyIGRhdGUgPSBuZXcgRGF0ZSgpOwoKICB2YXIgWVlZWSA9IHBhcnNlSW50KGdlbnRpbWUuc3Vic3RyKDAsIDQpLCAxMCk7CiAgdmFyIE1NID0gcGFyc2VJbnQoZ2VudGltZS5zdWJzdHIoNCwgMiksIDEwKSAtIDE7IC8vIHVzZSAwLTExIGZvciBtb250aAogIHZhciBERCA9IHBhcnNlSW50KGdlbnRpbWUuc3Vic3RyKDYsIDIpLCAxMCk7CiAgdmFyIGhoID0gcGFyc2VJbnQoZ2VudGltZS5zdWJzdHIoOCwgMiksIDEwKTsKICB2YXIgbW0gPSBwYXJzZUludChnZW50aW1lLnN1YnN0cigxMCwgMiksIDEwKTsKICB2YXIgc3MgPSBwYXJzZUludChnZW50aW1lLnN1YnN0cigxMiwgMiksIDEwKTsKICB2YXIgZmZmID0gMDsKICB2YXIgb2Zmc2V0ID0gMDsKICB2YXIgaXNVVEMgPSBmYWxzZTsKCiAgaWYoZ2VudGltZS5jaGFyQXQoZ2VudGltZS5sZW5ndGggLSAxKSA9PT0gJ1onKSB7CiAgICBpc1VUQyA9IHRydWU7CiAgfQoKICB2YXIgZW5kID0gZ2VudGltZS5sZW5ndGggLSA1LCBjID0gZ2VudGltZS5jaGFyQXQoZW5kKTsKICBpZihjID09PSAnKycgfHwgYyA9PT0gJy0nKSB7CiAgICAvLyBnZXQgaG91cnMrbWludXRlcyBvZmZzZXQKICAgIHZhciBoaG9mZnNldCA9IHBhcnNlSW50KGdlbnRpbWUuc3Vic3RyKGVuZCArIDEsIDIpLCAxMCk7CiAgICB2YXIgbW1vZmZzZXQgPSBwYXJzZUludChnZW50aW1lLnN1YnN0cihlbmQgKyA0LCAyKSwgMTApOwoKICAgIC8vIGNhbGN1bGF0ZSBvZmZzZXQgaW4gbWlsbGlzZWNvbmRzCiAgICBvZmZzZXQgPSBoaG9mZnNldCAqIDYwICsgbW1vZmZzZXQ7CiAgICBvZmZzZXQgKj0gNjAwMDA7CgogICAgLy8gYXBwbHkgb2Zmc2V0CiAgICBpZihjID09PSAnKycpIHsKICAgICAgb2Zmc2V0ICo9IC0xOwogICAgfQoKICAgIGlzVVRDID0gdHJ1ZTsKICB9CgogIC8vIGNoZWNrIGZvciBzZWNvbmQgZnJhY3Rpb24KICBpZihnZW50aW1lLmNoYXJBdCgxNCkgPT09ICcuJykgewogICAgZmZmID0gcGFyc2VGbG9hdChnZW50aW1lLnN1YnN0cigxNCksIDEwKSAqIDEwMDA7CiAgfQoKICBpZihpc1VUQykgewogICAgZGF0ZS5zZXRVVENGdWxsWWVhcihZWVlZLCBNTSwgREQpOwogICAgZGF0ZS5zZXRVVENIb3VycyhoaCwgbW0sIHNzLCBmZmYpOwoKICAgIC8vIGFwcGx5IG9mZnNldAogICAgZGF0ZS5zZXRUaW1lKCtkYXRlICsgb2Zmc2V0KTsKICB9IGVsc2UgewogICAgZGF0ZS5zZXRGdWxsWWVhcihZWVlZLCBNTSwgREQpOwogICAgZGF0ZS5zZXRIb3VycyhoaCwgbW0sIHNzLCBmZmYpOwogIH0KCiAgcmV0dXJuIGRhdGU7Cn07CgovKioKICogQ29udmVydHMgYSBkYXRlIHRvIGEgVVRDVGltZSB2YWx1ZS4KICoKICogTm90ZTogR2VuZXJhbGl6ZWRUaW1lIGhhcyA0IGRpZ2l0cyBmb3IgdGhlIHllYXIgYW5kIGlzIHVzZWQgZm9yIFguNTA5CiAqIGRhdGVzIHBhc3NlZCAyMDQ5LiBDb252ZXJ0aW5nIHRvIGEgR2VuZXJhbGl6ZWRUaW1lIGhhc24ndCBiZWVuCiAqIGltcGxlbWVudGVkIHlldC4KICoKICogQHBhcmFtIGRhdGUgdGhlIGRhdGUgdG8gY29udmVydC4KICoKICogQHJldHVybiB0aGUgVVRDVGltZSB2YWx1ZS4KICovCmFzbjEuZGF0ZVRvVXRjVGltZSA9IGZ1bmN0aW9uKGRhdGUpIHsKICAvLyBUT0RPOiB2YWxpZGF0ZTsgY3VycmVudGx5IGFzc3VtZXMgcHJvcGVyIGZvcm1hdAogIGlmKHR5cGVvZiBkYXRlID09PSAnc3RyaW5nJykgewogICAgcmV0dXJuIGRhdGU7CiAgfQoKICB2YXIgcnZhbCA9ICcnOwoKICAvLyBjcmVhdGUgZm9ybWF0IFlZTU1ERGhobW1zc1oKICB2YXIgZm9ybWF0ID0gW107CiAgZm9ybWF0LnB1c2goKCcnICsgZGF0ZS5nZXRVVENGdWxsWWVhcigpKS5zdWJzdHIoMikpOwogIGZvcm1hdC5wdXNoKCcnICsgKGRhdGUuZ2V0VVRDTW9udGgoKSArIDEpKTsKICBmb3JtYXQucHVzaCgnJyArIGRhdGUuZ2V0VVRDRGF0ZSgpKTsKICBmb3JtYXQucHVzaCgnJyArIGRhdGUuZ2V0VVRDSG91cnMoKSk7CiAgZm9ybWF0LnB1c2goJycgKyBkYXRlLmdldFVUQ01pbnV0ZXMoKSk7CiAgZm9ybWF0LnB1c2goJycgKyBkYXRlLmdldFVUQ1NlY29uZHMoKSk7CgogIC8vIGVuc3VyZSAyIGRpZ2l0cyBhcmUgdXNlZCBmb3IgZWFjaCBmb3JtYXQgZW50cnkKICBmb3IodmFyIGkgPSAwOyBpIDwgZm9ybWF0Lmxlbmd0aDsgKytpKSB7CiAgICBpZihmb3JtYXRbaV0ubGVuZ3RoIDwgMikgewogICAgICBydmFsICs9ICcwJzsKICAgIH0KICAgIHJ2YWwgKz0gZm9ybWF0W2ldOwogIH0KICBydmFsICs9ICdaJzsKCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ29udmVydHMgYSBkYXRlIHRvIGEgR2VuZXJhbGl6ZWRUaW1lIHZhbHVlLgogKgogKiBAcGFyYW0gZGF0ZSB0aGUgZGF0ZSB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBHZW5lcmFsaXplZFRpbWUgdmFsdWUgYXMgYSBzdHJpbmcuCiAqLwphc24xLmRhdGVUb0dlbmVyYWxpemVkVGltZSA9IGZ1bmN0aW9uKGRhdGUpIHsKICAvLyBUT0RPOiB2YWxpZGF0ZTsgY3VycmVudGx5IGFzc3VtZXMgcHJvcGVyIGZvcm1hdAogIGlmKHR5cGVvZiBkYXRlID09PSAnc3RyaW5nJykgewogICAgcmV0dXJuIGRhdGU7CiAgfQoKICB2YXIgcnZhbCA9ICcnOwoKICAvLyBjcmVhdGUgZm9ybWF0IFlZWVlNTURESEhNTVNTWgogIHZhciBmb3JtYXQgPSBbXTsKICBmb3JtYXQucHVzaCgnJyArIGRhdGUuZ2V0VVRDRnVsbFllYXIoKSk7CiAgZm9ybWF0LnB1c2goJycgKyAoZGF0ZS5nZXRVVENNb250aCgpICsgMSkpOwogIGZvcm1hdC5wdXNoKCcnICsgZGF0ZS5nZXRVVENEYXRlKCkpOwogIGZvcm1hdC5wdXNoKCcnICsgZGF0ZS5nZXRVVENIb3VycygpKTsKICBmb3JtYXQucHVzaCgnJyArIGRhdGUuZ2V0VVRDTWludXRlcygpKTsKICBmb3JtYXQucHVzaCgnJyArIGRhdGUuZ2V0VVRDU2Vjb25kcygpKTsKCiAgLy8gZW5zdXJlIDIgZGlnaXRzIGFyZSB1c2VkIGZvciBlYWNoIGZvcm1hdCBlbnRyeQogIGZvcih2YXIgaSA9IDA7IGkgPCBmb3JtYXQubGVuZ3RoOyArK2kpIHsKICAgIGlmKGZvcm1hdFtpXS5sZW5ndGggPCAyKSB7CiAgICAgIHJ2YWwgKz0gJzAnOwogICAgfQogICAgcnZhbCArPSBmb3JtYXRbaV07CiAgfQogIHJ2YWwgKz0gJ1onOwoKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDb252ZXJ0cyBhIGphdmFzY3JpcHQgaW50ZWdlciB0byBhIERFUi1lbmNvZGVkIGJ5dGUgYnVmZmVyIHRvIGJlIHVzZWQKICogYXMgdGhlIHZhbHVlIGZvciBhbiBJTlRFR0VSIHR5cGUuCiAqCiAqIEBwYXJhbSB4IHRoZSBpbnRlZ2VyLgogKgogKiBAcmV0dXJuIHRoZSBieXRlIGJ1ZmZlci4KICovCmFzbjEuaW50ZWdlclRvRGVyID0gZnVuY3Rpb24oeCkgewogIHZhciBydmFsID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBpZih4ID49IC0weDgwICYmIHggPCAweDgwKSB7CiAgICByZXR1cm4gcnZhbC5wdXRTaWduZWRJbnQoeCwgOCk7CiAgfQogIGlmKHggPj0gLTB4ODAwMCAmJiB4IDwgMHg4MDAwKSB7CiAgICByZXR1cm4gcnZhbC5wdXRTaWduZWRJbnQoeCwgMTYpOwogIH0KICBpZih4ID49IC0weDgwMDAwMCAmJiB4IDwgMHg4MDAwMDApIHsKICAgIHJldHVybiBydmFsLnB1dFNpZ25lZEludCh4LCAyNCk7CiAgfQogIGlmKHggPj0gLTB4ODAwMDAwMDAgJiYgeCA8IDB4ODAwMDAwMDApIHsKICAgIHJldHVybiBydmFsLnB1dFNpZ25lZEludCh4LCAzMik7CiAgfQogIHZhciBlcnJvciA9IG5ldyBFcnJvcignSW50ZWdlciB0b28gbGFyZ2U7IG1heCBpcyAzMi1iaXRzLicpOwogIGVycm9yLmludGVnZXIgPSB4OwogIHRocm93IGVycm9yOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgREVSLWVuY29kZWQgYnl0ZSBidWZmZXIgdG8gYSBqYXZhc2NyaXB0IGludGVnZXIuIFRoaXMgaXMKICogdHlwaWNhbGx5IHVzZWQgdG8gZGVjb2RlIHRoZSB2YWx1ZSBvZiBhbiBJTlRFR0VSIHR5cGUuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZSBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhlIGludGVnZXIuCiAqLwphc24xLmRlclRvSW50ZWdlciA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgLy8gd3JhcCBpbiBidWZmZXIgaWYgbmVlZGVkCiAgaWYodHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJykgewogICAgYnl0ZXMgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihieXRlcyk7CiAgfQoKICB2YXIgbiA9IGJ5dGVzLmxlbmd0aCgpICogODsKICBpZihuID4gMzIpIHsKICAgIHRocm93IG5ldyBFcnJvcignSW50ZWdlciB0b28gbGFyZ2U7IG1heCBpcyAzMi1iaXRzLicpOwogIH0KICByZXR1cm4gYnl0ZXMuZ2V0U2lnbmVkSW50KG4pOwp9OwoKLyoqCiAqIFZhbGlkYXRlcyB0aGUgdGhhdCBnaXZlbiBBU04uMSBvYmplY3QgaXMgYXQgbGVhc3QgYSBzdXBlciBzZXQgb2YgdGhlCiAqIGdpdmVuIEFTTi4xIHN0cnVjdHVyZS4gT25seSB0YWcgY2xhc3NlcyBhbmQgdHlwZXMgYXJlIGNoZWNrZWQuIEFuCiAqIG9wdGlvbmFsIG1hcCBtYXkgYWxzbyBiZSBwcm92aWRlZCB0byBjYXB0dXJlIEFTTi4xIHZhbHVlcyB3aGlsZSB0aGUKICogc3RydWN0dXJlIGlzIGNoZWNrZWQuCiAqCiAqIFRvIGNhcHR1cmUgYW4gQVNOLjEgdmFsdWUsIHNldCBhbiBvYmplY3QgaW4gdGhlIHZhbGlkYXRvcidzICdjYXB0dXJlJwogKiBwYXJhbWV0ZXIgdG8gdGhlIGtleSB0byB1c2UgaW4gdGhlIGNhcHR1cmUgbWFwLiBUbyBjYXB0dXJlIHRoZSBmdWxsCiAqIEFTTi4xIG9iamVjdCwgc3BlY2lmeSAnY2FwdHVyZUFzbjEnLgogKgogKiBPYmplY3RzIGluIHRoZSB2YWxpZGF0b3IgbWF5IHNldCBhIGZpZWxkICdvcHRpb25hbCcgdG8gdHJ1ZSB0byBpbmRpY2F0ZQogKiB0aGF0IGl0IGlzbid0IG5lY2Vzc2FyeSB0byBwYXNzIHZhbGlkYXRpb24uCiAqCiAqIEBwYXJhbSBvYmogdGhlIEFTTi4xIG9iamVjdCB0byB2YWxpZGF0ZS4KICogQHBhcmFtIHYgdGhlIEFTTi4xIHN0cnVjdHVyZSB2YWxpZGF0b3IuCiAqIEBwYXJhbSBjYXB0dXJlIGFuIG9wdGlvbmFsIG1hcCB0byBjYXB0dXJlIHZhbHVlcyBpbi4KICogQHBhcmFtIGVycm9ycyBhbiBvcHRpb25hbCBhcnJheSBmb3Igc3RvcmluZyB2YWxpZGF0aW9uIGVycm9ycy4KICoKICogQHJldHVybiB0cnVlIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGZhaWx1cmUuCiAqLwphc24xLnZhbGlkYXRlID0gZnVuY3Rpb24ob2JqLCB2LCBjYXB0dXJlLCBlcnJvcnMpIHsKICB2YXIgcnZhbCA9IGZhbHNlOwoKICAvLyBlbnN1cmUgdGFnIGNsYXNzIGFuZCB0eXBlIGFyZSB0aGUgc2FtZSBpZiBzcGVjaWZpZWQKICBpZigob2JqLnRhZ0NsYXNzID09PSB2LnRhZ0NsYXNzIHx8IHR5cGVvZih2LnRhZ0NsYXNzKSA9PT0gJ3VuZGVmaW5lZCcpICYmCiAgICAob2JqLnR5cGUgPT09IHYudHlwZSB8fCB0eXBlb2Yodi50eXBlKSA9PT0gJ3VuZGVmaW5lZCcpKSB7CiAgICAvLyBlbnN1cmUgY29uc3RydWN0ZWQgZmxhZyBpcyB0aGUgc2FtZSBpZiBzcGVjaWZpZWQKICAgIGlmKG9iai5jb25zdHJ1Y3RlZCA9PT0gdi5jb25zdHJ1Y3RlZCB8fAogICAgICB0eXBlb2Yodi5jb25zdHJ1Y3RlZCkgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIHJ2YWwgPSB0cnVlOwoKICAgICAgLy8gaGFuZGxlIHN1YiB2YWx1ZXMKICAgICAgaWYodi52YWx1ZSAmJiBmb3JnZS51dGlsLmlzQXJyYXkodi52YWx1ZSkpIHsKICAgICAgICB2YXIgaiA9IDA7CiAgICAgICAgZm9yKHZhciBpID0gMDsgcnZhbCAmJiBpIDwgdi52YWx1ZS5sZW5ndGg7ICsraSkgewogICAgICAgICAgcnZhbCA9IHYudmFsdWVbaV0ub3B0aW9uYWwgfHwgZmFsc2U7CiAgICAgICAgICBpZihvYmoudmFsdWVbal0pIHsKICAgICAgICAgICAgcnZhbCA9IGFzbjEudmFsaWRhdGUob2JqLnZhbHVlW2pdLCB2LnZhbHVlW2ldLCBjYXB0dXJlLCBlcnJvcnMpOwogICAgICAgICAgICBpZihydmFsKSB7CiAgICAgICAgICAgICAgKytqOwogICAgICAgICAgICB9IGVsc2UgaWYodi52YWx1ZVtpXS5vcHRpb25hbCkgewogICAgICAgICAgICAgIHJ2YWwgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBpZighcnZhbCAmJiBlcnJvcnMpIHsKICAgICAgICAgICAgZXJyb3JzLnB1c2goCiAgICAgICAgICAgICAgJ1snICsgdi5uYW1lICsgJ10gJyArCiAgICAgICAgICAgICAgJ1RhZyBjbGFzcyAiJyArIHYudGFnQ2xhc3MgKyAnIiwgdHlwZSAiJyArCiAgICAgICAgICAgICAgdi50eXBlICsgJyIgZXhwZWN0ZWQgdmFsdWUgbGVuZ3RoICInICsKICAgICAgICAgICAgICB2LnZhbHVlLmxlbmd0aCArICciLCBnb3QgIicgKwogICAgICAgICAgICAgIG9iai52YWx1ZS5sZW5ndGggKyAnIicpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgaWYocnZhbCAmJiBjYXB0dXJlKSB7CiAgICAgICAgaWYodi5jYXB0dXJlKSB7CiAgICAgICAgICBjYXB0dXJlW3YuY2FwdHVyZV0gPSBvYmoudmFsdWU7CiAgICAgICAgfQogICAgICAgIGlmKHYuY2FwdHVyZUFzbjEpIHsKICAgICAgICAgIGNhcHR1cmVbdi5jYXB0dXJlQXNuMV0gPSBvYmo7CiAgICAgICAgfQogICAgICB9CiAgICB9IGVsc2UgaWYoZXJyb3JzKSB7CiAgICAgIGVycm9ycy5wdXNoKAogICAgICAgICdbJyArIHYubmFtZSArICddICcgKwogICAgICAgICdFeHBlY3RlZCBjb25zdHJ1Y3RlZCAiJyArIHYuY29uc3RydWN0ZWQgKyAnIiwgZ290ICInICsKICAgICAgICBvYmouY29uc3RydWN0ZWQgKyAnIicpOwogICAgfQogIH0gZWxzZSBpZihlcnJvcnMpIHsKICAgIGlmKG9iai50YWdDbGFzcyAhPT0gdi50YWdDbGFzcykgewogICAgICBlcnJvcnMucHVzaCgKICAgICAgICAnWycgKyB2Lm5hbWUgKyAnXSAnICsKICAgICAgICAnRXhwZWN0ZWQgdGFnIGNsYXNzICInICsgdi50YWdDbGFzcyArICciLCBnb3QgIicgKwogICAgICAgIG9iai50YWdDbGFzcyArICciJyk7CiAgICB9CiAgICBpZihvYmoudHlwZSAhPT0gdi50eXBlKSB7CiAgICAgIGVycm9ycy5wdXNoKAogICAgICAgICdbJyArIHYubmFtZSArICddICcgKwogICAgICAgICdFeHBlY3RlZCB0eXBlICInICsgdi50eXBlICsgJyIsIGdvdCAiJyArIG9iai50eXBlICsgJyInKTsKICAgIH0KICB9CiAgcmV0dXJuIHJ2YWw7Cn07CgovLyByZWdleCBmb3IgdGVzdGluZyBmb3Igbm9uLWxhdGluIGNoYXJhY3RlcnMKdmFyIF9ub25MYXRpblJlZ2V4ID0gL1teXFx1MDAwMC1cXHUwMGZmXS87CgovKioKICogUHJldHR5IHByaW50cyBhbiBBU04uMSBvYmplY3QgdG8gYSBzdHJpbmcuCiAqCiAqIEBwYXJhbSBvYmogdGhlIG9iamVjdCB0byB3cml0ZSBvdXQuCiAqIEBwYXJhbSBsZXZlbCB0aGUgbGV2ZWwgaW4gdGhlIHRyZWUuCiAqIEBwYXJhbSBpbmRlbnRhdGlvbiB0aGUgaW5kZW50YXRpb24gdG8gdXNlLgogKgogKiBAcmV0dXJuIHRoZSBzdHJpbmcuCiAqLwphc24xLnByZXR0eVByaW50ID0gZnVuY3Rpb24ob2JqLCBsZXZlbCwgaW5kZW50YXRpb24pIHsKICB2YXIgcnZhbCA9ICcnOwoKICAvLyBzZXQgZGVmYXVsdCBsZXZlbCBhbmQgaW5kZW50YXRpb24KICBsZXZlbCA9IGxldmVsIHx8IDA7CiAgaW5kZW50YXRpb24gPSBpbmRlbnRhdGlvbiB8fCAyOwoKICAvLyBzdGFydCBuZXcgbGluZSBmb3IgZGVlcCBsZXZlbHMKICBpZihsZXZlbCA+IDApIHsKICAgIHJ2YWwgKz0gJ1xuJzsKICB9CgogIC8vIGNyZWF0ZSBpbmRlbnQKICB2YXIgaW5kZW50ID0gJyc7CiAgZm9yKHZhciBpID0gMDsgaSA8IGxldmVsICogaW5kZW50YXRpb247ICsraSkgewogICAgaW5kZW50ICs9ICcgJzsKICB9CgogIC8vIHByaW50IGNsYXNzOnR5cGUKICBydmFsICs9IGluZGVudCArICdUYWc6ICc7CiAgc3dpdGNoKG9iai50YWdDbGFzcykgewogIGNhc2UgYXNuMS5DbGFzcy5VTklWRVJTQUw6CiAgICBydmFsICs9ICdVbml2ZXJzYWw6JzsKICAgIGJyZWFrOwogIGNhc2UgYXNuMS5DbGFzcy5BUFBMSUNBVElPTjoKICAgIHJ2YWwgKz0gJ0FwcGxpY2F0aW9uOic7CiAgICBicmVhazsKICBjYXNlIGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQzoKICAgIHJ2YWwgKz0gJ0NvbnRleHQtU3BlY2lmaWM6JzsKICAgIGJyZWFrOwogIGNhc2UgYXNuMS5DbGFzcy5QUklWQVRFOgogICAgcnZhbCArPSAnUHJpdmF0ZTonOwogICAgYnJlYWs7CiAgfQoKICBpZihvYmoudGFnQ2xhc3MgPT09IGFzbjEuQ2xhc3MuVU5JVkVSU0FMKSB7CiAgICBydmFsICs9IG9iai50eXBlOwoKICAgIC8vIGtub3duIHR5cGVzCiAgICBzd2l0Y2gob2JqLnR5cGUpIHsKICAgIGNhc2UgYXNuMS5UeXBlLk5PTkU6CiAgICAgIHJ2YWwgKz0gJyAoTm9uZSknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLkJPT0xFQU46CiAgICAgIHJ2YWwgKz0gJyAoQm9vbGVhbiknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLkJJVFNUUklORzoKICAgICAgcnZhbCArPSAnIChCaXQgc3RyaW5nKSc7CiAgICAgIGJyZWFrOwogICAgY2FzZSBhc24xLlR5cGUuSU5URUdFUjoKICAgICAgcnZhbCArPSAnIChJbnRlZ2VyKSc7CiAgICAgIGJyZWFrOwogICAgY2FzZSBhc24xLlR5cGUuT0NURVRTVFJJTkc6CiAgICAgIHJ2YWwgKz0gJyAoT2N0ZXQgc3RyaW5nKSc7CiAgICAgIGJyZWFrOwogICAgY2FzZSBhc24xLlR5cGUuTlVMTDoKICAgICAgcnZhbCArPSAnIChOdWxsKSc7CiAgICAgIGJyZWFrOwogICAgY2FzZSBhc24xLlR5cGUuT0lEOgogICAgICBydmFsICs9ICcgKE9iamVjdCBJZGVudGlmaWVyKSc7CiAgICAgIGJyZWFrOwogICAgY2FzZSBhc24xLlR5cGUuT0RFU0M6CiAgICAgIHJ2YWwgKz0gJyAoT2JqZWN0IERlc2NyaXB0b3IpJzsKICAgICAgYnJlYWs7CiAgICBjYXNlIGFzbjEuVHlwZS5FWFRFUk5BTDoKICAgICAgcnZhbCArPSAnIChFeHRlcm5hbCBvciBJbnN0YW5jZSBvZiknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLlJFQUw6CiAgICAgIHJ2YWwgKz0gJyAoUmVhbCknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLkVOVU1FUkFURUQ6CiAgICAgIHJ2YWwgKz0gJyAoRW51bWVyYXRlZCknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLkVNQkVEREVEOgogICAgICBydmFsICs9ICcgKEVtYmVkZGVkIFBEViknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLlVURjg6CiAgICAgIHJ2YWwgKz0gJyAoVVRGOCknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLlJPSUQ6CiAgICAgIHJ2YWwgKz0gJyAoUmVsYXRpdmUgT2JqZWN0IElkZW50aWZpZXIpJzsKICAgICAgYnJlYWs7CiAgICBjYXNlIGFzbjEuVHlwZS5TRVFVRU5DRToKICAgICAgcnZhbCArPSAnIChTZXF1ZW5jZSknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLlNFVDoKICAgICAgcnZhbCArPSAnIChTZXQpJzsKICAgICAgYnJlYWs7CiAgICBjYXNlIGFzbjEuVHlwZS5QUklOVEFCTEVTVFJJTkc6CiAgICAgIHJ2YWwgKz0gJyAoUHJpbnRhYmxlIFN0cmluZyknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLklBNVN0cmluZzoKICAgICAgcnZhbCArPSAnIChJQTVTdHJpbmcgKEFTQ0lJKSknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLlVUQ1RJTUU6CiAgICAgIHJ2YWwgKz0gJyAoVVRDIHRpbWUpJzsKICAgICAgYnJlYWs7CiAgICBjYXNlIGFzbjEuVHlwZS5HRU5FUkFMSVpFRFRJTUU6CiAgICAgIHJ2YWwgKz0gJyAoR2VuZXJhbGl6ZWQgdGltZSknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLkJNUFNUUklORzoKICAgICAgcnZhbCArPSAnIChCTVAgU3RyaW5nKSc7CiAgICAgIGJyZWFrOwogICAgfQogIH0gZWxzZSB7CiAgICBydmFsICs9IG9iai50eXBlOwogIH0KCiAgcnZhbCArPSAnXG4nOwogIHJ2YWwgKz0gaW5kZW50ICsgJ0NvbnN0cnVjdGVkOiAnICsgb2JqLmNvbnN0cnVjdGVkICsgJ1xuJzsKCiAgaWYob2JqLmNvbXBvc2VkKSB7CiAgICB2YXIgc3VidmFsdWVzID0gMDsKICAgIHZhciBzdWIgPSAnJzsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBvYmoudmFsdWUubGVuZ3RoOyArK2kpIHsKICAgICAgaWYob2JqLnZhbHVlW2ldICE9PSB1bmRlZmluZWQpIHsKICAgICAgICBzdWJ2YWx1ZXMgKz0gMTsKICAgICAgICBzdWIgKz0gYXNuMS5wcmV0dHlQcmludChvYmoudmFsdWVbaV0sIGxldmVsICsgMSwgaW5kZW50YXRpb24pOwogICAgICAgIGlmKChpICsgMSkgPCBvYmoudmFsdWUubGVuZ3RoKSB7CiAgICAgICAgICBzdWIgKz0gJywnOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcnZhbCArPSBpbmRlbnQgKyAnU3ViIHZhbHVlczogJyArIHN1YnZhbHVlcyArIHN1YjsKICB9IGVsc2UgewogICAgcnZhbCArPSBpbmRlbnQgKyAnVmFsdWU6ICc7CiAgICBpZihvYmoudHlwZSA9PT0gYXNuMS5UeXBlLk9JRCkgewogICAgICB2YXIgb2lkID0gYXNuMS5kZXJUb09pZChvYmoudmFsdWUpOwogICAgICBydmFsICs9IG9pZDsKICAgICAgaWYoZm9yZ2UucGtpICYmIGZvcmdlLnBraS5vaWRzKSB7CiAgICAgICAgaWYob2lkIGluIGZvcmdlLnBraS5vaWRzKSB7CiAgICAgICAgICBydmFsICs9ICcgKCcgKyBmb3JnZS5wa2kub2lkc1tvaWRdICsgJykgJzsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGlmKG9iai50eXBlID09PSBhc24xLlR5cGUuSU5URUdFUikgewogICAgICB0cnkgewogICAgICAgIHJ2YWwgKz0gYXNuMS5kZXJUb0ludGVnZXIob2JqLnZhbHVlKTsKICAgICAgfSBjYXRjaChleCkgewogICAgICAgIHJ2YWwgKz0gJzB4JyArIGZvcmdlLnV0aWwuYnl0ZXNUb0hleChvYmoudmFsdWUpOwogICAgICB9CiAgICB9IGVsc2UgaWYob2JqLnR5cGUgPT09IGFzbjEuVHlwZS5PQ1RFVFNUUklORykgewogICAgICBpZighX25vbkxhdGluUmVnZXgudGVzdChvYmoudmFsdWUpKSB7CiAgICAgICAgcnZhbCArPSAnKCcgKyBvYmoudmFsdWUgKyAnKSAnOwogICAgICB9CiAgICAgIHJ2YWwgKz0gJzB4JyArIGZvcmdlLnV0aWwuYnl0ZXNUb0hleChvYmoudmFsdWUpOwogICAgfSBlbHNlIGlmKG9iai50eXBlID09PSBhc24xLlR5cGUuVVRGOCkgewogICAgICBydmFsICs9IGZvcmdlLnV0aWwuZGVjb2RlVXRmOChvYmoudmFsdWUpOwogICAgfSBlbHNlIGlmKG9iai50eXBlID09PSBhc24xLlR5cGUuUFJJTlRBQkxFU1RSSU5HIHx8CiAgICAgIG9iai50eXBlID09PSBhc24xLlR5cGUuSUE1U3RyaW5nKSB7CiAgICAgIHJ2YWwgKz0gb2JqLnZhbHVlOwogICAgfSBlbHNlIGlmKF9ub25MYXRpblJlZ2V4LnRlc3Qob2JqLnZhbHVlKSkgewogICAgICBydmFsICs9ICcweCcgKyBmb3JnZS51dGlsLmJ5dGVzVG9IZXgob2JqLnZhbHVlKTsKICAgIH0gZWxzZSBpZihvYmoudmFsdWUubGVuZ3RoID09PSAwKSB7CiAgICAgIHJ2YWwgKz0gJ1tudWxsXSc7CiAgICB9IGVsc2UgewogICAgICBydmFsICs9IG9iai52YWx1ZTsKICAgIH0KICB9CgogIHJldHVybiBydmFsOwp9OwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAnYXNuMSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9hc24xJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCcsICcuL29pZHMnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogTWVzc2FnZSBEaWdlc3QgQWxnb3JpdGhtIDUgd2l0aCAxMjgtYml0IGRpZ2VzdCAoTUQ1KSBpbXBsZW1lbnRhdGlvbi4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7Cgp2YXIgbWQ1ID0gZm9yZ2UubWQ1ID0gZm9yZ2UubWQ1IHx8IHt9Owpmb3JnZS5tZCA9IGZvcmdlLm1kIHx8IHt9Owpmb3JnZS5tZC5hbGdvcml0aG1zID0gZm9yZ2UubWQuYWxnb3JpdGhtcyB8fCB7fTsKZm9yZ2UubWQubWQ1ID0gZm9yZ2UubWQuYWxnb3JpdGhtcy5tZDUgPSBtZDU7CgovKioKICogQ3JlYXRlcyBhbiBNRDUgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0LgogKgogKiBAcmV0dXJuIGEgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0LgogKi8KbWQ1LmNyZWF0ZSA9IGZ1bmN0aW9uKCkgewogIC8vIGRvIGluaXRpYWxpemF0aW9uIGFzIG5lY2Vzc2FyeQogIGlmKCFfaW5pdGlhbGl6ZWQpIHsKICAgIF9pbml0KCk7CiAgfQoKICAvLyBNRDUgc3RhdGUgY29udGFpbnMgZm91ciAzMi1iaXQgaW50ZWdlcnMKICB2YXIgX3N0YXRlID0gbnVsbDsKCiAgLy8gaW5wdXQgYnVmZmVyCiAgdmFyIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIHVzZWQgZm9yIHdvcmQgc3RvcmFnZQogIHZhciBfdyA9IG5ldyBBcnJheSgxNik7CgogIC8vIG1lc3NhZ2UgZGlnZXN0IG9iamVjdAogIHZhciBtZCA9IHsKICAgIGFsZ29yaXRobTogJ21kNScsCiAgICBibG9ja0xlbmd0aDogNjQsCiAgICBkaWdlc3RMZW5ndGg6IDE2LAogICAgLy8gNTYtYml0IGxlbmd0aCBvZiBtZXNzYWdlIHNvIGZhciAoZG9lcyBub3QgaW5jbHVkaW5nIHBhZGRpbmcpCiAgICBtZXNzYWdlTGVuZ3RoOiAwLAogICAgLy8gdHJ1ZSBtZXNzYWdlIGxlbmd0aAogICAgZnVsbE1lc3NhZ2VMZW5ndGg6IG51bGwsCiAgICAvLyBzaXplIG9mIG1lc3NhZ2UgbGVuZ3RoIGluIGJ5dGVzCiAgICBtZXNzYWdlTGVuZ3RoU2l6ZTogOAogIH07CgogIC8qKgogICAqIFN0YXJ0cyB0aGUgZGlnZXN0LgogICAqCiAgICogQHJldHVybiB0aGlzIGRpZ2VzdCBvYmplY3QuCiAgICovCiAgbWQuc3RhcnQgPSBmdW5jdGlvbigpIHsKICAgIC8vIHVwIHRvIDU2LWJpdCBtZXNzYWdlIGxlbmd0aCBmb3IgY29udmVuaWVuY2UKICAgIG1kLm1lc3NhZ2VMZW5ndGggPSAwOwoKICAgIC8vIGZ1bGwgbWVzc2FnZSBsZW5ndGggKHNldCBtZC5tZXNzYWdlTGVuZ3RoNjQgZm9yIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5KQogICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGggPSBtZC5tZXNzYWdlTGVuZ3RoNjQgPSBbXTsKICAgIHZhciBpbnQzMnMgPSBtZC5tZXNzYWdlTGVuZ3RoU2l6ZSAvIDQ7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgaW50MzJzOyArK2kpIHsKICAgICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGgucHVzaCgwKTsKICAgIH0KICAgIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBfc3RhdGUgPSB7CiAgICAgIGgwOiAweDY3NDUyMzAxLAogICAgICBoMTogMHhFRkNEQUI4OSwKICAgICAgaDI6IDB4OThCQURDRkUsCiAgICAgIGgzOiAweDEwMzI1NDc2CiAgICB9OwogICAgcmV0dXJuIG1kOwogIH07CiAgLy8gc3RhcnQgZGlnZXN0IGF1dG9tYXRpY2FsbHkgZm9yIGZpcnN0IHRpbWUKICBtZC5zdGFydCgpOwoKICAvKioKICAgKiBVcGRhdGVzIHRoZSBkaWdlc3Qgd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZSBpbnB1dC4gVGhlIGdpdmVuIGlucHV0IGNhbgogICAqIHRyZWF0ZWQgYXMgcmF3IGlucHV0IChubyBlbmNvZGluZyB3aWxsIGJlIGFwcGxpZWQpIG9yIGFuIGVuY29kaW5nIG9mCiAgICogJ3V0ZjgnIG1heWJlIGdpdmVuIHRvIGVuY29kZSB0aGUgaW5wdXQgdXNpbmcgVVRGLTguCiAgICoKICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlIGlucHV0IHRvIHVwZGF0ZSB3aXRoLgogICAqIEBwYXJhbSBlbmNvZGluZyB0aGUgZW5jb2RpbmcgdG8gdXNlIChkZWZhdWx0OiAncmF3Jywgb3RoZXI6ICd1dGY4JykuCiAgICoKICAgKiBAcmV0dXJuIHRoaXMgZGlnZXN0IG9iamVjdC4KICAgKi8KICBtZC51cGRhdGUgPSBmdW5jdGlvbihtc2csIGVuY29kaW5nKSB7CiAgICBpZihlbmNvZGluZyA9PT0gJ3V0ZjgnKSB7CiAgICAgIG1zZyA9IGZvcmdlLnV0aWwuZW5jb2RlVXRmOChtc2cpOwogICAgfQoKICAgIC8vIHVwZGF0ZSBtZXNzYWdlIGxlbmd0aAogICAgdmFyIGxlbiA9IG1zZy5sZW5ndGg7CiAgICBtZC5tZXNzYWdlTGVuZ3RoICs9IGxlbjsKICAgIGxlbiA9IFsobGVuIC8gMHgxMDAwMDAwMDApID4+PiAwLCBsZW4gPj4+IDBdOwogICAgZm9yKHZhciBpID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGgubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHsKICAgICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gKz0gbGVuWzFdOwogICAgICBsZW5bMV0gPSBsZW5bMF0gKyAoKG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldIC8gMHgxMDAwMDAwMDApID4+PiAwKTsKICAgICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gPSBtZC5mdWxsTWVzc2FnZUxlbmd0aFtpXSA+Pj4gMDsKICAgICAgbGVuWzBdID0gKChsZW5bMV0gLyAweDEwMDAwMDAwMCkgPj4+IDApOwogICAgfQoKICAgIC8vIGFkZCBieXRlcyB0byBpbnB1dCBidWZmZXIKICAgIF9pbnB1dC5wdXRCeXRlcyhtc2cpOwoKICAgIC8vIHByb2Nlc3MgYnl0ZXMKICAgIF91cGRhdGUoX3N0YXRlLCBfdywgX2lucHV0KTsKCiAgICAvLyBjb21wYWN0IGlucHV0IGJ1ZmZlciBldmVyeSAySyBvciBpZiBlbXB0eQogICAgaWYoX2lucHV0LnJlYWQgPiAyMDQ4IHx8IF9pbnB1dC5sZW5ndGgoKSA9PT0gMCkgewogICAgICBfaW5wdXQuY29tcGFjdCgpOwogICAgfQoKICAgIHJldHVybiBtZDsKICB9OwoKICAvKioKICAgKiBQcm9kdWNlcyB0aGUgZGlnZXN0LgogICAqCiAgICogQHJldHVybiBhIGJ5dGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIGRpZ2VzdCB2YWx1ZS4KICAgKi8KICBtZC5kaWdlc3QgPSBmdW5jdGlvbigpIHsKICAgIC8qIE5vdGU6IEhlcmUgd2UgY29weSB0aGUgcmVtYWluaW5nIGJ5dGVzIGluIHRoZSBpbnB1dCBidWZmZXIgYW5kCiAgICBhZGQgdGhlIGFwcHJvcHJpYXRlIE1ENSBwYWRkaW5nLiBUaGVuIHdlIGRvIHRoZSBmaW5hbCB1cGRhdGUKICAgIG9uIGEgY29weSBvZiB0aGUgc3RhdGUgc28gdGhhdCBpZiB0aGUgdXNlciB3YW50cyB0byBnZXQKICAgIGludGVybWVkaWF0ZSBkaWdlc3RzIHRoZXkgY2FuIGRvIHNvLiAqLwoKICAgIC8qIERldGVybWluZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgbXVzdCBiZSBhZGRlZCB0byB0aGUgbWVzc2FnZQogICAgdG8gZW5zdXJlIGl0cyBsZW5ndGggaXMgY29uZ3J1ZW50IHRvIDQ0OCBtb2QgNTEyLiBJbiBvdGhlciB3b3JkcywKICAgIHRoZSBkYXRhIHRvIGJlIGRpZ2VzdGVkIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA1MTIgYml0cyAob3IgMTI4IGJ5dGVzKS4KICAgIFRoaXMgZGF0YSBpbmNsdWRlcyB0aGUgbWVzc2FnZSwgc29tZSBwYWRkaW5nLCBhbmQgdGhlIGxlbmd0aCBvZiB0aGUKICAgIG1lc3NhZ2UuIFNpbmNlIHRoZSBsZW5ndGggb2YgdGhlIG1lc3NhZ2Ugd2lsbCBiZSBlbmNvZGVkIGFzIDggYnl0ZXMgKDY0CiAgICBiaXRzKSwgdGhhdCBtZWFucyB0aGF0IHRoZSBsYXN0IHNlZ21lbnQgb2YgdGhlIGRhdGEgbXVzdCBoYXZlIDU2IGJ5dGVzCiAgICAoNDQ4IGJpdHMpIG9mIG1lc3NhZ2UgYW5kIHBhZGRpbmcuIFRoZXJlZm9yZSwgdGhlIGxlbmd0aCBvZiB0aGUgbWVzc2FnZQogICAgcGx1cyB0aGUgcGFkZGluZyBtdXN0IGJlIGNvbmdydWVudCB0byA0NDggbW9kIDUxMiBiZWNhdXNlCiAgICA1MTIgLSAxMjggPSA0NDguCgogICAgSW4gb3JkZXIgdG8gZmlsbCB1cCB0aGUgbWVzc2FnZSBsZW5ndGggaXQgbXVzdCBiZSBmaWxsZWQgd2l0aAogICAgcGFkZGluZyB0aGF0IGJlZ2lucyB3aXRoIDEgYml0IGZvbGxvd2VkIGJ5IGFsbCAwIGJpdHMuIFBhZGRpbmcKICAgIG11c3QgKmFsd2F5cyogYmUgcHJlc2VudCwgc28gaWYgdGhlIG1lc3NhZ2UgbGVuZ3RoIGlzIGFscmVhZHkKICAgIGNvbmdydWVudCB0byA0NDggbW9kIDUxMiwgdGhlbiA1MTIgcGFkZGluZyBiaXRzIG11c3QgYmUgYWRkZWQuICovCgogICAgdmFyIGZpbmFsQmxvY2sgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgZmluYWxCbG9jay5wdXRCeXRlcyhfaW5wdXQuYnl0ZXMoKSk7CgogICAgLy8gY29tcHV0ZSByZW1haW5pbmcgc2l6ZSB0byBiZSBkaWdlc3RlZCAoaW5jbHVkZSBtZXNzYWdlIGxlbmd0aCBzaXplKQogICAgdmFyIHJlbWFpbmluZyA9ICgKICAgICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGhbbWQuZnVsbE1lc3NhZ2VMZW5ndGgubGVuZ3RoIC0gMV0gKwogICAgICBtZC5tZXNzYWdlTGVuZ3RoU2l6ZSk7CgogICAgLy8gYWRkIHBhZGRpbmcgZm9yIG92ZXJmbG93IGJsb2NrU2l6ZSAtIG92ZXJmbG93CiAgICAvLyBfcGFkZGluZyBzdGFydHMgd2l0aCAxIGJ5dGUgd2l0aCBmaXJzdCBiaXQgaXMgc2V0IChieXRlIHZhbHVlIDEyOCksIHRoZW4KICAgIC8vIHRoZXJlIG1heSBiZSB1cCB0byAoYmxvY2tTaXplIC0gMSkgb3RoZXIgcGFkIGJ5dGVzCiAgICB2YXIgb3ZlcmZsb3cgPSByZW1haW5pbmcgJiAobWQuYmxvY2tMZW5ndGggLSAxKTsKICAgIGZpbmFsQmxvY2sucHV0Qnl0ZXMoX3BhZGRpbmcuc3Vic3RyKDAsIG1kLmJsb2NrTGVuZ3RoIC0gb3ZlcmZsb3cpKTsKCiAgICAvLyBzZXJpYWxpemUgbWVzc2FnZSBsZW5ndGggaW4gYml0cyBpbiBsaXR0bGUtZW5kaWFuIG9yZGVyOyBzaW5jZSBsZW5ndGgKICAgIC8vIGlzIHN0b3JlZCBpbiBieXRlcyB3ZSBtdWx0aXBseSBieSA4IGFuZCBhZGQgY2FycnkKICAgIHZhciBiaXRzLCBjYXJyeSA9IDA7CiAgICBmb3IodmFyIGkgPSBtZC5mdWxsTWVzc2FnZUxlbmd0aC5sZW5ndGggLSAxOyBpID49IDA7IC0taSkgewogICAgICBiaXRzID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gKiA4ICsgY2Fycnk7CiAgICAgIGNhcnJ5ID0gKGJpdHMgLyAweDEwMDAwMDAwMCkgPj4+IDA7CiAgICAgIGZpbmFsQmxvY2sucHV0SW50MzJMZShiaXRzID4+PiAwKTsKICAgIH0KCiAgICB2YXIgczIgPSB7CiAgICAgIGgwOiBfc3RhdGUuaDAsCiAgICAgIGgxOiBfc3RhdGUuaDEsCiAgICAgIGgyOiBfc3RhdGUuaDIsCiAgICAgIGgzOiBfc3RhdGUuaDMKICAgIH07CiAgICBfdXBkYXRlKHMyLCBfdywgZmluYWxCbG9jayk7CiAgICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBydmFsLnB1dEludDMyTGUoczIuaDApOwogICAgcnZhbC5wdXRJbnQzMkxlKHMyLmgxKTsKICAgIHJ2YWwucHV0SW50MzJMZShzMi5oMik7CiAgICBydmFsLnB1dEludDMyTGUoczIuaDMpOwogICAgcmV0dXJuIHJ2YWw7CiAgfTsKCiAgcmV0dXJuIG1kOwp9OwoKLy8gcGFkZGluZywgY29uc3RhbnQgdGFibGVzIGZvciBjYWxjdWxhdGluZyBtZDUKdmFyIF9wYWRkaW5nID0gbnVsbDsKdmFyIF9nID0gbnVsbDsKdmFyIF9yID0gbnVsbDsKdmFyIF9rID0gbnVsbDsKdmFyIF9pbml0aWFsaXplZCA9IGZhbHNlOwoKLyoqCiAqIEluaXRpYWxpemVzIHRoZSBjb25zdGFudCB0YWJsZXMuCiAqLwpmdW5jdGlvbiBfaW5pdCgpIHsKICAvLyBjcmVhdGUgcGFkZGluZwogIF9wYWRkaW5nID0gU3RyaW5nLmZyb21DaGFyQ29kZSgxMjgpOwogIF9wYWRkaW5nICs9IGZvcmdlLnV0aWwuZmlsbFN0cmluZyhTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDApLCA2NCk7CgogIC8vIGcgdmFsdWVzCiAgX2cgPSBbCiAgICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAogICAgMSwgNiwgMTEsIDAsIDUsIDEwLCAxNSwgNCwgOSwgMTQsIDMsIDgsIDEzLCAyLCA3LCAxMiwKICAgIDUsIDgsIDExLCAxNCwgMSwgNCwgNywgMTAsIDEzLCAwLCAzLCA2LCA5LCAxMiwgMTUsIDIsCiAgICAwLCA3LCAxNCwgNSwgMTIsIDMsIDEwLCAxLCA4LCAxNSwgNiwgMTMsIDQsIDExLCAyLCA5XTsKCiAgLy8gcm91bmRzIHRhYmxlCiAgX3IgPSBbCiAgICA3LCAxMiwgMTcsIDIyLCAgNywgMTIsIDE3LCAyMiwgIDcsIDEyLCAxNywgMjIsICA3LCAxMiwgMTcsIDIyLAogICAgNSwgIDksIDE0LCAyMCwgIDUsICA5LCAxNCwgMjAsICA1LCAgOSwgMTQsIDIwLCAgNSwgIDksIDE0LCAyMCwKICAgIDQsIDExLCAxNiwgMjMsICA0LCAxMSwgMTYsIDIzLCAgNCwgMTEsIDE2LCAyMywgIDQsIDExLCAxNiwgMjMsCiAgICA2LCAxMCwgMTUsIDIxLCAgNiwgMTAsIDE1LCAyMSwgIDYsIDEwLCAxNSwgMjEsICA2LCAxMCwgMTUsIDIxXTsKCiAgLy8gZ2V0IHRoZSByZXN1bHQgb2YgYWJzKHNpbihpICsgMSkpIGFzIGEgMzItYml0IGludGVnZXIKICBfayA9IG5ldyBBcnJheSg2NCk7CiAgZm9yKHZhciBpID0gMDsgaSA8IDY0OyArK2kpIHsKICAgIF9rW2ldID0gTWF0aC5mbG9vcihNYXRoLmFicyhNYXRoLnNpbihpICsgMSkpICogMHgxMDAwMDAwMDApOwogIH0KCiAgLy8gbm93IGluaXRpYWxpemVkCiAgX2luaXRpYWxpemVkID0gdHJ1ZTsKfQoKLyoqCiAqIFVwZGF0ZXMgYW4gTUQ1IHN0YXRlIHdpdGggdGhlIGdpdmVuIGJ5dGUgYnVmZmVyLgogKgogKiBAcGFyYW0gcyB0aGUgTUQ1IHN0YXRlIHRvIHVwZGF0ZS4KICogQHBhcmFtIHcgdGhlIGFycmF5IHRvIHVzZSB0byBzdG9yZSB3b3Jkcy4KICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlIGJ1ZmZlciB0byB1cGRhdGUgd2l0aC4KICovCmZ1bmN0aW9uIF91cGRhdGUocywgdywgYnl0ZXMpIHsKICAvLyBjb25zdW1lIDUxMiBiaXQgKDY0IGJ5dGUpIGNodW5rcwogIHZhciB0LCBhLCBiLCBjLCBkLCBmLCByLCBpOwogIHZhciBsZW4gPSBieXRlcy5sZW5ndGgoKTsKICB3aGlsZShsZW4gPj0gNjQpIHsKICAgIC8vIGluaXRpYWxpemUgaGFzaCB2YWx1ZSBmb3IgdGhpcyBjaHVuawogICAgYSA9IHMuaDA7CiAgICBiID0gcy5oMTsKICAgIGMgPSBzLmgyOwogICAgZCA9IHMuaDM7CgogICAgLy8gcm91bmQgMQogICAgZm9yKGkgPSAwOyBpIDwgMTY7ICsraSkgewogICAgICB3W2ldID0gYnl0ZXMuZ2V0SW50MzJMZSgpOwogICAgICBmID0gZCBeIChiICYgKGMgXiBkKSk7CiAgICAgIHQgPSAoYSArIGYgKyBfa1tpXSArIHdbaV0pOwogICAgICByID0gX3JbaV07CiAgICAgIGEgPSBkOwogICAgICBkID0gYzsKICAgICAgYyA9IGI7CiAgICAgIGIgKz0gKHQgPDwgcikgfCAodCA+Pj4gKDMyIC0gcikpOwogICAgfQogICAgLy8gcm91bmQgMgogICAgZm9yKDsgaSA8IDMyOyArK2kpIHsKICAgICAgZiA9IGMgXiAoZCAmIChiIF4gYykpOwogICAgICB0ID0gKGEgKyBmICsgX2tbaV0gKyB3W19nW2ldXSk7CiAgICAgIHIgPSBfcltpXTsKICAgICAgYSA9IGQ7CiAgICAgIGQgPSBjOwogICAgICBjID0gYjsKICAgICAgYiArPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7CiAgICB9CiAgICAvLyByb3VuZCAzCiAgICBmb3IoOyBpIDwgNDg7ICsraSkgewogICAgICBmID0gYiBeIGMgXiBkOwogICAgICB0ID0gKGEgKyBmICsgX2tbaV0gKyB3W19nW2ldXSk7CiAgICAgIHIgPSBfcltpXTsKICAgICAgYSA9IGQ7CiAgICAgIGQgPSBjOwogICAgICBjID0gYjsKICAgICAgYiArPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7CiAgICB9CiAgICAvLyByb3VuZCA0CiAgICBmb3IoOyBpIDwgNjQ7ICsraSkgewogICAgICBmID0gYyBeIChiIHwgfmQpOwogICAgICB0ID0gKGEgKyBmICsgX2tbaV0gKyB3W19nW2ldXSk7CiAgICAgIHIgPSBfcltpXTsKICAgICAgYSA9IGQ7CiAgICAgIGQgPSBjOwogICAgICBjID0gYjsKICAgICAgYiArPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7CiAgICB9CgogICAgLy8gdXBkYXRlIGhhc2ggc3RhdGUKICAgIHMuaDAgPSAocy5oMCArIGEpIHwgMDsKICAgIHMuaDEgPSAocy5oMSArIGIpIHwgMDsKICAgIHMuaDIgPSAocy5oMiArIGMpIHwgMDsKICAgIHMuaDMgPSAocy5oMyArIGQpIHwgMDsKCiAgICBsZW4gLT0gNjQ7CiAgfQp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdtZDUnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvbWQ1JyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBTZWN1cmUgSGFzaCBBbGdvcml0aG0gd2l0aCAxNjAtYml0IGRpZ2VzdCAoU0hBLTEpIGltcGxlbWVudGF0aW9uLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNSBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCnZhciBzaGExID0gZm9yZ2Uuc2hhMSA9IGZvcmdlLnNoYTEgfHwge307CmZvcmdlLm1kID0gZm9yZ2UubWQgfHwge307CmZvcmdlLm1kLmFsZ29yaXRobXMgPSBmb3JnZS5tZC5hbGdvcml0aG1zIHx8IHt9Owpmb3JnZS5tZC5zaGExID0gZm9yZ2UubWQuYWxnb3JpdGhtcy5zaGExID0gc2hhMTsKCi8qKgogKiBDcmVhdGVzIGEgU0hBLTEgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0LgogKgogKiBAcmV0dXJuIGEgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0LgogKi8Kc2hhMS5jcmVhdGUgPSBmdW5jdGlvbigpIHsKICAvLyBkbyBpbml0aWFsaXphdGlvbiBhcyBuZWNlc3NhcnkKICBpZighX2luaXRpYWxpemVkKSB7CiAgICBfaW5pdCgpOwogIH0KCiAgLy8gU0hBLTEgc3RhdGUgY29udGFpbnMgZml2ZSAzMi1iaXQgaW50ZWdlcnMKICB2YXIgX3N0YXRlID0gbnVsbDsKCiAgLy8gaW5wdXQgYnVmZmVyCiAgdmFyIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIHVzZWQgZm9yIHdvcmQgc3RvcmFnZQogIHZhciBfdyA9IG5ldyBBcnJheSg4MCk7CgogIC8vIG1lc3NhZ2UgZGlnZXN0IG9iamVjdAogIHZhciBtZCA9IHsKICAgIGFsZ29yaXRobTogJ3NoYTEnLAogICAgYmxvY2tMZW5ndGg6IDY0LAogICAgZGlnZXN0TGVuZ3RoOiAyMCwKICAgIC8vIDU2LWJpdCBsZW5ndGggb2YgbWVzc2FnZSBzbyBmYXIgKGRvZXMgbm90IGluY2x1ZGluZyBwYWRkaW5nKQogICAgbWVzc2FnZUxlbmd0aDogMCwKICAgIC8vIHRydWUgbWVzc2FnZSBsZW5ndGgKICAgIGZ1bGxNZXNzYWdlTGVuZ3RoOiBudWxsLAogICAgLy8gc2l6ZSBvZiBtZXNzYWdlIGxlbmd0aCBpbiBieXRlcwogICAgbWVzc2FnZUxlbmd0aFNpemU6IDgKICB9OwoKICAvKioKICAgKiBTdGFydHMgdGhlIGRpZ2VzdC4KICAgKgogICAqIEByZXR1cm4gdGhpcyBkaWdlc3Qgb2JqZWN0LgogICAqLwogIG1kLnN0YXJ0ID0gZnVuY3Rpb24oKSB7CiAgICAvLyB1cCB0byA1Ni1iaXQgbWVzc2FnZSBsZW5ndGggZm9yIGNvbnZlbmllbmNlCiAgICBtZC5tZXNzYWdlTGVuZ3RoID0gMDsKCiAgICAvLyBmdWxsIG1lc3NhZ2UgbGVuZ3RoIChzZXQgbWQubWVzc2FnZUxlbmd0aDY0IGZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eSkKICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoID0gbWQubWVzc2FnZUxlbmd0aDY0ID0gW107CiAgICB2YXIgaW50MzJzID0gbWQubWVzc2FnZUxlbmd0aFNpemUgLyA0OwogICAgZm9yKHZhciBpID0gMDsgaSA8IGludDMyczsgKytpKSB7CiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoLnB1c2goMCk7CiAgICB9CiAgICBfaW5wdXQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgX3N0YXRlID0gewogICAgICBoMDogMHg2NzQ1MjMwMSwKICAgICAgaDE6IDB4RUZDREFCODksCiAgICAgIGgyOiAweDk4QkFEQ0ZFLAogICAgICBoMzogMHgxMDMyNTQ3NiwKICAgICAgaDQ6IDB4QzNEMkUxRjAKICAgIH07CiAgICByZXR1cm4gbWQ7CiAgfTsKICAvLyBzdGFydCBkaWdlc3QgYXV0b21hdGljYWxseSBmb3IgZmlyc3QgdGltZQogIG1kLnN0YXJ0KCk7CgogIC8qKgogICAqIFVwZGF0ZXMgdGhlIGRpZ2VzdCB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlIGlucHV0LiBUaGUgZ2l2ZW4gaW5wdXQgY2FuCiAgICogdHJlYXRlZCBhcyByYXcgaW5wdXQgKG5vIGVuY29kaW5nIHdpbGwgYmUgYXBwbGllZCkgb3IgYW4gZW5jb2Rpbmcgb2YKICAgKiAndXRmOCcgbWF5YmUgZ2l2ZW4gdG8gZW5jb2RlIHRoZSBpbnB1dCB1c2luZyBVVEYtOC4KICAgKgogICAqIEBwYXJhbSBtc2cgdGhlIG1lc3NhZ2UgaW5wdXQgdG8gdXBkYXRlIHdpdGguCiAgICogQHBhcmFtIGVuY29kaW5nIHRoZSBlbmNvZGluZyB0byB1c2UgKGRlZmF1bHQ6ICdyYXcnLCBvdGhlcjogJ3V0ZjgnKS4KICAgKgogICAqIEByZXR1cm4gdGhpcyBkaWdlc3Qgb2JqZWN0LgogICAqLwogIG1kLnVwZGF0ZSA9IGZ1bmN0aW9uKG1zZywgZW5jb2RpbmcpIHsKICAgIGlmKGVuY29kaW5nID09PSAndXRmOCcpIHsKICAgICAgbXNnID0gZm9yZ2UudXRpbC5lbmNvZGVVdGY4KG1zZyk7CiAgICB9CgogICAgLy8gdXBkYXRlIG1lc3NhZ2UgbGVuZ3RoCiAgICB2YXIgbGVuID0gbXNnLmxlbmd0aDsKICAgIG1kLm1lc3NhZ2VMZW5ndGggKz0gbGVuOwogICAgbGVuID0gWyhsZW4gLyAweDEwMDAwMDAwMCkgPj4+IDAsIGxlbiA+Pj4gMF07CiAgICBmb3IodmFyIGkgPSBtZC5mdWxsTWVzc2FnZUxlbmd0aC5sZW5ndGggLSAxOyBpID49IDA7IC0taSkgewogICAgICBtZC5mdWxsTWVzc2FnZUxlbmd0aFtpXSArPSBsZW5bMV07CiAgICAgIGxlblsxXSA9IGxlblswXSArICgobWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gLyAweDEwMDAwMDAwMCkgPj4+IDApOwogICAgICBtZC5mdWxsTWVzc2FnZUxlbmd0aFtpXSA9IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldID4+PiAwOwogICAgICBsZW5bMF0gPSAoKGxlblsxXSAvIDB4MTAwMDAwMDAwKSA+Pj4gMCk7CiAgICB9CgogICAgLy8gYWRkIGJ5dGVzIHRvIGlucHV0IGJ1ZmZlcgogICAgX2lucHV0LnB1dEJ5dGVzKG1zZyk7CgogICAgLy8gcHJvY2VzcyBieXRlcwogICAgX3VwZGF0ZShfc3RhdGUsIF93LCBfaW5wdXQpOwoKICAgIC8vIGNvbXBhY3QgaW5wdXQgYnVmZmVyIGV2ZXJ5IDJLIG9yIGlmIGVtcHR5CiAgICBpZihfaW5wdXQucmVhZCA+IDIwNDggfHwgX2lucHV0Lmxlbmd0aCgpID09PSAwKSB7CiAgICAgIF9pbnB1dC5jb21wYWN0KCk7CiAgICB9CgogICAgcmV0dXJuIG1kOwogIH07CgogICAvKioKICAgICogUHJvZHVjZXMgdGhlIGRpZ2VzdC4KICAgICoKICAgICogQHJldHVybiBhIGJ5dGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIGRpZ2VzdCB2YWx1ZS4KICAgICovCiAgIG1kLmRpZ2VzdCA9IGZ1bmN0aW9uKCkgewogICAgLyogTm90ZTogSGVyZSB3ZSBjb3B5IHRoZSByZW1haW5pbmcgYnl0ZXMgaW4gdGhlIGlucHV0IGJ1ZmZlciBhbmQKICAgIGFkZCB0aGUgYXBwcm9wcmlhdGUgU0hBLTEgcGFkZGluZy4gVGhlbiB3ZSBkbyB0aGUgZmluYWwgdXBkYXRlCiAgICBvbiBhIGNvcHkgb2YgdGhlIHN0YXRlIHNvIHRoYXQgaWYgdGhlIHVzZXIgd2FudHMgdG8gZ2V0CiAgICBpbnRlcm1lZGlhdGUgZGlnZXN0cyB0aGV5IGNhbiBkbyBzby4gKi8KCiAgICAvKiBEZXRlcm1pbmUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IG11c3QgYmUgYWRkZWQgdG8gdGhlIG1lc3NhZ2UKICAgIHRvIGVuc3VyZSBpdHMgbGVuZ3RoIGlzIGNvbmdydWVudCB0byA0NDggbW9kIDUxMi4gSW4gb3RoZXIgd29yZHMsCiAgICB0aGUgZGF0YSB0byBiZSBkaWdlc3RlZCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNTEyIGJpdHMgKG9yIDEyOCBieXRlcykuCiAgICBUaGlzIGRhdGEgaW5jbHVkZXMgdGhlIG1lc3NhZ2UsIHNvbWUgcGFkZGluZywgYW5kIHRoZSBsZW5ndGggb2YgdGhlCiAgICBtZXNzYWdlLiBTaW5jZSB0aGUgbGVuZ3RoIG9mIHRoZSBtZXNzYWdlIHdpbGwgYmUgZW5jb2RlZCBhcyA4IGJ5dGVzICg2NAogICAgYml0cyksIHRoYXQgbWVhbnMgdGhhdCB0aGUgbGFzdCBzZWdtZW50IG9mIHRoZSBkYXRhIG11c3QgaGF2ZSA1NiBieXRlcwogICAgKDQ0OCBiaXRzKSBvZiBtZXNzYWdlIGFuZCBwYWRkaW5nLiBUaGVyZWZvcmUsIHRoZSBsZW5ndGggb2YgdGhlIG1lc3NhZ2UKICAgIHBsdXMgdGhlIHBhZGRpbmcgbXVzdCBiZSBjb25ncnVlbnQgdG8gNDQ4IG1vZCA1MTIgYmVjYXVzZQogICAgNTEyIC0gMTI4ID0gNDQ4LgoKICAgIEluIG9yZGVyIHRvIGZpbGwgdXAgdGhlIG1lc3NhZ2UgbGVuZ3RoIGl0IG11c3QgYmUgZmlsbGVkIHdpdGgKICAgIHBhZGRpbmcgdGhhdCBiZWdpbnMgd2l0aCAxIGJpdCBmb2xsb3dlZCBieSBhbGwgMCBiaXRzLiBQYWRkaW5nCiAgICBtdXN0ICphbHdheXMqIGJlIHByZXNlbnQsIHNvIGlmIHRoZSBtZXNzYWdlIGxlbmd0aCBpcyBhbHJlYWR5CiAgICBjb25ncnVlbnQgdG8gNDQ4IG1vZCA1MTIsIHRoZW4gNTEyIHBhZGRpbmcgYml0cyBtdXN0IGJlIGFkZGVkLiAqLwoKICAgIHZhciBmaW5hbEJsb2NrID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIGZpbmFsQmxvY2sucHV0Qnl0ZXMoX2lucHV0LmJ5dGVzKCkpOwoKICAgIC8vIGNvbXB1dGUgcmVtYWluaW5nIHNpemUgdG8gYmUgZGlnZXN0ZWQgKGluY2x1ZGUgbWVzc2FnZSBsZW5ndGggc2l6ZSkKICAgIHZhciByZW1haW5pbmcgPSAoCiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW21kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aCAtIDFdICsKICAgICAgbWQubWVzc2FnZUxlbmd0aFNpemUpOwoKICAgIC8vIGFkZCBwYWRkaW5nIGZvciBvdmVyZmxvdyBibG9ja1NpemUgLSBvdmVyZmxvdwogICAgLy8gX3BhZGRpbmcgc3RhcnRzIHdpdGggMSBieXRlIHdpdGggZmlyc3QgYml0IGlzIHNldCAoYnl0ZSB2YWx1ZSAxMjgpLCB0aGVuCiAgICAvLyB0aGVyZSBtYXkgYmUgdXAgdG8gKGJsb2NrU2l6ZSAtIDEpIG90aGVyIHBhZCBieXRlcwogICAgdmFyIG92ZXJmbG93ID0gcmVtYWluaW5nICYgKG1kLmJsb2NrTGVuZ3RoIC0gMSk7CiAgICBmaW5hbEJsb2NrLnB1dEJ5dGVzKF9wYWRkaW5nLnN1YnN0cigwLCBtZC5ibG9ja0xlbmd0aCAtIG92ZXJmbG93KSk7CgogICAgLy8gc2VyaWFsaXplIG1lc3NhZ2UgbGVuZ3RoIGluIGJpdHMgaW4gYmlnLWVuZGlhbiBvcmRlcjsgc2luY2UgbGVuZ3RoCiAgICAvLyBpcyBzdG9yZWQgaW4gYnl0ZXMgd2UgbXVsdGlwbHkgYnkgOCBhbmQgYWRkIGNhcnJ5IGZyb20gbmV4dCBpbnQKICAgIHZhciBtZXNzYWdlTGVuZ3RoID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIHZhciBuZXh0LCBjYXJyeTsKICAgIHZhciBiaXRzID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbMF0gKiA4OwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aDsgKytpKSB7CiAgICAgIG5leHQgPSBtZC5mdWxsTWVzc2FnZUxlbmd0aFtpICsgMV0gKiA4OwogICAgICBjYXJyeSA9IChuZXh0IC8gMHgxMDAwMDAwMDApID4+PiAwOwogICAgICBiaXRzICs9IGNhcnJ5OwogICAgICBmaW5hbEJsb2NrLnB1dEludDMyKGJpdHMgPj4+IDApOwogICAgICBiaXRzID0gbmV4dDsKICAgIH0KCiAgICB2YXIgczIgPSB7CiAgICAgIGgwOiBfc3RhdGUuaDAsCiAgICAgIGgxOiBfc3RhdGUuaDEsCiAgICAgIGgyOiBfc3RhdGUuaDIsCiAgICAgIGgzOiBfc3RhdGUuaDMsCiAgICAgIGg0OiBfc3RhdGUuaDQKICAgIH07CiAgICBfdXBkYXRlKHMyLCBfdywgZmluYWxCbG9jayk7CiAgICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBydmFsLnB1dEludDMyKHMyLmgwKTsKICAgIHJ2YWwucHV0SW50MzIoczIuaDEpOwogICAgcnZhbC5wdXRJbnQzMihzMi5oMik7CiAgICBydmFsLnB1dEludDMyKHMyLmgzKTsKICAgIHJ2YWwucHV0SW50MzIoczIuaDQpOwogICAgcmV0dXJuIHJ2YWw7CiAgfTsKCiAgcmV0dXJuIG1kOwp9OwoKLy8gc2hhLTEgcGFkZGluZyBieXRlcyBub3QgaW5pdGlhbGl6ZWQgeWV0CnZhciBfcGFkZGluZyA9IG51bGw7CnZhciBfaW5pdGlhbGl6ZWQgPSBmYWxzZTsKCi8qKgogKiBJbml0aWFsaXplcyB0aGUgY29uc3RhbnQgdGFibGVzLgogKi8KZnVuY3Rpb24gX2luaXQoKSB7CiAgLy8gY3JlYXRlIHBhZGRpbmcKICBfcGFkZGluZyA9IFN0cmluZy5mcm9tQ2hhckNvZGUoMTI4KTsKICBfcGFkZGluZyArPSBmb3JnZS51dGlsLmZpbGxTdHJpbmcoU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKSwgNjQpOwoKICAvLyBub3cgaW5pdGlhbGl6ZWQKICBfaW5pdGlhbGl6ZWQgPSB0cnVlOwp9CgovKioKICogVXBkYXRlcyBhIFNIQS0xIHN0YXRlIHdpdGggdGhlIGdpdmVuIGJ5dGUgYnVmZmVyLgogKgogKiBAcGFyYW0gcyB0aGUgU0hBLTEgc3RhdGUgdG8gdXBkYXRlLgogKiBAcGFyYW0gdyB0aGUgYXJyYXkgdG8gdXNlIHRvIHN0b3JlIHdvcmRzLgogKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGUgYnVmZmVyIHRvIHVwZGF0ZSB3aXRoLgogKi8KZnVuY3Rpb24gX3VwZGF0ZShzLCB3LCBieXRlcykgewogIC8vIGNvbnN1bWUgNTEyIGJpdCAoNjQgYnl0ZSkgY2h1bmtzCiAgdmFyIHQsIGEsIGIsIGMsIGQsIGUsIGYsIGk7CiAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aCgpOwogIHdoaWxlKGxlbiA+PSA2NCkgewogICAgLy8gdGhlIHcgYXJyYXkgd2lsbCBiZSBwb3B1bGF0ZWQgd2l0aCBzaXh0ZWVuIDMyLWJpdCBiaWctZW5kaWFuIHdvcmRzCiAgICAvLyBhbmQgdGhlbiBleHRlbmRlZCBpbnRvIDgwIDMyLWJpdCB3b3JkcyBhY2NvcmRpbmcgdG8gU0hBLTEgYWxnb3JpdGhtCiAgICAvLyBhbmQgZm9yIDMyLTc5IHVzaW5nIE1heCBMb2NrdHl1a2hpbidzIG9wdGltaXphdGlvbgoKICAgIC8vIGluaXRpYWxpemUgaGFzaCB2YWx1ZSBmb3IgdGhpcyBjaHVuawogICAgYSA9IHMuaDA7CiAgICBiID0gcy5oMTsKICAgIGMgPSBzLmgyOwogICAgZCA9IHMuaDM7CiAgICBlID0gcy5oNDsKCiAgICAvLyByb3VuZCAxCiAgICBmb3IoaSA9IDA7IGkgPCAxNjsgKytpKSB7CiAgICAgIHQgPSBieXRlcy5nZXRJbnQzMigpOwogICAgICB3W2ldID0gdDsKICAgICAgZiA9IGQgXiAoYiAmIChjIF4gZCkpOwogICAgICB0ID0gKChhIDw8IDUpIHwgKGEgPj4+IDI3KSkgKyBmICsgZSArIDB4NUE4Mjc5OTkgKyB0OwogICAgICBlID0gZDsKICAgICAgZCA9IGM7CiAgICAgIGMgPSAoYiA8PCAzMCkgfCAoYiA+Pj4gMik7CiAgICAgIGIgPSBhOwogICAgICBhID0gdDsKICAgIH0KICAgIGZvcig7IGkgPCAyMDsgKytpKSB7CiAgICAgIHQgPSAod1tpIC0gM10gXiB3W2kgLSA4XSBeIHdbaSAtIDE0XSBeIHdbaSAtIDE2XSk7CiAgICAgIHQgPSAodCA8PCAxKSB8ICh0ID4+PiAzMSk7CiAgICAgIHdbaV0gPSB0OwogICAgICBmID0gZCBeIChiICYgKGMgXiBkKSk7CiAgICAgIHQgPSAoKGEgPDwgNSkgfCAoYSA+Pj4gMjcpKSArIGYgKyBlICsgMHg1QTgyNzk5OSArIHQ7CiAgICAgIGUgPSBkOwogICAgICBkID0gYzsKICAgICAgYyA9IChiIDw8IDMwKSB8IChiID4+PiAyKTsKICAgICAgYiA9IGE7CiAgICAgIGEgPSB0OwogICAgfQogICAgLy8gcm91bmQgMgogICAgZm9yKDsgaSA8IDMyOyArK2kpIHsKICAgICAgdCA9ICh3W2kgLSAzXSBeIHdbaSAtIDhdIF4gd1tpIC0gMTRdIF4gd1tpIC0gMTZdKTsKICAgICAgdCA9ICh0IDw8IDEpIHwgKHQgPj4+IDMxKTsKICAgICAgd1tpXSA9IHQ7CiAgICAgIGYgPSBiIF4gYyBeIGQ7CiAgICAgIHQgPSAoKGEgPDwgNSkgfCAoYSA+Pj4gMjcpKSArIGYgKyBlICsgMHg2RUQ5RUJBMSArIHQ7CiAgICAgIGUgPSBkOwogICAgICBkID0gYzsKICAgICAgYyA9IChiIDw8IDMwKSB8IChiID4+PiAyKTsKICAgICAgYiA9IGE7CiAgICAgIGEgPSB0OwogICAgfQogICAgZm9yKDsgaSA8IDQwOyArK2kpIHsKICAgICAgdCA9ICh3W2kgLSA2XSBeIHdbaSAtIDE2XSBeIHdbaSAtIDI4XSBeIHdbaSAtIDMyXSk7CiAgICAgIHQgPSAodCA8PCAyKSB8ICh0ID4+PiAzMCk7CiAgICAgIHdbaV0gPSB0OwogICAgICBmID0gYiBeIGMgXiBkOwogICAgICB0ID0gKChhIDw8IDUpIHwgKGEgPj4+IDI3KSkgKyBmICsgZSArIDB4NkVEOUVCQTEgKyB0OwogICAgICBlID0gZDsKICAgICAgZCA9IGM7CiAgICAgIGMgPSAoYiA8PCAzMCkgfCAoYiA+Pj4gMik7CiAgICAgIGIgPSBhOwogICAgICBhID0gdDsKICAgIH0KICAgIC8vIHJvdW5kIDMKICAgIGZvcig7IGkgPCA2MDsgKytpKSB7CiAgICAgIHQgPSAod1tpIC0gNl0gXiB3W2kgLSAxNl0gXiB3W2kgLSAyOF0gXiB3W2kgLSAzMl0pOwogICAgICB0ID0gKHQgPDwgMikgfCAodCA+Pj4gMzApOwogICAgICB3W2ldID0gdDsKICAgICAgZiA9IChiICYgYykgfCAoZCAmIChiIF4gYykpOwogICAgICB0ID0gKChhIDw8IDUpIHwgKGEgPj4+IDI3KSkgKyBmICsgZSArIDB4OEYxQkJDREMgKyB0OwogICAgICBlID0gZDsKICAgICAgZCA9IGM7CiAgICAgIGMgPSAoYiA8PCAzMCkgfCAoYiA+Pj4gMik7CiAgICAgIGIgPSBhOwogICAgICBhID0gdDsKICAgIH0KICAgIC8vIHJvdW5kIDQKICAgIGZvcig7IGkgPCA4MDsgKytpKSB7CiAgICAgIHQgPSAod1tpIC0gNl0gXiB3W2kgLSAxNl0gXiB3W2kgLSAyOF0gXiB3W2kgLSAzMl0pOwogICAgICB0ID0gKHQgPDwgMikgfCAodCA+Pj4gMzApOwogICAgICB3W2ldID0gdDsKICAgICAgZiA9IGIgXiBjIF4gZDsKICAgICAgdCA9ICgoYSA8PCA1KSB8IChhID4+PiAyNykpICsgZiArIGUgKyAweENBNjJDMUQ2ICsgdDsKICAgICAgZSA9IGQ7CiAgICAgIGQgPSBjOwogICAgICBjID0gKGIgPDwgMzApIHwgKGIgPj4+IDIpOwogICAgICBiID0gYTsKICAgICAgYSA9IHQ7CiAgICB9CgogICAgLy8gdXBkYXRlIGhhc2ggc3RhdGUKICAgIHMuaDAgPSAocy5oMCArIGEpIHwgMDsKICAgIHMuaDEgPSAocy5oMSArIGIpIHwgMDsKICAgIHMuaDIgPSAocy5oMiArIGMpIHwgMDsKICAgIHMuaDMgPSAocy5oMyArIGQpIHwgMDsKICAgIHMuaDQgPSAocy5oNCArIGUpIHwgMDsKCiAgICBsZW4gLT0gNjQ7CiAgfQp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdzaGExJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3NoYTEnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFNlY3VyZSBIYXNoIEFsZ29yaXRobSB3aXRoIDI1Ni1iaXQgZGlnZXN0IChTSEEtMjU2KSBpbXBsZW1lbnRhdGlvbi4KICoKICogU2VlIEZJUFMgMTgwLTIgZm9yIGRldGFpbHMuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDE1IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKdmFyIHNoYTI1NiA9IGZvcmdlLnNoYTI1NiA9IGZvcmdlLnNoYTI1NiB8fCB7fTsKZm9yZ2UubWQgPSBmb3JnZS5tZCB8fCB7fTsKZm9yZ2UubWQuYWxnb3JpdGhtcyA9IGZvcmdlLm1kLmFsZ29yaXRobXMgfHwge307CmZvcmdlLm1kLnNoYTI1NiA9IGZvcmdlLm1kLmFsZ29yaXRobXMuc2hhMjU2ID0gc2hhMjU2OwoKLyoqCiAqIENyZWF0ZXMgYSBTSEEtMjU2IG1lc3NhZ2UgZGlnZXN0IG9iamVjdC4KICoKICogQHJldHVybiBhIG1lc3NhZ2UgZGlnZXN0IG9iamVjdC4KICovCnNoYTI1Ni5jcmVhdGUgPSBmdW5jdGlvbigpIHsKICAvLyBkbyBpbml0aWFsaXphdGlvbiBhcyBuZWNlc3NhcnkKICBpZighX2luaXRpYWxpemVkKSB7CiAgICBfaW5pdCgpOwogIH0KCiAgLy8gU0hBLTI1NiBzdGF0ZSBjb250YWlucyBlaWdodCAzMi1iaXQgaW50ZWdlcnMKICB2YXIgX3N0YXRlID0gbnVsbDsKCiAgLy8gaW5wdXQgYnVmZmVyCiAgdmFyIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIHVzZWQgZm9yIHdvcmQgc3RvcmFnZQogIHZhciBfdyA9IG5ldyBBcnJheSg2NCk7CgogIC8vIG1lc3NhZ2UgZGlnZXN0IG9iamVjdAogIHZhciBtZCA9IHsKICAgIGFsZ29yaXRobTogJ3NoYTI1NicsCiAgICBibG9ja0xlbmd0aDogNjQsCiAgICBkaWdlc3RMZW5ndGg6IDMyLAogICAgLy8gNTYtYml0IGxlbmd0aCBvZiBtZXNzYWdlIHNvIGZhciAoZG9lcyBub3QgaW5jbHVkaW5nIHBhZGRpbmcpCiAgICBtZXNzYWdlTGVuZ3RoOiAwLAogICAgLy8gdHJ1ZSBtZXNzYWdlIGxlbmd0aAogICAgZnVsbE1lc3NhZ2VMZW5ndGg6IG51bGwsCiAgICAvLyBzaXplIG9mIG1lc3NhZ2UgbGVuZ3RoIGluIGJ5dGVzCiAgICBtZXNzYWdlTGVuZ3RoU2l6ZTogOAogIH07CgogIC8qKgogICAqIFN0YXJ0cyB0aGUgZGlnZXN0LgogICAqCiAgICogQHJldHVybiB0aGlzIGRpZ2VzdCBvYmplY3QuCiAgICovCiAgbWQuc3RhcnQgPSBmdW5jdGlvbigpIHsKICAgIC8vIHVwIHRvIDU2LWJpdCBtZXNzYWdlIGxlbmd0aCBmb3IgY29udmVuaWVuY2UKICAgIG1kLm1lc3NhZ2VMZW5ndGggPSAwOwoKICAgIC8vIGZ1bGwgbWVzc2FnZSBsZW5ndGggKHNldCBtZC5tZXNzYWdlTGVuZ3RoNjQgZm9yIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5KQogICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGggPSBtZC5tZXNzYWdlTGVuZ3RoNjQgPSBbXTsKICAgIHZhciBpbnQzMnMgPSBtZC5tZXNzYWdlTGVuZ3RoU2l6ZSAvIDQ7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgaW50MzJzOyArK2kpIHsKICAgICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGgucHVzaCgwKTsKICAgIH0KICAgIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBfc3RhdGUgPSB7CiAgICAgIGgwOiAweDZBMDlFNjY3LAogICAgICBoMTogMHhCQjY3QUU4NSwKICAgICAgaDI6IDB4M0M2RUYzNzIsCiAgICAgIGgzOiAweEE1NEZGNTNBLAogICAgICBoNDogMHg1MTBFNTI3RiwKICAgICAgaDU6IDB4OUIwNTY4OEMsCiAgICAgIGg2OiAweDFGODNEOUFCLAogICAgICBoNzogMHg1QkUwQ0QxOQogICAgfTsKICAgIHJldHVybiBtZDsKICB9OwogIC8vIHN0YXJ0IGRpZ2VzdCBhdXRvbWF0aWNhbGx5IGZvciBmaXJzdCB0aW1lCiAgbWQuc3RhcnQoKTsKCiAgLyoqCiAgICogVXBkYXRlcyB0aGUgZGlnZXN0IHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UgaW5wdXQuIFRoZSBnaXZlbiBpbnB1dCBjYW4KICAgKiB0cmVhdGVkIGFzIHJhdyBpbnB1dCAobm8gZW5jb2Rpbmcgd2lsbCBiZSBhcHBsaWVkKSBvciBhbiBlbmNvZGluZyBvZgogICAqICd1dGY4JyBtYXliZSBnaXZlbiB0byBlbmNvZGUgdGhlIGlucHV0IHVzaW5nIFVURi04LgogICAqCiAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSBpbnB1dCB0byB1cGRhdGUgd2l0aC4KICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGVuY29kaW5nIHRvIHVzZSAoZGVmYXVsdDogJ3JhdycsIG90aGVyOiAndXRmOCcpLgogICAqCiAgICogQHJldHVybiB0aGlzIGRpZ2VzdCBvYmplY3QuCiAgICovCiAgbWQudXBkYXRlID0gZnVuY3Rpb24obXNnLCBlbmNvZGluZykgewogICAgaWYoZW5jb2RpbmcgPT09ICd1dGY4JykgewogICAgICBtc2cgPSBmb3JnZS51dGlsLmVuY29kZVV0ZjgobXNnKTsKICAgIH0KCiAgICAvLyB1cGRhdGUgbWVzc2FnZSBsZW5ndGgKICAgIHZhciBsZW4gPSBtc2cubGVuZ3RoOwogICAgbWQubWVzc2FnZUxlbmd0aCArPSBsZW47CiAgICBsZW4gPSBbKGxlbiAvIDB4MTAwMDAwMDAwKSA+Pj4gMCwgbGVuID4+PiAwXTsKICAgIGZvcih2YXIgaSA9IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7CiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldICs9IGxlblsxXTsKICAgICAgbGVuWzFdID0gbGVuWzBdICsgKChtZC5mdWxsTWVzc2FnZUxlbmd0aFtpXSAvIDB4MTAwMDAwMDAwKSA+Pj4gMCk7CiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gPj4+IDA7CiAgICAgIGxlblswXSA9ICgobGVuWzFdIC8gMHgxMDAwMDAwMDApID4+PiAwKTsKICAgIH0KCiAgICAvLyBhZGQgYnl0ZXMgdG8gaW5wdXQgYnVmZmVyCiAgICBfaW5wdXQucHV0Qnl0ZXMobXNnKTsKCiAgICAvLyBwcm9jZXNzIGJ5dGVzCiAgICBfdXBkYXRlKF9zdGF0ZSwgX3csIF9pbnB1dCk7CgogICAgLy8gY29tcGFjdCBpbnB1dCBidWZmZXIgZXZlcnkgMksgb3IgaWYgZW1wdHkKICAgIGlmKF9pbnB1dC5yZWFkID4gMjA0OCB8fCBfaW5wdXQubGVuZ3RoKCkgPT09IDApIHsKICAgICAgX2lucHV0LmNvbXBhY3QoKTsKICAgIH0KCiAgICByZXR1cm4gbWQ7CiAgfTsKCiAgLyoqCiAgICogUHJvZHVjZXMgdGhlIGRpZ2VzdC4KICAgKgogICAqIEByZXR1cm4gYSBieXRlIGJ1ZmZlciBjb250YWluaW5nIHRoZSBkaWdlc3QgdmFsdWUuCiAgICovCiAgbWQuZGlnZXN0ID0gZnVuY3Rpb24oKSB7CiAgICAvKiBOb3RlOiBIZXJlIHdlIGNvcHkgdGhlIHJlbWFpbmluZyBieXRlcyBpbiB0aGUgaW5wdXQgYnVmZmVyIGFuZAogICAgYWRkIHRoZSBhcHByb3ByaWF0ZSBTSEEtMjU2IHBhZGRpbmcuIFRoZW4gd2UgZG8gdGhlIGZpbmFsIHVwZGF0ZQogICAgb24gYSBjb3B5IG9mIHRoZSBzdGF0ZSBzbyB0aGF0IGlmIHRoZSB1c2VyIHdhbnRzIHRvIGdldAogICAgaW50ZXJtZWRpYXRlIGRpZ2VzdHMgdGhleSBjYW4gZG8gc28uICovCgogICAgLyogRGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBtdXN0IGJlIGFkZGVkIHRvIHRoZSBtZXNzYWdlCiAgICB0byBlbnN1cmUgaXRzIGxlbmd0aCBpcyBjb25ncnVlbnQgdG8gNDQ4IG1vZCA1MTIuIEluIG90aGVyIHdvcmRzLAogICAgdGhlIGRhdGEgdG8gYmUgZGlnZXN0ZWQgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDUxMiBiaXRzIChvciAxMjggYnl0ZXMpLgogICAgVGhpcyBkYXRhIGluY2x1ZGVzIHRoZSBtZXNzYWdlLCBzb21lIHBhZGRpbmcsIGFuZCB0aGUgbGVuZ3RoIG9mIHRoZQogICAgbWVzc2FnZS4gU2luY2UgdGhlIGxlbmd0aCBvZiB0aGUgbWVzc2FnZSB3aWxsIGJlIGVuY29kZWQgYXMgOCBieXRlcyAoNjQKICAgIGJpdHMpLCB0aGF0IG1lYW5zIHRoYXQgdGhlIGxhc3Qgc2VnbWVudCBvZiB0aGUgZGF0YSBtdXN0IGhhdmUgNTYgYnl0ZXMKICAgICg0NDggYml0cykgb2YgbWVzc2FnZSBhbmQgcGFkZGluZy4gVGhlcmVmb3JlLCB0aGUgbGVuZ3RoIG9mIHRoZSBtZXNzYWdlCiAgICBwbHVzIHRoZSBwYWRkaW5nIG11c3QgYmUgY29uZ3J1ZW50IHRvIDQ0OCBtb2QgNTEyIGJlY2F1c2UKICAgIDUxMiAtIDEyOCA9IDQ0OC4KCiAgICBJbiBvcmRlciB0byBmaWxsIHVwIHRoZSBtZXNzYWdlIGxlbmd0aCBpdCBtdXN0IGJlIGZpbGxlZCB3aXRoCiAgICBwYWRkaW5nIHRoYXQgYmVnaW5zIHdpdGggMSBiaXQgZm9sbG93ZWQgYnkgYWxsIDAgYml0cy4gUGFkZGluZwogICAgbXVzdCAqYWx3YXlzKiBiZSBwcmVzZW50LCBzbyBpZiB0aGUgbWVzc2FnZSBsZW5ndGggaXMgYWxyZWFkeQogICAgY29uZ3J1ZW50IHRvIDQ0OCBtb2QgNTEyLCB0aGVuIDUxMiBwYWRkaW5nIGJpdHMgbXVzdCBiZSBhZGRlZC4gKi8KCiAgICB2YXIgZmluYWxCbG9jayA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBmaW5hbEJsb2NrLnB1dEJ5dGVzKF9pbnB1dC5ieXRlcygpKTsKCiAgICAvLyBjb21wdXRlIHJlbWFpbmluZyBzaXplIHRvIGJlIGRpZ2VzdGVkIChpbmNsdWRlIG1lc3NhZ2UgbGVuZ3RoIHNpemUpCiAgICB2YXIgcmVtYWluaW5nID0gKAogICAgICBtZC5mdWxsTWVzc2FnZUxlbmd0aFttZC5mdWxsTWVzc2FnZUxlbmd0aC5sZW5ndGggLSAxXSArCiAgICAgIG1kLm1lc3NhZ2VMZW5ndGhTaXplKTsKCiAgICAvLyBhZGQgcGFkZGluZyBmb3Igb3ZlcmZsb3cgYmxvY2tTaXplIC0gb3ZlcmZsb3cKICAgIC8vIF9wYWRkaW5nIHN0YXJ0cyB3aXRoIDEgYnl0ZSB3aXRoIGZpcnN0IGJpdCBpcyBzZXQgKGJ5dGUgdmFsdWUgMTI4KSwgdGhlbgogICAgLy8gdGhlcmUgbWF5IGJlIHVwIHRvIChibG9ja1NpemUgLSAxKSBvdGhlciBwYWQgYnl0ZXMKICAgIHZhciBvdmVyZmxvdyA9IHJlbWFpbmluZyAmIChtZC5ibG9ja0xlbmd0aCAtIDEpOwogICAgZmluYWxCbG9jay5wdXRCeXRlcyhfcGFkZGluZy5zdWJzdHIoMCwgbWQuYmxvY2tMZW5ndGggLSBvdmVyZmxvdykpOwoKICAgIC8vIHNlcmlhbGl6ZSBtZXNzYWdlIGxlbmd0aCBpbiBiaXRzIGluIGJpZy1lbmRpYW4gb3JkZXI7IHNpbmNlIGxlbmd0aAogICAgLy8gaXMgc3RvcmVkIGluIGJ5dGVzIHdlIG11bHRpcGx5IGJ5IDggYW5kIGFkZCBjYXJyeSBmcm9tIG5leHQgaW50CiAgICB2YXIgbWVzc2FnZUxlbmd0aCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICB2YXIgbmV4dCwgY2Fycnk7CiAgICB2YXIgYml0cyA9IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoWzBdICogODsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtZC5mdWxsTWVzc2FnZUxlbmd0aC5sZW5ndGg7ICsraSkgewogICAgICBuZXh0ID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaSArIDFdICogODsKICAgICAgY2FycnkgPSAobmV4dCAvIDB4MTAwMDAwMDAwKSA+Pj4gMDsKICAgICAgYml0cyArPSBjYXJyeTsKICAgICAgZmluYWxCbG9jay5wdXRJbnQzMihiaXRzID4+PiAwKTsKICAgICAgYml0cyA9IG5leHQ7CiAgICB9CgogICAgdmFyIHMyID0gewogICAgICBoMDogX3N0YXRlLmgwLAogICAgICBoMTogX3N0YXRlLmgxLAogICAgICBoMjogX3N0YXRlLmgyLAogICAgICBoMzogX3N0YXRlLmgzLAogICAgICBoNDogX3N0YXRlLmg0LAogICAgICBoNTogX3N0YXRlLmg1LAogICAgICBoNjogX3N0YXRlLmg2LAogICAgICBoNzogX3N0YXRlLmg3CiAgICB9OwogICAgX3VwZGF0ZShzMiwgX3csIGZpbmFsQmxvY2spOwogICAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgcnZhbC5wdXRJbnQzMihzMi5oMCk7CiAgICBydmFsLnB1dEludDMyKHMyLmgxKTsKICAgIHJ2YWwucHV0SW50MzIoczIuaDIpOwogICAgcnZhbC5wdXRJbnQzMihzMi5oMyk7CiAgICBydmFsLnB1dEludDMyKHMyLmg0KTsKICAgIHJ2YWwucHV0SW50MzIoczIuaDUpOwogICAgcnZhbC5wdXRJbnQzMihzMi5oNik7CiAgICBydmFsLnB1dEludDMyKHMyLmg3KTsKICAgIHJldHVybiBydmFsOwogIH07CgogIHJldHVybiBtZDsKfTsKCi8vIHNoYS0yNTYgcGFkZGluZyBieXRlcyBub3QgaW5pdGlhbGl6ZWQgeWV0CnZhciBfcGFkZGluZyA9IG51bGw7CnZhciBfaW5pdGlhbGl6ZWQgPSBmYWxzZTsKCi8vIHRhYmxlIG9mIGNvbnN0YW50cwp2YXIgX2sgPSBudWxsOwoKLyoqCiAqIEluaXRpYWxpemVzIHRoZSBjb25zdGFudCB0YWJsZXMuCiAqLwpmdW5jdGlvbiBfaW5pdCgpIHsKICAvLyBjcmVhdGUgcGFkZGluZwogIF9wYWRkaW5nID0gU3RyaW5nLmZyb21DaGFyQ29kZSgxMjgpOwogIF9wYWRkaW5nICs9IGZvcmdlLnV0aWwuZmlsbFN0cmluZyhTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDApLCA2NCk7CgogIC8vIGNyZWF0ZSBLIHRhYmxlIGZvciBTSEEtMjU2CiAgX2sgPSBbCiAgICAweDQyOGEyZjk4LCAweDcxMzc0NDkxLCAweGI1YzBmYmNmLCAweGU5YjVkYmE1LAogICAgMHgzOTU2YzI1YiwgMHg1OWYxMTFmMSwgMHg5MjNmODJhNCwgMHhhYjFjNWVkNSwKICAgIDB4ZDgwN2FhOTgsIDB4MTI4MzViMDEsIDB4MjQzMTg1YmUsIDB4NTUwYzdkYzMsCiAgICAweDcyYmU1ZDc0LCAweDgwZGViMWZlLCAweDliZGMwNmE3LCAweGMxOWJmMTc0LAogICAgMHhlNDliNjljMSwgMHhlZmJlNDc4NiwgMHgwZmMxOWRjNiwgMHgyNDBjYTFjYywKICAgIDB4MmRlOTJjNmYsIDB4NGE3NDg0YWEsIDB4NWNiMGE5ZGMsIDB4NzZmOTg4ZGEsCiAgICAweDk4M2U1MTUyLCAweGE4MzFjNjZkLCAweGIwMDMyN2M4LCAweGJmNTk3ZmM3LAogICAgMHhjNmUwMGJmMywgMHhkNWE3OTE0NywgMHgwNmNhNjM1MSwgMHgxNDI5Mjk2NywKICAgIDB4MjdiNzBhODUsIDB4MmUxYjIxMzgsIDB4NGQyYzZkZmMsIDB4NTMzODBkMTMsCiAgICAweDY1MGE3MzU0LCAweDc2NmEwYWJiLCAweDgxYzJjOTJlLCAweDkyNzIyYzg1LAogICAgMHhhMmJmZThhMSwgMHhhODFhNjY0YiwgMHhjMjRiOGI3MCwgMHhjNzZjNTFhMywKICAgIDB4ZDE5MmU4MTksIDB4ZDY5OTA2MjQsIDB4ZjQwZTM1ODUsIDB4MTA2YWEwNzAsCiAgICAweDE5YTRjMTE2LCAweDFlMzc2YzA4LCAweDI3NDg3NzRjLCAweDM0YjBiY2I1LAogICAgMHgzOTFjMGNiMywgMHg0ZWQ4YWE0YSwgMHg1YjljY2E0ZiwgMHg2ODJlNmZmMywKICAgIDB4NzQ4ZjgyZWUsIDB4NzhhNTYzNmYsIDB4ODRjODc4MTQsIDB4OGNjNzAyMDgsCiAgICAweDkwYmVmZmZhLCAweGE0NTA2Y2ViLCAweGJlZjlhM2Y3LCAweGM2NzE3OGYyXTsKCiAgLy8gbm93IGluaXRpYWxpemVkCiAgX2luaXRpYWxpemVkID0gdHJ1ZTsKfQoKLyoqCiAqIFVwZGF0ZXMgYSBTSEEtMjU2IHN0YXRlIHdpdGggdGhlIGdpdmVuIGJ5dGUgYnVmZmVyLgogKgogKiBAcGFyYW0gcyB0aGUgU0hBLTI1NiBzdGF0ZSB0byB1cGRhdGUuCiAqIEBwYXJhbSB3IHRoZSBhcnJheSB0byB1c2UgdG8gc3RvcmUgd29yZHMuCiAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZSBidWZmZXIgdG8gdXBkYXRlIHdpdGguCiAqLwpmdW5jdGlvbiBfdXBkYXRlKHMsIHcsIGJ5dGVzKSB7CiAgLy8gY29uc3VtZSA1MTIgYml0ICg2NCBieXRlKSBjaHVua3MKICB2YXIgdDEsIHQyLCBzMCwgczEsIGNoLCBtYWosIGksIGEsIGIsIGMsIGQsIGUsIGYsIGcsIGg7CiAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aCgpOwogIHdoaWxlKGxlbiA+PSA2NCkgewogICAgLy8gdGhlIHcgYXJyYXkgd2lsbCBiZSBwb3B1bGF0ZWQgd2l0aCBzaXh0ZWVuIDMyLWJpdCBiaWctZW5kaWFuIHdvcmRzCiAgICAvLyBhbmQgdGhlbiBleHRlbmRlZCBpbnRvIDY0IDMyLWJpdCB3b3JkcyBhY2NvcmRpbmcgdG8gU0hBLTI1NgogICAgZm9yKGkgPSAwOyBpIDwgMTY7ICsraSkgewogICAgICB3W2ldID0gYnl0ZXMuZ2V0SW50MzIoKTsKICAgIH0KICAgIGZvcig7IGkgPCA2NDsgKytpKSB7CiAgICAgIC8vIFhPUiB3b3JkIDIgd29yZHMgYWdvIHJvdCByaWdodCAxNywgcm90IHJpZ2h0IDE5LCBzaGZ0IHJpZ2h0IDEwCiAgICAgIHQxID0gd1tpIC0gMl07CiAgICAgIHQxID0KICAgICAgICAoKHQxID4+PiAxNykgfCAodDEgPDwgMTUpKSBeCiAgICAgICAgKCh0MSA+Pj4gMTkpIHwgKHQxIDw8IDEzKSkgXgogICAgICAgICh0MSA+Pj4gMTApOwogICAgICAvLyBYT1Igd29yZCAxNSB3b3JkcyBhZ28gcm90IHJpZ2h0IDcsIHJvdCByaWdodCAxOCwgc2hmdCByaWdodCAzCiAgICAgIHQyID0gd1tpIC0gMTVdOwogICAgICB0MiA9CiAgICAgICAgKCh0MiA+Pj4gNykgfCAodDIgPDwgMjUpKSBeCiAgICAgICAgKCh0MiA+Pj4gMTgpIHwgKHQyIDw8IDE0KSkgXgogICAgICAgICh0MiA+Pj4gMyk7CiAgICAgIC8vIHN1bSh0MSwgd29yZCA3IGFnbywgdDIsIHdvcmQgMTYgYWdvKSBtb2R1bG8gMl4zMgogICAgICB3W2ldID0gKHQxICsgd1tpIC0gN10gKyB0MiArIHdbaSAtIDE2XSkgfCAwOwogICAgfQoKICAgIC8vIGluaXRpYWxpemUgaGFzaCB2YWx1ZSBmb3IgdGhpcyBjaHVuawogICAgYSA9IHMuaDA7CiAgICBiID0gcy5oMTsKICAgIGMgPSBzLmgyOwogICAgZCA9IHMuaDM7CiAgICBlID0gcy5oNDsKICAgIGYgPSBzLmg1OwogICAgZyA9IHMuaDY7CiAgICBoID0gcy5oNzsKCiAgICAvLyByb3VuZCBmdW5jdGlvbgogICAgZm9yKGkgPSAwOyBpIDwgNjQ7ICsraSkgewogICAgICAvLyBTdW0xKGUpCiAgICAgIHMxID0KICAgICAgICAoKGUgPj4+IDYpIHwgKGUgPDwgMjYpKSBeCiAgICAgICAgKChlID4+PiAxMSkgfCAoZSA8PCAyMSkpIF4KICAgICAgICAoKGUgPj4+IDI1KSB8IChlIDw8IDcpKTsKICAgICAgLy8gQ2goZSwgZiwgZykgKG9wdGltaXplZCB0aGUgc2FtZSB3YXkgYXMgU0hBLTEpCiAgICAgIGNoID0gZyBeIChlICYgKGYgXiBnKSk7CiAgICAgIC8vIFN1bTAoYSkKICAgICAgczAgPQogICAgICAgICgoYSA+Pj4gMikgfCAoYSA8PCAzMCkpIF4KICAgICAgICAoKGEgPj4+IDEzKSB8IChhIDw8IDE5KSkgXgogICAgICAgICgoYSA+Pj4gMjIpIHwgKGEgPDwgMTApKTsKICAgICAgLy8gTWFqKGEsIGIsIGMpIChvcHRpbWl6ZWQgdGhlIHNhbWUgd2F5IGFzIFNIQS0xKQogICAgICBtYWogPSAoYSAmIGIpIHwgKGMgJiAoYSBeIGIpKTsKCiAgICAgIC8vIG1haW4gYWxnb3JpdGhtCiAgICAgIHQxID0gaCArIHMxICsgY2ggKyBfa1tpXSArIHdbaV07CiAgICAgIHQyID0gczAgKyBtYWo7CiAgICAgIGggPSBnOwogICAgICBnID0gZjsKICAgICAgZiA9IGU7CiAgICAgIGUgPSAoZCArIHQxKSB8IDA7CiAgICAgIGQgPSBjOwogICAgICBjID0gYjsKICAgICAgYiA9IGE7CiAgICAgIGEgPSAodDEgKyB0MikgfCAwOwogICAgfQoKICAgIC8vIHVwZGF0ZSBoYXNoIHN0YXRlCiAgICBzLmgwID0gKHMuaDAgKyBhKSB8IDA7CiAgICBzLmgxID0gKHMuaDEgKyBiKSB8IDA7CiAgICBzLmgyID0gKHMuaDIgKyBjKSB8IDA7CiAgICBzLmgzID0gKHMuaDMgKyBkKSB8IDA7CiAgICBzLmg0ID0gKHMuaDQgKyBlKSB8IDA7CiAgICBzLmg1ID0gKHMuaDUgKyBmKSB8IDA7CiAgICBzLmg2ID0gKHMuaDYgKyBnKSB8IDA7CiAgICBzLmg3ID0gKHMuaDcgKyBoKSB8IDA7CiAgICBsZW4gLT0gNjQ7CiAgfQp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdzaGEyNTYnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvc2hhMjU2JyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBTZWN1cmUgSGFzaCBBbGdvcml0aG0gd2l0aCBhIDEwMjQtYml0IGJsb2NrIHNpemUgaW1wbGVtZW50YXRpb24uCiAqCiAqIFRoaXMgaW5jbHVkZXM6IFNIQS01MTIsIFNIQS0zODQsIFNIQS01MTIvMjI0LCBhbmQgU0hBLTUxMi8yNTYuIEZvcgogKiBTSEEtMjU2IChibG9jayBzaXplIDUxMiBiaXRzKSwgc2VlIHNoYTI1Ni5qcy4KICoKICogU2VlIEZJUFMgMTgwLTQgZm9yIGRldGFpbHMuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxNC0yMDE1IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKdmFyIHNoYTUxMiA9IGZvcmdlLnNoYTUxMiA9IGZvcmdlLnNoYTUxMiB8fCB7fTsKZm9yZ2UubWQgPSBmb3JnZS5tZCB8fCB7fTsKZm9yZ2UubWQuYWxnb3JpdGhtcyA9IGZvcmdlLm1kLmFsZ29yaXRobXMgfHwge307CgovLyBTSEEtNTEyCmZvcmdlLm1kLnNoYTUxMiA9IGZvcmdlLm1kLmFsZ29yaXRobXMuc2hhNTEyID0gc2hhNTEyOwoKLy8gU0hBLTM4NAp2YXIgc2hhMzg0ID0gZm9yZ2Uuc2hhMzg0ID0gZm9yZ2Uuc2hhNTEyLnNoYTM4NCA9IGZvcmdlLnNoYTUxMi5zaGEzODQgfHwge307CnNoYTM4NC5jcmVhdGUgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gc2hhNTEyLmNyZWF0ZSgnU0hBLTM4NCcpOwp9Owpmb3JnZS5tZC5zaGEzODQgPSBmb3JnZS5tZC5hbGdvcml0aG1zLnNoYTM4NCA9IHNoYTM4NDsKCi8vIFNIQS01MTIvMjU2CmZvcmdlLnNoYTUxMi5zaGEyNTYgPSBmb3JnZS5zaGE1MTIuc2hhMjU2IHx8IHsKICBjcmVhdGU6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHNoYTUxMi5jcmVhdGUoJ1NIQS01MTIvMjU2Jyk7CiAgfQp9Owpmb3JnZS5tZFsnc2hhNTEyLzI1NiddID0gZm9yZ2UubWQuYWxnb3JpdGhtc1snc2hhNTEyLzI1NiddID0KICBmb3JnZS5zaGE1MTIuc2hhMjU2OwoKLy8gU0hBLTUxMi8yMjQKZm9yZ2Uuc2hhNTEyLnNoYTIyNCA9IGZvcmdlLnNoYTUxMi5zaGEyMjQgfHwgewogIGNyZWF0ZTogZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gc2hhNTEyLmNyZWF0ZSgnU0hBLTUxMi8yMjQnKTsKICB9Cn07CmZvcmdlLm1kWydzaGE1MTIvMjI0J10gPSBmb3JnZS5tZC5hbGdvcml0aG1zWydzaGE1MTIvMjI0J10gPQogIGZvcmdlLnNoYTUxMi5zaGEyMjQ7CgovKioKICogQ3JlYXRlcyBhIFNIQS0yIG1lc3NhZ2UgZGlnZXN0IG9iamVjdC4KICoKICogQHBhcmFtIGFsZ29yaXRobSB0aGUgYWxnb3JpdGhtIHRvIHVzZSAoU0hBLTUxMiwgU0hBLTM4NCwgU0hBLTUxMi8yMjQsCiAqICAgICAgICAgIFNIQS01MTIvMjU2KS4KICoKICogQHJldHVybiBhIG1lc3NhZ2UgZGlnZXN0IG9iamVjdC4KICovCnNoYTUxMi5jcmVhdGUgPSBmdW5jdGlvbihhbGdvcml0aG0pIHsKICAvLyBkbyBpbml0aWFsaXphdGlvbiBhcyBuZWNlc3NhcnkKICBpZighX2luaXRpYWxpemVkKSB7CiAgICBfaW5pdCgpOwogIH0KCiAgaWYodHlwZW9mIGFsZ29yaXRobSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIGFsZ29yaXRobSA9ICdTSEEtNTEyJzsKICB9CgogIGlmKCEoYWxnb3JpdGhtIGluIF9zdGF0ZXMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgU0hBLTUxMiBhbGdvcml0aG06ICcgKyBhbGdvcml0aG0pOwogIH0KCiAgLy8gU0hBLTUxMiBzdGF0ZSBjb250YWlucyBlaWdodCA2NC1iaXQgaW50ZWdlcnMgKGVhY2ggYXMgdHdvIDMyLWJpdCBpbnRzKQogIHZhciBfc3RhdGUgPSBfc3RhdGVzW2FsZ29yaXRobV07CiAgdmFyIF9oID0gbnVsbDsKCiAgLy8gaW5wdXQgYnVmZmVyCiAgdmFyIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIHVzZWQgZm9yIDY0LWJpdCB3b3JkIHN0b3JhZ2UKICB2YXIgX3cgPSBuZXcgQXJyYXkoODApOwogIGZvcih2YXIgd2kgPSAwOyB3aSA8IDgwOyArK3dpKSB7CiAgICBfd1t3aV0gPSBuZXcgQXJyYXkoMik7CiAgfQoKICAvLyBtZXNzYWdlIGRpZ2VzdCBvYmplY3QKICB2YXIgbWQgPSB7CiAgICAvLyBTSEEtNTEyID0+IHNoYTUxMgogICAgYWxnb3JpdGhtOiBhbGdvcml0aG0ucmVwbGFjZSgnLScsICcnKS50b0xvd2VyQ2FzZSgpLAogICAgYmxvY2tMZW5ndGg6IDEyOCwKICAgIGRpZ2VzdExlbmd0aDogNjQsCiAgICAvLyA1Ni1iaXQgbGVuZ3RoIG9mIG1lc3NhZ2Ugc28gZmFyIChkb2VzIG5vdCBpbmNsdWRpbmcgcGFkZGluZykKICAgIG1lc3NhZ2VMZW5ndGg6IDAsCiAgICAvLyB0cnVlIG1lc3NhZ2UgbGVuZ3RoCiAgICBmdWxsTWVzc2FnZUxlbmd0aDogbnVsbCwKICAgIC8vIHNpemUgb2YgbWVzc2FnZSBsZW5ndGggaW4gYnl0ZXMKICAgIG1lc3NhZ2VMZW5ndGhTaXplOiAxNgogIH07CgogIC8qKgogICAqIFN0YXJ0cyB0aGUgZGlnZXN0LgogICAqCiAgICogQHJldHVybiB0aGlzIGRpZ2VzdCBvYmplY3QuCiAgICovCiAgbWQuc3RhcnQgPSBmdW5jdGlvbigpIHsKICAgIC8vIHVwIHRvIDU2LWJpdCBtZXNzYWdlIGxlbmd0aCBmb3IgY29udmVuaWVuY2UKICAgIG1kLm1lc3NhZ2VMZW5ndGggPSAwOwoKICAgIC8vIGZ1bGwgbWVzc2FnZSBsZW5ndGggKHNldCBtZC5tZXNzYWdlTGVuZ3RoMTI4IGZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eSkKICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoID0gbWQubWVzc2FnZUxlbmd0aDEyOCA9IFtdOwogICAgdmFyIGludDMycyA9IG1kLm1lc3NhZ2VMZW5ndGhTaXplIC8gNDsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBpbnQzMnM7ICsraSkgewogICAgICBtZC5mdWxsTWVzc2FnZUxlbmd0aC5wdXNoKDApOwogICAgfQogICAgX2lucHV0ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIF9oID0gbmV3IEFycmF5KF9zdGF0ZS5sZW5ndGgpOwogICAgZm9yKHZhciBpID0gMDsgaSA8IF9zdGF0ZS5sZW5ndGg7ICsraSkgewogICAgICBfaFtpXSA9IF9zdGF0ZVtpXS5zbGljZSgwKTsKICAgIH0KICAgIHJldHVybiBtZDsKICB9OwogIC8vIHN0YXJ0IGRpZ2VzdCBhdXRvbWF0aWNhbGx5IGZvciBmaXJzdCB0aW1lCiAgbWQuc3RhcnQoKTsKCiAgLyoqCiAgICogVXBkYXRlcyB0aGUgZGlnZXN0IHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UgaW5wdXQuIFRoZSBnaXZlbiBpbnB1dCBjYW4KICAgKiB0cmVhdGVkIGFzIHJhdyBpbnB1dCAobm8gZW5jb2Rpbmcgd2lsbCBiZSBhcHBsaWVkKSBvciBhbiBlbmNvZGluZyBvZgogICAqICd1dGY4JyBtYXliZSBnaXZlbiB0byBlbmNvZGUgdGhlIGlucHV0IHVzaW5nIFVURi04LgogICAqCiAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSBpbnB1dCB0byB1cGRhdGUgd2l0aC4KICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGVuY29kaW5nIHRvIHVzZSAoZGVmYXVsdDogJ3JhdycsIG90aGVyOiAndXRmOCcpLgogICAqCiAgICogQHJldHVybiB0aGlzIGRpZ2VzdCBvYmplY3QuCiAgICovCiAgbWQudXBkYXRlID0gZnVuY3Rpb24obXNnLCBlbmNvZGluZykgewogICAgaWYoZW5jb2RpbmcgPT09ICd1dGY4JykgewogICAgICBtc2cgPSBmb3JnZS51dGlsLmVuY29kZVV0ZjgobXNnKTsKICAgIH0KCiAgICAvLyB1cGRhdGUgbWVzc2FnZSBsZW5ndGgKICAgIHZhciBsZW4gPSBtc2cubGVuZ3RoOwogICAgbWQubWVzc2FnZUxlbmd0aCArPSBsZW47CiAgICBsZW4gPSBbKGxlbiAvIDB4MTAwMDAwMDAwKSA+Pj4gMCwgbGVuID4+PiAwXTsKICAgIGZvcih2YXIgaSA9IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7CiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldICs9IGxlblsxXTsKICAgICAgbGVuWzFdID0gbGVuWzBdICsgKChtZC5mdWxsTWVzc2FnZUxlbmd0aFtpXSAvIDB4MTAwMDAwMDAwKSA+Pj4gMCk7CiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gPj4+IDA7CiAgICAgIGxlblswXSA9ICgobGVuWzFdIC8gMHgxMDAwMDAwMDApID4+PiAwKTsKICAgIH0KCiAgICAvLyBhZGQgYnl0ZXMgdG8gaW5wdXQgYnVmZmVyCiAgICBfaW5wdXQucHV0Qnl0ZXMobXNnKTsKCiAgICAvLyBwcm9jZXNzIGJ5dGVzCiAgICBfdXBkYXRlKF9oLCBfdywgX2lucHV0KTsKCiAgICAvLyBjb21wYWN0IGlucHV0IGJ1ZmZlciBldmVyeSAySyBvciBpZiBlbXB0eQogICAgaWYoX2lucHV0LnJlYWQgPiAyMDQ4IHx8IF9pbnB1dC5sZW5ndGgoKSA9PT0gMCkgewogICAgICBfaW5wdXQuY29tcGFjdCgpOwogICAgfQoKICAgIHJldHVybiBtZDsKICB9OwoKICAvKioKICAgKiBQcm9kdWNlcyB0aGUgZGlnZXN0LgogICAqCiAgICogQHJldHVybiBhIGJ5dGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIGRpZ2VzdCB2YWx1ZS4KICAgKi8KICBtZC5kaWdlc3QgPSBmdW5jdGlvbigpIHsKICAgIC8qIE5vdGU6IEhlcmUgd2UgY29weSB0aGUgcmVtYWluaW5nIGJ5dGVzIGluIHRoZSBpbnB1dCBidWZmZXIgYW5kCiAgICBhZGQgdGhlIGFwcHJvcHJpYXRlIFNIQS01MTIgcGFkZGluZy4gVGhlbiB3ZSBkbyB0aGUgZmluYWwgdXBkYXRlCiAgICBvbiBhIGNvcHkgb2YgdGhlIHN0YXRlIHNvIHRoYXQgaWYgdGhlIHVzZXIgd2FudHMgdG8gZ2V0CiAgICBpbnRlcm1lZGlhdGUgZGlnZXN0cyB0aGV5IGNhbiBkbyBzby4gKi8KCiAgICAvKiBEZXRlcm1pbmUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IG11c3QgYmUgYWRkZWQgdG8gdGhlIG1lc3NhZ2UKICAgIHRvIGVuc3VyZSBpdHMgbGVuZ3RoIGlzIGNvbmdydWVudCB0byA4OTYgbW9kIDEwMjQuIEluIG90aGVyIHdvcmRzLAogICAgdGhlIGRhdGEgdG8gYmUgZGlnZXN0ZWQgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDEwMjQgYml0cyAob3IgMTI4IGJ5dGVzKS4KICAgIFRoaXMgZGF0YSBpbmNsdWRlcyB0aGUgbWVzc2FnZSwgc29tZSBwYWRkaW5nLCBhbmQgdGhlIGxlbmd0aCBvZiB0aGUKICAgIG1lc3NhZ2UuIFNpbmNlIHRoZSBsZW5ndGggb2YgdGhlIG1lc3NhZ2Ugd2lsbCBiZSBlbmNvZGVkIGFzIDE2IGJ5dGVzICgxMjgKICAgIGJpdHMpLCB0aGF0IG1lYW5zIHRoYXQgdGhlIGxhc3Qgc2VnbWVudCBvZiB0aGUgZGF0YSBtdXN0IGhhdmUgMTEyIGJ5dGVzCiAgICAoODk2IGJpdHMpIG9mIG1lc3NhZ2UgYW5kIHBhZGRpbmcuIFRoZXJlZm9yZSwgdGhlIGxlbmd0aCBvZiB0aGUgbWVzc2FnZQogICAgcGx1cyB0aGUgcGFkZGluZyBtdXN0IGJlIGNvbmdydWVudCB0byA4OTYgbW9kIDEwMjQgYmVjYXVzZQogICAgMTAyNCAtIDEyOCA9IDg5Ni4KCiAgICBJbiBvcmRlciB0byBmaWxsIHVwIHRoZSBtZXNzYWdlIGxlbmd0aCBpdCBtdXN0IGJlIGZpbGxlZCB3aXRoCiAgICBwYWRkaW5nIHRoYXQgYmVnaW5zIHdpdGggMSBiaXQgZm9sbG93ZWQgYnkgYWxsIDAgYml0cy4gUGFkZGluZwogICAgbXVzdCAqYWx3YXlzKiBiZSBwcmVzZW50LCBzbyBpZiB0aGUgbWVzc2FnZSBsZW5ndGggaXMgYWxyZWFkeQogICAgY29uZ3J1ZW50IHRvIDg5NiBtb2QgMTAyNCwgdGhlbiAxMDI0IHBhZGRpbmcgYml0cyBtdXN0IGJlIGFkZGVkLiAqLwoKICAgIHZhciBmaW5hbEJsb2NrID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIGZpbmFsQmxvY2sucHV0Qnl0ZXMoX2lucHV0LmJ5dGVzKCkpOwoKICAgIC8vIGNvbXB1dGUgcmVtYWluaW5nIHNpemUgdG8gYmUgZGlnZXN0ZWQgKGluY2x1ZGUgbWVzc2FnZSBsZW5ndGggc2l6ZSkKICAgIHZhciByZW1haW5pbmcgPSAoCiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW21kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aCAtIDFdICsKICAgICAgbWQubWVzc2FnZUxlbmd0aFNpemUpOwoKICAgIC8vIGFkZCBwYWRkaW5nIGZvciBvdmVyZmxvdyBibG9ja1NpemUgLSBvdmVyZmxvdwogICAgLy8gX3BhZGRpbmcgc3RhcnRzIHdpdGggMSBieXRlIHdpdGggZmlyc3QgYml0IGlzIHNldCAoYnl0ZSB2YWx1ZSAxMjgpLCB0aGVuCiAgICAvLyB0aGVyZSBtYXkgYmUgdXAgdG8gKGJsb2NrU2l6ZSAtIDEpIG90aGVyIHBhZCBieXRlcwogICAgdmFyIG92ZXJmbG93ID0gcmVtYWluaW5nICYgKG1kLmJsb2NrTGVuZ3RoIC0gMSk7CiAgICBmaW5hbEJsb2NrLnB1dEJ5dGVzKF9wYWRkaW5nLnN1YnN0cigwLCBtZC5ibG9ja0xlbmd0aCAtIG92ZXJmbG93KSk7CgogICAgLy8gc2VyaWFsaXplIG1lc3NhZ2UgbGVuZ3RoIGluIGJpdHMgaW4gYmlnLWVuZGlhbiBvcmRlcjsgc2luY2UgbGVuZ3RoCiAgICAvLyBpcyBzdG9yZWQgaW4gYnl0ZXMgd2UgbXVsdGlwbHkgYnkgOCBhbmQgYWRkIGNhcnJ5IGZyb20gbmV4dCBpbnQKICAgIHZhciBtZXNzYWdlTGVuZ3RoID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIHZhciBuZXh0LCBjYXJyeTsKICAgIHZhciBiaXRzID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbMF0gKiA4OwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aDsgKytpKSB7CiAgICAgIG5leHQgPSBtZC5mdWxsTWVzc2FnZUxlbmd0aFtpICsgMV0gKiA4OwogICAgICBjYXJyeSA9IChuZXh0IC8gMHgxMDAwMDAwMDApID4+PiAwOwogICAgICBiaXRzICs9IGNhcnJ5OwogICAgICBmaW5hbEJsb2NrLnB1dEludDMyKGJpdHMgPj4+IDApOwogICAgICBiaXRzID0gbmV4dDsKICAgIH0KCiAgICB2YXIgaCA9IG5ldyBBcnJheShfaC5sZW5ndGgpOwogICAgZm9yKHZhciBpID0gMDsgaSA8IF9oLmxlbmd0aDsgKytpKSB7CiAgICAgIGhbaV0gPSBfaFtpXS5zbGljZSgwKTsKICAgIH0KICAgIF91cGRhdGUoaCwgX3csIGZpbmFsQmxvY2spOwogICAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgdmFyIGhsZW47CiAgICBpZihhbGdvcml0aG0gPT09ICdTSEEtNTEyJykgewogICAgICBobGVuID0gaC5sZW5ndGg7CiAgICB9IGVsc2UgaWYoYWxnb3JpdGhtID09PSAnU0hBLTM4NCcpIHsKICAgICAgaGxlbiA9IGgubGVuZ3RoIC0gMjsKICAgIH0gZWxzZSB7CiAgICAgIGhsZW4gPSBoLmxlbmd0aCAtIDQ7CiAgICB9CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgaGxlbjsgKytpKSB7CiAgICAgIHJ2YWwucHV0SW50MzIoaFtpXVswXSk7CiAgICAgIGlmKGkgIT09IGhsZW4gLSAxIHx8IGFsZ29yaXRobSAhPT0gJ1NIQS01MTIvMjI0JykgewogICAgICAgIHJ2YWwucHV0SW50MzIoaFtpXVsxXSk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBydmFsOwogIH07CgogIHJldHVybiBtZDsKfTsKCi8vIHNoYS01MTIgcGFkZGluZyBieXRlcyBub3QgaW5pdGlhbGl6ZWQgeWV0CnZhciBfcGFkZGluZyA9IG51bGw7CnZhciBfaW5pdGlhbGl6ZWQgPSBmYWxzZTsKCi8vIHRhYmxlIG9mIGNvbnN0YW50cwp2YXIgX2sgPSBudWxsOwoKLy8gaW5pdGlhbCBoYXNoIHN0YXRlcwp2YXIgX3N0YXRlcyA9IG51bGw7CgovKioKICogSW5pdGlhbGl6ZXMgdGhlIGNvbnN0YW50IHRhYmxlcy4KICovCmZ1bmN0aW9uIF9pbml0KCkgewogIC8vIGNyZWF0ZSBwYWRkaW5nCiAgX3BhZGRpbmcgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDEyOCk7CiAgX3BhZGRpbmcgKz0gZm9yZ2UudXRpbC5maWxsU3RyaW5nKFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwMCksIDEyOCk7CgogIC8vIGNyZWF0ZSBLIHRhYmxlIGZvciBTSEEtNTEyCiAgX2sgPSBbCiAgICBbMHg0MjhhMmY5OCwgMHhkNzI4YWUyMl0sIFsweDcxMzc0NDkxLCAweDIzZWY2NWNkXSwKICAgIFsweGI1YzBmYmNmLCAweGVjNGQzYjJmXSwgWzB4ZTliNWRiYTUsIDB4ODE4OWRiYmNdLAogICAgWzB4Mzk1NmMyNWIsIDB4ZjM0OGI1MzhdLCBbMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOV0sCiAgICBbMHg5MjNmODJhNCwgMHhhZjE5NGY5Yl0sIFsweGFiMWM1ZWQ1LCAweGRhNmQ4MTE4XSwKICAgIFsweGQ4MDdhYTk4LCAweGEzMDMwMjQyXSwgWzB4MTI4MzViMDEsIDB4NDU3MDZmYmVdLAogICAgWzB4MjQzMTg1YmUsIDB4NGVlNGIyOGNdLCBbMHg1NTBjN2RjMywgMHhkNWZmYjRlMl0sCiAgICBbMHg3MmJlNWQ3NCwgMHhmMjdiODk2Zl0sIFsweDgwZGViMWZlLCAweDNiMTY5NmIxXSwKICAgIFsweDliZGMwNmE3LCAweDI1YzcxMjM1XSwgWzB4YzE5YmYxNzQsIDB4Y2Y2OTI2OTRdLAogICAgWzB4ZTQ5YjY5YzEsIDB4OWVmMTRhZDJdLCBbMHhlZmJlNDc4NiwgMHgzODRmMjVlM10sCiAgICBbMHgwZmMxOWRjNiwgMHg4YjhjZDViNV0sIFsweDI0MGNhMWNjLCAweDc3YWM5YzY1XSwKICAgIFsweDJkZTkyYzZmLCAweDU5MmIwMjc1XSwgWzB4NGE3NDg0YWEsIDB4NmVhNmU0ODNdLAogICAgWzB4NWNiMGE5ZGMsIDB4YmQ0MWZiZDRdLCBbMHg3NmY5ODhkYSwgMHg4MzExNTNiNV0sCiAgICBbMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYl0sIFsweGE4MzFjNjZkLCAweDJkYjQzMjEwXSwKICAgIFsweGIwMDMyN2M4LCAweDk4ZmIyMTNmXSwgWzB4YmY1OTdmYzcsIDB4YmVlZjBlZTRdLAogICAgWzB4YzZlMDBiZjMsIDB4M2RhODhmYzJdLCBbMHhkNWE3OTE0NywgMHg5MzBhYTcyNV0sCiAgICBbMHgwNmNhNjM1MSwgMHhlMDAzODI2Zl0sIFsweDE0MjkyOTY3LCAweDBhMGU2ZTcwXSwKICAgIFsweDI3YjcwYTg1LCAweDQ2ZDIyZmZjXSwgWzB4MmUxYjIxMzgsIDB4NWMyNmM5MjZdLAogICAgWzB4NGQyYzZkZmMsIDB4NWFjNDJhZWRdLCBbMHg1MzM4MGQxMywgMHg5ZDk1YjNkZl0sCiAgICBbMHg2NTBhNzM1NCwgMHg4YmFmNjNkZV0sIFsweDc2NmEwYWJiLCAweDNjNzdiMmE4XSwKICAgIFsweDgxYzJjOTJlLCAweDQ3ZWRhZWU2XSwgWzB4OTI3MjJjODUsIDB4MTQ4MjM1M2JdLAogICAgWzB4YTJiZmU4YTEsIDB4NGNmMTAzNjRdLCBbMHhhODFhNjY0YiwgMHhiYzQyMzAwMV0sCiAgICBbMHhjMjRiOGI3MCwgMHhkMGY4OTc5MV0sIFsweGM3NmM1MWEzLCAweDA2NTRiZTMwXSwKICAgIFsweGQxOTJlODE5LCAweGQ2ZWY1MjE4XSwgWzB4ZDY5OTA2MjQsIDB4NTU2NWE5MTBdLAogICAgWzB4ZjQwZTM1ODUsIDB4NTc3MTIwMmFdLCBbMHgxMDZhYTA3MCwgMHgzMmJiZDFiOF0sCiAgICBbMHgxOWE0YzExNiwgMHhiOGQyZDBjOF0sIFsweDFlMzc2YzA4LCAweDUxNDFhYjUzXSwKICAgIFsweDI3NDg3NzRjLCAweGRmOGVlYjk5XSwgWzB4MzRiMGJjYjUsIDB4ZTE5YjQ4YThdLAogICAgWzB4MzkxYzBjYjMsIDB4YzVjOTVhNjNdLCBbMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYl0sCiAgICBbMHg1YjljY2E0ZiwgMHg3NzYzZTM3M10sIFsweDY4MmU2ZmYzLCAweGQ2YjJiOGEzXSwKICAgIFsweDc0OGY4MmVlLCAweDVkZWZiMmZjXSwgWzB4NzhhNTYzNmYsIDB4NDMxNzJmNjBdLAogICAgWzB4ODRjODc4MTQsIDB4YTFmMGFiNzJdLCBbMHg4Y2M3MDIwOCwgMHgxYTY0MzllY10sCiAgICBbMHg5MGJlZmZmYSwgMHgyMzYzMWUyOF0sIFsweGE0NTA2Y2ViLCAweGRlODJiZGU5XSwKICAgIFsweGJlZjlhM2Y3LCAweGIyYzY3OTE1XSwgWzB4YzY3MTc4ZjIsIDB4ZTM3MjUzMmJdLAogICAgWzB4Y2EyNzNlY2UsIDB4ZWEyNjYxOWNdLCBbMHhkMTg2YjhjNywgMHgyMWMwYzIwN10sCiAgICBbMHhlYWRhN2RkNiwgMHhjZGUwZWIxZV0sIFsweGY1N2Q0ZjdmLCAweGVlNmVkMTc4XSwKICAgIFsweDA2ZjA2N2FhLCAweDcyMTc2ZmJhXSwgWzB4MGE2MzdkYzUsIDB4YTJjODk4YTZdLAogICAgWzB4MTEzZjk4MDQsIDB4YmVmOTBkYWVdLCBbMHgxYjcxMGIzNSwgMHgxMzFjNDcxYl0sCiAgICBbMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NF0sIFsweDMyY2FhYjdiLCAweDQwYzcyNDkzXSwKICAgIFsweDNjOWViZTBhLCAweDE1YzliZWJjXSwgWzB4NDMxZDY3YzQsIDB4OWMxMDBkNGNdLAogICAgWzB4NGNjNWQ0YmUsIDB4Y2IzZTQyYjZdLCBbMHg1OTdmMjk5YywgMHhmYzY1N2UyYV0sCiAgICBbMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlY10sIFsweDZjNDQxOThjLCAweDRhNDc1ODE3XQogIF07CgogIC8vIGluaXRpYWwgaGFzaCBzdGF0ZXMKICBfc3RhdGVzID0ge307CiAgX3N0YXRlc1snU0hBLTUxMiddID0gWwogICAgWzB4NmEwOWU2NjcsIDB4ZjNiY2M5MDhdLAogICAgWzB4YmI2N2FlODUsIDB4ODRjYWE3M2JdLAogICAgWzB4M2M2ZWYzNzIsIDB4ZmU5NGY4MmJdLAogICAgWzB4YTU0ZmY1M2EsIDB4NWYxZDM2ZjFdLAogICAgWzB4NTEwZTUyN2YsIDB4YWRlNjgyZDFdLAogICAgWzB4OWIwNTY4OGMsIDB4MmIzZTZjMWZdLAogICAgWzB4MWY4M2Q5YWIsIDB4ZmI0MWJkNmJdLAogICAgWzB4NWJlMGNkMTksIDB4MTM3ZTIxNzldCiAgXTsKICBfc3RhdGVzWydTSEEtMzg0J10gPSBbCiAgICBbMHhjYmJiOWQ1ZCwgMHhjMTA1OWVkOF0sCiAgICBbMHg2MjlhMjkyYSwgMHgzNjdjZDUwN10sCiAgICBbMHg5MTU5MDE1YSwgMHgzMDcwZGQxN10sCiAgICBbMHgxNTJmZWNkOCwgMHhmNzBlNTkzOV0sCiAgICBbMHg2NzMzMjY2NywgMHhmZmMwMGIzMV0sCiAgICBbMHg4ZWI0NGE4NywgMHg2ODU4MTUxMV0sCiAgICBbMHhkYjBjMmUwZCwgMHg2NGY5OGZhN10sCiAgICBbMHg0N2I1NDgxZCwgMHhiZWZhNGZhNF0KICBdOwogIF9zdGF0ZXNbJ1NIQS01MTIvMjU2J10gPSBbCiAgICBbMHgyMjMxMjE5NCwgMHhGQzJCRjcyQ10sCiAgICBbMHg5RjU1NUZBMywgMHhDODRDNjRDMl0sCiAgICBbMHgyMzkzQjg2QiwgMHg2RjUzQjE1MV0sCiAgICBbMHg5NjM4NzcxOSwgMHg1OTQwRUFCRF0sCiAgICBbMHg5NjI4M0VFMiwgMHhBODhFRkZFM10sCiAgICBbMHhCRTVFMUUyNSwgMHg1Mzg2Mzk5Ml0sCiAgICBbMHgyQjAxOTlGQywgMHgyQzg1QjhBQV0sCiAgICBbMHgwRUI3MkREQywgMHg4MUM1MkNBMl0KICBdOwogIF9zdGF0ZXNbJ1NIQS01MTIvMjI0J10gPSBbCiAgICBbMHg4QzNEMzdDOCwgMHgxOTU0NERBMl0sCiAgICBbMHg3M0UxOTk2NiwgMHg4OURDRDRENl0sCiAgICBbMHgxREZBQjdBRSwgMHgzMkZGOUM4Ml0sCiAgICBbMHg2NzlERDUxNCwgMHg1ODJGOUZDRl0sCiAgICBbMHgwRjZEMkI2OSwgMHg3QkQ0NERBOF0sCiAgICBbMHg3N0UzNkY3MywgMHgwNEM0ODk0Ml0sCiAgICBbMHgzRjlEODVBOCwgMHg2QTFEMzZDOF0sCiAgICBbMHgxMTEyRTZBRCwgMHg5MUQ2OTJBMV0KICBdOwoKICAvLyBub3cgaW5pdGlhbGl6ZWQKICBfaW5pdGlhbGl6ZWQgPSB0cnVlOwp9CgovKioKICogVXBkYXRlcyBhIFNIQS01MTIgc3RhdGUgd2l0aCB0aGUgZ2l2ZW4gYnl0ZSBidWZmZXIuCiAqCiAqIEBwYXJhbSBzIHRoZSBTSEEtNTEyIHN0YXRlIHRvIHVwZGF0ZS4KICogQHBhcmFtIHcgdGhlIGFycmF5IHRvIHVzZSB0byBzdG9yZSB3b3Jkcy4KICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlIGJ1ZmZlciB0byB1cGRhdGUgd2l0aC4KICovCmZ1bmN0aW9uIF91cGRhdGUocywgdywgYnl0ZXMpIHsKICAvLyBjb25zdW1lIDUxMiBiaXQgKDEyOCBieXRlKSBjaHVua3MKICB2YXIgdDFfaGksIHQxX2xvOwogIHZhciB0Ml9oaSwgdDJfbG87CiAgdmFyIHMwX2hpLCBzMF9sbzsKICB2YXIgczFfaGksIHMxX2xvOwogIHZhciBjaF9oaSwgY2hfbG87CiAgdmFyIG1hal9oaSwgbWFqX2xvOwogIHZhciBhX2hpLCBhX2xvOwogIHZhciBiX2hpLCBiX2xvOwogIHZhciBjX2hpLCBjX2xvOwogIHZhciBkX2hpLCBkX2xvOwogIHZhciBlX2hpLCBlX2xvOwogIHZhciBmX2hpLCBmX2xvOwogIHZhciBnX2hpLCBnX2xvOwogIHZhciBoX2hpLCBoX2xvOwogIHZhciBpLCBoaSwgbG8sIHcyLCB3NywgdzE1LCB3MTY7CiAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aCgpOwogIHdoaWxlKGxlbiA+PSAxMjgpIHsKICAgIC8vIHRoZSB3IGFycmF5IHdpbGwgYmUgcG9wdWxhdGVkIHdpdGggc2l4dGVlbiA2NC1iaXQgYmlnLWVuZGlhbiB3b3JkcwogICAgLy8gYW5kIHRoZW4gZXh0ZW5kZWQgaW50byA2NCA2NC1iaXQgd29yZHMgYWNjb3JkaW5nIHRvIFNIQS01MTIKICAgIGZvcihpID0gMDsgaSA8IDE2OyArK2kpIHsKICAgICAgd1tpXVswXSA9IGJ5dGVzLmdldEludDMyKCkgPj4+IDA7CiAgICAgIHdbaV1bMV0gPSBieXRlcy5nZXRJbnQzMigpID4+PiAwOwogICAgfQogICAgZm9yKDsgaSA8IDgwOyArK2kpIHsKICAgICAgLy8gZm9yIHdvcmQgMiB3b3JkcyBhZ286IFJPVFIgMTkoeCkgXiBST1RSIDYxKHgpIF4gU0hSIDYoeCkKICAgICAgdzIgPSB3W2kgLSAyXTsKICAgICAgaGkgPSB3MlswXTsKICAgICAgbG8gPSB3MlsxXTsKCiAgICAgIC8vIGhpZ2ggYml0cwogICAgICB0MV9oaSA9ICgKICAgICAgICAoKGhpID4+PiAxOSkgfCAobG8gPDwgMTMpKSBeIC8vIFJPVFIgMTkKICAgICAgICAoKGxvID4+PiAyOSkgfCAoaGkgPDwgMykpIF4gLy8gUk9UUiA2MS8oc3dhcCArIFJPVFIgMjkpCiAgICAgICAgKGhpID4+PiA2KSkgPj4+IDA7IC8vIFNIUiA2CiAgICAgIC8vIGxvdyBiaXRzCiAgICAgIHQxX2xvID0gKAogICAgICAgICgoaGkgPDwgMTMpIHwgKGxvID4+PiAxOSkpIF4gLy8gUk9UUiAxOQogICAgICAgICgobG8gPDwgMykgfCAoaGkgPj4+IDI5KSkgXiAvLyBST1RSIDYxLyhzd2FwICsgUk9UUiAyOSkKICAgICAgICAoKGhpIDw8IDI2KSB8IChsbyA+Pj4gNikpKSA+Pj4gMDsgLy8gU0hSIDYKCiAgICAgIC8vIGZvciB3b3JkIDE1IHdvcmRzIGFnbzogUk9UUiAxKHgpIF4gUk9UUiA4KHgpIF4gU0hSIDcoeCkKICAgICAgdzE1ID0gd1tpIC0gMTVdOwogICAgICBoaSA9IHcxNVswXTsKICAgICAgbG8gPSB3MTVbMV07CgogICAgICAvLyBoaWdoIGJpdHMKICAgICAgdDJfaGkgPSAoCiAgICAgICAgKChoaSA+Pj4gMSkgfCAobG8gPDwgMzEpKSBeIC8vIFJPVFIgMQogICAgICAgICgoaGkgPj4+IDgpIHwgKGxvIDw8IDI0KSkgXiAvLyBST1RSIDgKICAgICAgICAoaGkgPj4+IDcpKSA+Pj4gMDsgLy8gU0hSIDcKICAgICAgLy8gbG93IGJpdHMKICAgICAgdDJfbG8gPSAoCiAgICAgICAgKChoaSA8PCAzMSkgfCAobG8gPj4+IDEpKSBeIC8vIFJPVFIgMQogICAgICAgICgoaGkgPDwgMjQpIHwgKGxvID4+PiA4KSkgXiAvLyBST1RSIDgKICAgICAgICAoKGhpIDw8IDI1KSB8IChsbyA+Pj4gNykpKSA+Pj4gMDsgLy8gU0hSIDcKCiAgICAgIC8vIHN1bSh0MSwgd29yZCA3IGFnbywgdDIsIHdvcmQgMTYgYWdvKSBtb2R1bG8gMl42NCAoY2FycnkgbG8gb3ZlcmZsb3cpCiAgICAgIHc3ID0gd1tpIC0gN107CiAgICAgIHcxNiA9IHdbaSAtIDE2XTsKICAgICAgbG8gPSAodDFfbG8gKyB3N1sxXSArIHQyX2xvICsgdzE2WzFdKTsKICAgICAgd1tpXVswXSA9ICh0MV9oaSArIHc3WzBdICsgdDJfaGkgKyB3MTZbMF0gKwogICAgICAgICgobG8gLyAweDEwMDAwMDAwMCkgPj4+IDApKSA+Pj4gMDsKICAgICAgd1tpXVsxXSA9IGxvID4+PiAwOwogICAgfQoKICAgIC8vIGluaXRpYWxpemUgaGFzaCB2YWx1ZSBmb3IgdGhpcyBjaHVuawogICAgYV9oaSA9IHNbMF1bMF07CiAgICBhX2xvID0gc1swXVsxXTsKICAgIGJfaGkgPSBzWzFdWzBdOwogICAgYl9sbyA9IHNbMV1bMV07CiAgICBjX2hpID0gc1syXVswXTsKICAgIGNfbG8gPSBzWzJdWzFdOwogICAgZF9oaSA9IHNbM11bMF07CiAgICBkX2xvID0gc1szXVsxXTsKICAgIGVfaGkgPSBzWzRdWzBdOwogICAgZV9sbyA9IHNbNF1bMV07CiAgICBmX2hpID0gc1s1XVswXTsKICAgIGZfbG8gPSBzWzVdWzFdOwogICAgZ19oaSA9IHNbNl1bMF07CiAgICBnX2xvID0gc1s2XVsxXTsKICAgIGhfaGkgPSBzWzddWzBdOwogICAgaF9sbyA9IHNbN11bMV07CgogICAgLy8gcm91bmQgZnVuY3Rpb24KICAgIGZvcihpID0gMDsgaSA8IDgwOyArK2kpIHsKICAgICAgLy8gU3VtMShlKSA9IFJPVFIgMTQoZSkgXiBST1RSIDE4KGUpIF4gUk9UUiA0MShlKQogICAgICBzMV9oaSA9ICgKICAgICAgICAoKGVfaGkgPj4+IDE0KSB8IChlX2xvIDw8IDE4KSkgXiAvLyBST1RSIDE0CiAgICAgICAgKChlX2hpID4+PiAxOCkgfCAoZV9sbyA8PCAxNCkpIF4gLy8gUk9UUiAxOAogICAgICAgICgoZV9sbyA+Pj4gOSkgfCAoZV9oaSA8PCAyMykpKSA+Pj4gMDsgLy8gUk9UUiA0MS8oc3dhcCArIFJPVFIgOSkKICAgICAgczFfbG8gPSAoCiAgICAgICAgKChlX2hpIDw8IDE4KSB8IChlX2xvID4+PiAxNCkpIF4gLy8gUk9UUiAxNAogICAgICAgICgoZV9oaSA8PCAxNCkgfCAoZV9sbyA+Pj4gMTgpKSBeIC8vIFJPVFIgMTgKICAgICAgICAoKGVfbG8gPDwgMjMpIHwgKGVfaGkgPj4+IDkpKSkgPj4+IDA7IC8vIFJPVFIgNDEvKHN3YXAgKyBST1RSIDkpCgogICAgICAvLyBDaChlLCBmLCBnKSAob3B0aW1pemVkIHRoZSBzYW1lIHdheSBhcyBTSEEtMSkKICAgICAgY2hfaGkgPSAoZ19oaSBeIChlX2hpICYgKGZfaGkgXiBnX2hpKSkpID4+PiAwOwogICAgICBjaF9sbyA9IChnX2xvIF4gKGVfbG8gJiAoZl9sbyBeIGdfbG8pKSkgPj4+IDA7CgogICAgICAvLyBTdW0wKGEpID0gUk9UUiAyOChhKSBeIFJPVFIgMzQoYSkgXiBST1RSIDM5KGEpCiAgICAgIHMwX2hpID0gKAogICAgICAgICgoYV9oaSA+Pj4gMjgpIHwgKGFfbG8gPDwgNCkpIF4gLy8gUk9UUiAyOAogICAgICAgICgoYV9sbyA+Pj4gMikgfCAoYV9oaSA8PCAzMCkpIF4gLy8gUk9UUiAzNC8oc3dhcCArIFJPVFIgMikKICAgICAgICAoKGFfbG8gPj4+IDcpIHwgKGFfaGkgPDwgMjUpKSkgPj4+IDA7IC8vIFJPVFIgMzkvKHN3YXAgKyBST1RSIDcpCiAgICAgIHMwX2xvID0gKAogICAgICAgICgoYV9oaSA8PCA0KSB8IChhX2xvID4+PiAyOCkpIF4gLy8gUk9UUiAyOAogICAgICAgICgoYV9sbyA8PCAzMCkgfCAoYV9oaSA+Pj4gMikpIF4gLy8gUk9UUiAzNC8oc3dhcCArIFJPVFIgMikKICAgICAgICAoKGFfbG8gPDwgMjUpIHwgKGFfaGkgPj4+IDcpKSkgPj4+IDA7IC8vIFJPVFIgMzkvKHN3YXAgKyBST1RSIDcpCgogICAgICAvLyBNYWooYSwgYiwgYykgKG9wdGltaXplZCB0aGUgc2FtZSB3YXkgYXMgU0hBLTEpCiAgICAgIG1hal9oaSA9ICgoYV9oaSAmIGJfaGkpIHwgKGNfaGkgJiAoYV9oaSBeIGJfaGkpKSkgPj4+IDA7CiAgICAgIG1hal9sbyA9ICgoYV9sbyAmIGJfbG8pIHwgKGNfbG8gJiAoYV9sbyBeIGJfbG8pKSkgPj4+IDA7CgogICAgICAvLyBtYWluIGFsZ29yaXRobQogICAgICAvLyB0MSA9IChoICsgczEgKyBjaCArIF9rW2ldICsgX3dbaV0pIG1vZHVsbyAyXjY0IChjYXJyeSBsbyBvdmVyZmxvdykKICAgICAgbG8gPSAoaF9sbyArIHMxX2xvICsgY2hfbG8gKyBfa1tpXVsxXSArIHdbaV1bMV0pOwogICAgICB0MV9oaSA9IChoX2hpICsgczFfaGkgKyBjaF9oaSArIF9rW2ldWzBdICsgd1tpXVswXSArCiAgICAgICAgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgICB0MV9sbyA9IGxvID4+PiAwOwoKICAgICAgLy8gdDIgPSBzMCArIG1haiBtb2R1bG8gMl42NCAoY2FycnkgbG8gb3ZlcmZsb3cpCiAgICAgIGxvID0gczBfbG8gKyBtYWpfbG87CiAgICAgIHQyX2hpID0gKHMwX2hpICsgbWFqX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgICB0Ml9sbyA9IGxvID4+PiAwOwoKICAgICAgaF9oaSA9IGdfaGk7CiAgICAgIGhfbG8gPSBnX2xvOwoKICAgICAgZ19oaSA9IGZfaGk7CiAgICAgIGdfbG8gPSBmX2xvOwoKICAgICAgZl9oaSA9IGVfaGk7CiAgICAgIGZfbG8gPSBlX2xvOwoKICAgICAgLy8gZSA9IChkICsgdDEpIG1vZHVsbyAyXjY0IChjYXJyeSBsbyBvdmVyZmxvdykKICAgICAgbG8gPSBkX2xvICsgdDFfbG87CiAgICAgIGVfaGkgPSAoZF9oaSArIHQxX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgICBlX2xvID0gbG8gPj4+IDA7CgogICAgICBkX2hpID0gY19oaTsKICAgICAgZF9sbyA9IGNfbG87CgogICAgICBjX2hpID0gYl9oaTsKICAgICAgY19sbyA9IGJfbG87CgogICAgICBiX2hpID0gYV9oaTsKICAgICAgYl9sbyA9IGFfbG87CgogICAgICAvLyBhID0gKHQxICsgdDIpIG1vZHVsbyAyXjY0IChjYXJyeSBsbyBvdmVyZmxvdykKICAgICAgbG8gPSB0MV9sbyArIHQyX2xvOwogICAgICBhX2hpID0gKHQxX2hpICsgdDJfaGkgKyAoKGxvIC8gMHgxMDAwMDAwMDApID4+PiAwKSkgPj4+IDA7CiAgICAgIGFfbG8gPSBsbyA+Pj4gMDsKICAgIH0KCiAgICAvLyB1cGRhdGUgaGFzaCBzdGF0ZSAoYWRkaXRpb25hbCBtb2R1bG8gMl42NCkKICAgIGxvID0gc1swXVsxXSArIGFfbG87CiAgICBzWzBdWzBdID0gKHNbMF1bMF0gKyBhX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1swXVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1sxXVsxXSArIGJfbG87CiAgICBzWzFdWzBdID0gKHNbMV1bMF0gKyBiX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1sxXVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1syXVsxXSArIGNfbG87CiAgICBzWzJdWzBdID0gKHNbMl1bMF0gKyBjX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1syXVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1szXVsxXSArIGRfbG87CiAgICBzWzNdWzBdID0gKHNbM11bMF0gKyBkX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1szXVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1s0XVsxXSArIGVfbG87CiAgICBzWzRdWzBdID0gKHNbNF1bMF0gKyBlX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1s0XVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1s1XVsxXSArIGZfbG87CiAgICBzWzVdWzBdID0gKHNbNV1bMF0gKyBmX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1s1XVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1s2XVsxXSArIGdfbG87CiAgICBzWzZdWzBdID0gKHNbNl1bMF0gKyBnX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1s2XVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1s3XVsxXSArIGhfbG87CiAgICBzWzddWzBdID0gKHNbN11bMF0gKyBoX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1s3XVsxXSA9IGxvID4+PiAwOwoKICAgIGxlbiAtPSAxMjg7CiAgfQp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdzaGE1MTInOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvc2hhNTEyJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBOb2RlLmpzIG1vZHVsZSBmb3IgRm9yZ2UgbWVzc2FnZSBkaWdlc3RzLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgMjAxMS0yMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKZm9yZ2UubWQgPSBmb3JnZS5tZCB8fCB7fTsKZm9yZ2UubWQuYWxnb3JpdGhtcyA9IHsKICBtZDU6IGZvcmdlLm1kNSwKICBzaGExOiBmb3JnZS5zaGExLAogIHNoYTI1NjogZm9yZ2Uuc2hhMjU2Cn07CmZvcmdlLm1kLm1kNSA9IGZvcmdlLm1kNTsKZm9yZ2UubWQuc2hhMSA9IGZvcmdlLnNoYTE7CmZvcmdlLm1kLnNoYTI1NiA9IGZvcmdlLnNoYTI1NjsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ21kJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoCiAgJ2pzL21kJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vbWQ1JywgJy4vc2hhMScsICcuL3NoYTI1NicsICcuL3NoYTUxMiddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBIYXNoLWJhc2VkIE1lc3NhZ2UgQXV0aGVudGljYXRpb24gQ29kZSBpbXBsZW1lbnRhdGlvbi4gUmVxdWlyZXMgYSBtZXNzYWdlCiAqIGRpZ2VzdCBvYmplY3QgdGhhdCBjYW4gYmUgb2J0YWluZWQsIGZvciBleGFtcGxlLCBmcm9tIGZvcmdlLm1kLnNoYTEgb3IKICogZm9yZ2UubWQubWQ1LgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxMiBEaWdpdGFsIEJhemFhciwgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8qIEhNQUMgQVBJICovCnZhciBobWFjID0gZm9yZ2UuaG1hYyA9IGZvcmdlLmhtYWMgfHwge307CgovKioKICogQ3JlYXRlcyBhbiBITUFDIG9iamVjdCB0aGF0IHVzZXMgdGhlIGdpdmVuIG1lc3NhZ2UgZGlnZXN0IG9iamVjdC4KICoKICogQHJldHVybiBhbiBITUFDIG9iamVjdC4KICovCmhtYWMuY3JlYXRlID0gZnVuY3Rpb24oKSB7CiAgLy8gdGhlIGhtYWMga2V5IHRvIHVzZQogIHZhciBfa2V5ID0gbnVsbDsKCiAgLy8gdGhlIG1lc3NhZ2UgZGlnZXN0IHRvIHVzZQogIHZhciBfbWQgPSBudWxsOwoKICAvLyB0aGUgaW5uZXIgcGFkZGluZwogIHZhciBfaXBhZGRpbmcgPSBudWxsOwoKICAvLyB0aGUgb3V0ZXIgcGFkZGluZwogIHZhciBfb3BhZGRpbmcgPSBudWxsOwoKICAvLyBobWFjIGNvbnRleHQKICB2YXIgY3R4ID0ge307CgogIC8qKgogICAqIFN0YXJ0cyBvciByZXN0YXJ0cyB0aGUgSE1BQyB3aXRoIHRoZSBnaXZlbiBrZXkgYW5kIG1lc3NhZ2UgZGlnZXN0LgogICAqCiAgICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCB0byB1c2UsIG51bGwgdG8gcmV1c2UgdGhlIHByZXZpb3VzIG9uZSwKICAgKiAgICAgICAgICAgYSBzdHJpbmcgdG8gdXNlIGJ1aWx0aW4gJ3NoYTEnLCAnbWQ1JywgJ3NoYTI1NicuCiAgICogQHBhcmFtIGtleSB0aGUga2V5IHRvIHVzZSBhcyBhIHN0cmluZywgYXJyYXkgb2YgYnl0ZXMsIGJ5dGUgYnVmZmVyLAogICAqICAgICAgICAgICBvciBudWxsIHRvIHJldXNlIHRoZSBwcmV2aW91cyBrZXkuCiAgICovCiAgY3R4LnN0YXJ0ID0gZnVuY3Rpb24obWQsIGtleSkgewogICAgaWYobWQgIT09IG51bGwpIHsKICAgICAgaWYodHlwZW9mIG1kID09PSAnc3RyaW5nJykgewogICAgICAgIC8vIGNyZWF0ZSBidWlsdGluIG1lc3NhZ2UgZGlnZXN0CiAgICAgICAgbWQgPSBtZC50b0xvd2VyQ2FzZSgpOwogICAgICAgIGlmKG1kIGluIGZvcmdlLm1kLmFsZ29yaXRobXMpIHsKICAgICAgICAgIF9tZCA9IGZvcmdlLm1kLmFsZ29yaXRobXNbbWRdLmNyZWF0ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gaGFzaCBhbGdvcml0aG0gIicgKyBtZCArICciJyk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIC8vIHN0b3JlIG1lc3NhZ2UgZGlnZXN0CiAgICAgICAgX21kID0gbWQ7CiAgICAgIH0KICAgIH0KCiAgICBpZihrZXkgPT09IG51bGwpIHsKICAgICAgLy8gcmV1c2UgcHJldmlvdXMga2V5CiAgICAgIGtleSA9IF9rZXk7CiAgICB9IGVsc2UgewogICAgICBpZih0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykgewogICAgICAgIC8vIGNvbnZlcnQgc3RyaW5nIGludG8gYnl0ZSBidWZmZXIKICAgICAgICBrZXkgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihrZXkpOwogICAgICB9IGVsc2UgaWYoZm9yZ2UudXRpbC5pc0FycmF5KGtleSkpIHsKICAgICAgICAvLyBjb252ZXJ0IGJ5dGUgYXJyYXkgaW50byBieXRlIGJ1ZmZlcgogICAgICAgIHZhciB0bXAgPSBrZXk7CiAgICAgICAga2V5ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdG1wLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICBrZXkucHV0Qnl0ZSh0bXBbaV0pOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gaWYga2V5IGlzIGxvbmdlciB0aGFuIGJsb2Nrc2l6ZSwgaGFzaCBpdAogICAgICB2YXIga2V5bGVuID0ga2V5Lmxlbmd0aCgpOwogICAgICBpZihrZXlsZW4gPiBfbWQuYmxvY2tMZW5ndGgpIHsKICAgICAgICBfbWQuc3RhcnQoKTsKICAgICAgICBfbWQudXBkYXRlKGtleS5ieXRlcygpKTsKICAgICAgICBrZXkgPSBfbWQuZGlnZXN0KCk7CiAgICAgIH0KCiAgICAgIC8vIG1peCBrZXkgaW50byBpbm5lciBhbmQgb3V0ZXIgcGFkZGluZwogICAgICAvLyBpcGFkZGluZyA9IFsweDM2ICogYmxvY2tzaXplXSBeIGtleQogICAgICAvLyBvcGFkZGluZyA9IFsweDVDICogYmxvY2tzaXplXSBeIGtleQogICAgICBfaXBhZGRpbmcgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgICBfb3BhZGRpbmcgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgICBrZXlsZW4gPSBrZXkubGVuZ3RoKCk7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBrZXlsZW47ICsraSkgewogICAgICAgIHZhciB0bXAgPSBrZXkuYXQoaSk7CiAgICAgICAgX2lwYWRkaW5nLnB1dEJ5dGUoMHgzNiBeIHRtcCk7CiAgICAgICAgX29wYWRkaW5nLnB1dEJ5dGUoMHg1QyBeIHRtcCk7CiAgICAgIH0KCiAgICAgIC8vIGlmIGtleSBpcyBzaG9ydGVyIHRoYW4gYmxvY2tzaXplLCBhZGQgYWRkaXRpb25hbCBwYWRkaW5nCiAgICAgIGlmKGtleWxlbiA8IF9tZC5ibG9ja0xlbmd0aCkgewogICAgICAgIHZhciB0bXAgPSBfbWQuYmxvY2tMZW5ndGggLSBrZXlsZW47CiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHRtcDsgKytpKSB7CiAgICAgICAgICBfaXBhZGRpbmcucHV0Qnl0ZSgweDM2KTsKICAgICAgICAgIF9vcGFkZGluZy5wdXRCeXRlKDB4NUMpOwogICAgICAgIH0KICAgICAgfQogICAgICBfa2V5ID0ga2V5OwogICAgICBfaXBhZGRpbmcgPSBfaXBhZGRpbmcuYnl0ZXMoKTsKICAgICAgX29wYWRkaW5nID0gX29wYWRkaW5nLmJ5dGVzKCk7CiAgICB9CgogICAgLy8gZGlnZXN0IGlzIGRvbmUgbGlrZSBzbzogaGFzaChvcGFkZGluZyB8IGhhc2goaXBhZGRpbmcgfCBtZXNzYWdlKSkKCiAgICAvLyBwcmVwYXJlIHRvIGRvIGlubmVyIGhhc2gKICAgIC8vIGhhc2goaXBhZGRpbmcgfCBtZXNzYWdlKQogICAgX21kLnN0YXJ0KCk7CiAgICBfbWQudXBkYXRlKF9pcGFkZGluZyk7CiAgfTsKCiAgLyoqCiAgICogVXBkYXRlcyB0aGUgSE1BQyB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlIGJ5dGVzLgogICAqCiAgICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyB0byB1cGRhdGUgd2l0aC4KICAgKi8KICBjdHgudXBkYXRlID0gZnVuY3Rpb24oYnl0ZXMpIHsKICAgIF9tZC51cGRhdGUoYnl0ZXMpOwogIH07CgogIC8qKgogICAqIFByb2R1Y2VzIHRoZSBNZXNzYWdlIEF1dGhlbnRpY2F0aW9uIENvZGUgKE1BQykuCiAgICoKICAgKiBAcmV0dXJuIGEgYnl0ZSBidWZmZXIgY29udGFpbmluZyB0aGUgZGlnZXN0IHZhbHVlLgogICAqLwogIGN0eC5nZXRNYWMgPSBmdW5jdGlvbigpIHsKICAgIC8vIGRpZ2VzdCBpcyBkb25lIGxpa2Ugc286IGhhc2gob3BhZGRpbmcgfCBoYXNoKGlwYWRkaW5nIHwgbWVzc2FnZSkpCiAgICAvLyBoZXJlIHdlIGRvIHRoZSBvdXRlciBoYXNoaW5nCiAgICB2YXIgaW5uZXIgPSBfbWQuZGlnZXN0KCkuYnl0ZXMoKTsKICAgIF9tZC5zdGFydCgpOwogICAgX21kLnVwZGF0ZShfb3BhZGRpbmcpOwogICAgX21kLnVwZGF0ZShpbm5lcik7CiAgICByZXR1cm4gX21kLmRpZ2VzdCgpOwogIH07CiAgLy8gYWxpYXMgZm9yIGdldE1hYwogIGN0eC5kaWdlc3QgPSBjdHguZ2V0TWFjOwoKICByZXR1cm4gY3R4Owp9OwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAnaG1hYyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9obWFjJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vbWQnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIEphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgYmFzaWMgUEVNIChQcml2YWN5IEVuaGFuY2VkIE1haWwpIGFsZ29yaXRobXMuCiAqCiAqIFNlZTogUkZDIDE0MjEuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqCiAqIEEgRm9yZ2UgUEVNIG9iamVjdCBoYXMgdGhlIGZvbGxvd2luZyBmaWVsZHM6CiAqCiAqIHR5cGU6IGlkZW50aWZpZXMgdGhlIHR5cGUgb2YgbWVzc2FnZSAoZWc6ICJSU0EgUFJJVkFURSBLRVkiKS4KICoKICogcHJvY1R5cGU6IGlkZW50aWZpZXMgdGhlIHR5cGUgb2YgcHJvY2Vzc2luZyBwZXJmb3JtZWQgb24gdGhlIG1lc3NhZ2UsCiAqICAgaXQgaGFzIHR3byBzdWJmaWVsZHM6IHZlcnNpb24gYW5kIHR5cGUsIGVnOiA0LEVOQ1JZUFRFRC4KICoKICogY29udGVudERvbWFpbjogaWRlbnRpZmllcyB0aGUgdHlwZSBvZiBjb250ZW50IGluIHRoZSBtZXNzYWdlLCB0eXBpY2FsbHkKICogICBvbmx5IHVzZXMgdGhlIHZhbHVlOiAiUkZDODIyIi4KICoKICogZGVrSW5mbzogaWRlbnRpZmllcyB0aGUgbWVzc2FnZSBlbmNyeXB0aW9uIGFsZ29yaXRobSBhbmQgbW9kZSBhbmQgaW5jbHVkZXMKICogICBhbnkgcGFyYW1ldGVycyBmb3IgdGhlIGFsZ29yaXRobSwgaXQgaGFzIHR3byBzdWJmaWVsZHM6IGFsZ29yaXRobSBhbmQKICogICBwYXJhbWV0ZXJzLCBlZzogREVTLUNCQyxGODE0M0VERTU5NjBDNTk3LgogKgogKiBoZWFkZXJzOiBjb250YWlucyBhbGwgb3RoZXIgUEVNIGVuY2Fwc3VsYXRlZCBoZWFkZXJzIC0tIHdoZXJlIG9yZGVyIGlzCiAqICAgc2lnbmlmaWNhbnQgKGZvciBwYWlyaW5nIGRhdGEgbGlrZSByZWNpcGllbnQgSUQgKyBrZXkgaW5mbykuCiAqCiAqIGJvZHk6IHRoZSBiaW5hcnktZW5jb2RlZCBib2R5LgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8vIHNob3J0Y3V0IGZvciBwZW0gQVBJCnZhciBwZW0gPSBmb3JnZS5wZW0gPSBmb3JnZS5wZW0gfHwge307CgovKioKICogRW5jb2RlcyAoc2VyaWFsaXplcykgdGhlIGdpdmVuIFBFTSBvYmplY3QuCiAqCiAqIEBwYXJhbSBtc2cgdGhlIFBFTSBtZXNzYWdlIG9iamVjdCB0byBlbmNvZGUuCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgbWF4bGluZSB0aGUgbWF4aW11bSBjaGFyYWN0ZXJzIHBlciBsaW5lIGZvciB0aGUgYm9keSwgKGRlZmF1bHQ6IDY0KS4KICoKICogQHJldHVybiB0aGUgUEVNLWZvcm1hdHRlZCBzdHJpbmcuCiAqLwpwZW0uZW5jb2RlID0gZnVuY3Rpb24obXNnLCBvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdmFyIHJ2YWwgPSAnLS0tLS1CRUdJTiAnICsgbXNnLnR5cGUgKyAnLS0tLS1cclxuJzsKCiAgLy8gZW5jb2RlIHNwZWNpYWwgaGVhZGVycwogIHZhciBoZWFkZXI7CiAgaWYobXNnLnByb2NUeXBlKSB7CiAgICBoZWFkZXIgPSB7CiAgICAgIG5hbWU6ICdQcm9jLVR5cGUnLAogICAgICB2YWx1ZXM6IFtTdHJpbmcobXNnLnByb2NUeXBlLnZlcnNpb24pLCBtc2cucHJvY1R5cGUudHlwZV0KICAgIH07CiAgICBydmFsICs9IGZvbGRIZWFkZXIoaGVhZGVyKTsKICB9CiAgaWYobXNnLmNvbnRlbnREb21haW4pIHsKICAgIGhlYWRlciA9IHtuYW1lOiAnQ29udGVudC1Eb21haW4nLCB2YWx1ZXM6IFttc2cuY29udGVudERvbWFpbl19OwogICAgcnZhbCArPSBmb2xkSGVhZGVyKGhlYWRlcik7CiAgfQogIGlmKG1zZy5kZWtJbmZvKSB7CiAgICBoZWFkZXIgPSB7bmFtZTogJ0RFSy1JbmZvJywgdmFsdWVzOiBbbXNnLmRla0luZm8uYWxnb3JpdGhtXX07CiAgICBpZihtc2cuZGVrSW5mby5wYXJhbWV0ZXJzKSB7CiAgICAgIGhlYWRlci52YWx1ZXMucHVzaChtc2cuZGVrSW5mby5wYXJhbWV0ZXJzKTsKICAgIH0KICAgIHJ2YWwgKz0gZm9sZEhlYWRlcihoZWFkZXIpOwogIH0KCiAgaWYobXNnLmhlYWRlcnMpIHsKICAgIC8vIGVuY29kZSBhbGwgb3RoZXIgaGVhZGVycwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1zZy5oZWFkZXJzLmxlbmd0aDsgKytpKSB7CiAgICAgIHJ2YWwgKz0gZm9sZEhlYWRlcihtc2cuaGVhZGVyc1tpXSk7CiAgICB9CiAgfQoKICAvLyB0ZXJtaW5hdGUgaGVhZGVyCiAgaWYobXNnLnByb2NUeXBlKSB7CiAgICBydmFsICs9ICdcclxuJzsKICB9CgogIC8vIGFkZCBib2R5CiAgcnZhbCArPSBmb3JnZS51dGlsLmVuY29kZTY0KG1zZy5ib2R5LCBvcHRpb25zLm1heGxpbmUgfHwgNjQpICsgJ1xyXG4nOwoKICBydmFsICs9ICctLS0tLUVORCAnICsgbXNnLnR5cGUgKyAnLS0tLS1cclxuJzsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBEZWNvZGVzIChkZXNlcmlhbGl6ZXMpIGFsbCBQRU0gbWVzc2FnZXMgZm91bmQgaW4gdGhlIGdpdmVuIHN0cmluZy4KICoKICogQHBhcmFtIHN0ciB0aGUgUEVNLWZvcm1hdHRlZCBzdHJpbmcgdG8gZGVjb2RlLgogKgogKiBAcmV0dXJuIHRoZSBQRU0gbWVzc2FnZSBvYmplY3RzIGluIGFuIGFycmF5LgogKi8KcGVtLmRlY29kZSA9IGZ1bmN0aW9uKHN0cikgewogIHZhciBydmFsID0gW107CgogIC8vIHNwbGl0IHN0cmluZyBpbnRvIFBFTSBtZXNzYWdlcyAoYmUgbGVuaWVudCB3L0VPRiBvbiBCRUdJTiBsaW5lKQogIHZhciByTWVzc2FnZSA9IC9ccyotLS0tLUJFR0lOIChbQS1aMC05LSBdKyktLS0tLVxyP1xuPyhbXHgyMS1ceDdlXHNdKz8oPzpccj9cblxyP1xuKSk/KFs6QS1aYS16MC05K1wvPVxzXSs/KS0tLS0tRU5EIFwxLS0tLS0vZzsKICB2YXIgckhlYWRlciA9IC8oW1x4MjEtXHg3ZV0rKTpccyooW1x4MjEtXHg3ZVxzXjpdKykvOwogIHZhciByQ1JMRiA9IC9ccj9cbi87CiAgdmFyIG1hdGNoOwogIHdoaWxlKHRydWUpIHsKICAgIG1hdGNoID0gck1lc3NhZ2UuZXhlYyhzdHIpOwogICAgaWYoIW1hdGNoKSB7CiAgICAgIGJyZWFrOwogICAgfQoKICAgIHZhciBtc2cgPSB7CiAgICAgIHR5cGU6IG1hdGNoWzFdLAogICAgICBwcm9jVHlwZTogbnVsbCwKICAgICAgY29udGVudERvbWFpbjogbnVsbCwKICAgICAgZGVrSW5mbzogbnVsbCwKICAgICAgaGVhZGVyczogW10sCiAgICAgIGJvZHk6IGZvcmdlLnV0aWwuZGVjb2RlNjQobWF0Y2hbM10pCiAgICB9OwogICAgcnZhbC5wdXNoKG1zZyk7CgogICAgLy8gbm8gaGVhZGVycwogICAgaWYoIW1hdGNoWzJdKSB7CiAgICAgIGNvbnRpbnVlOwogICAgfQoKICAgIC8vIHBhcnNlIGhlYWRlcnMKICAgIHZhciBsaW5lcyA9IG1hdGNoWzJdLnNwbGl0KHJDUkxGKTsKICAgIHZhciBsaSA9IDA7CiAgICB3aGlsZShtYXRjaCAmJiBsaSA8IGxpbmVzLmxlbmd0aCkgewogICAgICAvLyBnZXQgbGluZSwgdHJpbSBhbnkgcmhzIHdoaXRlc3BhY2UKICAgICAgdmFyIGxpbmUgPSBsaW5lc1tsaV0ucmVwbGFjZSgvXHMrJC8sICcnKTsKCiAgICAgIC8vIFJGQzI4MjIgdW5mb2xkIGFueSBmb2xsb3dpbmcgZm9sZGVkIGxpbmVzCiAgICAgIGZvcih2YXIgbmwgPSBsaSArIDE7IG5sIDwgbGluZXMubGVuZ3RoOyArK25sKSB7CiAgICAgICAgdmFyIG5leHQgPSBsaW5lc1tubF07CiAgICAgICAgaWYoIS9ccy8udGVzdChuZXh0WzBdKSkgewogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGxpbmUgKz0gbmV4dDsKICAgICAgICBsaSA9IG5sOwogICAgICB9CgogICAgICAvLyBwYXJzZSBoZWFkZXIKICAgICAgbWF0Y2ggPSBsaW5lLm1hdGNoKHJIZWFkZXIpOwogICAgICBpZihtYXRjaCkgewogICAgICAgIHZhciBoZWFkZXIgPSB7bmFtZTogbWF0Y2hbMV0sIHZhbHVlczogW119OwogICAgICAgIHZhciB2YWx1ZXMgPSBtYXRjaFsyXS5zcGxpdCgnLCcpOwogICAgICAgIGZvcih2YXIgdmkgPSAwOyB2aSA8IHZhbHVlcy5sZW5ndGg7ICsrdmkpIHsKICAgICAgICAgIGhlYWRlci52YWx1ZXMucHVzaChsdHJpbSh2YWx1ZXNbdmldKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBQcm9jLVR5cGUgbXVzdCBiZSB0aGUgZmlyc3QgaGVhZGVyCiAgICAgICAgaWYoIW1zZy5wcm9jVHlwZSkgewogICAgICAgICAgaWYoaGVhZGVyLm5hbWUgIT09ICdQcm9jLVR5cGUnKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBQRU0gZm9ybWF0dGVkIG1lc3NhZ2UuIFRoZSBmaXJzdCAnICsKICAgICAgICAgICAgICAnZW5jYXBzdWxhdGVkIGhlYWRlciBtdXN0IGJlICJQcm9jLVR5cGUiLicpOwogICAgICAgICAgfSBlbHNlIGlmKGhlYWRlci52YWx1ZXMubGVuZ3RoICE9PSAyKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBQRU0gZm9ybWF0dGVkIG1lc3NhZ2UuIFRoZSAiUHJvYy1UeXBlIiAnICsKICAgICAgICAgICAgICAnaGVhZGVyIG11c3QgaGF2ZSB0d28gc3ViZmllbGRzLicpOwogICAgICAgICAgfQogICAgICAgICAgbXNnLnByb2NUeXBlID0ge3ZlcnNpb246IHZhbHVlc1swXSwgdHlwZTogdmFsdWVzWzFdfTsKICAgICAgICB9IGVsc2UgaWYoIW1zZy5jb250ZW50RG9tYWluICYmIGhlYWRlci5uYW1lID09PSAnQ29udGVudC1Eb21haW4nKSB7CiAgICAgICAgICAvLyBzcGVjaWFsLWNhc2UgQ29udGVudC1Eb21haW4KICAgICAgICAgIG1zZy5jb250ZW50RG9tYWluID0gdmFsdWVzWzBdIHx8ICcnOwogICAgICAgIH0gZWxzZSBpZighbXNnLmRla0luZm8gJiYgaGVhZGVyLm5hbWUgPT09ICdERUstSW5mbycpIHsKICAgICAgICAgIC8vIHNwZWNpYWwtY2FzZSBERUstSW5mbwogICAgICAgICAgaWYoaGVhZGVyLnZhbHVlcy5sZW5ndGggPT09IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIFBFTSBmb3JtYXR0ZWQgbWVzc2FnZS4gVGhlICJERUstSW5mbyIgJyArCiAgICAgICAgICAgICAgJ2hlYWRlciBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIHN1YmZpZWxkLicpOwogICAgICAgICAgfQogICAgICAgICAgbXNnLmRla0luZm8gPSB7YWxnb3JpdGhtOiB2YWx1ZXNbMF0sIHBhcmFtZXRlcnM6IHZhbHVlc1sxXSB8fCBudWxsfTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbXNnLmhlYWRlcnMucHVzaChoZWFkZXIpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgKytsaTsKICAgIH0KCiAgICBpZihtc2cucHJvY1R5cGUgPT09ICdFTkNSWVBURUQnICYmICFtc2cuZGVrSW5mbykgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgUEVNIGZvcm1hdHRlZCBtZXNzYWdlLiBUaGUgIkRFSy1JbmZvIiAnICsKICAgICAgICAnaGVhZGVyIG11c3QgYmUgcHJlc2VudCBpZiAiUHJvYy1UeXBlIiBpcyAiRU5DUllQVEVEIi4nKTsKICAgIH0KICB9CgogIGlmKHJ2YWwubGVuZ3RoID09PSAwKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgUEVNIGZvcm1hdHRlZCBtZXNzYWdlLicpOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgpmdW5jdGlvbiBmb2xkSGVhZGVyKGhlYWRlcikgewogIHZhciBydmFsID0gaGVhZGVyLm5hbWUgKyAnOiAnOwoKICAvLyBlbnN1cmUgdmFsdWVzIHdpdGggQ1JMRiBhcmUgZm9sZGVkCiAgdmFyIHZhbHVlcyA9IFtdOwogIHZhciBpbnNlcnRTcGFjZSA9IGZ1bmN0aW9uKG1hdGNoLCAkMSkgewogICAgcmV0dXJuICcgJyArICQxOwogIH07CiAgZm9yKHZhciBpID0gMDsgaSA8IGhlYWRlci52YWx1ZXMubGVuZ3RoOyArK2kpIHsKICAgIHZhbHVlcy5wdXNoKGhlYWRlci52YWx1ZXNbaV0ucmVwbGFjZSgvXihcUytcclxuKS8sIGluc2VydFNwYWNlKSk7CiAgfQogIHJ2YWwgKz0gdmFsdWVzLmpvaW4oJywnKSArICdcclxuJzsKCiAgLy8gZG8gZm9sZGluZwogIHZhciBsZW5ndGggPSAwOwogIHZhciBjYW5kaWRhdGUgPSAtMTsKICBmb3IodmFyIGkgPSAwOyBpIDwgcnZhbC5sZW5ndGg7ICsraSwgKytsZW5ndGgpIHsKICAgIGlmKGxlbmd0aCA+IDY1ICYmIGNhbmRpZGF0ZSAhPT0gLTEpIHsKICAgICAgdmFyIGluc2VydCA9IHJ2YWxbY2FuZGlkYXRlXTsKICAgICAgaWYoaW5zZXJ0ID09PSAnLCcpIHsKICAgICAgICArK2NhbmRpZGF0ZTsKICAgICAgICBydmFsID0gcnZhbC5zdWJzdHIoMCwgY2FuZGlkYXRlKSArICdcclxuICcgKyBydmFsLnN1YnN0cihjYW5kaWRhdGUpOwogICAgICB9IGVsc2UgewogICAgICAgIHJ2YWwgPSBydmFsLnN1YnN0cigwLCBjYW5kaWRhdGUpICsKICAgICAgICAgICdcclxuJyArIGluc2VydCArIHJ2YWwuc3Vic3RyKGNhbmRpZGF0ZSArIDEpOwogICAgICB9CiAgICAgIGxlbmd0aCA9IChpIC0gY2FuZGlkYXRlIC0gMSk7CiAgICAgIGNhbmRpZGF0ZSA9IC0xOwogICAgICArK2k7CiAgICB9IGVsc2UgaWYocnZhbFtpXSA9PT0gJyAnIHx8IHJ2YWxbaV0gPT09ICdcdCcgfHwgcnZhbFtpXSA9PT0gJywnKSB7CiAgICAgIGNhbmRpZGF0ZSA9IGk7CiAgICB9CiAgfQoKICByZXR1cm4gcnZhbDsKfQoKZnVuY3Rpb24gbHRyaW0oc3RyKSB7CiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXHMrLywgJycpOwp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdwZW0nOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvcGVtJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBERVMgKERhdGEgRW5jcnlwdGlvbiBTdGFuZGFyZCkgaW1wbGVtZW50YXRpb24uCiAqCiAqIFRoaXMgaW1wbGVtZW50YXRpb24gc3VwcG9ydHMgREVTIGFzIHdlbGwgYXMgM0RFUy1FREUgaW4gRUNCIGFuZCBDQkMgbW9kZS4KICogSXQgaXMgYmFzZWQgb24gdGhlIEJTRC1saWNlbnNlZCBpbXBsZW1lbnRhdGlvbiBieSBQYXVsIFRlcm86CiAqCiAqIFBhdWwgVGVybywgSnVseSAyMDAxCiAqIGh0dHA6Ly93d3cudGVyby5jby51ay9kZXMvCiAqCiAqIE9wdGltaXNlZCBmb3IgcGVyZm9ybWFuY2Ugd2l0aCBsYXJnZSBibG9ja3MgYnkgTWljaGFlbCBIYXl3b3J0aCwgTm92ZW1iZXIgMjAwMQogKiBodHRwOi8vd3d3Lm5ldGRlYWxpbmcuY29tCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiBBTkQKICogQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFCiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCiAqIEFSRSBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFCiAqIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMCiAqIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTCiAqIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKQogKiBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVAogKiBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZCiAqIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKICogU1VDSCBEQU1BR0UuCiAqCiAqIEBhdXRob3IgU3RlZmFuIFNpZWdsCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMiBTdGVmYW4gU2llZ2wgPHN0ZXNpZUBicm9rZW5waXBlLmRlPgogKiBDb3B5cmlnaHQgKGMpIDIwMTItMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8qIERFUyBBUEkgKi8KZm9yZ2UuZGVzID0gZm9yZ2UuZGVzIHx8IHt9OwoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogdmFyIGNpcGhlciA9IGZvcmdlLmNpcGhlci5jcmVhdGVDaXBoZXIoJ0RFUy08bW9kZT4nLCBrZXkpOwogKiBjaXBoZXIuc3RhcnQoe2l2OiBpdn0pOwogKgogKiBDcmVhdGVzIGFuIERFUyBjaXBoZXIgb2JqZWN0IHRvIGVuY3J5cHQgZGF0YSB1c2luZyB0aGUgZ2l2ZW4gc3ltbWV0cmljIGtleS4KICogVGhlIG91dHB1dCB3aWxsIGJlIHN0b3JlZCBpbiB0aGUgJ291dHB1dCcgbWVtYmVyIG9mIHRoZSByZXR1cm5lZCBjaXBoZXIuCiAqCiAqIFRoZSBrZXkgYW5kIGl2IG1heSBiZSBnaXZlbiBhcyBiaW5hcnktZW5jb2RlZCBzdHJpbmdzIG9mIGJ5dGVzIG9yCiAqIGJ5dGUgYnVmZmVycy4KICoKICogQHBhcmFtIGtleSB0aGUgc3ltbWV0cmljIGtleSB0byB1c2UgKDY0IG9yIDE5MiBiaXRzKS4KICogQHBhcmFtIGl2IHRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3IgdG8gdXNlLgogKiBAcGFyYW0gb3V0cHV0IHRoZSBidWZmZXIgdG8gd3JpdGUgdG8sIG51bGwgdG8gY3JlYXRlIG9uZS4KICogQHBhcmFtIG1vZGUgdGhlIGNpcGhlciBtb2RlIHRvIHVzZSAoZGVmYXVsdDogJ0NCQycgaWYgSVYgaXMKICogICAgICAgICAgZ2l2ZW4sICdFQ0InIGlmIG51bGwpLgogKgogKiBAcmV0dXJuIHRoZSBjaXBoZXIuCiAqLwpmb3JnZS5kZXMuc3RhcnRFbmNyeXB0aW5nID0gZnVuY3Rpb24oa2V5LCBpdiwgb3V0cHV0LCBtb2RlKSB7CiAgdmFyIGNpcGhlciA9IF9jcmVhdGVDaXBoZXIoewogICAga2V5OiBrZXksCiAgICBvdXRwdXQ6IG91dHB1dCwKICAgIGRlY3J5cHQ6IGZhbHNlLAogICAgbW9kZTogbW9kZSB8fCAoaXYgPT09IG51bGwgPyAnRUNCJyA6ICdDQkMnKQogIH0pOwogIGNpcGhlci5zdGFydChpdik7CiAgcmV0dXJuIGNpcGhlcjsKfTsKCi8qKgogKiBEZXByZWNhdGVkLiBJbnN0ZWFkLCB1c2U6CiAqCiAqIHZhciBjaXBoZXIgPSBmb3JnZS5jaXBoZXIuY3JlYXRlQ2lwaGVyKCdERVMtPG1vZGU+Jywga2V5KTsKICoKICogQ3JlYXRlcyBhbiBERVMgY2lwaGVyIG9iamVjdCB0byBlbmNyeXB0IGRhdGEgdXNpbmcgdGhlIGdpdmVuIHN5bW1ldHJpYyBrZXkuCiAqCiAqIFRoZSBrZXkgbWF5IGJlIGdpdmVuIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzIG9yIGEgYnl0ZSBidWZmZXIuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlICg2NCBvciAxOTIgYml0cykuCiAqIEBwYXJhbSBtb2RlIHRoZSBjaXBoZXIgbW9kZSB0byB1c2UgKGRlZmF1bHQ6ICdDQkMnKS4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZm9yZ2UuZGVzLmNyZWF0ZUVuY3J5cHRpb25DaXBoZXIgPSBmdW5jdGlvbihrZXksIG1vZGUpIHsKICByZXR1cm4gX2NyZWF0ZUNpcGhlcih7CiAgICBrZXk6IGtleSwKICAgIG91dHB1dDogbnVsbCwKICAgIGRlY3J5cHQ6IGZhbHNlLAogICAgbW9kZTogbW9kZQogIH0pOwp9OwoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogdmFyIGRlY2lwaGVyID0gZm9yZ2UuY2lwaGVyLmNyZWF0ZURlY2lwaGVyKCdERVMtPG1vZGU+Jywga2V5KTsKICogZGVjaXBoZXIuc3RhcnQoe2l2OiBpdn0pOwogKgogKiBDcmVhdGVzIGFuIERFUyBjaXBoZXIgb2JqZWN0IHRvIGRlY3J5cHQgZGF0YSB1c2luZyB0aGUgZ2l2ZW4gc3ltbWV0cmljIGtleS4KICogVGhlIG91dHB1dCB3aWxsIGJlIHN0b3JlZCBpbiB0aGUgJ291dHB1dCcgbWVtYmVyIG9mIHRoZSByZXR1cm5lZCBjaXBoZXIuCiAqCiAqIFRoZSBrZXkgYW5kIGl2IG1heSBiZSBnaXZlbiBhcyBiaW5hcnktZW5jb2RlZCBzdHJpbmdzIG9mIGJ5dGVzIG9yCiAqIGJ5dGUgYnVmZmVycy4KICoKICogQHBhcmFtIGtleSB0aGUgc3ltbWV0cmljIGtleSB0byB1c2UgKDY0IG9yIDE5MiBiaXRzKS4KICogQHBhcmFtIGl2IHRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3IgdG8gdXNlLgogKiBAcGFyYW0gb3V0cHV0IHRoZSBidWZmZXIgdG8gd3JpdGUgdG8sIG51bGwgdG8gY3JlYXRlIG9uZS4KICogQHBhcmFtIG1vZGUgdGhlIGNpcGhlciBtb2RlIHRvIHVzZSAoZGVmYXVsdDogJ0NCQycgaWYgSVYgaXMKICogICAgICAgICAgZ2l2ZW4sICdFQ0InIGlmIG51bGwpLgogKgogKiBAcmV0dXJuIHRoZSBjaXBoZXIuCiAqLwpmb3JnZS5kZXMuc3RhcnREZWNyeXB0aW5nID0gZnVuY3Rpb24oa2V5LCBpdiwgb3V0cHV0LCBtb2RlKSB7CiAgdmFyIGNpcGhlciA9IF9jcmVhdGVDaXBoZXIoewogICAga2V5OiBrZXksCiAgICBvdXRwdXQ6IG91dHB1dCwKICAgIGRlY3J5cHQ6IHRydWUsCiAgICBtb2RlOiBtb2RlIHx8IChpdiA9PT0gbnVsbCA/ICdFQ0InIDogJ0NCQycpCiAgfSk7CiAgY2lwaGVyLnN0YXJ0KGl2KTsKICByZXR1cm4gY2lwaGVyOwp9OwoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogdmFyIGRlY2lwaGVyID0gZm9yZ2UuY2lwaGVyLmNyZWF0ZURlY2lwaGVyKCdERVMtPG1vZGU+Jywga2V5KTsKICoKICogQ3JlYXRlcyBhbiBERVMgY2lwaGVyIG9iamVjdCB0byBkZWNyeXB0IGRhdGEgdXNpbmcgdGhlIGdpdmVuIHN5bW1ldHJpYyBrZXkuCiAqCiAqIFRoZSBrZXkgbWF5IGJlIGdpdmVuIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzIG9yIGEgYnl0ZSBidWZmZXIuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlICg2NCBvciAxOTIgYml0cykuCiAqIEBwYXJhbSBtb2RlIHRoZSBjaXBoZXIgbW9kZSB0byB1c2UgKGRlZmF1bHQ6ICdDQkMnKS4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZm9yZ2UuZGVzLmNyZWF0ZURlY3J5cHRpb25DaXBoZXIgPSBmdW5jdGlvbihrZXksIG1vZGUpIHsKICByZXR1cm4gX2NyZWF0ZUNpcGhlcih7CiAgICBrZXk6IGtleSwKICAgIG91dHB1dDogbnVsbCwKICAgIGRlY3J5cHQ6IHRydWUsCiAgICBtb2RlOiBtb2RlCiAgfSk7Cn07CgovKioKICogQ3JlYXRlcyBhIG5ldyBERVMgY2lwaGVyIGFsZ29yaXRobSBvYmplY3QuCiAqCiAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0uCiAqIEBwYXJhbSBtb2RlIHRoZSBtb2RlIGZhY3RvcnkgZnVuY3Rpb24uCiAqCiAqIEByZXR1cm4gdGhlIERFUyBhbGdvcml0aG0gb2JqZWN0LgogKi8KZm9yZ2UuZGVzLkFsZ29yaXRobSA9IGZ1bmN0aW9uKG5hbWUsIG1vZGUpIHsKICB2YXIgc2VsZiA9IHRoaXM7CiAgc2VsZi5uYW1lID0gbmFtZTsKICBzZWxmLm1vZGUgPSBuZXcgbW9kZSh7CiAgICBibG9ja1NpemU6IDgsCiAgICBjaXBoZXI6IHsKICAgICAgZW5jcnlwdDogZnVuY3Rpb24oaW5CbG9jaywgb3V0QmxvY2spIHsKICAgICAgICByZXR1cm4gX3VwZGF0ZUJsb2NrKHNlbGYuX2tleXMsIGluQmxvY2ssIG91dEJsb2NrLCBmYWxzZSk7CiAgICAgIH0sCiAgICAgIGRlY3J5cHQ6IGZ1bmN0aW9uKGluQmxvY2ssIG91dEJsb2NrKSB7CiAgICAgICAgcmV0dXJuIF91cGRhdGVCbG9jayhzZWxmLl9rZXlzLCBpbkJsb2NrLCBvdXRCbG9jaywgdHJ1ZSk7CiAgICAgIH0KICAgIH0KICB9KTsKICBzZWxmLl9pbml0ID0gZmFsc2U7Cn07CgovKioKICogSW5pdGlhbGl6ZXMgdGhpcyBERVMgYWxnb3JpdGhtIGJ5IGV4cGFuZGluZyBpdHMga2V5LgogKgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2UuCiAqICAgICAgICAgIGtleSB0aGUga2V5IHRvIHVzZSB3aXRoIHRoaXMgYWxnb3JpdGhtLgogKiAgICAgICAgICBkZWNyeXB0IHRydWUgaWYgdGhlIGFsZ29yaXRobSBzaG91bGQgYmUgaW5pdGlhbGl6ZWQgZm9yIGRlY3J5cHRpb24sCiAqICAgICAgICAgICAgZmFsc2UgZm9yIGVuY3J5cHRpb24uCiAqLwpmb3JnZS5kZXMuQWxnb3JpdGhtLnByb3RvdHlwZS5pbml0aWFsaXplID0gZnVuY3Rpb24ob3B0aW9ucykgewogIGlmKHRoaXMuX2luaXQpIHsKICAgIHJldHVybjsKICB9CgogIHZhciBrZXkgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihvcHRpb25zLmtleSk7CiAgaWYodGhpcy5uYW1lLmluZGV4T2YoJzNERVMnKSA9PT0gMCkgewogICAgaWYoa2V5Lmxlbmd0aCgpICE9PSAyNCkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgVHJpcGxlLURFUyBrZXkgc2l6ZTogJyArIGtleS5sZW5ndGgoKSAqIDgpOwogICAgfQogIH0KCiAgLy8gZG8ga2V5IGV4cGFuc2lvbiB0byAxNiBvciA0OCBzdWJrZXlzIChzaW5nbGUgb3IgdHJpcGxlIERFUykKICB0aGlzLl9rZXlzID0gX2NyZWF0ZUtleXMoa2V5KTsKICB0aGlzLl9pbml0ID0gdHJ1ZTsKfTsKCgovKiogUmVnaXN0ZXIgREVTIGFsZ29yaXRobXMgKiovCgpyZWdpc3RlckFsZ29yaXRobSgnREVTLUVDQicsIGZvcmdlLmNpcGhlci5tb2Rlcy5lY2IpOwpyZWdpc3RlckFsZ29yaXRobSgnREVTLUNCQycsIGZvcmdlLmNpcGhlci5tb2Rlcy5jYmMpOwpyZWdpc3RlckFsZ29yaXRobSgnREVTLUNGQicsIGZvcmdlLmNpcGhlci5tb2Rlcy5jZmIpOwpyZWdpc3RlckFsZ29yaXRobSgnREVTLU9GQicsIGZvcmdlLmNpcGhlci5tb2Rlcy5vZmIpOwpyZWdpc3RlckFsZ29yaXRobSgnREVTLUNUUicsIGZvcmdlLmNpcGhlci5tb2Rlcy5jdHIpOwoKcmVnaXN0ZXJBbGdvcml0aG0oJzNERVMtRUNCJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmVjYik7CnJlZ2lzdGVyQWxnb3JpdGhtKCczREVTLUNCQycsIGZvcmdlLmNpcGhlci5tb2Rlcy5jYmMpOwpyZWdpc3RlckFsZ29yaXRobSgnM0RFUy1DRkInLCBmb3JnZS5jaXBoZXIubW9kZXMuY2ZiKTsKcmVnaXN0ZXJBbGdvcml0aG0oJzNERVMtT0ZCJywgZm9yZ2UuY2lwaGVyLm1vZGVzLm9mYik7CnJlZ2lzdGVyQWxnb3JpdGhtKCczREVTLUNUUicsIGZvcmdlLmNpcGhlci5tb2Rlcy5jdHIpOwoKZnVuY3Rpb24gcmVnaXN0ZXJBbGdvcml0aG0obmFtZSwgbW9kZSkgewogIHZhciBmYWN0b3J5ID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gbmV3IGZvcmdlLmRlcy5BbGdvcml0aG0obmFtZSwgbW9kZSk7CiAgfTsKICBmb3JnZS5jaXBoZXIucmVnaXN0ZXJBbGdvcml0aG0obmFtZSwgZmFjdG9yeSk7Cn0KCgovKiogREVTIGltcGxlbWVudGF0aW9uICoqLwoKdmFyIHNwZnVuY3Rpb24xID0gWzB4MTAxMDQwMCwwLDB4MTAwMDAsMHgxMDEwNDA0LDB4MTAxMDAwNCwweDEwNDA0LDB4NCwweDEwMDAwLDB4NDAwLDB4MTAxMDQwMCwweDEwMTA0MDQsMHg0MDAsMHgxMDAwNDA0LDB4MTAxMDAwNCwweDEwMDAwMDAsMHg0LDB4NDA0LDB4MTAwMDQwMCwweDEwMDA0MDAsMHgxMDQwMCwweDEwNDAwLDB4MTAxMDAwMCwweDEwMTAwMDAsMHgxMDAwNDA0LDB4MTAwMDQsMHgxMDAwMDA0LDB4MTAwMDAwNCwweDEwMDA0LDAsMHg0MDQsMHgxMDQwNCwweDEwMDAwMDAsMHgxMDAwMCwweDEwMTA0MDQsMHg0LDB4MTAxMDAwMCwweDEwMTA0MDAsMHgxMDAwMDAwLDB4MTAwMDAwMCwweDQwMCwweDEwMTAwMDQsMHgxMDAwMCwweDEwNDAwLDB4MTAwMDAwNCwweDQwMCwweDQsMHgxMDAwNDA0LDB4MTA0MDQsMHgxMDEwNDA0LDB4MTAwMDQsMHgxMDEwMDAwLDB4MTAwMDQwNCwweDEwMDAwMDQsMHg0MDQsMHgxMDQwNCwweDEwMTA0MDAsMHg0MDQsMHgxMDAwNDAwLDB4MTAwMDQwMCwwLDB4MTAwMDQsMHgxMDQwMCwwLDB4MTAxMDAwNF07CnZhciBzcGZ1bmN0aW9uMiA9IFstMHg3ZmVmN2ZlMCwtMHg3ZmZmODAwMCwweDgwMDAsMHgxMDgwMjAsMHgxMDAwMDAsMHgyMCwtMHg3ZmVmZmZlMCwtMHg3ZmZmN2ZlMCwtMHg3ZmZmZmZlMCwtMHg3ZmVmN2ZlMCwtMHg3ZmVmODAwMCwtMHg4MDAwMDAwMCwtMHg3ZmZmODAwMCwweDEwMDAwMCwweDIwLC0weDdmZWZmZmUwLDB4MTA4MDAwLDB4MTAwMDIwLC0weDdmZmY3ZmUwLDAsLTB4ODAwMDAwMDAsMHg4MDAwLDB4MTA4MDIwLC0weDdmZjAwMDAwLDB4MTAwMDIwLC0weDdmZmZmZmUwLDAsMHgxMDgwMDAsMHg4MDIwLC0weDdmZWY4MDAwLC0weDdmZjAwMDAwLDB4ODAyMCwwLDB4MTA4MDIwLC0weDdmZWZmZmUwLDB4MTAwMDAwLC0weDdmZmY3ZmUwLC0weDdmZjAwMDAwLC0weDdmZWY4MDAwLDB4ODAwMCwtMHg3ZmYwMDAwMCwtMHg3ZmZmODAwMCwweDIwLC0weDdmZWY3ZmUwLDB4MTA4MDIwLDB4MjAsMHg4MDAwLC0weDgwMDAwMDAwLDB4ODAyMCwtMHg3ZmVmODAwMCwweDEwMDAwMCwtMHg3ZmZmZmZlMCwweDEwMDAyMCwtMHg3ZmZmN2ZlMCwtMHg3ZmZmZmZlMCwweDEwMDAyMCwweDEwODAwMCwwLC0weDdmZmY4MDAwLDB4ODAyMCwtMHg4MDAwMDAwMCwtMHg3ZmVmZmZlMCwtMHg3ZmVmN2ZlMCwweDEwODAwMF07CnZhciBzcGZ1bmN0aW9uMyA9IFsweDIwOCwweDgwMjAyMDAsMCwweDgwMjAwMDgsMHg4MDAwMjAwLDAsMHgyMDIwOCwweDgwMDAyMDAsMHgyMDAwOCwweDgwMDAwMDgsMHg4MDAwMDA4LDB4MjAwMDAsMHg4MDIwMjA4LDB4MjAwMDgsMHg4MDIwMDAwLDB4MjA4LDB4ODAwMDAwMCwweDgsMHg4MDIwMjAwLDB4MjAwLDB4MjAyMDAsMHg4MDIwMDAwLDB4ODAyMDAwOCwweDIwMjA4LDB4ODAwMDIwOCwweDIwMjAwLDB4MjAwMDAsMHg4MDAwMjA4LDB4OCwweDgwMjAyMDgsMHgyMDAsMHg4MDAwMDAwLDB4ODAyMDIwMCwweDgwMDAwMDAsMHgyMDAwOCwweDIwOCwweDIwMDAwLDB4ODAyMDIwMCwweDgwMDAyMDAsMCwweDIwMCwweDIwMDA4LDB4ODAyMDIwOCwweDgwMDAyMDAsMHg4MDAwMDA4LDB4MjAwLDAsMHg4MDIwMDA4LDB4ODAwMDIwOCwweDIwMDAwLDB4ODAwMDAwMCwweDgwMjAyMDgsMHg4LDB4MjAyMDgsMHgyMDIwMCwweDgwMDAwMDgsMHg4MDIwMDAwLDB4ODAwMDIwOCwweDIwOCwweDgwMjAwMDAsMHgyMDIwOCwweDgsMHg4MDIwMDA4LDB4MjAyMDBdOwp2YXIgc3BmdW5jdGlvbjQgPSBbMHg4MDIwMDEsMHgyMDgxLDB4MjA4MSwweDgwLDB4ODAyMDgwLDB4ODAwMDgxLDB4ODAwMDAxLDB4MjAwMSwwLDB4ODAyMDAwLDB4ODAyMDAwLDB4ODAyMDgxLDB4ODEsMCwweDgwMDA4MCwweDgwMDAwMSwweDEsMHgyMDAwLDB4ODAwMDAwLDB4ODAyMDAxLDB4ODAsMHg4MDAwMDAsMHgyMDAxLDB4MjA4MCwweDgwMDA4MSwweDEsMHgyMDgwLDB4ODAwMDgwLDB4MjAwMCwweDgwMjA4MCwweDgwMjA4MSwweDgxLDB4ODAwMDgwLDB4ODAwMDAxLDB4ODAyMDAwLDB4ODAyMDgxLDB4ODEsMCwwLDB4ODAyMDAwLDB4MjA4MCwweDgwMDA4MCwweDgwMDA4MSwweDEsMHg4MDIwMDEsMHgyMDgxLDB4MjA4MSwweDgwLDB4ODAyMDgxLDB4ODEsMHgxLDB4MjAwMCwweDgwMDAwMSwweDIwMDEsMHg4MDIwODAsMHg4MDAwODEsMHgyMDAxLDB4MjA4MCwweDgwMDAwMCwweDgwMjAwMSwweDgwLDB4ODAwMDAwLDB4MjAwMCwweDgwMjA4MF07CnZhciBzcGZ1bmN0aW9uNSA9IFsweDEwMCwweDIwODAxMDAsMHgyMDgwMDAwLDB4NDIwMDAxMDAsMHg4MDAwMCwweDEwMCwweDQwMDAwMDAwLDB4MjA4MDAwMCwweDQwMDgwMTAwLDB4ODAwMDAsMHgyMDAwMTAwLDB4NDAwODAxMDAsMHg0MjAwMDEwMCwweDQyMDgwMDAwLDB4ODAxMDAsMHg0MDAwMDAwMCwweDIwMDAwMDAsMHg0MDA4MDAwMCwweDQwMDgwMDAwLDAsMHg0MDAwMDEwMCwweDQyMDgwMTAwLDB4NDIwODAxMDAsMHgyMDAwMTAwLDB4NDIwODAwMDAsMHg0MDAwMDEwMCwwLDB4NDIwMDAwMDAsMHgyMDgwMTAwLDB4MjAwMDAwMCwweDQyMDAwMDAwLDB4ODAxMDAsMHg4MDAwMCwweDQyMDAwMTAwLDB4MTAwLDB4MjAwMDAwMCwweDQwMDAwMDAwLDB4MjA4MDAwMCwweDQyMDAwMTAwLDB4NDAwODAxMDAsMHgyMDAwMTAwLDB4NDAwMDAwMDAsMHg0MjA4MDAwMCwweDIwODAxMDAsMHg0MDA4MDEwMCwweDEwMCwweDIwMDAwMDAsMHg0MjA4MDAwMCwweDQyMDgwMTAwLDB4ODAxMDAsMHg0MjAwMDAwMCwweDQyMDgwMTAwLDB4MjA4MDAwMCwwLDB4NDAwODAwMDAsMHg0MjAwMDAwMCwweDgwMTAwLDB4MjAwMDEwMCwweDQwMDAwMTAwLDB4ODAwMDAsMCwweDQwMDgwMDAwLDB4MjA4MDEwMCwweDQwMDAwMTAwXTsKdmFyIHNwZnVuY3Rpb242ID0gWzB4MjAwMDAwMTAsMHgyMDQwMDAwMCwweDQwMDAsMHgyMDQwNDAxMCwweDIwNDAwMDAwLDB4MTAsMHgyMDQwNDAxMCwweDQwMDAwMCwweDIwMDA0MDAwLDB4NDA0MDEwLDB4NDAwMDAwLDB4MjAwMDAwMTAsMHg0MDAwMTAsMHgyMDAwNDAwMCwweDIwMDAwMDAwLDB4NDAxMCwwLDB4NDAwMDEwLDB4MjAwMDQwMTAsMHg0MDAwLDB4NDA0MDAwLDB4MjAwMDQwMTAsMHgxMCwweDIwNDAwMDEwLDB4MjA0MDAwMTAsMCwweDQwNDAxMCwweDIwNDA0MDAwLDB4NDAxMCwweDQwNDAwMCwweDIwNDA0MDAwLDB4MjAwMDAwMDAsMHgyMDAwNDAwMCwweDEwLDB4MjA0MDAwMTAsMHg0MDQwMDAsMHgyMDQwNDAxMCwweDQwMDAwMCwweDQwMTAsMHgyMDAwMDAxMCwweDQwMDAwMCwweDIwMDA0MDAwLDB4MjAwMDAwMDAsMHg0MDEwLDB4MjAwMDAwMTAsMHgyMDQwNDAxMCwweDQwNDAwMCwweDIwNDAwMDAwLDB4NDA0MDEwLDB4MjA0MDQwMDAsMCwweDIwNDAwMDEwLDB4MTAsMHg0MDAwLDB4MjA0MDAwMDAsMHg0MDQwMTAsMHg0MDAwLDB4NDAwMDEwLDB4MjAwMDQwMTAsMCwweDIwNDA0MDAwLDB4MjAwMDAwMDAsMHg0MDAwMTAsMHgyMDAwNDAxMF07CnZhciBzcGZ1bmN0aW9uNyA9IFsweDIwMDAwMCwweDQyMDAwMDIsMHg0MDAwODAyLDAsMHg4MDAsMHg0MDAwODAyLDB4MjAwODAyLDB4NDIwMDgwMCwweDQyMDA4MDIsMHgyMDAwMDAsMCwweDQwMDAwMDIsMHgyLDB4NDAwMDAwMCwweDQyMDAwMDIsMHg4MDIsMHg0MDAwODAwLDB4MjAwODAyLDB4MjAwMDAyLDB4NDAwMDgwMCwweDQwMDAwMDIsMHg0MjAwMDAwLDB4NDIwMDgwMCwweDIwMDAwMiwweDQyMDAwMDAsMHg4MDAsMHg4MDIsMHg0MjAwODAyLDB4MjAwODAwLDB4MiwweDQwMDAwMDAsMHgyMDA4MDAsMHg0MDAwMDAwLDB4MjAwODAwLDB4MjAwMDAwLDB4NDAwMDgwMiwweDQwMDA4MDIsMHg0MjAwMDAyLDB4NDIwMDAwMiwweDIsMHgyMDAwMDIsMHg0MDAwMDAwLDB4NDAwMDgwMCwweDIwMDAwMCwweDQyMDA4MDAsMHg4MDIsMHgyMDA4MDIsMHg0MjAwODAwLDB4ODAyLDB4NDAwMDAwMiwweDQyMDA4MDIsMHg0MjAwMDAwLDB4MjAwODAwLDAsMHgyLDB4NDIwMDgwMiwwLDB4MjAwODAyLDB4NDIwMDAwMCwweDgwMCwweDQwMDAwMDIsMHg0MDAwODAwLDB4ODAwLDB4MjAwMDAyXTsKdmFyIHNwZnVuY3Rpb244ID0gWzB4MTAwMDEwNDAsMHgxMDAwLDB4NDAwMDAsMHgxMDA0MTA0MCwweDEwMDAwMDAwLDB4MTAwMDEwNDAsMHg0MCwweDEwMDAwMDAwLDB4NDAwNDAsMHgxMDA0MDAwMCwweDEwMDQxMDQwLDB4NDEwMDAsMHgxMDA0MTAwMCwweDQxMDQwLDB4MTAwMCwweDQwLDB4MTAwNDAwMDAsMHgxMDAwMDA0MCwweDEwMDAxMDAwLDB4MTA0MCwweDQxMDAwLDB4NDAwNDAsMHgxMDA0MDA0MCwweDEwMDQxMDAwLDB4MTA0MCwwLDAsMHgxMDA0MDA0MCwweDEwMDAwMDQwLDB4MTAwMDEwMDAsMHg0MTA0MCwweDQwMDAwLDB4NDEwNDAsMHg0MDAwMCwweDEwMDQxMDAwLDB4MTAwMCwweDQwLDB4MTAwNDAwNDAsMHgxMDAwLDB4NDEwNDAsMHgxMDAwMTAwMCwweDQwLDB4MTAwMDAwNDAsMHgxMDA0MDAwMCwweDEwMDQwMDQwLDB4MTAwMDAwMDAsMHg0MDAwMCwweDEwMDAxMDQwLDAsMHgxMDA0MTA0MCwweDQwMDQwLDB4MTAwMDAwNDAsMHgxMDA0MDAwMCwweDEwMDAxMDAwLDB4MTAwMDEwNDAsMCwweDEwMDQxMDQwLDB4NDEwMDAsMHg0MTAwMCwweDEwNDAsMHgxMDQwLDB4NDAwNDAsMHgxMDAwMDAwMCwweDEwMDQxMDAwXTsKCi8qKgogKiBDcmVhdGUgbmVjZXNzYXJ5IHN1YiBrZXlzLgogKgogKiBAcGFyYW0ga2V5IHRoZSA2NC1iaXQgb3IgMTkyLWJpdCBrZXkuCiAqCiAqIEByZXR1cm4gdGhlIGV4cGFuZGVkIGtleXMuCiAqLwpmdW5jdGlvbiBfY3JlYXRlS2V5cyhrZXkpIHsKICB2YXIgcGMyYnl0ZXMwICA9IFswLDB4NCwweDIwMDAwMDAwLDB4MjAwMDAwMDQsMHgxMDAwMCwweDEwMDA0LDB4MjAwMTAwMDAsMHgyMDAxMDAwNCwweDIwMCwweDIwNCwweDIwMDAwMjAwLDB4MjAwMDAyMDQsMHgxMDIwMCwweDEwMjA0LDB4MjAwMTAyMDAsMHgyMDAxMDIwNF0sCiAgICAgIHBjMmJ5dGVzMSAgPSBbMCwweDEsMHgxMDAwMDAsMHgxMDAwMDEsMHg0MDAwMDAwLDB4NDAwMDAwMSwweDQxMDAwMDAsMHg0MTAwMDAxLDB4MTAwLDB4MTAxLDB4MTAwMTAwLDB4MTAwMTAxLDB4NDAwMDEwMCwweDQwMDAxMDEsMHg0MTAwMTAwLDB4NDEwMDEwMV0sCiAgICAgIHBjMmJ5dGVzMiAgPSBbMCwweDgsMHg4MDAsMHg4MDgsMHgxMDAwMDAwLDB4MTAwMDAwOCwweDEwMDA4MDAsMHgxMDAwODA4LDAsMHg4LDB4ODAwLDB4ODA4LDB4MTAwMDAwMCwweDEwMDAwMDgsMHgxMDAwODAwLDB4MTAwMDgwOF0sCiAgICAgIHBjMmJ5dGVzMyAgPSBbMCwweDIwMDAwMCwweDgwMDAwMDAsMHg4MjAwMDAwLDB4MjAwMCwweDIwMjAwMCwweDgwMDIwMDAsMHg4MjAyMDAwLDB4MjAwMDAsMHgyMjAwMDAsMHg4MDIwMDAwLDB4ODIyMDAwMCwweDIyMDAwLDB4MjIyMDAwLDB4ODAyMjAwMCwweDgyMjIwMDBdLAogICAgICBwYzJieXRlczQgID0gWzAsMHg0MDAwMCwweDEwLDB4NDAwMTAsMCwweDQwMDAwLDB4MTAsMHg0MDAxMCwweDEwMDAsMHg0MTAwMCwweDEwMTAsMHg0MTAxMCwweDEwMDAsMHg0MTAwMCwweDEwMTAsMHg0MTAxMF0sCiAgICAgIHBjMmJ5dGVzNSAgPSBbMCwweDQwMCwweDIwLDB4NDIwLDAsMHg0MDAsMHgyMCwweDQyMCwweDIwMDAwMDAsMHgyMDAwNDAwLDB4MjAwMDAyMCwweDIwMDA0MjAsMHgyMDAwMDAwLDB4MjAwMDQwMCwweDIwMDAwMjAsMHgyMDAwNDIwXSwKICAgICAgcGMyYnl0ZXM2ICA9IFswLDB4MTAwMDAwMDAsMHg4MDAwMCwweDEwMDgwMDAwLDB4MiwweDEwMDAwMDAyLDB4ODAwMDIsMHgxMDA4MDAwMiwwLDB4MTAwMDAwMDAsMHg4MDAwMCwweDEwMDgwMDAwLDB4MiwweDEwMDAwMDAyLDB4ODAwMDIsMHgxMDA4MDAwMl0sCiAgICAgIHBjMmJ5dGVzNyAgPSBbMCwweDEwMDAwLDB4ODAwLDB4MTA4MDAsMHgyMDAwMDAwMCwweDIwMDEwMDAwLDB4MjAwMDA4MDAsMHgyMDAxMDgwMCwweDIwMDAwLDB4MzAwMDAsMHgyMDgwMCwweDMwODAwLDB4MjAwMjAwMDAsMHgyMDAzMDAwMCwweDIwMDIwODAwLDB4MjAwMzA4MDBdLAogICAgICBwYzJieXRlczggID0gWzAsMHg0MDAwMCwwLDB4NDAwMDAsMHgyLDB4NDAwMDIsMHgyLDB4NDAwMDIsMHgyMDAwMDAwLDB4MjA0MDAwMCwweDIwMDAwMDAsMHgyMDQwMDAwLDB4MjAwMDAwMiwweDIwNDAwMDIsMHgyMDAwMDAyLDB4MjA0MDAwMl0sCiAgICAgIHBjMmJ5dGVzOSAgPSBbMCwweDEwMDAwMDAwLDB4OCwweDEwMDAwMDA4LDAsMHgxMDAwMDAwMCwweDgsMHgxMDAwMDAwOCwweDQwMCwweDEwMDAwNDAwLDB4NDA4LDB4MTAwMDA0MDgsMHg0MDAsMHgxMDAwMDQwMCwweDQwOCwweDEwMDAwNDA4XSwKICAgICAgcGMyYnl0ZXMxMCA9IFswLDB4MjAsMCwweDIwLDB4MTAwMDAwLDB4MTAwMDIwLDB4MTAwMDAwLDB4MTAwMDIwLDB4MjAwMCwweDIwMjAsMHgyMDAwLDB4MjAyMCwweDEwMjAwMCwweDEwMjAyMCwweDEwMjAwMCwweDEwMjAyMF0sCiAgICAgIHBjMmJ5dGVzMTEgPSBbMCwweDEwMDAwMDAsMHgyMDAsMHgxMDAwMjAwLDB4MjAwMDAwLDB4MTIwMDAwMCwweDIwMDIwMCwweDEyMDAyMDAsMHg0MDAwMDAwLDB4NTAwMDAwMCwweDQwMDAyMDAsMHg1MDAwMjAwLDB4NDIwMDAwMCwweDUyMDAwMDAsMHg0MjAwMjAwLDB4NTIwMDIwMF0sCiAgICAgIHBjMmJ5dGVzMTIgPSBbMCwweDEwMDAsMHg4MDAwMDAwLDB4ODAwMTAwMCwweDgwMDAwLDB4ODEwMDAsMHg4MDgwMDAwLDB4ODA4MTAwMCwweDEwLDB4MTAxMCwweDgwMDAwMTAsMHg4MDAxMDEwLDB4ODAwMTAsMHg4MTAxMCwweDgwODAwMTAsMHg4MDgxMDEwXSwKICAgICAgcGMyYnl0ZXMxMyA9IFswLDB4NCwweDEwMCwweDEwNCwwLDB4NCwweDEwMCwweDEwNCwweDEsMHg1LDB4MTAxLDB4MTA1LDB4MSwweDUsMHgxMDEsMHgxMDVdOwoKICAvLyBob3cgbWFueSBpdGVyYXRpb25zICgxIGZvciBkZXMsIDMgZm9yIHRyaXBsZSBkZXMpCiAgLy8gY2hhbmdlZCBieSBQYXVsIDE2LzYvMjAwNyB0byB1c2UgVHJpcGxlIERFUyBmb3IgOSsgYnl0ZSBrZXlzCiAgdmFyIGl0ZXJhdGlvbnMgPSBrZXkubGVuZ3RoKCkgPiA4ID8gMyA6IDE7CgogIC8vIHN0b3JlcyB0aGUgcmV0dXJuIGtleXMKICB2YXIga2V5cyA9IFtdOwoKICAvLyBub3cgZGVmaW5lIHRoZSBsZWZ0IHNoaWZ0cyB3aGljaCBuZWVkIHRvIGJlIGRvbmUKICB2YXIgc2hpZnRzID0gWzAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDBdOwoKICB2YXIgbiA9IDAsIHRtcDsKICBmb3IodmFyIGogPSAwOyBqIDwgaXRlcmF0aW9uczsgaiArKykgewogICAgdmFyIGxlZnQgPSBrZXkuZ2V0SW50MzIoKTsKICAgIHZhciByaWdodCA9IGtleS5nZXRJbnQzMigpOwoKICAgIHRtcCA9ICgobGVmdCA+Pj4gNCkgXiByaWdodCkgJiAweDBmMGYwZjBmOwogICAgcmlnaHQgXj0gdG1wOwogICAgbGVmdCBePSAodG1wIDw8IDQpOwoKICAgIHRtcCA9ICgocmlnaHQgPj4+IC0xNikgXiBsZWZ0KSAmIDB4MDAwMGZmZmY7CiAgICBsZWZ0IF49IHRtcDsKICAgIHJpZ2h0IF49ICh0bXAgPDwgLTE2KTsKCiAgICB0bXAgPSAoKGxlZnQgPj4+IDIpIF4gcmlnaHQpICYgMHgzMzMzMzMzMzsKICAgIHJpZ2h0IF49IHRtcDsKICAgIGxlZnQgXj0gKHRtcCA8PCAyKTsKCiAgICB0bXAgPSAoKHJpZ2h0ID4+PiAtMTYpIF4gbGVmdCkgJiAweDAwMDBmZmZmOwogICAgbGVmdCBePSB0bXA7CiAgICByaWdodCBePSAodG1wIDw8IC0xNik7CgogICAgdG1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7CiAgICByaWdodCBePSB0bXA7CiAgICBsZWZ0IF49ICh0bXAgPDwgMSk7CgogICAgdG1wID0gKChyaWdodCA+Pj4gOCkgXiBsZWZ0KSAmIDB4MDBmZjAwZmY7CiAgICBsZWZ0IF49IHRtcDsKICAgIHJpZ2h0IF49ICh0bXAgPDwgOCk7CgogICAgdG1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7CiAgICByaWdodCBePSB0bXA7CiAgICBsZWZ0IF49ICh0bXAgPDwgMSk7CgogICAgLy8gcmlnaHQgbmVlZHMgdG8gYmUgc2hpZnRlZCBhbmQgT1InZCB3aXRoIGxhc3QgZm91ciBiaXRzIG9mIGxlZnQKICAgIHRtcCA9IChsZWZ0IDw8IDgpIHwgKChyaWdodCA+Pj4gMjApICYgMHgwMDAwMDBmMCk7CgogICAgLy8gbGVmdCBuZWVkcyB0byBiZSBwdXQgdXBzaWRlIGRvd24KICAgIGxlZnQgPSAoKHJpZ2h0IDw8IDI0KSB8ICgocmlnaHQgPDwgOCkgJiAweGZmMDAwMCkgfAogICAgICAoKHJpZ2h0ID4+PiA4KSAmIDB4ZmYwMCkgfCAoKHJpZ2h0ID4+PiAyNCkgJiAweGYwKSk7CiAgICByaWdodCA9IHRtcDsKCiAgICAvLyBub3cgZ28gdGhyb3VnaCBhbmQgcGVyZm9ybSB0aGVzZSBzaGlmdHMgb24gdGhlIGxlZnQgYW5kIHJpZ2h0IGtleXMKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBzaGlmdHMubGVuZ3RoOyArK2kpIHsKICAgICAgLy9zaGlmdCB0aGUga2V5cyBlaXRoZXIgb25lIG9yIHR3byBiaXRzIHRvIHRoZSBsZWZ0CiAgICAgIGlmKHNoaWZ0c1tpXSkgewogICAgICAgIGxlZnQgPSAobGVmdCA8PCAyKSB8IChsZWZ0ID4+PiAyNik7CiAgICAgICAgcmlnaHQgPSAocmlnaHQgPDwgMikgfCAocmlnaHQgPj4+IDI2KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBsZWZ0ID0gKGxlZnQgPDwgMSkgfCAobGVmdCA+Pj4gMjcpOwogICAgICAgIHJpZ2h0ID0gKHJpZ2h0IDw8IDEpIHwgKHJpZ2h0ID4+PiAyNyk7CiAgICAgIH0KICAgICAgbGVmdCAmPSAtMHhmOwogICAgICByaWdodCAmPSAtMHhmOwoKICAgICAgLy8gbm93IGFwcGx5IFBDLTIsIGluIHN1Y2ggYSB3YXkgdGhhdCBFIGlzIGVhc2llciB3aGVuIGVuY3J5cHRpbmcgb3IKICAgICAgLy8gZGVjcnlwdGluZyB0aGlzIGNvbnZlcnNpb24gd2lsbCBsb29rIGxpa2UgUEMtMiBleGNlcHQgb25seSB0aGUgbGFzdCA2CiAgICAgIC8vIGJpdHMgb2YgZWFjaCBieXRlIGFyZSB1c2VkIHJhdGhlciB0aGFuIDQ4IGNvbnNlY3V0aXZlIGJpdHMgYW5kIHRoZQogICAgICAvLyBvcmRlciBvZiBsaW5lcyB3aWxsIGJlIGFjY29yZGluZyB0byBob3cgdGhlIFMgc2VsZWN0aW9uIGZ1bmN0aW9ucyB3aWxsCiAgICAgIC8vIGJlIGFwcGxpZWQ6IFMyLCBTNCwgUzYsIFM4LCBTMSwgUzMsIFM1LCBTNwogICAgICB2YXIgbGVmdHRtcCA9ICgKICAgICAgICBwYzJieXRlczBbbGVmdCA+Pj4gMjhdIHwgcGMyYnl0ZXMxWyhsZWZ0ID4+PiAyNCkgJiAweGZdIHwKICAgICAgICBwYzJieXRlczJbKGxlZnQgPj4+IDIwKSAmIDB4Zl0gfCBwYzJieXRlczNbKGxlZnQgPj4+IDE2KSAmIDB4Zl0gfAogICAgICAgIHBjMmJ5dGVzNFsobGVmdCA+Pj4gMTIpICYgMHhmXSB8IHBjMmJ5dGVzNVsobGVmdCA+Pj4gOCkgJiAweGZdIHwKICAgICAgICBwYzJieXRlczZbKGxlZnQgPj4+IDQpICYgMHhmXSk7CiAgICAgIHZhciByaWdodHRtcCA9ICgKICAgICAgICBwYzJieXRlczdbcmlnaHQgPj4+IDI4XSB8IHBjMmJ5dGVzOFsocmlnaHQgPj4+IDI0KSAmIDB4Zl0gfAogICAgICAgIHBjMmJ5dGVzOVsocmlnaHQgPj4+IDIwKSAmIDB4Zl0gfCBwYzJieXRlczEwWyhyaWdodCA+Pj4gMTYpICYgMHhmXSB8CiAgICAgICAgcGMyYnl0ZXMxMVsocmlnaHQgPj4+IDEyKSAmIDB4Zl0gfCBwYzJieXRlczEyWyhyaWdodCA+Pj4gOCkgJiAweGZdIHwKICAgICAgICBwYzJieXRlczEzWyhyaWdodCA+Pj4gNCkgJiAweGZdKTsKICAgICAgdG1wID0gKChyaWdodHRtcCA+Pj4gMTYpIF4gbGVmdHRtcCkgJiAweDAwMDBmZmZmOwogICAgICBrZXlzW24rK10gPSBsZWZ0dG1wIF4gdG1wOwogICAgICBrZXlzW24rK10gPSByaWdodHRtcCBeICh0bXAgPDwgMTYpOwogICAgfQogIH0KCiAgcmV0dXJuIGtleXM7Cn0KCi8qKgogKiBVcGRhdGVzIGEgc2luZ2xlIGJsb2NrICgxIGJ5dGUpIHVzaW5nIERFUy4gVGhlIHVwZGF0ZSB3aWxsIGVpdGhlcgogKiBlbmNyeXB0IG9yIGRlY3J5cHQgdGhlIGJsb2NrLgogKgogKiBAcGFyYW0ga2V5cyB0aGUgZXhwYW5kZWQga2V5cy4KICogQHBhcmFtIGlucHV0IHRoZSBpbnB1dCBibG9jayAoYW4gYXJyYXkgb2YgMzItYml0IHdvcmRzKS4KICogQHBhcmFtIG91dHB1dCB0aGUgdXBkYXRlZCBvdXRwdXQgYmxvY2suCiAqIEBwYXJhbSBkZWNyeXB0IHRydWUgdG8gZGVjcnlwdCB0aGUgYmxvY2ssIGZhbHNlIHRvIGVuY3J5cHQgaXQuCiAqLwpmdW5jdGlvbiBfdXBkYXRlQmxvY2soa2V5cywgaW5wdXQsIG91dHB1dCwgZGVjcnlwdCkgewogIC8vIHNldCB1cCBsb29wcyBmb3Igc2luZ2xlIG9yIHRyaXBsZSBERVMKICB2YXIgaXRlcmF0aW9ucyA9IGtleXMubGVuZ3RoID09PSAzMiA/IDMgOiA5OwogIHZhciBsb29waW5nOwogIGlmKGl0ZXJhdGlvbnMgPT09IDMpIHsKICAgIGxvb3BpbmcgPSBkZWNyeXB0ID8gWzMwLCAtMiwgLTJdIDogWzAsIDMyLCAyXTsKICB9IGVsc2UgewogICAgbG9vcGluZyA9IChkZWNyeXB0ID8KICAgICAgWzk0LCA2MiwgLTIsIDMyLCA2NCwgMiwgMzAsIC0yLCAtMl0gOgogICAgICBbMCwgMzIsIDIsIDYyLCAzMCwgLTIsIDY0LCA5NiwgMl0pOwogIH0KCiAgdmFyIHRtcDsKCiAgdmFyIGxlZnQgPSBpbnB1dFswXTsKICB2YXIgcmlnaHQgPSBpbnB1dFsxXTsKCiAgLy8gZmlyc3QgZWFjaCA2NCBiaXQgY2h1bmsgb2YgdGhlIG1lc3NhZ2UgbXVzdCBiZSBwZXJtdXRlZCBhY2NvcmRpbmcgdG8gSVAKICB0bXAgPSAoKGxlZnQgPj4+IDQpIF4gcmlnaHQpICYgMHgwZjBmMGYwZjsKICByaWdodCBePSB0bXA7CiAgbGVmdCBePSAodG1wIDw8IDQpOwoKICB0bXAgPSAoKGxlZnQgPj4+IDE2KSBeIHJpZ2h0KSAmIDB4MDAwMGZmZmY7CiAgcmlnaHQgXj0gdG1wOwogIGxlZnQgXj0gKHRtcCA8PCAxNik7CgogIHRtcCA9ICgocmlnaHQgPj4+IDIpIF4gbGVmdCkgJiAweDMzMzMzMzMzOwogIGxlZnQgXj0gdG1wOwogIHJpZ2h0IF49ICh0bXAgPDwgMik7CgogIHRtcCA9ICgocmlnaHQgPj4+IDgpIF4gbGVmdCkgJiAweDAwZmYwMGZmOwogIGxlZnQgXj0gdG1wOwogIHJpZ2h0IF49ICh0bXAgPDwgOCk7CgogIHRtcCA9ICgobGVmdCA+Pj4gMSkgXiByaWdodCkgJiAweDU1NTU1NTU1OwogIHJpZ2h0IF49IHRtcDsKICBsZWZ0IF49ICh0bXAgPDwgMSk7CgogIC8vIHJvdGF0ZSBsZWZ0IDEgYml0CiAgbGVmdCA9ICgobGVmdCA8PCAxKSB8IChsZWZ0ID4+PiAzMSkpOwogIHJpZ2h0ID0gKChyaWdodCA8PCAxKSB8IChyaWdodCA+Pj4gMzEpKTsKCiAgZm9yKHZhciBqID0gMDsgaiA8IGl0ZXJhdGlvbnM7IGogKz0gMykgewogICAgdmFyIGVuZGxvb3AgPSBsb29waW5nW2ogKyAxXTsKICAgIHZhciBsb29waW5jID0gbG9vcGluZ1tqICsgMl07CgogICAgLy8gbm93IGdvIHRocm91Z2ggYW5kIHBlcmZvcm0gdGhlIGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbgogICAgZm9yKHZhciBpID0gbG9vcGluZ1tqXTsgaSAhPSBlbmRsb29wOyBpICs9IGxvb3BpbmMpIHsKICAgICAgdmFyIHJpZ2h0MSA9IHJpZ2h0IF4ga2V5c1tpXTsKICAgICAgdmFyIHJpZ2h0MiA9ICgocmlnaHQgPj4+IDQpIHwgKHJpZ2h0IDw8IDI4KSkgXiBrZXlzW2kgKyAxXTsKCiAgICAgIC8vIHBhc3NpbmcgdGhlc2UgYnl0ZXMgdGhyb3VnaCB0aGUgUyBzZWxlY3Rpb24gZnVuY3Rpb25zCiAgICAgIHRtcCA9IGxlZnQ7CiAgICAgIGxlZnQgPSByaWdodDsKICAgICAgcmlnaHQgPSB0bXAgXiAoCiAgICAgICAgc3BmdW5jdGlvbjJbKHJpZ2h0MSA+Pj4gMjQpICYgMHgzZl0gfAogICAgICAgIHNwZnVuY3Rpb240WyhyaWdodDEgPj4+IDE2KSAmIDB4M2ZdIHwKICAgICAgICBzcGZ1bmN0aW9uNlsocmlnaHQxID4+PiAgOCkgJiAweDNmXSB8CiAgICAgICAgc3BmdW5jdGlvbjhbcmlnaHQxICYgMHgzZl0gfAogICAgICAgIHNwZnVuY3Rpb24xWyhyaWdodDIgPj4+IDI0KSAmIDB4M2ZdIHwKICAgICAgICBzcGZ1bmN0aW9uM1socmlnaHQyID4+PiAxNikgJiAweDNmXSB8CiAgICAgICAgc3BmdW5jdGlvbjVbKHJpZ2h0MiA+Pj4gIDgpICYgMHgzZl0gfAogICAgICAgIHNwZnVuY3Rpb243W3JpZ2h0MiAmIDB4M2ZdKTsKICAgIH0KICAgIC8vIHVucmV2ZXJzZSBsZWZ0IGFuZCByaWdodAogICAgdG1wID0gbGVmdDsKICAgIGxlZnQgPSByaWdodDsKICAgIHJpZ2h0ID0gdG1wOwogIH0KCiAgLy8gcm90YXRlIHJpZ2h0IDEgYml0CiAgbGVmdCA9ICgobGVmdCA+Pj4gMSkgfCAobGVmdCA8PCAzMSkpOwogIHJpZ2h0ID0gKChyaWdodCA+Pj4gMSkgfCAocmlnaHQgPDwgMzEpKTsKCiAgLy8gbm93IHBlcmZvcm0gSVAtMSwgd2hpY2ggaXMgSVAgaW4gdGhlIG9wcG9zaXRlIGRpcmVjdGlvbgogIHRtcCA9ICgobGVmdCA+Pj4gMSkgXiByaWdodCkgJiAweDU1NTU1NTU1OwogIHJpZ2h0IF49IHRtcDsKICBsZWZ0IF49ICh0bXAgPDwgMSk7CgogIHRtcCA9ICgocmlnaHQgPj4+IDgpIF4gbGVmdCkgJiAweDAwZmYwMGZmOwogIGxlZnQgXj0gdG1wOwogIHJpZ2h0IF49ICh0bXAgPDwgOCk7CgogIHRtcCA9ICgocmlnaHQgPj4+IDIpIF4gbGVmdCkgJiAweDMzMzMzMzMzOwogIGxlZnQgXj0gdG1wOwogIHJpZ2h0IF49ICh0bXAgPDwgMik7CgogIHRtcCA9ICgobGVmdCA+Pj4gMTYpIF4gcmlnaHQpICYgMHgwMDAwZmZmZjsKICByaWdodCBePSB0bXA7CiAgbGVmdCBePSAodG1wIDw8IDE2KTsKCiAgdG1wID0gKChsZWZ0ID4+PiA0KSBeIHJpZ2h0KSAmIDB4MGYwZjBmMGY7CiAgcmlnaHQgXj0gdG1wOwogIGxlZnQgXj0gKHRtcCA8PCA0KTsKCiAgb3V0cHV0WzBdID0gbGVmdDsKICBvdXRwdXRbMV0gPSByaWdodDsKfQoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogZm9yZ2UuY2lwaGVyLmNyZWF0ZUNpcGhlcignREVTLTxtb2RlPicsIGtleSk7CiAqIGZvcmdlLmNpcGhlci5jcmVhdGVEZWNpcGhlcignREVTLTxtb2RlPicsIGtleSk7CiAqCiAqIENyZWF0ZXMgYSBkZXByZWNhdGVkIERFUyBjaXBoZXIgb2JqZWN0LiBUaGlzIG9iamVjdCdzIG1vZGUgd2lsbCBkZWZhdWx0IHRvCiAqIENCQyAoY2lwaGVyLWJsb2NrLWNoYWluaW5nKS4KICoKICogVGhlIGtleSBtYXkgYmUgZ2l2ZW4gYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMgb3IgYSBieXRlIGJ1ZmZlci4KICoKICogQHBhcmFtIG9wdGlvbnMgdGhlIG9wdGlvbnMgdG8gdXNlLgogKiAgICAgICAgICBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlICg2NCBvciAxOTIgYml0cykuCiAqICAgICAgICAgIG91dHB1dCB0aGUgYnVmZmVyIHRvIHdyaXRlIHRvLgogKiAgICAgICAgICBkZWNyeXB0IHRydWUgZm9yIGRlY3J5cHRpb24sIGZhbHNlIGZvciBlbmNyeXB0aW9uLgogKiAgICAgICAgICBtb2RlIHRoZSBjaXBoZXIgbW9kZSB0byB1c2UgKGRlZmF1bHQ6ICdDQkMnKS4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZnVuY3Rpb24gX2NyZWF0ZUNpcGhlcihvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdmFyIG1vZGUgPSAob3B0aW9ucy5tb2RlIHx8ICdDQkMnKS50b1VwcGVyQ2FzZSgpOwogIHZhciBhbGdvcml0aG0gPSAnREVTLScgKyBtb2RlOwoKICB2YXIgY2lwaGVyOwogIGlmKG9wdGlvbnMuZGVjcnlwdCkgewogICAgY2lwaGVyID0gZm9yZ2UuY2lwaGVyLmNyZWF0ZURlY2lwaGVyKGFsZ29yaXRobSwgb3B0aW9ucy5rZXkpOwogIH0gZWxzZSB7CiAgICBjaXBoZXIgPSBmb3JnZS5jaXBoZXIuY3JlYXRlQ2lwaGVyKGFsZ29yaXRobSwgb3B0aW9ucy5rZXkpOwogIH0KCiAgLy8gYmFja3dhcmRzIGNvbXBhdGlibGUgc3RhcnQgQVBJCiAgdmFyIHN0YXJ0ID0gY2lwaGVyLnN0YXJ0OwogIGNpcGhlci5zdGFydCA9IGZ1bmN0aW9uKGl2LCBvcHRpb25zKSB7CiAgICAvLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eTogc3VwcG9ydCBzZWNvbmQgYXJnIGFzIG91dHB1dCBidWZmZXIKICAgIHZhciBvdXRwdXQgPSBudWxsOwogICAgaWYob3B0aW9ucyBpbnN0YW5jZW9mIGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcikgewogICAgICBvdXRwdXQgPSBvcHRpb25zOwogICAgICBvcHRpb25zID0ge307CiAgICB9CiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICAgIG9wdGlvbnMub3V0cHV0ID0gb3V0cHV0OwogICAgb3B0aW9ucy5pdiA9IGl2OwogICAgc3RhcnQuY2FsbChjaXBoZXIsIG9wdGlvbnMpOwogIH07CgogIHJldHVybiBjaXBoZXI7Cn0KCgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdkZXMnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgKICAnanMvZGVzJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vY2lwaGVyJywgJy4vY2lwaGVyTW9kZXMnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFBhc3N3b3JkLUJhc2VkIEtleS1EZXJpdmF0aW9uIEZ1bmN0aW9uICMyIGltcGxlbWVudGF0aW9uLgogKgogKiBTZWUgUkZDIDI4OTggZm9yIGRldGFpbHMuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDEzIERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKdmFyIHBrY3M1ID0gZm9yZ2UucGtjczUgPSBmb3JnZS5wa2NzNSB8fCB7fTsKCnZhciBfbm9kZWpzID0gKAogIHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLnZlcnNpb25zICYmIHByb2Nlc3MudmVyc2lvbnMubm9kZSk7CnZhciBjcnlwdG87CmlmKF9ub2RlanMgJiYgIWZvcmdlLmRpc2FibGVOYXRpdmVDb2RlKSB7CiAgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7Cn0KCi8qKgogKiBEZXJpdmVzIGEga2V5IGZyb20gYSBwYXNzd29yZC4KICoKICogQHBhcmFtIHAgdGhlIHBhc3N3b3JkIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzLgogKiBAcGFyYW0gcyB0aGUgc2FsdCBhcyBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZyBvZiBieXRlcy4KICogQHBhcmFtIGMgdGhlIGl0ZXJhdGlvbiBjb3VudCwgYSBwb3NpdGl2ZSBpbnRlZ2VyLgogKiBAcGFyYW0gZGtMZW4gdGhlIGludGVuZGVkIGxlbmd0aCwgaW4gYnl0ZXMsIG9mIHRoZSBkZXJpdmVkIGtleSwKICogICAgICAgICAgKG1heDogMl4zMiAtIDEpICogaGFzaCBsZW5ndGggb2YgdGhlIFBSRi4KICogQHBhcmFtIFttZF0gdGhlIG1lc3NhZ2UgZGlnZXN0IChvciBhbGdvcml0aG0gaWRlbnRpZmllciBhcyBhIHN0cmluZykgdG8gdXNlCiAqICAgICAgICAgIGluIHRoZSBQUkYsIGRlZmF1bHRzIHRvIFNIQS0xLgogKiBAcGFyYW0gW2NhbGxiYWNrKGVyciwga2V5KV0gcHJlc2VuY2UgdHJpZ2dlcnMgYXN5bmNocm9ub3VzIHZlcnNpb24sIGNhbGxlZAogKiAgICAgICAgICBvbmNlIHRoZSBvcGVyYXRpb24gY29tcGxldGVzLgogKgogKiBAcmV0dXJuIHRoZSBkZXJpdmVkIGtleSwgYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMsIGZvciB0aGUKICogICAgICAgICAgIHN5bmNocm9ub3VzIHZlcnNpb24gKGlmIG5vIGNhbGxiYWNrIGlzIHNwZWNpZmllZCkuCiAqLwpmb3JnZS5wYmtkZjIgPSBwa2NzNS5wYmtkZjIgPSBmdW5jdGlvbihwLCBzLCBjLCBka0xlbiwgbWQsIGNhbGxiYWNrKSB7CiAgaWYodHlwZW9mIG1kID09PSAnZnVuY3Rpb24nKSB7CiAgICBjYWxsYmFjayA9IG1kOwogICAgbWQgPSBudWxsOwogIH0KCiAgLy8gdXNlIG5hdGl2ZSBpbXBsZW1lbnRhdGlvbiBpZiBwb3NzaWJsZSBhbmQgbm90IGRpc2FibGVkLCBub3RlIHRoYXQKICAvLyBzb21lIG5vZGUgdmVyc2lvbnMgb25seSBzdXBwb3J0IFNIQS0xLCBvdGhlcnMgYWxsb3cgZGlnZXN0IHRvIGJlIGNoYW5nZWQKICBpZihfbm9kZWpzICYmICFmb3JnZS5kaXNhYmxlTmF0aXZlQ29kZSAmJiBjcnlwdG8ucGJrZGYyICYmCiAgICAobWQgPT09IG51bGwgfHwgdHlwZW9mIG1kICE9PSAnb2JqZWN0JykgJiYKICAgIChjcnlwdG8ucGJrZGYyU3luYy5sZW5ndGggPiA0IHx8ICghbWQgfHwgbWQgPT09ICdzaGExJykpKSB7CiAgICBpZih0eXBlb2YgbWQgIT09ICdzdHJpbmcnKSB7CiAgICAgIC8vIGRlZmF1bHQgcHJmIHRvIFNIQS0xCiAgICAgIG1kID0gJ3NoYTEnOwogICAgfQogICAgcyA9IG5ldyBCdWZmZXIocywgJ2JpbmFyeScpOwogICAgaWYoIWNhbGxiYWNrKSB7CiAgICAgIGlmKGNyeXB0by5wYmtkZjJTeW5jLmxlbmd0aCA9PT0gNCkgewogICAgICAgIHJldHVybiBjcnlwdG8ucGJrZGYyU3luYyhwLCBzLCBjLCBka0xlbikudG9TdHJpbmcoJ2JpbmFyeScpOwogICAgICB9CiAgICAgIHJldHVybiBjcnlwdG8ucGJrZGYyU3luYyhwLCBzLCBjLCBka0xlbiwgbWQpLnRvU3RyaW5nKCdiaW5hcnknKTsKICAgIH0KICAgIGlmKGNyeXB0by5wYmtkZjJTeW5jLmxlbmd0aCA9PT0gNCkgewogICAgICByZXR1cm4gY3J5cHRvLnBia2RmMihwLCBzLCBjLCBka0xlbiwgZnVuY3Rpb24oZXJyLCBrZXkpIHsKICAgICAgICBpZihlcnIpIHsKICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpOwogICAgICAgIH0KICAgICAgICBjYWxsYmFjayhudWxsLCBrZXkudG9TdHJpbmcoJ2JpbmFyeScpKTsKICAgICAgfSk7CiAgICB9CiAgICByZXR1cm4gY3J5cHRvLnBia2RmMihwLCBzLCBjLCBka0xlbiwgbWQsIGZ1bmN0aW9uKGVyciwga2V5KSB7CiAgICAgIGlmKGVycikgewogICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpOwogICAgICB9CiAgICAgIGNhbGxiYWNrKG51bGwsIGtleS50b1N0cmluZygnYmluYXJ5JykpOwogICAgfSk7CiAgfQoKICBpZih0eXBlb2YgbWQgPT09ICd1bmRlZmluZWQnIHx8IG1kID09PSBudWxsKSB7CiAgICAvLyBkZWZhdWx0IHByZiB0byBTSEEtMQogICAgbWQgPSBmb3JnZS5tZC5zaGExLmNyZWF0ZSgpOwogIH0KICBpZih0eXBlb2YgbWQgPT09ICdzdHJpbmcnKSB7CiAgICBpZighKG1kIGluIGZvcmdlLm1kLmFsZ29yaXRobXMpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBoYXNoIGFsZ29yaXRobTogJyArIG1kKTsKICAgIH0KICAgIG1kID0gZm9yZ2UubWRbbWRdLmNyZWF0ZSgpOwogIH0KCiAgdmFyIGhMZW4gPSBtZC5kaWdlc3RMZW5ndGg7CgogIC8qIDEuIElmIGRrTGVuID4gKDJeMzIgLSAxKSAqIGhMZW4sIG91dHB1dCAiZGVyaXZlZCBrZXkgdG9vIGxvbmciIGFuZAogICAgc3RvcC4gKi8KICBpZihka0xlbiA+ICgweEZGRkZGRkZGICogaExlbikpIHsKICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ0Rlcml2ZWQga2V5IGlzIHRvbyBsb25nLicpOwogICAgaWYoY2FsbGJhY2spIHsKICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7CiAgICB9CiAgICB0aHJvdyBlcnI7CiAgfQoKICAvKiAyLiBMZXQgbGVuIGJlIHRoZSBudW1iZXIgb2YgaExlbi1vY3RldCBibG9ja3MgaW4gdGhlIGRlcml2ZWQga2V5LAogICAgcm91bmRpbmcgdXAsIGFuZCBsZXQgciBiZSB0aGUgbnVtYmVyIG9mIG9jdGV0cyBpbiB0aGUgbGFzdAogICAgYmxvY2s6CgogICAgbGVuID0gQ0VJTChka0xlbiAvIGhMZW4pLAogICAgciA9IGRrTGVuIC0gKGxlbiAtIDEpICogaExlbi4gKi8KICB2YXIgbGVuID0gTWF0aC5jZWlsKGRrTGVuIC8gaExlbik7CiAgdmFyIHIgPSBka0xlbiAtIChsZW4gLSAxKSAqIGhMZW47CgogIC8qIDMuIEZvciBlYWNoIGJsb2NrIG9mIHRoZSBkZXJpdmVkIGtleSBhcHBseSB0aGUgZnVuY3Rpb24gRiBkZWZpbmVkCiAgICBiZWxvdyB0byB0aGUgcGFzc3dvcmQgUCwgdGhlIHNhbHQgUywgdGhlIGl0ZXJhdGlvbiBjb3VudCBjLCBhbmQKICAgIHRoZSBibG9jayBpbmRleCB0byBjb21wdXRlIHRoZSBibG9jazoKCiAgICBUXzEgPSBGKFAsIFMsIGMsIDEpLAogICAgVF8yID0gRihQLCBTLCBjLCAyKSwKICAgIC4uLgogICAgVF9sZW4gPSBGKFAsIFMsIGMsIGxlbiksCgogICAgd2hlcmUgdGhlIGZ1bmN0aW9uIEYgaXMgZGVmaW5lZCBhcyB0aGUgZXhjbHVzaXZlLW9yIHN1bSBvZiB0aGUKICAgIGZpcnN0IGMgaXRlcmF0ZXMgb2YgdGhlIHVuZGVybHlpbmcgcHNldWRvcmFuZG9tIGZ1bmN0aW9uIFBSRgogICAgYXBwbGllZCB0byB0aGUgcGFzc3dvcmQgUCBhbmQgdGhlIGNvbmNhdGVuYXRpb24gb2YgdGhlIHNhbHQgUwogICAgYW5kIHRoZSBibG9jayBpbmRleCBpOgoKICAgIEYoUCwgUywgYywgaSkgPSB1XzEgWE9SIHVfMiBYT1IgLi4uIFhPUiB1X2MKCiAgICB3aGVyZQoKICAgIHVfMSA9IFBSRihQLCBTIHx8IElOVChpKSksCiAgICB1XzIgPSBQUkYoUCwgdV8xKSwKICAgIC4uLgogICAgdV9jID0gUFJGKFAsIHVfe2MtMX0pLgoKICAgIEhlcmUsIElOVChpKSBpcyBhIGZvdXItb2N0ZXQgZW5jb2Rpbmcgb2YgdGhlIGludGVnZXIgaSwgbW9zdAogICAgc2lnbmlmaWNhbnQgb2N0ZXQgZmlyc3QuICovCiAgdmFyIHByZiA9IGZvcmdlLmhtYWMuY3JlYXRlKCk7CiAgcHJmLnN0YXJ0KG1kLCBwKTsKICB2YXIgZGsgPSAnJzsKICB2YXIgeG9yLCB1X2MsIHVfYzE7CgogIC8vIHN5bmMgdmVyc2lvbgogIGlmKCFjYWxsYmFjaykgewogICAgZm9yKHZhciBpID0gMTsgaSA8PSBsZW47ICsraSkgewogICAgICAvLyBQUkYoUCwgUyB8fCBJTlQoaSkpIChmaXJzdCBpdGVyYXRpb24pCiAgICAgIHByZi5zdGFydChudWxsLCBudWxsKTsKICAgICAgcHJmLnVwZGF0ZShzKTsKICAgICAgcHJmLnVwZGF0ZShmb3JnZS51dGlsLmludDMyVG9CeXRlcyhpKSk7CiAgICAgIHhvciA9IHVfYzEgPSBwcmYuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKCiAgICAgIC8vIFBSRihQLCB1X3tjLTF9KSAob3RoZXIgaXRlcmF0aW9ucykKICAgICAgZm9yKHZhciBqID0gMjsgaiA8PSBjOyArK2opIHsKICAgICAgICBwcmYuc3RhcnQobnVsbCwgbnVsbCk7CiAgICAgICAgcHJmLnVwZGF0ZSh1X2MxKTsKICAgICAgICB1X2MgPSBwcmYuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKICAgICAgICAvLyBGKHAsIHMsIGMsIGkpCiAgICAgICAgeG9yID0gZm9yZ2UudXRpbC54b3JCeXRlcyh4b3IsIHVfYywgaExlbik7CiAgICAgICAgdV9jMSA9IHVfYzsKICAgICAgfQoKICAgICAgLyogNC4gQ29uY2F0ZW5hdGUgdGhlIGJsb2NrcyBhbmQgZXh0cmFjdCB0aGUgZmlyc3QgZGtMZW4gb2N0ZXRzIHRvCiAgICAgICAgcHJvZHVjZSBhIGRlcml2ZWQga2V5IERLOgoKICAgICAgICBESyA9IFRfMSB8fCBUXzIgfHwgIC4uLiAgfHwgVF9sZW48MC4uci0xPiAqLwogICAgICBkayArPSAoaSA8IGxlbikgPyB4b3IgOiB4b3Iuc3Vic3RyKDAsIHIpOwogICAgfQogICAgLyogNS4gT3V0cHV0IHRoZSBkZXJpdmVkIGtleSBESy4gKi8KICAgIHJldHVybiBkazsKICB9CgogIC8vIGFzeW5jIHZlcnNpb24KICB2YXIgaSA9IDEsIGo7CiAgZnVuY3Rpb24gb3V0ZXIoKSB7CiAgICBpZihpID4gbGVuKSB7CiAgICAgIC8vIGRvbmUKICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGRrKTsKICAgIH0KCiAgICAvLyBQUkYoUCwgUyB8fCBJTlQoaSkpIChmaXJzdCBpdGVyYXRpb24pCiAgICBwcmYuc3RhcnQobnVsbCwgbnVsbCk7CiAgICBwcmYudXBkYXRlKHMpOwogICAgcHJmLnVwZGF0ZShmb3JnZS51dGlsLmludDMyVG9CeXRlcyhpKSk7CiAgICB4b3IgPSB1X2MxID0gcHJmLmRpZ2VzdCgpLmdldEJ5dGVzKCk7CgogICAgLy8gUFJGKFAsIHVfe2MtMX0pIChvdGhlciBpdGVyYXRpb25zKQogICAgaiA9IDI7CiAgICBpbm5lcigpOwogIH0KCiAgZnVuY3Rpb24gaW5uZXIoKSB7CiAgICBpZihqIDw9IGMpIHsKICAgICAgcHJmLnN0YXJ0KG51bGwsIG51bGwpOwogICAgICBwcmYudXBkYXRlKHVfYzEpOwogICAgICB1X2MgPSBwcmYuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKICAgICAgLy8gRihwLCBzLCBjLCBpKQogICAgICB4b3IgPSBmb3JnZS51dGlsLnhvckJ5dGVzKHhvciwgdV9jLCBoTGVuKTsKICAgICAgdV9jMSA9IHVfYzsKICAgICAgKytqOwogICAgICByZXR1cm4gZm9yZ2UudXRpbC5zZXRJbW1lZGlhdGUoaW5uZXIpOwogICAgfQoKICAgIC8qIDQuIENvbmNhdGVuYXRlIHRoZSBibG9ja3MgYW5kIGV4dHJhY3QgdGhlIGZpcnN0IGRrTGVuIG9jdGV0cyB0bwogICAgICBwcm9kdWNlIGEgZGVyaXZlZCBrZXkgREs6CgogICAgICBESyA9IFRfMSB8fCBUXzIgfHwgIC4uLiAgfHwgVF9sZW48MC4uci0xPiAqLwogICAgZGsgKz0gKGkgPCBsZW4pID8geG9yIDogeG9yLnN1YnN0cigwLCByKTsKCiAgICArK2k7CiAgICBvdXRlcigpOwogIH0KCiAgb3V0ZXIoKTsKfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3Bia2RmMic7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9wYmtkZjInLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9obWFjJywgJy4vbWQnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIEEgamF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBhIGNyeXB0b2dyYXBoaWNhbGx5LXNlY3VyZQogKiBQc2V1ZG8gUmFuZG9tIE51bWJlciBHZW5lcmF0b3IgKFBSTkcpLiBUaGUgRm9ydHVuYSBhbGdvcml0aG0gaXMgZm9sbG93ZWQKICogaGVyZSB0aG91Z2ggdGhlIHVzZSBvZiBTSEEtMjU2IGlzIG5vdCBlbmZvcmNlZDsgd2hlbiBnZW5lcmF0aW5nIGFuCiAqIGEgUFJORyBjb250ZXh0LCB0aGUgaGFzaGluZyBhbGdvcml0aG0gYW5kIGJsb2NrIGNpcGhlciB1c2VkIGZvcgogKiB0aGUgZ2VuZXJhdG9yIGFyZSBzcGVjaWZpZWQgdmlhIGEgcGx1Z2luLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCnZhciBfbm9kZWpzID0gKAogIHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLnZlcnNpb25zICYmIHByb2Nlc3MudmVyc2lvbnMubm9kZSk7CnZhciBfY3J5cHRvID0gbnVsbDsKaWYoIWZvcmdlLmRpc2FibGVOYXRpdmVDb2RlICYmIF9ub2RlanMgJiYgIXByb2Nlc3MudmVyc2lvbnNbJ25vZGUtd2Via2l0J10pIHsKICBfY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7Cn0KCi8qIFBSTkcgQVBJICovCnZhciBwcm5nID0gZm9yZ2UucHJuZyA9IGZvcmdlLnBybmcgfHwge307CgovKioKICogQ3JlYXRlcyBhIG5ldyBQUk5HIGNvbnRleHQuCiAqCiAqIEEgUFJORyBwbHVnaW4gbXVzdCBiZSBwYXNzZWQgaW4gdGhhdCB3aWxsIHByb3ZpZGU6CiAqCiAqIDEuIEEgZnVuY3Rpb24gdGhhdCBpbml0aWFsaXplcyB0aGUga2V5IGFuZCBzZWVkIG9mIGEgUFJORyBjb250ZXh0LiBJdAogKiAgIHdpbGwgYmUgZ2l2ZW4gYSAxNiBieXRlIGtleSBhbmQgYSAxNiBieXRlIHNlZWQuIEFueSBrZXkgZXhwYW5zaW9uCiAqICAgb3IgdHJhbnNmb3JtYXRpb24gb2YgdGhlIHNlZWQgZnJvbSBhIGJ5dGUgc3RyaW5nIGludG8gYW4gYXJyYXkgb2YKICogICBpbnRlZ2VycyAob3Igc2ltaWxhcikgc2hvdWxkIGJlIHBlcmZvcm1lZC4KICogMi4gVGhlIGNyeXB0b2dyYXBoaWMgZnVuY3Rpb24gdXNlZCBieSB0aGUgZ2VuZXJhdG9yLiBJdCB0YWtlcyBhIGtleSBhbmQKICogICBhIHNlZWQuCiAqIDMuIEEgc2VlZCBpbmNyZW1lbnQgZnVuY3Rpb24uIEl0IHRha2VzIHRoZSBzZWVkIGFuZCByZXR1cm5zIHNlZWQgKyAxLgogKiA0LiBBbiBhcGkgdG8gY3JlYXRlIGEgbWVzc2FnZSBkaWdlc3QuCiAqCiAqIEZvciBhbiBleGFtcGxlLCBzZWUgcmFuZG9tLmpzLgogKgogKiBAcGFyYW0gcGx1Z2luIHRoZSBQUk5HIHBsdWdpbiB0byB1c2UuCiAqLwpwcm5nLmNyZWF0ZSA9IGZ1bmN0aW9uKHBsdWdpbikgewogIHZhciBjdHggPSB7CiAgICBwbHVnaW46IHBsdWdpbiwKICAgIGtleTogbnVsbCwKICAgIHNlZWQ6IG51bGwsCiAgICB0aW1lOiBudWxsLAogICAgLy8gbnVtYmVyIG9mIHJlc2VlZHMgc28gZmFyCiAgICByZXNlZWRzOiAwLAogICAgLy8gYW1vdW50IG9mIGRhdGEgZ2VuZXJhdGVkIHNvIGZhcgogICAgZ2VuZXJhdGVkOiAwCiAgfTsKCiAgLy8gY3JlYXRlIDMyIGVudHJvcHkgcG9vbHMgKGVhY2ggaXMgYSBtZXNzYWdlIGRpZ2VzdCkKICB2YXIgbWQgPSBwbHVnaW4ubWQ7CiAgdmFyIHBvb2xzID0gbmV3IEFycmF5KDMyKTsKICBmb3IodmFyIGkgPSAwOyBpIDwgMzI7ICsraSkgewogICAgcG9vbHNbaV0gPSBtZC5jcmVhdGUoKTsKICB9CiAgY3R4LnBvb2xzID0gcG9vbHM7CgogIC8vIGVudHJvcHkgcG9vbHMgYXJlIHdyaXR0ZW4gdG8gY3ljbGljYWxseSwgc3RhcnRpbmcgYXQgaW5kZXggMAogIGN0eC5wb29sID0gMDsKCiAgLyoqCiAgICogR2VuZXJhdGVzIHJhbmRvbSBieXRlcy4gVGhlIGJ5dGVzIG1heSBiZSBnZW5lcmF0ZWQgc3luY2hyb25vdXNseSBvcgogICAqIGFzeW5jaHJvbm91c2x5LiBXZWIgd29ya2VycyBtdXN0IHVzZSB0aGUgYXN5bmNocm9ub3VzIGludGVyZmFjZSBvcgogICAqIGVsc2UgdGhlIGJlaGF2aW9yIGlzIHVuZGVmaW5lZC4KICAgKgogICAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIHJhbmRvbSBieXRlcyB0byBnZW5lcmF0ZS4KICAgKiBAcGFyYW0gW2NhbGxiYWNrKGVyciwgYnl0ZXMpXSBjYWxsZWQgb25jZSB0aGUgb3BlcmF0aW9uIGNvbXBsZXRlcy4KICAgKgogICAqIEByZXR1cm4gY291bnQgcmFuZG9tIGJ5dGVzIGFzIGEgc3RyaW5nLgogICAqLwogIGN0eC5nZW5lcmF0ZSA9IGZ1bmN0aW9uKGNvdW50LCBjYWxsYmFjaykgewogICAgLy8gZG8gc3luY2hyb25vdXNseQogICAgaWYoIWNhbGxiYWNrKSB7CiAgICAgIHJldHVybiBjdHguZ2VuZXJhdGVTeW5jKGNvdW50KTsKICAgIH0KCiAgICAvLyBzaW1wbGUgZ2VuZXJhdG9yIHVzaW5nIGNvdW50ZXItYmFzZWQgQ0JDCiAgICB2YXIgY2lwaGVyID0gY3R4LnBsdWdpbi5jaXBoZXI7CiAgICB2YXIgaW5jcmVtZW50ID0gY3R4LnBsdWdpbi5pbmNyZW1lbnQ7CiAgICB2YXIgZm9ybWF0S2V5ID0gY3R4LnBsdWdpbi5mb3JtYXRLZXk7CiAgICB2YXIgZm9ybWF0U2VlZCA9IGN0eC5wbHVnaW4uZm9ybWF0U2VlZDsKICAgIHZhciBiID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKCiAgICAvLyByZXNldCBrZXkgZm9yIGV2ZXJ5IHJlcXVlc3QKICAgIGN0eC5rZXkgPSBudWxsOwoKICAgIGdlbmVyYXRlKCk7CgogICAgZnVuY3Rpb24gZ2VuZXJhdGUoZXJyKSB7CiAgICAgIGlmKGVycikgewogICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpOwogICAgICB9CgogICAgICAvLyBzdWZmaWNpZW50IGJ5dGVzIGdlbmVyYXRlZAogICAgICBpZihiLmxlbmd0aCgpID49IGNvdW50KSB7CiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGIuZ2V0Qnl0ZXMoY291bnQpKTsKICAgICAgfQoKICAgICAgLy8gaWYgYW1vdW50IG9mIGRhdGEgZ2VuZXJhdGVkIGlzIGdyZWF0ZXIgdGhhbiAxIE1pQiwgdHJpZ2dlciByZXNlZWQKICAgICAgaWYoY3R4LmdlbmVyYXRlZCA+IDB4ZmZmZmYpIHsKICAgICAgICBjdHgua2V5ID0gbnVsbDsKICAgICAgfQoKICAgICAgaWYoY3R4LmtleSA9PT0gbnVsbCkgewogICAgICAgIC8vIHByZXZlbnQgc3RhY2sgb3ZlcmZsb3cKICAgICAgICByZXR1cm4gZm9yZ2UudXRpbC5uZXh0VGljayhmdW5jdGlvbigpIHsKICAgICAgICAgIF9yZXNlZWQoZ2VuZXJhdGUpOwogICAgICAgIH0pOwogICAgICB9CgogICAgICAvLyBnZW5lcmF0ZSB0aGUgcmFuZG9tIGJ5dGVzCiAgICAgIHZhciBieXRlcyA9IGNpcGhlcihjdHgua2V5LCBjdHguc2VlZCk7CiAgICAgIGN0eC5nZW5lcmF0ZWQgKz0gYnl0ZXMubGVuZ3RoOwogICAgICBiLnB1dEJ5dGVzKGJ5dGVzKTsKCiAgICAgIC8vIGdlbmVyYXRlIGJ5dGVzIGZvciBhIG5ldyBrZXkgYW5kIHNlZWQKICAgICAgY3R4LmtleSA9IGZvcm1hdEtleShjaXBoZXIoY3R4LmtleSwgaW5jcmVtZW50KGN0eC5zZWVkKSkpOwogICAgICBjdHguc2VlZCA9IGZvcm1hdFNlZWQoY2lwaGVyKGN0eC5rZXksIGN0eC5zZWVkKSk7CgogICAgICBmb3JnZS51dGlsLnNldEltbWVkaWF0ZShnZW5lcmF0ZSk7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogR2VuZXJhdGVzIHJhbmRvbSBieXRlcyBzeW5jaHJvbm91c2x5LgogICAqCiAgICogQHBhcmFtIGNvdW50IHRoZSBudW1iZXIgb2YgcmFuZG9tIGJ5dGVzIHRvIGdlbmVyYXRlLgogICAqCiAgICogQHJldHVybiBjb3VudCByYW5kb20gYnl0ZXMgYXMgYSBzdHJpbmcuCiAgICovCiAgY3R4LmdlbmVyYXRlU3luYyA9IGZ1bmN0aW9uKGNvdW50KSB7CiAgICAvLyBzaW1wbGUgZ2VuZXJhdG9yIHVzaW5nIGNvdW50ZXItYmFzZWQgQ0JDCiAgICB2YXIgY2lwaGVyID0gY3R4LnBsdWdpbi5jaXBoZXI7CiAgICB2YXIgaW5jcmVtZW50ID0gY3R4LnBsdWdpbi5pbmNyZW1lbnQ7CiAgICB2YXIgZm9ybWF0S2V5ID0gY3R4LnBsdWdpbi5mb3JtYXRLZXk7CiAgICB2YXIgZm9ybWF0U2VlZCA9IGN0eC5wbHVnaW4uZm9ybWF0U2VlZDsKCiAgICAvLyByZXNldCBrZXkgZm9yIGV2ZXJ5IHJlcXVlc3QKICAgIGN0eC5rZXkgPSBudWxsOwoKICAgIHZhciBiID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIHdoaWxlKGIubGVuZ3RoKCkgPCBjb3VudCkgewogICAgICAvLyBpZiBhbW91bnQgb2YgZGF0YSBnZW5lcmF0ZWQgaXMgZ3JlYXRlciB0aGFuIDEgTWlCLCB0cmlnZ2VyIHJlc2VlZAogICAgICBpZihjdHguZ2VuZXJhdGVkID4gMHhmZmZmZikgewogICAgICAgIGN0eC5rZXkgPSBudWxsOwogICAgICB9CgogICAgICBpZihjdHgua2V5ID09PSBudWxsKSB7CiAgICAgICAgX3Jlc2VlZFN5bmMoKTsKICAgICAgfQoKICAgICAgLy8gZ2VuZXJhdGUgdGhlIHJhbmRvbSBieXRlcwogICAgICB2YXIgYnl0ZXMgPSBjaXBoZXIoY3R4LmtleSwgY3R4LnNlZWQpOwogICAgICBjdHguZ2VuZXJhdGVkICs9IGJ5dGVzLmxlbmd0aDsKICAgICAgYi5wdXRCeXRlcyhieXRlcyk7CgogICAgICAvLyBnZW5lcmF0ZSBieXRlcyBmb3IgYSBuZXcga2V5IGFuZCBzZWVkCiAgICAgIGN0eC5rZXkgPSBmb3JtYXRLZXkoY2lwaGVyKGN0eC5rZXksIGluY3JlbWVudChjdHguc2VlZCkpKTsKICAgICAgY3R4LnNlZWQgPSBmb3JtYXRTZWVkKGNpcGhlcihjdHgua2V5LCBjdHguc2VlZCkpOwogICAgfQoKICAgIHJldHVybiBiLmdldEJ5dGVzKGNvdW50KTsKICB9OwoKICAvKioKICAgKiBQcml2YXRlIGZ1bmN0aW9uIHRoYXQgYXN5bmNocm9ub3VzbHkgcmVzZWVkcyBhIGdlbmVyYXRvci4KICAgKgogICAqIEBwYXJhbSBjYWxsYmFjayhlcnIpIGNhbGxlZCBvbmNlIHRoZSBvcGVyYXRpb24gY29tcGxldGVzLgogICAqLwogIGZ1bmN0aW9uIF9yZXNlZWQoY2FsbGJhY2spIHsKICAgIGlmKGN0eC5wb29sc1swXS5tZXNzYWdlTGVuZ3RoID49IDMyKSB7CiAgICAgIF9zZWVkKCk7CiAgICAgIHJldHVybiBjYWxsYmFjaygpOwogICAgfQogICAgLy8gbm90IGVub3VnaCBzZWVkIGRhdGEuLi4KICAgIHZhciBuZWVkZWQgPSAoMzIgLSBjdHgucG9vbHNbMF0ubWVzc2FnZUxlbmd0aCkgPDwgNTsKICAgIGN0eC5zZWVkRmlsZShuZWVkZWQsIGZ1bmN0aW9uKGVyciwgYnl0ZXMpIHsKICAgICAgaWYoZXJyKSB7CiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7CiAgICAgIH0KICAgICAgY3R4LmNvbGxlY3QoYnl0ZXMpOwogICAgICBfc2VlZCgpOwogICAgICBjYWxsYmFjaygpOwogICAgfSk7CiAgfQoKICAvKioKICAgKiBQcml2YXRlIGZ1bmN0aW9uIHRoYXQgc3luY2hyb25vdXNseSByZXNlZWRzIGEgZ2VuZXJhdG9yLgogICAqLwogIGZ1bmN0aW9uIF9yZXNlZWRTeW5jKCkgewogICAgaWYoY3R4LnBvb2xzWzBdLm1lc3NhZ2VMZW5ndGggPj0gMzIpIHsKICAgICAgcmV0dXJuIF9zZWVkKCk7CiAgICB9CiAgICAvLyBub3QgZW5vdWdoIHNlZWQgZGF0YS4uLgogICAgdmFyIG5lZWRlZCA9ICgzMiAtIGN0eC5wb29sc1swXS5tZXNzYWdlTGVuZ3RoKSA8PCA1OwogICAgY3R4LmNvbGxlY3QoY3R4LnNlZWRGaWxlU3luYyhuZWVkZWQpKTsKICAgIF9zZWVkKCk7CiAgfQoKICAvKioKICAgKiBQcml2YXRlIGZ1bmN0aW9uIHRoYXQgc2VlZHMgYSBnZW5lcmF0b3Igb25jZSBlbm91Z2ggYnl0ZXMgYXJlIGF2YWlsYWJsZS4KICAgKi8KICBmdW5jdGlvbiBfc2VlZCgpIHsKICAgIC8vIGNyZWF0ZSBhIHBsdWdpbi1iYXNlZCBtZXNzYWdlIGRpZ2VzdAogICAgdmFyIG1kID0gY3R4LnBsdWdpbi5tZC5jcmVhdGUoKTsKCiAgICAvLyBkaWdlc3QgcG9vbCAwJ3MgZW50cm9weSBhbmQgcmVzdGFydCBpdAogICAgbWQudXBkYXRlKGN0eC5wb29sc1swXS5kaWdlc3QoKS5nZXRCeXRlcygpKTsKICAgIGN0eC5wb29sc1swXS5zdGFydCgpOwoKICAgIC8vIGRpZ2VzdCB0aGUgZW50cm9weSBvZiBvdGhlciBwb29scyB3aG9zZSBpbmRleCBrIG1lZXQgdGhlCiAgICAvLyBjb25kaXRpb24gJzJeayBtb2QgbiA9PSAwJyB3aGVyZSBuIGlzIHRoZSBudW1iZXIgb2YgcmVzZWVkcwogICAgdmFyIGsgPSAxOwogICAgZm9yKHZhciBpID0gMTsgaSA8IDMyOyArK2kpIHsKICAgICAgLy8gcHJldmVudCBzaWduZWQgbnVtYmVycyBmcm9tIGJlaW5nIHVzZWQKICAgICAgayA9IChrID09PSAzMSkgPyAweDgwMDAwMDAwIDogKGsgPDwgMik7CiAgICAgIGlmKGsgJSBjdHgucmVzZWVkcyA9PT0gMCkgewogICAgICAgIG1kLnVwZGF0ZShjdHgucG9vbHNbaV0uZGlnZXN0KCkuZ2V0Qnl0ZXMoKSk7CiAgICAgICAgY3R4LnBvb2xzW2ldLnN0YXJ0KCk7CiAgICAgIH0KICAgIH0KCiAgICAvLyBnZXQgZGlnZXN0IGZvciBrZXkgYnl0ZXMgYW5kIGl0ZXJhdGUgYWdhaW4gZm9yIHNlZWQgYnl0ZXMKICAgIHZhciBrZXlCeXRlcyA9IG1kLmRpZ2VzdCgpLmdldEJ5dGVzKCk7CiAgICBtZC5zdGFydCgpOwogICAgbWQudXBkYXRlKGtleUJ5dGVzKTsKICAgIHZhciBzZWVkQnl0ZXMgPSBtZC5kaWdlc3QoKS5nZXRCeXRlcygpOwoKICAgIC8vIHVwZGF0ZQogICAgY3R4LmtleSA9IGN0eC5wbHVnaW4uZm9ybWF0S2V5KGtleUJ5dGVzKTsKICAgIGN0eC5zZWVkID0gY3R4LnBsdWdpbi5mb3JtYXRTZWVkKHNlZWRCeXRlcyk7CiAgICBjdHgucmVzZWVkcyA9IChjdHgucmVzZWVkcyA9PT0gMHhmZmZmZmZmZikgPyAwIDogY3R4LnJlc2VlZHMgKyAxOwogICAgY3R4LmdlbmVyYXRlZCA9IDA7CiAgfQoKICAvKioKICAgKiBUaGUgYnVpbHQtaW4gZGVmYXVsdCBzZWVkRmlsZS4gVGhpcyBzZWVkRmlsZSBpcyB1c2VkIHdoZW4gZW50cm9weQogICAqIGlzIG5lZWRlZCBpbW1lZGlhdGVseS4KICAgKgogICAqIEBwYXJhbSBuZWVkZWQgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IGFyZSBuZWVkZWQuCiAgICoKICAgKiBAcmV0dXJuIHRoZSByYW5kb20gYnl0ZXMuCiAgICovCiAgZnVuY3Rpb24gZGVmYXVsdFNlZWRGaWxlKG5lZWRlZCkgewogICAgLy8gdXNlIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzIHN0cm9uZyBzb3VyY2Ugb2YgZW50cm9weSBpZiBhdmFpbGFibGUKICAgIHZhciBnZXRSYW5kb21WYWx1ZXMgPSBudWxsOwogICAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgdmFyIF9jcnlwdG8gPSB3aW5kb3cuY3J5cHRvIHx8IHdpbmRvdy5tc0NyeXB0bzsKICAgICAgaWYoX2NyeXB0byAmJiBfY3J5cHRvLmdldFJhbmRvbVZhbHVlcykgewogICAgICAgIGdldFJhbmRvbVZhbHVlcyA9IGZ1bmN0aW9uKGFycikgewogICAgICAgICAgcmV0dXJuIF9jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGFycik7CiAgICAgICAgfTsKICAgICAgfQogICAgfQoKICAgIHZhciBiID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIGlmKGdldFJhbmRvbVZhbHVlcykgewogICAgICB3aGlsZShiLmxlbmd0aCgpIDwgbmVlZGVkKSB7CiAgICAgICAgLy8gbWF4IGJ5dGUgbGVuZ3RoIGlzIDY1NTM2IGJlZm9yZSBRdW90YUV4Y2VlZGVkRXJyb3IgaXMgdGhyb3duCiAgICAgICAgLy8gaHR0cDovL3d3dy53My5vcmcvVFIvV2ViQ3J5cHRvQVBJLyNSYW5kb21Tb3VyY2UtbWV0aG9kLWdldFJhbmRvbVZhbHVlcwogICAgICAgIHZhciBjb3VudCA9IE1hdGgubWF4KDEsIE1hdGgubWluKG5lZWRlZCAtIGIubGVuZ3RoKCksIDY1NTM2KSAvIDQpOwogICAgICAgIHZhciBlbnRyb3B5ID0gbmV3IFVpbnQzMkFycmF5KE1hdGguZmxvb3IoY291bnQpKTsKICAgICAgICB0cnkgewogICAgICAgICAgZ2V0UmFuZG9tVmFsdWVzKGVudHJvcHkpOwogICAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGVudHJvcHkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgYi5wdXRJbnQzMihlbnRyb3B5W2ldKTsKICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoKGUpIHsKICAgICAgICAgIC8qIG9ubHkgaWdub3JlIFF1b3RhRXhjZWVkZWRFcnJvciAqLwogICAgICAgICAgaWYoISh0eXBlb2YgUXVvdGFFeGNlZWRlZEVycm9yICE9PSAndW5kZWZpbmVkJyAmJgogICAgICAgICAgICBlIGluc3RhbmNlb2YgUXVvdGFFeGNlZWRlZEVycm9yKSkgewogICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIC8vIGJlIHNhZCBhbmQgYWRkIHNvbWUgd2VhayByYW5kb20gZGF0YQogICAgaWYoYi5sZW5ndGgoKSA8IG5lZWRlZCkgewogICAgICAvKiBEcmF3cyBmcm9tIFBhcmstTWlsbGVyICJtaW5pbWFsIHN0YW5kYXJkIiAzMSBiaXQgUFJORywKICAgICAgaW1wbGVtZW50ZWQgd2l0aCBEYXZpZCBHLiBDYXJ0YSdzIG9wdGltaXphdGlvbjogd2l0aCAzMiBiaXQgbWF0aAogICAgICBhbmQgd2l0aG91dCBkaXZpc2lvbiAoUHVibGljIERvbWFpbikuICovCiAgICAgIHZhciBoaSwgbG8sIG5leHQ7CiAgICAgIHZhciBzZWVkID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMHgwMTAwMDApOwogICAgICB3aGlsZShiLmxlbmd0aCgpIDwgbmVlZGVkKSB7CiAgICAgICAgbG8gPSAxNjgwNyAqIChzZWVkICYgMHhGRkZGKTsKICAgICAgICBoaSA9IDE2ODA3ICogKHNlZWQgPj4gMTYpOwogICAgICAgIGxvICs9IChoaSAmIDB4N0ZGRikgPDwgMTY7CiAgICAgICAgbG8gKz0gaGkgPj4gMTU7CiAgICAgICAgbG8gPSAobG8gJiAweDdGRkZGRkZGKSArIChsbyA+PiAzMSk7CiAgICAgICAgc2VlZCA9IGxvICYgMHhGRkZGRkZGRjsKCiAgICAgICAgLy8gY29uc3VtZSBsb3dlciAzIGJ5dGVzIG9mIHNlZWQKICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgMzsgKytpKSB7CiAgICAgICAgICAvLyB0aHJvdyBpbiBtb3JlIHBzZXVkbyByYW5kb20KICAgICAgICAgIG5leHQgPSBzZWVkID4+PiAoaSA8PCAzKTsKICAgICAgICAgIG5leHQgXj0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMHgwMTAwKTsKICAgICAgICAgIGIucHV0Qnl0ZShTdHJpbmcuZnJvbUNoYXJDb2RlKG5leHQgJiAweEZGKSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgcmV0dXJuIGIuZ2V0Qnl0ZXMobmVlZGVkKTsKICB9CiAgLy8gaW5pdGlhbGl6ZSBzZWVkIGZpbGUgQVBJcwogIGlmKF9jcnlwdG8pIHsKICAgIC8vIHVzZSBub2RlanMgYXN5bmMgQVBJCiAgICBjdHguc2VlZEZpbGUgPSBmdW5jdGlvbihuZWVkZWQsIGNhbGxiYWNrKSB7CiAgICAgIF9jcnlwdG8ucmFuZG9tQnl0ZXMobmVlZGVkLCBmdW5jdGlvbihlcnIsIGJ5dGVzKSB7CiAgICAgICAgaWYoZXJyKSB7CiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTsKICAgICAgICB9CiAgICAgICAgY2FsbGJhY2sobnVsbCwgYnl0ZXMudG9TdHJpbmcoKSk7CiAgICAgIH0pOwogICAgfTsKICAgIC8vIHVzZSBub2RlanMgc3luYyBBUEkKICAgIGN0eC5zZWVkRmlsZVN5bmMgPSBmdW5jdGlvbihuZWVkZWQpIHsKICAgICAgcmV0dXJuIF9jcnlwdG8ucmFuZG9tQnl0ZXMobmVlZGVkKS50b1N0cmluZygpOwogICAgfTsKICB9IGVsc2UgewogICAgY3R4LnNlZWRGaWxlID0gZnVuY3Rpb24obmVlZGVkLCBjYWxsYmFjaykgewogICAgICB0cnkgewogICAgICAgIGNhbGxiYWNrKG51bGwsIGRlZmF1bHRTZWVkRmlsZShuZWVkZWQpKTsKICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgY2FsbGJhY2soZSk7CiAgICAgIH0KICAgIH07CiAgICBjdHguc2VlZEZpbGVTeW5jID0gZGVmYXVsdFNlZWRGaWxlOwogIH0KCiAgLyoqCiAgICogQWRkcyBlbnRyb3B5IHRvIGEgcHJuZyBjdHgncyBhY2N1bXVsYXRvci4KICAgKgogICAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZXMgb2YgZW50cm9weSBhcyBhIHN0cmluZy4KICAgKi8KICBjdHguY29sbGVjdCA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgICAvLyBpdGVyYXRlIG92ZXIgcG9vbHMgZGlzdHJpYnV0aW5nIGVudHJvcHkgY3ljbGljYWxseQogICAgdmFyIGNvdW50ID0gYnl0ZXMubGVuZ3RoOwogICAgZm9yKHZhciBpID0gMDsgaSA8IGNvdW50OyArK2kpIHsKICAgICAgY3R4LnBvb2xzW2N0eC5wb29sXS51cGRhdGUoYnl0ZXMuc3Vic3RyKGksIDEpKTsKICAgICAgY3R4LnBvb2wgPSAoY3R4LnBvb2wgPT09IDMxKSA/IDAgOiBjdHgucG9vbCArIDE7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogQ29sbGVjdHMgYW4gaW50ZWdlciBvZiBuIGJpdHMuCiAgICoKICAgKiBAcGFyYW0gaSB0aGUgaW50ZWdlciBlbnRyb3B5LgogICAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICAgKi8KICBjdHguY29sbGVjdEludCA9IGZ1bmN0aW9uKGksIG4pIHsKICAgIHZhciBieXRlcyA9ICcnOwogICAgZm9yKHZhciB4ID0gMDsgeCA8IG47IHggKz0gOCkgewogICAgICBieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChpID4+IHgpICYgMHhGRik7CiAgICB9CiAgICBjdHguY29sbGVjdChieXRlcyk7CiAgfTsKCiAgLyoqCiAgICogUmVnaXN0ZXJzIGEgV2ViIFdvcmtlciB0byByZWNlaXZlIGltbWVkaWF0ZSBlbnRyb3B5IGZyb20gdGhlIG1haW4gdGhyZWFkLgogICAqIFRoaXMgbWV0aG9kIGlzIHJlcXVpcmVkIHVudGlsIFdlYiBXb3JrZXJzIGNhbiBhY2Nlc3MgdGhlIG5hdGl2ZSBjcnlwdG8KICAgKiBBUEkuIFRoaXMgbWV0aG9kIHNob3VsZCBiZSBjYWxsZWQgdHdpY2UgZm9yIGVhY2ggY3JlYXRlZCB3b3JrZXIsIG9uY2UgaW4KICAgKiB0aGUgbWFpbiB0aHJlYWQsIGFuZCBvbmNlIGluIHRoZSB3b3JrZXIgaXRzZWxmLgogICAqCiAgICogQHBhcmFtIHdvcmtlciB0aGUgd29ya2VyIHRvIHJlZ2lzdGVyLgogICAqLwogIGN0eC5yZWdpc3RlcldvcmtlciA9IGZ1bmN0aW9uKHdvcmtlcikgewogICAgLy8gd29ya2VyIHJlY2VpdmVzIHJhbmRvbSBieXRlcwogICAgaWYod29ya2VyID09PSBzZWxmKSB7CiAgICAgIGN0eC5zZWVkRmlsZSA9IGZ1bmN0aW9uKG5lZWRlZCwgY2FsbGJhY2spIHsKICAgICAgICBmdW5jdGlvbiBsaXN0ZW5lcihlKSB7CiAgICAgICAgICB2YXIgZGF0YSA9IGUuZGF0YTsKICAgICAgICAgIGlmKGRhdGEuZm9yZ2UgJiYgZGF0YS5mb3JnZS5wcm5nKSB7CiAgICAgICAgICAgIHNlbGYucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGxpc3RlbmVyKTsKICAgICAgICAgICAgY2FsbGJhY2soZGF0YS5mb3JnZS5wcm5nLmVyciwgZGF0YS5mb3JnZS5wcm5nLmJ5dGVzKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2VsZi5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgbGlzdGVuZXIpOwogICAgICAgIHNlbGYucG9zdE1lc3NhZ2Uoe2ZvcmdlOiB7cHJuZzoge25lZWRlZDogbmVlZGVkfX19KTsKICAgICAgfTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIG1haW4gdGhyZWFkIHNlbmRzIHJhbmRvbSBieXRlcyB1cG9uIHJlcXVlc3QKICAgICAgdmFyIGxpc3RlbmVyID0gZnVuY3Rpb24oZSkgewogICAgICAgIHZhciBkYXRhID0gZS5kYXRhOwogICAgICAgIGlmKGRhdGEuZm9yZ2UgJiYgZGF0YS5mb3JnZS5wcm5nKSB7CiAgICAgICAgICBjdHguc2VlZEZpbGUoZGF0YS5mb3JnZS5wcm5nLm5lZWRlZCwgZnVuY3Rpb24oZXJyLCBieXRlcykgewogICAgICAgICAgICB3b3JrZXIucG9zdE1lc3NhZ2Uoe2ZvcmdlOiB7cHJuZzoge2VycjogZXJyLCBieXRlczogYnl0ZXN9fX0pOwogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9OwogICAgICAvLyBUT0RPOiBkbyB3ZSBuZWVkIHRvIHJlbW92ZSB0aGUgZXZlbnQgbGlzdGVuZXIgd2hlbiB0aGUgd29ya2VyIGRpZXM/CiAgICAgIHdvcmtlci5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgbGlzdGVuZXIpOwogICAgfQogIH07CgogIHJldHVybiBjdHg7Cn07Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdwcm5nJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3BybmcnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9tZCcsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cgp9KSgpOwoKLyoqCiAqIEFuIEFQSSBmb3IgZ2V0dGluZyBjcnlwdG9ncmFwaGljYWxseS1zZWN1cmUgcmFuZG9tIGJ5dGVzLiBUaGUgYnl0ZXMgYXJlCiAqIGdlbmVyYXRlZCB1c2luZyB0aGUgRm9ydHVuYSBhbGdvcml0aG0gZGV2aXNlZCBieSBCcnVjZSBTY2huZWllciBhbmQKICogTmllbHMgRmVyZ3Vzb24uCiAqCiAqIEdldHRpbmcgc3Ryb25nIHJhbmRvbSBieXRlcyBpcyBub3QgeWV0IGVhc3kgdG8gZG8gaW4gamF2YXNjcmlwdC4gVGhlIG9ubHkKICogdHJ1aXNoIHJhbmRvbSBlbnRyb3B5IHRoYXQgY2FuIGJlIGNvbGxlY3RlZCBpcyBmcm9tIHRoZSBtb3VzZSwga2V5Ym9hcmQsIG9yCiAqIGZyb20gdGltaW5nIHdpdGggcmVzcGVjdCB0byBwYWdlIGxvYWRzLCBldGMuIFRoaXMgZ2VuZXJhdG9yIG1ha2VzIGEgcG9vcgogKiBhdHRlbXB0IGF0IHByb3ZpZGluZyByYW5kb20gYnl0ZXMgd2hlbiB0aG9zZSBzb3VyY2VzIGhhdmVuJ3QgeWV0IHByb3ZpZGVkCiAqIGVub3VnaCBlbnRyb3B5IHRvIGluaXRpYWxseSBzZWVkIG9yIHRvIHJlc2VlZCB0aGUgUFJORy4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDA5LTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovLyBmb3JnZS5yYW5kb20gYWxyZWFkeSBkZWZpbmVkCmlmKGZvcmdlLnJhbmRvbSAmJiBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMpIHsKICByZXR1cm47Cn0KCihmdW5jdGlvbihqUXVlcnkpIHsKCi8vIHRoZSBkZWZhdWx0IHBybmcgcGx1Z2luLCB1c2VzIEFFUy0xMjgKdmFyIHBybmdfYWVzID0ge307CnZhciBfcHJuZ19hZXNfb3V0cHV0ID0gbmV3IEFycmF5KDQpOwp2YXIgX3BybmdfYWVzX2J1ZmZlciA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CnBybmdfYWVzLmZvcm1hdEtleSA9IGZ1bmN0aW9uKGtleSkgewogIC8vIGNvbnZlcnQgdGhlIGtleSBpbnRvIDMyLWJpdCBpbnRlZ2VycwogIHZhciB0bXAgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihrZXkpOwogIGtleSA9IG5ldyBBcnJheSg0KTsKICBrZXlbMF0gPSB0bXAuZ2V0SW50MzIoKTsKICBrZXlbMV0gPSB0bXAuZ2V0SW50MzIoKTsKICBrZXlbMl0gPSB0bXAuZ2V0SW50MzIoKTsKICBrZXlbM10gPSB0bXAuZ2V0SW50MzIoKTsKCiAgLy8gcmV0dXJuIHRoZSBleHBhbmRlZCBrZXkKICByZXR1cm4gZm9yZ2UuYWVzLl9leHBhbmRLZXkoa2V5LCBmYWxzZSk7Cn07CnBybmdfYWVzLmZvcm1hdFNlZWQgPSBmdW5jdGlvbihzZWVkKSB7CiAgLy8gY29udmVydCBzZWVkIGludG8gMzItYml0IGludGVnZXJzCiAgdmFyIHRtcCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKHNlZWQpOwogIHNlZWQgPSBuZXcgQXJyYXkoNCk7CiAgc2VlZFswXSA9IHRtcC5nZXRJbnQzMigpOwogIHNlZWRbMV0gPSB0bXAuZ2V0SW50MzIoKTsKICBzZWVkWzJdID0gdG1wLmdldEludDMyKCk7CiAgc2VlZFszXSA9IHRtcC5nZXRJbnQzMigpOwogIHJldHVybiBzZWVkOwp9Owpwcm5nX2Flcy5jaXBoZXIgPSBmdW5jdGlvbihrZXksIHNlZWQpIHsKICBmb3JnZS5hZXMuX3VwZGF0ZUJsb2NrKGtleSwgc2VlZCwgX3BybmdfYWVzX291dHB1dCwgZmFsc2UpOwogIF9wcm5nX2Flc19idWZmZXIucHV0SW50MzIoX3BybmdfYWVzX291dHB1dFswXSk7CiAgX3BybmdfYWVzX2J1ZmZlci5wdXRJbnQzMihfcHJuZ19hZXNfb3V0cHV0WzFdKTsKICBfcHJuZ19hZXNfYnVmZmVyLnB1dEludDMyKF9wcm5nX2Flc19vdXRwdXRbMl0pOwogIF9wcm5nX2Flc19idWZmZXIucHV0SW50MzIoX3BybmdfYWVzX291dHB1dFszXSk7CiAgcmV0dXJuIF9wcm5nX2Flc19idWZmZXIuZ2V0Qnl0ZXMoKTsKfTsKcHJuZ19hZXMuaW5jcmVtZW50ID0gZnVuY3Rpb24oc2VlZCkgewogIC8vIEZJWE1FOiBkbyB3ZSBjYXJlIGFib3V0IGNhcnJ5IG9yIHNpZ25lZCBpc3N1ZXM/CiAgKytzZWVkWzNdOwogIHJldHVybiBzZWVkOwp9Owpwcm5nX2Flcy5tZCA9IGZvcmdlLm1kLnNoYTI1NjsKCi8qKgogKiBDcmVhdGVzIGEgbmV3IFBSTkcuCiAqLwpmdW5jdGlvbiBzcGF3blBybmcoKSB7CiAgdmFyIGN0eCA9IGZvcmdlLnBybmcuY3JlYXRlKHBybmdfYWVzKTsKCiAgLyoqCiAgICogR2V0cyByYW5kb20gYnl0ZXMuIElmIGEgbmF0aXZlIHNlY3VyZSBjcnlwdG8gQVBJIGlzIHVuYXZhaWxhYmxlLCB0aGlzCiAgICogbWV0aG9kIHRyaWVzIHRvIG1ha2UgdGhlIGJ5dGVzIG1vcmUgdW5wcmVkaWN0YWJsZSBieSBkcmF3aW5nIGZyb20gZGF0YSB0aGF0CiAgICogY2FuIGJlIGNvbGxlY3RlZCBmcm9tIHRoZSB1c2VyIG9mIHRoZSBicm93c2VyLCBlZzogbW91c2UgbW92ZW1lbnQuCiAgICoKICAgKiBJZiBhIGNhbGxiYWNrIGlzIGdpdmVuLCB0aGlzIG1ldGhvZCB3aWxsIGJlIGNhbGxlZCBhc3luY2hyb25vdXNseS4KICAgKgogICAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIHJhbmRvbSBieXRlcyB0byBnZXQuCiAgICogQHBhcmFtIFtjYWxsYmFjayhlcnIsIGJ5dGVzKV0gY2FsbGVkIG9uY2UgdGhlIG9wZXJhdGlvbiBjb21wbGV0ZXMuCiAgICoKICAgKiBAcmV0dXJuIHRoZSByYW5kb20gYnl0ZXMgaW4gYSBzdHJpbmcuCiAgICovCiAgY3R4LmdldEJ5dGVzID0gZnVuY3Rpb24oY291bnQsIGNhbGxiYWNrKSB7CiAgICByZXR1cm4gY3R4LmdlbmVyYXRlKGNvdW50LCBjYWxsYmFjayk7CiAgfTsKCiAgLyoqCiAgICogR2V0cyByYW5kb20gYnl0ZXMgYXN5bmNocm9ub3VzbHkuIElmIGEgbmF0aXZlIHNlY3VyZSBjcnlwdG8gQVBJIGlzCiAgICogdW5hdmFpbGFibGUsIHRoaXMgbWV0aG9kIHRyaWVzIHRvIG1ha2UgdGhlIGJ5dGVzIG1vcmUgdW5wcmVkaWN0YWJsZSBieQogICAqIGRyYXdpbmcgZnJvbSBkYXRhIHRoYXQgY2FuIGJlIGNvbGxlY3RlZCBmcm9tIHRoZSB1c2VyIG9mIHRoZSBicm93c2VyLAogICAqIGVnOiBtb3VzZSBtb3ZlbWVudC4KICAgKgogICAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIHJhbmRvbSBieXRlcyB0byBnZXQuCiAgICoKICAgKiBAcmV0dXJuIHRoZSByYW5kb20gYnl0ZXMgaW4gYSBzdHJpbmcuCiAgICovCiAgY3R4LmdldEJ5dGVzU3luYyA9IGZ1bmN0aW9uKGNvdW50KSB7CiAgICByZXR1cm4gY3R4LmdlbmVyYXRlKGNvdW50KTsKICB9OwoKICByZXR1cm4gY3R4Owp9CgovLyBjcmVhdGUgZGVmYXVsdCBwcm5nIGNvbnRleHQKdmFyIF9jdHggPSBzcGF3blBybmcoKTsKCi8vIGFkZCBvdGhlciBzb3VyY2VzIG9mIGVudHJvcHkgb25seSBpZiB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyBpcyBub3QKLy8gYXZhaWxhYmxlIC0tIG90aGVyd2lzZSB0aGlzIHNvdXJjZSB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgdXNlZCBieSB0aGUgcHJuZwp2YXIgX25vZGVqcyA9ICgKICB0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvY2Vzcy52ZXJzaW9ucyAmJiBwcm9jZXNzLnZlcnNpb25zLm5vZGUpOwp2YXIgZ2V0UmFuZG9tVmFsdWVzID0gbnVsbDsKaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHsKICB2YXIgX2NyeXB0byA9IHdpbmRvdy5jcnlwdG8gfHwgd2luZG93Lm1zQ3J5cHRvOwogIGlmKF9jcnlwdG8gJiYgX2NyeXB0by5nZXRSYW5kb21WYWx1ZXMpIHsKICAgIGdldFJhbmRvbVZhbHVlcyA9IGZ1bmN0aW9uKGFycikgewogICAgICByZXR1cm4gX2NyeXB0by5nZXRSYW5kb21WYWx1ZXMoYXJyKTsKICAgIH07CiAgfQp9CmlmKGZvcmdlLmRpc2FibGVOYXRpdmVDb2RlIHx8ICghX25vZGVqcyAmJiAhZ2V0UmFuZG9tVmFsdWVzKSkgewogIC8vIGlmIHRoaXMgaXMgYSB3ZWIgd29ya2VyLCBkbyBub3QgdXNlIHdlYWsgZW50cm9weSwgaW5zdGVhZCByZWdpc3RlciB0bwogIC8vIHJlY2VpdmUgc3Ryb25nIGVudHJvcHkgYXN5bmNocm9ub3VzbHkgZnJvbSB0aGUgbWFpbiB0aHJlYWQKICBpZih0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJyB8fCB3aW5kb3cuZG9jdW1lbnQgPT09IHVuZGVmaW5lZCkgewogICAgLy8gRklYTUU6CiAgfQoKICAvLyBnZXQgbG9hZCB0aW1lIGVudHJvcHkKICBfY3R4LmNvbGxlY3RJbnQoK25ldyBEYXRlKCksIDMyKTsKCiAgLy8gYWRkIHNvbWUgZW50cm9weSBmcm9tIG5hdmlnYXRvciBvYmplY3QKICBpZih0eXBlb2YobmF2aWdhdG9yKSAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgIHZhciBfbmF2Qnl0ZXMgPSAnJzsKICAgIGZvcih2YXIga2V5IGluIG5hdmlnYXRvcikgewogICAgICB0cnkgewogICAgICAgIGlmKHR5cGVvZihuYXZpZ2F0b3Jba2V5XSkgPT0gJ3N0cmluZycpIHsKICAgICAgICAgIF9uYXZCeXRlcyArPSBuYXZpZ2F0b3Jba2V5XTsKICAgICAgICB9CiAgICAgIH0gY2F0Y2goZSkgewogICAgICAgIC8qIFNvbWUgbmF2aWdhdG9yIGtleXMgbWlnaHQgbm90IGJlIGFjY2Vzc2libGUsIGUuZy4gdGhlIGdlb2xvY2F0aW9uCiAgICAgICAgICBhdHRyaWJ1dGUgdGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0b3VjaGVkIGluIE1vemlsbGEgY2hyb21lOi8vCiAgICAgICAgICBjb250ZXh0LgoKICAgICAgICAgIFNpbGVudGx5IGlnbm9yZSB0aGlzIGFuZCBqdXN0IGRvbid0IHVzZSB0aGlzIGFzIGEgc291cmNlIG9mCiAgICAgICAgICBlbnRyb3B5LiAqLwogICAgICB9CiAgICB9CiAgICBfY3R4LmNvbGxlY3QoX25hdkJ5dGVzKTsKICAgIF9uYXZCeXRlcyA9IG51bGw7CiAgfQoKICAvLyBhZGQgbW91c2UgYW5kIGtleWJvYXJkIGNvbGxlY3RvcnMgaWYganF1ZXJ5IGlzIGF2YWlsYWJsZQogIGlmKGpRdWVyeSkgewogICAgLy8gc2V0IHVwIG1vdXNlIGVudHJvcHkgY2FwdHVyZQogICAgalF1ZXJ5KCkubW91c2Vtb3ZlKGZ1bmN0aW9uKGUpIHsKICAgICAgLy8gYWRkIG1vdXNlIGNvb3JkcwogICAgICBfY3R4LmNvbGxlY3RJbnQoZS5jbGllbnRYLCAxNik7CiAgICAgIF9jdHguY29sbGVjdEludChlLmNsaWVudFksIDE2KTsKICAgIH0pOwoKICAgIC8vIHNldCB1cCBrZXlib2FyZCBlbnRyb3B5IGNhcHR1cmUKICAgIGpRdWVyeSgpLmtleXByZXNzKGZ1bmN0aW9uKGUpIHsKICAgICAgX2N0eC5jb2xsZWN0SW50KGUuY2hhckNvZGUsIDgpOwogICAgfSk7CiAgfQp9CgovKiBSYW5kb20gQVBJICovCmlmKCFmb3JnZS5yYW5kb20pIHsKICBmb3JnZS5yYW5kb20gPSBfY3R4Owp9IGVsc2UgewogIC8vIGV4dGVuZCBmb3JnZS5yYW5kb20gd2l0aCBfY3R4CiAgZm9yKHZhciBrZXkgaW4gX2N0eCkgewogICAgZm9yZ2UucmFuZG9tW2tleV0gPSBfY3R4W2tleV07CiAgfQp9CgovLyBleHBvc2Ugc3Bhd24gUFJORwpmb3JnZS5yYW5kb20uY3JlYXRlSW5zdGFuY2UgPSBzcGF3blBybmc7Cgp9KSh0eXBlb2YoalF1ZXJ5KSAhPT0gJ3VuZGVmaW5lZCcgPyBqUXVlcnkgOiBudWxsKTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3JhbmRvbSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9yYW5kb20nLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9hZXMnLCAnLi9tZCcsICcuL3BybmcnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFJDMiBpbXBsZW1lbnRhdGlvbi4KICoKICogQGF1dGhvciBTdGVmYW4gU2llZ2wKICoKICogQ29weXJpZ2h0IChjKSAyMDEyIFN0ZWZhbiBTaWVnbCA8c3Rlc2llQGJyb2tlbnBpcGUuZGU+CiAqCiAqIEluZm9ybWF0aW9uIG9uIHRoZSBSQzIgY2lwaGVyIGlzIGF2YWlsYWJsZSBmcm9tIFJGQyAjMjI2OCwKICogaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI2OC50eHQKICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7Cgp2YXIgcGlUYWJsZSA9IFsKICAweGQ5LCAweDc4LCAweGY5LCAweGM0LCAweDE5LCAweGRkLCAweGI1LCAweGVkLCAweDI4LCAweGU5LCAweGZkLCAweDc5LCAweDRhLCAweGEwLCAweGQ4LCAweDlkLAogIDB4YzYsIDB4N2UsIDB4MzcsIDB4ODMsIDB4MmIsIDB4NzYsIDB4NTMsIDB4OGUsIDB4NjIsIDB4NGMsIDB4NjQsIDB4ODgsIDB4NDQsIDB4OGIsIDB4ZmIsIDB4YTIsCiAgMHgxNywgMHg5YSwgMHg1OSwgMHhmNSwgMHg4NywgMHhiMywgMHg0ZiwgMHgxMywgMHg2MSwgMHg0NSwgMHg2ZCwgMHg4ZCwgMHgwOSwgMHg4MSwgMHg3ZCwgMHgzMiwKICAweGJkLCAweDhmLCAweDQwLCAweGViLCAweDg2LCAweGI3LCAweDdiLCAweDBiLCAweGYwLCAweDk1LCAweDIxLCAweDIyLCAweDVjLCAweDZiLCAweDRlLCAweDgyLAogIDB4NTQsIDB4ZDYsIDB4NjUsIDB4OTMsIDB4Y2UsIDB4NjAsIDB4YjIsIDB4MWMsIDB4NzMsIDB4NTYsIDB4YzAsIDB4MTQsIDB4YTcsIDB4OGMsIDB4ZjEsIDB4ZGMsCiAgMHgxMiwgMHg3NSwgMHhjYSwgMHgxZiwgMHgzYiwgMHhiZSwgMHhlNCwgMHhkMSwgMHg0MiwgMHgzZCwgMHhkNCwgMHgzMCwgMHhhMywgMHgzYywgMHhiNiwgMHgyNiwKICAweDZmLCAweGJmLCAweDBlLCAweGRhLCAweDQ2LCAweDY5LCAweDA3LCAweDU3LCAweDI3LCAweGYyLCAweDFkLCAweDliLCAweGJjLCAweDk0LCAweDQzLCAweDAzLAogIDB4ZjgsIDB4MTEsIDB4YzcsIDB4ZjYsIDB4OTAsIDB4ZWYsIDB4M2UsIDB4ZTcsIDB4MDYsIDB4YzMsIDB4ZDUsIDB4MmYsIDB4YzgsIDB4NjYsIDB4MWUsIDB4ZDcsCiAgMHgwOCwgMHhlOCwgMHhlYSwgMHhkZSwgMHg4MCwgMHg1MiwgMHhlZSwgMHhmNywgMHg4NCwgMHhhYSwgMHg3MiwgMHhhYywgMHgzNSwgMHg0ZCwgMHg2YSwgMHgyYSwKICAweDk2LCAweDFhLCAweGQyLCAweDcxLCAweDVhLCAweDE1LCAweDQ5LCAweDc0LCAweDRiLCAweDlmLCAweGQwLCAweDVlLCAweDA0LCAweDE4LCAweGE0LCAweGVjLAogIDB4YzIsIDB4ZTAsIDB4NDEsIDB4NmUsIDB4MGYsIDB4NTEsIDB4Y2IsIDB4Y2MsIDB4MjQsIDB4OTEsIDB4YWYsIDB4NTAsIDB4YTEsIDB4ZjQsIDB4NzAsIDB4MzksCiAgMHg5OSwgMHg3YywgMHgzYSwgMHg4NSwgMHgyMywgMHhiOCwgMHhiNCwgMHg3YSwgMHhmYywgMHgwMiwgMHgzNiwgMHg1YiwgMHgyNSwgMHg1NSwgMHg5NywgMHgzMSwKICAweDJkLCAweDVkLCAweGZhLCAweDk4LCAweGUzLCAweDhhLCAweDkyLCAweGFlLCAweDA1LCAweGRmLCAweDI5LCAweDEwLCAweDY3LCAweDZjLCAweGJhLCAweGM5LAogIDB4ZDMsIDB4MDAsIDB4ZTYsIDB4Y2YsIDB4ZTEsIDB4OWUsIDB4YTgsIDB4MmMsIDB4NjMsIDB4MTYsIDB4MDEsIDB4M2YsIDB4NTgsIDB4ZTIsIDB4ODksIDB4YTksCiAgMHgwZCwgMHgzOCwgMHgzNCwgMHgxYiwgMHhhYiwgMHgzMywgMHhmZiwgMHhiMCwgMHhiYiwgMHg0OCwgMHgwYywgMHg1ZiwgMHhiOSwgMHhiMSwgMHhjZCwgMHgyZSwKICAweGM1LCAweGYzLCAweGRiLCAweDQ3LCAweGU1LCAweGE1LCAweDljLCAweDc3LCAweDBhLCAweGE2LCAweDIwLCAweDY4LCAweGZlLCAweDdmLCAweGMxLCAweGFkCl07Cgp2YXIgcyA9IFsxLCAyLCAzLCA1XTsKCgovKioKICogUm90YXRlIGEgd29yZCBsZWZ0IGJ5IGdpdmVuIG51bWJlciBvZiBiaXRzLgogKgogKiBCaXRzIHRoYXQgYXJlIHNoaWZ0ZWQgb3V0IG9uIHRoZSBsZWZ0IGFyZSBwdXQgYmFjayBpbiBvbiB0aGUgcmlnaHQKICogaGFuZCBzaWRlLgogKgogKiBAcGFyYW0gd29yZCBUaGUgd29yZCB0byBzaGlmdCBsZWZ0LgogKiBAcGFyYW0gYml0cyBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnQgYnkuCiAqIEByZXR1cm4gVGhlIHJvdGF0ZWQgd29yZC4KICovCnZhciByb2wgPSBmdW5jdGlvbih3b3JkLCBiaXRzKSB7CiAgcmV0dXJuICgod29yZCA8PCBiaXRzKSAmIDB4ZmZmZikgfCAoKHdvcmQgJiAweGZmZmYpID4+ICgxNiAtIGJpdHMpKTsKfTsKCi8qKgogKiBSb3RhdGUgYSB3b3JkIHJpZ2h0IGJ5IGdpdmVuIG51bWJlciBvZiBiaXRzLgogKgogKiBCaXRzIHRoYXQgYXJlIHNoaWZ0ZWQgb3V0IG9uIHRoZSByaWdodCBhcmUgcHV0IGJhY2sgaW4gb24gdGhlIGxlZnQKICogaGFuZCBzaWRlLgogKgogKiBAcGFyYW0gd29yZCBUaGUgd29yZCB0byBzaGlmdCByaWdodC4KICogQHBhcmFtIGJpdHMgVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0IGJ5LgogKiBAcmV0dXJuIFRoZSByb3RhdGVkIHdvcmQuCiAqLwp2YXIgcm9yID0gZnVuY3Rpb24od29yZCwgYml0cykgewogIHJldHVybiAoKHdvcmQgJiAweGZmZmYpID4+IGJpdHMpIHwgKCh3b3JkIDw8ICgxNiAtIGJpdHMpKSAmIDB4ZmZmZik7Cn07CgoKLyogUkMyIEFQSSAqLwpmb3JnZS5yYzIgPSBmb3JnZS5yYzIgfHwge307CgovKioKICogUGVyZm9ybSBSQzIga2V5IGV4cGFuc2lvbiBhcyBwZXIgUkZDICMyMjY4LCBzZWN0aW9uIDIuCiAqCiAqIEBwYXJhbSBrZXkgdmFyaWFibGUtbGVuZ3RoIHVzZXIga2V5IChiZXR3ZWVuIDEgYW5kIDEyOCBieXRlcykKICogQHBhcmFtIGVmZktleUJpdHMgbnVtYmVyIG9mIGVmZmVjdGl2ZSBrZXkgYml0cyAoZGVmYXVsdDogMTI4KQogKiBAcmV0dXJuIHRoZSBleHBhbmRlZCBSQzIga2V5IChCeXRlQnVmZmVyIG9mIDEyOCBieXRlcykKICovCmZvcmdlLnJjMi5leHBhbmRLZXkgPSBmdW5jdGlvbihrZXksIGVmZktleUJpdHMpIHsKICBpZih0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykgewogICAga2V5ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoa2V5KTsKICB9CiAgZWZmS2V5Qml0cyA9IGVmZktleUJpdHMgfHwgMTI4OwoKICAvKiBpbnRyb2R1Y2UgdmFyaWFibGVzIHRoYXQgbWF0Y2ggdGhlIG5hbWVzIHVzZWQgaW4gUkZDICMyMjY4ICovCiAgdmFyIEwgPSBrZXk7CiAgdmFyIFQgPSBrZXkubGVuZ3RoKCk7CiAgdmFyIFQxID0gZWZmS2V5Qml0czsKICB2YXIgVDggPSBNYXRoLmNlaWwoVDEgLyA4KTsKICB2YXIgVE0gPSAweGZmID4+IChUMSAmIDB4MDcpOwogIHZhciBpOwoKICBmb3IoaSA9IFQ7IGkgPCAxMjg7IGkgKyspIHsKICAgIEwucHV0Qnl0ZShwaVRhYmxlWyhMLmF0KGkgLSAxKSArIEwuYXQoaSAtIFQpKSAmIDB4ZmZdKTsKICB9CgogIEwuc2V0QXQoMTI4IC0gVDgsIHBpVGFibGVbTC5hdCgxMjggLSBUOCkgJiBUTV0pOwoKICBmb3IoaSA9IDEyNyAtIFQ4OyBpID49IDA7IGkgLS0pIHsKICAgIEwuc2V0QXQoaSwgcGlUYWJsZVtMLmF0KGkgKyAxKSBeIEwuYXQoaSArIFQ4KV0pOwogIH0KCiAgcmV0dXJuIEw7Cn07CgoKLyoqCiAqIENyZWF0ZXMgYSBSQzIgY2lwaGVyIG9iamVjdC4KICoKICogQHBhcmFtIGtleSB0aGUgc3ltbWV0cmljIGtleSB0byB1c2UgKGFzIGJhc2UgZm9yIGtleSBnZW5lcmF0aW9uKS4KICogQHBhcmFtIGJpdHMgdGhlIG51bWJlciBvZiBlZmZlY3RpdmUga2V5IGJpdHMuCiAqIEBwYXJhbSBlbmNyeXB0IGZhbHNlIGZvciBkZWNyeXB0aW9uLCB0cnVlIGZvciBlbmNyeXB0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBjaXBoZXIuCiAqLwp2YXIgY3JlYXRlQ2lwaGVyID0gZnVuY3Rpb24oa2V5LCBiaXRzLCBlbmNyeXB0KSB7CiAgdmFyIF9maW5pc2ggPSBmYWxzZSwgX2lucHV0ID0gbnVsbCwgX291dHB1dCA9IG51bGwsIF9pdiA9IG51bGw7CiAgdmFyIG1peFJvdW5kLCBtYXNoUm91bmQ7CiAgdmFyIGksIGosIEsgPSBbXTsKCiAgLyogRXhwYW5kIGtleSBhbmQgZmlsbCBpbnRvIEtbXSBBcnJheSAqLwogIGtleSA9IGZvcmdlLnJjMi5leHBhbmRLZXkoa2V5LCBiaXRzKTsKICBmb3IoaSA9IDA7IGkgPCA2NDsgaSArKykgewogICAgSy5wdXNoKGtleS5nZXRJbnQxNkxlKCkpOwogIH0KCiAgaWYoZW5jcnlwdCkgewogICAgLyoqCiAgICAgKiBQZXJmb3JtIG9uZSBtaXhpbmcgcm91bmQgImluIHBsYWNlIi4KICAgICAqCiAgICAgKiBAcGFyYW0gUiBBcnJheSBvZiBmb3VyIHdvcmRzIHRvIHBlcmZvcm0gbWl4aW5nIG9uLgogICAgICovCiAgICBtaXhSb3VuZCA9IGZ1bmN0aW9uKFIpIHsKICAgICAgZm9yKGkgPSAwOyBpIDwgNDsgaSsrKSB7CiAgICAgICAgUltpXSArPSBLW2pdICsgKFJbKGkgKyAzKSAlIDRdICYgUlsoaSArIDIpICUgNF0pICsKICAgICAgICAgICgoflJbKGkgKyAzKSAlIDRdKSAmIFJbKGkgKyAxKSAlIDRdKTsKICAgICAgICBSW2ldID0gcm9sKFJbaV0sIHNbaV0pOwogICAgICAgIGogKys7CiAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBQZXJmb3JtIG9uZSBtYXNoaW5nIHJvdW5kICJpbiBwbGFjZSIuCiAgICAgKgogICAgICogQHBhcmFtIFIgQXJyYXkgb2YgZm91ciB3b3JkcyB0byBwZXJmb3JtIG1hc2hpbmcgb24uCiAgICAgKi8KICAgIG1hc2hSb3VuZCA9IGZ1bmN0aW9uKFIpIHsKICAgICAgZm9yKGkgPSAwOyBpIDwgNDsgaSArKykgewogICAgICAgIFJbaV0gKz0gS1tSWyhpICsgMykgJSA0XSAmIDYzXTsKICAgICAgfQogICAgfTsKICB9IGVsc2UgewogICAgLyoqCiAgICAgKiBQZXJmb3JtIG9uZSByLW1peGluZyByb3VuZCAiaW4gcGxhY2UiLgogICAgICoKICAgICAqIEBwYXJhbSBSIEFycmF5IG9mIGZvdXIgd29yZHMgdG8gcGVyZm9ybSBtaXhpbmcgb24uCiAgICAgKi8KICAgIG1peFJvdW5kID0gZnVuY3Rpb24oUikgewogICAgICBmb3IoaSA9IDM7IGkgPj0gMDsgaS0tKSB7CiAgICAgICAgUltpXSA9IHJvcihSW2ldLCBzW2ldKTsKICAgICAgICBSW2ldIC09IEtbal0gKyAoUlsoaSArIDMpICUgNF0gJiBSWyhpICsgMikgJSA0XSkgKwogICAgICAgICAgKCh+UlsoaSArIDMpICUgNF0pICYgUlsoaSArIDEpICUgNF0pOwogICAgICAgIGogLS07CiAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBQZXJmb3JtIG9uZSByLW1hc2hpbmcgcm91bmQgImluIHBsYWNlIi4KICAgICAqCiAgICAgKiBAcGFyYW0gUiBBcnJheSBvZiBmb3VyIHdvcmRzIHRvIHBlcmZvcm0gbWFzaGluZyBvbi4KICAgICAqLwogICAgbWFzaFJvdW5kID0gZnVuY3Rpb24oUikgewogICAgICBmb3IoaSA9IDM7IGkgPj0gMDsgaS0tKSB7CiAgICAgICAgUltpXSAtPSBLW1JbKGkgKyAzKSAlIDRdICYgNjNdOwogICAgICB9CiAgICB9OwogIH0KCiAgLyoqCiAgICogUnVuIHRoZSBzcGVjaWZpZWQgY2lwaGVyIGV4ZWN1dGlvbiBwbGFuLgogICAqCiAgICogVGhpcyBmdW5jdGlvbiB0YWtlcyBmb3VyIHdvcmRzIGZyb20gdGhlIGlucHV0IGJ1ZmZlciwgYXBwbGllcyB0aGUgSVYgb24KICAgKiBpdCAoaWYgcmVxdWVzdGVkKSBhbmQgcnVucyB0aGUgcHJvdmlkZWQgZXhlY3V0aW9uIHBsYW4uCiAgICoKICAgKiBUaGUgcGxhbiBtdXN0IGJlIHB1dCB0b2dldGhlciBpbiBmb3JtIG9mIGEgYXJyYXkgb2YgYXJyYXlzLiAgV2hlcmUgdGhlCiAgICogb3V0ZXIgb25lIGlzIHNpbXBseSBhIGxpc3Qgb2Ygc3RlcHMgdG8gcGVyZm9ybSBhbmQgdGhlIGlubmVyIG9uZSBuZWVkcwogICAqIHRvIGhhdmUgdHdvIGVsZW1lbnRzOiB0aGUgZmlyc3Qgb25lIHRlbGxpbmcgaG93IG1hbnkgcm91bmRzIHRvIHBlcmZvcm0sCiAgICogdGhlIHNlY29uZCBvbmUgdGVsbGluZyB3aGF0IHRvIGRvIChpLmUuIHRoZSBmdW5jdGlvbiB0byBjYWxsKS4KICAgKgogICAqIEBwYXJhbSB7QXJyYXl9IHBsYW4gVGhlIHBsYW4gdG8gZXhlY3V0ZS4KICAgKi8KICB2YXIgcnVuUGxhbiA9IGZ1bmN0aW9uKHBsYW4pIHsKICAgIHZhciBSID0gW107CgogICAgLyogR2V0IGRhdGEgZnJvbSBpbnB1dCBidWZmZXIgYW5kIGZpbGwgdGhlIGZvdXIgd29yZHMgaW50byBSICovCiAgICBmb3IoaSA9IDA7IGkgPCA0OyBpICsrKSB7CiAgICAgIHZhciB2YWwgPSBfaW5wdXQuZ2V0SW50MTZMZSgpOwoKICAgICAgaWYoX2l2ICE9PSBudWxsKSB7CiAgICAgICAgaWYoZW5jcnlwdCkgewogICAgICAgICAgLyogV2UncmUgZW5jcnlwdGluZywgYXBwbHkgdGhlIElWIGZpcnN0LiAqLwogICAgICAgICAgdmFsIF49IF9pdi5nZXRJbnQxNkxlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8qIFdlJ3JlIGRlY3J5cHRpb24sIGtlZXAgY2lwaGVyIHRleHQgZm9yIG5leHQgYmxvY2suICovCiAgICAgICAgICBfaXYucHV0SW50MTZMZSh2YWwpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgUi5wdXNoKHZhbCAmIDB4ZmZmZik7CiAgICB9CgogICAgLyogUmVzZXQgZ2xvYmFsICJqIiB2YXJpYWJsZSBhcyBwZXIgc3BlYy4gKi8KICAgIGogPSBlbmNyeXB0ID8gMCA6IDYzOwoKICAgIC8qIFJ1biBleGVjdXRpb24gcGxhbi4gKi8KICAgIGZvcih2YXIgcHRyID0gMDsgcHRyIDwgcGxhbi5sZW5ndGg7IHB0ciArKykgewogICAgICBmb3IodmFyIGN0ciA9IDA7IGN0ciA8IHBsYW5bcHRyXVswXTsgY3RyICsrKSB7CiAgICAgICAgcGxhbltwdHJdWzFdKFIpOwogICAgICB9CiAgICB9CgogICAgLyogV3JpdGUgYmFjayByZXN1bHQgdG8gb3V0cHV0IGJ1ZmZlci4gKi8KICAgIGZvcihpID0gMDsgaSA8IDQ7IGkgKyspIHsKICAgICAgaWYoX2l2ICE9PSBudWxsKSB7CiAgICAgICAgaWYoZW5jcnlwdCkgewogICAgICAgICAgLyogV2UncmUgZW5jcnlwdGluZyBpbiBDQkMtbW9kZSwgZmVlZCBiYWNrIGVuY3J5cHRlZCBieXRlcyBpbnRvCiAgICAgICAgICAgICBJViBidWZmZXIgdG8gY2FycnkgaXQgZm9yd2FyZCB0byBuZXh0IGJsb2NrLiAqLwogICAgICAgICAgX2l2LnB1dEludDE2TGUoUltpXSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIFJbaV0gXj0gX2l2LmdldEludDE2TGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIF9vdXRwdXQucHV0SW50MTZMZShSW2ldKTsKICAgIH0KICB9OwoKCiAgLyogQ3JlYXRlIGNpcGhlciBvYmplY3QgKi8KICB2YXIgY2lwaGVyID0gbnVsbDsKICBjaXBoZXIgPSB7CiAgICAvKioKICAgICAqIFN0YXJ0cyBvciByZXN0YXJ0cyB0aGUgZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uIHByb2Nlc3MsIHdoaWNoZXZlcgogICAgICogd2FzIHByZXZpb3VzbHkgY29uZmlndXJlZC4KICAgICAqCiAgICAgKiBUbyB1c2UgdGhlIGNpcGhlciBpbiBDQkMgbW9kZSwgaXYgbWF5IGJlIGdpdmVuIGVpdGhlciBhcyBhIHN0cmluZwogICAgICogb2YgYnl0ZXMsIG9yIGFzIGEgYnl0ZSBidWZmZXIuICBGb3IgRUNCIG1vZGUsIGdpdmUgbnVsbCBhcyBpdi4KICAgICAqCiAgICAgKiBAcGFyYW0gaXYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciB0byB1c2UsIG51bGwgZm9yIEVDQiBtb2RlLgogICAgICogQHBhcmFtIG91dHB1dCB0aGUgb3V0cHV0IHRoZSBidWZmZXIgdG8gd3JpdGUgdG8sIG51bGwgdG8gY3JlYXRlIG9uZS4KICAgICAqLwogICAgc3RhcnQ6IGZ1bmN0aW9uKGl2LCBvdXRwdXQpIHsKICAgICAgaWYoaXYpIHsKICAgICAgICAvKiBDQkMgbW9kZSAqLwogICAgICAgIGlmKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIHsKICAgICAgICAgIGl2ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoaXYpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgX2ZpbmlzaCA9IGZhbHNlOwogICAgICBfaW5wdXQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgICBfb3V0cHV0ID0gb3V0cHV0IHx8IG5ldyBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgICBfaXYgPSBpdjsKCiAgICAgIGNpcGhlci5vdXRwdXQgPSBfb3V0cHV0OwogICAgfSwKCiAgICAvKioKICAgICAqIFVwZGF0ZXMgdGhlIG5leHQgYmxvY2suCiAgICAgKgogICAgICogQHBhcmFtIGlucHV0IHRoZSBidWZmZXIgdG8gcmVhZCBmcm9tLgogICAgICovCiAgICB1cGRhdGU6IGZ1bmN0aW9uKGlucHV0KSB7CiAgICAgIGlmKCFfZmluaXNoKSB7CiAgICAgICAgLy8gbm90IGZpbmlzaGluZywgc28gZmlsbCB0aGUgaW5wdXQgYnVmZmVyIHdpdGggbW9yZSBpbnB1dAogICAgICAgIF9pbnB1dC5wdXRCdWZmZXIoaW5wdXQpOwogICAgICB9CgogICAgICB3aGlsZShfaW5wdXQubGVuZ3RoKCkgPj0gOCkgewogICAgICAgIHJ1blBsYW4oWwogICAgICAgICAgICBbIDUsIG1peFJvdW5kIF0sCiAgICAgICAgICAgIFsgMSwgbWFzaFJvdW5kIF0sCiAgICAgICAgICAgIFsgNiwgbWl4Um91bmQgXSwKICAgICAgICAgICAgWyAxLCBtYXNoUm91bmQgXSwKICAgICAgICAgICAgWyA1LCBtaXhSb3VuZCBdCiAgICAgICAgICBdKTsKICAgICAgfQogICAgfSwKCiAgICAvKioKICAgICAqIEZpbmlzaGVzIGVuY3J5cHRpbmcgb3IgZGVjcnlwdGluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gcGFkIGEgcGFkZGluZyBmdW5jdGlvbiB0byB1c2UsIG51bGwgZm9yIFBLQ1MjNyBwYWRkaW5nLAogICAgICogICAgICAgICAgIHNpZ25hdHVyZShibG9ja1NpemUsIGJ1ZmZlciwgZGVjcnlwdCkuCiAgICAgKgogICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwsIGZhbHNlIG9uIGVycm9yLgogICAgICovCiAgICBmaW5pc2g6IGZ1bmN0aW9uKHBhZCkgewogICAgICB2YXIgcnZhbCA9IHRydWU7CgogICAgICBpZihlbmNyeXB0KSB7CiAgICAgICAgaWYocGFkKSB7CiAgICAgICAgICBydmFsID0gcGFkKDgsIF9pbnB1dCwgIWVuY3J5cHQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBhZGQgUEtDUyM3IHBhZGRpbmcgdG8gYmxvY2sgKGVhY2ggcGFkIGJ5dGUgaXMgdGhlCiAgICAgICAgICAvLyB2YWx1ZSBvZiB0aGUgbnVtYmVyIG9mIHBhZCBieXRlcykKICAgICAgICAgIHZhciBwYWRkaW5nID0gKF9pbnB1dC5sZW5ndGgoKSA9PT0gOCkgPyA4IDogKDggLSBfaW5wdXQubGVuZ3RoKCkpOwogICAgICAgICAgX2lucHV0LmZpbGxXaXRoQnl0ZShwYWRkaW5nLCBwYWRkaW5nKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmKHJ2YWwpIHsKICAgICAgICAvLyBkbyBmaW5hbCB1cGRhdGUKICAgICAgICBfZmluaXNoID0gdHJ1ZTsKICAgICAgICBjaXBoZXIudXBkYXRlKCk7CiAgICAgIH0KCiAgICAgIGlmKCFlbmNyeXB0KSB7CiAgICAgICAgLy8gY2hlY2sgZm9yIGVycm9yOiBpbnB1dCBkYXRhIG5vdCBhIG11bHRpcGxlIG9mIGJsb2NrIHNpemUKICAgICAgICBydmFsID0gKF9pbnB1dC5sZW5ndGgoKSA9PT0gMCk7CiAgICAgICAgaWYocnZhbCkgewogICAgICAgICAgaWYocGFkKSB7CiAgICAgICAgICAgIHJ2YWwgPSBwYWQoOCwgX291dHB1dCwgIWVuY3J5cHQpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gZW5zdXJlIHBhZGRpbmcgYnl0ZSBjb3VudCBpcyB2YWxpZAogICAgICAgICAgICB2YXIgbGVuID0gX291dHB1dC5sZW5ndGgoKTsKICAgICAgICAgICAgdmFyIGNvdW50ID0gX291dHB1dC5hdChsZW4gLSAxKTsKCiAgICAgICAgICAgIGlmKGNvdW50ID4gbGVuKSB7CiAgICAgICAgICAgICAgcnZhbCA9IGZhbHNlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIC8vIHRyaW0gb2ZmIHBhZGRpbmcgYnl0ZXMKICAgICAgICAgICAgICBfb3V0cHV0LnRydW5jYXRlKGNvdW50KTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgcmV0dXJuIHJ2YWw7CiAgICB9CiAgfTsKCiAgcmV0dXJuIGNpcGhlcjsKfTsKCgovKioKICogQ3JlYXRlcyBhbiBSQzIgY2lwaGVyIG9iamVjdCB0byBlbmNyeXB0IGRhdGEgaW4gRUNCIG9yIENCQyBtb2RlIHVzaW5nIHRoZQogKiBnaXZlbiBzeW1tZXRyaWMga2V5LiBUaGUgb3V0cHV0IHdpbGwgYmUgc3RvcmVkIGluIHRoZSAnb3V0cHV0JyBtZW1iZXIKICogb2YgdGhlIHJldHVybmVkIGNpcGhlci4KICoKICogVGhlIGtleSBhbmQgaXYgbWF5IGJlIGdpdmVuIGFzIGEgc3RyaW5nIG9mIGJ5dGVzIG9yIGEgYnl0ZSBidWZmZXIuCiAqIFRoZSBjaXBoZXIgaXMgaW5pdGlhbGl6ZWQgdG8gdXNlIDEyOCBlZmZlY3RpdmUga2V5IGJpdHMuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKiBAcGFyYW0gaXYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciB0byB1c2UuCiAqIEBwYXJhbSBvdXRwdXQgdGhlIGJ1ZmZlciB0byB3cml0ZSB0bywgbnVsbCB0byBjcmVhdGUgb25lLgogKgogKiBAcmV0dXJuIHRoZSBjaXBoZXIuCiAqLwpmb3JnZS5yYzIuc3RhcnRFbmNyeXB0aW5nID0gZnVuY3Rpb24oa2V5LCBpdiwgb3V0cHV0KSB7CiAgdmFyIGNpcGhlciA9IGZvcmdlLnJjMi5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyKGtleSwgMTI4KTsKICBjaXBoZXIuc3RhcnQoaXYsIG91dHB1dCk7CiAgcmV0dXJuIGNpcGhlcjsKfTsKCi8qKgogKiBDcmVhdGVzIGFuIFJDMiBjaXBoZXIgb2JqZWN0IHRvIGVuY3J5cHQgZGF0YSBpbiBFQ0Igb3IgQ0JDIG1vZGUgdXNpbmcgdGhlCiAqIGdpdmVuIHN5bW1ldHJpYyBrZXkuCiAqCiAqIFRoZSBrZXkgbWF5IGJlIGdpdmVuIGFzIGEgc3RyaW5nIG9mIGJ5dGVzIG9yIGEgYnl0ZSBidWZmZXIuCiAqCiAqIFRvIHN0YXJ0IGVuY3J5cHRpbmcgY2FsbCBzdGFydCgpIG9uIHRoZSBjaXBoZXIgd2l0aCBhbiBpdiBhbmQgb3B0aW9uYWwKICogb3V0cHV0IGJ1ZmZlci4KICoKICogQHBhcmFtIGtleSB0aGUgc3ltbWV0cmljIGtleSB0byB1c2UuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLnJjMi5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyID0gZnVuY3Rpb24oa2V5LCBiaXRzKSB7CiAgcmV0dXJuIGNyZWF0ZUNpcGhlcihrZXksIGJpdHMsIHRydWUpOwp9OwoKLyoqCiAqIENyZWF0ZXMgYW4gUkMyIGNpcGhlciBvYmplY3QgdG8gZGVjcnlwdCBkYXRhIGluIEVDQiBvciBDQkMgbW9kZSB1c2luZyB0aGUKICogZ2l2ZW4gc3ltbWV0cmljIGtleS4gVGhlIG91dHB1dCB3aWxsIGJlIHN0b3JlZCBpbiB0aGUgJ291dHB1dCcgbWVtYmVyCiAqIG9mIHRoZSByZXR1cm5lZCBjaXBoZXIuCiAqCiAqIFRoZSBrZXkgYW5kIGl2IG1heSBiZSBnaXZlbiBhcyBhIHN0cmluZyBvZiBieXRlcyBvciBhIGJ5dGUgYnVmZmVyLgogKiBUaGUgY2lwaGVyIGlzIGluaXRpYWxpemVkIHRvIHVzZSAxMjggZWZmZWN0aXZlIGtleSBiaXRzLgogKgogKiBAcGFyYW0ga2V5IHRoZSBzeW1tZXRyaWMga2V5IHRvIHVzZS4KICogQHBhcmFtIGl2IHRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3IgdG8gdXNlLgogKiBAcGFyYW0gb3V0cHV0IHRoZSBidWZmZXIgdG8gd3JpdGUgdG8sIG51bGwgdG8gY3JlYXRlIG9uZS4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZm9yZ2UucmMyLnN0YXJ0RGVjcnlwdGluZyA9IGZ1bmN0aW9uKGtleSwgaXYsIG91dHB1dCkgewogIHZhciBjaXBoZXIgPSBmb3JnZS5yYzIuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcihrZXksIDEyOCk7CiAgY2lwaGVyLnN0YXJ0KGl2LCBvdXRwdXQpOwogIHJldHVybiBjaXBoZXI7Cn07CgovKioKICogQ3JlYXRlcyBhbiBSQzIgY2lwaGVyIG9iamVjdCB0byBkZWNyeXB0IGRhdGEgaW4gRUNCIG9yIENCQyBtb2RlIHVzaW5nIHRoZQogKiBnaXZlbiBzeW1tZXRyaWMga2V5LgogKgogKiBUaGUga2V5IG1heSBiZSBnaXZlbiBhcyBhIHN0cmluZyBvZiBieXRlcyBvciBhIGJ5dGUgYnVmZmVyLgogKgogKiBUbyBzdGFydCBkZWNyeXB0aW5nIGNhbGwgc3RhcnQoKSBvbiB0aGUgY2lwaGVyIHdpdGggYW4gaXYgYW5kIG9wdGlvbmFsCiAqIG91dHB1dCBidWZmZXIuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKgogKiBAcmV0dXJuIHRoZSBjaXBoZXIuCiAqLwpmb3JnZS5yYzIuY3JlYXRlRGVjcnlwdGlvbkNpcGhlciA9IGZ1bmN0aW9uKGtleSwgYml0cykgewogIHJldHVybiBjcmVhdGVDaXBoZXIoa2V5LCBiaXRzLCBmYWxzZSk7Cn07Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdyYzInOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvcmMyJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8vIENvcHlyaWdodCAoYykgMjAwNSAgVG9tIFd1Ci8vIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi8vIFNlZSAiTElDRU5TRSIgZm9yIGRldGFpbHMuCgovLyBCYXNpYyBKYXZhU2NyaXB0IEJOIGxpYnJhcnkgLSBzdWJzZXQgdXNlZnVsIGZvciBSU0EgZW5jcnlwdGlvbi4KCi8qCkxpY2Vuc2luZyAoTElDRU5TRSkKLS0tLS0tLS0tLS0tLS0tLS0tLQoKVGhpcyBzb2Z0d2FyZSBpcyBjb3ZlcmVkIHVuZGVyIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0OgoqLwovKgogKiBDb3B5cmlnaHQgKGMpIDIwMDMtMjAwNSAgVG9tIFd1CiAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZwogKiBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUKICogIlNvZnR3YXJlIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZwogKiB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsCiAqIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0bwogKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8KICogdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZQogKiBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUy1JUyIgQU5EIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCiAqIEVYUFJFU1MsIElNUExJRUQgT1IgT1RIRVJXSVNFLCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OLCBBTlkKICogV0FSUkFOVFkgT0YgTUVSQ0hBTlRBQklMSVRZIE9SIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgogKgogKiBJTiBOTyBFVkVOVCBTSEFMTCBUT00gV1UgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5DSURFTlRBTCwKICogSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9GIEFOWSBLSU5ELCBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSCiAqIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgT1IgTk9UIEFEVklTRUQgT0YKICogVEhFIFBPU1NJQklMSVRZIE9GIERBTUFHRSwgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBBUklTSU5HIE9VVAogKiBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKgogKiBJbiBhZGRpdGlvbiwgdGhlIGZvbGxvd2luZyBjb25kaXRpb24gYXBwbGllczoKICoKICogQWxsIHJlZGlzdHJpYnV0aW9ucyBtdXN0IHJldGFpbiBhbiBpbnRhY3QgY29weSBvZiB0aGlzIGNvcHlyaWdodCBub3RpY2UKICogYW5kIGRpc2NsYWltZXIuCiAqLwovKgpBZGRyZXNzIGFsbCBxdWVzdGlvbnMgcmVnYXJkaW5nIHRoaXMgbGljZW5zZSB0bzoKCiAgVG9tIFd1CiAgdGp3QGNzLlN0YW5mb3JkLkVEVQoqLwoKKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8vIEJpdHMgcGVyIGRpZ2l0CnZhciBkYml0czsKCi8vIEphdmFTY3JpcHQgZW5naW5lIGFuYWx5c2lzCnZhciBjYW5hcnkgPSAweGRlYWRiZWVmY2FmZTsKdmFyIGpfbG0gPSAoKGNhbmFyeSYweGZmZmZmZik9PTB4ZWZjYWZlKTsKCi8vIChwdWJsaWMpIENvbnN0cnVjdG9yCmZ1bmN0aW9uIEJpZ0ludGVnZXIoYSxiLGMpIHsKICB0aGlzLmRhdGEgPSBbXTsKICBpZihhICE9IG51bGwpCiAgICBpZigibnVtYmVyIiA9PSB0eXBlb2YgYSkgdGhpcy5mcm9tTnVtYmVyKGEsYixjKTsKICAgIGVsc2UgaWYoYiA9PSBudWxsICYmICJzdHJpbmciICE9IHR5cGVvZiBhKSB0aGlzLmZyb21TdHJpbmcoYSwyNTYpOwogICAgZWxzZSB0aGlzLmZyb21TdHJpbmcoYSxiKTsKfQoKLy8gcmV0dXJuIG5ldywgdW5zZXQgQmlnSW50ZWdlcgpmdW5jdGlvbiBuYmkoKSB7IHJldHVybiBuZXcgQmlnSW50ZWdlcihudWxsKTsgfQoKLy8gYW06IENvbXB1dGUgd19qICs9ICh4KnRoaXNfaSksIHByb3BhZ2F0ZSBjYXJyaWVzLAovLyBjIGlzIGluaXRpYWwgY2FycnksIHJldHVybnMgZmluYWwgY2FycnkuCi8vIGMgPCAzKmR2YWx1ZSwgeCA8IDIqZHZhbHVlLCB0aGlzX2kgPCBkdmFsdWUKLy8gV2UgbmVlZCB0byBzZWxlY3QgdGhlIGZhc3Rlc3Qgb25lIHRoYXQgd29ya3MgaW4gdGhpcyBlbnZpcm9ubWVudC4KCi8vIGFtMTogdXNlIGEgc2luZ2xlIG11bHQgYW5kIGRpdmlkZSB0byBnZXQgdGhlIGhpZ2ggYml0cywKLy8gbWF4IGRpZ2l0IGJpdHMgc2hvdWxkIGJlIDI2IGJlY2F1c2UKLy8gbWF4IGludGVybmFsIHZhbHVlID0gMipkdmFsdWVeMi0yKmR2YWx1ZSAoPCAyXjUzKQpmdW5jdGlvbiBhbTEoaSx4LHcsaixjLG4pIHsKICB3aGlsZSgtLW4gPj0gMCkgewogICAgdmFyIHYgPSB4KnRoaXMuZGF0YVtpKytdK3cuZGF0YVtqXStjOwogICAgYyA9IE1hdGguZmxvb3Iodi8weDQwMDAwMDApOwogICAgdy5kYXRhW2orK10gPSB2JjB4M2ZmZmZmZjsKICB9CiAgcmV0dXJuIGM7Cn0KLy8gYW0yIGF2b2lkcyBhIGJpZyBtdWx0LWFuZC1leHRyYWN0IGNvbXBsZXRlbHkuCi8vIE1heCBkaWdpdCBiaXRzIHNob3VsZCBiZSA8PSAzMCBiZWNhdXNlIHdlIGRvIGJpdHdpc2Ugb3BzCi8vIG9uIHZhbHVlcyB1cCB0byAyKmhkdmFsdWVeMi1oZHZhbHVlLTEgKDwgMl4zMSkKZnVuY3Rpb24gYW0yKGkseCx3LGosYyxuKSB7CiAgdmFyIHhsID0geCYweDdmZmYsIHhoID0geD4+MTU7CiAgd2hpbGUoLS1uID49IDApIHsKICAgIHZhciBsID0gdGhpcy5kYXRhW2ldJjB4N2ZmZjsKICAgIHZhciBoID0gdGhpcy5kYXRhW2krK10+PjE1OwogICAgdmFyIG0gPSB4aCpsK2gqeGw7CiAgICBsID0geGwqbCsoKG0mMHg3ZmZmKTw8MTUpK3cuZGF0YVtqXSsoYyYweDNmZmZmZmZmKTsKICAgIGMgPSAobD4+PjMwKSsobT4+PjE1KSt4aCpoKyhjPj4+MzApOwogICAgdy5kYXRhW2orK10gPSBsJjB4M2ZmZmZmZmY7CiAgfQogIHJldHVybiBjOwp9Ci8vIEFsdGVybmF0ZWx5LCBzZXQgbWF4IGRpZ2l0IGJpdHMgdG8gMjggc2luY2Ugc29tZQovLyBicm93c2VycyBzbG93IGRvd24gd2hlbiBkZWFsaW5nIHdpdGggMzItYml0IG51bWJlcnMuCmZ1bmN0aW9uIGFtMyhpLHgsdyxqLGMsbikgewogIHZhciB4bCA9IHgmMHgzZmZmLCB4aCA9IHg+PjE0OwogIHdoaWxlKC0tbiA+PSAwKSB7CiAgICB2YXIgbCA9IHRoaXMuZGF0YVtpXSYweDNmZmY7CiAgICB2YXIgaCA9IHRoaXMuZGF0YVtpKytdPj4xNDsKICAgIHZhciBtID0geGgqbCtoKnhsOwogICAgbCA9IHhsKmwrKChtJjB4M2ZmZik8PDE0KSt3LmRhdGFbal0rYzsKICAgIGMgPSAobD4+MjgpKyhtPj4xNCkreGgqaDsKICAgIHcuZGF0YVtqKytdID0gbCYweGZmZmZmZmY7CiAgfQogIHJldHVybiBjOwp9CgovLyBub2RlLmpzIChubyBicm93c2VyKQppZih0eXBlb2YobmF2aWdhdG9yKSA9PT0gJ3VuZGVmaW5lZCcpCnsKICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYW0gPSBhbTM7CiAgIGRiaXRzID0gMjg7Cn0gZWxzZSBpZihqX2xtICYmIChuYXZpZ2F0b3IuYXBwTmFtZSA9PSAiTWljcm9zb2Z0IEludGVybmV0IEV4cGxvcmVyIikpIHsKICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMjsKICBkYml0cyA9IDMwOwp9IGVsc2UgaWYoal9sbSAmJiAobmF2aWdhdG9yLmFwcE5hbWUgIT0gIk5ldHNjYXBlIikpIHsKICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMTsKICBkYml0cyA9IDI2Owp9IGVsc2UgeyAvLyBNb3ppbGxhL05ldHNjYXBlIHNlZW1zIHRvIHByZWZlciBhbTMKICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMzsKICBkYml0cyA9IDI4Owp9CgpCaWdJbnRlZ2VyLnByb3RvdHlwZS5EQiA9IGRiaXRzOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5ETSA9ICgoMTw8ZGJpdHMpLTEpOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5EViA9ICgxPDxkYml0cyk7Cgp2YXIgQklfRlAgPSA1MjsKQmlnSW50ZWdlci5wcm90b3R5cGUuRlYgPSBNYXRoLnBvdygyLEJJX0ZQKTsKQmlnSW50ZWdlci5wcm90b3R5cGUuRjEgPSBCSV9GUC1kYml0czsKQmlnSW50ZWdlci5wcm90b3R5cGUuRjIgPSAyKmRiaXRzLUJJX0ZQOwoKLy8gRGlnaXQgY29udmVyc2lvbnMKdmFyIEJJX1JNID0gIjAxMjM0NTY3ODlhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiI7CnZhciBCSV9SQyA9IG5ldyBBcnJheSgpOwp2YXIgcnIsdnY7CnJyID0gIjAiLmNoYXJDb2RlQXQoMCk7CmZvcih2diA9IDA7IHZ2IDw9IDk7ICsrdnYpIEJJX1JDW3JyKytdID0gdnY7CnJyID0gImEiLmNoYXJDb2RlQXQoMCk7CmZvcih2diA9IDEwOyB2diA8IDM2OyArK3Z2KSBCSV9SQ1tycisrXSA9IHZ2OwpyciA9ICJBIi5jaGFyQ29kZUF0KDApOwpmb3IodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2djsKCmZ1bmN0aW9uIGludDJjaGFyKG4pIHsgcmV0dXJuIEJJX1JNLmNoYXJBdChuKTsgfQpmdW5jdGlvbiBpbnRBdChzLGkpIHsKICB2YXIgYyA9IEJJX1JDW3MuY2hhckNvZGVBdChpKV07CiAgcmV0dXJuIChjPT1udWxsKT8tMTpjOwp9CgovLyAocHJvdGVjdGVkKSBjb3B5IHRoaXMgdG8gcgpmdW5jdGlvbiBibnBDb3B5VG8ocikgewogIGZvcih2YXIgaSA9IHRoaXMudC0xOyBpID49IDA7IC0taSkgci5kYXRhW2ldID0gdGhpcy5kYXRhW2ldOwogIHIudCA9IHRoaXMudDsKICByLnMgPSB0aGlzLnM7Cn0KCi8vIChwcm90ZWN0ZWQpIHNldCBmcm9tIGludGVnZXIgdmFsdWUgeCwgLURWIDw9IHggPCBEVgpmdW5jdGlvbiBibnBGcm9tSW50KHgpIHsKICB0aGlzLnQgPSAxOwogIHRoaXMucyA9ICh4PDApPy0xOjA7CiAgaWYoeCA+IDApIHRoaXMuZGF0YVswXSA9IHg7CiAgZWxzZSBpZih4IDwgLTEpIHRoaXMuZGF0YVswXSA9IHgrdGhpcy5EVjsKICBlbHNlIHRoaXMudCA9IDA7Cn0KCi8vIHJldHVybiBiaWdpbnQgaW5pdGlhbGl6ZWQgdG8gdmFsdWUKZnVuY3Rpb24gbmJ2KGkpIHsgdmFyIHIgPSBuYmkoKTsgci5mcm9tSW50KGkpOyByZXR1cm4gcjsgfQoKLy8gKHByb3RlY3RlZCkgc2V0IGZyb20gc3RyaW5nIGFuZCByYWRpeApmdW5jdGlvbiBibnBGcm9tU3RyaW5nKHMsYikgewogIHZhciBrOwogIGlmKGIgPT0gMTYpIGsgPSA0OwogIGVsc2UgaWYoYiA9PSA4KSBrID0gMzsKICBlbHNlIGlmKGIgPT0gMjU2KSBrID0gODsgLy8gYnl0ZSBhcnJheQogIGVsc2UgaWYoYiA9PSAyKSBrID0gMTsKICBlbHNlIGlmKGIgPT0gMzIpIGsgPSA1OwogIGVsc2UgaWYoYiA9PSA0KSBrID0gMjsKICBlbHNlIHsgdGhpcy5mcm9tUmFkaXgocyxiKTsgcmV0dXJuOyB9CiAgdGhpcy50ID0gMDsKICB0aGlzLnMgPSAwOwogIHZhciBpID0gcy5sZW5ndGgsIG1pID0gZmFsc2UsIHNoID0gMDsKICB3aGlsZSgtLWkgPj0gMCkgewogICAgdmFyIHggPSAoaz09OCk/c1tpXSYweGZmOmludEF0KHMsaSk7CiAgICBpZih4IDwgMCkgewogICAgICBpZihzLmNoYXJBdChpKSA9PSAiLSIpIG1pID0gdHJ1ZTsKICAgICAgY29udGludWU7CiAgICB9CiAgICBtaSA9IGZhbHNlOwogICAgaWYoc2ggPT0gMCkKICAgICAgdGhpcy5kYXRhW3RoaXMudCsrXSA9IHg7CiAgICBlbHNlIGlmKHNoK2sgPiB0aGlzLkRCKSB7CiAgICAgIHRoaXMuZGF0YVt0aGlzLnQtMV0gfD0gKHgmKCgxPDwodGhpcy5EQi1zaCkpLTEpKTw8c2g7CiAgICAgIHRoaXMuZGF0YVt0aGlzLnQrK10gPSAoeD4+KHRoaXMuREItc2gpKTsKICAgIH0gZWxzZQogICAgICB0aGlzLmRhdGFbdGhpcy50LTFdIHw9IHg8PHNoOwogICAgc2ggKz0gazsKICAgIGlmKHNoID49IHRoaXMuREIpIHNoIC09IHRoaXMuREI7CiAgfQogIGlmKGsgPT0gOCAmJiAoc1swXSYweDgwKSAhPSAwKSB7CiAgICB0aGlzLnMgPSAtMTsKICAgIGlmKHNoID4gMCkgdGhpcy5kYXRhW3RoaXMudC0xXSB8PSAoKDE8PCh0aGlzLkRCLXNoKSktMSk8PHNoOwogIH0KICB0aGlzLmNsYW1wKCk7CiAgaWYobWkpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLHRoaXMpOwp9CgovLyAocHJvdGVjdGVkKSBjbGFtcCBvZmYgZXhjZXNzIGhpZ2ggd29yZHMKZnVuY3Rpb24gYm5wQ2xhbXAoKSB7CiAgdmFyIGMgPSB0aGlzLnMmdGhpcy5ETTsKICB3aGlsZSh0aGlzLnQgPiAwICYmIHRoaXMuZGF0YVt0aGlzLnQtMV0gPT0gYykgLS10aGlzLnQ7Cn0KCi8vIChwdWJsaWMpIHJldHVybiBzdHJpbmcgcmVwcmVzZW50YXRpb24gaW4gZ2l2ZW4gcmFkaXgKZnVuY3Rpb24gYm5Ub1N0cmluZyhiKSB7CiAgaWYodGhpcy5zIDwgMCkgcmV0dXJuICItIit0aGlzLm5lZ2F0ZSgpLnRvU3RyaW5nKGIpOwogIHZhciBrOwogIGlmKGIgPT0gMTYpIGsgPSA0OwogIGVsc2UgaWYoYiA9PSA4KSBrID0gMzsKICBlbHNlIGlmKGIgPT0gMikgayA9IDE7CiAgZWxzZSBpZihiID09IDMyKSBrID0gNTsKICBlbHNlIGlmKGIgPT0gNCkgayA9IDI7CiAgZWxzZSByZXR1cm4gdGhpcy50b1JhZGl4KGIpOwogIHZhciBrbSA9ICgxPDxrKS0xLCBkLCBtID0gZmFsc2UsIHIgPSAiIiwgaSA9IHRoaXMudDsKICB2YXIgcCA9IHRoaXMuREItKGkqdGhpcy5EQiklazsKICBpZihpLS0gPiAwKSB7CiAgICBpZihwIDwgdGhpcy5EQiAmJiAoZCA9IHRoaXMuZGF0YVtpXT4+cCkgPiAwKSB7IG0gPSB0cnVlOyByID0gaW50MmNoYXIoZCk7IH0KICAgIHdoaWxlKGkgPj0gMCkgewogICAgICBpZihwIDwgaykgewogICAgICAgIGQgPSAodGhpcy5kYXRhW2ldJigoMTw8cCktMSkpPDwoay1wKTsKICAgICAgICBkIHw9IHRoaXMuZGF0YVstLWldPj4ocCs9dGhpcy5EQi1rKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkID0gKHRoaXMuZGF0YVtpXT4+KHAtPWspKSZrbTsKICAgICAgICBpZihwIDw9IDApIHsgcCArPSB0aGlzLkRCOyAtLWk7IH0KICAgICAgfQogICAgICBpZihkID4gMCkgbSA9IHRydWU7CiAgICAgIGlmKG0pIHIgKz0gaW50MmNoYXIoZCk7CiAgICB9CiAgfQogIHJldHVybiBtP3I6IjAiOwp9CgovLyAocHVibGljKSAtdGhpcwpmdW5jdGlvbiBibk5lZ2F0ZSgpIHsgdmFyIHIgPSBuYmkoKTsgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMscik7IHJldHVybiByOyB9CgovLyAocHVibGljKSB8dGhpc3wKZnVuY3Rpb24gYm5BYnMoKSB7IHJldHVybiAodGhpcy5zPDApP3RoaXMubmVnYXRlKCk6dGhpczsgfQoKLy8gKHB1YmxpYykgcmV0dXJuICsgaWYgdGhpcyA+IGEsIC0gaWYgdGhpcyA8IGEsIDAgaWYgZXF1YWwKZnVuY3Rpb24gYm5Db21wYXJlVG8oYSkgewogIHZhciByID0gdGhpcy5zLWEuczsKICBpZihyICE9IDApIHJldHVybiByOwogIHZhciBpID0gdGhpcy50OwogIHIgPSBpLWEudDsKICBpZihyICE9IDApIHJldHVybiAodGhpcy5zPDApPy1yOnI7CiAgd2hpbGUoLS1pID49IDApIGlmKChyPXRoaXMuZGF0YVtpXS1hLmRhdGFbaV0pICE9IDApIHJldHVybiByOwogIHJldHVybiAwOwp9CgovLyByZXR1cm5zIGJpdCBsZW5ndGggb2YgdGhlIGludGVnZXIgeApmdW5jdGlvbiBuYml0cyh4KSB7CiAgdmFyIHIgPSAxLCB0OwogIGlmKCh0PXg+Pj4xNikgIT0gMCkgeyB4ID0gdDsgciArPSAxNjsgfQogIGlmKCh0PXg+PjgpICE9IDApIHsgeCA9IHQ7IHIgKz0gODsgfQogIGlmKCh0PXg+PjQpICE9IDApIHsgeCA9IHQ7IHIgKz0gNDsgfQogIGlmKCh0PXg+PjIpICE9IDApIHsgeCA9IHQ7IHIgKz0gMjsgfQogIGlmKCh0PXg+PjEpICE9IDApIHsgeCA9IHQ7IHIgKz0gMTsgfQogIHJldHVybiByOwp9CgovLyAocHVibGljKSByZXR1cm4gdGhlIG51bWJlciBvZiBiaXRzIGluICJ0aGlzIgpmdW5jdGlvbiBibkJpdExlbmd0aCgpIHsKICBpZih0aGlzLnQgPD0gMCkgcmV0dXJuIDA7CiAgcmV0dXJuIHRoaXMuREIqKHRoaXMudC0xKStuYml0cyh0aGlzLmRhdGFbdGhpcy50LTFdXih0aGlzLnMmdGhpcy5ETSkpOwp9CgovLyAocHJvdGVjdGVkKSByID0gdGhpcyA8PCBuKkRCCmZ1bmN0aW9uIGJucERMU2hpZnRUbyhuLHIpIHsKICB2YXIgaTsKICBmb3IoaSA9IHRoaXMudC0xOyBpID49IDA7IC0taSkgci5kYXRhW2krbl0gPSB0aGlzLmRhdGFbaV07CiAgZm9yKGkgPSBuLTE7IGkgPj0gMDsgLS1pKSByLmRhdGFbaV0gPSAwOwogIHIudCA9IHRoaXMudCtuOwogIHIucyA9IHRoaXMuczsKfQoKLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPj4gbipEQgpmdW5jdGlvbiBibnBEUlNoaWZ0VG8obixyKSB7CiAgZm9yKHZhciBpID0gbjsgaSA8IHRoaXMudDsgKytpKSByLmRhdGFbaS1uXSA9IHRoaXMuZGF0YVtpXTsKICByLnQgPSBNYXRoLm1heCh0aGlzLnQtbiwwKTsKICByLnMgPSB0aGlzLnM7Cn0KCi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIDw8IG4KZnVuY3Rpb24gYm5wTFNoaWZ0VG8obixyKSB7CiAgdmFyIGJzID0gbiV0aGlzLkRCOwogIHZhciBjYnMgPSB0aGlzLkRCLWJzOwogIHZhciBibSA9ICgxPDxjYnMpLTE7CiAgdmFyIGRzID0gTWF0aC5mbG9vcihuL3RoaXMuREIpLCBjID0gKHRoaXMuczw8YnMpJnRoaXMuRE0sIGk7CiAgZm9yKGkgPSB0aGlzLnQtMTsgaSA+PSAwOyAtLWkpIHsKICAgIHIuZGF0YVtpK2RzKzFdID0gKHRoaXMuZGF0YVtpXT4+Y2JzKXxjOwogICAgYyA9ICh0aGlzLmRhdGFbaV0mYm0pPDxiczsKICB9CiAgZm9yKGkgPSBkcy0xOyBpID49IDA7IC0taSkgci5kYXRhW2ldID0gMDsKICByLmRhdGFbZHNdID0gYzsKICByLnQgPSB0aGlzLnQrZHMrMTsKICByLnMgPSB0aGlzLnM7CiAgci5jbGFtcCgpOwp9CgovLyAocHJvdGVjdGVkKSByID0gdGhpcyA+PiBuCmZ1bmN0aW9uIGJucFJTaGlmdFRvKG4scikgewogIHIucyA9IHRoaXMuczsKICB2YXIgZHMgPSBNYXRoLmZsb29yKG4vdGhpcy5EQik7CiAgaWYoZHMgPj0gdGhpcy50KSB7IHIudCA9IDA7IHJldHVybjsgfQogIHZhciBicyA9IG4ldGhpcy5EQjsKICB2YXIgY2JzID0gdGhpcy5EQi1iczsKICB2YXIgYm0gPSAoMTw8YnMpLTE7CiAgci5kYXRhWzBdID0gdGhpcy5kYXRhW2RzXT4+YnM7CiAgZm9yKHZhciBpID0gZHMrMTsgaSA8IHRoaXMudDsgKytpKSB7CiAgICByLmRhdGFbaS1kcy0xXSB8PSAodGhpcy5kYXRhW2ldJmJtKTw8Y2JzOwogICAgci5kYXRhW2ktZHNdID0gdGhpcy5kYXRhW2ldPj5iczsKICB9CiAgaWYoYnMgPiAwKSByLmRhdGFbdGhpcy50LWRzLTFdIHw9ICh0aGlzLnMmYm0pPDxjYnM7CiAgci50ID0gdGhpcy50LWRzOwogIHIuY2xhbXAoKTsKfQoKLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgLSBhCmZ1bmN0aW9uIGJucFN1YlRvKGEscikgewogIHZhciBpID0gMCwgYyA9IDAsIG0gPSBNYXRoLm1pbihhLnQsdGhpcy50KTsKICB3aGlsZShpIDwgbSkgewogICAgYyArPSB0aGlzLmRhdGFbaV0tYS5kYXRhW2ldOwogICAgci5kYXRhW2krK10gPSBjJnRoaXMuRE07CiAgICBjID4+PSB0aGlzLkRCOwogIH0KICBpZihhLnQgPCB0aGlzLnQpIHsKICAgIGMgLT0gYS5zOwogICAgd2hpbGUoaSA8IHRoaXMudCkgewogICAgICBjICs9IHRoaXMuZGF0YVtpXTsKICAgICAgci5kYXRhW2krK10gPSBjJnRoaXMuRE07CiAgICAgIGMgPj49IHRoaXMuREI7CiAgICB9CiAgICBjICs9IHRoaXMuczsKICB9IGVsc2UgewogICAgYyArPSB0aGlzLnM7CiAgICB3aGlsZShpIDwgYS50KSB7CiAgICAgIGMgLT0gYS5kYXRhW2ldOwogICAgICByLmRhdGFbaSsrXSA9IGMmdGhpcy5ETTsKICAgICAgYyA+Pj0gdGhpcy5EQjsKICAgIH0KICAgIGMgLT0gYS5zOwogIH0KICByLnMgPSAoYzwwKT8tMTowOwogIGlmKGMgPCAtMSkgci5kYXRhW2krK10gPSB0aGlzLkRWK2M7CiAgZWxzZSBpZihjID4gMCkgci5kYXRhW2krK10gPSBjOwogIHIudCA9IGk7CiAgci5jbGFtcCgpOwp9CgovLyAocHJvdGVjdGVkKSByID0gdGhpcyAqIGEsIHIgIT0gdGhpcyxhIChIQUMgMTQuMTIpCi8vICJ0aGlzIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuCmZ1bmN0aW9uIGJucE11bHRpcGx5VG8oYSxyKSB7CiAgdmFyIHggPSB0aGlzLmFicygpLCB5ID0gYS5hYnMoKTsKICB2YXIgaSA9IHgudDsKICByLnQgPSBpK3kudDsKICB3aGlsZSgtLWkgPj0gMCkgci5kYXRhW2ldID0gMDsKICBmb3IoaSA9IDA7IGkgPCB5LnQ7ICsraSkgci5kYXRhW2kreC50XSA9IHguYW0oMCx5LmRhdGFbaV0scixpLDAseC50KTsKICByLnMgPSAwOwogIHIuY2xhbXAoKTsKICBpZih0aGlzLnMgIT0gYS5zKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8ocixyKTsKfQoKLy8gKHByb3RlY3RlZCkgciA9IHRoaXNeMiwgciAhPSB0aGlzIChIQUMgMTQuMTYpCmZ1bmN0aW9uIGJucFNxdWFyZVRvKHIpIHsKICB2YXIgeCA9IHRoaXMuYWJzKCk7CiAgdmFyIGkgPSByLnQgPSAyKngudDsKICB3aGlsZSgtLWkgPj0gMCkgci5kYXRhW2ldID0gMDsKICBmb3IoaSA9IDA7IGkgPCB4LnQtMTsgKytpKSB7CiAgICB2YXIgYyA9IHguYW0oaSx4LmRhdGFbaV0sciwyKmksMCwxKTsKICAgIGlmKChyLmRhdGFbaSt4LnRdKz14LmFtKGkrMSwyKnguZGF0YVtpXSxyLDIqaSsxLGMseC50LWktMSkpID49IHguRFYpIHsKICAgICAgci5kYXRhW2kreC50XSAtPSB4LkRWOwogICAgICByLmRhdGFbaSt4LnQrMV0gPSAxOwogICAgfQogIH0KICBpZihyLnQgPiAwKSByLmRhdGFbci50LTFdICs9IHguYW0oaSx4LmRhdGFbaV0sciwyKmksMCwxKTsKICByLnMgPSAwOwogIHIuY2xhbXAoKTsKfQoKLy8gKHByb3RlY3RlZCkgZGl2aWRlIHRoaXMgYnkgbSwgcXVvdGllbnQgYW5kIHJlbWFpbmRlciB0byBxLCByIChIQUMgMTQuMjApCi8vIHIgIT0gcSwgdGhpcyAhPSBtLiAgcSBvciByIG1heSBiZSBudWxsLgpmdW5jdGlvbiBibnBEaXZSZW1UbyhtLHEscikgewogIHZhciBwbSA9IG0uYWJzKCk7CiAgaWYocG0udCA8PSAwKSByZXR1cm47CiAgdmFyIHB0ID0gdGhpcy5hYnMoKTsKICBpZihwdC50IDwgcG0udCkgewogICAgaWYocSAhPSBudWxsKSBxLmZyb21JbnQoMCk7CiAgICBpZihyICE9IG51bGwpIHRoaXMuY29weVRvKHIpOwogICAgcmV0dXJuOwogIH0KICBpZihyID09IG51bGwpIHIgPSBuYmkoKTsKICB2YXIgeSA9IG5iaSgpLCB0cyA9IHRoaXMucywgbXMgPSBtLnM7CiAgdmFyIG5zaCA9IHRoaXMuREItbmJpdHMocG0uZGF0YVtwbS50LTFdKTsJLy8gbm9ybWFsaXplIG1vZHVsdXMKICBpZihuc2ggPiAwKSB7IHBtLmxTaGlmdFRvKG5zaCx5KTsgcHQubFNoaWZ0VG8obnNoLHIpOyB9IGVsc2UgeyBwbS5jb3B5VG8oeSk7IHB0LmNvcHlUbyhyKTsgfQogIHZhciB5cyA9IHkudDsKICB2YXIgeTAgPSB5LmRhdGFbeXMtMV07CiAgaWYoeTAgPT0gMCkgcmV0dXJuOwogIHZhciB5dCA9IHkwKigxPDx0aGlzLkYxKSsoKHlzPjEpP3kuZGF0YVt5cy0yXT4+dGhpcy5GMjowKTsKICB2YXIgZDEgPSB0aGlzLkZWL3l0LCBkMiA9ICgxPDx0aGlzLkYxKS95dCwgZSA9IDE8PHRoaXMuRjI7CiAgdmFyIGkgPSByLnQsIGogPSBpLXlzLCB0ID0gKHE9PW51bGwpP25iaSgpOnE7CiAgeS5kbFNoaWZ0VG8oaix0KTsKICBpZihyLmNvbXBhcmVUbyh0KSA+PSAwKSB7CiAgICByLmRhdGFbci50KytdID0gMTsKICAgIHIuc3ViVG8odCxyKTsKICB9CiAgQmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKHlzLHQpOwogIHQuc3ViVG8oeSx5KTsJLy8gIm5lZ2F0aXZlIiB5IHNvIHdlIGNhbiByZXBsYWNlIHN1YiB3aXRoIGFtIGxhdGVyCiAgd2hpbGUoeS50IDwgeXMpIHkuZGF0YVt5LnQrK10gPSAwOwogIHdoaWxlKC0taiA+PSAwKSB7CiAgICAvLyBFc3RpbWF0ZSBxdW90aWVudCBkaWdpdAogICAgdmFyIHFkID0gKHIuZGF0YVstLWldPT15MCk/dGhpcy5ETTpNYXRoLmZsb29yKHIuZGF0YVtpXSpkMSsoci5kYXRhW2ktMV0rZSkqZDIpOwogICAgaWYoKHIuZGF0YVtpXSs9eS5hbSgwLHFkLHIsaiwwLHlzKSkgPCBxZCkgewkvLyBUcnkgaXQgb3V0CiAgICAgIHkuZGxTaGlmdFRvKGosdCk7CiAgICAgIHIuc3ViVG8odCxyKTsKICAgICAgd2hpbGUoci5kYXRhW2ldIDwgLS1xZCkgci5zdWJUbyh0LHIpOwogICAgfQogIH0KICBpZihxICE9IG51bGwpIHsKICAgIHIuZHJTaGlmdFRvKHlzLHEpOwogICAgaWYodHMgIT0gbXMpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhxLHEpOwogIH0KICByLnQgPSB5czsKICByLmNsYW1wKCk7CiAgaWYobnNoID4gMCkgci5yU2hpZnRUbyhuc2gscik7CS8vIERlbm9ybWFsaXplIHJlbWFpbmRlcgogIGlmKHRzIDwgMCkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHIscik7Cn0KCi8vIChwdWJsaWMpIHRoaXMgbW9kIGEKZnVuY3Rpb24gYm5Nb2QoYSkgewogIHZhciByID0gbmJpKCk7CiAgdGhpcy5hYnMoKS5kaXZSZW1UbyhhLG51bGwscik7CiAgaWYodGhpcy5zIDwgMCAmJiByLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pID4gMCkgYS5zdWJUbyhyLHIpOwogIHJldHVybiByOwp9CgovLyBNb2R1bGFyIHJlZHVjdGlvbiB1c2luZyAiY2xhc3NpYyIgYWxnb3JpdGhtCmZ1bmN0aW9uIENsYXNzaWMobSkgeyB0aGlzLm0gPSBtOyB9CmZ1bmN0aW9uIGNDb252ZXJ0KHgpIHsKICBpZih4LnMgPCAwIHx8IHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgcmV0dXJuIHgubW9kKHRoaXMubSk7CiAgZWxzZSByZXR1cm4geDsKfQpmdW5jdGlvbiBjUmV2ZXJ0KHgpIHsgcmV0dXJuIHg7IH0KZnVuY3Rpb24gY1JlZHVjZSh4KSB7IHguZGl2UmVtVG8odGhpcy5tLG51bGwseCk7IH0KZnVuY3Rpb24gY011bFRvKHgseSxyKSB7IHgubXVsdGlwbHlUbyh5LHIpOyB0aGlzLnJlZHVjZShyKTsgfQpmdW5jdGlvbiBjU3FyVG8oeCxyKSB7IHguc3F1YXJlVG8ocik7IHRoaXMucmVkdWNlKHIpOyB9CgpDbGFzc2ljLnByb3RvdHlwZS5jb252ZXJ0ID0gY0NvbnZlcnQ7CkNsYXNzaWMucHJvdG90eXBlLnJldmVydCA9IGNSZXZlcnQ7CkNsYXNzaWMucHJvdG90eXBlLnJlZHVjZSA9IGNSZWR1Y2U7CkNsYXNzaWMucHJvdG90eXBlLm11bFRvID0gY011bFRvOwpDbGFzc2ljLnByb3RvdHlwZS5zcXJUbyA9IGNTcXJUbzsKCi8vIChwcm90ZWN0ZWQpIHJldHVybiAiLTEvdGhpcyAlIDJeREIiOyB1c2VmdWwgZm9yIE1vbnQuIHJlZHVjdGlvbgovLyBqdXN0aWZpY2F0aW9uOgovLyAgICAgICAgIHh5ID09IDEgKG1vZCBtKQovLyAgICAgICAgIHh5ID0gIDEra20KLy8gICB4eSgyLXh5KSA9ICgxK2ttKSgxLWttKQovLyB4W3koMi14eSldID0gMS1rXjJtXjIKLy8geFt5KDIteHkpXSA9PSAxIChtb2QgbV4yKQovLyBpZiB5IGlzIDEveCBtb2QgbSwgdGhlbiB5KDIteHkpIGlzIDEveCBtb2QgbV4yCi8vIHNob3VsZCByZWR1Y2UgeCBhbmQgeSgyLXh5KSBieSBtXjIgYXQgZWFjaCBzdGVwIHRvIGtlZXAgc2l6ZSBib3VuZGVkLgovLyBKUyBtdWx0aXBseSAib3ZlcmZsb3dzIiBkaWZmZXJlbnRseSBmcm9tIEMvQysrLCBzbyBjYXJlIGlzIG5lZWRlZCBoZXJlLgpmdW5jdGlvbiBibnBJbnZEaWdpdCgpIHsKICBpZih0aGlzLnQgPCAxKSByZXR1cm4gMDsKICB2YXIgeCA9IHRoaXMuZGF0YVswXTsKICBpZigoeCYxKSA9PSAwKSByZXR1cm4gMDsKICB2YXIgeSA9IHgmMzsJCS8vIHkgPT0gMS94IG1vZCAyXjIKICB5ID0gKHkqKDItKHgmMHhmKSp5KSkmMHhmOwkvLyB5ID09IDEveCBtb2QgMl40CiAgeSA9ICh5KigyLSh4JjB4ZmYpKnkpKSYweGZmOwkvLyB5ID09IDEveCBtb2QgMl44CiAgeSA9ICh5KigyLSgoKHgmMHhmZmZmKSp5KSYweGZmZmYpKSkmMHhmZmZmOwkvLyB5ID09IDEveCBtb2QgMl4xNgogIC8vIGxhc3Qgc3RlcCAtIGNhbGN1bGF0ZSBpbnZlcnNlIG1vZCBEViBkaXJlY3RseTsKICAvLyBhc3N1bWVzIDE2IDwgREIgPD0gMzIgYW5kIGFzc3VtZXMgYWJpbGl0eSB0byBoYW5kbGUgNDgtYml0IGludHMKICB5ID0gKHkqKDIteCp5JXRoaXMuRFYpKSV0aGlzLkRWOwkJLy8geSA9PSAxL3ggbW9kIDJeZGJpdHMKICAvLyB3ZSByZWFsbHkgd2FudCB0aGUgbmVnYXRpdmUgaW52ZXJzZSwgYW5kIC1EViA8IHkgPCBEVgogIHJldHVybiAoeT4wKT90aGlzLkRWLXk6LXk7Cn0KCi8vIE1vbnRnb21lcnkgcmVkdWN0aW9uCmZ1bmN0aW9uIE1vbnRnb21lcnkobSkgewogIHRoaXMubSA9IG07CiAgdGhpcy5tcCA9IG0uaW52RGlnaXQoKTsKICB0aGlzLm1wbCA9IHRoaXMubXAmMHg3ZmZmOwogIHRoaXMubXBoID0gdGhpcy5tcD4+MTU7CiAgdGhpcy51bSA9ICgxPDwobS5EQi0xNSkpLTE7CiAgdGhpcy5tdDIgPSAyKm0udDsKfQoKLy8geFIgbW9kIG0KZnVuY3Rpb24gbW9udENvbnZlcnQoeCkgewogIHZhciByID0gbmJpKCk7CiAgeC5hYnMoKS5kbFNoaWZ0VG8odGhpcy5tLnQscik7CiAgci5kaXZSZW1Ubyh0aGlzLm0sbnVsbCxyKTsKICBpZih4LnMgPCAwICYmIHIuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgPiAwKSB0aGlzLm0uc3ViVG8ocixyKTsKICByZXR1cm4gcjsKfQoKLy8geC9SIG1vZCBtCmZ1bmN0aW9uIG1vbnRSZXZlcnQoeCkgewogIHZhciByID0gbmJpKCk7CiAgeC5jb3B5VG8ocik7CiAgdGhpcy5yZWR1Y2Uocik7CiAgcmV0dXJuIHI7Cn0KCi8vIHggPSB4L1IgbW9kIG0gKEhBQyAxNC4zMikKZnVuY3Rpb24gbW9udFJlZHVjZSh4KSB7CiAgd2hpbGUoeC50IDw9IHRoaXMubXQyKQkvLyBwYWQgeCBzbyBhbSBoYXMgZW5vdWdoIHJvb20gbGF0ZXIKICAgIHguZGF0YVt4LnQrK10gPSAwOwogIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLm0udDsgKytpKSB7CiAgICAvLyBmYXN0ZXIgd2F5IG9mIGNhbGN1bGF0aW5nIHUwID0geC5kYXRhW2ldKm1wIG1vZCBEVgogICAgdmFyIGogPSB4LmRhdGFbaV0mMHg3ZmZmOwogICAgdmFyIHUwID0gKGoqdGhpcy5tcGwrKCgoaip0aGlzLm1waCsoeC5kYXRhW2ldPj4xNSkqdGhpcy5tcGwpJnRoaXMudW0pPDwxNSkpJnguRE07CiAgICAvLyB1c2UgYW0gdG8gY29tYmluZSB0aGUgbXVsdGlwbHktc2hpZnQtYWRkIGludG8gb25lIGNhbGwKICAgIGogPSBpK3RoaXMubS50OwogICAgeC5kYXRhW2pdICs9IHRoaXMubS5hbSgwLHUwLHgsaSwwLHRoaXMubS50KTsKICAgIC8vIHByb3BhZ2F0ZSBjYXJyeQogICAgd2hpbGUoeC5kYXRhW2pdID49IHguRFYpIHsgeC5kYXRhW2pdIC09IHguRFY7IHguZGF0YVsrK2pdKys7IH0KICB9CiAgeC5jbGFtcCgpOwogIHguZHJTaGlmdFRvKHRoaXMubS50LHgpOwogIGlmKHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgeC5zdWJUbyh0aGlzLm0seCk7Cn0KCi8vIHIgPSAieF4yL1IgbW9kIG0iOyB4ICE9IHIKZnVuY3Rpb24gbW9udFNxclRvKHgscikgeyB4LnNxdWFyZVRvKHIpOyB0aGlzLnJlZHVjZShyKTsgfQoKLy8gciA9ICJ4eS9SIG1vZCBtIjsgeCx5ICE9IHIKZnVuY3Rpb24gbW9udE11bFRvKHgseSxyKSB7IHgubXVsdGlwbHlUbyh5LHIpOyB0aGlzLnJlZHVjZShyKTsgfQoKTW9udGdvbWVyeS5wcm90b3R5cGUuY29udmVydCA9IG1vbnRDb252ZXJ0OwpNb250Z29tZXJ5LnByb3RvdHlwZS5yZXZlcnQgPSBtb250UmV2ZXJ0OwpNb250Z29tZXJ5LnByb3RvdHlwZS5yZWR1Y2UgPSBtb250UmVkdWNlOwpNb250Z29tZXJ5LnByb3RvdHlwZS5tdWxUbyA9IG1vbnRNdWxUbzsKTW9udGdvbWVyeS5wcm90b3R5cGUuc3FyVG8gPSBtb250U3FyVG87CgovLyAocHJvdGVjdGVkKSB0cnVlIGlmZiB0aGlzIGlzIGV2ZW4KZnVuY3Rpb24gYm5wSXNFdmVuKCkgeyByZXR1cm4gKCh0aGlzLnQ+MCk/KHRoaXMuZGF0YVswXSYxKTp0aGlzLnMpID09IDA7IH0KCi8vIChwcm90ZWN0ZWQpIHRoaXNeZSwgZSA8IDJeMzIsIGRvaW5nIHNxciBhbmQgbXVsIHdpdGggInIiIChIQUMgMTQuNzkpCmZ1bmN0aW9uIGJucEV4cChlLHopIHsKICBpZihlID4gMHhmZmZmZmZmZiB8fCBlIDwgMSkgcmV0dXJuIEJpZ0ludGVnZXIuT05FOwogIHZhciByID0gbmJpKCksIHIyID0gbmJpKCksIGcgPSB6LmNvbnZlcnQodGhpcyksIGkgPSBuYml0cyhlKS0xOwogIGcuY29weVRvKHIpOwogIHdoaWxlKC0taSA+PSAwKSB7CiAgICB6LnNxclRvKHIscjIpOwogICAgaWYoKGUmKDE8PGkpKSA+IDApIHoubXVsVG8ocjIsZyxyKTsKICAgIGVsc2UgeyB2YXIgdCA9IHI7IHIgPSByMjsgcjIgPSB0OyB9CiAgfQogIHJldHVybiB6LnJldmVydChyKTsKfQoKLy8gKHB1YmxpYykgdGhpc15lICUgbSwgMCA8PSBlIDwgMl4zMgpmdW5jdGlvbiBibk1vZFBvd0ludChlLG0pIHsKICB2YXIgejsKICBpZihlIDwgMjU2IHx8IG0uaXNFdmVuKCkpIHogPSBuZXcgQ2xhc3NpYyhtKTsgZWxzZSB6ID0gbmV3IE1vbnRnb21lcnkobSk7CiAgcmV0dXJuIHRoaXMuZXhwKGUseik7Cn0KCi8vIHByb3RlY3RlZApCaWdJbnRlZ2VyLnByb3RvdHlwZS5jb3B5VG8gPSBibnBDb3B5VG87CkJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21JbnQgPSBibnBGcm9tSW50OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tU3RyaW5nID0gYm5wRnJvbVN0cmluZzsKQmlnSW50ZWdlci5wcm90b3R5cGUuY2xhbXAgPSBibnBDbGFtcDsKQmlnSW50ZWdlci5wcm90b3R5cGUuZGxTaGlmdFRvID0gYm5wRExTaGlmdFRvOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kclNoaWZ0VG8gPSBibnBEUlNoaWZ0VG87CkJpZ0ludGVnZXIucHJvdG90eXBlLmxTaGlmdFRvID0gYm5wTFNoaWZ0VG87CkJpZ0ludGVnZXIucHJvdG90eXBlLnJTaGlmdFRvID0gYm5wUlNoaWZ0VG87CkJpZ0ludGVnZXIucHJvdG90eXBlLnN1YlRvID0gYm5wU3ViVG87CkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5VG8gPSBibnBNdWx0aXBseVRvOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5zcXVhcmVUbyA9IGJucFNxdWFyZVRvOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZSZW1UbyA9IGJucERpdlJlbVRvOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5pbnZEaWdpdCA9IGJucEludkRpZ2l0OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5pc0V2ZW4gPSBibnBJc0V2ZW47CkJpZ0ludGVnZXIucHJvdG90eXBlLmV4cCA9IGJucEV4cDsKCi8vIHB1YmxpYwpCaWdJbnRlZ2VyLnByb3RvdHlwZS50b1N0cmluZyA9IGJuVG9TdHJpbmc7CkJpZ0ludGVnZXIucHJvdG90eXBlLm5lZ2F0ZSA9IGJuTmVnYXRlOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5hYnMgPSBibkFiczsKQmlnSW50ZWdlci5wcm90b3R5cGUuY29tcGFyZVRvID0gYm5Db21wYXJlVG87CkJpZ0ludGVnZXIucHJvdG90eXBlLmJpdExlbmd0aCA9IGJuQml0TGVuZ3RoOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2QgPSBibk1vZDsKQmlnSW50ZWdlci5wcm90b3R5cGUubW9kUG93SW50ID0gYm5Nb2RQb3dJbnQ7CgovLyAiY29uc3RhbnRzIgpCaWdJbnRlZ2VyLlpFUk8gPSBuYnYoMCk7CkJpZ0ludGVnZXIuT05FID0gbmJ2KDEpOwoKLy8ganNibjIgbGliCgovL0NvcHlyaWdodCAoYykgMjAwNS0yMDA5ICBUb20gV3UKLy9BbGwgUmlnaHRzIFJlc2VydmVkLgovL1NlZSAiTElDRU5TRSIgZm9yIGRldGFpbHMgKFNlZSBqc2JuLmpzIGZvciBMSUNFTlNFKS4KCi8vRXh0ZW5kZWQgSmF2YVNjcmlwdCBCTiBmdW5jdGlvbnMsIHJlcXVpcmVkIGZvciBSU0EgcHJpdmF0ZSBvcHMuCgovL1ZlcnNpb24gMS4xOiBuZXcgQmlnSW50ZWdlcigiMCIsIDEwKSByZXR1cm5zICJwcm9wZXIiIHplcm8KCi8vKHB1YmxpYykKZnVuY3Rpb24gYm5DbG9uZSgpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5jb3B5VG8ocik7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIHJldHVybiB2YWx1ZSBhcyBpbnRlZ2VyCmZ1bmN0aW9uIGJuSW50VmFsdWUoKSB7CmlmKHRoaXMucyA8IDApIHsKIGlmKHRoaXMudCA9PSAxKSByZXR1cm4gdGhpcy5kYXRhWzBdLXRoaXMuRFY7CiBlbHNlIGlmKHRoaXMudCA9PSAwKSByZXR1cm4gLTE7Cn0gZWxzZSBpZih0aGlzLnQgPT0gMSkgcmV0dXJuIHRoaXMuZGF0YVswXTsKZWxzZSBpZih0aGlzLnQgPT0gMCkgcmV0dXJuIDA7Ci8vIGFzc3VtZXMgMTYgPCBEQiA8IDMyCnJldHVybiAoKHRoaXMuZGF0YVsxXSYoKDE8PCgzMi10aGlzLkRCKSktMSkpPDx0aGlzLkRCKXx0aGlzLmRhdGFbMF07Cn0KCi8vKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGJ5dGUKZnVuY3Rpb24gYm5CeXRlVmFsdWUoKSB7IHJldHVybiAodGhpcy50PT0wKT90aGlzLnM6KHRoaXMuZGF0YVswXTw8MjQpPj4yNDsgfQoKLy8ocHVibGljKSByZXR1cm4gdmFsdWUgYXMgc2hvcnQgKGFzc3VtZXMgREI+PTE2KQpmdW5jdGlvbiBiblNob3J0VmFsdWUoKSB7IHJldHVybiAodGhpcy50PT0wKT90aGlzLnM6KHRoaXMuZGF0YVswXTw8MTYpPj4xNjsgfQoKLy8ocHJvdGVjdGVkKSByZXR1cm4geCBzLnQuIHJeeCA8IERWCmZ1bmN0aW9uIGJucENodW5rU2l6ZShyKSB7IHJldHVybiBNYXRoLmZsb29yKE1hdGguTE4yKnRoaXMuREIvTWF0aC5sb2cocikpOyB9CgovLyhwdWJsaWMpIDAgaWYgdGhpcyA9PSAwLCAxIGlmIHRoaXMgPiAwCmZ1bmN0aW9uIGJuU2lnTnVtKCkgewppZih0aGlzLnMgPCAwKSByZXR1cm4gLTE7CmVsc2UgaWYodGhpcy50IDw9IDAgfHwgKHRoaXMudCA9PSAxICYmIHRoaXMuZGF0YVswXSA8PSAwKSkgcmV0dXJuIDA7CmVsc2UgcmV0dXJuIDE7Cn0KCi8vKHByb3RlY3RlZCkgY29udmVydCB0byByYWRpeCBzdHJpbmcKZnVuY3Rpb24gYm5wVG9SYWRpeChiKSB7CmlmKGIgPT0gbnVsbCkgYiA9IDEwOwppZih0aGlzLnNpZ251bSgpID09IDAgfHwgYiA8IDIgfHwgYiA+IDM2KSByZXR1cm4gIjAiOwp2YXIgY3MgPSB0aGlzLmNodW5rU2l6ZShiKTsKdmFyIGEgPSBNYXRoLnBvdyhiLGNzKTsKdmFyIGQgPSBuYnYoYSksIHkgPSBuYmkoKSwgeiA9IG5iaSgpLCByID0gIiI7CnRoaXMuZGl2UmVtVG8oZCx5LHopOwp3aGlsZSh5LnNpZ251bSgpID4gMCkgewogciA9IChhK3ouaW50VmFsdWUoKSkudG9TdHJpbmcoYikuc3Vic3RyKDEpICsgcjsKIHkuZGl2UmVtVG8oZCx5LHopOwp9CnJldHVybiB6LmludFZhbHVlKCkudG9TdHJpbmcoYikgKyByOwp9CgovLyhwcm90ZWN0ZWQpIGNvbnZlcnQgZnJvbSByYWRpeCBzdHJpbmcKZnVuY3Rpb24gYm5wRnJvbVJhZGl4KHMsYikgewp0aGlzLmZyb21JbnQoMCk7CmlmKGIgPT0gbnVsbCkgYiA9IDEwOwp2YXIgY3MgPSB0aGlzLmNodW5rU2l6ZShiKTsKdmFyIGQgPSBNYXRoLnBvdyhiLGNzKSwgbWkgPSBmYWxzZSwgaiA9IDAsIHcgPSAwOwpmb3IodmFyIGkgPSAwOyBpIDwgcy5sZW5ndGg7ICsraSkgewogdmFyIHggPSBpbnRBdChzLGkpOwogaWYoeCA8IDApIHsKICAgaWYocy5jaGFyQXQoaSkgPT0gIi0iICYmIHRoaXMuc2lnbnVtKCkgPT0gMCkgbWkgPSB0cnVlOwogICBjb250aW51ZTsKIH0KIHcgPSBiKncreDsKIGlmKCsraiA+PSBjcykgewogICB0aGlzLmRNdWx0aXBseShkKTsKICAgdGhpcy5kQWRkT2Zmc2V0KHcsMCk7CiAgIGogPSAwOwogICB3ID0gMDsKIH0KfQppZihqID4gMCkgewogdGhpcy5kTXVsdGlwbHkoTWF0aC5wb3coYixqKSk7CiB0aGlzLmRBZGRPZmZzZXQodywwKTsKfQppZihtaSkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsdGhpcyk7Cn0KCi8vKHByb3RlY3RlZCkgYWx0ZXJuYXRlIGNvbnN0cnVjdG9yCmZ1bmN0aW9uIGJucEZyb21OdW1iZXIoYSxiLGMpIHsKaWYoIm51bWJlciIgPT0gdHlwZW9mIGIpIHsKIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxpbnQsUk5HKQogaWYoYSA8IDIpIHRoaXMuZnJvbUludCgxKTsKIGVsc2UgewogICB0aGlzLmZyb21OdW1iZXIoYSxjKTsKICAgaWYoIXRoaXMudGVzdEJpdChhLTEpKSAgLy8gZm9yY2UgTVNCIHNldAogICAgIHRoaXMuYml0d2lzZVRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhLTEpLG9wX29yLHRoaXMpOwogICBpZih0aGlzLmlzRXZlbigpKSB0aGlzLmRBZGRPZmZzZXQoMSwwKTsgLy8gZm9yY2Ugb2RkCiAgIHdoaWxlKCF0aGlzLmlzUHJvYmFibGVQcmltZShiKSkgewogICAgIHRoaXMuZEFkZE9mZnNldCgyLDApOwogICAgIGlmKHRoaXMuYml0TGVuZ3RoKCkgPiBhKSB0aGlzLnN1YlRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhLTEpLHRoaXMpOwogICB9CiB9Cn0gZWxzZSB7CiAvLyBuZXcgQmlnSW50ZWdlcihpbnQsUk5HKQogdmFyIHggPSBuZXcgQXJyYXkoKSwgdCA9IGEmNzsKIHgubGVuZ3RoID0gKGE+PjMpKzE7CiBiLm5leHRCeXRlcyh4KTsKIGlmKHQgPiAwKSB4WzBdICY9ICgoMTw8dCktMSk7IGVsc2UgeFswXSA9IDA7CiB0aGlzLmZyb21TdHJpbmcoeCwyNTYpOwp9Cn0KCi8vKHB1YmxpYykgY29udmVydCB0byBiaWdlbmRpYW4gYnl0ZSBhcnJheQpmdW5jdGlvbiBiblRvQnl0ZUFycmF5KCkgewp2YXIgaSA9IHRoaXMudCwgciA9IG5ldyBBcnJheSgpOwpyWzBdID0gdGhpcy5zOwp2YXIgcCA9IHRoaXMuREItKGkqdGhpcy5EQiklOCwgZCwgayA9IDA7CmlmKGktLSA+IDApIHsKIGlmKHAgPCB0aGlzLkRCICYmIChkID0gdGhpcy5kYXRhW2ldPj5wKSAhPSAodGhpcy5zJnRoaXMuRE0pPj5wKQogICByW2srK10gPSBkfCh0aGlzLnM8PCh0aGlzLkRCLXApKTsKIHdoaWxlKGkgPj0gMCkgewogICBpZihwIDwgOCkgewogICAgIGQgPSAodGhpcy5kYXRhW2ldJigoMTw8cCktMSkpPDwoOC1wKTsKICAgICBkIHw9IHRoaXMuZGF0YVstLWldPj4ocCs9dGhpcy5EQi04KTsKICAgfSBlbHNlIHsKICAgICBkID0gKHRoaXMuZGF0YVtpXT4+KHAtPTgpKSYweGZmOwogICAgIGlmKHAgPD0gMCkgeyBwICs9IHRoaXMuREI7IC0taTsgfQogICB9CiAgIGlmKChkJjB4ODApICE9IDApIGQgfD0gLTI1NjsKICAgaWYoayA9PSAwICYmICh0aGlzLnMmMHg4MCkgIT0gKGQmMHg4MCkpICsrazsKICAgaWYoayA+IDAgfHwgZCAhPSB0aGlzLnMpIHJbaysrXSA9IGQ7CiB9Cn0KcmV0dXJuIHI7Cn0KCmZ1bmN0aW9uIGJuRXF1YWxzKGEpIHsgcmV0dXJuKHRoaXMuY29tcGFyZVRvKGEpPT0wKTsgfQpmdW5jdGlvbiBibk1pbihhKSB7IHJldHVybih0aGlzLmNvbXBhcmVUbyhhKTwwKT90aGlzOmE7IH0KZnVuY3Rpb24gYm5NYXgoYSkgeyByZXR1cm4odGhpcy5jb21wYXJlVG8oYSk+MCk/dGhpczphOyB9CgovLyhwcm90ZWN0ZWQpIHIgPSB0aGlzIG9wIGEgKGJpdHdpc2UpCmZ1bmN0aW9uIGJucEJpdHdpc2VUbyhhLG9wLHIpIHsKdmFyIGksIGYsIG0gPSBNYXRoLm1pbihhLnQsdGhpcy50KTsKZm9yKGkgPSAwOyBpIDwgbTsgKytpKSByLmRhdGFbaV0gPSBvcCh0aGlzLmRhdGFbaV0sYS5kYXRhW2ldKTsKaWYoYS50IDwgdGhpcy50KSB7CiBmID0gYS5zJnRoaXMuRE07CiBmb3IoaSA9IG07IGkgPCB0aGlzLnQ7ICsraSkgci5kYXRhW2ldID0gb3AodGhpcy5kYXRhW2ldLGYpOwogci50ID0gdGhpcy50Owp9IGVsc2UgewogZiA9IHRoaXMucyZ0aGlzLkRNOwogZm9yKGkgPSBtOyBpIDwgYS50OyArK2kpIHIuZGF0YVtpXSA9IG9wKGYsYS5kYXRhW2ldKTsKIHIudCA9IGEudDsKfQpyLnMgPSBvcCh0aGlzLnMsYS5zKTsKci5jbGFtcCgpOwp9CgovLyhwdWJsaWMpIHRoaXMgJiBhCmZ1bmN0aW9uIG9wX2FuZCh4LHkpIHsgcmV0dXJuIHgmeTsgfQpmdW5jdGlvbiBibkFuZChhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuYml0d2lzZVRvKGEsb3BfYW5kLHIpOyByZXR1cm4gcjsgfQoKLy8ocHVibGljKSB0aGlzIHwgYQpmdW5jdGlvbiBvcF9vcih4LHkpIHsgcmV0dXJuIHh8eTsgfQpmdW5jdGlvbiBibk9yKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF9vcixyKTsgcmV0dXJuIHI7IH0KCi8vKHB1YmxpYykgdGhpcyBeIGEKZnVuY3Rpb24gb3BfeG9yKHgseSkgeyByZXR1cm4geF55OyB9CmZ1bmN0aW9uIGJuWG9yKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF94b3Iscik7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIHRoaXMgJiB+YQpmdW5jdGlvbiBvcF9hbmRub3QoeCx5KSB7IHJldHVybiB4Jn55OyB9CmZ1bmN0aW9uIGJuQW5kTm90KGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF9hbmRub3Qscik7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIH50aGlzCmZ1bmN0aW9uIGJuTm90KCkgewp2YXIgciA9IG5iaSgpOwpmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHIuZGF0YVtpXSA9IHRoaXMuRE0mfnRoaXMuZGF0YVtpXTsKci50ID0gdGhpcy50OwpyLnMgPSB+dGhpcy5zOwpyZXR1cm4gcjsKfQoKLy8ocHVibGljKSB0aGlzIDw8IG4KZnVuY3Rpb24gYm5TaGlmdExlZnQobikgewp2YXIgciA9IG5iaSgpOwppZihuIDwgMCkgdGhpcy5yU2hpZnRUbygtbixyKTsgZWxzZSB0aGlzLmxTaGlmdFRvKG4scik7CnJldHVybiByOwp9CgovLyhwdWJsaWMpIHRoaXMgPj4gbgpmdW5jdGlvbiBiblNoaWZ0UmlnaHQobikgewp2YXIgciA9IG5iaSgpOwppZihuIDwgMCkgdGhpcy5sU2hpZnRUbygtbixyKTsgZWxzZSB0aGlzLnJTaGlmdFRvKG4scik7CnJldHVybiByOwp9CgovL3JldHVybiBpbmRleCBvZiBsb3dlc3QgMS1iaXQgaW4geCwgeCA8IDJeMzEKZnVuY3Rpb24gbGJpdCh4KSB7CmlmKHggPT0gMCkgcmV0dXJuIC0xOwp2YXIgciA9IDA7CmlmKCh4JjB4ZmZmZikgPT0gMCkgeyB4ID4+PSAxNjsgciArPSAxNjsgfQppZigoeCYweGZmKSA9PSAwKSB7IHggPj49IDg7IHIgKz0gODsgfQppZigoeCYweGYpID09IDApIHsgeCA+Pj0gNDsgciArPSA0OyB9CmlmKCh4JjMpID09IDApIHsgeCA+Pj0gMjsgciArPSAyOyB9CmlmKCh4JjEpID09IDApICsrcjsKcmV0dXJuIHI7Cn0KCi8vKHB1YmxpYykgcmV0dXJucyBpbmRleCBvZiBsb3dlc3QgMS1iaXQgKG9yIC0xIGlmIG5vbmUpCmZ1bmN0aW9uIGJuR2V0TG93ZXN0U2V0Qml0KCkgewpmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpCiBpZih0aGlzLmRhdGFbaV0gIT0gMCkgcmV0dXJuIGkqdGhpcy5EQitsYml0KHRoaXMuZGF0YVtpXSk7CmlmKHRoaXMucyA8IDApIHJldHVybiB0aGlzLnQqdGhpcy5EQjsKcmV0dXJuIC0xOwp9CgovL3JldHVybiBudW1iZXIgb2YgMSBiaXRzIGluIHgKZnVuY3Rpb24gY2JpdCh4KSB7CnZhciByID0gMDsKd2hpbGUoeCAhPSAwKSB7IHggJj0geC0xOyArK3I7IH0KcmV0dXJuIHI7Cn0KCi8vKHB1YmxpYykgcmV0dXJuIG51bWJlciBvZiBzZXQgYml0cwpmdW5jdGlvbiBibkJpdENvdW50KCkgewp2YXIgciA9IDAsIHggPSB0aGlzLnMmdGhpcy5ETTsKZm9yKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKSByICs9IGNiaXQodGhpcy5kYXRhW2ldXngpOwpyZXR1cm4gcjsKfQoKLy8ocHVibGljKSB0cnVlIGlmZiBudGggYml0IGlzIHNldApmdW5jdGlvbiBiblRlc3RCaXQobikgewp2YXIgaiA9IE1hdGguZmxvb3Iobi90aGlzLkRCKTsKaWYoaiA+PSB0aGlzLnQpIHJldHVybih0aGlzLnMhPTApOwpyZXR1cm4oKHRoaXMuZGF0YVtqXSYoMTw8KG4ldGhpcy5EQikpKSE9MCk7Cn0KCi8vKHByb3RlY3RlZCkgdGhpcyBvcCAoMTw8bikKZnVuY3Rpb24gYm5wQ2hhbmdlQml0KG4sb3ApIHsKdmFyIHIgPSBCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQobik7CnRoaXMuYml0d2lzZVRvKHIsb3Ascik7CnJldHVybiByOwp9CgovLyhwdWJsaWMpIHRoaXMgfCAoMTw8bikKZnVuY3Rpb24gYm5TZXRCaXQobikgeyByZXR1cm4gdGhpcy5jaGFuZ2VCaXQobixvcF9vcik7IH0KCi8vKHB1YmxpYykgdGhpcyAmIH4oMTw8bikKZnVuY3Rpb24gYm5DbGVhckJpdChuKSB7IHJldHVybiB0aGlzLmNoYW5nZUJpdChuLG9wX2FuZG5vdCk7IH0KCi8vKHB1YmxpYykgdGhpcyBeICgxPDxuKQpmdW5jdGlvbiBibkZsaXBCaXQobikgeyByZXR1cm4gdGhpcy5jaGFuZ2VCaXQobixvcF94b3IpOyB9CgovLyhwcm90ZWN0ZWQpIHIgPSB0aGlzICsgYQpmdW5jdGlvbiBibnBBZGRUbyhhLHIpIHsKdmFyIGkgPSAwLCBjID0gMCwgbSA9IE1hdGgubWluKGEudCx0aGlzLnQpOwp3aGlsZShpIDwgbSkgewogYyArPSB0aGlzLmRhdGFbaV0rYS5kYXRhW2ldOwogci5kYXRhW2krK10gPSBjJnRoaXMuRE07CiBjID4+PSB0aGlzLkRCOwp9CmlmKGEudCA8IHRoaXMudCkgewogYyArPSBhLnM7CiB3aGlsZShpIDwgdGhpcy50KSB7CiAgIGMgKz0gdGhpcy5kYXRhW2ldOwogICByLmRhdGFbaSsrXSA9IGMmdGhpcy5ETTsKICAgYyA+Pj0gdGhpcy5EQjsKIH0KIGMgKz0gdGhpcy5zOwp9IGVsc2UgewogYyArPSB0aGlzLnM7CiB3aGlsZShpIDwgYS50KSB7CiAgIGMgKz0gYS5kYXRhW2ldOwogICByLmRhdGFbaSsrXSA9IGMmdGhpcy5ETTsKICAgYyA+Pj0gdGhpcy5EQjsKIH0KIGMgKz0gYS5zOwp9CnIucyA9IChjPDApPy0xOjA7CmlmKGMgPiAwKSByLmRhdGFbaSsrXSA9IGM7CmVsc2UgaWYoYyA8IC0xKSByLmRhdGFbaSsrXSA9IHRoaXMuRFYrYzsKci50ID0gaTsKci5jbGFtcCgpOwp9CgovLyhwdWJsaWMpIHRoaXMgKyBhCmZ1bmN0aW9uIGJuQWRkKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5hZGRUbyhhLHIpOyByZXR1cm4gcjsgfQoKLy8ocHVibGljKSB0aGlzIC0gYQpmdW5jdGlvbiBiblN1YnRyYWN0KGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5zdWJUbyhhLHIpOyByZXR1cm4gcjsgfQoKLy8ocHVibGljKSB0aGlzICogYQpmdW5jdGlvbiBibk11bHRpcGx5KGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5tdWx0aXBseVRvKGEscik7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIHRoaXMgLyBhCmZ1bmN0aW9uIGJuRGl2aWRlKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5kaXZSZW1UbyhhLHIsbnVsbCk7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIHRoaXMgJSBhCmZ1bmN0aW9uIGJuUmVtYWluZGVyKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5kaXZSZW1UbyhhLG51bGwscik7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIFt0aGlzL2EsdGhpcyVhXQpmdW5jdGlvbiBibkRpdmlkZUFuZFJlbWFpbmRlcihhKSB7CnZhciBxID0gbmJpKCksIHIgPSBuYmkoKTsKdGhpcy5kaXZSZW1UbyhhLHEscik7CnJldHVybiBuZXcgQXJyYXkocSxyKTsKfQoKLy8ocHJvdGVjdGVkKSB0aGlzICo9IG4sIHRoaXMgPj0gMCwgMSA8IG4gPCBEVgpmdW5jdGlvbiBibnBETXVsdGlwbHkobikgewp0aGlzLmRhdGFbdGhpcy50XSA9IHRoaXMuYW0oMCxuLTEsdGhpcywwLDAsdGhpcy50KTsKKyt0aGlzLnQ7CnRoaXMuY2xhbXAoKTsKfQoKLy8ocHJvdGVjdGVkKSB0aGlzICs9IG4gPDwgdyB3b3JkcywgdGhpcyA+PSAwCmZ1bmN0aW9uIGJucERBZGRPZmZzZXQobix3KSB7CmlmKG4gPT0gMCkgcmV0dXJuOwp3aGlsZSh0aGlzLnQgPD0gdykgdGhpcy5kYXRhW3RoaXMudCsrXSA9IDA7CnRoaXMuZGF0YVt3XSArPSBuOwp3aGlsZSh0aGlzLmRhdGFbd10gPj0gdGhpcy5EVikgewogdGhpcy5kYXRhW3ddIC09IHRoaXMuRFY7CiBpZigrK3cgPj0gdGhpcy50KSB0aGlzLmRhdGFbdGhpcy50KytdID0gMDsKICsrdGhpcy5kYXRhW3ddOwp9Cn0KCi8vQSAibnVsbCIgcmVkdWNlcgpmdW5jdGlvbiBOdWxsRXhwKCkge30KZnVuY3Rpb24gbk5vcCh4KSB7IHJldHVybiB4OyB9CmZ1bmN0aW9uIG5NdWxUbyh4LHkscikgeyB4Lm11bHRpcGx5VG8oeSxyKTsgfQpmdW5jdGlvbiBuU3FyVG8oeCxyKSB7IHguc3F1YXJlVG8ocik7IH0KCk51bGxFeHAucHJvdG90eXBlLmNvbnZlcnQgPSBuTm9wOwpOdWxsRXhwLnByb3RvdHlwZS5yZXZlcnQgPSBuTm9wOwpOdWxsRXhwLnByb3RvdHlwZS5tdWxUbyA9IG5NdWxUbzsKTnVsbEV4cC5wcm90b3R5cGUuc3FyVG8gPSBuU3FyVG87CgovLyhwdWJsaWMpIHRoaXNeZQpmdW5jdGlvbiBiblBvdyhlKSB7IHJldHVybiB0aGlzLmV4cChlLG5ldyBOdWxsRXhwKCkpOyB9CgovLyhwcm90ZWN0ZWQpIHIgPSBsb3dlciBuIHdvcmRzIG9mICJ0aGlzICogYSIsIGEudCA8PSBuCi8vInRoaXMiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS4KZnVuY3Rpb24gYm5wTXVsdGlwbHlMb3dlclRvKGEsbixyKSB7CnZhciBpID0gTWF0aC5taW4odGhpcy50K2EudCxuKTsKci5zID0gMDsgLy8gYXNzdW1lcyBhLHRoaXMgPj0gMApyLnQgPSBpOwp3aGlsZShpID4gMCkgci5kYXRhWy0taV0gPSAwOwp2YXIgajsKZm9yKGogPSByLnQtdGhpcy50OyBpIDwgajsgKytpKSByLmRhdGFbaSt0aGlzLnRdID0gdGhpcy5hbSgwLGEuZGF0YVtpXSxyLGksMCx0aGlzLnQpOwpmb3IoaiA9IE1hdGgubWluKGEudCxuKTsgaSA8IGo7ICsraSkgdGhpcy5hbSgwLGEuZGF0YVtpXSxyLGksMCxuLWkpOwpyLmNsYW1wKCk7Cn0KCi8vKHByb3RlY3RlZCkgciA9ICJ0aGlzICogYSIgd2l0aG91dCBsb3dlciBuIHdvcmRzLCBuID4gMAovLyJ0aGlzIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuCmZ1bmN0aW9uIGJucE11bHRpcGx5VXBwZXJUbyhhLG4scikgewotLW47CnZhciBpID0gci50ID0gdGhpcy50K2EudC1uOwpyLnMgPSAwOyAvLyBhc3N1bWVzIGEsdGhpcyA+PSAwCndoaWxlKC0taSA+PSAwKSByLmRhdGFbaV0gPSAwOwpmb3IoaSA9IE1hdGgubWF4KG4tdGhpcy50LDApOyBpIDwgYS50OyArK2kpCiByLmRhdGFbdGhpcy50K2ktbl0gPSB0aGlzLmFtKG4taSxhLmRhdGFbaV0sciwwLDAsdGhpcy50K2ktbik7CnIuY2xhbXAoKTsKci5kclNoaWZ0VG8oMSxyKTsKfQoKLy9CYXJyZXR0IG1vZHVsYXIgcmVkdWN0aW9uCmZ1bmN0aW9uIEJhcnJldHQobSkgewovLyBzZXR1cCBCYXJyZXR0CnRoaXMucjIgPSBuYmkoKTsKdGhpcy5xMyA9IG5iaSgpOwpCaWdJbnRlZ2VyLk9ORS5kbFNoaWZ0VG8oMiptLnQsdGhpcy5yMik7CnRoaXMubXUgPSB0aGlzLnIyLmRpdmlkZShtKTsKdGhpcy5tID0gbTsKfQoKZnVuY3Rpb24gYmFycmV0dENvbnZlcnQoeCkgewppZih4LnMgPCAwIHx8IHgudCA+IDIqdGhpcy5tLnQpIHJldHVybiB4Lm1vZCh0aGlzLm0pOwplbHNlIGlmKHguY29tcGFyZVRvKHRoaXMubSkgPCAwKSByZXR1cm4geDsKZWxzZSB7IHZhciByID0gbmJpKCk7IHguY29weVRvKHIpOyB0aGlzLnJlZHVjZShyKTsgcmV0dXJuIHI7IH0KfQoKZnVuY3Rpb24gYmFycmV0dFJldmVydCh4KSB7IHJldHVybiB4OyB9CgovL3ggPSB4IG1vZCBtIChIQUMgMTQuNDIpCmZ1bmN0aW9uIGJhcnJldHRSZWR1Y2UoeCkgewp4LmRyU2hpZnRUbyh0aGlzLm0udC0xLHRoaXMucjIpOwppZih4LnQgPiB0aGlzLm0udCsxKSB7IHgudCA9IHRoaXMubS50KzE7IHguY2xhbXAoKTsgfQp0aGlzLm11Lm11bHRpcGx5VXBwZXJUbyh0aGlzLnIyLHRoaXMubS50KzEsdGhpcy5xMyk7CnRoaXMubS5tdWx0aXBseUxvd2VyVG8odGhpcy5xMyx0aGlzLm0udCsxLHRoaXMucjIpOwp3aGlsZSh4LmNvbXBhcmVUbyh0aGlzLnIyKSA8IDApIHguZEFkZE9mZnNldCgxLHRoaXMubS50KzEpOwp4LnN1YlRvKHRoaXMucjIseCk7CndoaWxlKHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgeC5zdWJUbyh0aGlzLm0seCk7Cn0KCi8vciA9IHheMiBtb2QgbTsgeCAhPSByCmZ1bmN0aW9uIGJhcnJldHRTcXJUbyh4LHIpIHsgeC5zcXVhcmVUbyhyKTsgdGhpcy5yZWR1Y2Uocik7IH0KCi8vciA9IHgqeSBtb2QgbTsgeCx5ICE9IHIKZnVuY3Rpb24gYmFycmV0dE11bFRvKHgseSxyKSB7IHgubXVsdGlwbHlUbyh5LHIpOyB0aGlzLnJlZHVjZShyKTsgfQoKQmFycmV0dC5wcm90b3R5cGUuY29udmVydCA9IGJhcnJldHRDb252ZXJ0OwpCYXJyZXR0LnByb3RvdHlwZS5yZXZlcnQgPSBiYXJyZXR0UmV2ZXJ0OwpCYXJyZXR0LnByb3RvdHlwZS5yZWR1Y2UgPSBiYXJyZXR0UmVkdWNlOwpCYXJyZXR0LnByb3RvdHlwZS5tdWxUbyA9IGJhcnJldHRNdWxUbzsKQmFycmV0dC5wcm90b3R5cGUuc3FyVG8gPSBiYXJyZXR0U3FyVG87CgovLyhwdWJsaWMpIHRoaXNeZSAlIG0gKEhBQyAxNC44NSkKZnVuY3Rpb24gYm5Nb2RQb3coZSxtKSB7CnZhciBpID0gZS5iaXRMZW5ndGgoKSwgaywgciA9IG5idigxKSwgejsKaWYoaSA8PSAwKSByZXR1cm4gcjsKZWxzZSBpZihpIDwgMTgpIGsgPSAxOwplbHNlIGlmKGkgPCA0OCkgayA9IDM7CmVsc2UgaWYoaSA8IDE0NCkgayA9IDQ7CmVsc2UgaWYoaSA8IDc2OCkgayA9IDU7CmVsc2UgayA9IDY7CmlmKGkgPCA4KQogeiA9IG5ldyBDbGFzc2ljKG0pOwplbHNlIGlmKG0uaXNFdmVuKCkpCiB6ID0gbmV3IEJhcnJldHQobSk7CmVsc2UKIHogPSBuZXcgTW9udGdvbWVyeShtKTsKCi8vIHByZWNvbXB1dGF0aW9uCnZhciBnID0gbmV3IEFycmF5KCksIG4gPSAzLCBrMSA9IGstMSwga20gPSAoMTw8ayktMTsKZ1sxXSA9IHouY29udmVydCh0aGlzKTsKaWYoayA+IDEpIHsKIHZhciBnMiA9IG5iaSgpOwogei5zcXJUbyhnWzFdLGcyKTsKIHdoaWxlKG4gPD0ga20pIHsKICAgZ1tuXSA9IG5iaSgpOwogICB6Lm11bFRvKGcyLGdbbi0yXSxnW25dKTsKICAgbiArPSAyOwogfQp9Cgp2YXIgaiA9IGUudC0xLCB3LCBpczEgPSB0cnVlLCByMiA9IG5iaSgpLCB0OwppID0gbmJpdHMoZS5kYXRhW2pdKS0xOwp3aGlsZShqID49IDApIHsKIGlmKGkgPj0gazEpIHcgPSAoZS5kYXRhW2pdPj4oaS1rMSkpJmttOwogZWxzZSB7CiAgIHcgPSAoZS5kYXRhW2pdJigoMTw8KGkrMSkpLTEpKTw8KGsxLWkpOwogICBpZihqID4gMCkgdyB8PSBlLmRhdGFbai0xXT4+KHRoaXMuREIraS1rMSk7CiB9CgogbiA9IGs7CiB3aGlsZSgodyYxKSA9PSAwKSB7IHcgPj49IDE7IC0tbjsgfQogaWYoKGkgLT0gbikgPCAwKSB7IGkgKz0gdGhpcy5EQjsgLS1qOyB9CiBpZihpczEpIHsgIC8vIHJldCA9PSAxLCBkb24ndCBib3RoZXIgc3F1YXJpbmcgb3IgbXVsdGlwbHlpbmcgaXQKICAgZ1t3XS5jb3B5VG8ocik7CiAgIGlzMSA9IGZhbHNlOwogfSBlbHNlIHsKICAgd2hpbGUobiA+IDEpIHsgei5zcXJUbyhyLHIyKTsgei5zcXJUbyhyMixyKTsgbiAtPSAyOyB9CiAgIGlmKG4gPiAwKSB6LnNxclRvKHIscjIpOyBlbHNlIHsgdCA9IHI7IHIgPSByMjsgcjIgPSB0OyB9CiAgIHoubXVsVG8ocjIsZ1t3XSxyKTsKIH0KCiB3aGlsZShqID49IDAgJiYgKGUuZGF0YVtqXSYoMTw8aSkpID09IDApIHsKICAgei5zcXJUbyhyLHIyKTsgdCA9IHI7IHIgPSByMjsgcjIgPSB0OwogICBpZigtLWkgPCAwKSB7IGkgPSB0aGlzLkRCLTE7IC0tajsgfQogfQp9CnJldHVybiB6LnJldmVydChyKTsKfQoKLy8ocHVibGljKSBnY2QodGhpcyxhKSAoSEFDIDE0LjU0KQpmdW5jdGlvbiBibkdDRChhKSB7CnZhciB4ID0gKHRoaXMuczwwKT90aGlzLm5lZ2F0ZSgpOnRoaXMuY2xvbmUoKTsKdmFyIHkgPSAoYS5zPDApP2EubmVnYXRlKCk6YS5jbG9uZSgpOwppZih4LmNvbXBhcmVUbyh5KSA8IDApIHsgdmFyIHQgPSB4OyB4ID0geTsgeSA9IHQ7IH0KdmFyIGkgPSB4LmdldExvd2VzdFNldEJpdCgpLCBnID0geS5nZXRMb3dlc3RTZXRCaXQoKTsKaWYoZyA8IDApIHJldHVybiB4OwppZihpIDwgZykgZyA9IGk7CmlmKGcgPiAwKSB7CiB4LnJTaGlmdFRvKGcseCk7CiB5LnJTaGlmdFRvKGcseSk7Cn0Kd2hpbGUoeC5zaWdudW0oKSA+IDApIHsKIGlmKChpID0geC5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB4LnJTaGlmdFRvKGkseCk7CiBpZigoaSA9IHkuZ2V0TG93ZXN0U2V0Qml0KCkpID4gMCkgeS5yU2hpZnRUbyhpLHkpOwogaWYoeC5jb21wYXJlVG8oeSkgPj0gMCkgewogICB4LnN1YlRvKHkseCk7CiAgIHguclNoaWZ0VG8oMSx4KTsKIH0gZWxzZSB7CiAgIHkuc3ViVG8oeCx5KTsKICAgeS5yU2hpZnRUbygxLHkpOwogfQp9CmlmKGcgPiAwKSB5LmxTaGlmdFRvKGcseSk7CnJldHVybiB5Owp9CgovLyhwcm90ZWN0ZWQpIHRoaXMgJSBuLCBuIDwgMl4yNgpmdW5jdGlvbiBibnBNb2RJbnQobikgewppZihuIDw9IDApIHJldHVybiAwOwp2YXIgZCA9IHRoaXMuRFYlbiwgciA9ICh0aGlzLnM8MCk/bi0xOjA7CmlmKHRoaXMudCA+IDApCiBpZihkID09IDApIHIgPSB0aGlzLmRhdGFbMF0lbjsKIGVsc2UgZm9yKHZhciBpID0gdGhpcy50LTE7IGkgPj0gMDsgLS1pKSByID0gKGQqcit0aGlzLmRhdGFbaV0pJW47CnJldHVybiByOwp9CgovLyhwdWJsaWMpIDEvdGhpcyAlIG0gKEhBQyAxNC42MSkKZnVuY3Rpb24gYm5Nb2RJbnZlcnNlKG0pIHsKdmFyIGFjID0gbS5pc0V2ZW4oKTsKaWYoKHRoaXMuaXNFdmVuKCkgJiYgYWMpIHx8IG0uc2lnbnVtKCkgPT0gMCkgcmV0dXJuIEJpZ0ludGVnZXIuWkVSTzsKdmFyIHUgPSBtLmNsb25lKCksIHYgPSB0aGlzLmNsb25lKCk7CnZhciBhID0gbmJ2KDEpLCBiID0gbmJ2KDApLCBjID0gbmJ2KDApLCBkID0gbmJ2KDEpOwp3aGlsZSh1LnNpZ251bSgpICE9IDApIHsKIHdoaWxlKHUuaXNFdmVuKCkpIHsKICAgdS5yU2hpZnRUbygxLHUpOwogICBpZihhYykgewogICAgIGlmKCFhLmlzRXZlbigpIHx8ICFiLmlzRXZlbigpKSB7IGEuYWRkVG8odGhpcyxhKTsgYi5zdWJUbyhtLGIpOyB9CiAgICAgYS5yU2hpZnRUbygxLGEpOwogICB9IGVsc2UgaWYoIWIuaXNFdmVuKCkpIGIuc3ViVG8obSxiKTsKICAgYi5yU2hpZnRUbygxLGIpOwogfQogd2hpbGUodi5pc0V2ZW4oKSkgewogICB2LnJTaGlmdFRvKDEsdik7CiAgIGlmKGFjKSB7CiAgICAgaWYoIWMuaXNFdmVuKCkgfHwgIWQuaXNFdmVuKCkpIHsgYy5hZGRUbyh0aGlzLGMpOyBkLnN1YlRvKG0sZCk7IH0KICAgICBjLnJTaGlmdFRvKDEsYyk7CiAgIH0gZWxzZSBpZighZC5pc0V2ZW4oKSkgZC5zdWJUbyhtLGQpOwogICBkLnJTaGlmdFRvKDEsZCk7CiB9CiBpZih1LmNvbXBhcmVUbyh2KSA+PSAwKSB7CiAgIHUuc3ViVG8odix1KTsKICAgaWYoYWMpIGEuc3ViVG8oYyxhKTsKICAgYi5zdWJUbyhkLGIpOwogfSBlbHNlIHsKICAgdi5zdWJUbyh1LHYpOwogICBpZihhYykgYy5zdWJUbyhhLGMpOwogICBkLnN1YlRvKGIsZCk7CiB9Cn0KaWYodi5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpICE9IDApIHJldHVybiBCaWdJbnRlZ2VyLlpFUk87CmlmKGQuY29tcGFyZVRvKG0pID49IDApIHJldHVybiBkLnN1YnRyYWN0KG0pOwppZihkLnNpZ251bSgpIDwgMCkgZC5hZGRUbyhtLGQpOyBlbHNlIHJldHVybiBkOwppZihkLnNpZ251bSgpIDwgMCkgcmV0dXJuIGQuYWRkKG0pOyBlbHNlIHJldHVybiBkOwp9Cgp2YXIgbG93cHJpbWVzID0gWzIsMyw1LDcsMTEsMTMsMTcsMTksMjMsMjksMzEsMzcsNDEsNDMsNDcsNTMsNTksNjEsNjcsNzEsNzMsNzksODMsODksOTcsMTAxLDEwMywxMDcsMTA5LDExMywxMjcsMTMxLDEzNywxMzksMTQ5LDE1MSwxNTcsMTYzLDE2NywxNzMsMTc5LDE4MSwxOTEsMTkzLDE5NywxOTksMjExLDIyMywyMjcsMjI5LDIzMywyMzksMjQxLDI1MSwyNTcsMjYzLDI2OSwyNzEsMjc3LDI4MSwyODMsMjkzLDMwNywzMTEsMzEzLDMxNywzMzEsMzM3LDM0NywzNDksMzUzLDM1OSwzNjcsMzczLDM3OSwzODMsMzg5LDM5Nyw0MDEsNDA5LDQxOSw0MjEsNDMxLDQzMyw0MzksNDQzLDQ0OSw0NTcsNDYxLDQ2Myw0NjcsNDc5LDQ4Nyw0OTEsNDk5LDUwMyw1MDldOwp2YXIgbHBsaW0gPSAoMTw8MjYpL2xvd3ByaW1lc1tsb3dwcmltZXMubGVuZ3RoLTFdOwoKLy8ocHVibGljKSB0ZXN0IHByaW1hbGl0eSB3aXRoIGNlcnRhaW50eSA+PSAxLS41XnQKZnVuY3Rpb24gYm5Jc1Byb2JhYmxlUHJpbWUodCkgewp2YXIgaSwgeCA9IHRoaXMuYWJzKCk7CmlmKHgudCA9PSAxICYmIHguZGF0YVswXSA8PSBsb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aC0xXSkgewogZm9yKGkgPSAwOyBpIDwgbG93cHJpbWVzLmxlbmd0aDsgKytpKQogICBpZih4LmRhdGFbMF0gPT0gbG93cHJpbWVzW2ldKSByZXR1cm4gdHJ1ZTsKIHJldHVybiBmYWxzZTsKfQppZih4LmlzRXZlbigpKSByZXR1cm4gZmFsc2U7CmkgPSAxOwp3aGlsZShpIDwgbG93cHJpbWVzLmxlbmd0aCkgewogdmFyIG0gPSBsb3dwcmltZXNbaV0sIGogPSBpKzE7CiB3aGlsZShqIDwgbG93cHJpbWVzLmxlbmd0aCAmJiBtIDwgbHBsaW0pIG0gKj0gbG93cHJpbWVzW2orK107CiBtID0geC5tb2RJbnQobSk7CiB3aGlsZShpIDwgaikgaWYobSVsb3dwcmltZXNbaSsrXSA9PSAwKSByZXR1cm4gZmFsc2U7Cn0KcmV0dXJuIHgubWlsbGVyUmFiaW4odCk7Cn0KCi8vKHByb3RlY3RlZCkgdHJ1ZSBpZiBwcm9iYWJseSBwcmltZSAoSEFDIDQuMjQsIE1pbGxlci1SYWJpbikKZnVuY3Rpb24gYm5wTWlsbGVyUmFiaW4odCkgewp2YXIgbjEgPSB0aGlzLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTsKdmFyIGsgPSBuMS5nZXRMb3dlc3RTZXRCaXQoKTsKaWYoayA8PSAwKSByZXR1cm4gZmFsc2U7CnZhciByID0gbjEuc2hpZnRSaWdodChrKTsKdmFyIHBybmcgPSBibkdldFBybmcoKTsKdmFyIGE7CmZvcih2YXIgaSA9IDA7IGkgPCB0OyArK2kpIHsKIC8vIHNlbGVjdCB3aXRuZXNzICdhJyBhdCByYW5kb20gZnJvbSBiZXR3ZWVuIDEgYW5kIG4xCiBkbyB7CiAgIGEgPSBuZXcgQmlnSW50ZWdlcih0aGlzLmJpdExlbmd0aCgpLCBwcm5nKTsKIH0KIHdoaWxlKGEuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA8PSAwIHx8IGEuY29tcGFyZVRvKG4xKSA+PSAwKTsKIHZhciB5ID0gYS5tb2RQb3cocix0aGlzKTsKIGlmKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPSAwICYmIHkuY29tcGFyZVRvKG4xKSAhPSAwKSB7CiAgIHZhciBqID0gMTsKICAgd2hpbGUoaisrIDwgayAmJiB5LmNvbXBhcmVUbyhuMSkgIT0gMCkgewogICAgIHkgPSB5Lm1vZFBvd0ludCgyLHRoaXMpOwogICAgIGlmKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwKSByZXR1cm4gZmFsc2U7CiAgIH0KICAgaWYoeS5jb21wYXJlVG8objEpICE9IDApIHJldHVybiBmYWxzZTsKIH0KfQpyZXR1cm4gdHJ1ZTsKfQoKLy8gZ2V0IHBzZXVkbyByYW5kb20gbnVtYmVyIGdlbmVyYXRvcgpmdW5jdGlvbiBibkdldFBybmcoKSB7CiAgLy8gY3JlYXRlIHBybmcgd2l0aCBhcGkgdGhhdCBtYXRjaGVzIEJpZ0ludGVnZXIgc2VjdXJlIHJhbmRvbQogIHJldHVybiB7CiAgICAvLyB4IGlzIGFuIGFycmF5IHRvIGZpbGwgd2l0aCBieXRlcwogICAgbmV4dEJ5dGVzOiBmdW5jdGlvbih4KSB7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgeFtpXSA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDB4MDEwMCk7CiAgICAgIH0KICAgIH0KICB9Owp9CgovL3Byb3RlY3RlZApCaWdJbnRlZ2VyLnByb3RvdHlwZS5jaHVua1NpemUgPSBibnBDaHVua1NpemU7CkJpZ0ludGVnZXIucHJvdG90eXBlLnRvUmFkaXggPSBibnBUb1JhZGl4OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tUmFkaXggPSBibnBGcm9tUmFkaXg7CkJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21OdW1iZXIgPSBibnBGcm9tTnVtYmVyOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXR3aXNlVG8gPSBibnBCaXR3aXNlVG87CkJpZ0ludGVnZXIucHJvdG90eXBlLmNoYW5nZUJpdCA9IGJucENoYW5nZUJpdDsKQmlnSW50ZWdlci5wcm90b3R5cGUuYWRkVG8gPSBibnBBZGRUbzsKQmlnSW50ZWdlci5wcm90b3R5cGUuZE11bHRpcGx5ID0gYm5wRE11bHRpcGx5OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kQWRkT2Zmc2V0ID0gYm5wREFkZE9mZnNldDsKQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHlMb3dlclRvID0gYm5wTXVsdGlwbHlMb3dlclRvOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseVVwcGVyVG8gPSBibnBNdWx0aXBseVVwcGVyVG87CkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludCA9IGJucE1vZEludDsKQmlnSW50ZWdlci5wcm90b3R5cGUubWlsbGVyUmFiaW4gPSBibnBNaWxsZXJSYWJpbjsKCi8vcHVibGljCkJpZ0ludGVnZXIucHJvdG90eXBlLmNsb25lID0gYm5DbG9uZTsKQmlnSW50ZWdlci5wcm90b3R5cGUuaW50VmFsdWUgPSBibkludFZhbHVlOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5ieXRlVmFsdWUgPSBibkJ5dGVWYWx1ZTsKQmlnSW50ZWdlci5wcm90b3R5cGUuc2hvcnRWYWx1ZSA9IGJuU2hvcnRWYWx1ZTsKQmlnSW50ZWdlci5wcm90b3R5cGUuc2lnbnVtID0gYm5TaWdOdW07CkJpZ0ludGVnZXIucHJvdG90eXBlLnRvQnl0ZUFycmF5ID0gYm5Ub0J5dGVBcnJheTsKQmlnSW50ZWdlci5wcm90b3R5cGUuZXF1YWxzID0gYm5FcXVhbHM7CkJpZ0ludGVnZXIucHJvdG90eXBlLm1pbiA9IGJuTWluOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5tYXggPSBibk1heDsKQmlnSW50ZWdlci5wcm90b3R5cGUuYW5kID0gYm5BbmQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLm9yID0gYm5PcjsKQmlnSW50ZWdlci5wcm90b3R5cGUueG9yID0gYm5Yb3I7CkJpZ0ludGVnZXIucHJvdG90eXBlLmFuZE5vdCA9IGJuQW5kTm90OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5ub3QgPSBibk5vdDsKQmlnSW50ZWdlci5wcm90b3R5cGUuc2hpZnRMZWZ0ID0gYm5TaGlmdExlZnQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLnNoaWZ0UmlnaHQgPSBiblNoaWZ0UmlnaHQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLmdldExvd2VzdFNldEJpdCA9IGJuR2V0TG93ZXN0U2V0Qml0OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXRDb3VudCA9IGJuQml0Q291bnQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLnRlc3RCaXQgPSBiblRlc3RCaXQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLnNldEJpdCA9IGJuU2V0Qml0OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5jbGVhckJpdCA9IGJuQ2xlYXJCaXQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLmZsaXBCaXQgPSBibkZsaXBCaXQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLmFkZCA9IGJuQWRkOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5zdWJ0cmFjdCA9IGJuU3VidHJhY3Q7CkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5ID0gYm5NdWx0aXBseTsKQmlnSW50ZWdlci5wcm90b3R5cGUuZGl2aWRlID0gYm5EaXZpZGU7CkJpZ0ludGVnZXIucHJvdG90eXBlLnJlbWFpbmRlciA9IGJuUmVtYWluZGVyOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZpZGVBbmRSZW1haW5kZXIgPSBibkRpdmlkZUFuZFJlbWFpbmRlcjsKQmlnSW50ZWdlci5wcm90b3R5cGUubW9kUG93ID0gYm5Nb2RQb3c7CkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludmVyc2UgPSBibk1vZEludmVyc2U7CkJpZ0ludGVnZXIucHJvdG90eXBlLnBvdyA9IGJuUG93OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5nY2QgPSBibkdDRDsKQmlnSW50ZWdlci5wcm90b3R5cGUuaXNQcm9iYWJsZVByaW1lID0gYm5Jc1Byb2JhYmxlUHJpbWU7CgovL0JpZ0ludGVnZXIgaW50ZXJmYWNlcyBub3QgaW1wbGVtZW50ZWQgaW4ganNibjoKCi8vQmlnSW50ZWdlcihpbnQgc2lnbnVtLCBieXRlW10gbWFnbml0dWRlKQovL2RvdWJsZSBkb3VibGVWYWx1ZSgpCi8vZmxvYXQgZmxvYXRWYWx1ZSgpCi8vaW50IGhhc2hDb2RlKCkKLy9sb25nIGxvbmdWYWx1ZSgpCi8vc3RhdGljIEJpZ0ludGVnZXIgdmFsdWVPZihsb25nIHZhbCkKCmZvcmdlLmpzYm4gPSBmb3JnZS5qc2JuIHx8IHt9Owpmb3JnZS5qc2JuLkJpZ0ludGVnZXIgPSBCaWdJbnRlZ2VyOwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAnanNibic7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9qc2JuJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFBhcnRpYWwgaW1wbGVtZW50YXRpb24gb2YgUEtDUyMxIHYyLjI6IFJTQS1PRUFQCiAqCiAqIE1vZGlmaWVkIGJ1dCBiYXNlZCBvbiB0aGUgZm9sbG93aW5nIE1JVCBhbmQgQlNEIGxpY2Vuc2VkIGNvZGU6CiAqCiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9ranVyL2pzandzL2Jsb2IvbWFzdGVyL3JzYS5qczoKICoKICogVGhlICdqc2p3cycoSlNPTiBXZWIgU2lnbmF0dXJlIEphdmFTY3JpcHQgTGlicmFyeSkgTGljZW5zZQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIgS2VuamkgVXJ1c2hpbWEKICoKICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQogKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAogKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCiAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKICogY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzCiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CiAqCiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgogKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKICogT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTgogKiBUSEUgU09GVFdBUkUuCiAqCiAqIGh0dHA6Ly93ZWJyc2EuY3ZzLnNvdXJjZWZvcmdlLm5ldC92aWV3dmMvd2VicnNhL0NsaWVudC9SU0FFUy1PQUVQLmpzP2NvbnRlbnQtdHlwZT10ZXh0JTJGcGxhaW46CiAqCiAqIFJTQUVTLU9BRVAuanMKICogJElkOiBSU0FFUy1PQUVQLmpzLHYgMS4xLjEuMSAyMDAzLzAzLzE5IDE1OjM3OjIwIGVsbGlzcHJpdGNoYXJkIEV4cCAkCiAqIEphdmFTY3JpcHQgSW1wbGVtZW50YXRpb24gb2YgUEtDUyAjMSB2Mi4xIFJTQSBDUllQVE9HUkFQSFkgU1RBTkRBUkQgKFJTQSBMYWJvcmF0b3JpZXMsIEp1bmUgMTQsIDIwMDIpCiAqIENvcHlyaWdodCAoQykgRWxsaXMgUHJpdGNoYXJkLCBHdWFyZGlhbiBVbmxpbWl0ZWQgMjAwMy4KICogQ29udGFjdDogZWxsaXNAbnVraW5ldGljcy5jb20KICogRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJTRCBMaWNlbnNlLgogKgogKiBPZmZpY2lhbCBkb2N1bWVudGF0aW9uOiBodHRwOi8vd3d3LnJzYS5jb20vcnNhbGFicy9ub2RlLmFzcD9pZD0yMTI1CiAqCiAqIEBhdXRob3IgRXZhbiBKb25lcyAoaHR0cDovL2V2YW5qb25lcy5jYS8pCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKLy8gc2hvcnRjdXQgZm9yIFBLQ1MjMSBBUEkKdmFyIHBrY3MxID0gZm9yZ2UucGtjczEgPSBmb3JnZS5wa2NzMSB8fCB7fTsKCi8qKgogKiBFbmNvZGUgdGhlIGdpdmVuIFJTQUVTLU9BRVAgbWVzc2FnZSAoTSkgdXNpbmcga2V5LCB3aXRoIG9wdGlvbmFsIGxhYmVsIChMKQogKiBhbmQgc2VlZC4KICoKICogVGhpcyBtZXRob2QgZG9lcyBub3QgcGVyZm9ybSBSU0EgZW5jcnlwdGlvbiwgaXQgb25seSBlbmNvZGVzIHRoZSBtZXNzYWdlCiAqIHVzaW5nIFJTQUVTLU9BRVAuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIFJTQSBrZXkgdG8gdXNlLgogKiBAcGFyYW0gbWVzc2FnZSB0aGUgbWVzc2FnZSB0byBlbmNvZGUuCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgbGFiZWwgYW4gb3B0aW9uYWwgbGFiZWwgdG8gdXNlLgogKiAgICAgICAgICBzZWVkIHRoZSBzZWVkIHRvIHVzZS4KICogICAgICAgICAgbWQgdGhlIG1lc3NhZ2UgZGlnZXN0IG9iamVjdCB0byB1c2UsIHVuZGVmaW5lZCBmb3IgU0hBLTEuCiAqICAgICAgICAgIG1nZjEgb3B0aW9uYWwgbWdmMSBwYXJhbWV0ZXJzOgogKiAgICAgICAgICAgIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3QgdG8gdXNlIGZvciBNR0YxLgogKgogKiBAcmV0dXJuIHRoZSBlbmNvZGVkIG1lc3NhZ2UgYnl0ZXMuCiAqLwpwa2NzMS5lbmNvZGVfcnNhX29hZXAgPSBmdW5jdGlvbihrZXksIG1lc3NhZ2UsIG9wdGlvbnMpIHsKICAvLyBwYXJzZSBhcmd1bWVudHMKICB2YXIgbGFiZWw7CiAgdmFyIHNlZWQ7CiAgdmFyIG1kOwogIHZhciBtZ2YxTWQ7CiAgLy8gbGVnYWN5IGFyZ3MgKGxhYmVsLCBzZWVkLCBtZCkKICBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpIHsKICAgIGxhYmVsID0gb3B0aW9uczsKICAgIHNlZWQgPSBhcmd1bWVudHNbM10gfHwgdW5kZWZpbmVkOwogICAgbWQgPSBhcmd1bWVudHNbNF0gfHwgdW5kZWZpbmVkOwogIH0gZWxzZSBpZihvcHRpb25zKSB7CiAgICBsYWJlbCA9IG9wdGlvbnMubGFiZWwgfHwgdW5kZWZpbmVkOwogICAgc2VlZCA9IG9wdGlvbnMuc2VlZCB8fCB1bmRlZmluZWQ7CiAgICBtZCA9IG9wdGlvbnMubWQgfHwgdW5kZWZpbmVkOwogICAgaWYob3B0aW9ucy5tZ2YxICYmIG9wdGlvbnMubWdmMS5tZCkgewogICAgICBtZ2YxTWQgPSBvcHRpb25zLm1nZjEubWQ7CiAgICB9CiAgfQoKICAvLyBkZWZhdWx0IE9BRVAgdG8gU0hBLTEgbWVzc2FnZSBkaWdlc3QKICBpZighbWQpIHsKICAgIG1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICB9IGVsc2UgewogICAgbWQuc3RhcnQoKTsKICB9CgogIC8vIGRlZmF1bHQgTUdGLTEgdG8gc2FtZSBhcyBPQUVQCiAgaWYoIW1nZjFNZCkgewogICAgbWdmMU1kID0gbWQ7CiAgfQoKICAvLyBjb21wdXRlIGxlbmd0aCBpbiBieXRlcyBhbmQgY2hlY2sgb3V0cHV0CiAgdmFyIGtleUxlbmd0aCA9IE1hdGguY2VpbChrZXkubi5iaXRMZW5ndGgoKSAvIDgpOwogIHZhciBtYXhMZW5ndGggPSBrZXlMZW5ndGggLSAyICogbWQuZGlnZXN0TGVuZ3RoIC0gMjsKICBpZihtZXNzYWdlLmxlbmd0aCA+IG1heExlbmd0aCkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdSU0FFUy1PQUVQIGlucHV0IG1lc3NhZ2UgbGVuZ3RoIGlzIHRvbyBsb25nLicpOwogICAgZXJyb3IubGVuZ3RoID0gbWVzc2FnZS5sZW5ndGg7CiAgICBlcnJvci5tYXhMZW5ndGggPSBtYXhMZW5ndGg7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIGlmKCFsYWJlbCkgewogICAgbGFiZWwgPSAnJzsKICB9CiAgbWQudXBkYXRlKGxhYmVsLCAncmF3Jyk7CiAgdmFyIGxIYXNoID0gbWQuZGlnZXN0KCk7CgogIHZhciBQUyA9ICcnOwogIHZhciBQU19sZW5ndGggPSBtYXhMZW5ndGggLSBtZXNzYWdlLmxlbmd0aDsKICBmb3IgKHZhciBpID0gMDsgaSA8IFBTX2xlbmd0aDsgaSsrKSB7CiAgICBQUyArPSAnXHgwMCc7CiAgfQoKICB2YXIgREIgPSBsSGFzaC5nZXRCeXRlcygpICsgUFMgKyAnXHgwMScgKyBtZXNzYWdlOwoKICBpZighc2VlZCkgewogICAgc2VlZCA9IGZvcmdlLnJhbmRvbS5nZXRCeXRlcyhtZC5kaWdlc3RMZW5ndGgpOwogIH0gZWxzZSBpZihzZWVkLmxlbmd0aCAhPT0gbWQuZGlnZXN0TGVuZ3RoKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0ludmFsaWQgUlNBRVMtT0FFUCBzZWVkLiBUaGUgc2VlZCBsZW5ndGggbXVzdCAnICsKICAgICAgJ21hdGNoIHRoZSBkaWdlc3QgbGVuZ3RoLicpCiAgICBlcnJvci5zZWVkTGVuZ3RoID0gc2VlZC5sZW5ndGg7CiAgICBlcnJvci5kaWdlc3RMZW5ndGggPSBtZC5kaWdlc3RMZW5ndGg7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIHZhciBkYk1hc2sgPSByc2FfbWdmMShzZWVkLCBrZXlMZW5ndGggLSBtZC5kaWdlc3RMZW5ndGggLSAxLCBtZ2YxTWQpOwogIHZhciBtYXNrZWREQiA9IGZvcmdlLnV0aWwueG9yQnl0ZXMoREIsIGRiTWFzaywgREIubGVuZ3RoKTsKCiAgdmFyIHNlZWRNYXNrID0gcnNhX21nZjEobWFza2VkREIsIG1kLmRpZ2VzdExlbmd0aCwgbWdmMU1kKTsKICB2YXIgbWFza2VkU2VlZCA9IGZvcmdlLnV0aWwueG9yQnl0ZXMoc2VlZCwgc2VlZE1hc2ssIHNlZWQubGVuZ3RoKTsKCiAgLy8gcmV0dXJuIGVuY29kZWQgbWVzc2FnZQogIHJldHVybiAnXHgwMCcgKyBtYXNrZWRTZWVkICsgbWFza2VkREI7Cn07CgovKioKICogRGVjb2RlIHRoZSBnaXZlbiBSU0FFUy1PQUVQIGVuY29kZWQgbWVzc2FnZSAoRU0pIHVzaW5nIGtleSwgd2l0aCBvcHRpb25hbAogKiBsYWJlbCAoTCkuCiAqCiAqIFRoaXMgbWV0aG9kIGRvZXMgbm90IHBlcmZvcm0gUlNBIGRlY3J5cHRpb24sIGl0IG9ubHkgZGVjb2RlcyB0aGUgbWVzc2FnZQogKiB1c2luZyBSU0FFUy1PQUVQLgogKgogKiBAcGFyYW0ga2V5IHRoZSBSU0Ega2V5IHRvIHVzZS4KICogQHBhcmFtIGVtIHRoZSBlbmNvZGVkIG1lc3NhZ2UgdG8gZGVjb2RlLgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2U6CiAqICAgICAgICAgIGxhYmVsIGFuIG9wdGlvbmFsIGxhYmVsIHRvIHVzZS4KICogICAgICAgICAgbWQgdGhlIG1lc3NhZ2UgZGlnZXN0IG9iamVjdCB0byB1c2UgZm9yIE9BRVAsIHVuZGVmaW5lZCBmb3IgU0hBLTEuCiAqICAgICAgICAgIG1nZjEgb3B0aW9uYWwgbWdmMSBwYXJhbWV0ZXJzOgogKiAgICAgICAgICAgIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3QgdG8gdXNlIGZvciBNR0YxLgogKgogKiBAcmV0dXJuIHRoZSBkZWNvZGVkIG1lc3NhZ2UgYnl0ZXMuCiAqLwpwa2NzMS5kZWNvZGVfcnNhX29hZXAgPSBmdW5jdGlvbihrZXksIGVtLCBvcHRpb25zKSB7CiAgLy8gcGFyc2UgYXJncwogIHZhciBsYWJlbDsKICB2YXIgbWQ7CiAgdmFyIG1nZjFNZDsKICAvLyBsZWdhY3kgYXJncwogIGlmKHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJykgewogICAgbGFiZWwgPSBvcHRpb25zOwogICAgbWQgPSBhcmd1bWVudHNbM10gfHwgdW5kZWZpbmVkOwogIH0gZWxzZSBpZihvcHRpb25zKSB7CiAgICBsYWJlbCA9IG9wdGlvbnMubGFiZWwgfHwgdW5kZWZpbmVkOwogICAgbWQgPSBvcHRpb25zLm1kIHx8IHVuZGVmaW5lZDsKICAgIGlmKG9wdGlvbnMubWdmMSAmJiBvcHRpb25zLm1nZjEubWQpIHsKICAgICAgbWdmMU1kID0gb3B0aW9ucy5tZ2YxLm1kOwogICAgfQogIH0KCiAgLy8gY29tcHV0ZSBsZW5ndGggaW4gYnl0ZXMKICB2YXIga2V5TGVuZ3RoID0gTWF0aC5jZWlsKGtleS5uLmJpdExlbmd0aCgpIC8gOCk7CgogIGlmKGVtLmxlbmd0aCAhPT0ga2V5TGVuZ3RoKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1JTQUVTLU9BRVAgZW5jb2RlZCBtZXNzYWdlIGxlbmd0aCBpcyBpbnZhbGlkLicpOwogICAgZXJyb3IubGVuZ3RoID0gZW0ubGVuZ3RoOwogICAgZXJyb3IuZXhwZWN0ZWRMZW5ndGggPSBrZXlMZW5ndGg7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIC8vIGRlZmF1bHQgT0FFUCB0byBTSEEtMSBtZXNzYWdlIGRpZ2VzdAogIGlmKG1kID09PSB1bmRlZmluZWQpIHsKICAgIG1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICB9IGVsc2UgewogICAgbWQuc3RhcnQoKTsKICB9CgogIC8vIGRlZmF1bHQgTUdGLTEgdG8gc2FtZSBhcyBPQUVQCiAgaWYoIW1nZjFNZCkgewogICAgbWdmMU1kID0gbWQ7CiAgfQoKICBpZihrZXlMZW5ndGggPCAyICogbWQuZGlnZXN0TGVuZ3RoICsgMikgewogICAgdGhyb3cgbmV3IEVycm9yKCdSU0FFUy1PQUVQIGtleSBpcyB0b28gc2hvcnQgZm9yIHRoZSBoYXNoIGZ1bmN0aW9uLicpOwogIH0KCiAgaWYoIWxhYmVsKSB7CiAgICBsYWJlbCA9ICcnOwogIH0KICBtZC51cGRhdGUobGFiZWwsICdyYXcnKTsKICB2YXIgbEhhc2ggPSBtZC5kaWdlc3QoKS5nZXRCeXRlcygpOwoKICAvLyBzcGxpdCB0aGUgbWVzc2FnZSBpbnRvIGl0cyBwYXJ0cwogIHZhciB5ID0gZW0uY2hhckF0KDApOwogIHZhciBtYXNrZWRTZWVkID0gZW0uc3Vic3RyaW5nKDEsIG1kLmRpZ2VzdExlbmd0aCArIDEpOwogIHZhciBtYXNrZWREQiA9IGVtLnN1YnN0cmluZygxICsgbWQuZGlnZXN0TGVuZ3RoKTsKCiAgdmFyIHNlZWRNYXNrID0gcnNhX21nZjEobWFza2VkREIsIG1kLmRpZ2VzdExlbmd0aCwgbWdmMU1kKTsKICB2YXIgc2VlZCA9IGZvcmdlLnV0aWwueG9yQnl0ZXMobWFza2VkU2VlZCwgc2VlZE1hc2ssIG1hc2tlZFNlZWQubGVuZ3RoKTsKCiAgdmFyIGRiTWFzayA9IHJzYV9tZ2YxKHNlZWQsIGtleUxlbmd0aCAtIG1kLmRpZ2VzdExlbmd0aCAtIDEsIG1nZjFNZCk7CiAgdmFyIGRiID0gZm9yZ2UudXRpbC54b3JCeXRlcyhtYXNrZWREQiwgZGJNYXNrLCBtYXNrZWREQi5sZW5ndGgpOwoKICB2YXIgbEhhc2hQcmltZSA9IGRiLnN1YnN0cmluZygwLCBtZC5kaWdlc3RMZW5ndGgpOwoKICAvLyBjb25zdGFudCB0aW1lIGNoZWNrIHRoYXQgYWxsIHZhbHVlcyBtYXRjaCB3aGF0IGlzIGV4cGVjdGVkCiAgdmFyIGVycm9yID0gKHkgIT09ICdceDAwJyk7CgogIC8vIGNvbnN0YW50IHRpbWUgY2hlY2sgbEhhc2ggdnMgbEhhc2hQcmltZQogIGZvcih2YXIgaSA9IDA7IGkgPCBtZC5kaWdlc3RMZW5ndGg7ICsraSkgewogICAgZXJyb3IgfD0gKGxIYXNoLmNoYXJBdChpKSAhPT0gbEhhc2hQcmltZS5jaGFyQXQoaSkpOwogIH0KCiAgLy8gImNvbnN0YW50IHRpbWUiIGZpbmQgdGhlIDB4MSBieXRlIHNlcGFyYXRpbmcgdGhlIHBhZGRpbmcgKHplcm9zKSBmcm9tIHRoZQogIC8vIG1lc3NhZ2UKICAvLyBUT0RPOiBJdCBtdXN0IGJlIHBvc3NpYmxlIHRvIGRvIHRoaXMgaW4gYSBiZXR0ZXIvc21hcnRlciB3YXk/CiAgdmFyIGluX3BzID0gMTsKICB2YXIgaW5kZXggPSBtZC5kaWdlc3RMZW5ndGg7CiAgZm9yKHZhciBqID0gbWQuZGlnZXN0TGVuZ3RoOyBqIDwgZGIubGVuZ3RoOyBqKyspIHsKICAgIHZhciBjb2RlID0gZGIuY2hhckNvZGVBdChqKTsKCiAgICB2YXIgaXNfMCA9IChjb2RlICYgMHgxKSBeIDB4MTsKCiAgICAvLyBub24temVybyBpZiBub3QgMCBvciAxIGluIHRoZSBwcyBzZWN0aW9uCiAgICB2YXIgZXJyb3JfbWFzayA9IGluX3BzID8gMHhmZmZlIDogMHgwMDAwOwogICAgZXJyb3IgfD0gKGNvZGUgJiBlcnJvcl9tYXNrKTsKCiAgICAvLyBsYXRjaCBpbl9wcyB0byB6ZXJvIGFmdGVyIHdlIGZpbmQgMHgxCiAgICBpbl9wcyA9IGluX3BzICYgaXNfMDsKICAgIGluZGV4ICs9IGluX3BzOwogIH0KCiAgaWYoZXJyb3IgfHwgZGIuY2hhckNvZGVBdChpbmRleCkgIT09IDB4MSkgewogICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIFJTQUVTLU9BRVAgcGFkZGluZy4nKTsKICB9CgogIHJldHVybiBkYi5zdWJzdHJpbmcoaW5kZXggKyAxKTsKfTsKCmZ1bmN0aW9uIHJzYV9tZ2YxKHNlZWQsIG1hc2tMZW5ndGgsIGhhc2gpIHsKICAvLyBkZWZhdWx0IHRvIFNIQS0xIG1lc3NhZ2UgZGlnZXN0CiAgaWYoIWhhc2gpIHsKICAgIGhhc2ggPSBmb3JnZS5tZC5zaGExLmNyZWF0ZSgpOwogIH0KICB2YXIgdCA9ICcnOwogIHZhciBjb3VudCA9IE1hdGguY2VpbChtYXNrTGVuZ3RoIC8gaGFzaC5kaWdlc3RMZW5ndGgpOwogIGZvcih2YXIgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7CiAgICB2YXIgYyA9IFN0cmluZy5mcm9tQ2hhckNvZGUoCiAgICAgIChpID4+IDI0KSAmIDB4RkYsIChpID4+IDE2KSAmIDB4RkYsIChpID4+IDgpICYgMHhGRiwgaSAmIDB4RkYpOwogICAgaGFzaC5zdGFydCgpOwogICAgaGFzaC51cGRhdGUoc2VlZCArIGMpOwogICAgdCArPSBoYXNoLmRpZ2VzdCgpLmdldEJ5dGVzKCk7CiAgfQogIHJldHVybiB0LnN1YnN0cmluZygwLCBtYXNrTGVuZ3RoKTsKfQoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAncGtjczEnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvcGtjczEnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi91dGlsJywgJy4vcmFuZG9tJywgJy4vc2hhMSddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBQcmltZSBudW1iZXIgZ2VuZXJhdGlvbiBBUEkuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8vIGZvcmdlLnByaW1lIGFscmVhZHkgZGVmaW5lZAppZihmb3JnZS5wcmltZSkgewogIHJldHVybjsKfQoKLyogUFJJTUUgQVBJICovCnZhciBwcmltZSA9IGZvcmdlLnByaW1lID0gZm9yZ2UucHJpbWUgfHwge307Cgp2YXIgQmlnSW50ZWdlciA9IGZvcmdlLmpzYm4uQmlnSW50ZWdlcjsKCi8vIHByaW1lcyBhcmUgMzBrK2kgZm9yIGkgPSAxLCA3LCAxMSwgMTMsIDE3LCAxOSwgMjMsIDI5CnZhciBHQ0RfMzBfREVMVEEgPSBbNiwgNCwgMiwgNCwgMiwgNCwgNiwgMl07CnZhciBUSElSVFkgPSBuZXcgQmlnSW50ZWdlcihudWxsKTsKVEhJUlRZLmZyb21JbnQoMzApOwp2YXIgb3Bfb3IgPSBmdW5jdGlvbih4LCB5KSB7cmV0dXJuIHh8eTt9OwoKLyoqCiAqIEdlbmVyYXRlcyBhIHJhbmRvbSBwcm9iYWJsZSBwcmltZSB3aXRoIHRoZSBnaXZlbiBudW1iZXIgb2YgYml0cy4KICoKICogQWx0ZXJuYXRpdmUgYWxnb3JpdGhtcyBjYW4gYmUgc3BlY2lmaWVkIGJ5IG5hbWUgYXMgYSBzdHJpbmcgb3IgYXMgYW4KICogb2JqZWN0IHdpdGggY3VzdG9tIG9wdGlvbnMgbGlrZSBzbzoKICoKICogewogKiAgIG5hbWU6ICdQUklNRUlOQycsCiAqICAgb3B0aW9uczogewogKiAgICAgbWF4QmxvY2tUaW1lOiA8dGhlIG1heGltdW0gYW1vdW50IG9mIHRpbWUgdG8gYmxvY2sgdGhlIG1haW4KICogICAgICAgdGhyZWFkIGJlZm9yZSBhbGxvd2luZyBJL08gb3RoZXIgSlMgdG8gcnVuPiwKICogICAgIG1pbGxlclJhYmluVGVzdHM6IDx0aGUgbnVtYmVyIG9mIG1pbGxlci1yYWJpbiB0ZXN0cyB0byBydW4+LAogKiAgICAgd29ya2VyU2NyaXB0OiA8dGhlIHdvcmtlciBzY3JpcHQgVVJMPiwKICogICAgIHdvcmtlcnM6IDx0aGUgbnVtYmVyIG9mIHdlYiB3b3JrZXJzIChpZiBzdXBwb3J0ZWQpIHRvIHVzZSwKICogICAgICAgLTEgdG8gdXNlIGVzdGltYXRlZCBjb3JlcyBtaW51cyBvbmU+LgogKiAgICAgd29ya0xvYWQ6IHRoZSBzaXplIG9mIHRoZSB3b3JrIGxvYWQsIGllOiBudW1iZXIgb2YgcG9zc2libGUgcHJpbWUKICogICAgICAgbnVtYmVycyBmb3IgZWFjaCB3ZWIgd29ya2VyIHRvIGNoZWNrIHBlciB3b3JrIGFzc2lnbm1lbnQsCiAqICAgICAgIChkZWZhdWx0OiAxMDApLgogKiAgIH0KICogfQogKgogKiBAcGFyYW0gYml0cyB0aGUgbnVtYmVyIG9mIGJpdHMgZm9yIHRoZSBwcmltZSBudW1iZXIuCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZS4KICogICAgICAgICAgW2FsZ29yaXRobV0gdGhlIGFsZ29yaXRobSB0byB1c2UgKGRlZmF1bHQ6ICdQUklNRUlOQycpLgogKiAgICAgICAgICBbcHJuZ10gYSBjdXN0b20gY3J5cHRvLXNlY3VyZSBwc2V1ZG8tcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgdG8gdXNlLAogKiAgICAgICAgICAgIHRoYXQgbXVzdCBkZWZpbmUgImdldEJ5dGVzU3luYyIuCiAqCiAqIEByZXR1cm4gY2FsbGJhY2soZXJyLCBudW0pIGNhbGxlZCBvbmNlIHRoZSBvcGVyYXRpb24gY29tcGxldGVzLgogKi8KcHJpbWUuZ2VuZXJhdGVQcm9iYWJsZVByaW1lID0gZnVuY3Rpb24oYml0cywgb3B0aW9ucywgY2FsbGJhY2spIHsKICBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykgewogICAgY2FsbGJhY2sgPSBvcHRpb25zOwogICAgb3B0aW9ucyA9IHt9OwogIH0KICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKCiAgLy8gZGVmYXVsdCB0byBQUklNRUlOQyBhbGdvcml0aG0KICB2YXIgYWxnb3JpdGhtID0gb3B0aW9ucy5hbGdvcml0aG0gfHwgJ1BSSU1FSU5DJzsKICBpZih0eXBlb2YgYWxnb3JpdGhtID09PSAnc3RyaW5nJykgewogICAgYWxnb3JpdGhtID0ge25hbWU6IGFsZ29yaXRobX07CiAgfQogIGFsZ29yaXRobS5vcHRpb25zID0gYWxnb3JpdGhtLm9wdGlvbnMgfHwge307CgogIC8vIGNyZWF0ZSBwcm5nIHdpdGggYXBpIHRoYXQgbWF0Y2hlcyBCaWdJbnRlZ2VyIHNlY3VyZSByYW5kb20KICB2YXIgcHJuZyA9IG9wdGlvbnMucHJuZyB8fCBmb3JnZS5yYW5kb207CiAgdmFyIHJuZyA9IHsKICAgIC8vIHggaXMgYW4gYXJyYXkgdG8gZmlsbCB3aXRoIGJ5dGVzCiAgICBuZXh0Qnl0ZXM6IGZ1bmN0aW9uKHgpIHsKICAgICAgdmFyIGIgPSBwcm5nLmdldEJ5dGVzU3luYyh4Lmxlbmd0aCk7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgeFtpXSA9IGIuY2hhckNvZGVBdChpKTsKICAgICAgfQogICAgfQogIH07CgogIGlmKGFsZ29yaXRobS5uYW1lID09PSAnUFJJTUVJTkMnKSB7CiAgICByZXR1cm4gcHJpbWVpbmNGaW5kUHJpbWUoYml0cywgcm5nLCBhbGdvcml0aG0ub3B0aW9ucywgY2FsbGJhY2spOwogIH0KCiAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHByaW1lIGdlbmVyYXRpb24gYWxnb3JpdGhtOiAnICsgYWxnb3JpdGhtLm5hbWUpOwp9OwoKZnVuY3Rpb24gcHJpbWVpbmNGaW5kUHJpbWUoYml0cywgcm5nLCBvcHRpb25zLCBjYWxsYmFjaykgewogIGlmKCd3b3JrZXJzJyBpbiBvcHRpb25zKSB7CiAgICByZXR1cm4gcHJpbWVpbmNGaW5kUHJpbWVXaXRoV29ya2VycyhiaXRzLCBybmcsIG9wdGlvbnMsIGNhbGxiYWNrKTsKICB9CiAgcmV0dXJuIHByaW1laW5jRmluZFByaW1lV2l0aG91dFdvcmtlcnMoYml0cywgcm5nLCBvcHRpb25zLCBjYWxsYmFjayk7Cn0KCmZ1bmN0aW9uIHByaW1laW5jRmluZFByaW1lV2l0aG91dFdvcmtlcnMoYml0cywgcm5nLCBvcHRpb25zLCBjYWxsYmFjaykgewogIC8vIGluaXRpYWxpemUgcmFuZG9tIG51bWJlcgogIHZhciBudW0gPSBnZW5lcmF0ZVJhbmRvbShiaXRzLCBybmcpOwoKICAvKiBOb3RlOiBBbGwgcHJpbWVzIGFyZSBvZiB0aGUgZm9ybSAzMGsraSBmb3IgaSA8IDMwIGFuZCBnY2QoMzAsIGkpPTEuIFRoZQogIG51bWJlciB3ZSBhcmUgZ2l2ZW4gaXMgYWx3YXlzIGFsaWduZWQgYXQgMzBrICsgMS4gRWFjaCB0aW1lIHRoZSBudW1iZXIgaXMKICBkZXRlcm1pbmVkIG5vdCB0byBiZSBwcmltZSB3ZSBhZGQgdG8gZ2V0IHRvIHRoZSBuZXh0ICdpJywgZWc6IGlmIHRoZSBudW1iZXIKICB3YXMgYXQgMzBrICsgMSB3ZSBhZGQgNi4gKi8KICB2YXIgZGVsdGFJZHggPSAwOwoKICAvLyBnZXQgcmVxdWlyZWQgbnVtYmVyIG9mIE1SIHRlc3RzCiAgdmFyIG1yVGVzdHMgPSBnZXRNaWxsZXJSYWJpblRlc3RzKG51bS5iaXRMZW5ndGgoKSk7CiAgaWYoJ21pbGxlclJhYmluVGVzdHMnIGluIG9wdGlvbnMpIHsKICAgIG1yVGVzdHMgPSBvcHRpb25zLm1pbGxlclJhYmluVGVzdHM7CiAgfQoKICAvLyBmaW5kIHByaW1lIG5lYXJlc3QgdG8gJ251bScgZm9yIG1heEJsb2NrVGltZSBtcwogIC8vIDEwIG1zIGdpdmVzIDVtcyBvZiBsZWV3YXkgZm9yIG90aGVyIGNhbGN1bGF0aW9ucyBiZWZvcmUgZHJvcHBpbmcKICAvLyBiZWxvdyA2MGZwcyAoMTAwMC82MCA9PSAxNi42NyksIGJ1dCBpbiByZWFsaXR5LCB0aGUgbnVtYmVyIHdpbGwKICAvLyBsaWtlbHkgYmUgaGlnaGVyIGR1ZSB0byBhbiAnYXRvbWljJyBiaWcgaW50IG1vZFBvdwogIHZhciBtYXhCbG9ja1RpbWUgPSAxMDsKICBpZignbWF4QmxvY2tUaW1lJyBpbiBvcHRpb25zKSB7CiAgICBtYXhCbG9ja1RpbWUgPSBvcHRpb25zLm1heEJsb2NrVGltZTsKICB9CiAgdmFyIHN0YXJ0ID0gK25ldyBEYXRlKCk7CiAgZG8gewogICAgLy8gb3ZlcmZsb3csIHJlZ2VuZXJhdGUgcmFuZG9tIG51bWJlcgogICAgaWYobnVtLmJpdExlbmd0aCgpID4gYml0cykgewogICAgICBudW0gPSBnZW5lcmF0ZVJhbmRvbShiaXRzLCBybmcpOwogICAgfQogICAgLy8gZG8gcHJpbWFsaXR5IHRlc3QKICAgIGlmKG51bS5pc1Byb2JhYmxlUHJpbWUobXJUZXN0cykpIHsKICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIG51bSk7CiAgICB9CiAgICAvLyBnZXQgbmV4dCBwb3RlbnRpYWwgcHJpbWUKICAgIG51bS5kQWRkT2Zmc2V0KEdDRF8zMF9ERUxUQVtkZWx0YUlkeCsrICUgOF0sIDApOwogIH0gd2hpbGUobWF4QmxvY2tUaW1lIDwgMCB8fCAoK25ldyBEYXRlKCkgLSBzdGFydCA8IG1heEJsb2NrVGltZSkpOwoKICAvLyBrZWVwIHRyeWluZyAoc2V0SW1tZWRpYXRlIHdvdWxkIGJlIGJldHRlciBoZXJlKQogIGZvcmdlLnV0aWwuc2V0SW1tZWRpYXRlKGZ1bmN0aW9uKCkgewogICAgcHJpbWVpbmNGaW5kUHJpbWVXaXRob3V0V29ya2VycyhiaXRzLCBybmcsIG9wdGlvbnMsIGNhbGxiYWNrKTsKICB9KTsKfQoKZnVuY3Rpb24gcHJpbWVpbmNGaW5kUHJpbWVXaXRoV29ya2VycyhiaXRzLCBybmcsIG9wdGlvbnMsIGNhbGxiYWNrKSB7CiAgLy8gd2ViIHdvcmtlcnMgdW5hdmFpbGFibGUKICBpZih0eXBlb2YgV29ya2VyID09PSAndW5kZWZpbmVkJykgewogICAgcmV0dXJuIHByaW1laW5jRmluZFByaW1lV2l0aG91dFdvcmtlcnMoYml0cywgcm5nLCBvcHRpb25zLCBjYWxsYmFjayk7CiAgfQoKICAvLyBpbml0aWFsaXplIHJhbmRvbSBudW1iZXIKICB2YXIgbnVtID0gZ2VuZXJhdGVSYW5kb20oYml0cywgcm5nKTsKCiAgLy8gdXNlIHdlYiB3b3JrZXJzIHRvIGdlbmVyYXRlIGtleXMKICB2YXIgbnVtV29ya2VycyA9IG9wdGlvbnMud29ya2VyczsKICB2YXIgd29ya0xvYWQgPSBvcHRpb25zLndvcmtMb2FkIHx8IDEwMDsKICB2YXIgcmFuZ2UgPSB3b3JrTG9hZCAqIDMwIC8gODsKICB2YXIgd29ya2VyU2NyaXB0ID0gb3B0aW9ucy53b3JrZXJTY3JpcHQgfHwgJ2ZvcmdlL3ByaW1lLndvcmtlci5qcyc7CiAgaWYobnVtV29ya2VycyA9PT0gLTEpIHsKICAgIHJldHVybiBmb3JnZS51dGlsLmVzdGltYXRlQ29yZXMoZnVuY3Rpb24oZXJyLCBjb3JlcykgewogICAgICBpZihlcnIpIHsKICAgICAgICAvLyBkZWZhdWx0IHRvIDIKICAgICAgICBjb3JlcyA9IDI7CiAgICAgIH0KICAgICAgbnVtV29ya2VycyA9IGNvcmVzIC0gMTsKICAgICAgZ2VuZXJhdGUoKTsKICAgIH0pOwogIH0KICBnZW5lcmF0ZSgpOwoKICBmdW5jdGlvbiBnZW5lcmF0ZSgpIHsKICAgIC8vIHJlcXVpcmUgYXQgbGVhc3QgMSB3b3JrZXIKICAgIG51bVdvcmtlcnMgPSBNYXRoLm1heCgxLCBudW1Xb3JrZXJzKTsKCiAgICAvLyBUT0RPOiBjb25zaWRlciBvcHRpbWl6aW5nIGJ5IHN0YXJ0aW5nIHdvcmtlcnMgb3V0c2lkZSBnZXRQcmltZSgpIC4uLgogICAgLy8gbm90ZSB0aGF0IGluIG9yZGVyIHRvIGNsZWFuIHVwIHRoZXkgd2lsbCBoYXZlIHRvIGJlIG1hZGUgaW50ZXJuYWxseQogICAgLy8gYXN5bmNocm9ub3VzIHdoaWNoIG1heSBhY3R1YWxseSBiZSBzbG93ZXIKCiAgICAvLyBzdGFydCB3b3JrZXJzIGltbWVkaWF0ZWx5CiAgICB2YXIgd29ya2VycyA9IFtdOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG51bVdvcmtlcnM7ICsraSkgewogICAgICAvLyBGSVhNRTogZml4IHBhdGggb3IgdXNlIGJsb2IgVVJMcwogICAgICB3b3JrZXJzW2ldID0gbmV3IFdvcmtlcih3b3JrZXJTY3JpcHQpOwogICAgfQogICAgdmFyIHJ1bm5pbmcgPSBudW1Xb3JrZXJzOwoKICAgIC8vIGxpc3RlbiBmb3IgcmVxdWVzdHMgZnJvbSB3b3JrZXJzIGFuZCBhc3NpZ24gcmFuZ2VzIHRvIGZpbmQgcHJpbWUKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBudW1Xb3JrZXJzOyArK2kpIHsKICAgICAgd29ya2Vyc1tpXS5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgd29ya2VyTWVzc2FnZSk7CiAgICB9CgogICAgLyogTm90ZTogVGhlIGRpc3RyaWJ1dGlvbiBvZiByYW5kb20gbnVtYmVycyBpcyB1bmtub3duLiBUaGVyZWZvcmUsIGVhY2gKICAgIHdlYiB3b3JrZXIgaXMgY29udGludW91c2x5IGFsbG9jYXRlZCBhIHJhbmdlIG9mIG51bWJlcnMgdG8gY2hlY2sgZm9yIGEKICAgIHJhbmRvbSBudW1iZXIgdW50aWwgb25lIGlzIGZvdW5kLgoKICAgIEV2ZXJ5IDMwIG51bWJlcnMgd2lsbCBiZSBjaGVja2VkIGp1c3QgOCB0aW1lcywgYmVjYXVzZSBwcmltZSBudW1iZXJzCiAgICBoYXZlIHRoZSBmb3JtOgoKICAgIDMwaytpLCBmb3IgaSA8IDMwIGFuZCBnY2QoMzAsIGkpPTEgKHRoZXJlIGFyZSA4IHZhbHVlcyBvZiBpIGZvciB0aGlzKQoKICAgIFRoZXJlZm9yZSwgaWYgd2Ugd2FudCBhIHdlYiB3b3JrZXIgdG8gcnVuIE4gY2hlY2tzIGJlZm9yZSBhc2tpbmcgZm9yCiAgICBhIG5ldyByYW5nZSBvZiBudW1iZXJzLCBlYWNoIHJhbmdlIG11c3QgY29udGFpbiBOKjMwLzggbnVtYmVycy4KCiAgICBGb3IgMTAwIGNoZWNrcyAod29ya0xvYWQpLCB0aGlzIGlzIGEgcmFuZ2Ugb2YgMzc1LiAqLwoKICAgIHZhciBmb3VuZCA9IGZhbHNlOwogICAgZnVuY3Rpb24gd29ya2VyTWVzc2FnZShlKSB7CiAgICAgIC8vIGlnbm9yZSBtZXNzYWdlLCBwcmltZSBhbHJlYWR5IGZvdW5kCiAgICAgIGlmKGZvdW5kKSB7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICAtLXJ1bm5pbmc7CiAgICAgIHZhciBkYXRhID0gZS5kYXRhOwogICAgICBpZihkYXRhLmZvdW5kKSB7CiAgICAgICAgLy8gdGVybWluYXRlIGFsbCB3b3JrZXJzCiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHdvcmtlcnMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgIHdvcmtlcnNbaV0udGVybWluYXRlKCk7CiAgICAgICAgfQogICAgICAgIGZvdW5kID0gdHJ1ZTsKICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgbmV3IEJpZ0ludGVnZXIoZGF0YS5wcmltZSwgMTYpKTsKICAgICAgfQoKICAgICAgLy8gb3ZlcmZsb3csIHJlZ2VuZXJhdGUgcmFuZG9tIG51bWJlcgogICAgICBpZihudW0uYml0TGVuZ3RoKCkgPiBiaXRzKSB7CiAgICAgICAgbnVtID0gZ2VuZXJhdGVSYW5kb20oYml0cywgcm5nKTsKICAgICAgfQoKICAgICAgLy8gYXNzaWduIG5ldyByYW5nZSB0byBjaGVjawogICAgICB2YXIgaGV4ID0gbnVtLnRvU3RyaW5nKDE2KTsKCiAgICAgIC8vIHN0YXJ0IHByaW1lIHNlYXJjaAogICAgICBlLnRhcmdldC5wb3N0TWVzc2FnZSh7CiAgICAgICAgaGV4OiBoZXgsCiAgICAgICAgd29ya0xvYWQ6IHdvcmtMb2FkCiAgICAgIH0pOwoKICAgICAgbnVtLmRBZGRPZmZzZXQocmFuZ2UsIDApOwogICAgfQogIH0KfQoKLyoqCiAqIEdlbmVyYXRlcyBhIHJhbmRvbSBudW1iZXIgdXNpbmcgdGhlIGdpdmVuIG51bWJlciBvZiBiaXRzIGFuZCBSTkcuCiAqCiAqIEBwYXJhbSBiaXRzIHRoZSBudW1iZXIgb2YgYml0cyBmb3IgdGhlIG51bWJlci4KICogQHBhcmFtIHJuZyB0aGUgcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgdG8gdXNlLgogKgogKiBAcmV0dXJuIHRoZSByYW5kb20gbnVtYmVyLgogKi8KZnVuY3Rpb24gZ2VuZXJhdGVSYW5kb20oYml0cywgcm5nKSB7CiAgdmFyIG51bSA9IG5ldyBCaWdJbnRlZ2VyKGJpdHMsIHJuZyk7CiAgLy8gZm9yY2UgTVNCIHNldAogIHZhciBiaXRzMSA9IGJpdHMgLSAxOwogIGlmKCFudW0udGVzdEJpdChiaXRzMSkpIHsKICAgIG51bS5iaXR3aXNlVG8oQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGJpdHMxKSwgb3Bfb3IsIG51bSk7CiAgfQogIC8vIGFsaWduIG51bWJlciBvbiAzMGsrMSBib3VuZGFyeQogIG51bS5kQWRkT2Zmc2V0KDMxIC0gbnVtLm1vZChUSElSVFkpLmJ5dGVWYWx1ZSgpLCAwKTsKICByZXR1cm4gbnVtOwp9CgovKioKICogUmV0dXJucyB0aGUgcmVxdWlyZWQgbnVtYmVyIG9mIE1pbGxlci1SYWJpbiB0ZXN0cyB0byBnZW5lcmF0ZSBhCiAqIHByaW1lIHdpdGggYW4gZXJyb3IgcHJvYmFiaWxpdHkgb2YgKDEvMileODAuCiAqCiAqIFNlZSBIYW5kYm9vayBvZiBBcHBsaWVkIENyeXB0b2dyYXBoeSBDaGFwdGVyIDQsIFRhYmxlIDQuNC4KICoKICogQHBhcmFtIGJpdHMgdGhlIGJpdCBzaXplLgogKgogKiBAcmV0dXJuIHRoZSByZXF1aXJlZCBudW1iZXIgb2YgaXRlcmF0aW9ucy4KICovCmZ1bmN0aW9uIGdldE1pbGxlclJhYmluVGVzdHMoYml0cykgewogIGlmKGJpdHMgPD0gMTAwKSByZXR1cm4gMjc7CiAgaWYoYml0cyA8PSAxNTApIHJldHVybiAxODsKICBpZihiaXRzIDw9IDIwMCkgcmV0dXJuIDE1OwogIGlmKGJpdHMgPD0gMjUwKSByZXR1cm4gMTI7CiAgaWYoYml0cyA8PSAzMDApIHJldHVybiA5OwogIGlmKGJpdHMgPD0gMzUwKSByZXR1cm4gODsKICBpZihiaXRzIDw9IDQwMCkgcmV0dXJuIDc7CiAgaWYoYml0cyA8PSA1MDApIHJldHVybiA2OwogIGlmKGJpdHMgPD0gNjAwKSByZXR1cm4gNTsKICBpZihiaXRzIDw9IDgwMCkgcmV0dXJuIDQ7CiAgaWYoYml0cyA8PSAxMjUwKSByZXR1cm4gMzsKICByZXR1cm4gMjsKfQoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAncHJpbWUnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvcHJpbWUnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi91dGlsJywgJy4vanNibicsICcuL3JhbmRvbSddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKCn0pKCk7CgovKioKICogSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBiYXNpYyBSU0EgYWxnb3JpdGhtcy4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICoKICogVGhlIG9ubHkgYWxnb3JpdGhtIGN1cnJlbnRseSBzdXBwb3J0ZWQgZm9yIFBLSSBpcyBSU0EuCiAqCiAqIEFuIFJTQSBrZXkgaXMgb2Z0ZW4gc3RvcmVkIGluIEFTTi4xIERFUiBmb3JtYXQuIFRoZSBTdWJqZWN0UHVibGljS2V5SW5mbwogKiBBU04uMSBzdHJ1Y3R1cmUgaXMgY29tcG9zZWQgb2YgYW4gYWxnb3JpdGhtIG9mIHR5cGUgQWxnb3JpdGhtSWRlbnRpZmllcgogKiBhbmQgYSBzdWJqZWN0UHVibGljS2V5IG9mIHR5cGUgYml0IHN0cmluZy4KICoKICogVGhlIEFsZ29yaXRobUlkZW50aWZpZXIgY29udGFpbnMgYW4gT2JqZWN0IElkZW50aWZpZXIgKE9JRCkgYW5kIHBhcmFtZXRlcnMKICogZm9yIHRoZSBhbGdvcml0aG0sIGlmIGFueS4gSW4gdGhlIGNhc2Ugb2YgUlNBLCB0aGVyZSBhcmVuJ3QgYW55LgogKgogKiBTdWJqZWN0UHVibGljS2V5SW5mbyA6Oj0gU0VRVUVOQ0UgewogKiAgIGFsZ29yaXRobSBBbGdvcml0aG1JZGVudGlmaWVyLAogKiAgIHN1YmplY3RQdWJsaWNLZXkgQklUIFNUUklORwogKiB9CiAqCiAqIEFsZ29yaXRobUlkZW50aWZlciA6Oj0gU0VRVUVOQ0UgewogKiAgIGFsZ29yaXRobSBPQkpFQ1QgSURFTlRJRklFUiwKICogICBwYXJhbWV0ZXJzIEFOWSBERUZJTkVEIEJZIGFsZ29yaXRobSBPUFRJT05BTAogKiB9CiAqCiAqIEZvciBhbiBSU0EgcHVibGljIGtleSwgdGhlIHN1YmplY3RQdWJsaWNLZXkgaXM6CiAqCiAqIFJTQVB1YmxpY0tleSA6Oj0gU0VRVUVOQ0UgewogKiAgIG1vZHVsdXMgICAgICAgICAgICBJTlRFR0VSLCAgICAtLSBuCiAqICAgcHVibGljRXhwb25lbnQgICAgIElOVEVHRVIgICAgIC0tIGUKICogfQogKgogKiBQcml2YXRlS2V5SW5mbyA6Oj0gU0VRVUVOQ0UgewogKiAgIHZlcnNpb24gICAgICAgICAgICAgICAgICAgVmVyc2lvbiwKICogICBwcml2YXRlS2V5QWxnb3JpdGhtICAgICAgIFByaXZhdGVLZXlBbGdvcml0aG1JZGVudGlmaWVyLAogKiAgIHByaXZhdGVLZXkgICAgICAgICAgICAgICAgUHJpdmF0ZUtleSwKICogICBhdHRyaWJ1dGVzICAgICAgICAgICBbMF0gIElNUExJQ0lUIEF0dHJpYnV0ZXMgT1BUSU9OQUwKICogfQogKgogKiBWZXJzaW9uIDo6PSBJTlRFR0VSCiAqIFByaXZhdGVLZXlBbGdvcml0aG1JZGVudGlmaWVyIDo6PSBBbGdvcml0aG1JZGVudGlmaWVyCiAqIFByaXZhdGVLZXkgOjo9IE9DVEVUIFNUUklORwogKiBBdHRyaWJ1dGVzIDo6PSBTRVQgT0YgQXR0cmlidXRlCiAqCiAqIEFuIFJTQSBwcml2YXRlIGtleSBhcyB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZToKICoKICogUlNBUHJpdmF0ZUtleSA6Oj0gU0VRVUVOQ0UgewogKiAgIHZlcnNpb24gVmVyc2lvbiwKICogICBtb2R1bHVzIElOVEVHRVIsIC0tIG4KICogICBwdWJsaWNFeHBvbmVudCBJTlRFR0VSLCAtLSBlCiAqICAgcHJpdmF0ZUV4cG9uZW50IElOVEVHRVIsIC0tIGQKICogICBwcmltZTEgSU5URUdFUiwgLS0gcAogKiAgIHByaW1lMiBJTlRFR0VSLCAtLSBxCiAqICAgZXhwb25lbnQxIElOVEVHRVIsIC0tIGQgbW9kIChwLTEpCiAqICAgZXhwb25lbnQyIElOVEVHRVIsIC0tIGQgbW9kIChxLTEpCiAqICAgY29lZmZpY2llbnQgSU5URUdFUiAtLSAoaW52ZXJzZSBvZiBxKSBtb2QgcAogKiB9CiAqCiAqIFZlcnNpb24gOjo9IElOVEVHRVIKICoKICogVGhlIE9JRCBmb3IgdGhlIFJTQSBrZXkgYWxnb3JpdGhtIGlzOiAxLjIuODQwLjExMzU0OS4xLjEuMQogKi8KKGZ1bmN0aW9uKCkgewpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KCmlmKHR5cGVvZiBCaWdJbnRlZ2VyID09PSAndW5kZWZpbmVkJykgewogIHZhciBCaWdJbnRlZ2VyID0gZm9yZ2UuanNibi5CaWdJbnRlZ2VyOwp9CgovLyBzaG9ydGN1dCBmb3IgYXNuLjEgQVBJCnZhciBhc24xID0gZm9yZ2UuYXNuMTsKCi8qCiAqIFJTQSBlbmNyeXB0aW9uIGFuZCBkZWNyeXB0aW9uLCBzZWUgUkZDIDIzMTMuCiAqLwpmb3JnZS5wa2kgPSBmb3JnZS5wa2kgfHwge307CmZvcmdlLnBraS5yc2EgPSBmb3JnZS5yc2EgPSBmb3JnZS5yc2EgfHwge307CnZhciBwa2kgPSBmb3JnZS5wa2k7CgovLyBmb3IgZmluZGluZyBwcmltZXMsIHdoaWNoIGFyZSAzMGsraSBmb3IgaSA9IDEsIDcsIDExLCAxMywgMTcsIDE5LCAyMywgMjkKdmFyIEdDRF8zMF9ERUxUQSA9IFs2LCA0LCAyLCA0LCAyLCA0LCA2LCAyXTsKCi8vIHZhbGlkYXRvciBmb3IgYSBQcml2YXRlS2V5SW5mbyBzdHJ1Y3R1cmUKdmFyIHByaXZhdGVLZXlWYWxpZGF0b3IgPSB7CiAgLy8gUHJpdmF0ZUtleUluZm8KICBuYW1lOiAnUHJpdmF0ZUtleUluZm8nLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICAvLyBWZXJzaW9uIChJTlRFR0VSKQogICAgbmFtZTogJ1ByaXZhdGVLZXlJbmZvLnZlcnNpb24nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHJpdmF0ZUtleVZlcnNpb24nCiAgfSwgewogICAgLy8gcHJpdmF0ZUtleUFsZ29yaXRobQogICAgbmFtZTogJ1ByaXZhdGVLZXlJbmZvLnByaXZhdGVLZXlBbGdvcml0aG0nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICB2YWx1ZTogW3sKICAgICAgbmFtZTogJ0FsZ29yaXRobUlkZW50aWZpZXIuYWxnb3JpdGhtJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdwcml2YXRlS2V5T2lkJwogICAgfV0KICB9LCB7CiAgICAvLyBQcml2YXRlS2V5CiAgICBuYW1lOiAnUHJpdmF0ZUtleUluZm8nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ByaXZhdGVLZXknCiAgfV0KfTsKCi8vIHZhbGlkYXRvciBmb3IgYW4gUlNBIHByaXZhdGUga2V5CnZhciByc2FQcml2YXRlS2V5VmFsaWRhdG9yID0gewogIC8vIFJTQVByaXZhdGVLZXkKICBuYW1lOiAnUlNBUHJpdmF0ZUtleScsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIC8vIFZlcnNpb24gKElOVEVHRVIpCiAgICBuYW1lOiAnUlNBUHJpdmF0ZUtleS52ZXJzaW9uJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5JTlRFR0VSLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ByaXZhdGVLZXlWZXJzaW9uJwogIH0sIHsKICAgIC8vIG1vZHVsdXMgKG4pCiAgICBuYW1lOiAnUlNBUHJpdmF0ZUtleS5tb2R1bHVzJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5JTlRFR0VSLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ByaXZhdGVLZXlNb2R1bHVzJwogIH0sIHsKICAgIC8vIHB1YmxpY0V4cG9uZW50IChlKQogICAgbmFtZTogJ1JTQVByaXZhdGVLZXkucHVibGljRXhwb25lbnQnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHJpdmF0ZUtleVB1YmxpY0V4cG9uZW50JwogIH0sIHsKICAgIC8vIHByaXZhdGVFeHBvbmVudCAoZCkKICAgIG5hbWU6ICdSU0FQcml2YXRlS2V5LnByaXZhdGVFeHBvbmVudCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuSU5URUdFUiwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdwcml2YXRlS2V5UHJpdmF0ZUV4cG9uZW50JwogIH0sIHsKICAgIC8vIHByaW1lMSAocCkKICAgIG5hbWU6ICdSU0FQcml2YXRlS2V5LnByaW1lMScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuSU5URUdFUiwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdwcml2YXRlS2V5UHJpbWUxJwogIH0sIHsKICAgIC8vIHByaW1lMiAocSkKICAgIG5hbWU6ICdSU0FQcml2YXRlS2V5LnByaW1lMicsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuSU5URUdFUiwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdwcml2YXRlS2V5UHJpbWUyJwogIH0sIHsKICAgIC8vIGV4cG9uZW50MSAoZCBtb2QgKHAtMSkpCiAgICBuYW1lOiAnUlNBUHJpdmF0ZUtleS5leHBvbmVudDEnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHJpdmF0ZUtleUV4cG9uZW50MScKICB9LCB7CiAgICAvLyBleHBvbmVudDIgKGQgbW9kIChxLTEpKQogICAgbmFtZTogJ1JTQVByaXZhdGVLZXkuZXhwb25lbnQyJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5JTlRFR0VSLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ByaXZhdGVLZXlFeHBvbmVudDInCiAgfSwgewogICAgLy8gY29lZmZpY2llbnQgKChpbnZlcnNlIG9mIHEpIG1vZCBwKQogICAgbmFtZTogJ1JTQVByaXZhdGVLZXkuY29lZmZpY2llbnQnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHJpdmF0ZUtleUNvZWZmaWNpZW50JwogIH1dCn07CgovLyB2YWxpZGF0b3IgZm9yIGFuIFJTQSBwdWJsaWMga2V5CnZhciByc2FQdWJsaWNLZXlWYWxpZGF0b3IgPSB7CiAgLy8gUlNBUHVibGljS2V5CiAgbmFtZTogJ1JTQVB1YmxpY0tleScsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIC8vIG1vZHVsdXMgKG4pCiAgICBuYW1lOiAnUlNBUHVibGljS2V5Lm1vZHVsdXMnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHVibGljS2V5TW9kdWx1cycKICB9LCB7CiAgICAvLyBwdWJsaWNFeHBvbmVudCAoZSkKICAgIG5hbWU6ICdSU0FQdWJsaWNLZXkuZXhwb25lbnQnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHVibGljS2V5RXhwb25lbnQnCiAgfV0KfTsKCi8vIHZhbGlkYXRvciBmb3IgYW4gU3ViamVjdFB1YmxpY0tleUluZm8gc3RydWN0dXJlCi8vIE5vdGU6IEN1cnJlbnRseSBvbmx5IHdvcmtzIHdpdGggYW4gUlNBIHB1YmxpYyBrZXkKdmFyIHB1YmxpY0tleVZhbGlkYXRvciA9IGZvcmdlLnBraS5yc2EucHVibGljS2V5VmFsaWRhdG9yID0gewogIG5hbWU6ICdTdWJqZWN0UHVibGljS2V5SW5mbycsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICBjYXB0dXJlQXNuMTogJ3N1YmplY3RQdWJsaWNLZXlJbmZvJywKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdTdWJqZWN0UHVibGljS2V5SW5mby5BbGdvcml0aG1JZGVudGlmaWVyJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdBbGdvcml0aG1JZGVudGlmaWVyLmFsZ29yaXRobScsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLk9JRCwKICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICBjYXB0dXJlOiAncHVibGljS2V5T2lkJwogICAgfV0KICB9LCB7CiAgICAvLyBzdWJqZWN0UHVibGljS2V5CiAgICBuYW1lOiAnU3ViamVjdFB1YmxpY0tleUluZm8uc3ViamVjdFB1YmxpY0tleScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuQklUU1RSSU5HLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgdmFsdWU6IFt7CiAgICAgIC8vIFJTQVB1YmxpY0tleQogICAgICBuYW1lOiAnU3ViamVjdFB1YmxpY0tleUluZm8uc3ViamVjdFB1YmxpY0tleS5SU0FQdWJsaWNLZXknLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICBjYXB0dXJlQXNuMTogJ3JzYVB1YmxpY0tleScKICAgIH1dCiAgfV0KfTsKCi8qKgogKiBXcmFwIGRpZ2VzdCBpbiBEaWdlc3RJbmZvIG9iamVjdC4KICoKICogVGhpcyBmdW5jdGlvbiBpbXBsZW1lbnRzIEVNU0EtUEtDUzEtdjFfNS1FTkNPREUgYXMgcGVyIFJGQyAzNDQ3LgogKgogKiBEaWdlc3RJbmZvIDo6PSBTRVFVRU5DRSB7CiAqICAgZGlnZXN0QWxnb3JpdGhtIERpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXIsCiAqICAgZGlnZXN0IERpZ2VzdAogKiB9CiAqCiAqIERpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXIgOjo9IEFsZ29yaXRobUlkZW50aWZpZXIKICogRGlnZXN0IDo6PSBPQ1RFVCBTVFJJTkcKICoKICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3Qgd2l0aCB0aGUgaGFzaCB0byBzaWduLgogKgogKiBAcmV0dXJuIHRoZSBlbmNvZGVkIG1lc3NhZ2UgKHJlYWR5IGZvciBSU0EgZW5jcnl0aW9uKQogKi8KdmFyIGVtc2FQa2NzMXYxNWVuY29kZSA9IGZ1bmN0aW9uKG1kKSB7CiAgLy8gZ2V0IHRoZSBvaWQgZm9yIHRoZSBhbGdvcml0aG0KICB2YXIgb2lkOwogIGlmKG1kLmFsZ29yaXRobSBpbiBwa2kub2lkcykgewogICAgb2lkID0gcGtpLm9pZHNbbWQuYWxnb3JpdGhtXTsKICB9IGVsc2UgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdVbmtub3duIG1lc3NhZ2UgZGlnZXN0IGFsZ29yaXRobS4nKTsKICAgIGVycm9yLmFsZ29yaXRobSA9IG1kLmFsZ29yaXRobTsKICAgIHRocm93IGVycm9yOwogIH0KICB2YXIgb2lkQnl0ZXMgPSBhc24xLm9pZFRvRGVyKG9pZCkuZ2V0Qnl0ZXMoKTsKCiAgLy8gY3JlYXRlIHRoZSBkaWdlc3QgaW5mbwogIHZhciBkaWdlc3RJbmZvID0gYXNuMS5jcmVhdGUoCiAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbXSk7CiAgdmFyIGRpZ2VzdEFsZ29yaXRobSA9IGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgW10pOwogIGRpZ2VzdEFsZ29yaXRobS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLCBvaWRCeXRlcykpOwogIGRpZ2VzdEFsZ29yaXRobS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5OVUxMLCBmYWxzZSwgJycpKTsKICB2YXIgZGlnZXN0ID0gYXNuMS5jcmVhdGUoCiAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgZmFsc2UsIG1kLmRpZ2VzdCgpLmdldEJ5dGVzKCkpOwogIGRpZ2VzdEluZm8udmFsdWUucHVzaChkaWdlc3RBbGdvcml0aG0pOwogIGRpZ2VzdEluZm8udmFsdWUucHVzaChkaWdlc3QpOwoKICAvLyBlbmNvZGUgZGlnZXN0IGluZm8KICByZXR1cm4gYXNuMS50b0RlcihkaWdlc3RJbmZvKS5nZXRCeXRlcygpOwp9OwoKLyoqCiAqIFBlcmZvcm1zIHheYyBtb2QgbiAoUlNBIGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbiBvcGVyYXRpb24pLgogKgogKiBAcGFyYW0geCB0aGUgbnVtYmVyIHRvIHJhaXNlIGFuZCBtb2QuCiAqIEBwYXJhbSBrZXkgdGhlIGtleSB0byB1c2UuCiAqIEBwYXJhbSBwdWIgdHJ1ZSBpZiB0aGUga2V5IGlzIHB1YmxpYywgZmFsc2UgaWYgcHJpdmF0ZS4KICoKICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHheYyBtb2Qgbi4KICovCnZhciBfbW9kUG93ID0gZnVuY3Rpb24oeCwga2V5LCBwdWIpIHsKICBpZihwdWIpIHsKICAgIHJldHVybiB4Lm1vZFBvdyhrZXkuZSwga2V5Lm4pOwogIH0KCiAgaWYoIWtleS5wIHx8ICFrZXkucSkgewogICAgLy8gYWxsb3cgY2FsY3VsYXRpb24gd2l0aG91dCBDUlQgcGFyYW1zIChzbG93KQogICAgcmV0dXJuIHgubW9kUG93KGtleS5kLCBrZXkubik7CiAgfQoKICAvLyBwcmUtY29tcHV0ZSBkUCwgZFEsIGFuZCBxSW52IGlmIG5lY2Vzc2FyeQogIGlmKCFrZXkuZFApIHsKICAgIGtleS5kUCA9IGtleS5kLm1vZChrZXkucC5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSkpOwogIH0KICBpZigha2V5LmRRKSB7CiAgICBrZXkuZFEgPSBrZXkuZC5tb2Qoa2V5LnEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKTsKICB9CiAgaWYoIWtleS5xSW52KSB7CiAgICBrZXkucUludiA9IGtleS5xLm1vZEludmVyc2Uoa2V5LnApOwogIH0KCiAgLyogQ2hpbmVzZSByZW1haW5kZXIgdGhlb3JlbSAoQ1JUKSBzdGF0ZXM6CgogICAgU3VwcG9zZSBuMSwgbjIsIC4uLiwgbmsgYXJlIHBvc2l0aXZlIGludGVnZXJzIHdoaWNoIGFyZSBwYWlyd2lzZQogICAgY29wcmltZSAobjEgYW5kIG4yIGhhdmUgbm8gY29tbW9uIGZhY3RvcnMgb3RoZXIgdGhhbiAxKS4gRm9yIGFueQogICAgaW50ZWdlcnMgeDEsIHgyLCAuLi4sIHhrIHRoZXJlIGV4aXN0cyBhbiBpbnRlZ2VyIHggc29sdmluZyB0aGUKICAgIHN5c3RlbSBvZiBzaW11bHRhbmVvdXMgY29uZ3J1ZW5jZXMgKHdoZXJlIH49IG1lYW5zIG1vZHVsYXJseQogICAgY29uZ3J1ZW50IHNvIGEgfj0gYiBtb2QgbiBtZWFucyBhIG1vZCBuID0gYiBtb2Qgbik6CgogICAgeCB+PSB4MSBtb2QgbjEKICAgIHggfj0geDIgbW9kIG4yCiAgICAuLi4KICAgIHggfj0geGsgbW9kIG5rCgogICAgVGhpcyBzeXN0ZW0gb2YgY29uZ3J1ZW5jZXMgaGFzIGEgc2luZ2xlIHNpbXVsdGFuZW91cyBzb2x1dGlvbiB4CiAgICBiZXR3ZWVuIDAgYW5kIG4gLSAxLiBGdXJ0aGVybW9yZSwgZWFjaCB4ayBzb2x1dGlvbiBhbmQgeCBpdHNlbGYKICAgIGlzIGNvbmdydWVudCBtb2R1bG8gdGhlIHByb2R1Y3QgbiA9IG4xKm4yKi4uLipuay4KICAgIFNvIHgxIG1vZCBuID0geDIgbW9kIG4gPSB4ayBtb2QgbiA9IHggbW9kIG4uCgogICAgVGhlIHNpbmdsZSBzaW11bHRhbmVvdXMgc29sdXRpb24geCBjYW4gYmUgc29sdmVkIHdpdGggdGhlIGZvbGxvd2luZwogICAgZXF1YXRpb246CgogICAgeCA9IHN1bSh4aSpyaSpzaSkgbW9kIG4gd2hlcmUgcmkgPSBuL25pIGFuZCBzaSA9IHJpXi0xIG1vZCBuaS4KCiAgICBXaGVyZSB4IGlzIGxlc3MgdGhhbiBuLCB4aSA9IHggbW9kIG5pLgoKICAgIEZvciBSU0Egd2UgYXJlIG9ubHkgY29uY2VybmVkIHdpdGggayA9IDIuIFRoZSBtb2R1bHVzIG4gPSBwcSwgd2hlcmUKICAgIHAgYW5kIHEgYXJlIGNvcHJpbWUuIFRoZSBSU0EgZGVjcnlwdGlvbiBhbGdvcml0aG0gaXM6CgogICAgeSA9IHheZCBtb2QgbgoKICAgIEdpdmVuIHRoZSBhYm92ZToKCiAgICB4MSA9IHheZCBtb2QgcAogICAgcjEgPSBuL3AgPSBxCiAgICBzMSA9IHFeLTEgbW9kIHAKICAgIHgyID0geF5kIG1vZCBxCiAgICByMiA9IG4vcSA9IHAKICAgIHMyID0gcF4tMSBtb2QgcQoKICAgIFNvIHkgPSAoeDFyMXMxICsgeDJyMnMyKSBtb2QgbgogICAgICAgICA9ICgoeF5kIG1vZCBwKXEocV4tMSBtb2QgcCkgKyAoeF5kIG1vZCBxKXAocF4tMSBtb2QgcSkpIG1vZCBuCgogICAgQWNjb3JkaW5nIHRvIEZlcm1hdCdzIExpdHRsZSBUaGVvcmVtLCBpZiB0aGUgbW9kdWx1cyBQIGlzIHByaW1lLAogICAgZm9yIGFueSBpbnRlZ2VyIEEgbm90IGV2ZW5seSBkaXZpc2libGUgYnkgUCwgQV4oUC0xKSB+PSAxIG1vZCBQLgogICAgU2luY2UgQSBpcyBub3QgZGl2aXNpYmxlIGJ5IFAgaXQgZm9sbG93cyB0aGF0IGlmOgogICAgTiB+PSBNIG1vZCAoUCAtIDEpLCB0aGVuIEFeTiBtb2QgUCA9IEFeTSBtb2QgUC4gVGhlcmVmb3JlOgoKICAgIEFeTiBtb2QgUCA9IEFeKE0gbW9kIChQIC0gMSkpIG1vZCBQLiAoVGhlIGxhdHRlciB0YWtlcyBsZXNzIGVmZm9ydAogICAgdG8gY2FsY3VsYXRlKS4gSW4gb3JkZXIgdG8gY2FsY3VsYXRlIHheZCBtb2QgcCBtb3JlIHF1aWNrbHkgdGhlCiAgICBleHBvbmVudCBkIG1vZCAocCAtIDEpIGlzIHN0b3JlZCBpbiB0aGUgUlNBIHByaXZhdGUga2V5ICh0aGUgc2FtZQogICAgaXMgZG9uZSBmb3IgeF5kIG1vZCBxKS4gVGhlc2UgdmFsdWVzIGFyZSByZWZlcnJlZCB0byBhcyBkUCBhbmQgZFEKICAgIHJlc3BlY3RpdmVseS4gVGhlcmVmb3JlIHdlIG5vdyBoYXZlOgoKICAgIHkgPSAoKHheZFAgbW9kIHApcShxXi0xIG1vZCBwKSArICh4XmRRIG1vZCBxKXAocF4tMSBtb2QgcSkpIG1vZCBuCgogICAgU2luY2Ugd2UnbGwgYmUgcmVkdWNpbmcgeF5kUCBieSBtb2R1bG8gcCAoc2FtZSBmb3IgcSkgd2UgY2FuIGFsc28KICAgIHJlZHVjZSB4IGJ5IHAgKGFuZCBxIHJlc3BlY3RpdmVseSkgYmVmb3JlIGhhbmQuIFRoZXJlZm9yZSwgbGV0CgogICAgeHAgPSAoKHggbW9kIHApXmRQIG1vZCBwKSwgYW5kCiAgICB4cSA9ICgoeCBtb2QgcSleZFEgbW9kIHEpLCB5aWVsZGluZzoKCiAgICB5ID0gKHhwKnEqKHFeLTEgbW9kIHApICsgeHEqcCoocF4tMSBtb2QgcSkpIG1vZCBuCgogICAgVGhpcyBjYW4gYmUgZnVydGhlciByZWR1Y2VkIHRvIGEgc2ltcGxlIGFsZ29yaXRobSB0aGF0IG9ubHkKICAgIHJlcXVpcmVzIDEgaW52ZXJzZSAodGhlIHEgaW52ZXJzZSBpcyB1c2VkKSB0byBiZSB1c2VkIGFuZCBzdG9yZWQuCiAgICBUaGUgYWxnb3JpdGhtIGlzIGNhbGxlZCBHYXJuZXIncyBhbGdvcml0aG0uIElmIHFJbnYgaXMgdGhlCiAgICBpbnZlcnNlIG9mIHEsIHdlIHNpbXBseSBjYWxjdWxhdGU6CgogICAgeSA9IChxSW52Kih4cCAtIHhxKSBtb2QgcCkgKiBxICsgeHEKCiAgICBIb3dldmVyLCB0aGVyZSBhcmUgdHdvIGZ1cnRoZXIgY29tcGxpY2F0aW9ucy4gRmlyc3QsIHdlIG5lZWQgdG8KICAgIGVuc3VyZSB0aGF0IHhwID4geHEgdG8gcHJldmVudCBzaWduZWQgQmlnSW50ZWdlcnMgZnJvbSBiZWluZyB1c2VkCiAgICBzbyB3ZSBhZGQgcCB1bnRpbCB0aGlzIGlzIHRydWUgKHNpbmNlIHdlIHdpbGwgYmUgbW9kJ2luZyB3aXRoCiAgICBwIGFueXdheSkuIFRoZW4sIHRoZXJlIGlzIGEga25vd24gdGltaW5nIGF0dGFjayBvbiBhbGdvcml0aG1zCiAgICB1c2luZyB0aGUgQ1JULiBUbyBtaXRpZ2F0ZSB0aGlzIHJpc2ssICJjcnlwdG9ncmFwaGljIGJsaW5kaW5nIgogICAgc2hvdWxkIGJlIHVzZWQuIFRoaXMgcmVxdWlyZXMgc2ltcGx5IGdlbmVyYXRpbmcgYSByYW5kb20gbnVtYmVyIHIKICAgIGJldHdlZW4gMCBhbmQgbi0xIGFuZCBpdHMgaW52ZXJzZSBhbmQgbXVsdGlwbHlpbmcgeCBieSByXmUgYmVmb3JlCiAgICBjYWxjdWxhdGluZyB5IGFuZCB0aGVuIG11bHRpcGx5aW5nIHkgYnkgcl4tMSBhZnRlcndhcmRzLiBOb3RlIHRoYXQKICAgIHIgbXVzdCBiZSBjb3ByaW1lIHdpdGggbiAoZ2NkKHIsIG4pID09PSAxKSBpbiBvcmRlciB0byBoYXZlIGFuCiAgICBpbnZlcnNlLgogICovCgogIC8vIGNyeXB0b2dyYXBoaWMgYmxpbmRpbmcKICB2YXIgcjsKICBkbyB7CiAgICByID0gbmV3IEJpZ0ludGVnZXIoCiAgICAgIGZvcmdlLnV0aWwuYnl0ZXNUb0hleChmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMoa2V5Lm4uYml0TGVuZ3RoKCkgLyA4KSksCiAgICAgIDE2KTsKICB9IHdoaWxlKHIuY29tcGFyZVRvKGtleS5uKSA+PSAwIHx8ICFyLmdjZChrZXkubikuZXF1YWxzKEJpZ0ludGVnZXIuT05FKSk7CiAgeCA9IHgubXVsdGlwbHkoci5tb2RQb3coa2V5LmUsIGtleS5uKSkubW9kKGtleS5uKTsKCiAgLy8gY2FsY3VsYXRlIHhwIGFuZCB4cQogIHZhciB4cCA9IHgubW9kKGtleS5wKS5tb2RQb3coa2V5LmRQLCBrZXkucCk7CiAgdmFyIHhxID0geC5tb2Qoa2V5LnEpLm1vZFBvdyhrZXkuZFEsIGtleS5xKTsKCiAgLy8geHAgbXVzdCBiZSBsYXJnZXIgdGhhbiB4cSB0byBhdm9pZCBzaWduZWQgYml0IHVzYWdlCiAgd2hpbGUoeHAuY29tcGFyZVRvKHhxKSA8IDApIHsKICAgIHhwID0geHAuYWRkKGtleS5wKTsKICB9CgogIC8vIGRvIGxhc3Qgc3RlcAogIHZhciB5ID0geHAuc3VidHJhY3QoeHEpCiAgICAubXVsdGlwbHkoa2V5LnFJbnYpLm1vZChrZXkucCkKICAgIC5tdWx0aXBseShrZXkucSkuYWRkKHhxKTsKCiAgLy8gcmVtb3ZlIGVmZmVjdCBvZiByYW5kb20gZm9yIGNyeXB0b2dyYXBoaWMgYmxpbmRpbmcKICB5ID0geS5tdWx0aXBseShyLm1vZEludmVyc2Uoa2V5Lm4pKS5tb2Qoa2V5Lm4pOwoKICByZXR1cm4geTsKfTsKCi8qKgogKiBOT1RFOiBUSElTIE1FVEhPRCBJUyBERVBSRUNBVEVELCB1c2UgJ3NpZ24nIG9uIGEgcHJpdmF0ZSBrZXkgb2JqZWN0IG9yCiAqICdlbmNyeXB0JyBvbiBhIHB1YmxpYyBrZXkgb2JqZWN0IGluc3RlYWQuCiAqCiAqIFBlcmZvcm1zIFJTQSBlbmNyeXB0aW9uLgogKgogKiBUaGUgcGFyYW1ldGVyIGJ0IGNvbnRyb2xzIHdoZXRoZXIgdG8gcHV0IHBhZGRpbmcgYnl0ZXMgYmVmb3JlIHRoZQogKiBtZXNzYWdlIHBhc3NlZCBpbi4gU2V0IGJ0IHRvIGVpdGhlciB0cnVlIG9yIGZhbHNlIHRvIGRpc2FibGUgcGFkZGluZwogKiBjb21wbGV0ZWx5IChpbiBvcmRlciB0byBoYW5kbGUgZS5nLiBFTVNBLVBTUyBlbmNvZGluZyBzZXBlcmF0ZWx5IGJlZm9yZSksCiAqIHNpZ25hbGluZyB3aGV0aGVyIHRoZSBlbmNyeXB0aW9uIG9wZXJhdGlvbiBpcyBhIHB1YmxpYyBrZXkgb3BlcmF0aW9uCiAqIChpLmUuIGVuY3J5cHRpbmcgZGF0YSkgb3Igbm90LCBpLmUuIHByaXZhdGUga2V5IG9wZXJhdGlvbiAoZGF0YSBzaWduaW5nKS4KICoKICogRm9yIFBLQ1MjMSB2MS41IHBhZGRpbmcgcGFzcyBpbiB0aGUgYmxvY2sgdHlwZSB0byB1c2UsIGkuZS4gZWl0aGVyIDB4MDEKICogKGZvciBzaWduaW5nKSBvciAweDAyIChmb3IgZW5jcnlwdGlvbikuIFRoZSBrZXkgb3BlcmF0aW9uIG1vZGUgKHByaXZhdGUKICogb3IgcHVibGljKSBpcyBkZXJpdmVkIGZyb20gdGhpcyBmbGFnIGluIHRoYXQgY2FzZSkuCiAqCiAqIEBwYXJhbSBtIHRoZSBtZXNzYWdlIHRvIGVuY3J5cHQgYXMgYSBieXRlIHN0cmluZy4KICogQHBhcmFtIGtleSB0aGUgUlNBIGtleSB0byB1c2UuCiAqIEBwYXJhbSBidCBmb3IgUEtDUyMxIHYxLjUgcGFkZGluZywgdGhlIGJsb2NrIHR5cGUgdG8gdXNlCiAqICAgKDB4MDEgZm9yIHByaXZhdGUga2V5LCAweDAyIGZvciBwdWJsaWMpLAogKiAgIHRvIGRpc2FibGUgcGFkZGluZzogdHJ1ZSA9IHB1YmxpYyBrZXksIGZhbHNlID0gcHJpdmF0ZSBrZXkuCiAqCiAqIEByZXR1cm4gdGhlIGVuY3J5cHRlZCBieXRlcyBhcyBhIHN0cmluZy4KICovCnBraS5yc2EuZW5jcnlwdCA9IGZ1bmN0aW9uKG0sIGtleSwgYnQpIHsKICB2YXIgcHViID0gYnQ7CiAgdmFyIGViOwoKICAvLyBnZXQgdGhlIGxlbmd0aCBvZiB0aGUgbW9kdWx1cyBpbiBieXRlcwogIHZhciBrID0gTWF0aC5jZWlsKGtleS5uLmJpdExlbmd0aCgpIC8gOCk7CgogIGlmKGJ0ICE9PSBmYWxzZSAmJiBidCAhPT0gdHJ1ZSkgewogICAgLy8gbGVnYWN5LCBkZWZhdWx0IHRvIFBLQ1MjMSB2MS41IHBhZGRpbmcKICAgIHB1YiA9IChidCA9PT0gMHgwMik7CiAgICBlYiA9IF9lbmNvZGVQa2NzMV92MV81KG0sIGtleSwgYnQpOwogIH0gZWxzZSB7CiAgICBlYiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBlYi5wdXRCeXRlcyhtKTsKICB9CgogIC8vIGxvYWQgZW5jcnlwdGlvbiBibG9jayBhcyBiaWcgaW50ZWdlciAneCcKICAvLyBGSVhNRTogaGV4IGNvbnZlcnNpb24gaW5lZmZpY2llbnQsIGdldCBCaWdJbnRlZ2VyIHcvYnl0ZSBzdHJpbmdzCiAgdmFyIHggPSBuZXcgQmlnSW50ZWdlcihlYi50b0hleCgpLCAxNik7CgogIC8vIGRvIFJTQSBlbmNyeXB0aW9uCiAgdmFyIHkgPSBfbW9kUG93KHgsIGtleSwgcHViKTsKCiAgLy8gY29udmVydCB5IGludG8gdGhlIGVuY3J5cHRlZCBkYXRhIGJ5dGUgc3RyaW5nLCBpZiB5IGlzIHNob3J0ZXIgaW4KICAvLyBieXRlcyB0aGFuIGssIHRoZW4gcHJlcGVuZCB6ZXJvIGJ5dGVzIHRvIGZpbGwgdXAgZWQKICAvLyBGSVhNRTogaGV4IGNvbnZlcnNpb24gaW5lZmZpY2llbnQsIGdldCBCaWdJbnRlZ2VyIHcvYnl0ZSBzdHJpbmdzCiAgdmFyIHloZXggPSB5LnRvU3RyaW5nKDE2KTsKICB2YXIgZWQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHZhciB6ZXJvcyA9IGsgLSBNYXRoLmNlaWwoeWhleC5sZW5ndGggLyAyKTsKICB3aGlsZSh6ZXJvcyA+IDApIHsKICAgIGVkLnB1dEJ5dGUoMHgwMCk7CiAgICAtLXplcm9zOwogIH0KICBlZC5wdXRCeXRlcyhmb3JnZS51dGlsLmhleFRvQnl0ZXMoeWhleCkpOwogIHJldHVybiBlZC5nZXRCeXRlcygpOwp9OwoKLyoqCiAqIE5PVEU6IFRISVMgTUVUSE9EIElTIERFUFJFQ0FURUQsIHVzZSAnZGVjcnlwdCcgb24gYSBwcml2YXRlIGtleSBvYmplY3Qgb3IKICogJ3ZlcmlmeScgb24gYSBwdWJsaWMga2V5IG9iamVjdCBpbnN0ZWFkLgogKgogKiBQZXJmb3JtcyBSU0EgZGVjcnlwdGlvbi4KICoKICogVGhlIHBhcmFtZXRlciBtbCBjb250cm9scyB3aGV0aGVyIHRvIGFwcGx5IFBLQ1MjMSB2MS41IHBhZGRpbmcKICogb3Igbm90LiAgU2V0IG1sID0gZmFsc2UgdG8gZGlzYWJsZSBwYWRkaW5nIHJlbW92YWwgY29tcGxldGVseQogKiAoaW4gb3JkZXIgdG8gaGFuZGxlIGUuZy4gRU1TQS1QU1MgbGF0ZXIgb24pIGFuZCBzaW1wbHkgcGFzcyBiYWNrCiAqIHRoZSBSU0EgZW5jcnlwdGlvbiBibG9jay4KICoKICogQHBhcmFtIGVkIHRoZSBlbmNyeXB0ZWQgZGF0YSB0byBkZWNyeXB0IGluIGFzIGEgYnl0ZSBzdHJpbmcuCiAqIEBwYXJhbSBrZXkgdGhlIFJTQSBrZXkgdG8gdXNlLgogKiBAcGFyYW0gcHViIHRydWUgZm9yIGEgcHVibGljIGtleSBvcGVyYXRpb24sIGZhbHNlIGZvciBwcml2YXRlLgogKiBAcGFyYW0gbWwgdGhlIG1lc3NhZ2UgbGVuZ3RoLCBpZiBrbm93biwgZmFsc2UgdG8gZGlzYWJsZSBwYWRkaW5nLgogKgogKiBAcmV0dXJuIHRoZSBkZWNyeXB0ZWQgbWVzc2FnZSBhcyBhIGJ5dGUgc3RyaW5nLgogKi8KcGtpLnJzYS5kZWNyeXB0ID0gZnVuY3Rpb24oZWQsIGtleSwgcHViLCBtbCkgewogIC8vIGdldCB0aGUgbGVuZ3RoIG9mIHRoZSBtb2R1bHVzIGluIGJ5dGVzCiAgdmFyIGsgPSBNYXRoLmNlaWwoa2V5Lm4uYml0TGVuZ3RoKCkgLyA4KTsKCiAgLy8gZXJyb3IgaWYgdGhlIGxlbmd0aCBvZiB0aGUgZW5jcnlwdGVkIGRhdGEgRUQgaXMgbm90IGsKICBpZihlZC5sZW5ndGggIT09IGspIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignRW5jcnlwdGVkIG1lc3NhZ2UgbGVuZ3RoIGlzIGludmFsaWQuJyk7CiAgICBlcnJvci5sZW5ndGggPSBlZC5sZW5ndGg7CiAgICBlcnJvci5leHBlY3RlZCA9IGs7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIC8vIGNvbnZlcnQgZW5jcnlwdGVkIGRhdGEgaW50byBhIGJpZyBpbnRlZ2VyCiAgLy8gRklYTUU6IGhleCBjb252ZXJzaW9uIGluZWZmaWNpZW50LCBnZXQgQmlnSW50ZWdlciB3L2J5dGUgc3RyaW5ncwogIHZhciB5ID0gbmV3IEJpZ0ludGVnZXIoZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoZWQpLnRvSGV4KCksIDE2KTsKCiAgLy8geSBtdXN0IGJlIGxlc3MgdGhhbiB0aGUgbW9kdWx1cyBvciBpdCB3YXNuJ3QgdGhlIHJlc3VsdCBvZgogIC8vIGEgcHJldmlvdXMgbW9kIG9wZXJhdGlvbiAoZW5jcnlwdGlvbikgdXNpbmcgdGhhdCBtb2R1bHVzCiAgaWYoeS5jb21wYXJlVG8oa2V5Lm4pID49IDApIHsKICAgIHRocm93IG5ldyBFcnJvcignRW5jcnlwdGVkIG1lc3NhZ2UgaXMgaW52YWxpZC4nKTsKICB9CgogIC8vIGRvIFJTQSBkZWNyeXB0aW9uCiAgdmFyIHggPSBfbW9kUG93KHksIGtleSwgcHViKTsKCiAgLy8gY3JlYXRlIHRoZSBlbmNyeXB0aW9uIGJsb2NrLCBpZiB4IGlzIHNob3J0ZXIgaW4gYnl0ZXMgdGhhbiBrLCB0aGVuCiAgLy8gcHJlcGVuZCB6ZXJvIGJ5dGVzIHRvIGZpbGwgdXAgZWIKICAvLyBGSVhNRTogaGV4IGNvbnZlcnNpb24gaW5lZmZpY2llbnQsIGdldCBCaWdJbnRlZ2VyIHcvYnl0ZSBzdHJpbmdzCiAgdmFyIHhoZXggPSB4LnRvU3RyaW5nKDE2KTsKICB2YXIgZWIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHZhciB6ZXJvcyA9IGsgLSBNYXRoLmNlaWwoeGhleC5sZW5ndGggLyAyKTsKICB3aGlsZSh6ZXJvcyA+IDApIHsKICAgIGViLnB1dEJ5dGUoMHgwMCk7CiAgICAtLXplcm9zOwogIH0KICBlYi5wdXRCeXRlcyhmb3JnZS51dGlsLmhleFRvQnl0ZXMoeGhleCkpOwoKICBpZihtbCAhPT0gZmFsc2UpIHsKICAgIC8vIGxlZ2FjeSwgZGVmYXVsdCB0byBQS0NTIzEgdjEuNSBwYWRkaW5nCiAgICByZXR1cm4gX2RlY29kZVBrY3MxX3YxXzUoZWIuZ2V0Qnl0ZXMoKSwga2V5LCBwdWIpOwogIH0KCiAgLy8gcmV0dXJuIG1lc3NhZ2UKICByZXR1cm4gZWIuZ2V0Qnl0ZXMoKTsKfTsKCi8qKgogKiBDcmVhdGVzIGFuIFJTQSBrZXktcGFpciBnZW5lcmF0aW9uIHN0YXRlIG9iamVjdC4gSXQgaXMgdXNlZCB0byBhbGxvdwogKiBrZXktZ2VuZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQgaW4gc3RlcHMuIEl0IGFsc28gYWxsb3dzIGZvciBhIFVJIHRvCiAqIGRpc3BsYXkgcHJvZ3Jlc3MgdXBkYXRlcy4KICoKICogQHBhcmFtIGJpdHMgdGhlIHNpemUgZm9yIHRoZSBwcml2YXRlIGtleSBpbiBiaXRzLCBkZWZhdWx0cyB0byAyMDQ4LgogKiBAcGFyYW0gZSB0aGUgcHVibGljIGV4cG9uZW50IHRvIHVzZSwgZGVmYXVsdHMgdG8gNjU1MzcgKDB4MTAwMDEpLgogKiBAcGFyYW0gW29wdGlvbnNdIHRoZSBvcHRpb25zIHRvIHVzZS4KICogICAgICAgICAgcHJuZyBhIGN1c3RvbSBjcnlwdG8tc2VjdXJlIHBzZXVkby1yYW5kb20gbnVtYmVyIGdlbmVyYXRvciB0byB1c2UsCiAqICAgICAgICAgICAgdGhhdCBtdXN0IGRlZmluZSAiZ2V0Qnl0ZXNTeW5jIi4KICogICAgICAgICAgYWxnb3JpdGhtIHRoZSBhbGdvcml0aG0gdG8gdXNlIChkZWZhdWx0OiAnUFJJTUVJTkMnKS4KICoKICogQHJldHVybiB0aGUgc3RhdGUgb2JqZWN0IHRvIHVzZSB0byBnZW5lcmF0ZSB0aGUga2V5LXBhaXIuCiAqLwpwa2kucnNhLmNyZWF0ZUtleVBhaXJHZW5lcmF0aW9uU3RhdGUgPSBmdW5jdGlvbihiaXRzLCBlLCBvcHRpb25zKSB7CiAgLy8gVE9ETzogbWlncmF0ZSBzdGVwLWJhc2VkIHByaW1lIGdlbmVyYXRpb24gY29kZSB0byBmb3JnZS5wcmltZQoKICAvLyBzZXQgZGVmYXVsdCBiaXRzCiAgaWYodHlwZW9mKGJpdHMpID09PSAnc3RyaW5nJykgewogICAgYml0cyA9IHBhcnNlSW50KGJpdHMsIDEwKTsKICB9CiAgYml0cyA9IGJpdHMgfHwgMjA0ODsKCiAgLy8gY3JlYXRlIHBybmcgd2l0aCBhcGkgdGhhdCBtYXRjaGVzIEJpZ0ludGVnZXIgc2VjdXJlIHJhbmRvbQogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIHZhciBwcm5nID0gb3B0aW9ucy5wcm5nIHx8IGZvcmdlLnJhbmRvbTsKICB2YXIgcm5nID0gewogICAgLy8geCBpcyBhbiBhcnJheSB0byBmaWxsIHdpdGggYnl0ZXMKICAgIG5leHRCeXRlczogZnVuY3Rpb24oeCkgewogICAgICB2YXIgYiA9IHBybmcuZ2V0Qnl0ZXNTeW5jKHgubGVuZ3RoKTsKICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyArK2kpIHsKICAgICAgICB4W2ldID0gYi5jaGFyQ29kZUF0KGkpOwogICAgICB9CiAgICB9CiAgfTsKCiAgdmFyIGFsZ29yaXRobSA9IG9wdGlvbnMuYWxnb3JpdGhtIHx8ICdQUklNRUlOQyc7CgogIC8vIGNyZWF0ZSBQUklNRUlOQyBhbGdvcml0aG0gc3RhdGUKICB2YXIgcnZhbDsKICBpZihhbGdvcml0aG0gPT09ICdQUklNRUlOQycpIHsKICAgIHJ2YWwgPSB7CiAgICAgIGFsZ29yaXRobTogYWxnb3JpdGhtLAogICAgICBzdGF0ZTogMCwKICAgICAgYml0czogYml0cywKICAgICAgcm5nOiBybmcsCiAgICAgIGVJbnQ6IGUgfHwgNjU1MzcsCiAgICAgIGU6IG5ldyBCaWdJbnRlZ2VyKG51bGwpLAogICAgICBwOiBudWxsLAogICAgICBxOiBudWxsLAogICAgICBxQml0czogYml0cyA+PiAxLAogICAgICBwQml0czogYml0cyAtIChiaXRzID4+IDEpLAogICAgICBwcVN0YXRlOiAwLAogICAgICBudW06IG51bGwsCiAgICAgIGtleXM6IG51bGwKICAgIH07CiAgICBydmFsLmUuZnJvbUludChydmFsLmVJbnQpOwogIH0gZWxzZSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQga2V5IGdlbmVyYXRpb24gYWxnb3JpdGhtOiAnICsgYWxnb3JpdGhtKTsKICB9CgogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIEF0dGVtcHRzIHRvIHJ1bnMgdGhlIGtleS1nZW5lcmF0aW9uIGFsZ29yaXRobSBmb3IgYXQgbW9zdCBuIHNlY29uZHMKICogKGFwcHJveGltYXRlbHkpIHVzaW5nIHRoZSBnaXZlbiBzdGF0ZS4gV2hlbiBrZXktZ2VuZXJhdGlvbiBoYXMgY29tcGxldGVkLAogKiB0aGUga2V5cyB3aWxsIGJlIHN0b3JlZCBpbiBzdGF0ZS5rZXlzLgogKgogKiBUbyB1c2UgdGhpcyBmdW5jdGlvbiB0byB1cGRhdGUgYSBVSSB3aGlsZSBnZW5lcmF0aW5nIGEga2V5IG9yIHRvIHByZXZlbnQKICogY2F1c2luZyBicm93c2VyIGxvY2t1cHMvd2FybmluZ3MsIHNldCAibiIgdG8gYSB2YWx1ZSBvdGhlciB0aGFuIDAuIEEKICogc2ltcGxlIHBhdHRlcm4gZm9yIGdlbmVyYXRpbmcgYSBrZXkgYW5kIHNob3dpbmcgYSBwcm9ncmVzcyBpbmRpY2F0b3IgaXM6CiAqCiAqIHZhciBzdGF0ZSA9IHBraS5yc2EuY3JlYXRlS2V5UGFpckdlbmVyYXRpb25TdGF0ZSgyMDQ4KTsKICogdmFyIHN0ZXAgPSBmdW5jdGlvbigpIHsKICogICAvLyBzdGVwIGtleS1nZW5lcmF0aW9uLCBydW4gYWxnb3JpdGhtIGZvciAxMDAgbXMsIHJlcGVhdAogKiAgIGlmKCFmb3JnZS5wa2kucnNhLnN0ZXBLZXlQYWlyR2VuZXJhdGlvblN0YXRlKHN0YXRlLCAxMDApKSB7CiAqICAgICBzZXRUaW1lb3V0KHN0ZXAsIDEpOwogKiAgIH0gZWxzZSB7CiAqICAgICAvLyBrZXktZ2VuZXJhdGlvbiBjb21wbGV0ZQogKiAgICAgLy8gVE9ETzogdHVybiBvZmYgcHJvZ3Jlc3MgaW5kaWNhdG9yIGhlcmUKICogICAgIC8vIFRPRE86IHVzZSB0aGUgZ2VuZXJhdGVkIGtleS1wYWlyIGluICJzdGF0ZS5rZXlzIgogKiAgIH0KICogfTsKICogLy8gVE9ETzogdHVybiBvbiBwcm9ncmVzcyBpbmRpY2F0b3IgaGVyZQogKiBzZXRUaW1lb3V0KHN0ZXAsIDApOwogKgogKiBAcGFyYW0gc3RhdGUgdGhlIHN0YXRlIHRvIHVzZS4KICogQHBhcmFtIG4gdGhlIG1heGltdW0gbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBydW4gdGhlIGFsZ29yaXRobSBmb3IsIDAKICogICAgICAgICAgdG8gcnVuIHRoZSBhbGdvcml0aG0gdG8gY29tcGxldGlvbi4KICoKICogQHJldHVybiB0cnVlIGlmIHRoZSBrZXktZ2VuZXJhdGlvbiBjb21wbGV0ZWQsIGZhbHNlIGlmIG5vdC4KICovCnBraS5yc2Euc3RlcEtleVBhaXJHZW5lcmF0aW9uU3RhdGUgPSBmdW5jdGlvbihzdGF0ZSwgbikgewogIC8vIHNldCBkZWZhdWx0IGFsZ29yaXRobSBpZiBub3Qgc2V0CiAgaWYoISgnYWxnb3JpdGhtJyBpbiBzdGF0ZSkpIHsKICAgIHN0YXRlLmFsZ29yaXRobSA9ICdQUklNRUlOQyc7CiAgfQoKICAvLyBUT0RPOiBtaWdyYXRlIHN0ZXAtYmFzZWQgcHJpbWUgZ2VuZXJhdGlvbiBjb2RlIHRvIGZvcmdlLnByaW1lCiAgLy8gVE9ETzogYWJzdHJhY3QgYXMgUFJJTUVJTkMgYWxnb3JpdGhtCgogIC8vIGRvIGtleSBnZW5lcmF0aW9uIChiYXNlZCBvbiBUb20gV3UncyByc2EuanMsIHNlZSBqc2JuLmpzIGxpY2Vuc2UpCiAgLy8gd2l0aCBzb21lIG1pbm9yIG9wdGltaXphdGlvbnMgYW5kIGRlc2lnbmVkIHRvIHJ1biBpbiBzdGVwcwoKICAvLyBsb2NhbCBzdGF0ZSB2YXJzCiAgdmFyIFRISVJUWSA9IG5ldyBCaWdJbnRlZ2VyKG51bGwpOwogIFRISVJUWS5mcm9tSW50KDMwKTsKICB2YXIgZGVsdGFJZHggPSAwOwogIHZhciBvcF9vciA9IGZ1bmN0aW9uKHgseSkgeyByZXR1cm4geHx5OyB9OwoKICAvLyBrZWVwIHN0ZXBwaW5nIHVudGlsIHRpbWUgbGltaXQgaXMgcmVhY2hlZCBvciBkb25lCiAgdmFyIHQxID0gK25ldyBEYXRlKCk7CiAgdmFyIHQyOwogIHZhciB0b3RhbCA9IDA7CiAgd2hpbGUoc3RhdGUua2V5cyA9PT0gbnVsbCAmJiAobiA8PSAwIHx8IHRvdGFsIDwgbikpIHsKICAgIC8vIGdlbmVyYXRlIHAgb3IgcQogICAgaWYoc3RhdGUuc3RhdGUgPT09IDApIHsKICAgICAgLyogTm90ZTogQWxsIHByaW1lcyBhcmUgb2YgdGhlIGZvcm06CgogICAgICAgIDMwaytpLCBmb3IgaSA8IDMwIGFuZCBnY2QoMzAsIGkpPTEsIHdoZXJlIHRoZXJlIGFyZSA4IHZhbHVlcyBmb3IgaQoKICAgICAgICBXaGVuIHdlIGdlbmVyYXRlIGEgcmFuZG9tIG51bWJlciwgd2UgYWx3YXlzIGFsaWduIGl0IGF0IDMwayArIDEuIEVhY2gKICAgICAgICB0aW1lIHRoZSBudW1iZXIgaXMgZGV0ZXJtaW5lZCBub3QgdG8gYmUgcHJpbWUgd2UgYWRkIHRvIGdldCB0byB0aGUKICAgICAgICBuZXh0ICdpJywgZWc6IGlmIHRoZSBudW1iZXIgd2FzIGF0IDMwayArIDEgd2UgYWRkIDYuICovCiAgICAgIHZhciBiaXRzID0gKHN0YXRlLnAgPT09IG51bGwpID8gc3RhdGUucEJpdHMgOiBzdGF0ZS5xQml0czsKICAgICAgdmFyIGJpdHMxID0gYml0cyAtIDE7CgogICAgICAvLyBnZXQgYSByYW5kb20gbnVtYmVyCiAgICAgIGlmKHN0YXRlLnBxU3RhdGUgPT09IDApIHsKICAgICAgICBzdGF0ZS5udW0gPSBuZXcgQmlnSW50ZWdlcihiaXRzLCBzdGF0ZS5ybmcpOwogICAgICAgIC8vIGZvcmNlIE1TQiBzZXQKICAgICAgICBpZighc3RhdGUubnVtLnRlc3RCaXQoYml0czEpKSB7CiAgICAgICAgICBzdGF0ZS5udW0uYml0d2lzZVRvKAogICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQoYml0czEpLCBvcF9vciwgc3RhdGUubnVtKTsKICAgICAgICB9CiAgICAgICAgLy8gYWxpZ24gbnVtYmVyIG9uIDMwaysxIGJvdW5kYXJ5CiAgICAgICAgc3RhdGUubnVtLmRBZGRPZmZzZXQoMzEgLSBzdGF0ZS5udW0ubW9kKFRISVJUWSkuYnl0ZVZhbHVlKCksIDApOwogICAgICAgIGRlbHRhSWR4ID0gMDsKCiAgICAgICAgKytzdGF0ZS5wcVN0YXRlOwogICAgICB9IGVsc2UgaWYoc3RhdGUucHFTdGF0ZSA9PT0gMSkgewogICAgICAgIC8vIHRyeSB0byBtYWtlIHRoZSBudW1iZXIgYSBwcmltZQogICAgICAgIGlmKHN0YXRlLm51bS5iaXRMZW5ndGgoKSA+IGJpdHMpIHsKICAgICAgICAgIC8vIG92ZXJmbG93LCB0cnkgYWdhaW4KICAgICAgICAgIHN0YXRlLnBxU3RhdGUgPSAwOwogICAgICAgICAgLy8gZG8gcHJpbWFsaXR5IHRlc3QKICAgICAgICB9IGVsc2UgaWYoc3RhdGUubnVtLmlzUHJvYmFibGVQcmltZSgKICAgICAgICAgIF9nZXRNaWxsZXJSYWJpblRlc3RzKHN0YXRlLm51bS5iaXRMZW5ndGgoKSkpKSB7CiAgICAgICAgICArK3N0YXRlLnBxU3RhdGU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8vIGdldCBuZXh0IHBvdGVudGlhbCBwcmltZQogICAgICAgICAgc3RhdGUubnVtLmRBZGRPZmZzZXQoR0NEXzMwX0RFTFRBW2RlbHRhSWR4KysgJSA4XSwgMCk7CiAgICAgICAgfQogICAgICB9IGVsc2UgaWYoc3RhdGUucHFTdGF0ZSA9PT0gMikgewogICAgICAgIC8vIGVuc3VyZSBudW1iZXIgaXMgY29wcmltZSB3aXRoIGUKICAgICAgICBzdGF0ZS5wcVN0YXRlID0KICAgICAgICAgIChzdGF0ZS5udW0uc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpLmdjZChzdGF0ZS5lKQogICAgICAgICAgLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT09IDApID8gMyA6IDA7CiAgICAgIH0gZWxzZSBpZihzdGF0ZS5wcVN0YXRlID09PSAzKSB7CiAgICAgICAgLy8gc3RvcmUgcCBvciBxCiAgICAgICAgc3RhdGUucHFTdGF0ZSA9IDA7CiAgICAgICAgaWYoc3RhdGUucCA9PT0gbnVsbCkgewogICAgICAgICAgc3RhdGUucCA9IHN0YXRlLm51bTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3RhdGUucSA9IHN0YXRlLm51bTsKICAgICAgICB9CgogICAgICAgIC8vIGFkdmFuY2Ugc3RhdGUgaWYgYm90aCBwIGFuZCBxIGFyZSByZWFkeQogICAgICAgIGlmKHN0YXRlLnAgIT09IG51bGwgJiYgc3RhdGUucSAhPT0gbnVsbCkgewogICAgICAgICAgKytzdGF0ZS5zdGF0ZTsKICAgICAgICB9CiAgICAgICAgc3RhdGUubnVtID0gbnVsbDsKICAgICAgfQogICAgfSBlbHNlIGlmKHN0YXRlLnN0YXRlID09PSAxKSB7CiAgICAgIC8vIGVuc3VyZSBwIGlzIGxhcmdlciB0aGFuIHEgKHN3YXAgdGhlbSBpZiBub3QpCiAgICAgIGlmKHN0YXRlLnAuY29tcGFyZVRvKHN0YXRlLnEpIDwgMCkgewogICAgICAgIHN0YXRlLm51bSA9IHN0YXRlLnA7CiAgICAgICAgc3RhdGUucCA9IHN0YXRlLnE7CiAgICAgICAgc3RhdGUucSA9IHN0YXRlLm51bTsKICAgICAgfQogICAgICArK3N0YXRlLnN0YXRlOwogICAgfSBlbHNlIGlmKHN0YXRlLnN0YXRlID09PSAyKSB7CiAgICAgIC8vIGNvbXB1dGUgcGhpOiAocCAtIDEpKHEgLSAxKSAoRXVsZXIncyB0b3RpZW50IGZ1bmN0aW9uKQogICAgICBzdGF0ZS5wMSA9IHN0YXRlLnAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpOwogICAgICBzdGF0ZS5xMSA9IHN0YXRlLnEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpOwogICAgICBzdGF0ZS5waGkgPSBzdGF0ZS5wMS5tdWx0aXBseShzdGF0ZS5xMSk7CiAgICAgICsrc3RhdGUuc3RhdGU7CiAgICB9IGVsc2UgaWYoc3RhdGUuc3RhdGUgPT09IDMpIHsKICAgICAgLy8gZW5zdXJlIGUgYW5kIHBoaSBhcmUgY29wcmltZQogICAgICBpZihzdGF0ZS5waGkuZ2NkKHN0YXRlLmUpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT09IDApIHsKICAgICAgICAvLyBwaGkgYW5kIGUgYXJlIGNvcHJpbWUsIGFkdmFuY2UKICAgICAgICArK3N0YXRlLnN0YXRlOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIHBoaSBhbmQgZSBhcmVuJ3QgY29wcmltZSwgc28gZ2VuZXJhdGUgYSBuZXcgcCBhbmQgcQogICAgICAgIHN0YXRlLnAgPSBudWxsOwogICAgICAgIHN0YXRlLnEgPSBudWxsOwogICAgICAgIHN0YXRlLnN0YXRlID0gMDsKICAgICAgfQogICAgfSBlbHNlIGlmKHN0YXRlLnN0YXRlID09PSA0KSB7CiAgICAgIC8vIGNyZWF0ZSBuLCBlbnN1cmUgbiBpcyBoYXMgdGhlIHJpZ2h0IG51bWJlciBvZiBiaXRzCiAgICAgIHN0YXRlLm4gPSBzdGF0ZS5wLm11bHRpcGx5KHN0YXRlLnEpOwoKICAgICAgLy8gZW5zdXJlIG4gaXMgcmlnaHQgbnVtYmVyIG9mIGJpdHMKICAgICAgaWYoc3RhdGUubi5iaXRMZW5ndGgoKSA9PT0gc3RhdGUuYml0cykgewogICAgICAgIC8vIHN1Y2Nlc3MsIGFkdmFuY2UKICAgICAgICArK3N0YXRlLnN0YXRlOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIGZhaWxlZCwgZ2V0IG5ldyBxCiAgICAgICAgc3RhdGUucSA9IG51bGw7CiAgICAgICAgc3RhdGUuc3RhdGUgPSAwOwogICAgICB9CiAgICB9IGVsc2UgaWYoc3RhdGUuc3RhdGUgPT09IDUpIHsKICAgICAgLy8gc2V0IGtleXMKICAgICAgdmFyIGQgPSBzdGF0ZS5lLm1vZEludmVyc2Uoc3RhdGUucGhpKTsKICAgICAgc3RhdGUua2V5cyA9IHsKICAgICAgICBwcml2YXRlS2V5OiBwa2kucnNhLnNldFByaXZhdGVLZXkoCiAgICAgICAgICBzdGF0ZS5uLCBzdGF0ZS5lLCBkLCBzdGF0ZS5wLCBzdGF0ZS5xLAogICAgICAgICAgZC5tb2Qoc3RhdGUucDEpLCBkLm1vZChzdGF0ZS5xMSksCiAgICAgICAgICBzdGF0ZS5xLm1vZEludmVyc2Uoc3RhdGUucCkpLAogICAgICAgIHB1YmxpY0tleTogcGtpLnJzYS5zZXRQdWJsaWNLZXkoc3RhdGUubiwgc3RhdGUuZSkKICAgICAgfTsKICAgIH0KCiAgICAvLyB1cGRhdGUgdGltaW5nCiAgICB0MiA9ICtuZXcgRGF0ZSgpOwogICAgdG90YWwgKz0gdDIgLSB0MTsKICAgIHQxID0gdDI7CiAgfQoKICByZXR1cm4gc3RhdGUua2V5cyAhPT0gbnVsbDsKfTsKCi8qKgogKiBHZW5lcmF0ZXMgYW4gUlNBIHB1YmxpYy1wcml2YXRlIGtleSBwYWlyIGluIGEgc2luZ2xlIGNhbGwuCiAqCiAqIFRvIGdlbmVyYXRlIGEga2V5LXBhaXIgaW4gc3RlcHMgKHRvIGFsbG93IGZvciBwcm9ncmVzcyB1cGRhdGVzIGFuZCB0bwogKiBwcmV2ZW50IGJsb2NraW5nIG9yIHdhcm5pbmdzIGluIHNsb3cgYnJvd3NlcnMpIHRoZW4gdXNlIHRoZSBrZXktcGFpcgogKiBnZW5lcmF0aW9uIHN0YXRlIGZ1bmN0aW9ucy4KICoKICogVG8gZ2VuZXJhdGUgYSBrZXktcGFpciBhc3luY2hyb25vdXNseSAoZWl0aGVyIHRocm91Z2ggd2ViLXdvcmtlcnMsIGlmCiAqIGF2YWlsYWJsZSwgb3IgYnkgYnJlYWtpbmcgdXAgdGhlIHdvcmsgb24gdGhlIG1haW4gdGhyZWFkKSwgcGFzcyBhCiAqIGNhbGxiYWNrIGZ1bmN0aW9uLgogKgogKiBAcGFyYW0gW2JpdHNdIHRoZSBzaXplIGZvciB0aGUgcHJpdmF0ZSBrZXkgaW4gYml0cywgZGVmYXVsdHMgdG8gMjA0OC4KICogQHBhcmFtIFtlXSB0aGUgcHVibGljIGV4cG9uZW50IHRvIHVzZSwgZGVmYXVsdHMgdG8gNjU1MzcuCiAqIEBwYXJhbSBbb3B0aW9uc10gb3B0aW9ucyBmb3Iga2V5LXBhaXIgZ2VuZXJhdGlvbiwgaWYgZ2l2ZW4gdGhlbiAnYml0cycKICogICAgICAgICAgYW5kICdlJyBtdXN0ICpub3QqIGJlIGdpdmVuOgogKiAgICAgICAgICBiaXRzIHRoZSBzaXplIGZvciB0aGUgcHJpdmF0ZSBrZXkgaW4gYml0cywgKGRlZmF1bHQ6IDIwNDgpLgogKiAgICAgICAgICBlIHRoZSBwdWJsaWMgZXhwb25lbnQgdG8gdXNlLCAoZGVmYXVsdDogNjU1MzcgKDB4MTAwMDEpKS4KICogICAgICAgICAgd29ya2VyU2NyaXB0IHRoZSB3b3JrZXIgc2NyaXB0IFVSTC4KICogICAgICAgICAgd29ya2VycyB0aGUgbnVtYmVyIG9mIHdlYiB3b3JrZXJzIChpZiBzdXBwb3J0ZWQpIHRvIHVzZSwKICogICAgICAgICAgICAoZGVmYXVsdDogMikuCiAqICAgICAgICAgIHdvcmtMb2FkIHRoZSBzaXplIG9mIHRoZSB3b3JrIGxvYWQsIGllOiBudW1iZXIgb2YgcG9zc2libGUgcHJpbWUKICogICAgICAgICAgICBudW1iZXJzIGZvciBlYWNoIHdlYiB3b3JrZXIgdG8gY2hlY2sgcGVyIHdvcmsgYXNzaWdubWVudCwKICogICAgICAgICAgICAoZGVmYXVsdDogMTAwKS4KICogICAgICAgICAgZSB0aGUgcHVibGljIGV4cG9uZW50IHRvIHVzZSwgZGVmYXVsdHMgdG8gNjU1MzcuCiAqICAgICAgICAgIHBybmcgYSBjdXN0b20gY3J5cHRvLXNlY3VyZSBwc2V1ZG8tcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgdG8gdXNlLAogKiAgICAgICAgICAgIHRoYXQgbXVzdCBkZWZpbmUgImdldEJ5dGVzU3luYyIuCiAqICAgICAgICAgIGFsZ29yaXRobSB0aGUgYWxnb3JpdGhtIHRvIHVzZSAoZGVmYXVsdDogJ1BSSU1FSU5DJykuCiAqIEBwYXJhbSBbY2FsbGJhY2soZXJyLCBrZXlwYWlyKV0gY2FsbGVkIG9uY2UgdGhlIG9wZXJhdGlvbiBjb21wbGV0ZXMuCiAqCiAqIEByZXR1cm4gYW4gb2JqZWN0IHdpdGggcHJpdmF0ZUtleSBhbmQgcHVibGljS2V5IHByb3BlcnRpZXMuCiAqLwpwa2kucnNhLmdlbmVyYXRlS2V5UGFpciA9IGZ1bmN0aW9uKGJpdHMsIGUsIG9wdGlvbnMsIGNhbGxiYWNrKSB7CiAgLy8gKGJpdHMpLCAob3B0aW9ucyksIChjYWxsYmFjaykKICBpZihhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7CiAgICBpZih0eXBlb2YgYml0cyA9PT0gJ29iamVjdCcpIHsKICAgICAgb3B0aW9ucyA9IGJpdHM7CiAgICAgIGJpdHMgPSB1bmRlZmluZWQ7CiAgICB9IGVsc2UgaWYodHlwZW9mIGJpdHMgPT09ICdmdW5jdGlvbicpIHsKICAgICAgY2FsbGJhY2sgPSBiaXRzOwogICAgICBiaXRzID0gdW5kZWZpbmVkOwogICAgfQogIH0gZWxzZSBpZihhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7CiAgICAvLyAoYml0cywgZSksIChiaXRzLCBvcHRpb25zKSwgKGJpdHMsIGNhbGxiYWNrKSwgKG9wdGlvbnMsIGNhbGxiYWNrKQogICAgaWYodHlwZW9mIGJpdHMgPT09ICdudW1iZXInKSB7CiAgICAgIGlmKHR5cGVvZiBlID09PSAnZnVuY3Rpb24nKSB7CiAgICAgICAgY2FsbGJhY2sgPSBlOwogICAgICAgIGUgPSB1bmRlZmluZWQ7CiAgICAgIH0gZWxzZSBpZih0eXBlb2YgZSAhPT0gJ251bWJlcicpIHsKICAgICAgICBvcHRpb25zID0gZTsKICAgICAgICBlID0gdW5kZWZpbmVkOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBvcHRpb25zID0gYml0czsKICAgICAgY2FsbGJhY2sgPSBlOwogICAgICBiaXRzID0gdW5kZWZpbmVkOwogICAgICBlID0gdW5kZWZpbmVkOwogICAgfQogIH0gZWxzZSBpZihhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7CiAgICAvLyAoYml0cywgZSwgb3B0aW9ucyksIChiaXRzLCBlLCBjYWxsYmFjayksIChiaXRzLCBvcHRpb25zLCBjYWxsYmFjaykKICAgIGlmKHR5cGVvZiBlID09PSAnbnVtYmVyJykgewogICAgICBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgIGNhbGxiYWNrID0gb3B0aW9uczsKICAgICAgICBvcHRpb25zID0gdW5kZWZpbmVkOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBjYWxsYmFjayA9IG9wdGlvbnM7CiAgICAgIG9wdGlvbnMgPSBlOwogICAgICBlID0gdW5kZWZpbmVkOwogICAgfQogIH0KICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICBpZihiaXRzID09PSB1bmRlZmluZWQpIHsKICAgIGJpdHMgPSBvcHRpb25zLmJpdHMgfHwgMjA0ODsKICB9CiAgaWYoZSA9PT0gdW5kZWZpbmVkKSB7CiAgICBlID0gb3B0aW9ucy5lIHx8IDB4MTAwMDE7CiAgfQogIHZhciBzdGF0ZSA9IHBraS5yc2EuY3JlYXRlS2V5UGFpckdlbmVyYXRpb25TdGF0ZShiaXRzLCBlLCBvcHRpb25zKTsKICBpZighY2FsbGJhY2spIHsKICAgIHBraS5yc2Euc3RlcEtleVBhaXJHZW5lcmF0aW9uU3RhdGUoc3RhdGUsIDApOwogICAgcmV0dXJuIHN0YXRlLmtleXM7CiAgfQogIF9nZW5lcmF0ZUtleVBhaXIoc3RhdGUsIG9wdGlvbnMsIGNhbGxiYWNrKTsKfTsKCi8qKgogKiBTZXRzIGFuIFJTQSBwdWJsaWMga2V5IGZyb20gQmlnSW50ZWdlcnMgbW9kdWx1cyBhbmQgZXhwb25lbnQuCiAqCiAqIEBwYXJhbSBuIHRoZSBtb2R1bHVzLgogKiBAcGFyYW0gZSB0aGUgZXhwb25lbnQuCiAqCiAqIEByZXR1cm4gdGhlIHB1YmxpYyBrZXkuCiAqLwpwa2kuc2V0UnNhUHVibGljS2V5ID0gcGtpLnJzYS5zZXRQdWJsaWNLZXkgPSBmdW5jdGlvbihuLCBlKSB7CiAgdmFyIGtleSA9IHsKICAgIG46IG4sCiAgICBlOiBlCiAgfTsKCiAgLyoqCiAgICogRW5jcnlwdHMgdGhlIGdpdmVuIGRhdGEgd2l0aCB0aGlzIHB1YmxpYyBrZXkuIE5ld2VyIGFwcGxpY2F0aW9ucwogICAqIHNob3VsZCB1c2UgdGhlICdSU0EtT0FFUCcgZGVjcnlwdGlvbiBzY2hlbWUsICdSU0FFUy1QS0NTMS1WMV81JyBpcyBmb3IKICAgKiBsZWdhY3kgYXBwbGljYXRpb25zLgogICAqCiAgICogQHBhcmFtIGRhdGEgdGhlIGJ5dGUgc3RyaW5nIHRvIGVuY3J5cHQuCiAgICogQHBhcmFtIHNjaGVtZSB0aGUgZW5jcnlwdGlvbiBzY2hlbWUgdG8gdXNlOgogICAqICAgICAgICAgICdSU0FFUy1QS0NTMS1WMV81JyAoZGVmYXVsdCksCiAgICogICAgICAgICAgJ1JTQS1PQUVQJywKICAgKiAgICAgICAgICAnUkFXJywgJ05PTkUnLCBvciBudWxsIHRvIHBlcmZvcm0gcmF3IFJTQSBlbmNyeXB0aW9uLAogICAqICAgICAgICAgIGFuIG9iamVjdCB3aXRoIGFuICdlbmNvZGUnIHByb3BlcnR5IHNldCB0byBhIGZ1bmN0aW9uCiAgICogICAgICAgICAgd2l0aCB0aGUgc2lnbmF0dXJlICdmdW5jdGlvbihkYXRhLCBrZXkpJyB0aGF0IHJldHVybnMKICAgKiAgICAgICAgICBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGVuY29kZWQgZGF0YS4KICAgKiBAcGFyYW0gc2NoZW1lT3B0aW9ucyBhbnkgc2NoZW1lLXNwZWNpZmljIG9wdGlvbnMuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBlbmNyeXB0ZWQgYnl0ZSBzdHJpbmcuCiAgICovCiAga2V5LmVuY3J5cHQgPSBmdW5jdGlvbihkYXRhLCBzY2hlbWUsIHNjaGVtZU9wdGlvbnMpIHsKICAgIGlmKHR5cGVvZiBzY2hlbWUgPT09ICdzdHJpbmcnKSB7CiAgICAgIHNjaGVtZSA9IHNjaGVtZS50b1VwcGVyQ2FzZSgpOwogICAgfSBlbHNlIGlmKHNjaGVtZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIHNjaGVtZSA9ICdSU0FFUy1QS0NTMS1WMV81JzsKICAgIH0KCiAgICBpZihzY2hlbWUgPT09ICdSU0FFUy1QS0NTMS1WMV81JykgewogICAgICBzY2hlbWUgPSB7CiAgICAgICAgZW5jb2RlOiBmdW5jdGlvbihtLCBrZXksIHB1YikgewogICAgICAgICAgcmV0dXJuIF9lbmNvZGVQa2NzMV92MV81KG0sIGtleSwgMHgwMikuZ2V0Qnl0ZXMoKTsKICAgICAgICB9CiAgICAgIH07CiAgICB9IGVsc2UgaWYoc2NoZW1lID09PSAnUlNBLU9BRVAnIHx8IHNjaGVtZSA9PT0gJ1JTQUVTLU9BRVAnKSB7CiAgICAgIHNjaGVtZSA9IHsKICAgICAgICBlbmNvZGU6IGZ1bmN0aW9uKG0sIGtleSkgewogICAgICAgICAgcmV0dXJuIGZvcmdlLnBrY3MxLmVuY29kZV9yc2Ffb2FlcChrZXksIG0sIHNjaGVtZU9wdGlvbnMpOwogICAgICAgIH0KICAgICAgfTsKICAgIH0gZWxzZSBpZihbJ1JBVycsICdOT05FJywgJ05VTEwnLCBudWxsXS5pbmRleE9mKHNjaGVtZSkgIT09IC0xKSB7CiAgICAgIHNjaGVtZSA9IHsgZW5jb2RlOiBmdW5jdGlvbihlKSB7IHJldHVybiBlOyB9IH07CiAgICB9IGVsc2UgaWYodHlwZW9mIHNjaGVtZSA9PT0gJ3N0cmluZycpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBlbmNyeXB0aW9uIHNjaGVtZTogIicgKyBzY2hlbWUgKyAnIi4nKTsKICAgIH0KCiAgICAvLyBkbyBzY2hlbWUtYmFzZWQgZW5jb2RpbmcgdGhlbiByc2EgZW5jcnlwdGlvbgogICAgdmFyIGUgPSBzY2hlbWUuZW5jb2RlKGRhdGEsIGtleSwgdHJ1ZSk7CiAgICByZXR1cm4gcGtpLnJzYS5lbmNyeXB0KGUsIGtleSwgdHJ1ZSk7CiAgfTsKCiAgLyoqCiAgICogVmVyaWZpZXMgdGhlIGdpdmVuIHNpZ25hdHVyZSBhZ2FpbnN0IHRoZSBnaXZlbiBkaWdlc3QuCiAgICoKICAgKiBQS0NTIzEgc3VwcG9ydHMgbXVsdGlwbGUgKGN1cnJlbnRseSB0d28pIHNpZ25hdHVyZSBzY2hlbWVzOgogICAqIFJTQVNTQS1QS0NTMS1WMV81IGFuZCBSU0FTU0EtUFNTLgogICAqCiAgICogQnkgZGVmYXVsdCB0aGlzIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlICJvbGQgc2NoZW1lIiwgaS5lLgogICAqIFJTQVNTQS1QS0NTMS1WMV81LCBpbiB3aGljaCBjYXNlIG9uY2UgUlNBLWRlY3J5cHRlZCwgdGhlCiAgICogc2lnbmF0dXJlIGlzIGFuIE9DVEVUIFNUUklORyB0aGF0IGhvbGRzIGEgRGlnZXN0SW5mby4KICAgKgogICAqIERpZ2VzdEluZm8gOjo9IFNFUVVFTkNFIHsKICAgKiAgIGRpZ2VzdEFsZ29yaXRobSBEaWdlc3RBbGdvcml0aG1JZGVudGlmaWVyLAogICAqICAgZGlnZXN0IERpZ2VzdAogICAqIH0KICAgKiBEaWdlc3RBbGdvcml0aG1JZGVudGlmaWVyIDo6PSBBbGdvcml0aG1JZGVudGlmaWVyCiAgICogRGlnZXN0IDo6PSBPQ1RFVCBTVFJJTkcKICAgKgogICAqIFRvIHBlcmZvcm0gUFNTIHNpZ25hdHVyZSB2ZXJpZmljYXRpb24sIHByb3ZpZGUgYW4gaW5zdGFuY2UKICAgKiBvZiBGb3JnZSBQU1Mgb2JqZWN0IGFzIHRoZSBzY2hlbWUgcGFyYW1ldGVyLgogICAqCiAgICogQHBhcmFtIGRpZ2VzdCB0aGUgbWVzc2FnZSBkaWdlc3QgaGFzaCB0byBjb21wYXJlIGFnYWluc3QgdGhlIHNpZ25hdHVyZSwKICAgKiAgICAgICAgICBhcyBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZy4KICAgKiBAcGFyYW0gc2lnbmF0dXJlIHRoZSBzaWduYXR1cmUgdG8gdmVyaWZ5LCBhcyBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZy4KICAgKiBAcGFyYW0gc2NoZW1lIHNpZ25hdHVyZSB2ZXJpZmljYXRpb24gc2NoZW1lIHRvIHVzZToKICAgKiAgICAgICAgICAnUlNBU1NBLVBLQ1MxLVYxXzUnIG9yIHVuZGVmaW5lZCBmb3IgUlNBU1NBIFBLQ1MjMSB2MS41LAogICAqICAgICAgICAgIGEgRm9yZ2UgUFNTIG9iamVjdCBmb3IgUlNBU1NBLVBTUywKICAgKiAgICAgICAgICAnTk9ORScgb3IgbnVsbCBmb3Igbm9uZSwgRGlnZXN0SW5mbyB3aWxsIG5vdCBiZSBleHBlY3RlZCwgYnV0CiAgICogICAgICAgICAgICBQS0NTIzEgdjEuNSBwYWRkaW5nIHdpbGwgc3RpbGwgYmUgdXNlZC4KICAgKgogICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc2lnbmF0dXJlIHdhcyB2ZXJpZmllZCwgZmFsc2UgaWYgbm90LgogICAqLwogICBrZXkudmVyaWZ5ID0gZnVuY3Rpb24oZGlnZXN0LCBzaWduYXR1cmUsIHNjaGVtZSkgewogICAgIGlmKHR5cGVvZiBzY2hlbWUgPT09ICdzdHJpbmcnKSB7CiAgICAgICBzY2hlbWUgPSBzY2hlbWUudG9VcHBlckNhc2UoKTsKICAgICB9IGVsc2UgaWYoc2NoZW1lID09PSB1bmRlZmluZWQpIHsKICAgICAgIHNjaGVtZSA9ICdSU0FTU0EtUEtDUzEtVjFfNSc7CiAgICAgfQoKICAgICBpZihzY2hlbWUgPT09ICdSU0FTU0EtUEtDUzEtVjFfNScpIHsKICAgICAgIHNjaGVtZSA9IHsKICAgICAgICAgdmVyaWZ5OiBmdW5jdGlvbihkaWdlc3QsIGQpIHsKICAgICAgICAgICAvLyByZW1vdmUgcGFkZGluZwogICAgICAgICAgIGQgPSBfZGVjb2RlUGtjczFfdjFfNShkLCBrZXksIHRydWUpOwogICAgICAgICAgIC8vIGQgaXMgQVNOLjEgQkVSLWVuY29kZWQgRGlnZXN0SW5mbwogICAgICAgICAgIHZhciBvYmogPSBhc24xLmZyb21EZXIoZCk7CiAgICAgICAgICAgLy8gY29tcGFyZSB0aGUgZ2l2ZW4gZGlnZXN0IHRvIHRoZSBkZWNyeXB0ZWQgb25lCiAgICAgICAgICAgcmV0dXJuIGRpZ2VzdCA9PT0gb2JqLnZhbHVlWzFdLnZhbHVlOwogICAgICAgICB9CiAgICAgICB9OwogICAgIH0gZWxzZSBpZihzY2hlbWUgPT09ICdOT05FJyB8fCBzY2hlbWUgPT09ICdOVUxMJyB8fCBzY2hlbWUgPT09IG51bGwpIHsKICAgICAgIHNjaGVtZSA9IHsKICAgICAgICAgdmVyaWZ5OiBmdW5jdGlvbihkaWdlc3QsIGQpIHsKICAgICAgICAgICAvLyByZW1vdmUgcGFkZGluZwogICAgICAgICAgIGQgPSBfZGVjb2RlUGtjczFfdjFfNShkLCBrZXksIHRydWUpOwogICAgICAgICAgIHJldHVybiBkaWdlc3QgPT09IGQ7CiAgICAgICAgIH0KICAgICAgIH07CiAgICAgfQoKICAgICAvLyBkbyByc2EgZGVjcnlwdGlvbiB3L28gYW55IGRlY29kaW5nLCB0aGVuIHZlcmlmeSAtLSB3aGljaCBkb2VzIGRlY29kaW5nCiAgICAgdmFyIGQgPSBwa2kucnNhLmRlY3J5cHQoc2lnbmF0dXJlLCBrZXksIHRydWUsIGZhbHNlKTsKICAgICByZXR1cm4gc2NoZW1lLnZlcmlmeShkaWdlc3QsIGQsIGtleS5uLmJpdExlbmd0aCgpKTsKICB9OwoKICByZXR1cm4ga2V5Owp9OwoKLyoqCiAqIFNldHMgYW4gUlNBIHByaXZhdGUga2V5IGZyb20gQmlnSW50ZWdlcnMgbW9kdWx1cywgZXhwb25lbnQsIHByaW1lcywKICogcHJpbWUgZXhwb25lbnRzLCBhbmQgbW9kdWxhciBtdWx0aXBsaWNhdGl2ZSBpbnZlcnNlLgogKgogKiBAcGFyYW0gbiB0aGUgbW9kdWx1cy4KICogQHBhcmFtIGUgdGhlIHB1YmxpYyBleHBvbmVudC4KICogQHBhcmFtIGQgdGhlIHByaXZhdGUgZXhwb25lbnQgKChpbnZlcnNlIG9mIGUpIG1vZCBuKS4KICogQHBhcmFtIHAgdGhlIGZpcnN0IHByaW1lLgogKiBAcGFyYW0gcSB0aGUgc2Vjb25kIHByaW1lLgogKiBAcGFyYW0gZFAgZXhwb25lbnQxIChkIG1vZCAocC0xKSkuCiAqIEBwYXJhbSBkUSBleHBvbmVudDIgKGQgbW9kIChxLTEpKS4KICogQHBhcmFtIHFJbnYgKChpbnZlcnNlIG9mIHEpIG1vZCBwKQogKgogKiBAcmV0dXJuIHRoZSBwcml2YXRlIGtleS4KICovCnBraS5zZXRSc2FQcml2YXRlS2V5ID0gcGtpLnJzYS5zZXRQcml2YXRlS2V5ID0gZnVuY3Rpb24oCiAgbiwgZSwgZCwgcCwgcSwgZFAsIGRRLCBxSW52KSB7CiAgdmFyIGtleSA9IHsKICAgIG46IG4sCiAgICBlOiBlLAogICAgZDogZCwKICAgIHA6IHAsCiAgICBxOiBxLAogICAgZFA6IGRQLAogICAgZFE6IGRRLAogICAgcUludjogcUludgogIH07CgogIC8qKgogICAqIERlY3J5cHRzIHRoZSBnaXZlbiBkYXRhIHdpdGggdGhpcyBwcml2YXRlIGtleS4gVGhlIGRlY3J5cHRpb24gc2NoZW1lCiAgICogbXVzdCBtYXRjaCB0aGUgb25lIHVzZWQgdG8gZW5jcnlwdCB0aGUgZGF0YS4KICAgKgogICAqIEBwYXJhbSBkYXRhIHRoZSBieXRlIHN0cmluZyB0byBkZWNyeXB0LgogICAqIEBwYXJhbSBzY2hlbWUgdGhlIGRlY3J5cHRpb24gc2NoZW1lIHRvIHVzZToKICAgKiAgICAgICAgICAnUlNBRVMtUEtDUzEtVjFfNScgKGRlZmF1bHQpLAogICAqICAgICAgICAgICdSU0EtT0FFUCcsCiAgICogICAgICAgICAgJ1JBVycsICdOT05FJywgb3IgbnVsbCB0byBwZXJmb3JtIHJhdyBSU0EgZGVjcnlwdGlvbi4KICAgKiBAcGFyYW0gc2NoZW1lT3B0aW9ucyBhbnkgc2NoZW1lLXNwZWNpZmljIG9wdGlvbnMuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBkZWNyeXB0ZWQgYnl0ZSBzdHJpbmcuCiAgICovCiAga2V5LmRlY3J5cHQgPSBmdW5jdGlvbihkYXRhLCBzY2hlbWUsIHNjaGVtZU9wdGlvbnMpIHsKICAgIGlmKHR5cGVvZiBzY2hlbWUgPT09ICdzdHJpbmcnKSB7CiAgICAgIHNjaGVtZSA9IHNjaGVtZS50b1VwcGVyQ2FzZSgpOwogICAgfSBlbHNlIGlmKHNjaGVtZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIHNjaGVtZSA9ICdSU0FFUy1QS0NTMS1WMV81JzsKICAgIH0KCiAgICAvLyBkbyByc2EgZGVjcnlwdGlvbiB3L28gYW55IGRlY29kaW5nCiAgICB2YXIgZCA9IHBraS5yc2EuZGVjcnlwdChkYXRhLCBrZXksIGZhbHNlLCBmYWxzZSk7CgogICAgaWYoc2NoZW1lID09PSAnUlNBRVMtUEtDUzEtVjFfNScpIHsKICAgICAgc2NoZW1lID0geyBkZWNvZGU6IF9kZWNvZGVQa2NzMV92MV81IH07CiAgICB9IGVsc2UgaWYoc2NoZW1lID09PSAnUlNBLU9BRVAnIHx8IHNjaGVtZSA9PT0gJ1JTQUVTLU9BRVAnKSB7CiAgICAgIHNjaGVtZSA9IHsKICAgICAgICBkZWNvZGU6IGZ1bmN0aW9uKGQsIGtleSkgewogICAgICAgICAgcmV0dXJuIGZvcmdlLnBrY3MxLmRlY29kZV9yc2Ffb2FlcChrZXksIGQsIHNjaGVtZU9wdGlvbnMpOwogICAgICAgIH0KICAgICAgfTsKICAgIH0gZWxzZSBpZihbJ1JBVycsICdOT05FJywgJ05VTEwnLCBudWxsXS5pbmRleE9mKHNjaGVtZSkgIT09IC0xKSB7CiAgICAgIHNjaGVtZSA9IHsgZGVjb2RlOiBmdW5jdGlvbihkKSB7IHJldHVybiBkOyB9IH07CiAgICB9IGVsc2UgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGVuY3J5cHRpb24gc2NoZW1lOiAiJyArIHNjaGVtZSArICciLicpOwogICAgfQoKICAgIC8vIGRlY29kZSBhY2NvcmRpbmcgdG8gc2NoZW1lCiAgICByZXR1cm4gc2NoZW1lLmRlY29kZShkLCBrZXksIGZhbHNlKTsKICB9OwoKICAvKioKICAgKiBTaWducyB0aGUgZ2l2ZW4gZGlnZXN0LCBwcm9kdWNpbmcgYSBzaWduYXR1cmUuCiAgICoKICAgKiBQS0NTIzEgc3VwcG9ydHMgbXVsdGlwbGUgKGN1cnJlbnRseSB0d28pIHNpZ25hdHVyZSBzY2hlbWVzOgogICAqIFJTQVNTQS1QS0NTMS1WMV81IGFuZCBSU0FTU0EtUFNTLgogICAqCiAgICogQnkgZGVmYXVsdCB0aGlzIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlICJvbGQgc2NoZW1lIiwgaS5lLgogICAqIFJTQVNTQS1QS0NTMS1WMV81LiBJbiBvcmRlciB0byBnZW5lcmF0ZSBhIFBTUyBzaWduYXR1cmUsIHByb3ZpZGUKICAgKiBhbiBpbnN0YW5jZSBvZiBGb3JnZSBQU1Mgb2JqZWN0IGFzIHRoZSBzY2hlbWUgcGFyYW1ldGVyLgogICAqCiAgICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3Qgd2l0aCB0aGUgaGFzaCB0byBzaWduLgogICAqIEBwYXJhbSBzY2hlbWUgdGhlIHNpZ25hdHVyZSBzY2hlbWUgdG8gdXNlOgogICAqICAgICAgICAgICdSU0FTU0EtUEtDUzEtVjFfNScgb3IgdW5kZWZpbmVkIGZvciBSU0FTU0EgUEtDUyMxIHYxLjUsCiAgICogICAgICAgICAgYSBGb3JnZSBQU1Mgb2JqZWN0IGZvciBSU0FTU0EtUFNTLAogICAqICAgICAgICAgICdOT05FJyBvciBudWxsIGZvciBub25lLCBEaWdlc3RJbmZvIHdpbGwgbm90IGJlIHVzZWQgYnV0CiAgICogICAgICAgICAgICBQS0NTIzEgdjEuNSBwYWRkaW5nIHdpbGwgc3RpbGwgYmUgdXNlZC4KICAgKgogICAqIEByZXR1cm4gdGhlIHNpZ25hdHVyZSBhcyBhIGJ5dGUgc3RyaW5nLgogICAqLwogIGtleS5zaWduID0gZnVuY3Rpb24obWQsIHNjaGVtZSkgewogICAgLyogTm90ZTogVGhlIGludGVybmFsIGltcGxlbWVudGF0aW9uIG9mIFJTQSBvcGVyYXRpb25zIGlzIGJlaW5nCiAgICAgIHRyYW5zaXRpb25lZCBhd2F5IGZyb20gYSBQS0NTIzEgdjEuNSBoYXJkLWNvZGVkIHNjaGVtZS4gU29tZSBsZWdhY3kKICAgICAgY29kZSBsaWtlIHRoZSB1c2Ugb2YgYW4gZW5jb2RpbmcgYmxvY2sgaWRlbnRpZmllciAnYnQnIHdpbGwgZXZlbnR1YWxseQogICAgICBiZSByZW1vdmVkLiAqLwoKICAgIC8vIHByaXZhdGUga2V5IG9wZXJhdGlvbgogICAgdmFyIGJ0ID0gZmFsc2U7CgogICAgaWYodHlwZW9mIHNjaGVtZSA9PT0gJ3N0cmluZycpIHsKICAgICAgc2NoZW1lID0gc2NoZW1lLnRvVXBwZXJDYXNlKCk7CiAgICB9CgogICAgaWYoc2NoZW1lID09PSB1bmRlZmluZWQgfHwgc2NoZW1lID09PSAnUlNBU1NBLVBLQ1MxLVYxXzUnKSB7CiAgICAgIHNjaGVtZSA9IHsgZW5jb2RlOiBlbXNhUGtjczF2MTVlbmNvZGUgfTsKICAgICAgYnQgPSAweDAxOwogICAgfSBlbHNlIGlmKHNjaGVtZSA9PT0gJ05PTkUnIHx8IHNjaGVtZSA9PT0gJ05VTEwnIHx8IHNjaGVtZSA9PT0gbnVsbCkgewogICAgICBzY2hlbWUgPSB7IGVuY29kZTogZnVuY3Rpb24oKSB7IHJldHVybiBtZDsgfSB9OwogICAgICBidCA9IDB4MDE7CiAgICB9CgogICAgLy8gZW5jb2RlIGFuZCB0aGVuIGVuY3J5cHQKICAgIHZhciBkID0gc2NoZW1lLmVuY29kZShtZCwga2V5Lm4uYml0TGVuZ3RoKCkpOwogICAgcmV0dXJuIHBraS5yc2EuZW5jcnlwdChkLCBrZXksIGJ0KTsKICB9OwoKICByZXR1cm4ga2V5Owp9OwoKLyoqCiAqIFdyYXBzIGFuIFJTQVByaXZhdGVLZXkgQVNOLjEgb2JqZWN0IGluIGFuIEFTTi4xIFByaXZhdGVLZXlJbmZvIG9iamVjdC4KICoKICogQHBhcmFtIHJzYUtleSB0aGUgQVNOLjEgUlNBUHJpdmF0ZUtleS4KICoKICogQHJldHVybiB0aGUgQVNOLjEgUHJpdmF0ZUtleUluZm8uCiAqLwpwa2kud3JhcFJzYVByaXZhdGVLZXkgPSBmdW5jdGlvbihyc2FLZXkpIHsKICAvLyBQcml2YXRlS2V5SW5mbwogIHJldHVybiBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAvLyB2ZXJzaW9uICgwKQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIoMCkuZ2V0Qnl0ZXMoKSksCiAgICAvLyBwcml2YXRlS2V5QWxnb3JpdGhtCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIGFzbjEuY3JlYXRlKAogICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICBhc24xLm9pZFRvRGVyKHBraS5vaWRzLnJzYUVuY3J5cHRpb24pLmdldEJ5dGVzKCkpLAogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgIF0pLAogICAgLy8gUHJpdmF0ZUtleQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsCiAgICAgIGFzbjEudG9EZXIocnNhS2V5KS5nZXRCeXRlcygpKQogICAgXSk7Cn07CgovKioKICogQ29udmVydHMgYSBwcml2YXRlIGtleSBmcm9tIGFuIEFTTi4xIG9iamVjdC4KICoKICogQHBhcmFtIG9iaiB0aGUgQVNOLjEgcmVwcmVzZW50YXRpb24gb2YgYSBQcml2YXRlS2V5SW5mbyBjb250YWluaW5nIGFuCiAqICAgICAgICAgIFJTQVByaXZhdGVLZXkgb3IgYW4gUlNBUHJpdmF0ZUtleS4KICoKICogQHJldHVybiB0aGUgcHJpdmF0ZSBrZXkuCiAqLwpwa2kucHJpdmF0ZUtleUZyb21Bc24xID0gZnVuY3Rpb24ob2JqKSB7CiAgLy8gZ2V0IFByaXZhdGVLZXlJbmZvCiAgdmFyIGNhcHR1cmUgPSB7fTsKICB2YXIgZXJyb3JzID0gW107CiAgaWYoYXNuMS52YWxpZGF0ZShvYmosIHByaXZhdGVLZXlWYWxpZGF0b3IsIGNhcHR1cmUsIGVycm9ycykpIHsKICAgIG9iaiA9IGFzbjEuZnJvbURlcihmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLnByaXZhdGVLZXkpKTsKICB9CgogIC8vIGdldCBSU0FQcml2YXRlS2V5CiAgY2FwdHVyZSA9IHt9OwogIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgcnNhUHJpdmF0ZUtleVZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBwcml2YXRlIGtleS4gJyArCiAgICAgICdBU04uMSBvYmplY3QgZG9lcyBub3QgY29udGFpbiBhbiBSU0FQcml2YXRlS2V5LicpOwogICAgZXJyb3IuZXJyb3JzID0gZXJyb3JzOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICAvLyBOb3RlOiBWZXJzaW9uIGlzIGN1cnJlbnRseSBpZ25vcmVkLgogIC8vIGNhcHR1cmUucHJpdmF0ZUtleVZlcnNpb24KICAvLyBGSVhNRTogaW5lZmZpY2llbnQsIGdldCBhIEJpZ0ludGVnZXIgdGhhdCB1c2VzIGJ5dGUgc3RyaW5ncwogIHZhciBuLCBlLCBkLCBwLCBxLCBkUCwgZFEsIHFJbnY7CiAgbiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUucHJpdmF0ZUtleU1vZHVsdXMpLnRvSGV4KCk7CiAgZSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUucHJpdmF0ZUtleVB1YmxpY0V4cG9uZW50KS50b0hleCgpOwogIGQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLnByaXZhdGVLZXlQcml2YXRlRXhwb25lbnQpLnRvSGV4KCk7CiAgcCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUucHJpdmF0ZUtleVByaW1lMSkudG9IZXgoKTsKICBxID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5wcml2YXRlS2V5UHJpbWUyKS50b0hleCgpOwogIGRQID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5wcml2YXRlS2V5RXhwb25lbnQxKS50b0hleCgpOwogIGRRID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5wcml2YXRlS2V5RXhwb25lbnQyKS50b0hleCgpOwogIHFJbnYgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLnByaXZhdGVLZXlDb2VmZmljaWVudCkudG9IZXgoKTsKCiAgLy8gc2V0IHByaXZhdGUga2V5CiAgcmV0dXJuIHBraS5zZXRSc2FQcml2YXRlS2V5KAogICAgbmV3IEJpZ0ludGVnZXIobiwgMTYpLAogICAgbmV3IEJpZ0ludGVnZXIoZSwgMTYpLAogICAgbmV3IEJpZ0ludGVnZXIoZCwgMTYpLAogICAgbmV3IEJpZ0ludGVnZXIocCwgMTYpLAogICAgbmV3IEJpZ0ludGVnZXIocSwgMTYpLAogICAgbmV3IEJpZ0ludGVnZXIoZFAsIDE2KSwKICAgIG5ldyBCaWdJbnRlZ2VyKGRRLCAxNiksCiAgICBuZXcgQmlnSW50ZWdlcihxSW52LCAxNikpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgcHJpdmF0ZSBrZXkgdG8gYW4gQVNOLjEgUlNBUHJpdmF0ZUtleS4KICoKICogQHBhcmFtIGtleSB0aGUgcHJpdmF0ZSBrZXkuCiAqCiAqIEByZXR1cm4gdGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIGFuIFJTQVByaXZhdGVLZXkuCiAqLwpwa2kucHJpdmF0ZUtleVRvQXNuMSA9IHBraS5wcml2YXRlS2V5VG9SU0FQcml2YXRlS2V5ID0gZnVuY3Rpb24oa2V5KSB7CiAgLy8gUlNBUHJpdmF0ZUtleQogIHJldHVybiBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAvLyB2ZXJzaW9uICgwID0gb25seSAyIHByaW1lcywgMSBtdWx0aXBsZSBwcmltZXMpCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBhc24xLmludGVnZXJUb0RlcigwKS5nZXRCeXRlcygpKSwKICAgIC8vIG1vZHVsdXMgKG4pCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5uKSksCiAgICAvLyBwdWJsaWNFeHBvbmVudCAoZSkKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgIF9iblRvQnl0ZXMoa2V5LmUpKSwKICAgIC8vIHByaXZhdGVFeHBvbmVudCAoZCkKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgIF9iblRvQnl0ZXMoa2V5LmQpKSwKICAgIC8vIHByaXZhdGVLZXlQcmltZTEgKHApCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5wKSksCiAgICAvLyBwcml2YXRlS2V5UHJpbWUyIChxKQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgX2JuVG9CeXRlcyhrZXkucSkpLAogICAgLy8gcHJpdmF0ZUtleUV4cG9uZW50MSAoZFApCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5kUCkpLAogICAgLy8gcHJpdmF0ZUtleUV4cG9uZW50MiAoZFEpCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5kUSkpLAogICAgLy8gY29lZmZpY2llbnQgKHFJbnYpCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5xSW52KSkKICBdKTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhIHB1YmxpYyBrZXkgZnJvbSBhbiBBU04uMSBTdWJqZWN0UHVibGljS2V5SW5mbyBvciBSU0FQdWJsaWNLZXkuCiAqCiAqIEBwYXJhbSBvYmogdGhlIGFzbjEgcmVwcmVzZW50YXRpb24gb2YgYSBTdWJqZWN0UHVibGljS2V5SW5mbyBvciBSU0FQdWJsaWNLZXkuCiAqCiAqIEByZXR1cm4gdGhlIHB1YmxpYyBrZXkuCiAqLwpwa2kucHVibGljS2V5RnJvbUFzbjEgPSBmdW5jdGlvbihvYmopIHsKICAvLyBnZXQgU3ViamVjdFB1YmxpY0tleUluZm8KICB2YXIgY2FwdHVyZSA9IHt9OwogIHZhciBlcnJvcnMgPSBbXTsKICBpZihhc24xLnZhbGlkYXRlKG9iaiwgcHVibGljS2V5VmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICAvLyBnZXQgb2lkCiAgICB2YXIgb2lkID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLnB1YmxpY0tleU9pZCk7CiAgICBpZihvaWQgIT09IHBraS5vaWRzLnJzYUVuY3J5cHRpb24pIHsKICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBwdWJsaWMga2V5LiBVbmtub3duIE9JRC4nKTsKICAgICAgZXJyb3Iub2lkID0gb2lkOwogICAgICB0aHJvdyBlcnJvcjsKICAgIH0KICAgIG9iaiA9IGNhcHR1cmUucnNhUHVibGljS2V5OwogIH0KCiAgLy8gZ2V0IFJTQSBwYXJhbXMKICBlcnJvcnMgPSBbXTsKICBpZighYXNuMS52YWxpZGF0ZShvYmosIHJzYVB1YmxpY0tleVZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBwdWJsaWMga2V5LiAnICsKICAgICAgJ0FTTi4xIG9iamVjdCBkb2VzIG5vdCBjb250YWluIGFuIFJTQVB1YmxpY0tleS4nKTsKICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gRklYTUU6IGluZWZmaWNpZW50LCBnZXQgYSBCaWdJbnRlZ2VyIHRoYXQgdXNlcyBieXRlIHN0cmluZ3MKICB2YXIgbiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUucHVibGljS2V5TW9kdWx1cykudG9IZXgoKTsKICB2YXIgZSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUucHVibGljS2V5RXhwb25lbnQpLnRvSGV4KCk7CgogIC8vIHNldCBwdWJsaWMga2V5CiAgcmV0dXJuIHBraS5zZXRSc2FQdWJsaWNLZXkoCiAgICBuZXcgQmlnSW50ZWdlcihuLCAxNiksCiAgICBuZXcgQmlnSW50ZWdlcihlLCAxNikpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgcHVibGljIGtleSB0byBhbiBBU04uMSBTdWJqZWN0UHVibGljS2V5SW5mby4KICoKICogQHBhcmFtIGtleSB0aGUgcHVibGljIGtleS4KICoKICogQHJldHVybiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhIFN1YmplY3RQdWJsaWNLZXlJbmZvLgogKi8KcGtpLnB1YmxpY0tleVRvQXNuMSA9IHBraS5wdWJsaWNLZXlUb1N1YmplY3RQdWJsaWNLZXlJbmZvID0gZnVuY3Rpb24oa2V5KSB7CiAgLy8gU3ViamVjdFB1YmxpY0tleUluZm8KICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgLy8gQWxnb3JpdGhtSWRlbnRpZmllcgogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAvLyBhbGdvcml0aG0KICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgIGFzbjEub2lkVG9EZXIocGtpLm9pZHMucnNhRW5jcnlwdGlvbikuZ2V0Qnl0ZXMoKSksCiAgICAgIC8vIHBhcmFtZXRlcnMgKG51bGwpCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuTlVMTCwgZmFsc2UsICcnKQogICAgXSksCiAgICAvLyBzdWJqZWN0UHVibGljS2V5CiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLkJJVFNUUklORywgZmFsc2UsIFsKICAgICAgcGtpLnB1YmxpY0tleVRvUlNBUHVibGljS2V5KGtleSkKICAgIF0pCiAgXSk7Cn07CgovKioKICogQ29udmVydHMgYSBwdWJsaWMga2V5IHRvIGFuIEFTTi4xIFJTQVB1YmxpY0tleS4KICoKICogQHBhcmFtIGtleSB0aGUgcHVibGljIGtleS4KICoKICogQHJldHVybiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhIFJTQVB1YmxpY0tleS4KICovCnBraS5wdWJsaWNLZXlUb1JTQVB1YmxpY0tleSA9IGZ1bmN0aW9uKGtleSkgewogIC8vIFJTQVB1YmxpY0tleQogIHJldHVybiBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAvLyBtb2R1bHVzIChuKQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgX2JuVG9CeXRlcyhrZXkubikpLAogICAgLy8gcHVibGljRXhwb25lbnQgKGUpCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5lKSkKICBdKTsKfTsKCi8qKgogKiBFbmNvZGVzIGEgbWVzc2FnZSB1c2luZyBQS0NTIzEgdjEuNSBwYWRkaW5nLgogKgogKiBAcGFyYW0gbSB0aGUgbWVzc2FnZSB0byBlbmNvZGUuCiAqIEBwYXJhbSBrZXkgdGhlIFJTQSBrZXkgdG8gdXNlLgogKiBAcGFyYW0gYnQgdGhlIGJsb2NrIHR5cGUgdG8gdXNlLCBpLmUuIGVpdGhlciAweDAxIChmb3Igc2lnbmluZykgb3IgMHgwMgogKiAgICAgICAgICAoZm9yIGVuY3J5cHRpb24pLgogKgogKiBAcmV0dXJuIHRoZSBwYWRkZWQgYnl0ZSBidWZmZXIuCiAqLwpmdW5jdGlvbiBfZW5jb2RlUGtjczFfdjFfNShtLCBrZXksIGJ0KSB7CiAgdmFyIGViID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKCiAgLy8gZ2V0IHRoZSBsZW5ndGggb2YgdGhlIG1vZHVsdXMgaW4gYnl0ZXMKICB2YXIgayA9IE1hdGguY2VpbChrZXkubi5iaXRMZW5ndGgoKSAvIDgpOwoKICAvKiB1c2UgUEtDUyMxIHYxLjUgcGFkZGluZyAqLwogIGlmKG0ubGVuZ3RoID4gKGsgLSAxMSkpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignTWVzc2FnZSBpcyB0b28gbG9uZyBmb3IgUEtDUyMxIHYxLjUgcGFkZGluZy4nKTsKICAgIGVycm9yLmxlbmd0aCA9IG0ubGVuZ3RoOwogICAgZXJyb3IubWF4ID0gayAtIDExOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICAvKiBBIGJsb2NrIHR5cGUgQlQsIGEgcGFkZGluZyBzdHJpbmcgUFMsIGFuZCB0aGUgZGF0YSBEIHNoYWxsIGJlCiAgICBmb3JtYXR0ZWQgaW50byBhbiBvY3RldCBzdHJpbmcgRUIsIHRoZSBlbmNyeXB0aW9uIGJsb2NrOgoKICAgIEVCID0gMDAgfHwgQlQgfHwgUFMgfHwgMDAgfHwgRAoKICAgIFRoZSBibG9jayB0eXBlIEJUIHNoYWxsIGJlIGEgc2luZ2xlIG9jdGV0IGluZGljYXRpbmcgdGhlIHN0cnVjdHVyZSBvZgogICAgdGhlIGVuY3J5cHRpb24gYmxvY2suIEZvciB0aGlzIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50IGl0IHNoYWxsIGhhdmUKICAgIHZhbHVlIDAwLCAwMSwgb3IgMDIuIEZvciBhIHByaXZhdGUta2V5IG9wZXJhdGlvbiwgdGhlIGJsb2NrIHR5cGUKICAgIHNoYWxsIGJlIDAwIG9yIDAxLiBGb3IgYSBwdWJsaWMta2V5IG9wZXJhdGlvbiwgaXQgc2hhbGwgYmUgMDIuCgogICAgVGhlIHBhZGRpbmcgc3RyaW5nIFBTIHNoYWxsIGNvbnNpc3Qgb2Ygay0zLXx8RHx8IG9jdGV0cy4gRm9yIGJsb2NrCiAgICB0eXBlIDAwLCB0aGUgb2N0ZXRzIHNoYWxsIGhhdmUgdmFsdWUgMDA7IGZvciBibG9jayB0eXBlIDAxLCB0aGV5CiAgICBzaGFsbCBoYXZlIHZhbHVlIEZGOyBhbmQgZm9yIGJsb2NrIHR5cGUgMDIsIHRoZXkgc2hhbGwgYmUKICAgIHBzZXVkb3JhbmRvbWx5IGdlbmVyYXRlZCBhbmQgbm9uemVyby4gVGhpcyBtYWtlcyB0aGUgbGVuZ3RoIG9mIHRoZQogICAgZW5jcnlwdGlvbiBibG9jayBFQiBlcXVhbCB0byBrLiAqLwoKICAvLyBidWlsZCB0aGUgZW5jcnlwdGlvbiBibG9jawogIGViLnB1dEJ5dGUoMHgwMCk7CiAgZWIucHV0Qnl0ZShidCk7CgogIC8vIGNyZWF0ZSB0aGUgcGFkZGluZwogIHZhciBwYWROdW0gPSBrIC0gMyAtIG0ubGVuZ3RoOwogIHZhciBwYWRCeXRlOwogIC8vIHByaXZhdGUga2V5IG9wCiAgaWYoYnQgPT09IDB4MDAgfHwgYnQgPT09IDB4MDEpIHsKICAgIHBhZEJ5dGUgPSAoYnQgPT09IDB4MDApID8gMHgwMCA6IDB4RkY7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgcGFkTnVtOyArK2kpIHsKICAgICAgZWIucHV0Qnl0ZShwYWRCeXRlKTsKICAgIH0KICB9IGVsc2UgewogICAgLy8gcHVibGljIGtleSBvcAogICAgLy8gcGFkIHdpdGggcmFuZG9tIG5vbi16ZXJvIHZhbHVlcwogICAgd2hpbGUocGFkTnVtID4gMCkgewogICAgICB2YXIgbnVtWmVyb3MgPSAwOwogICAgICB2YXIgcGFkQnl0ZXMgPSBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMocGFkTnVtKTsKICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHBhZE51bTsgKytpKSB7CiAgICAgICAgcGFkQnl0ZSA9IHBhZEJ5dGVzLmNoYXJDb2RlQXQoaSk7CiAgICAgICAgaWYocGFkQnl0ZSA9PT0gMCkgewogICAgICAgICAgKytudW1aZXJvczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZWIucHV0Qnl0ZShwYWRCeXRlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcGFkTnVtID0gbnVtWmVyb3M7CiAgICB9CiAgfQoKICAvLyB6ZXJvIGZvbGxvd2VkIGJ5IG1lc3NhZ2UKICBlYi5wdXRCeXRlKDB4MDApOwogIGViLnB1dEJ5dGVzKG0pOwoKICByZXR1cm4gZWI7Cn0KCi8qKgogKiBEZWNvZGVzIGEgbWVzc2FnZSB1c2luZyBQS0NTIzEgdjEuNSBwYWRkaW5nLgogKgogKiBAcGFyYW0gZW0gdGhlIG1lc3NhZ2UgdG8gZGVjb2RlLgogKiBAcGFyYW0ga2V5IHRoZSBSU0Ega2V5IHRvIHVzZS4KICogQHBhcmFtIHB1YiB0cnVlIGlmIHRoZSBrZXkgaXMgYSBwdWJsaWMga2V5LCBmYWxzZSBpZiBpdCBpcyBwcml2YXRlLgogKiBAcGFyYW0gbWwgdGhlIG1lc3NhZ2UgbGVuZ3RoLCBpZiBzcGVjaWZpZWQuCiAqCiAqIEByZXR1cm4gdGhlIGRlY29kZWQgYnl0ZXMuCiAqLwpmdW5jdGlvbiBfZGVjb2RlUGtjczFfdjFfNShlbSwga2V5LCBwdWIsIG1sKSB7CiAgLy8gZ2V0IHRoZSBsZW5ndGggb2YgdGhlIG1vZHVsdXMgaW4gYnl0ZXMKICB2YXIgayA9IE1hdGguY2VpbChrZXkubi5iaXRMZW5ndGgoKSAvIDgpOwoKICAvKiBJdCBpcyBhbiBlcnJvciBpZiBhbnkgb2YgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIG9jY3VyczoKCiAgICAxLiBUaGUgZW5jcnlwdGlvbiBibG9jayBFQiBjYW5ub3QgYmUgcGFyc2VkIHVuYW1iaWd1b3VzbHkuCiAgICAyLiBUaGUgcGFkZGluZyBzdHJpbmcgUFMgY29uc2lzdHMgb2YgZmV3ZXIgdGhhbiBlaWdodCBvY3RldHMKICAgICAgb3IgaXMgaW5jb25zaXNlbnQgd2l0aCB0aGUgYmxvY2sgdHlwZSBCVC4KICAgIDMuIFRoZSBkZWNyeXB0aW9uIHByb2Nlc3MgaXMgYSBwdWJsaWMta2V5IG9wZXJhdGlvbiBhbmQgdGhlIGJsb2NrCiAgICAgIHR5cGUgQlQgaXMgbm90IDAwIG9yIDAxLCBvciB0aGUgZGVjcnlwdGlvbiBwcm9jZXNzIGlzIGEKICAgICAgcHJpdmF0ZS1rZXkgb3BlcmF0aW9uIGFuZCB0aGUgYmxvY2sgdHlwZSBpcyBub3QgMDIuCiAgICovCgogIC8vIHBhcnNlIHRoZSBlbmNyeXB0aW9uIGJsb2NrCiAgdmFyIGViID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoZW0pOwogIHZhciBmaXJzdCA9IGViLmdldEJ5dGUoKTsKICB2YXIgYnQgPSBlYi5nZXRCeXRlKCk7CiAgaWYoZmlyc3QgIT09IDB4MDAgfHwKICAgIChwdWIgJiYgYnQgIT09IDB4MDAgJiYgYnQgIT09IDB4MDEpIHx8CiAgICAoIXB1YiAmJiBidCAhPSAweDAyKSB8fAogICAgKHB1YiAmJiBidCA9PT0gMHgwMCAmJiB0eXBlb2YobWwpID09PSAndW5kZWZpbmVkJykpIHsKICAgIHRocm93IG5ldyBFcnJvcignRW5jcnlwdGlvbiBibG9jayBpcyBpbnZhbGlkLicpOwogIH0KCiAgdmFyIHBhZE51bSA9IDA7CiAgaWYoYnQgPT09IDB4MDApIHsKICAgIC8vIGNoZWNrIGFsbCBwYWRkaW5nIGJ5dGVzIGZvciAweDAwCiAgICBwYWROdW0gPSBrIC0gMyAtIG1sOwogICAgZm9yKHZhciBpID0gMDsgaSA8IHBhZE51bTsgKytpKSB7CiAgICAgIGlmKGViLmdldEJ5dGUoKSAhPT0gMHgwMCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcignRW5jcnlwdGlvbiBibG9jayBpcyBpbnZhbGlkLicpOwogICAgICB9CiAgICB9CiAgfSBlbHNlIGlmKGJ0ID09PSAweDAxKSB7CiAgICAvLyBmaW5kIHRoZSBmaXJzdCBieXRlIHRoYXQgaXNuJ3QgMHhGRiwgc2hvdWxkIGJlIGFmdGVyIGFsbCBwYWRkaW5nCiAgICBwYWROdW0gPSAwOwogICAgd2hpbGUoZWIubGVuZ3RoKCkgPiAxKSB7CiAgICAgIGlmKGViLmdldEJ5dGUoKSAhPT0gMHhGRikgewogICAgICAgIC0tZWIucmVhZDsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICArK3BhZE51bTsKICAgIH0KICB9IGVsc2UgaWYoYnQgPT09IDB4MDIpIHsKICAgIC8vIGxvb2sgZm9yIDB4MDAgYnl0ZQogICAgcGFkTnVtID0gMDsKICAgIHdoaWxlKGViLmxlbmd0aCgpID4gMSkgewogICAgICBpZihlYi5nZXRCeXRlKCkgPT09IDB4MDApIHsKICAgICAgICAtLWViLnJlYWQ7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgKytwYWROdW07CiAgICB9CiAgfQoKICAvLyB6ZXJvIG11c3QgYmUgMHgwMCBhbmQgcGFkTnVtIG11c3QgYmUgKGsgLSAzIC0gbWVzc2FnZSBsZW5ndGgpCiAgdmFyIHplcm8gPSBlYi5nZXRCeXRlKCk7CiAgaWYoemVybyAhPT0gMHgwMCB8fCBwYWROdW0gIT09IChrIC0gMyAtIGViLmxlbmd0aCgpKSkgewogICAgdGhyb3cgbmV3IEVycm9yKCdFbmNyeXB0aW9uIGJsb2NrIGlzIGludmFsaWQuJyk7CiAgfQoKICByZXR1cm4gZWIuZ2V0Qnl0ZXMoKTsKfQoKLyoqCiAqIFJ1bnMgdGhlIGtleS1nZW5lcmF0aW9uIGFsZ29yaXRobSBhc3luY2hyb25vdXNseSwgZWl0aGVyIGluIHRoZSBiYWNrZ3JvdW5kCiAqIHZpYSBXZWIgV29ya2Vycywgb3IgdXNpbmcgdGhlIG1haW4gdGhyZWFkIGFuZCBzZXRJbW1lZGlhdGUuCiAqCiAqIEBwYXJhbSBzdGF0ZSB0aGUga2V5LXBhaXIgZ2VuZXJhdGlvbiBzdGF0ZS4KICogQHBhcmFtIFtvcHRpb25zXSBvcHRpb25zIGZvciBrZXktcGFpciBnZW5lcmF0aW9uOgogKiAgICAgICAgICB3b3JrZXJTY3JpcHQgdGhlIHdvcmtlciBzY3JpcHQgVVJMLgogKiAgICAgICAgICB3b3JrZXJzIHRoZSBudW1iZXIgb2Ygd2ViIHdvcmtlcnMgKGlmIHN1cHBvcnRlZCkgdG8gdXNlLAogKiAgICAgICAgICAgIChkZWZhdWx0OiAyLCAtMSB0byB1c2UgZXN0aW1hdGVkIGNvcmVzIG1pbnVzIG9uZSkuCiAqICAgICAgICAgIHdvcmtMb2FkIHRoZSBzaXplIG9mIHRoZSB3b3JrIGxvYWQsIGllOiBudW1iZXIgb2YgcG9zc2libGUgcHJpbWUKICogICAgICAgICAgICBudW1iZXJzIGZvciBlYWNoIHdlYiB3b3JrZXIgdG8gY2hlY2sgcGVyIHdvcmsgYXNzaWdubWVudCwKICogICAgICAgICAgICAoZGVmYXVsdDogMTAwKS4KICogQHBhcmFtIGNhbGxiYWNrKGVyciwga2V5cGFpcikgY2FsbGVkIG9uY2UgdGhlIG9wZXJhdGlvbiBjb21wbGV0ZXMuCiAqLwpmdW5jdGlvbiBfZ2VuZXJhdGVLZXlQYWlyKHN0YXRlLCBvcHRpb25zLCBjYWxsYmFjaykgewogIGlmKHR5cGVvZiBvcHRpb25zID09PSAnZnVuY3Rpb24nKSB7CiAgICBjYWxsYmFjayA9IG9wdGlvbnM7CiAgICBvcHRpb25zID0ge307CiAgfQogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwoKICB2YXIgb3B0cyA9IHsKICAgIGFsZ29yaXRobTogewogICAgICBuYW1lOiBvcHRpb25zLmFsZ29yaXRobSB8fCAnUFJJTUVJTkMnLAogICAgICBvcHRpb25zOiB7CiAgICAgICAgd29ya2Vyczogb3B0aW9ucy53b3JrZXJzIHx8IDIsCiAgICAgICAgd29ya0xvYWQ6IG9wdGlvbnMud29ya0xvYWQgfHwgMTAwLAogICAgICAgIHdvcmtlclNjcmlwdDogb3B0aW9ucy53b3JrZXJTY3JpcHQKICAgICAgfQogICAgfQogIH07CiAgaWYoJ3BybmcnIGluIG9wdGlvbnMpIHsKICAgIG9wdHMucHJuZyA9IG9wdGlvbnMucHJuZzsKICB9CgogIGdlbmVyYXRlKCk7CgogIGZ1bmN0aW9uIGdlbmVyYXRlKCkgewogICAgLy8gZmluZCBwIGFuZCB0aGVuIHEgKGRvbmUgaW4gc2VyaWVzIHRvIHNpbXBsaWZ5KQogICAgZ2V0UHJpbWUoc3RhdGUucEJpdHMsIGZ1bmN0aW9uKGVyciwgbnVtKSB7CiAgICAgIGlmKGVycikgewogICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpOwogICAgICB9CiAgICAgIHN0YXRlLnAgPSBudW07CiAgICAgIGlmKHN0YXRlLnEgIT09IG51bGwpIHsKICAgICAgICByZXR1cm4gZmluaXNoKGVyciwgc3RhdGUucSk7CiAgICAgIH0KICAgICAgZ2V0UHJpbWUoc3RhdGUucUJpdHMsIGZpbmlzaCk7CiAgICB9KTsKICB9CgogIGZ1bmN0aW9uIGdldFByaW1lKGJpdHMsIGNhbGxiYWNrKSB7CiAgICBmb3JnZS5wcmltZS5nZW5lcmF0ZVByb2JhYmxlUHJpbWUoYml0cywgb3B0cywgY2FsbGJhY2spOwogIH0KCiAgZnVuY3Rpb24gZmluaXNoKGVyciwgbnVtKSB7CiAgICBpZihlcnIpIHsKICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7CiAgICB9CgogICAgLy8gc2V0IHEKICAgIHN0YXRlLnEgPSBudW07CgogICAgLy8gZW5zdXJlIHAgaXMgbGFyZ2VyIHRoYW4gcSAoc3dhcCB0aGVtIGlmIG5vdCkKICAgIGlmKHN0YXRlLnAuY29tcGFyZVRvKHN0YXRlLnEpIDwgMCkgewogICAgICB2YXIgdG1wID0gc3RhdGUucDsKICAgICAgc3RhdGUucCA9IHN0YXRlLnE7CiAgICAgIHN0YXRlLnEgPSB0bXA7CiAgICB9CgogICAgLy8gZW5zdXJlIHAgaXMgY29wcmltZSB3aXRoIGUKICAgIGlmKHN0YXRlLnAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpLmdjZChzdGF0ZS5lKQogICAgICAuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPT0gMCkgewogICAgICBzdGF0ZS5wID0gbnVsbDsKICAgICAgZ2VuZXJhdGUoKTsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIGVuc3VyZSBxIGlzIGNvcHJpbWUgd2l0aCBlCiAgICBpZihzdGF0ZS5xLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKS5nY2Qoc3RhdGUuZSkKICAgICAgLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT09IDApIHsKICAgICAgc3RhdGUucSA9IG51bGw7CiAgICAgIGdldFByaW1lKHN0YXRlLnFCaXRzLCBmaW5pc2gpOwogICAgICByZXR1cm47CiAgICB9CgogICAgLy8gY29tcHV0ZSBwaGk6IChwIC0gMSkocSAtIDEpIChFdWxlcidzIHRvdGllbnQgZnVuY3Rpb24pCiAgICBzdGF0ZS5wMSA9IHN0YXRlLnAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpOwogICAgc3RhdGUucTEgPSBzdGF0ZS5xLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTsKICAgIHN0YXRlLnBoaSA9IHN0YXRlLnAxLm11bHRpcGx5KHN0YXRlLnExKTsKCiAgICAvLyBlbnN1cmUgZSBhbmQgcGhpIGFyZSBjb3ByaW1lCiAgICBpZihzdGF0ZS5waGkuZ2NkKHN0YXRlLmUpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT09IDApIHsKICAgICAgLy8gcGhpIGFuZCBlIGFyZW4ndCBjb3ByaW1lLCBzbyBnZW5lcmF0ZSBhIG5ldyBwIGFuZCBxCiAgICAgIHN0YXRlLnAgPSBzdGF0ZS5xID0gbnVsbDsKICAgICAgZ2VuZXJhdGUoKTsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIGNyZWF0ZSBuLCBlbnN1cmUgbiBpcyBoYXMgdGhlIHJpZ2h0IG51bWJlciBvZiBiaXRzCiAgICBzdGF0ZS5uID0gc3RhdGUucC5tdWx0aXBseShzdGF0ZS5xKTsKICAgIGlmKHN0YXRlLm4uYml0TGVuZ3RoKCkgIT09IHN0YXRlLmJpdHMpIHsKICAgICAgLy8gZmFpbGVkLCBnZXQgbmV3IHEKICAgICAgc3RhdGUucSA9IG51bGw7CiAgICAgIGdldFByaW1lKHN0YXRlLnFCaXRzLCBmaW5pc2gpOwogICAgICByZXR1cm47CiAgICB9CgogICAgLy8gc2V0IGtleXMKICAgIHZhciBkID0gc3RhdGUuZS5tb2RJbnZlcnNlKHN0YXRlLnBoaSk7CiAgICBzdGF0ZS5rZXlzID0gewogICAgICBwcml2YXRlS2V5OiBwa2kucnNhLnNldFByaXZhdGVLZXkoCiAgICAgICAgc3RhdGUubiwgc3RhdGUuZSwgZCwgc3RhdGUucCwgc3RhdGUucSwKICAgICAgICBkLm1vZChzdGF0ZS5wMSksIGQubW9kKHN0YXRlLnExKSwKICAgICAgICBzdGF0ZS5xLm1vZEludmVyc2Uoc3RhdGUucCkpLAogICAgICBwdWJsaWNLZXk6IHBraS5yc2Euc2V0UHVibGljS2V5KHN0YXRlLm4sIHN0YXRlLmUpCiAgICB9OwoKICAgIGNhbGxiYWNrKG51bGwsIHN0YXRlLmtleXMpOwogIH0KfQoKLyoqCiAqIENvbnZlcnRzIGEgcG9zaXRpdmUgQmlnSW50ZWdlciBpbnRvIDIncy1jb21wbGVtZW50IGJpZy1lbmRpYW4gYnl0ZXMuCiAqCiAqIEBwYXJhbSBiIHRoZSBiaWcgaW50ZWdlciB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBieXRlcy4KICovCmZ1bmN0aW9uIF9iblRvQnl0ZXMoYikgewogIC8vIHByZXBlbmQgMHgwMCBpZiBmaXJzdCBieXRlID49IDB4ODAKICB2YXIgaGV4ID0gYi50b1N0cmluZygxNik7CiAgaWYoaGV4WzBdID49ICc4JykgewogICAgaGV4ID0gJzAwJyArIGhleDsKICB9CiAgcmV0dXJuIGZvcmdlLnV0aWwuaGV4VG9CeXRlcyhoZXgpOwp9CgovKioKICogUmV0dXJucyB0aGUgcmVxdWlyZWQgbnVtYmVyIG9mIE1pbGxlci1SYWJpbiB0ZXN0cyB0byBnZW5lcmF0ZSBhCiAqIHByaW1lIHdpdGggYW4gZXJyb3IgcHJvYmFiaWxpdHkgb2YgKDEvMileODAuCiAqCiAqIFNlZSBIYW5kYm9vayBvZiBBcHBsaWVkIENyeXB0b2dyYXBoeSBDaGFwdGVyIDQsIFRhYmxlIDQuNC4KICoKICogQHBhcmFtIGJpdHMgdGhlIGJpdCBzaXplLgogKgogKiBAcmV0dXJuIHRoZSByZXF1aXJlZCBudW1iZXIgb2YgaXRlcmF0aW9ucy4KICovCmZ1bmN0aW9uIF9nZXRNaWxsZXJSYWJpblRlc3RzKGJpdHMpIHsKICBpZihiaXRzIDw9IDEwMCkgcmV0dXJuIDI3OwogIGlmKGJpdHMgPD0gMTUwKSByZXR1cm4gMTg7CiAgaWYoYml0cyA8PSAyMDApIHJldHVybiAxNTsKICBpZihiaXRzIDw9IDI1MCkgcmV0dXJuIDEyOwogIGlmKGJpdHMgPD0gMzAwKSByZXR1cm4gOTsKICBpZihiaXRzIDw9IDM1MCkgcmV0dXJuIDg7CiAgaWYoYml0cyA8PSA0MDApIHJldHVybiA3OwogIGlmKGJpdHMgPD0gNTAwKSByZXR1cm4gNjsKICBpZihiaXRzIDw9IDYwMCkgcmV0dXJuIDU7CiAgaWYoYml0cyA8PSA4MDApIHJldHVybiA0OwogIGlmKGJpdHMgPD0gMTI1MCkgcmV0dXJuIDM7CiAgcmV0dXJuIDI7Cn0KCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3JzYSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9yc2EnLFsKICAncmVxdWlyZScsCiAgJ21vZHVsZScsCiAgJy4vYXNuMScsCiAgJy4vanNibicsCiAgJy4vb2lkcycsCiAgJy4vcGtjczEnLAogICcuL3ByaW1lJywKICAnLi9yYW5kb20nLAogICcuL3V0aWwnCl0sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFBhc3N3b3JkLWJhc2VkIGVuY3J5cHRpb24gZnVuY3Rpb25zLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKiBAYXV0aG9yIFN0ZWZhbiBTaWVnbCA8c3Rlc2llQGJyb2tlbnBpcGUuZGU+CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDEzIERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqIENvcHlyaWdodCAoYykgMjAxMiBTdGVmYW4gU2llZ2wgPHN0ZXNpZUBicm9rZW5waXBlLmRlPgogKgogKiBBbiBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbzoKICoKICogRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gOjo9IFNFUVVFTkNFIHsKICogICBlbmNyeXB0aW9uQWxnb3JpdGhtICBFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciwKICogICBlbmNyeXB0ZWREYXRhICAgICAgICBFbmNyeXB0ZWREYXRhIH0KICoKICogRW5jcnlwdGlvbkFsZ29yaXRobUlkZW50aWZpZXIgOjo9IEFsZ29yaXRobUlkZW50aWZpZXIKICoKICogRW5jcnlwdGVkRGF0YSA6Oj0gT0NURVQgU1RSSU5HCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKaWYodHlwZW9mIEJpZ0ludGVnZXIgPT09ICd1bmRlZmluZWQnKSB7CiAgdmFyIEJpZ0ludGVnZXIgPSBmb3JnZS5qc2JuLkJpZ0ludGVnZXI7Cn0KCi8vIHNob3J0Y3V0IGZvciBhc24uMSBBUEkKdmFyIGFzbjEgPSBmb3JnZS5hc24xOwoKLyogUGFzc3dvcmQtYmFzZWQgZW5jcnlwdGlvbiBpbXBsZW1lbnRhdGlvbi4gKi8KdmFyIHBraSA9IGZvcmdlLnBraSA9IGZvcmdlLnBraSB8fCB7fTsKcGtpLnBiZSA9IGZvcmdlLnBiZSA9IGZvcmdlLnBiZSB8fCB7fTsKdmFyIG9pZHMgPSBwa2kub2lkczsKCi8vIHZhbGlkYXRvciBmb3IgYW4gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gc3RydWN0dXJlCi8vIE5vdGU6IEN1cnJlbnRseSBvbmx5IHdvcmtzIHcvYWxnb3JpdGhtIHBhcmFtcwp2YXIgZW5jcnlwdGVkUHJpdmF0ZUtleVZhbGlkYXRvciA9IHsKICBuYW1lOiAnRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8nLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uZW5jcnlwdGlvbkFsZ29yaXRobScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnQWxnb3JpdGhtSWRlbnRpZmllci5hbGdvcml0aG0nLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5PSUQsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ2VuY3J5cHRpb25PaWQnCiAgICB9LCB7CiAgICAgIG5hbWU6ICdBbGdvcml0aG1JZGVudGlmaWVyLnBhcmFtZXRlcnMnLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIGNhcHR1cmVBc24xOiAnZW5jcnlwdGlvblBhcmFtcycKICAgIH1dCiAgfSwgewogICAgLy8gZW5jcnlwdGVkRGF0YQogICAgbmFtZTogJ0VuY3J5cHRlZFByaXZhdGVLZXlJbmZvLmVuY3J5cHRlZERhdGEnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ2VuY3J5cHRlZERhdGEnCiAgfV0KfTsKCi8vIHZhbGlkYXRvciBmb3IgYSBQQkVTMkFsZ29yaXRobXMgc3RydWN0dXJlCi8vIE5vdGU6IEN1cnJlbnRseSBvbmx5IHdvcmtzIHcvUEJLREYyICsgQUVTIGVuY3J5cHRpb24gc2NoZW1lcwp2YXIgUEJFUzJBbGdvcml0aG1zVmFsaWRhdG9yID0gewogIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnUEJFUzJBbGdvcml0aG1zLmtleURlcml2YXRpb25GdW5jJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMua2V5RGVyaXZhdGlvbkZ1bmMub2lkJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdrZGZPaWQnCiAgICB9LCB7CiAgICAgIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMucGFyYW1zJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgICB2YWx1ZTogW3sKICAgICAgICBuYW1lOiAnUEJFUzJBbGdvcml0aG1zLnBhcmFtcy5zYWx0JywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBjYXB0dXJlOiAna2RmU2FsdCcKICAgICAgfSwgewogICAgICAgIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMucGFyYW1zLml0ZXJhdGlvbkNvdW50JywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgICAgb25zdHJ1Y3RlZDogdHJ1ZSwKICAgICAgICBjYXB0dXJlOiAna2RmSXRlcmF0aW9uQ291bnQnCiAgICAgIH1dCiAgICB9XQogIH0sIHsKICAgIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMuZW5jcnlwdGlvblNjaGVtZScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnUEJFUzJBbGdvcml0aG1zLmVuY3J5cHRpb25TY2hlbWUub2lkJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdlbmNPaWQnCiAgICB9LCB7CiAgICAgIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMuZW5jcnlwdGlvblNjaGVtZS5pdicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdlbmNJdicKICAgIH1dCiAgfV0KfTsKCnZhciBwa2NzMTJQYmVQYXJhbXNWYWxpZGF0b3IgPSB7CiAgbmFtZTogJ3BrY3MtMTJQYmVQYXJhbXMnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAncGtjcy0xMlBiZVBhcmFtcy5zYWx0JywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5PQ1RFVFNUUklORywKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdzYWx0JwogIH0sIHsKICAgIG5hbWU6ICdwa2NzLTEyUGJlUGFyYW1zLml0ZXJhdGlvbnMnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAnaXRlcmF0aW9ucycKICB9XQp9OwoKLyoqCiAqIEVuY3J5cHRzIGEgQVNOLjEgUHJpdmF0ZUtleUluZm8gb2JqZWN0LCBwcm9kdWNpbmcgYW4gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uCiAqCiAqIFBCRVMyQWxnb3JpdGhtcyBBTEdPUklUSE0tSURFTlRJRklFUiA6Oj0KICogICB7IHtQQkVTMi1wYXJhbXMgSURFTlRJRklFRCBCWSBpZC1QQkVTMn0sIC4uLn0KICoKICogaWQtUEJFUzIgT0JKRUNUIElERU5USUZJRVIgOjo9IHtwa2NzLTUgMTN9CiAqCiAqIFBCRVMyLXBhcmFtcyA6Oj0gU0VRVUVOQ0UgewogKiAgIGtleURlcml2YXRpb25GdW5jIEFsZ29yaXRobUlkZW50aWZpZXIge3tQQkVTMi1LREZzfX0sCiAqICAgZW5jcnlwdGlvblNjaGVtZSBBbGdvcml0aG1JZGVudGlmaWVyIHt7UEJFUzItRW5jc319CiAqIH0KICoKICogUEJFUzItS0RGcyBBTEdPUklUSE0tSURFTlRJRklFUiA6Oj0KICogICB7IHtQQktERjItcGFyYW1zIElERU5USUZJRUQgQlkgaWQtUEJLREYyfSwgLi4uIH0KICoKICogUEJFUzItRW5jcyBBTEdPUklUSE0tSURFTlRJRklFUiA6Oj0geyAuLi4gfQogKgogKiBQQktERjItcGFyYW1zIDo6PSBTRVFVRU5DRSB7CiAqICAgc2FsdCBDSE9JQ0UgewogKiAgICAgc3BlY2lmaWVkIE9DVEVUIFNUUklORywKICogICAgIG90aGVyU291cmNlIEFsZ29yaXRobUlkZW50aWZpZXIge3tQQktERjItU2FsdFNvdXJjZXN9fQogKiAgIH0sCiAqICAgaXRlcmF0aW9uQ291bnQgSU5URUdFUiAoMS4uTUFYKSwKICogICBrZXlMZW5ndGggSU5URUdFUiAoMS4uTUFYKSBPUFRJT05BTCwKICogICBwcmYgQWxnb3JpdGhtSWRlbnRpZmllciB7e1BCS0RGMi1QUkZzfX0gREVGQVVMVCBhbGdpZC1obWFjV2l0aFNIQTEKICogfQogKgogKiBAcGFyYW0gb2JqIHRoZSBBU04uMSBQcml2YXRlS2V5SW5mbyBvYmplY3QuCiAqIEBwYXJhbSBwYXNzd29yZCB0aGUgcGFzc3dvcmQgdG8gZW5jcnlwdCB3aXRoLgogKiBAcGFyYW0gb3B0aW9uczoKICogICAgICAgICAgYWxnb3JpdGhtIHRoZSBlbmNyeXB0aW9uIGFsZ29yaXRobSB0byB1c2UKICogICAgICAgICAgICAoJ2FlczEyOCcsICdhZXMxOTInLCAnYWVzMjU2JywgJzNkZXMnKSwgZGVmYXVsdHMgdG8gJ2FlczEyOCcuCiAqICAgICAgICAgIGNvdW50IHRoZSBpdGVyYXRpb24gY291bnQgdG8gdXNlLgogKiAgICAgICAgICBzYWx0U2l6ZSB0aGUgc2FsdCBzaXplIHRvIHVzZS4KICoKICogQHJldHVybiB0aGUgQVNOLjEgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uCiAqLwpwa2kuZW5jcnlwdFByaXZhdGVLZXlJbmZvID0gZnVuY3Rpb24ob2JqLCBwYXNzd29yZCwgb3B0aW9ucykgewogIC8vIHNldCBkZWZhdWx0IG9wdGlvbnMKICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICBvcHRpb25zLnNhbHRTaXplID0gb3B0aW9ucy5zYWx0U2l6ZSB8fCA4OwogIG9wdGlvbnMuY291bnQgPSBvcHRpb25zLmNvdW50IHx8IDIwNDg7CiAgb3B0aW9ucy5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobSB8fCAnYWVzMTI4JzsKCiAgLy8gZ2VuZXJhdGUgUEJFIHBhcmFtcwogIHZhciBzYWx0ID0gZm9yZ2UucmFuZG9tLmdldEJ5dGVzU3luYyhvcHRpb25zLnNhbHRTaXplKTsKICB2YXIgY291bnQgPSBvcHRpb25zLmNvdW50OwogIHZhciBjb3VudEJ5dGVzID0gYXNuMS5pbnRlZ2VyVG9EZXIoY291bnQpOwogIHZhciBka0xlbjsKICB2YXIgZW5jcnlwdGlvbkFsZ29yaXRobTsKICB2YXIgZW5jcnlwdGVkRGF0YTsKICBpZihvcHRpb25zLmFsZ29yaXRobS5pbmRleE9mKCdhZXMnKSA9PT0gMCB8fCBvcHRpb25zLmFsZ29yaXRobSA9PT0gJ2RlcycpIHsKICAgIC8vIERvIFBCRVMyCiAgICB2YXIgaXZMZW4sIGVuY09pZCwgY2lwaGVyRm47CiAgICBzd2l0Y2gob3B0aW9ucy5hbGdvcml0aG0pIHsKICAgIGNhc2UgJ2FlczEyOCc6CiAgICAgIGRrTGVuID0gMTY7CiAgICAgIGl2TGVuID0gMTY7CiAgICAgIGVuY09pZCA9IG9pZHNbJ2FlczEyOC1DQkMnXTsKICAgICAgY2lwaGVyRm4gPSBmb3JnZS5hZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgICAgYnJlYWs7CiAgICBjYXNlICdhZXMxOTInOgogICAgICBka0xlbiA9IDI0OwogICAgICBpdkxlbiA9IDE2OwogICAgICBlbmNPaWQgPSBvaWRzWydhZXMxOTItQ0JDJ107CiAgICAgIGNpcGhlckZuID0gZm9yZ2UuYWVzLmNyZWF0ZUVuY3J5cHRpb25DaXBoZXI7CiAgICAgIGJyZWFrOwogICAgY2FzZSAnYWVzMjU2JzoKICAgICAgZGtMZW4gPSAzMjsKICAgICAgaXZMZW4gPSAxNjsKICAgICAgZW5jT2lkID0gb2lkc1snYWVzMjU2LUNCQyddOwogICAgICBjaXBoZXJGbiA9IGZvcmdlLmFlcy5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyOwogICAgICBicmVhazsKICAgIGNhc2UgJ2Rlcyc6CiAgICAgIGRrTGVuID0gODsKICAgICAgaXZMZW4gPSA4OwogICAgICBlbmNPaWQgPSBvaWRzWydkZXNDQkMnXTsKICAgICAgY2lwaGVyRm4gPSBmb3JnZS5kZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCBlbmNyeXB0IHByaXZhdGUga2V5LiBVbmtub3duIGVuY3J5cHRpb24gYWxnb3JpdGhtLicpOwogICAgICBlcnJvci5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobTsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgLy8gZW5jcnlwdCBwcml2YXRlIGtleSB1c2luZyBwYmUgU0hBLTEgYW5kIEFFUy9ERVMKICAgIHZhciBkayA9IGZvcmdlLnBrY3M1LnBia2RmMihwYXNzd29yZCwgc2FsdCwgY291bnQsIGRrTGVuKTsKICAgIHZhciBpdiA9IGZvcmdlLnJhbmRvbS5nZXRCeXRlc1N5bmMoaXZMZW4pOwogICAgdmFyIGNpcGhlciA9IGNpcGhlckZuKGRrKTsKICAgIGNpcGhlci5zdGFydChpdik7CiAgICBjaXBoZXIudXBkYXRlKGFzbjEudG9EZXIob2JqKSk7CiAgICBjaXBoZXIuZmluaXNoKCk7CiAgICBlbmNyeXB0ZWREYXRhID0gY2lwaGVyLm91dHB1dC5nZXRCeXRlcygpOwoKICAgIGVuY3J5cHRpb25BbGdvcml0aG0gPSBhc24xLmNyZWF0ZSgKICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgYXNuMS5vaWRUb0RlcihvaWRzWydwa2NzNVBCRVMyJ10pLmdldEJ5dGVzKCkpLAogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgLy8ga2V5RGVyaXZhdGlvbkZ1bmMKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgICAgIGFzbjEub2lkVG9EZXIob2lkc1sncGtjczVQQktERjInXSkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgICAvLyBQQktERjItcGFyYW1zCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgICAgIC8vIHNhbHQKICAgICAgICAgICAgYXNuMS5jcmVhdGUoCiAgICAgICAgICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsIHNhbHQpLAogICAgICAgICAgICAvLyBpdGVyYXRpb24gY291bnQKICAgICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgICAgICAgICBjb3VudEJ5dGVzLmdldEJ5dGVzKCkpCiAgICAgICAgICBdKQogICAgICAgIF0pLAogICAgICAgIC8vIGVuY3J5cHRpb25TY2hlbWUKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgICAgIGFzbjEub2lkVG9EZXIoZW5jT2lkKS5nZXRCeXRlcygpKSwKICAgICAgICAgIC8vIGl2CiAgICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsIGl2KQogICAgICAgIF0pCiAgICAgIF0pCiAgICBdKTsKICB9IGVsc2UgaWYob3B0aW9ucy5hbGdvcml0aG0gPT09ICczZGVzJykgewogICAgLy8gRG8gUEtDUzEyIFBCRQogICAgZGtMZW4gPSAyNDsKCiAgICB2YXIgc2FsdEJ5dGVzID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcihzYWx0KTsKICAgIHZhciBkayA9IHBraS5wYmUuZ2VuZXJhdGVQa2NzMTJLZXkocGFzc3dvcmQsIHNhbHRCeXRlcywgMSwgY291bnQsIGRrTGVuKTsKICAgIHZhciBpdiA9IHBraS5wYmUuZ2VuZXJhdGVQa2NzMTJLZXkocGFzc3dvcmQsIHNhbHRCeXRlcywgMiwgY291bnQsIGRrTGVuKTsKICAgIHZhciBjaXBoZXIgPSBmb3JnZS5kZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcihkayk7CiAgICBjaXBoZXIuc3RhcnQoaXYpOwogICAgY2lwaGVyLnVwZGF0ZShhc24xLnRvRGVyKG9iaikpOwogICAgY2lwaGVyLmZpbmlzaCgpOwogICAgZW5jcnlwdGVkRGF0YSA9IGNpcGhlci5vdXRwdXQuZ2V0Qnl0ZXMoKTsKCiAgICBlbmNyeXB0aW9uQWxnb3JpdGhtID0gYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgIGFzbjEub2lkVG9EZXIob2lkc1sncGJlV2l0aFNIQUFuZDMtS2V5VHJpcGxlREVTLUNCQyddKS5nZXRCeXRlcygpKSwKICAgICAgLy8gcGtjcy0xMlBiZVBhcmFtcwogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgLy8gc2FsdAogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLCBzYWx0KSwKICAgICAgICAvLyBpdGVyYXRpb24gY291bnQKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICAgICAgY291bnRCeXRlcy5nZXRCeXRlcygpKQogICAgICBdKQogICAgXSk7CiAgfSBlbHNlIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IGVuY3J5cHQgcHJpdmF0ZSBrZXkuIFVua25vd24gZW5jcnlwdGlvbiBhbGdvcml0aG0uJyk7CiAgICBlcnJvci5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobTsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8KICB2YXIgcnZhbCA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgIC8vIGVuY3J5cHRpb25BbGdvcml0aG0KICAgIGVuY3J5cHRpb25BbGdvcml0aG0sCiAgICAvLyBlbmNyeXB0ZWREYXRhCiAgICBhc24xLmNyZWF0ZSgKICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsIGVuY3J5cHRlZERhdGEpCiAgXSk7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogRGVjcnlwdHMgYSBBU04uMSBQcml2YXRlS2V5SW5mbyBvYmplY3QuCiAqCiAqIEBwYXJhbSBvYmogdGhlIEFTTi4xIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIG9iamVjdC4KICogQHBhcmFtIHBhc3N3b3JkIHRoZSBwYXNzd29yZCB0byBkZWNyeXB0IHdpdGguCiAqCiAqIEByZXR1cm4gdGhlIEFTTi4xIFByaXZhdGVLZXlJbmZvIG9uIHN1Y2Nlc3MsIG51bGwgb24gZmFpbHVyZS4KICovCnBraS5kZWNyeXB0UHJpdmF0ZUtleUluZm8gPSBmdW5jdGlvbihvYmosIHBhc3N3b3JkKSB7CiAgdmFyIHJ2YWwgPSBudWxsOwoKICAvLyBnZXQgUEJFIHBhcmFtcwogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgZW5jcnlwdGVkUHJpdmF0ZUtleVZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBlbmNyeXB0ZWQgcHJpdmF0ZSBrZXkuICcgKwogICAgICAnQVNOLjEgb2JqZWN0IGlzIG5vdCBhIHN1cHBvcnRlZCBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mby4nKTsKICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gZ2V0IGNpcGhlcgogIHZhciBvaWQgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUuZW5jcnlwdGlvbk9pZCk7CiAgdmFyIGNpcGhlciA9IHBraS5wYmUuZ2V0Q2lwaGVyKG9pZCwgY2FwdHVyZS5lbmNyeXB0aW9uUGFyYW1zLCBwYXNzd29yZCk7CgogIC8vIGdldCBlbmNyeXB0ZWQgZGF0YQogIHZhciBlbmNyeXB0ZWQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLmVuY3J5cHRlZERhdGEpOwoKICBjaXBoZXIudXBkYXRlKGVuY3J5cHRlZCk7CiAgaWYoY2lwaGVyLmZpbmlzaCgpKSB7CiAgICBydmFsID0gYXNuMS5mcm9tRGVyKGNpcGhlci5vdXRwdXQpOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ29udmVydHMgYSBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyB0byBQRU0gZm9ybWF0LgogKgogKiBAcGFyYW0gZXBraSB0aGUgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uCiAqIEBwYXJhbSBtYXhsaW5lIHRoZSBtYXhpbXVtIGNoYXJhY3RlcnMgcGVyIGxpbmUsIGRlZmF1bHRzIHRvIDY0LgogKgogKiBAcmV0dXJuIHRoZSBQRU0tZm9ybWF0dGVkIGVuY3J5cHRlZCBwcml2YXRlIGtleS4KICovCnBraS5lbmNyeXB0ZWRQcml2YXRlS2V5VG9QZW0gPSBmdW5jdGlvbihlcGtpLCBtYXhsaW5lKSB7CiAgLy8gY29udmVydCB0byBERVIsIHRoZW4gUEVNLWVuY29kZQogIHZhciBtc2cgPSB7CiAgICB0eXBlOiAnRU5DUllQVEVEIFBSSVZBVEUgS0VZJywKICAgIGJvZHk6IGFzbjEudG9EZXIoZXBraSkuZ2V0Qnl0ZXMoKQogIH07CiAgcmV0dXJuIGZvcmdlLnBlbS5lbmNvZGUobXNnLCB7bWF4bGluZTogbWF4bGluZX0pOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgUEVNLWVuY29kZWQgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gdG8gQVNOLjEgZm9ybWF0LiBEZWNyeXB0aW9uCiAqIGlzIG5vdCBwZXJmb3JtZWQuCiAqCiAqIEBwYXJhbSBwZW0gdGhlIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIGluIFBFTS1mb3JtYXQuCiAqCiAqIEByZXR1cm4gdGhlIEFTTi4xIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvLgogKi8KcGtpLmVuY3J5cHRlZFByaXZhdGVLZXlGcm9tUGVtID0gZnVuY3Rpb24ocGVtKSB7CiAgdmFyIG1zZyA9IGZvcmdlLnBlbS5kZWNvZGUocGVtKVswXTsKCiAgaWYobXNnLnR5cGUgIT09ICdFTkNSWVBURUQgUFJJVkFURSBLRVknKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IGVuY3J5cHRlZCBwcml2YXRlIGtleSBmcm9tIFBFTTsgJyArCiAgICAgICdQRU0gaGVhZGVyIHR5cGUgaXMgIkVOQ1JZUFRFRCBQUklWQVRFIEtFWSIuJyk7CiAgICBlcnJvci5oZWFkZXJUeXBlID0gbXNnLnR5cGU7CiAgICB0aHJvdyBlcnJvcjsKICB9CiAgaWYobXNnLnByb2NUeXBlICYmIG1zZy5wcm9jVHlwZS50eXBlID09PSAnRU5DUllQVEVEJykgewogICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgY29udmVydCBlbmNyeXB0ZWQgcHJpdmF0ZSBrZXkgZnJvbSBQRU07ICcgKwogICAgICAnUEVNIGlzIGVuY3J5cHRlZC4nKTsKICB9CgogIC8vIGNvbnZlcnQgREVSIHRvIEFTTi4xIG9iamVjdAogIHJldHVybiBhc24xLmZyb21EZXIobXNnLmJvZHkpOwp9OwoKLyoqCiAqIEVuY3J5cHRzIGFuIFJTQSBwcml2YXRlIGtleS4gQnkgZGVmYXVsdCwgdGhlIGtleSB3aWxsIGJlIHdyYXBwZWQgaW4KICogYSBQcml2YXRlS2V5SW5mbyBhbmQgZW5jcnlwdGVkIHRvIHByb2R1Y2UgYSBQS0NTIzggRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uCiAqIFRoaXMgaXMgdGhlIHN0YW5kYXJkLCBwcmVmZXJyZWQgd2F5IHRvIGVuY3J5cHQgYSBwcml2YXRlIGtleS4KICoKICogVG8gcHJvZHVjZSBhIG5vbi1zdGFuZGFyZCBQRU0tZW5jcnlwdGVkIHByaXZhdGUga2V5IHRoYXQgdXNlcyBlbmNhcHN1bGF0ZWQKICogaGVhZGVycyB0byBpbmRpY2F0ZSB0aGUgZW5jcnlwdGlvbiBhbGdvcml0aG0gKG9sZC1zdHlsZSBub24tUEtDUyM4IE9wZW5TU0wKICogcHJpdmF0ZSBrZXkgZW5jcnlwdGlvbiksIHNldCB0aGUgJ2xlZ2FjeScgb3B0aW9uIHRvIHRydWUuIE5vdGU6IFVzaW5nIHRoaXMKICogb3B0aW9uIHdpbGwgY2F1c2UgdGhlIGl0ZXJhdGlvbiBjb3VudCB0byBiZSBmb3JjZWQgdG8gMS4KICoKICogTm90ZTogVGhlICdkZXMnIGFsZ29yaXRobSBpcyBzdXBwb3J0ZWQsIGJ1dCBpdCBpcyBub3QgY29uc2lkZXJlZCB0byBiZQogKiBzZWN1cmUgYmVjYXVzZSBpdCBvbmx5IHVzZXMgYSBzaW5nbGUgNTYtYml0IGtleS4gSWYgcG9zc2libGUsIGl0IGlzIGhpZ2hseQogKiByZWNvbW1lbmRlZCB0aGF0IGEgZGlmZmVyZW50IGFsZ29yaXRobSBiZSB1c2VkLgogKgogKiBAcGFyYW0gcnNhS2V5IHRoZSBSU0Ega2V5IHRvIGVuY3J5cHQuCiAqIEBwYXJhbSBwYXNzd29yZCB0aGUgcGFzc3dvcmQgdG8gdXNlLgogKiBAcGFyYW0gb3B0aW9uczoKICogICAgICAgICAgYWxnb3JpdGhtOiB0aGUgZW5jcnlwdGlvbiBhbGdvcml0aG0gdG8gdXNlCiAqICAgICAgICAgICAgKCdhZXMxMjgnLCAnYWVzMTkyJywgJ2FlczI1NicsICczZGVzJywgJ2RlcycpLgogKiAgICAgICAgICBjb3VudDogdGhlIGl0ZXJhdGlvbiBjb3VudCB0byB1c2UuCiAqICAgICAgICAgIHNhbHRTaXplOiB0aGUgc2FsdCBzaXplIHRvIHVzZS4KICogICAgICAgICAgbGVnYWN5OiBvdXRwdXQgYW4gb2xkIG5vbi1QS0NTIzggUEVNLWVuY3J5cHRlZCtlbmNhcHN1bGF0ZWQKICogICAgICAgICAgICBoZWFkZXJzIChERUstSW5mbykgcHJpdmF0ZSBrZXkuCiAqCiAqIEByZXR1cm4gdGhlIFBFTS1lbmNvZGVkIEFTTi4xIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvLgogKi8KcGtpLmVuY3J5cHRSc2FQcml2YXRlS2V5ID0gZnVuY3Rpb24ocnNhS2V5LCBwYXNzd29yZCwgb3B0aW9ucykgewogIC8vIHN0YW5kYXJkIFBLQ1MjOAogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIGlmKCFvcHRpb25zLmxlZ2FjeSkgewogICAgLy8gZW5jcnlwdCBQcml2YXRlS2V5SW5mbwogICAgdmFyIHJ2YWwgPSBwa2kud3JhcFJzYVByaXZhdGVLZXkocGtpLnByaXZhdGVLZXlUb0FzbjEocnNhS2V5KSk7CiAgICBydmFsID0gcGtpLmVuY3J5cHRQcml2YXRlS2V5SW5mbyhydmFsLCBwYXNzd29yZCwgb3B0aW9ucyk7CiAgICByZXR1cm4gcGtpLmVuY3J5cHRlZFByaXZhdGVLZXlUb1BlbShydmFsKTsKICB9CgogIC8vIGxlZ2FjeSBub24tUEtDUyM4CiAgdmFyIGFsZ29yaXRobTsKICB2YXIgaXY7CiAgdmFyIGRrTGVuOwogIHZhciBjaXBoZXJGbjsKICBzd2l0Y2gob3B0aW9ucy5hbGdvcml0aG0pIHsKICBjYXNlICdhZXMxMjgnOgogICAgYWxnb3JpdGhtID0gJ0FFUy0xMjgtQ0JDJzsKICAgIGRrTGVuID0gMTY7CiAgICBpdiA9IGZvcmdlLnJhbmRvbS5nZXRCeXRlc1N5bmMoMTYpOwogICAgY2lwaGVyRm4gPSBmb3JnZS5hZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgIGJyZWFrOwogIGNhc2UgJ2FlczE5Mic6CiAgICBhbGdvcml0aG0gPSAnQUVTLTE5Mi1DQkMnOwogICAgZGtMZW4gPSAyNDsKICAgIGl2ID0gZm9yZ2UucmFuZG9tLmdldEJ5dGVzU3luYygxNik7CiAgICBjaXBoZXJGbiA9IGZvcmdlLmFlcy5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyOwogICAgYnJlYWs7CiAgY2FzZSAnYWVzMjU2JzoKICAgIGFsZ29yaXRobSA9ICdBRVMtMjU2LUNCQyc7CiAgICBka0xlbiA9IDMyOwogICAgaXYgPSBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXNTeW5jKDE2KTsKICAgIGNpcGhlckZuID0gZm9yZ2UuYWVzLmNyZWF0ZUVuY3J5cHRpb25DaXBoZXI7CiAgICBicmVhazsKICBjYXNlICczZGVzJzoKICAgIGFsZ29yaXRobSA9ICdERVMtRURFMy1DQkMnOwogICAgZGtMZW4gPSAyNDsKICAgIGl2ID0gZm9yZ2UucmFuZG9tLmdldEJ5dGVzU3luYyg4KTsKICAgIGNpcGhlckZuID0gZm9yZ2UuZGVzLmNyZWF0ZUVuY3J5cHRpb25DaXBoZXI7CiAgICBicmVhazsKICBjYXNlICdkZXMnOgogICAgYWxnb3JpdGhtID0gJ0RFUy1DQkMnOwogICAgZGtMZW4gPSA4OwogICAgaXYgPSBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXNTeW5jKDgpOwogICAgY2lwaGVyRm4gPSBmb3JnZS5kZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBlbmNyeXB0IFJTQSBwcml2YXRlIGtleTsgdW5zdXBwb3J0ZWQgJyArCiAgICAgICdlbmNyeXB0aW9uIGFsZ29yaXRobSAiJyArIG9wdGlvbnMuYWxnb3JpdGhtICsgJyIuJyk7CiAgICBlcnJvci5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobTsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gZW5jcnlwdCBwcml2YXRlIGtleSB1c2luZyBPcGVuU1NMIGxlZ2FjeSBrZXkgZGVyaXZhdGlvbgogIHZhciBkayA9IGZvcmdlLnBiZS5vcGVuc3NsRGVyaXZlQnl0ZXMocGFzc3dvcmQsIGl2LnN1YnN0cigwLCA4KSwgZGtMZW4pOwogIHZhciBjaXBoZXIgPSBjaXBoZXJGbihkayk7CiAgY2lwaGVyLnN0YXJ0KGl2KTsKICBjaXBoZXIudXBkYXRlKGFzbjEudG9EZXIocGtpLnByaXZhdGVLZXlUb0FzbjEocnNhS2V5KSkpOwogIGNpcGhlci5maW5pc2goKTsKCiAgdmFyIG1zZyA9IHsKICAgIHR5cGU6ICdSU0EgUFJJVkFURSBLRVknLAogICAgcHJvY1R5cGU6IHsKICAgICAgdmVyc2lvbjogJzQnLAogICAgICB0eXBlOiAnRU5DUllQVEVEJwogICAgfSwKICAgIGRla0luZm86IHsKICAgICAgYWxnb3JpdGhtOiBhbGdvcml0aG0sCiAgICAgIHBhcmFtZXRlcnM6IGZvcmdlLnV0aWwuYnl0ZXNUb0hleChpdikudG9VcHBlckNhc2UoKQogICAgfSwKICAgIGJvZHk6IGNpcGhlci5vdXRwdXQuZ2V0Qnl0ZXMoKQogIH07CiAgcmV0dXJuIGZvcmdlLnBlbS5lbmNvZGUobXNnKTsKfTsKCi8qKgogKiBEZWNyeXB0cyBhbiBSU0EgcHJpdmF0ZSBrZXkuCiAqCiAqIEBwYXJhbSBwZW0gdGhlIFBFTS1mb3JtYXR0ZWQgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gdG8gZGVjcnlwdC4KICogQHBhcmFtIHBhc3N3b3JkIHRoZSBwYXNzd29yZCB0byB1c2UuCiAqCiAqIEByZXR1cm4gdGhlIFJTQSBrZXkgb24gc3VjY2VzcywgbnVsbCBvbiBmYWlsdXJlLgogKi8KcGtpLmRlY3J5cHRSc2FQcml2YXRlS2V5ID0gZnVuY3Rpb24ocGVtLCBwYXNzd29yZCkgewogIHZhciBydmFsID0gbnVsbDsKCiAgdmFyIG1zZyA9IGZvcmdlLnBlbS5kZWNvZGUocGVtKVswXTsKCiAgaWYobXNnLnR5cGUgIT09ICdFTkNSWVBURUQgUFJJVkFURSBLRVknICYmCiAgICBtc2cudHlwZSAhPT0gJ1BSSVZBVEUgS0VZJyAmJgogICAgbXNnLnR5cGUgIT09ICdSU0EgUFJJVkFURSBLRVknKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IHByaXZhdGUga2V5IGZyb20gUEVNOyBQRU0gaGVhZGVyIHR5cGUgJyArCiAgICAgICdpcyBub3QgIkVOQ1JZUFRFRCBQUklWQVRFIEtFWSIsICJQUklWQVRFIEtFWSIsIG9yICJSU0EgUFJJVkFURSBLRVkiLicpOwogICAgZXJyb3IuaGVhZGVyVHlwZSA9IGVycm9yOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB2YXIgZGtMZW47CiAgICB2YXIgY2lwaGVyRm47CiAgICBzd2l0Y2gobXNnLmRla0luZm8uYWxnb3JpdGhtKSB7CiAgICBjYXNlICdERVMtQ0JDJzoKICAgICAgZGtMZW4gPSA4OwogICAgICBjaXBoZXJGbiA9IGZvcmdlLmRlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyOwogICAgICBicmVhazsKICAgIGNhc2UgJ0RFUy1FREUzLUNCQyc6CiAgICAgIGRrTGVuID0gMjQ7CiAgICAgIGNpcGhlckZuID0gZm9yZ2UuZGVzLmNyZWF0ZURlY3J5cHRpb25DaXBoZXI7CiAgICAgIGJyZWFrOwogICAgY2FzZSAnQUVTLTEyOC1DQkMnOgogICAgICBka0xlbiA9IDE2OwogICAgICBjaXBoZXJGbiA9IGZvcmdlLmFlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyOwogICAgICBicmVhazsKICAgIGNhc2UgJ0FFUy0xOTItQ0JDJzoKICAgICAgZGtMZW4gPSAyNDsKICAgICAgY2lwaGVyRm4gPSBmb3JnZS5hZXMuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcjsKICAgICAgYnJlYWs7CiAgICBjYXNlICdBRVMtMjU2LUNCQyc6CiAgICAgIGRrTGVuID0gMzI7CiAgICAgIGNpcGhlckZuID0gZm9yZ2UuYWVzLmNyZWF0ZURlY3J5cHRpb25DaXBoZXI7CiAgICAgIGJyZWFrOwogICAgY2FzZSAnUkMyLTQwLUNCQyc6CiAgICAgIGRrTGVuID0gNTsKICAgICAgY2lwaGVyRm4gPSBmdW5jdGlvbihrZXkpIHsKICAgICAgICByZXR1cm4gZm9yZ2UucmMyLmNyZWF0ZURlY3J5cHRpb25DaXBoZXIoa2V5LCA0MCk7CiAgICAgIH07CiAgICAgIGJyZWFrOwogICAgY2FzZSAnUkMyLTY0LUNCQyc6CiAgICAgIGRrTGVuID0gODsKICAgICAgY2lwaGVyRm4gPSBmdW5jdGlvbihrZXkpIHsKICAgICAgICByZXR1cm4gZm9yZ2UucmMyLmNyZWF0ZURlY3J5cHRpb25DaXBoZXIoa2V5LCA2NCk7CiAgICAgIH07CiAgICAgIGJyZWFrOwogICAgY2FzZSAnUkMyLTEyOC1DQkMnOgogICAgICBka0xlbiA9IDE2OwogICAgICBjaXBoZXJGbiA9IGZ1bmN0aW9uKGtleSkgewogICAgICAgIHJldHVybiBmb3JnZS5yYzIuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcihrZXksIDEyOCk7CiAgICAgIH07CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDb3VsZCBub3QgZGVjcnlwdCBwcml2YXRlIGtleTsgdW5zdXBwb3J0ZWQgJyArCiAgICAgICAgJ2VuY3J5cHRpb24gYWxnb3JpdGhtICInICsgbXNnLmRla0luZm8uYWxnb3JpdGhtICsgJyIuJyk7CiAgICAgIGVycm9yLmFsZ29yaXRobSA9IG1zZy5kZWtJbmZvLmFsZ29yaXRobTsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgLy8gdXNlIE9wZW5TU0wgbGVnYWN5IGtleSBkZXJpdmF0aW9uCiAgICB2YXIgaXYgPSBmb3JnZS51dGlsLmhleFRvQnl0ZXMobXNnLmRla0luZm8ucGFyYW1ldGVycyk7CiAgICB2YXIgZGsgPSBmb3JnZS5wYmUub3BlbnNzbERlcml2ZUJ5dGVzKHBhc3N3b3JkLCBpdi5zdWJzdHIoMCwgOCksIGRrTGVuKTsKICAgIHZhciBjaXBoZXIgPSBjaXBoZXJGbihkayk7CiAgICBjaXBoZXIuc3RhcnQoaXYpOwogICAgY2lwaGVyLnVwZGF0ZShmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihtc2cuYm9keSkpOwogICAgaWYoY2lwaGVyLmZpbmlzaCgpKSB7CiAgICAgIHJ2YWwgPSBjaXBoZXIub3V0cHV0LmdldEJ5dGVzKCk7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gcnZhbDsKICAgIH0KICB9IGVsc2UgewogICAgcnZhbCA9IG1zZy5ib2R5OwogIH0KCiAgaWYobXNnLnR5cGUgPT09ICdFTkNSWVBURUQgUFJJVkFURSBLRVknKSB7CiAgICBydmFsID0gcGtpLmRlY3J5cHRQcml2YXRlS2V5SW5mbyhhc24xLmZyb21EZXIocnZhbCksIHBhc3N3b3JkKTsKICB9IGVsc2UgewogICAgLy8gZGVjcnlwdGlvbiBhbHJlYWR5IHBlcmZvcm1lZCBhYm92ZQogICAgcnZhbCA9IGFzbjEuZnJvbURlcihydmFsKTsKICB9CgogIGlmKHJ2YWwgIT09IG51bGwpIHsKICAgIHJ2YWwgPSBwa2kucHJpdmF0ZUtleUZyb21Bc24xKHJ2YWwpOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogRGVyaXZlcyBhIFBLQ1MjMTIga2V5LgogKgogKiBAcGFyYW0gcGFzc3dvcmQgdGhlIHBhc3N3b3JkIHRvIGRlcml2ZSB0aGUga2V5IG1hdGVyaWFsIGZyb20sIG51bGwgb3IKICogICAgICAgICAgdW5kZWZpbmVkIGZvciBub25lLgogKiBAcGFyYW0gc2FsdCB0aGUgc2FsdCwgYXMgYSBCeXRlQnVmZmVyLCB0byB1c2UuCiAqIEBwYXJhbSBpZCB0aGUgUEtDUyMxMiBJRCBieXRlICgxID0ga2V5IG1hdGVyaWFsLCAyID0gSVYsIDMgPSBNQUMpLgogKiBAcGFyYW0gaXRlciB0aGUgaXRlcmF0aW9uIGNvdW50LgogKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGRlcml2ZSBmcm9tIHRoZSBwYXNzd29yZC4KICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCB0byB1c2UsIGRlZmF1bHRzIHRvIFNIQS0xLgogKgogKiBAcmV0dXJuIGEgQnl0ZUJ1ZmZlciB3aXRoIHRoZSBieXRlcyBkZXJpdmVkIGZyb20gdGhlIHBhc3N3b3JkLgogKi8KcGtpLnBiZS5nZW5lcmF0ZVBrY3MxMktleSA9IGZ1bmN0aW9uKHBhc3N3b3JkLCBzYWx0LCBpZCwgaXRlciwgbiwgbWQpIHsKICB2YXIgaiwgbDsKCiAgaWYodHlwZW9mIG1kID09PSAndW5kZWZpbmVkJyB8fCBtZCA9PT0gbnVsbCkgewogICAgbWQgPSBmb3JnZS5tZC5zaGExLmNyZWF0ZSgpOwogIH0KCiAgdmFyIHUgPSBtZC5kaWdlc3RMZW5ndGg7CiAgdmFyIHYgPSBtZC5ibG9ja0xlbmd0aDsKICB2YXIgcmVzdWx0ID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwoKICAvKiBDb252ZXJ0IHBhc3N3b3JkIHRvIFVuaWNvZGUgYnl0ZSBidWZmZXIgKyB0cmFpbGluZyAwLWJ5dGUuICovCiAgdmFyIHBhc3NCdWYgPSBuZXcgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKCk7CiAgaWYocGFzc3dvcmQgIT09IG51bGwgJiYgcGFzc3dvcmQgIT09IHVuZGVmaW5lZCkgewogICAgZm9yKGwgPSAwOyBsIDwgcGFzc3dvcmQubGVuZ3RoOyBsKyspIHsKICAgICAgcGFzc0J1Zi5wdXRJbnQxNihwYXNzd29yZC5jaGFyQ29kZUF0KGwpKTsKICAgIH0KICAgIHBhc3NCdWYucHV0SW50MTYoMCk7CiAgfQoKICAvKiBMZW5ndGggb2Ygc2FsdCBhbmQgcGFzc3dvcmQgaW4gQllURVMuICovCiAgdmFyIHAgPSBwYXNzQnVmLmxlbmd0aCgpOwogIHZhciBzID0gc2FsdC5sZW5ndGgoKTsKCiAgLyogMS4gQ29uc3RydWN0IGEgc3RyaW5nLCBEICh0aGUgImRpdmVyc2lmaWVyIiksIGJ5IGNvbmNhdGVuYXRpbmcKICAgICAgICB2IGNvcGllcyBvZiBJRC4gKi8KICB2YXIgRCA9IG5ldyBmb3JnZS51dGlsLkJ5dGVCdWZmZXIoKTsKICBELmZpbGxXaXRoQnl0ZShpZCwgdik7CgogIC8qIDIuIENvbmNhdGVuYXRlIGNvcGllcyBvZiB0aGUgc2FsdCB0b2dldGhlciB0byBjcmVhdGUgYSBzdHJpbmcgUyBvZiBsZW5ndGgKICAgICAgICB2ICogY2VpbChzIC8gdikgYnl0ZXMgKHRoZSBmaW5hbCBjb3B5IG9mIHRoZSBzYWx0IG1heSBiZSB0cnVuYWN0ZWQKICAgICAgICB0byBjcmVhdGUgUykuCiAgICAgICAgTm90ZSB0aGF0IGlmIHRoZSBzYWx0IGlzIHRoZSBlbXB0eSBzdHJpbmcsIHRoZW4gc28gaXMgUy4gKi8KICB2YXIgU2xlbiA9IHYgKiBNYXRoLmNlaWwocyAvIHYpOwogIHZhciBTID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwogIGZvcihsID0gMDsgbCA8IFNsZW47IGwgKyspIHsKICAgIFMucHV0Qnl0ZShzYWx0LmF0KGwgJSBzKSk7CiAgfQoKICAvKiAzLiBDb25jYXRlbmF0ZSBjb3BpZXMgb2YgdGhlIHBhc3N3b3JkIHRvZ2V0aGVyIHRvIGNyZWF0ZSBhIHN0cmluZyBQIG9mCiAgICAgICAgbGVuZ3RoIHYgKiBjZWlsKHAgLyB2KSBieXRlcyAodGhlIGZpbmFsIGNvcHkgb2YgdGhlIHBhc3N3b3JkIG1heSBiZQogICAgICAgIHRydW5jYXRlZCB0byBjcmVhdGUgUCkuCiAgICAgICAgTm90ZSB0aGF0IGlmIHRoZSBwYXNzd29yZCBpcyB0aGUgZW1wdHkgc3RyaW5nLCB0aGVuIHNvIGlzIFAuICovCiAgdmFyIFBsZW4gPSB2ICogTWF0aC5jZWlsKHAgLyB2KTsKICB2YXIgUCA9IG5ldyBmb3JnZS51dGlsLkJ5dGVCdWZmZXIoKTsKICBmb3IobCA9IDA7IGwgPCBQbGVuOyBsICsrKSB7CiAgICBQLnB1dEJ5dGUocGFzc0J1Zi5hdChsICUgcCkpOwogIH0KCiAgLyogNC4gU2V0IEk9U3x8UCB0byBiZSB0aGUgY29uY2F0ZW5hdGlvbiBvZiBTIGFuZCBQLiAqLwogIHZhciBJID0gUzsKICBJLnB1dEJ1ZmZlcihQKTsKCiAgLyogNS4gU2V0IGM9Y2VpbChuIC8gdSkuICovCiAgdmFyIGMgPSBNYXRoLmNlaWwobiAvIHUpOwoKICAvKiA2LiBGb3IgaT0xLCAyLCAuLi4sIGMsIGRvIHRoZSBmb2xsb3dpbmc6ICovCiAgZm9yKHZhciBpID0gMTsgaSA8PSBjOyBpICsrKSB7CiAgICAvKiBhKSBTZXQgQWk9SF5yKER8fEkpLiAobC5lLiB0aGUgcnRoIGhhc2ggb2YgRHx8SSwgSChIKEgoLi4uSChEfHxJKSkpKSAqLwogICAgdmFyIGJ1ZiA9IG5ldyBmb3JnZS51dGlsLkJ5dGVCdWZmZXIoKTsKICAgIGJ1Zi5wdXRCeXRlcyhELmJ5dGVzKCkpOwogICAgYnVmLnB1dEJ5dGVzKEkuYnl0ZXMoKSk7CiAgICBmb3IodmFyIHJvdW5kID0gMDsgcm91bmQgPCBpdGVyOyByb3VuZCArKykgewogICAgICBtZC5zdGFydCgpOwogICAgICBtZC51cGRhdGUoYnVmLmdldEJ5dGVzKCkpOwogICAgICBidWYgPSBtZC5kaWdlc3QoKTsKICAgIH0KCiAgICAvKiBiKSBDb25jYXRlbmF0ZSBjb3BpZXMgb2YgQWkgdG8gY3JlYXRlIGEgc3RyaW5nIEIgb2YgbGVuZ3RoIHYgYnl0ZXMgKHRoZQogICAgICAgICAgZmluYWwgY29weSBvZiBBaSBtYXkgYmUgdHJ1bmNhdGVkIHRvIGNyZWF0ZSBCKS4gKi8KICAgIHZhciBCID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwogICAgZm9yKGwgPSAwOyBsIDwgdjsgbCArKykgewogICAgICBCLnB1dEJ5dGUoYnVmLmF0KGwgJSB1KSk7CiAgICB9CgogICAgLyogYykgVHJlYXRpbmcgSSBhcyBhIGNvbmNhdGVuYXRpb24gSTAsIEkxLCAuLi4sIElrLTEgb2Ygdi1ieXRlIGJsb2NrcywKICAgICAgICAgIHdoZXJlIGs9Y2VpbChzIC8gdikgKyBjZWlsKHAgLyB2KSwgbW9kaWZ5IEkgYnkgc2V0dGluZwogICAgICAgICAgSWo9KElqK0IrMSkgbW9kIDJ2IGZvciBlYWNoIGouICAqLwogICAgdmFyIGsgPSBNYXRoLmNlaWwocyAvIHYpICsgTWF0aC5jZWlsKHAgLyB2KTsKICAgIHZhciBJbmV3ID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwogICAgZm9yKGogPSAwOyBqIDwgazsgaiArKykgewogICAgICB2YXIgY2h1bmsgPSBuZXcgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKEkuZ2V0Qnl0ZXModikpOwogICAgICB2YXIgeCA9IDB4MWZmOwogICAgICBmb3IobCA9IEIubGVuZ3RoKCkgLSAxOyBsID49IDA7IGwgLS0pIHsKICAgICAgICB4ID0geCA+PiA4OwogICAgICAgIHggKz0gQi5hdChsKSArIGNodW5rLmF0KGwpOwogICAgICAgIGNodW5rLnNldEF0KGwsIHggJiAweGZmKTsKICAgICAgfQogICAgICBJbmV3LnB1dEJ1ZmZlcihjaHVuayk7CiAgICB9CiAgICBJID0gSW5ldzsKCiAgICAvKiBBZGQgQWkgdG8gQS4gKi8KICAgIHJlc3VsdC5wdXRCdWZmZXIoYnVmKTsKICB9CgogIHJlc3VsdC50cnVuY2F0ZShyZXN1bHQubGVuZ3RoKCkgLSBuKTsKICByZXR1cm4gcmVzdWx0Owp9OwoKLyoqCiAqIEdldCBuZXcgRm9yZ2UgY2lwaGVyIG9iamVjdCBpbnN0YW5jZS4KICoKICogQHBhcmFtIG9pZCB0aGUgT0lEIChpbiBzdHJpbmcgbm90YXRpb24pLgogKiBAcGFyYW0gcGFyYW1zIHRoZSBBU04uMSBwYXJhbXMgb2JqZWN0LgogKiBAcGFyYW0gcGFzc3dvcmQgdGhlIHBhc3N3b3JkIHRvIGRlY3J5cHQgd2l0aC4KICoKICogQHJldHVybiBuZXcgY2lwaGVyIG9iamVjdCBpbnN0YW5jZS4KICovCnBraS5wYmUuZ2V0Q2lwaGVyID0gZnVuY3Rpb24ob2lkLCBwYXJhbXMsIHBhc3N3b3JkKSB7CiAgc3dpdGNoKG9pZCkgewogIGNhc2UgcGtpLm9pZHNbJ3BrY3M1UEJFUzInXToKICAgIHJldHVybiBwa2kucGJlLmdldENpcGhlckZvclBCRVMyKG9pZCwgcGFyYW1zLCBwYXNzd29yZCk7CgogIGNhc2UgcGtpLm9pZHNbJ3BiZVdpdGhTSEFBbmQzLUtleVRyaXBsZURFUy1DQkMnXToKICBjYXNlIHBraS5vaWRzWydwYmV3aXRoU0hBQW5kNDBCaXRSQzItQ0JDJ106CiAgICByZXR1cm4gcGtpLnBiZS5nZXRDaXBoZXJGb3JQS0NTMTJQQkUob2lkLCBwYXJhbXMsIHBhc3N3b3JkKTsKCiAgZGVmYXVsdDoKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgZW5jcnlwdGVkIFBCRSBkYXRhIGJsb2NrLiBVbnN1cHBvcnRlZCBPSUQuJyk7CiAgICBlcnJvci5vaWQgPSBvaWQ7CiAgICBlcnJvci5zdXBwb3J0ZWRPaWRzID0gWwogICAgICAncGtjczVQQkVTMicsCiAgICAgICdwYmVXaXRoU0hBQW5kMy1LZXlUcmlwbGVERVMtQ0JDJywKICAgICAgJ3BiZXdpdGhTSEFBbmQ0MEJpdFJDMi1DQkMnCiAgICBdOwogICAgdGhyb3cgZXJyb3I7CiAgfQp9OwoKLyoqCiAqIEdldCBuZXcgRm9yZ2UgY2lwaGVyIG9iamVjdCBpbnN0YW5jZSBhY2NvcmRpbmcgdG8gUEJFUzIgcGFyYW1zIGJsb2NrLgogKgogKiBUaGUgcmV0dXJuZWQgY2lwaGVyIGluc3RhbmNlIGlzIGFscmVhZHkgc3RhcnRlZCB1c2luZyB0aGUgSVYKICogZnJvbSBQQkVTMiBwYXJhbWV0ZXIgYmxvY2suCiAqCiAqIEBwYXJhbSBvaWQgdGhlIFBLQ1MjNSBQQktERjIgT0lEIChpbiBzdHJpbmcgbm90YXRpb24pLgogKiBAcGFyYW0gcGFyYW1zIHRoZSBBU04uMSBQQkVTMi1wYXJhbXMgb2JqZWN0LgogKiBAcGFyYW0gcGFzc3dvcmQgdGhlIHBhc3N3b3JkIHRvIGRlY3J5cHQgd2l0aC4KICoKICogQHJldHVybiBuZXcgY2lwaGVyIG9iamVjdCBpbnN0YW5jZS4KICovCnBraS5wYmUuZ2V0Q2lwaGVyRm9yUEJFUzIgPSBmdW5jdGlvbihvaWQsIHBhcmFtcywgcGFzc3dvcmQpIHsKICAvLyBnZXQgUEJFIHBhcmFtcwogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKHBhcmFtcywgUEJFUzJBbGdvcml0aG1zVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIHBhc3N3b3JkLWJhc2VkLWVuY3J5cHRpb24gYWxnb3JpdGhtICcgKwogICAgICAncGFyYW1ldGVycy4gQVNOLjEgb2JqZWN0IGlzIG5vdCBhIHN1cHBvcnRlZCBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mby4nKTsKICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gY2hlY2sgb2lkcwogIG9pZCA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5rZGZPaWQpOwogIGlmKG9pZCAhPT0gcGtpLm9pZHNbJ3BrY3M1UEJLREYyJ10pIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgZW5jcnlwdGVkIHByaXZhdGUga2V5LiAnICsKICAgICAgJ1Vuc3VwcG9ydGVkIGtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uIE9JRC4nKTsKICAgIGVycm9yLm9pZCA9IG9pZDsKICAgIGVycm9yLnN1cHBvcnRlZE9pZHMgPSBbJ3BrY3M1UEJLREYyJ107CiAgICB0aHJvdyBlcnJvcjsKICB9CiAgb2lkID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLmVuY09pZCk7CiAgaWYob2lkICE9PSBwa2kub2lkc1snYWVzMTI4LUNCQyddICYmCiAgICBvaWQgIT09IHBraS5vaWRzWydhZXMxOTItQ0JDJ10gJiYKICAgIG9pZCAhPT0gcGtpLm9pZHNbJ2FlczI1Ni1DQkMnXSAmJgogICAgb2lkICE9PSBwa2kub2lkc1snZGVzLUVERTMtQ0JDJ10gJiYKICAgIG9pZCAhPT0gcGtpLm9pZHNbJ2Rlc0NCQyddKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIGVuY3J5cHRlZCBwcml2YXRlIGtleS4gJyArCiAgICAgICdVbnN1cHBvcnRlZCBlbmNyeXB0aW9uIHNjaGVtZSBPSUQuJyk7CiAgICBlcnJvci5vaWQgPSBvaWQ7CiAgICBlcnJvci5zdXBwb3J0ZWRPaWRzID0gWwogICAgICAnYWVzMTI4LUNCQycsICdhZXMxOTItQ0JDJywgJ2FlczI1Ni1DQkMnLCAnZGVzLUVERTMtQ0JDJywgJ2Rlc0NCQyddOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICAvLyBzZXQgUEJFIHBhcmFtcwogIHZhciBzYWx0ID0gY2FwdHVyZS5rZGZTYWx0OwogIHZhciBjb3VudCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUua2RmSXRlcmF0aW9uQ291bnQpOwogIGNvdW50ID0gY291bnQuZ2V0SW50KGNvdW50Lmxlbmd0aCgpIDw8IDMpOwogIHZhciBka0xlbjsKICB2YXIgY2lwaGVyRm47CiAgc3dpdGNoKHBraS5vaWRzW29pZF0pIHsKICBjYXNlICdhZXMxMjgtQ0JDJzoKICAgIGRrTGVuID0gMTY7CiAgICBjaXBoZXJGbiA9IGZvcmdlLmFlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyOwogICAgYnJlYWs7CiAgY2FzZSAnYWVzMTkyLUNCQyc6CiAgICBka0xlbiA9IDI0OwogICAgY2lwaGVyRm4gPSBmb3JnZS5hZXMuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcjsKICAgIGJyZWFrOwogIGNhc2UgJ2FlczI1Ni1DQkMnOgogICAgZGtMZW4gPSAzMjsKICAgIGNpcGhlckZuID0gZm9yZ2UuYWVzLmNyZWF0ZURlY3J5cHRpb25DaXBoZXI7CiAgICBicmVhazsKICBjYXNlICdkZXMtRURFMy1DQkMnOgogICAgZGtMZW4gPSAyNDsKICAgIGNpcGhlckZuID0gZm9yZ2UuZGVzLmNyZWF0ZURlY3J5cHRpb25DaXBoZXI7CiAgICBicmVhazsKICBjYXNlICdkZXNDQkMnOgogICAgZGtMZW4gPSA4OwogICAgY2lwaGVyRm4gPSBmb3JnZS5kZXMuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcjsKICAgIGJyZWFrOwogIH0KCiAgLy8gZGVjcnlwdCBwcml2YXRlIGtleSB1c2luZyBwYmUgU0hBLTEgYW5kIEFFUy9ERVMKICB2YXIgZGsgPSBmb3JnZS5wa2NzNS5wYmtkZjIocGFzc3dvcmQsIHNhbHQsIGNvdW50LCBka0xlbik7CiAgdmFyIGl2ID0gY2FwdHVyZS5lbmNJdjsKICB2YXIgY2lwaGVyID0gY2lwaGVyRm4oZGspOwogIGNpcGhlci5zdGFydChpdik7CgogIHJldHVybiBjaXBoZXI7Cn07CgovKioKICogR2V0IG5ldyBGb3JnZSBjaXBoZXIgb2JqZWN0IGluc3RhbmNlIGZvciBQS0NTIzEyIFBCRS4KICoKICogVGhlIHJldHVybmVkIGNpcGhlciBpbnN0YW5jZSBpcyBhbHJlYWR5IHN0YXJ0ZWQgdXNpbmcgdGhlIGtleSAmIElWCiAqIGRlcml2ZWQgZnJvbSB0aGUgcHJvdmlkZWQgcGFzc3dvcmQgYW5kIFBLQ1MjMTIgUEJFIHNhbHQuCiAqCiAqIEBwYXJhbSBvaWQgVGhlIFBLQ1MjMTIgUEJFIE9JRCAoaW4gc3RyaW5nIG5vdGF0aW9uKS4KICogQHBhcmFtIHBhcmFtcyBUaGUgQVNOLjEgUEtDUyMxMiBQQkUtcGFyYW1zIG9iamVjdC4KICogQHBhcmFtIHBhc3N3b3JkIFRoZSBwYXNzd29yZCB0byBkZWNyeXB0IHdpdGguCiAqCiAqIEByZXR1cm4gdGhlIG5ldyBjaXBoZXIgb2JqZWN0IGluc3RhbmNlLgogKi8KcGtpLnBiZS5nZXRDaXBoZXJGb3JQS0NTMTJQQkUgPSBmdW5jdGlvbihvaWQsIHBhcmFtcywgcGFzc3dvcmQpIHsKICAvLyBnZXQgUEJFIHBhcmFtcwogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKHBhcmFtcywgcGtjczEyUGJlUGFyYW1zVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIHBhc3N3b3JkLWJhc2VkLWVuY3J5cHRpb24gYWxnb3JpdGhtICcgKwogICAgICAncGFyYW1ldGVycy4gQVNOLjEgb2JqZWN0IGlzIG5vdCBhIHN1cHBvcnRlZCBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mby4nKTsKICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgIHRocm93IGVycm9yOwogIH0KCiAgdmFyIHNhbHQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLnNhbHQpOwogIHZhciBjb3VudCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUuaXRlcmF0aW9ucyk7CiAgY291bnQgPSBjb3VudC5nZXRJbnQoY291bnQubGVuZ3RoKCkgPDwgMyk7CgogIHZhciBka0xlbiwgZEl2TGVuLCBjaXBoZXJGbjsKICBzd2l0Y2gob2lkKSB7CiAgICBjYXNlIHBraS5vaWRzWydwYmVXaXRoU0hBQW5kMy1LZXlUcmlwbGVERVMtQ0JDJ106CiAgICAgIGRrTGVuID0gMjQ7CiAgICAgIGRJdkxlbiA9IDg7CiAgICAgIGNpcGhlckZuID0gZm9yZ2UuZGVzLnN0YXJ0RGVjcnlwdGluZzsKICAgICAgYnJlYWs7CgogICAgY2FzZSBwa2kub2lkc1sncGJld2l0aFNIQUFuZDQwQml0UkMyLUNCQyddOgogICAgICBka0xlbiA9IDU7CiAgICAgIGRJdkxlbiA9IDg7CiAgICAgIGNpcGhlckZuID0gZnVuY3Rpb24oa2V5LCBpdikgewogICAgICAgIHZhciBjaXBoZXIgPSBmb3JnZS5yYzIuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcihrZXksIDQwKTsKICAgICAgICBjaXBoZXIuc3RhcnQoaXYsIG51bGwpOwogICAgICAgIHJldHVybiBjaXBoZXI7CiAgICAgIH07CiAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgUEtDUyAjMTIgUEJFIGRhdGEgYmxvY2suIFVuc3VwcG9ydGVkIE9JRC4nKTsKICAgICAgZXJyb3Iub2lkID0gb2lkOwogICAgICB0aHJvdyBlcnJvcjsKICB9CgogIHZhciBrZXkgPSBwa2kucGJlLmdlbmVyYXRlUGtjczEyS2V5KHBhc3N3b3JkLCBzYWx0LCAxLCBjb3VudCwgZGtMZW4pOwogIHZhciBpdiA9IHBraS5wYmUuZ2VuZXJhdGVQa2NzMTJLZXkocGFzc3dvcmQsIHNhbHQsIDIsIGNvdW50LCBkSXZMZW4pOwoKICByZXR1cm4gY2lwaGVyRm4oa2V5LCBpdik7Cn07CgovKioKICogT3BlblNTTCdzIGxlZ2FjeSBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbi4KICoKICogU2VlOiBodHRwOi8vd3d3Lm9wZW5zc2wub3JnL2RvY3MvY3J5cHRvL0VWUF9CeXRlc1RvS2V5Lmh0bWwKICoKICogQHBhcmFtIHBhc3N3b3JkIHRoZSBwYXNzd29yZCB0byBkZXJpdmUgdGhlIGtleSBmcm9tLgogKiBAcGFyYW0gc2FsdCB0aGUgc2FsdCB0byB1c2UsIG51bGwgZm9yIG5vbmUuCiAqIEBwYXJhbSBka0xlbiB0aGUgbnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCBmb3IgdGhlIGRlcml2ZWQga2V5LgogKiBAcGFyYW0gW29wdGlvbnNdIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgW21kXSBhbiBvcHRpb25hbCBtZXNzYWdlIGRpZ2VzdCBvYmplY3QgdG8gdXNlLgogKi8KcGtpLnBiZS5vcGVuc3NsRGVyaXZlQnl0ZXMgPSBmdW5jdGlvbihwYXNzd29yZCwgc2FsdCwgZGtMZW4sIG1kKSB7CiAgaWYodHlwZW9mIG1kID09PSAndW5kZWZpbmVkJyB8fCBtZCA9PT0gbnVsbCkgewogICAgbWQgPSBmb3JnZS5tZC5tZDUuY3JlYXRlKCk7CiAgfQogIGlmKHNhbHQgPT09IG51bGwpIHsKICAgIHNhbHQgPSAnJzsKICB9CiAgdmFyIGRpZ2VzdHMgPSBbaGFzaChtZCwgcGFzc3dvcmQgKyBzYWx0KV07CiAgZm9yKHZhciBsZW5ndGggPSAxNiwgaSA9IDE7IGxlbmd0aCA8IGRrTGVuOyArK2ksIGxlbmd0aCArPSAxNikgewogICAgZGlnZXN0cy5wdXNoKGhhc2gobWQsIGRpZ2VzdHNbaSAtIDFdICsgcGFzc3dvcmQgKyBzYWx0KSk7CiAgfQogIHJldHVybiBkaWdlc3RzLmpvaW4oJycpLnN1YnN0cigwLCBka0xlbik7Cn07CgpmdW5jdGlvbiBoYXNoKG1kLCBieXRlcykgewogIHJldHVybiBtZC5zdGFydCgpLnVwZGF0ZShieXRlcykuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKfQoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAncGJlJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3BiZScsWwogICdyZXF1aXJlJywKICAnbW9kdWxlJywKICAnLi9hZXMnLAogICcuL2FzbjEnLAogICcuL2RlcycsCiAgJy4vbWQnLAogICcuL29pZHMnLAogICcuL3BlbScsCiAgJy4vcGJrZGYyJywKICAnLi9yYW5kb20nLAogICcuL3JjMicsCiAgJy4vcnNhJywKICAnLi91dGlsJwpdLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIEFTTi4xIHZhbGlkYXRvcnMgZm9yIFBLQ1MjNyB2MS41LgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKiBAYXV0aG9yIFN0ZWZhbiBTaWVnbAogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTItMjAxNSBEaWdpdGFsIEJhemFhciwgSW5jLgogKiBDb3B5cmlnaHQgKGMpIDIwMTIgU3RlZmFuIFNpZWdsIDxzdGVzaWVAYnJva2VucGlwZS5kZT4KICoKICogVGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIFBLQ1MjNyBpcyBhcyBmb2xsb3dzCiAqIChzZWUgUkZDICMyMzE1IGZvciBkZXRhaWxzLCBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzE1LnR4dCk6CiAqCiAqIEEgUEtDUyM3IG1lc3NhZ2UgY29uc2lzdHMgb2YgYSBDb250ZW50SW5mbyBvbiByb290IGxldmVsLCB3aGljaCBtYXkKICogY29udGFpbiBhbnkgbnVtYmVyIG9mIGZ1cnRoZXIgQ29udGVudEluZm8gbmVzdGVkIGludG8gaXQuCiAqCiAqIENvbnRlbnRJbmZvIDo6PSBTRVFVRU5DRSB7CiAqICAgY29udGVudFR5cGUgICAgICAgICAgICAgICAgQ29udGVudFR5cGUsCiAqICAgY29udGVudCAgICAgICAgICAgICAgIFswXSAgRVhQTElDSVQgQU5ZIERFRklORUQgQlkgY29udGVudFR5cGUgT1BUSU9OQUwKICogfQogKgogKiBDb250ZW50VHlwZSA6Oj0gT0JKRUNUIElERU5USUZJRVIKICoKICogRW52ZWxvcGVkRGF0YSA6Oj0gU0VRVUVOQ0UgewogKiAgIHZlcnNpb24gICAgICAgICAgICAgICAgICAgIFZlcnNpb24sCiAqICAgcmVjaXBpZW50SW5mb3MgICAgICAgICAgICAgUmVjaXBpZW50SW5mb3MsCiAqICAgZW5jcnlwdGVkQ29udGVudEluZm8gICAgICAgRW5jcnlwdGVkQ29udGVudEluZm8KICogfQogKgogKiBFbmNyeXB0ZWREYXRhIDo6PSBTRVFVRU5DRSB7CiAqICAgdmVyc2lvbiAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiwKICogICBlbmNyeXB0ZWRDb250ZW50SW5mbyAgICAgICBFbmNyeXB0ZWRDb250ZW50SW5mbwogKiB9CiAqCiAqIGlkLXNpZ25lZERhdGEgT0JKRUNUIElERU5USUZJRVIgOjo9IHsgaXNvKDEpIG1lbWJlci1ib2R5KDIpCiAqICAgdXMoODQwKSByc2Fkc2koMTEzNTQ5KSBwa2NzKDEpIHBrY3M3KDcpIDIgfQogKgogKiBTaWduZWREYXRhIDo6PSBTRVFVRU5DRSB7CiAqICAgdmVyc2lvbiAgICAgICAgICAgSU5URUdFUiwKICogICBkaWdlc3RBbGdvcml0aG1zICBEaWdlc3RBbGdvcml0aG1JZGVudGlmaWVycywKICogICBjb250ZW50SW5mbyAgICAgICBDb250ZW50SW5mbywKICogICBjZXJ0aWZpY2F0ZXMgICAgICBbMF0gSU1QTElDSVQgQ2VydGlmaWNhdGVzIE9QVElPTkFMLAogKiAgIGNybHMgICAgICAgICAgICAgIFsxXSBJTVBMSUNJVCBDZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0cyBPUFRJT05BTCwKICogICBzaWduZXJJbmZvcyAgICAgICBTaWduZXJJbmZvcwogKiB9CiAqCiAqIFNpZ25lckluZm9zIDo6PSBTRVQgT0YgU2lnbmVySW5mbwogKgogKiBTaWduZXJJbmZvIDo6PSBTRVFVRU5DRSB7CiAqICAgdmVyc2lvbiAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiwKICogICBpc3N1ZXJBbmRTZXJpYWxOdW1iZXIgICAgICBJc3N1ZXJBbmRTZXJpYWxOdW1iZXIsCiAqICAgZGlnZXN0QWxnb3JpdGhtICAgICAgICAgICAgRGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllciwKICogICBhdXRoZW50aWNhdGVkQXR0cmlidXRlcyAgICBbMF0gSU1QTElDSVQgQXR0cmlidXRlcyBPUFRJT05BTCwKICogICBkaWdlc3RFbmNyeXB0aW9uQWxnb3JpdGhtICBEaWdlc3RFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciwKICogICBlbmNyeXB0ZWREaWdlc3QgICAgICAgICAgICBFbmNyeXB0ZWREaWdlc3QsCiAqICAgdW5hdXRoZW50aWNhdGVkQXR0cmlidXRlcyAgWzFdIElNUExJQ0lUIEF0dHJpYnV0ZXMgT1BUSU9OQUwKICogfQogKgogKiBFbmNyeXB0ZWREaWdlc3QgOjo9IE9DVEVUIFNUUklORwogKgogKiBBdHRyaWJ1dGVzIDo6PSBTRVQgT0YgQXR0cmlidXRlCiAqCiAqIEF0dHJpYnV0ZSA6Oj0gU0VRVUVOQ0UgewogKiAgIGF0dHJUeXBlICAgIE9CSkVDVCBJREVOVElGSUVSLAogKiAgIGF0dHJWYWx1ZXMgIFNFVCBPRiBBdHRyaWJ1dGVWYWx1ZQogKiB9CiAqCiAqIEF0dHJpYnV0ZVZhbHVlIDo6PSBBTlkKICoKICogVmVyc2lvbiA6Oj0gSU5URUdFUgogKgogKiBSZWNpcGllbnRJbmZvcyA6Oj0gU0VUIE9GIFJlY2lwaWVudEluZm8KICoKICogRW5jcnlwdGVkQ29udGVudEluZm8gOjo9IFNFUVVFTkNFIHsKICogICBjb250ZW50VHlwZSAgICAgICAgICAgICAgICAgQ29udGVudFR5cGUsCiAqICAgY29udGVudEVuY3J5cHRpb25BbGdvcml0aG0gIENvbnRlbnRFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciwKICogICBlbmNyeXB0ZWRDb250ZW50ICAgICAgIFswXSAgSU1QTElDSVQgRW5jcnlwdGVkQ29udGVudCBPUFRJT05BTAogKiB9CiAqCiAqIENvbnRlbnRFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciA6Oj0gQWxnb3JpdGhtSWRlbnRpZmllcgogKgogKiBUaGUgQWxnb3JpdGhtSWRlbnRpZmllciBjb250YWlucyBhbiBPYmplY3QgSWRlbnRpZmllciAoT0lEKSBhbmQgcGFyYW1ldGVycwogKiBmb3IgdGhlIGFsZ29yaXRobSwgaWYgYW55LiBJbiB0aGUgY2FzZSBvZiBBRVMgYW5kIERFUzMsIHRoZXJlIGlzIG9ubHkgb25lLAogKiB0aGUgSVYuCiAqCiAqIEFsZ29yaXRobUlkZW50aWZlciA6Oj0gU0VRVUVOQ0UgewogKiAgICBhbGdvcml0aG0gT0JKRUNUIElERU5USUZJRVIsCiAqICAgIHBhcmFtZXRlcnMgQU5ZIERFRklORUQgQlkgYWxnb3JpdGhtIE9QVElPTkFMCiAqIH0KICoKICogRW5jcnlwdGVkQ29udGVudCA6Oj0gT0NURVQgU1RSSU5HCiAqCiAqIFJlY2lwaWVudEluZm8gOjo9IFNFUVVFTkNFIHsKICogICB2ZXJzaW9uICAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiwKICogICBpc3N1ZXJBbmRTZXJpYWxOdW1iZXIgICAgICAgSXNzdWVyQW5kU2VyaWFsTnVtYmVyLAogKiAgIGtleUVuY3J5cHRpb25BbGdvcml0aG0gICAgICBLZXlFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciwKICogICBlbmNyeXB0ZWRLZXkgICAgICAgICAgICAgICAgRW5jcnlwdGVkS2V5CiAqIH0KICoKICogSXNzdWVyQW5kU2VyaWFsTnVtYmVyIDo6PSBTRVFVRU5DRSB7CiAqICAgaXNzdWVyICAgICAgICAgICAgICAgICAgICAgIE5hbWUsCiAqICAgc2VyaWFsTnVtYmVyICAgICAgICAgICAgICAgIENlcnRpZmljYXRlU2VyaWFsTnVtYmVyCiAqIH0KICoKICogQ2VydGlmaWNhdGVTZXJpYWxOdW1iZXIgOjo9IElOVEVHRVIKICoKICogS2V5RW5jcnlwdGlvbkFsZ29yaXRobUlkZW50aWZpZXIgOjo9IEFsZ29yaXRobUlkZW50aWZpZXIKICoKICogRW5jcnlwdGVkS2V5IDo6PSBPQ1RFVCBTVFJJTkcKICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovLyBzaG9ydGN1dCBmb3IgQVNOLjEgQVBJCnZhciBhc24xID0gZm9yZ2UuYXNuMTsKCi8vIHNob3J0Y3V0IGZvciBQS0NTIzcgQVBJCnZhciBwN3YgPSBmb3JnZS5wa2NzN2FzbjEgPSBmb3JnZS5wa2NzN2FzbjEgfHwge307CmZvcmdlLnBrY3M3ID0gZm9yZ2UucGtjczcgfHwge307CmZvcmdlLnBrY3M3LmFzbjEgPSBwN3Y7Cgp2YXIgY29udGVudEluZm9WYWxpZGF0b3IgPSB7CiAgbmFtZTogJ0NvbnRlbnRJbmZvJywKICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogIGNvbnN0cnVjdGVkOiB0cnVlLAogIHZhbHVlOiBbewogICAgbmFtZTogJ0NvbnRlbnRJbmZvLkNvbnRlbnRUeXBlJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5PSUQsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAnY29udGVudFR5cGUnCiAgfSwgewogICAgbmFtZTogJ0NvbnRlbnRJbmZvLmNvbnRlbnQnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgIHR5cGU6IDAsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIG9wdGlvbmFsOiB0cnVlLAogICAgY2FwdHVyZUFzbjE6ICdjb250ZW50JwogIH1dCn07CnA3di5jb250ZW50SW5mb1ZhbGlkYXRvciA9IGNvbnRlbnRJbmZvVmFsaWRhdG9yOwoKdmFyIGVuY3J5cHRlZENvbnRlbnRJbmZvVmFsaWRhdG9yID0gewogIG5hbWU6ICdFbmNyeXB0ZWRDb250ZW50SW5mbycsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdFbmNyeXB0ZWRDb250ZW50SW5mby5jb250ZW50VHlwZScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ2NvbnRlbnRUeXBlJwogIH0sIHsKICAgIG5hbWU6ICdFbmNyeXB0ZWRDb250ZW50SW5mby5jb250ZW50RW5jcnlwdGlvbkFsZ29yaXRobScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnRW5jcnlwdGVkQ29udGVudEluZm8uY29udGVudEVuY3J5cHRpb25BbGdvcml0aG0uYWxnb3JpdGhtJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdlbmNBbGdvcml0aG0nCiAgICB9LCB7CiAgICAgIG5hbWU6ICdFbmNyeXB0ZWRDb250ZW50SW5mby5jb250ZW50RW5jcnlwdGlvbkFsZ29yaXRobS5wYXJhbWV0ZXInLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIGNhcHR1cmVBc24xOiAnZW5jUGFyYW1ldGVyJwogICAgfV0KICB9LCB7CiAgICBuYW1lOiAnRW5jcnlwdGVkQ29udGVudEluZm8uZW5jcnlwdGVkQ29udGVudCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLAogICAgdHlwZTogMCwKICAgIC8qIFRoZSBQS0NTIzcgc3RydWN0dXJlIG91dHB1dCBieSBPcGVuU1NMIHNvbWV3aGF0IGRpZmZlcnMgZnJvbSB3aGF0CiAgICAgKiBvdGhlciBpbXBsZW1lbnRhdGlvbnMgZG8gZ2VuZXJhdGUuCiAgICAgKgogICAgICogT3BlblNTTCBnZW5lcmF0ZXMgYSBzdHJ1Y3R1cmUgbGlrZSB0aGlzOgogICAgICogU0VRVUVOQ0UgewogICAgICogICAgLi4uCiAgICAgKiAgICBbMF0KICAgICAqICAgICAgIDI2IERBIDY3IEQyIDE3IDlDIDQ1IDNDIEIxIDJBIEE4IDU5IDJGIDI5IDMzIDM4CiAgICAgKiAgICAgICBDMyBDMyBERiA4NiA3MSA3NCA3QSAxOSA5RiA0MCBEMCAyOSBCRSA4NSA5MCA0NQogICAgICogICAgICAgLi4uCiAgICAgKiB9CiAgICAgKgogICAgICogV2hlcmVhcyBvdGhlciBpbXBsZW1lbnRhdGlvbnMgKGFuZCB0aGlzIFBLQ1MjNyBtb2R1bGUpIGdlbmVyYXRlOgogICAgICogU0VRVUVOQ0UgewogICAgICogICAgLi4uCiAgICAgKiAgICBbMF0gewogICAgICogICAgICAgT0NURVQgU1RSSU5HCiAgICAgKiAgICAgICAgICAyNiBEQSA2NyBEMiAxNyA5QyA0NSAzQyBCMSAyQSBBOCA1OSAyRiAyOSAzMyAzOAogICAgICogICAgICAgICAgQzMgQzMgREYgODYgNzEgNzQgN0EgMTkgOUYgNDAgRDAgMjkgQkUgODUgOTAgNDUKICAgICAqICAgICAgICAgIC4uLgogICAgICogICAgfQogICAgICogfQogICAgICoKICAgICAqIEluIG9yZGVyIHRvIHN1cHBvcnQgYm90aCwgd2UganVzdCBjYXB0dXJlIHRoZSBjb250ZXh0IHNwZWNpZmljCiAgICAgKiBmaWVsZCBoZXJlLiAgVGhlIE9DVEVUIFNUUklORyBiaXQgaXMgcmVtb3ZlZCBiZWxvdy4KICAgICAqLwogICAgY2FwdHVyZTogJ2VuY3J5cHRlZENvbnRlbnQnLAogICAgY2FwdHVyZUFzbjE6ICdlbmNyeXB0ZWRDb250ZW50QXNuMScKICB9XQp9OwoKcDd2LmVudmVsb3BlZERhdGFWYWxpZGF0b3IgPSB7CiAgbmFtZTogJ0VudmVsb3BlZERhdGEnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnRW52ZWxvcGVkRGF0YS5WZXJzaW9uJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5JTlRFR0VSLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ZlcnNpb24nCiAgfSwgewogICAgbmFtZTogJ0VudmVsb3BlZERhdGEuUmVjaXBpZW50SW5mb3MnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLlNFVCwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgY2FwdHVyZUFzbjE6ICdyZWNpcGllbnRJbmZvcycKICB9XS5jb25jYXQoZW5jcnlwdGVkQ29udGVudEluZm9WYWxpZGF0b3IpCn07CgpwN3YuZW5jcnlwdGVkRGF0YVZhbGlkYXRvciA9IHsKICBuYW1lOiAnRW5jcnlwdGVkRGF0YScsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdFbmNyeXB0ZWREYXRhLlZlcnNpb24nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAndmVyc2lvbicKICB9XS5jb25jYXQoZW5jcnlwdGVkQ29udGVudEluZm9WYWxpZGF0b3IpCn07Cgp2YXIgc2lnbmVyVmFsaWRhdG9yID0gewogIG5hbWU6ICdTaWduZXJJbmZvJywKICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogIGNvbnN0cnVjdGVkOiB0cnVlLAogIHZhbHVlOiBbewogICAgbmFtZTogJ1NpZ25lckluZm8udmVyc2lvbicsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuSU5URUdFUiwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZQogIH0sIHsKICAgIG5hbWU6ICdTaWduZXJJbmZvLmlzc3VlckFuZFNlcmlhbE51bWJlcicsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnU2lnbmVySW5mby5pc3N1ZXJBbmRTZXJpYWxOdW1iZXIuaXNzdWVyJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgICBjYXB0dXJlQXNuMTogJ2lzc3VlcicKICAgIH0sIHsKICAgICAgbmFtZTogJ1NpZ25lckluZm8uaXNzdWVyQW5kU2VyaWFsTnVtYmVyLnNlcmlhbE51bWJlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ3NlcmlhbCcKICAgIH1dCiAgfSwgewogICAgbmFtZTogJ1NpZ25lckluZm8uZGlnZXN0QWxnb3JpdGhtJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdTaWduZXJJbmZvLmRpZ2VzdEFsZ29yaXRobS5hbGdvcml0aG0nLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5PSUQsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ2RpZ2VzdEFsZ29yaXRobScKICAgIH0sIHsKICAgICAgbmFtZTogJ1NpZ25lckluZm8uZGlnZXN0QWxnb3JpdGhtLnBhcmFtZXRlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICBjYXB0dXJlQXNuMTogJ2RpZ2VzdFBhcmFtZXRlcicsCiAgICAgIG9wdGlvbmFsOiB0cnVlCiAgICB9XQogIH0sIHsKICAgIG5hbWU6ICdTaWduZXJJbmZvLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICB0eXBlOiAwLAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICBvcHRpb25hbDogdHJ1ZSwKICAgIGNhcHR1cmU6ICdhdXRoZW50aWNhdGVkQXR0cmlidXRlcycKICB9LCB7CiAgICBuYW1lOiAnU2lnbmVySW5mby5kaWdlc3RFbmNyeXB0aW9uQWxnb3JpdGhtJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgY2FwdHVyZTogJ3NpZ25hdHVyZUFsZ29yaXRobScKICB9LCB7CiAgICBuYW1lOiAnU2lnbmVySW5mby5lbmNyeXB0ZWREaWdlc3QnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3NpZ25hdHVyZScKICB9LCB7CiAgICBuYW1lOiAnU2lnbmVySW5mby51bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICB0eXBlOiAxLAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICBvcHRpb25hbDogdHJ1ZSwKICAgIGNhcHR1cmU6ICd1bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzJwogIH1dCn07CgpwN3Yuc2lnbmVkRGF0YVZhbGlkYXRvciA9IHsKICBuYW1lOiAnU2lnbmVkRGF0YScsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdTaWduZWREYXRhLlZlcnNpb24nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAndmVyc2lvbicKICB9LCB7CiAgICBuYW1lOiAnU2lnbmVkRGF0YS5EaWdlc3RBbGdvcml0aG1zJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVQsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIGNhcHR1cmVBc24xOiAnZGlnZXN0QWxnb3JpdGhtcycKICB9LAogIGNvbnRlbnRJbmZvVmFsaWRhdG9yLAogIHsKICAgIG5hbWU6ICdTaWduZWREYXRhLkNlcnRpZmljYXRlcycsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLAogICAgdHlwZTogMCwKICAgIG9wdGlvbmFsOiB0cnVlLAogICAgY2FwdHVyZUFzbjE6ICdjZXJ0aWZpY2F0ZXMnCiAgfSwgewogICAgbmFtZTogJ1NpZ25lZERhdGEuQ2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdHMnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgIHR5cGU6IDEsCiAgICBvcHRpb25hbDogdHJ1ZSwKICAgIGNhcHR1cmVBc24xOiAnY3JscycKICB9LCB7CiAgICBuYW1lOiAnU2lnbmVkRGF0YS5TaWduZXJJbmZvcycsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VULAogICAgY2FwdHVyZTogJ3NpZ25lckluZm9zJywKICAgIG9wdGlvbmFsOiB0cnVlLAogICAgdmFsdWU6IFtzaWduZXJWYWxpZGF0b3JdCiAgfV0KfTsKCnA3di5yZWNpcGllbnRJbmZvVmFsaWRhdG9yID0gewogIG5hbWU6ICdSZWNpcGllbnRJbmZvJywKICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogIGNvbnN0cnVjdGVkOiB0cnVlLAogIHZhbHVlOiBbewogICAgbmFtZTogJ1JlY2lwaWVudEluZm8udmVyc2lvbicsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuSU5URUdFUiwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICd2ZXJzaW9uJwogIH0sIHsKICAgIG5hbWU6ICdSZWNpcGllbnRJbmZvLmlzc3VlckFuZFNlcmlhbCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnUmVjaXBpZW50SW5mby5pc3N1ZXJBbmRTZXJpYWwuaXNzdWVyJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgICBjYXB0dXJlQXNuMTogJ2lzc3VlcicKICAgIH0sIHsKICAgICAgbmFtZTogJ1JlY2lwaWVudEluZm8uaXNzdWVyQW5kU2VyaWFsLnNlcmlhbE51bWJlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ3NlcmlhbCcKICAgIH1dCiAgfSwgewogICAgbmFtZTogJ1JlY2lwaWVudEluZm8ua2V5RW5jcnlwdGlvbkFsZ29yaXRobScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnUmVjaXBpZW50SW5mby5rZXlFbmNyeXB0aW9uQWxnb3JpdGhtLmFsZ29yaXRobScsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLk9JRCwKICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICBjYXB0dXJlOiAnZW5jQWxnb3JpdGhtJwogICAgfSwgewogICAgICBuYW1lOiAnUmVjaXBpZW50SW5mby5rZXlFbmNyeXB0aW9uQWxnb3JpdGhtLnBhcmFtZXRlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICBjYXB0dXJlQXNuMTogJ2VuY1BhcmFtZXRlcicKICAgIH1dCiAgfSwgewogICAgbmFtZTogJ1JlY2lwaWVudEluZm8uZW5jcnlwdGVkS2V5JywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5PQ1RFVFNUUklORywKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdlbmNLZXknCiAgfV0KfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3BrY3M3YXNuMSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9wa2NzN2FzbjEnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9hc24xJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIG1hc2sgZ2VuZXJhdGlvbiBmdW5jdGlvbiBNR0YxLgogKgogKiBAYXV0aG9yIFN0ZWZhbiBTaWVnbAogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIgU3RlZmFuIFNpZWdsIDxzdGVzaWVAYnJva2VucGlwZS5kZT4KICogQ29weXJpZ2h0IChjKSAyMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKZm9yZ2UubWdmID0gZm9yZ2UubWdmIHx8IHt9Owp2YXIgbWdmMSA9IGZvcmdlLm1nZi5tZ2YxID0gZm9yZ2UubWdmMSA9IGZvcmdlLm1nZjEgfHwge307CgovKioKICogQ3JlYXRlcyBhIE1HRjEgbWFzayBnZW5lcmF0aW9uIGZ1bmN0aW9uIG9iamVjdC4KICoKICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBBUEkgdG8gdXNlIChlZzogZm9yZ2UubWQuc2hhMS5jcmVhdGUoKSkuCiAqCiAqIEByZXR1cm4gYSBtYXNrIGdlbmVyYXRpb24gZnVuY3Rpb24gb2JqZWN0LgogKi8KbWdmMS5jcmVhdGUgPSBmdW5jdGlvbihtZCkgewogIHZhciBtZ2YgPSB7CiAgICAvKioKICAgICAqIEdlbmVyYXRlIG1hc2sgb2Ygc3BlY2lmaWVkIGxlbmd0aC4KICAgICAqCiAgICAgKiBAcGFyYW0ge1N0cmluZ30gc2VlZCBUaGUgc2VlZCBmb3IgbWFzayBnZW5lcmF0aW9uLgogICAgICogQHBhcmFtIG1hc2tMZW4gTnVtYmVyIG9mIGJ5dGVzIHRvIGdlbmVyYXRlLgogICAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgZ2VuZXJhdGVkIG1hc2suCiAgICAgKi8KICAgIGdlbmVyYXRlOiBmdW5jdGlvbihzZWVkLCBtYXNrTGVuKSB7CiAgICAgIC8qIDIuIExldCBUIGJlIHRoZSBlbXB0eSBvY3RldCBzdHJpbmcuICovCiAgICAgIHZhciB0ID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwoKICAgICAgLyogMy4gRm9yIGNvdW50ZXIgZnJvbSAwIHRvIGNlaWwobWFza0xlbiAvIGhMZW4pLCBkbyB0aGUgZm9sbG93aW5nOiAqLwogICAgICB2YXIgbGVuID0gTWF0aC5jZWlsKG1hc2tMZW4gLyBtZC5kaWdlc3RMZW5ndGgpOwogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgICAvKiBhLiBDb252ZXJ0IGNvdW50ZXIgdG8gYW4gb2N0ZXQgc3RyaW5nIEMgb2YgbGVuZ3RoIDQgb2N0ZXRzICovCiAgICAgICAgdmFyIGMgPSBuZXcgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKCk7CiAgICAgICAgYy5wdXRJbnQzMihpKTsKCiAgICAgICAgLyogYi4gQ29uY2F0ZW5hdGUgdGhlIGhhc2ggb2YgdGhlIHNlZWQgbWdmU2VlZCBhbmQgQyB0byB0aGUgb2N0ZXQKICAgICAgICAgKiBzdHJpbmcgVDogKi8KICAgICAgICBtZC5zdGFydCgpOwogICAgICAgIG1kLnVwZGF0ZShzZWVkICsgYy5nZXRCeXRlcygpKTsKICAgICAgICB0LnB1dEJ1ZmZlcihtZC5kaWdlc3QoKSk7CiAgICAgIH0KCiAgICAgIC8qIE91dHB1dCB0aGUgbGVhZGluZyBtYXNrTGVuIG9jdGV0cyBvZiBUIGFzIHRoZSBvY3RldCBzdHJpbmcgbWFzay4gKi8KICAgICAgdC50cnVuY2F0ZSh0Lmxlbmd0aCgpIC0gbWFza0xlbik7CiAgICAgIHJldHVybiB0LmdldEJ5dGVzKCk7CiAgICB9CiAgfTsKCiAgcmV0dXJuIG1nZjsKfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ21nZjEnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvbWdmMScsWydyZXF1aXJlJywgJ21vZHVsZScsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogTm9kZS5qcyBtb2R1bGUgZm9yIEZvcmdlIG1hc2sgZ2VuZXJhdGlvbiBmdW5jdGlvbnMuCiAqCiAqIEBhdXRob3IgU3RlZmFuIFNpZWdsCiAqCiAqIENvcHlyaWdodCAyMDEyIFN0ZWZhbiBTaWVnbCA8c3Rlc2llQGJyb2tlbnBpcGUuZGU+CiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKZm9yZ2UubWdmID0gZm9yZ2UubWdmIHx8IHt9Owpmb3JnZS5tZ2YubWdmMSA9IGZvcmdlLm1nZjE7Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdtZ2YnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvbWdmJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vbWdmMSddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIFBLQ1MjMSBQU1Mgc2lnbmF0dXJlIHBhZGRpbmcuCiAqCiAqIEBhdXRob3IgU3RlZmFuIFNpZWdsCiAqCiAqIENvcHlyaWdodCAoYykgMjAxMiBTdGVmYW4gU2llZ2wgPHN0ZXNpZUBicm9rZW5waXBlLmRlPgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8vIHNob3J0Y3V0IGZvciBQU1MgQVBJCnZhciBwc3MgPSBmb3JnZS5wc3MgPSBmb3JnZS5wc3MgfHwge307CgovKioKICogQ3JlYXRlcyBhIFBTUyBzaWduYXR1cmUgc2NoZW1lIG9iamVjdC4KICoKICogVGhlcmUgYXJlIHNldmVyYWwgd2F5cyB0byBwcm92aWRlIGEgc2FsdCBmb3IgZW5jb2Rpbmc6CiAqCiAqIDEuIFNwZWNpZnkgdGhlIHNhbHRMZW5ndGggb25seSBhbmQgdGhlIGJ1aWx0LWluIFBSTkcgd2lsbCBnZW5lcmF0ZSBpdC4KICogMi4gU3BlY2lmeSB0aGUgc2FsdExlbmd0aCBhbmQgYSBjdXN0b20gUFJORyB3aXRoICdnZXRCeXRlc1N5bmMnIGRlZmluZWQgdGhhdAogKiAgIHdpbGwgYmUgdXNlZC4KICogMy4gU3BlY2lmeSB0aGUgc2FsdCBpdHNlbGYgYXMgYSBmb3JnZS51dGlsLkJ5dGVCdWZmZXIuCiAqCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgbWQgdGhlIG1lc3NhZ2UgZGlnZXN0IG9iamVjdCB0byB1c2UsIGEgZm9yZ2UgbWQgaW5zdGFuY2UuCiAqICAgICAgICAgIG1nZiB0aGUgbWFzayBnZW5lcmF0aW9uIGZ1bmN0aW9uIHRvIHVzZSwgYSBmb3JnZSBtZ2YgaW5zdGFuY2UuCiAqICAgICAgICAgIFtzYWx0TGVuZ3RoXSB0aGUgbGVuZ3RoIG9mIHRoZSBzYWx0IGluIG9jdGV0cy4KICogICAgICAgICAgW3BybmddIHRoZSBwc2V1ZG8tcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgdG8gdXNlIHRvIHByb2R1Y2UgYSBzYWx0LgogKiAgICAgICAgICBbc2FsdF0gdGhlIHNhbHQgdG8gdXNlIHdoZW4gZW5jb2RpbmcuCiAqCiAqIEByZXR1cm4gYSBzaWduYXR1cmUgc2NoZW1lIG9iamVjdC4KICovCnBzcy5jcmVhdGUgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgLy8gYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgdy9sZWdhY3kgYXJnczogaGFzaCwgbWdmLCBzTGVuCiAgaWYoYXJndW1lbnRzLmxlbmd0aCA9PT0gMykgewogICAgb3B0aW9ucyA9IHsKICAgICAgbWQ6IGFyZ3VtZW50c1swXSwKICAgICAgbWdmOiBhcmd1bWVudHNbMV0sCiAgICAgIHNhbHRMZW5ndGg6IGFyZ3VtZW50c1syXQogICAgfTsKICB9CgogIHZhciBoYXNoID0gb3B0aW9ucy5tZDsKICB2YXIgbWdmID0gb3B0aW9ucy5tZ2Y7CiAgdmFyIGhMZW4gPSBoYXNoLmRpZ2VzdExlbmd0aDsKCiAgdmFyIHNhbHRfID0gb3B0aW9ucy5zYWx0IHx8IG51bGw7CiAgaWYodHlwZW9mIHNhbHRfID09PSAnc3RyaW5nJykgewogICAgLy8gYXNzdW1lIGJpbmFyeS1lbmNvZGVkIHN0cmluZwogICAgc2FsdF8gPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihzYWx0Xyk7CiAgfQoKICB2YXIgc0xlbjsKICBpZignc2FsdExlbmd0aCcgaW4gb3B0aW9ucykgewogICAgc0xlbiA9IG9wdGlvbnMuc2FsdExlbmd0aDsKICB9IGVsc2UgaWYoc2FsdF8gIT09IG51bGwpIHsKICAgIHNMZW4gPSBzYWx0Xy5sZW5ndGgoKTsKICB9IGVsc2UgewogICAgdGhyb3cgbmV3IEVycm9yKCdTYWx0IGxlbmd0aCBub3Qgc3BlY2lmaWVkIG9yIHNwZWNpZmljIHNhbHQgbm90IGdpdmVuLicpOwogIH0KCiAgaWYoc2FsdF8gIT09IG51bGwgJiYgc2FsdF8ubGVuZ3RoKCkgIT09IHNMZW4pIHsKICAgIHRocm93IG5ldyBFcnJvcignR2l2ZW4gc2FsdCBsZW5ndGggZG9lcyBub3QgbWF0Y2ggbGVuZ3RoIG9mIGdpdmVuIHNhbHQuJyk7CiAgfQoKICB2YXIgcHJuZyA9IG9wdGlvbnMucHJuZyB8fCBmb3JnZS5yYW5kb207CgogIHZhciBwc3NvYmogPSB7fTsKCiAgLyoqCiAgICogRW5jb2RlcyBhIFBTUyBzaWduYXR1cmUuCiAgICoKICAgKiBUaGlzIGZ1bmN0aW9uIGltcGxlbWVudHMgRU1TQS1QU1MtRU5DT0RFIGFzIHBlciBSRkMgMzQ0Nywgc2VjdGlvbiA5LjEuMS4KICAgKgogICAqIEBwYXJhbSBtZCB0aGUgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0IHdpdGggdGhlIGhhc2ggdG8gc2lnbi4KICAgKiBAcGFyYW0gbW9kc0JpdHMgdGhlIGxlbmd0aCBvZiB0aGUgUlNBIG1vZHVsdXMgaW4gYml0cy4KICAgKgogICAqIEByZXR1cm4gdGhlIGVuY29kZWQgbWVzc2FnZSBhcyBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZyBvZiBsZW5ndGgKICAgKiAgICAgICAgICAgY2VpbCgobW9kQml0cyAtIDEpIC8gOCkuCiAgICovCiAgcHNzb2JqLmVuY29kZSA9IGZ1bmN0aW9uKG1kLCBtb2RCaXRzKSB7CiAgICB2YXIgaTsKICAgIHZhciBlbUJpdHMgPSBtb2RCaXRzIC0gMTsKICAgIHZhciBlbUxlbiA9IE1hdGguY2VpbChlbUJpdHMgLyA4KTsKCiAgICAvKiAyLiBMZXQgbUhhc2ggPSBIYXNoKE0pLCBhbiBvY3RldCBzdHJpbmcgb2YgbGVuZ3RoIGhMZW4uICovCiAgICB2YXIgbUhhc2ggPSBtZC5kaWdlc3QoKS5nZXRCeXRlcygpOwoKICAgIC8qIDMuIElmIGVtTGVuIDwgaExlbiArIHNMZW4gKyAyLCBvdXRwdXQgImVuY29kaW5nIGVycm9yIiBhbmQgc3RvcC4gKi8KICAgIGlmKGVtTGVuIDwgaExlbiArIHNMZW4gKyAyKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignTWVzc2FnZSBpcyB0b28gbG9uZyB0byBlbmNyeXB0LicpOwogICAgfQoKICAgIC8qIDQuIEdlbmVyYXRlIGEgcmFuZG9tIG9jdGV0IHN0cmluZyBzYWx0IG9mIGxlbmd0aCBzTGVuOyBpZiBzTGVuID0gMCwKICAgICAqICAgIHRoZW4gc2FsdCBpcyB0aGUgZW1wdHkgc3RyaW5nLiAqLwogICAgdmFyIHNhbHQ7CiAgICBpZihzYWx0XyA9PT0gbnVsbCkgewogICAgICBzYWx0ID0gcHJuZy5nZXRCeXRlc1N5bmMoc0xlbik7CiAgICB9IGVsc2UgewogICAgICBzYWx0ID0gc2FsdF8uYnl0ZXMoKTsKICAgIH0KCiAgICAvKiA1LiBMZXQgTScgPSAoMHgpMDAgMDAgMDAgMDAgMDAgMDAgMDAgMDAgfHwgbUhhc2ggfHwgc2FsdDsgKi8KICAgIHZhciBtXyA9IG5ldyBmb3JnZS51dGlsLkJ5dGVCdWZmZXIoKTsKICAgIG1fLmZpbGxXaXRoQnl0ZSgwLCA4KTsKICAgIG1fLnB1dEJ5dGVzKG1IYXNoKTsKICAgIG1fLnB1dEJ5dGVzKHNhbHQpOwoKICAgIC8qIDYuIExldCBIID0gSGFzaChNJyksIGFuIG9jdGV0IHN0cmluZyBvZiBsZW5ndGggaExlbi4gKi8KICAgIGhhc2guc3RhcnQoKTsKICAgIGhhc2gudXBkYXRlKG1fLmdldEJ5dGVzKCkpOwogICAgdmFyIGggPSBoYXNoLmRpZ2VzdCgpLmdldEJ5dGVzKCk7CgogICAgLyogNy4gR2VuZXJhdGUgYW4gb2N0ZXQgc3RyaW5nIFBTIGNvbnNpc3Rpbmcgb2YgZW1MZW4gLSBzTGVuIC0gaExlbiAtIDIKICAgICAqICAgIHplcm8gb2N0ZXRzLiAgVGhlIGxlbmd0aCBvZiBQUyBtYXkgYmUgMC4gKi8KICAgIHZhciBwcyA9IG5ldyBmb3JnZS51dGlsLkJ5dGVCdWZmZXIoKTsKICAgIHBzLmZpbGxXaXRoQnl0ZSgwLCBlbUxlbiAtIHNMZW4gLSBoTGVuIC0gMik7CgogICAgLyogOC4gTGV0IERCID0gUFMgfHwgMHgwMSB8fCBzYWx0OyBEQiBpcyBhbiBvY3RldCBzdHJpbmcgb2YgbGVuZ3RoCiAgICAgKiAgICBlbUxlbiAtIGhMZW4gLSAxLiAqLwogICAgcHMucHV0Qnl0ZSgweDAxKTsKICAgIHBzLnB1dEJ5dGVzKHNhbHQpOwogICAgdmFyIGRiID0gcHMuZ2V0Qnl0ZXMoKTsKCiAgICAvKiA5LiBMZXQgZGJNYXNrID0gTUdGKEgsIGVtTGVuIC0gaExlbiAtIDEpLiAqLwogICAgdmFyIG1hc2tMZW4gPSBlbUxlbiAtIGhMZW4gLSAxOwogICAgdmFyIGRiTWFzayA9IG1nZi5nZW5lcmF0ZShoLCBtYXNrTGVuKTsKCiAgICAvKiAxMC4gTGV0IG1hc2tlZERCID0gREIgXHhvciBkYk1hc2suICovCiAgICB2YXIgbWFza2VkREIgPSAnJzsKICAgIGZvcihpID0gMDsgaSA8IG1hc2tMZW47IGkgKyspIHsKICAgICAgbWFza2VkREIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShkYi5jaGFyQ29kZUF0KGkpIF4gZGJNYXNrLmNoYXJDb2RlQXQoaSkpOwogICAgfQoKICAgIC8qIDExLiBTZXQgdGhlIGxlZnRtb3N0IDhlbUxlbiAtIGVtQml0cyBiaXRzIG9mIHRoZSBsZWZ0bW9zdCBvY3RldCBpbgogICAgICogICAgIG1hc2tlZERCIHRvIHplcm8uICovCiAgICB2YXIgbWFzayA9ICgweEZGMDAgPj4gKDggKiBlbUxlbiAtIGVtQml0cykpICYgMHhGRjsKICAgIG1hc2tlZERCID0gU3RyaW5nLmZyb21DaGFyQ29kZShtYXNrZWREQi5jaGFyQ29kZUF0KDApICYgfm1hc2spICsKICAgICAgbWFza2VkREIuc3Vic3RyKDEpOwoKICAgIC8qIDEyLiBMZXQgRU0gPSBtYXNrZWREQiB8fCBIIHx8IDB4YmMuCiAgICAgKiAxMy4gT3V0cHV0IEVNLiAqLwogICAgcmV0dXJuIG1hc2tlZERCICsgaCArIFN0cmluZy5mcm9tQ2hhckNvZGUoMHhiYyk7CiAgfTsKCiAgLyoqCiAgICogVmVyaWZpZXMgYSBQU1Mgc2lnbmF0dXJlLgogICAqCiAgICogVGhpcyBmdW5jdGlvbiBpbXBsZW1lbnRzIEVNU0EtUFNTLVZFUklGWSBhcyBwZXIgUkZDIDM0NDcsIHNlY3Rpb24gOS4xLjIuCiAgICoKICAgKiBAcGFyYW0gbUhhc2ggdGhlIG1lc3NhZ2UgZGlnZXN0IGhhc2gsIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nLCB0bwogICAqICAgICAgICAgY29tcGFyZSBhZ2FpbnN0IHRoZSBzaWduYXR1cmUuCiAgICogQHBhcmFtIGVtIHRoZSBlbmNvZGVkIG1lc3NhZ2UsIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nCiAgICogICAgICAgICAgKFJTQSBkZWNyeXB0aW9uIHJlc3VsdCkuCiAgICogQHBhcmFtIG1vZHNCaXRzIHRoZSBsZW5ndGggb2YgdGhlIFJTQSBtb2R1bHVzIGluIGJpdHMuCiAgICoKICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHNpZ25hdHVyZSB3YXMgdmVyaWZpZWQsIGZhbHNlIGlmIG5vdC4KICAgKi8KICBwc3NvYmoudmVyaWZ5ID0gZnVuY3Rpb24obUhhc2gsIGVtLCBtb2RCaXRzKSB7CiAgICB2YXIgaTsKICAgIHZhciBlbUJpdHMgPSBtb2RCaXRzIC0gMTsKICAgIHZhciBlbUxlbiA9IE1hdGguY2VpbChlbUJpdHMgLyA4KTsKCiAgICAvKiBjLiBDb252ZXJ0IHRoZSBtZXNzYWdlIHJlcHJlc2VudGF0aXZlIG0gdG8gYW4gZW5jb2RlZCBtZXNzYWdlIEVNCiAgICAgKiAgICBvZiBsZW5ndGggZW1MZW4gPSBjZWlsKChtb2RCaXRzIC0gMSkgLyA4KSBvY3RldHMsIHdoZXJlIG1vZEJpdHMKICAgICAqICAgIGlzIHRoZSBsZW5ndGggaW4gYml0cyBvZiB0aGUgUlNBIG1vZHVsdXMgbiAqLwogICAgZW0gPSBlbS5zdWJzdHIoLWVtTGVuKTsKCiAgICAvKiAzLiBJZiBlbUxlbiA8IGhMZW4gKyBzTGVuICsgMiwgb3V0cHV0ICJpbmNvbnNpc3RlbnQiIGFuZCBzdG9wLiAqLwogICAgaWYoZW1MZW4gPCBoTGVuICsgc0xlbiArIDIpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbmNvbnNpc3RlbnQgcGFyYW1ldGVycyB0byBQU1Mgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbi4nKTsKICAgIH0KCiAgICAvKiA0LiBJZiB0aGUgcmlnaHRtb3N0IG9jdGV0IG9mIEVNIGRvZXMgbm90IGhhdmUgaGV4YWRlY2ltYWwgdmFsdWUKICAgICAqICAgIDB4YmMsIG91dHB1dCAiaW5jb25zaXN0ZW50IiBhbmQgc3RvcC4gKi8KICAgIGlmKGVtLmNoYXJDb2RlQXQoZW1MZW4gLSAxKSAhPT0gMHhiYykgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VuY29kZWQgbWVzc2FnZSBkb2VzIG5vdCBlbmQgaW4gMHhCQy4nKTsKICAgIH0KCiAgICAvKiA1LiBMZXQgbWFza2VkREIgYmUgdGhlIGxlZnRtb3N0IGVtTGVuIC0gaExlbiAtIDEgb2N0ZXRzIG9mIEVNLCBhbmQKICAgICAqICAgIGxldCBIIGJlIHRoZSBuZXh0IGhMZW4gb2N0ZXRzLiAqLwogICAgdmFyIG1hc2tMZW4gPSBlbUxlbiAtIGhMZW4gLSAxOwogICAgdmFyIG1hc2tlZERCID0gZW0uc3Vic3RyKDAsIG1hc2tMZW4pOwogICAgdmFyIGggPSBlbS5zdWJzdHIobWFza0xlbiwgaExlbik7CgogICAgLyogNi4gSWYgdGhlIGxlZnRtb3N0IDhlbUxlbiAtIGVtQml0cyBiaXRzIG9mIHRoZSBsZWZ0bW9zdCBvY3RldCBpbgogICAgICogICAgbWFza2VkREIgYXJlIG5vdCBhbGwgZXF1YWwgdG8gemVybywgb3V0cHV0ICJpbmNvbnNpc3RlbnQiIGFuZCBzdG9wLiAqLwogICAgdmFyIG1hc2sgPSAoMHhGRjAwID4+ICg4ICogZW1MZW4gLSBlbUJpdHMpKSAmIDB4RkY7CiAgICBpZigobWFza2VkREIuY2hhckNvZGVBdCgwKSAmIG1hc2spICE9PSAwKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignQml0cyBiZXlvbmQga2V5c2l6ZSBub3QgemVybyBhcyBleHBlY3RlZC4nKTsKICAgIH0KCiAgICAvKiA3LiBMZXQgZGJNYXNrID0gTUdGKEgsIGVtTGVuIC0gaExlbiAtIDEpLiAqLwogICAgdmFyIGRiTWFzayA9IG1nZi5nZW5lcmF0ZShoLCBtYXNrTGVuKTsKCiAgICAvKiA4LiBMZXQgREIgPSBtYXNrZWREQiBceG9yIGRiTWFzay4gKi8KICAgIHZhciBkYiA9ICcnOwogICAgZm9yKGkgPSAwOyBpIDwgbWFza0xlbjsgaSArKykgewogICAgICBkYiArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKG1hc2tlZERCLmNoYXJDb2RlQXQoaSkgXiBkYk1hc2suY2hhckNvZGVBdChpKSk7CiAgICB9CgogICAgLyogOS4gU2V0IHRoZSBsZWZ0bW9zdCA4ZW1MZW4gLSBlbUJpdHMgYml0cyBvZiB0aGUgbGVmdG1vc3Qgb2N0ZXQKICAgICAqIGluIERCIHRvIHplcm8uICovCiAgICBkYiA9IFN0cmluZy5mcm9tQ2hhckNvZGUoZGIuY2hhckNvZGVBdCgwKSAmIH5tYXNrKSArIGRiLnN1YnN0cigxKTsKCiAgICAvKiAxMC4gSWYgdGhlIGVtTGVuIC0gaExlbiAtIHNMZW4gLSAyIGxlZnRtb3N0IG9jdGV0cyBvZiBEQiBhcmUgbm90IHplcm8KICAgICAqIG9yIGlmIHRoZSBvY3RldCBhdCBwb3NpdGlvbiBlbUxlbiAtIGhMZW4gLSBzTGVuIC0gMSAodGhlIGxlZnRtb3N0CiAgICAgKiBwb3NpdGlvbiBpcyAicG9zaXRpb24gMSIpIGRvZXMgbm90IGhhdmUgaGV4YWRlY2ltYWwgdmFsdWUgMHgwMSwKICAgICAqIG91dHB1dCAiaW5jb25zaXN0ZW50IiBhbmQgc3RvcC4gKi8KICAgIHZhciBjaGVja0xlbiA9IGVtTGVuIC0gaExlbiAtIHNMZW4gLSAyOwogICAgZm9yKGkgPSAwOyBpIDwgY2hlY2tMZW47IGkgKyspIHsKICAgICAgaWYoZGIuY2hhckNvZGVBdChpKSAhPT0gMHgwMCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcignTGVmdG1vc3Qgb2N0ZXRzIG5vdCB6ZXJvIGFzIGV4cGVjdGVkJyk7CiAgICAgIH0KICAgIH0KCiAgICBpZihkYi5jaGFyQ29kZUF0KGNoZWNrTGVuKSAhPT0gMHgwMSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ0luY29uc2lzdGVudCBQU1Mgc2lnbmF0dXJlLCAweDAxIG1hcmtlciBub3QgZm91bmQnKTsKICAgIH0KCiAgICAvKiAxMS4gTGV0IHNhbHQgYmUgdGhlIGxhc3Qgc0xlbiBvY3RldHMgb2YgREIuICovCiAgICB2YXIgc2FsdCA9IGRiLnN1YnN0cigtc0xlbik7CgogICAgLyogMTIuICBMZXQgTScgPSAoMHgpMDAgMDAgMDAgMDAgMDAgMDAgMDAgMDAgfHwgbUhhc2ggfHwgc2FsdCAqLwogICAgdmFyIG1fID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwogICAgbV8uZmlsbFdpdGhCeXRlKDAsIDgpOwogICAgbV8ucHV0Qnl0ZXMobUhhc2gpOwogICAgbV8ucHV0Qnl0ZXMoc2FsdCk7CgogICAgLyogMTMuIExldCBIJyA9IEhhc2goTScpLCBhbiBvY3RldCBzdHJpbmcgb2YgbGVuZ3RoIGhMZW4uICovCiAgICBoYXNoLnN0YXJ0KCk7CiAgICBoYXNoLnVwZGF0ZShtXy5nZXRCeXRlcygpKTsKICAgIHZhciBoXyA9IGhhc2guZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKCiAgICAvKiAxNC4gSWYgSCA9IEgnLCBvdXRwdXQgImNvbnNpc3RlbnQuIiBPdGhlcndpc2UsIG91dHB1dCAiaW5jb25zaXN0ZW50LiIgKi8KICAgIHJldHVybiBoID09PSBoXzsKICB9OwoKICByZXR1cm4gcHNzb2JqOwp9OwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAncHNzJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3BzcycsWydyZXF1aXJlJywgJ21vZHVsZScsICcuL3JhbmRvbScsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBYLjUwOSBhbmQgcmVsYXRlZCBjb21wb25lbnRzIChzdWNoIGFzCiAqIENlcnRpZmljYXRpb24gU2lnbmluZyBSZXF1ZXN0cykgb2YgYSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKgogKiBUaGUgQVNOLjEgcmVwcmVzZW50YXRpb24gb2YgYW4gWC41MDl2MyBjZXJ0aWZpY2F0ZSBpcyBhcyBmb2xsb3dzCiAqIChzZWUgUkZDIDI0NTkpOgogKgogKiBDZXJ0aWZpY2F0ZSA6Oj0gU0VRVUVOQ0UgewogKiAgIHRic0NlcnRpZmljYXRlICAgICAgIFRCU0NlcnRpZmljYXRlLAogKiAgIHNpZ25hdHVyZUFsZ29yaXRobSAgIEFsZ29yaXRobUlkZW50aWZpZXIsCiAqICAgc2lnbmF0dXJlVmFsdWUgICAgICAgQklUIFNUUklORwogKiB9CiAqCiAqIFRCU0NlcnRpZmljYXRlIDo6PSBTRVFVRU5DRSB7CiAqICAgdmVyc2lvbiAgICAgICAgIFswXSAgRVhQTElDSVQgVmVyc2lvbiBERUZBVUxUIHYxLAogKiAgIHNlcmlhbE51bWJlciAgICAgICAgIENlcnRpZmljYXRlU2VyaWFsTnVtYmVyLAogKiAgIHNpZ25hdHVyZSAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIsCiAqICAgaXNzdWVyICAgICAgICAgICAgICAgTmFtZSwKICogICB2YWxpZGl0eSAgICAgICAgICAgICBWYWxpZGl0eSwKICogICBzdWJqZWN0ICAgICAgICAgICAgICBOYW1lLAogKiAgIHN1YmplY3RQdWJsaWNLZXlJbmZvIFN1YmplY3RQdWJsaWNLZXlJbmZvLAogKiAgIGlzc3VlclVuaXF1ZUlEICBbMV0gIElNUExJQ0lUIFVuaXF1ZUlkZW50aWZpZXIgT1BUSU9OQUwsCiAqICAgICAgICAgICAgICAgICAgICAgICAgLS0gSWYgcHJlc2VudCwgdmVyc2lvbiBzaGFsbCBiZSB2MiBvciB2MwogKiAgIHN1YmplY3RVbmlxdWVJRCBbMl0gIElNUExJQ0lUIFVuaXF1ZUlkZW50aWZpZXIgT1BUSU9OQUwsCiAqICAgICAgICAgICAgICAgICAgICAgICAgLS0gSWYgcHJlc2VudCwgdmVyc2lvbiBzaGFsbCBiZSB2MiBvciB2MwogKiAgIGV4dGVuc2lvbnMgICAgICBbM10gIEVYUExJQ0lUIEV4dGVuc2lvbnMgT1BUSU9OQUwKICogICAgICAgICAgICAgICAgICAgICAgICAtLSBJZiBwcmVzZW50LCB2ZXJzaW9uIHNoYWxsIGJlIHYzCiAqIH0KICoKICogVmVyc2lvbiA6Oj0gSU5URUdFUiAgeyB2MSgwKSwgdjIoMSksIHYzKDIpIH0KICoKICogQ2VydGlmaWNhdGVTZXJpYWxOdW1iZXIgOjo9IElOVEVHRVIKICoKICogTmFtZSA6Oj0gQ0hPSUNFIHsKICogICAvLyBvbmx5IG9uZSBwb3NzaWJsZSBjaG9pY2UgZm9yIG5vdwogKiAgIFJETlNlcXVlbmNlCiAqIH0KICoKICogUkROU2VxdWVuY2UgOjo9IFNFUVVFTkNFIE9GIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUKICoKICogUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZSA6Oj0gU0VUIE9GIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZQogKgogKiBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgOjo9IFNFUVVFTkNFIHsKICogICB0eXBlICAgICBBdHRyaWJ1dGVUeXBlLAogKiAgIHZhbHVlICAgIEF0dHJpYnV0ZVZhbHVlCiAqIH0KICogQXR0cmlidXRlVHlwZSA6Oj0gT0JKRUNUIElERU5USUZJRVIKICogQXR0cmlidXRlVmFsdWUgOjo9IEFOWSBERUZJTkVEIEJZIEF0dHJpYnV0ZVR5cGUKICoKICogVmFsaWRpdHkgOjo9IFNFUVVFTkNFIHsKICogICBub3RCZWZvcmUgICAgICBUaW1lLAogKiAgIG5vdEFmdGVyICAgICAgIFRpbWUKICogfQogKgogKiBUaW1lIDo6PSBDSE9JQ0UgewogKiAgIHV0Y1RpbWUgICAgICAgIFVUQ1RpbWUsCiAqICAgZ2VuZXJhbFRpbWUgICAgR2VuZXJhbGl6ZWRUaW1lCiAqIH0KICoKICogVW5pcXVlSWRlbnRpZmllciA6Oj0gQklUIFNUUklORwogKgogKiBTdWJqZWN0UHVibGljS2V5SW5mbyA6Oj0gU0VRVUVOQ0UgewogKiAgIGFsZ29yaXRobSAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIsCiAqICAgc3ViamVjdFB1YmxpY0tleSAgICAgQklUIFNUUklORwogKiB9CiAqCiAqIEV4dGVuc2lvbnMgOjo9IFNFUVVFTkNFIFNJWkUgKDEuLk1BWCkgT0YgRXh0ZW5zaW9uCiAqCiAqIEV4dGVuc2lvbiA6Oj0gU0VRVUVOQ0UgewogKiAgIGV4dG5JRCAgICAgIE9CSkVDVCBJREVOVElGSUVSLAogKiAgIGNyaXRpY2FsICAgIEJPT0xFQU4gREVGQVVMVCBGQUxTRSwKICogICBleHRuVmFsdWUgICBPQ1RFVCBTVFJJTkcKICogfQogKgogKiBUaGUgb25seSBrZXkgYWxnb3JpdGhtIGN1cnJlbnRseSBzdXBwb3J0ZWQgZm9yIFBLSSBpcyBSU0EuCiAqCiAqIFJTQVNTQS1QU1Mgc2lnbmF0dXJlcyBhcmUgZGVzY3JpYmVkIGluIFJGQyAzNDQ3IGFuZCBSRkMgNDA1NS4KICoKICogUEtDUyMxMCB2MS43IGRlc2NyaWJlcyBjZXJ0aWZpY2F0ZSBzaWduaW5nIHJlcXVlc3RzOgogKgogKiBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm86CiAqCiAqIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyA6Oj0gU0VRVUVOQ0UgewogKiAgIHZlcnNpb24gICAgICAgSU5URUdFUiB7IHYxKDApIH0gKHYxLC4uLiksCiAqICAgc3ViamVjdCAgICAgICBOYW1lLAogKiAgIHN1YmplY3RQS0luZm8gU3ViamVjdFB1YmxpY0tleUluZm97eyBQS0luZm9BbGdvcml0aG1zIH19LAogKiAgIGF0dHJpYnV0ZXMgICAgWzBdIEF0dHJpYnV0ZXN7eyBDUklBdHRyaWJ1dGVzIH19CiAqIH0KICoKICogQXR0cmlidXRlcyB7IEFUVFJJQlVURTpJT1NldCB9IDo6PSBTRVQgT0YgQXR0cmlidXRle3sgSU9TZXQgfX0KICoKICogQ1JJQXR0cmlidXRlcyAgQVRUUklCVVRFICA6Oj0gewogKiAgIC4uLiAtLSBhZGQgYW55IGxvY2FsbHkgZGVmaW5lZCBhdHRyaWJ1dGVzIGhlcmUgLS0gfQogKgogKiBBdHRyaWJ1dGUgeyBBVFRSSUJVVEU6SU9TZXQgfSA6Oj0gU0VRVUVOQ0UgewogKiAgIHR5cGUgICBBVFRSSUJVVEUuJmlkKHtJT1NldH0pLAogKiAgIHZhbHVlcyBTRVQgU0laRSgxLi5NQVgpIE9GIEFUVFJJQlVURS4mVHlwZSh7SU9TZXR9e0B0eXBlfSkKICogfQogKgogKiBDZXJ0aWZpY2F0aW9uUmVxdWVzdCA6Oj0gU0VRVUVOQ0UgewogKiAgIGNlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8sCiAqICAgc2lnbmF0dXJlQWxnb3JpdGhtIEFsZ29yaXRobUlkZW50aWZpZXJ7eyBTaWduYXR1cmVBbGdvcml0aG1zIH19LAogKiAgIHNpZ25hdHVyZSAgICAgICAgICBCSVQgU1RSSU5HCiAqIH0KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovLyBzaG9ydGN1dCBmb3IgYXNuLjEgQVBJCnZhciBhc24xID0gZm9yZ2UuYXNuMTsKCi8qIFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUgKFBLSSkgaW1wbGVtZW50YXRpb24uICovCnZhciBwa2kgPSBmb3JnZS5wa2kgPSBmb3JnZS5wa2kgfHwge307CnZhciBvaWRzID0gcGtpLm9pZHM7CgovLyBzaG9ydCBuYW1lIE9JRCBtYXBwaW5ncwp2YXIgX3Nob3J0TmFtZXMgPSB7fTsKX3Nob3J0TmFtZXNbJ0NOJ10gPSBvaWRzWydjb21tb25OYW1lJ107Cl9zaG9ydE5hbWVzWydjb21tb25OYW1lJ10gPSAnQ04nOwpfc2hvcnROYW1lc1snQyddID0gb2lkc1snY291bnRyeU5hbWUnXTsKX3Nob3J0TmFtZXNbJ2NvdW50cnlOYW1lJ10gPSAnQyc7Cl9zaG9ydE5hbWVzWydMJ10gPSBvaWRzWydsb2NhbGl0eU5hbWUnXTsKX3Nob3J0TmFtZXNbJ2xvY2FsaXR5TmFtZSddID0gJ0wnOwpfc2hvcnROYW1lc1snU1QnXSA9IG9pZHNbJ3N0YXRlT3JQcm92aW5jZU5hbWUnXTsKX3Nob3J0TmFtZXNbJ3N0YXRlT3JQcm92aW5jZU5hbWUnXSA9ICdTVCc7Cl9zaG9ydE5hbWVzWydPJ10gPSBvaWRzWydvcmdhbml6YXRpb25OYW1lJ107Cl9zaG9ydE5hbWVzWydvcmdhbml6YXRpb25OYW1lJ10gPSAnTyc7Cl9zaG9ydE5hbWVzWydPVSddID0gb2lkc1snb3JnYW5pemF0aW9uYWxVbml0TmFtZSddOwpfc2hvcnROYW1lc1snb3JnYW5pemF0aW9uYWxVbml0TmFtZSddID0gJ09VJzsKX3Nob3J0TmFtZXNbJ0UnXSA9IG9pZHNbJ2VtYWlsQWRkcmVzcyddOwpfc2hvcnROYW1lc1snZW1haWxBZGRyZXNzJ10gPSAnRSc7CgovLyB2YWxpZGF0b3IgZm9yIGFuIFN1YmplY3RQdWJsaWNLZXlJbmZvIHN0cnVjdHVyZQovLyBOb3RlOiBDdXJyZW50bHkgb25seSB3b3JrcyB3aXRoIGFuIFJTQSBwdWJsaWMga2V5CnZhciBwdWJsaWNLZXlWYWxpZGF0b3IgPSBmb3JnZS5wa2kucnNhLnB1YmxpY0tleVZhbGlkYXRvcjsKCi8vIHZhbGlkYXRvciBmb3IgYW4gWC41MDl2MyBjZXJ0aWZpY2F0ZQp2YXIgeDUwOUNlcnRpZmljYXRlVmFsaWRhdG9yID0gewogIG5hbWU6ICdDZXJ0aWZpY2F0ZScsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIGNhcHR1cmVBc24xOiAndGJzQ2VydGlmaWNhdGUnLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZS52ZXJzaW9uJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgICAgdHlwZTogMCwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICB2YWx1ZTogW3sKICAgICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUudmVyc2lvbi5pbnRlZ2VyJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICAgIGNhcHR1cmU6ICdjZXJ0VmVyc2lvbicKICAgICAgfV0KICAgIH0sIHsKICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLnNlcmlhbE51bWJlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ2NlcnRTZXJpYWxOdW1iZXInCiAgICB9LCB7CiAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZS5zaWduYXR1cmUnLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIHZhbHVlOiBbewogICAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZS5zaWduYXR1cmUuYWxnb3JpdGhtJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLk9JRCwKICAgICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgICAgY2FwdHVyZTogJ2NlcnRpbmZvU2lnbmF0dXJlT2lkJwogICAgICB9LCB7CiAgICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLnNpZ25hdHVyZS5wYXJhbWV0ZXJzJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgb3B0aW9uYWw6IHRydWUsCiAgICAgICAgY2FwdHVyZUFzbjE6ICdjZXJ0aW5mb1NpZ25hdHVyZVBhcmFtcycKICAgICAgfV0KICAgIH0sIHsKICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLmlzc3VlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgICAgY2FwdHVyZUFzbjE6ICdjZXJ0SXNzdWVyJwogICAgfSwgewogICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUudmFsaWRpdHknLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIC8vIE5vdGU6IFVUQyBhbmQgZ2VuZXJhbGl6ZWQgdGltZXMgbWF5IGJvdGggYXBwZWFyIHNvIHRoZSBjYXB0dXJlCiAgICAgIC8vIG5hbWVzIGFyZSBiYXNlZCBvbiB0aGVpciBkZXRlY3RlZCBvcmRlciwgdGhlIG5hbWVzIHVzZWQgYmVsb3cKICAgICAgLy8gYXJlIG9ubHkgZm9yIHRoZSBjb21tb24gY2FzZSwgd2hpY2ggdmFsaWRpdHkgdGltZSByZWFsbHkgbWVhbnMKICAgICAgLy8gIm5vdEJlZm9yZSIgYW5kIHdoaWNoIG1lYW5zICJub3RBZnRlciIgd2lsbCBiZSBkZXRlcm1pbmVkIGJ5IG9yZGVyCiAgICAgIHZhbHVlOiBbewogICAgICAgIC8vIG5vdEJlZm9yZSAoVGltZSkgKFVUQyB0aW1lIGNhc2UpCiAgICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLnZhbGlkaXR5Lm5vdEJlZm9yZSAodXRjKScsCiAgICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICAgIHR5cGU6IGFzbjEuVHlwZS5VVENUSU1FLAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBvcHRpb25hbDogdHJ1ZSwKICAgICAgICBjYXB0dXJlOiAnY2VydFZhbGlkaXR5MVVUQ1RpbWUnCiAgICAgIH0sIHsKICAgICAgICAvLyBub3RCZWZvcmUgKFRpbWUpIChnZW5lcmFsaXplZCB0aW1lIGNhc2UpCiAgICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLnZhbGlkaXR5Lm5vdEJlZm9yZSAoZ2VuZXJhbGl6ZWQpJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLkdFTkVSQUxJWkVEVElNRSwKICAgICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgICAgb3B0aW9uYWw6IHRydWUsCiAgICAgICAgY2FwdHVyZTogJ2NlcnRWYWxpZGl0eTJHZW5lcmFsaXplZFRpbWUnCiAgICAgIH0sIHsKICAgICAgICAvLyBub3RBZnRlciAoVGltZSkgKG9ubHkgVVRDIHRpbWUgaXMgc3VwcG9ydGVkKQogICAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZS52YWxpZGl0eS5ub3RBZnRlciAodXRjKScsCiAgICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICAgIHR5cGU6IGFzbjEuVHlwZS5VVENUSU1FLAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBvcHRpb25hbDogdHJ1ZSwKICAgICAgICBjYXB0dXJlOiAnY2VydFZhbGlkaXR5M1VUQ1RpbWUnCiAgICAgIH0sIHsKICAgICAgICAvLyBub3RBZnRlciAoVGltZSkgKG9ubHkgVVRDIHRpbWUgaXMgc3VwcG9ydGVkKQogICAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZS52YWxpZGl0eS5ub3RBZnRlciAoZ2VuZXJhbGl6ZWQpJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLkdFTkVSQUxJWkVEVElNRSwKICAgICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgICAgb3B0aW9uYWw6IHRydWUsCiAgICAgICAgY2FwdHVyZTogJ2NlcnRWYWxpZGl0eTRHZW5lcmFsaXplZFRpbWUnCiAgICAgIH1dCiAgICB9LCB7CiAgICAgIC8vIE5hbWUgKHN1YmplY3QpIChSRE5TZXF1ZW5jZSkKICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLnN1YmplY3QnLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIGNhcHR1cmVBc24xOiAnY2VydFN1YmplY3QnCiAgICB9LAogICAgICAvLyBTdWJqZWN0UHVibGljS2V5SW5mbwogICAgICBwdWJsaWNLZXlWYWxpZGF0b3IsCiAgICB7CiAgICAgIC8vIGlzc3VlclVuaXF1ZUlEIChvcHRpb25hbCkKICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLmlzc3VlclVuaXF1ZUlEJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgICAgdHlwZTogMSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICB2YWx1ZTogW3sKICAgICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUuaXNzdWVyVW5pcXVlSUQuaWQnLAogICAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgICB0eXBlOiBhc24xLlR5cGUuQklUU1RSSU5HLAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBjYXB0dXJlOiAnY2VydElzc3VlclVuaXF1ZUlkJwogICAgICB9XQogICAgfSwgewogICAgICAvLyBzdWJqZWN0VW5pcXVlSUQgKG9wdGlvbmFsKQogICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUuc3ViamVjdFVuaXF1ZUlEJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgICAgdHlwZTogMiwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICB2YWx1ZTogW3sKICAgICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUuc3ViamVjdFVuaXF1ZUlELmlkJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLkJJVFNUUklORywKICAgICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgICAgY2FwdHVyZTogJ2NlcnRTdWJqZWN0VW5pcXVlSWQnCiAgICAgIH1dCiAgICB9LCB7CiAgICAgIC8vIEV4dGVuc2lvbnMgKG9wdGlvbmFsKQogICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUuZXh0ZW5zaW9ucycsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICAgIHR5cGU6IDMsCiAgICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgICBjYXB0dXJlQXNuMTogJ2NlcnRFeHRlbnNpb25zJywKICAgICAgb3B0aW9uYWw6IHRydWUKICAgIH1dCiAgfSwgewogICAgLy8gQWxnb3JpdGhtSWRlbnRpZmllciAoc2lnbmF0dXJlIGFsZ29yaXRobSkKICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5zaWduYXR1cmVBbGdvcml0aG0nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICB2YWx1ZTogW3sKICAgICAgLy8gYWxnb3JpdGhtCiAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5zaWduYXR1cmVBbGdvcml0aG0uYWxnb3JpdGhtJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdjZXJ0U2lnbmF0dXJlT2lkJwogICAgfSwgewogICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUuc2lnbmF0dXJlLnBhcmFtZXRlcnMnLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICBjYXB0dXJlQXNuMTogJ2NlcnRTaWduYXR1cmVQYXJhbXMnCiAgICB9XQogIH0sIHsKICAgIC8vIFNpZ25hdHVyZVZhbHVlCiAgICBuYW1lOiAnQ2VydGlmaWNhdGUuc2lnbmF0dXJlVmFsdWUnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLkJJVFNUUklORywKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdjZXJ0U2lnbmF0dXJlJwogIH1dCn07Cgp2YXIgcnNhc3NhUHNzUGFyYW1ldGVyVmFsaWRhdG9yID0gewogIG5hbWU6ICdyc2Fwc3MnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAncnNhcHNzLmhhc2hBbGdvcml0aG0nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgIHR5cGU6IDAsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAncnNhcHNzLmhhc2hBbGdvcml0aG0uQWxnb3JpdGhtSWRlbnRpZmllcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5DbGFzcy5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICB2YWx1ZTogW3sKICAgICAgICBuYW1lOiAncnNhcHNzLmhhc2hBbGdvcml0aG0uQWxnb3JpdGhtSWRlbnRpZmllci5hbGdvcml0aG0nLAogICAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBjYXB0dXJlOiAnaGFzaE9pZCcKICAgICAgICAvKiBwYXJhbWV0ZXIgYmxvY2sgb21pdHRlZCwgZm9yIFNIQTEgTlVMTCBhbnlob3cuICovCiAgICAgIH1dCiAgICB9XQogIH0sIHsKICAgIG5hbWU6ICdyc2Fwc3MubWFza0dlbkFsZ29yaXRobScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLAogICAgdHlwZTogMSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdyc2Fwc3MubWFza0dlbkFsZ29yaXRobS5BbGdvcml0aG1JZGVudGlmaWVyJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLkNsYXNzLlNFUVVFTkNFLAogICAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgICAgb3B0aW9uYWw6IHRydWUsCiAgICAgIHZhbHVlOiBbewogICAgICAgIG5hbWU6ICdyc2Fwc3MubWFza0dlbkFsZ29yaXRobS5BbGdvcml0aG1JZGVudGlmaWVyLmFsZ29yaXRobScsCiAgICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICAgIHR5cGU6IGFzbjEuVHlwZS5PSUQsCiAgICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICAgIGNhcHR1cmU6ICdtYXNrR2VuT2lkJwogICAgICB9LCB7CiAgICAgICAgbmFtZTogJ3JzYXBzcy5tYXNrR2VuQWxnb3JpdGhtLkFsZ29yaXRobUlkZW50aWZpZXIucGFyYW1zJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgICAgIHZhbHVlOiBbewogICAgICAgICAgbmFtZTogJ3JzYXBzcy5tYXNrR2VuQWxnb3JpdGhtLkFsZ29yaXRobUlkZW50aWZpZXIucGFyYW1zLmFsZ29yaXRobScsCiAgICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICAgICAgY2FwdHVyZTogJ21hc2tHZW5IYXNoT2lkJwogICAgICAgICAgLyogcGFyYW1ldGVyIGJsb2NrIG9taXR0ZWQsIGZvciBTSEExIE5VTEwgYW55aG93LiAqLwogICAgICAgIH1dCiAgICAgIH1dCiAgICB9XQogIH0sIHsKICAgIG5hbWU6ICdyc2Fwc3Muc2FsdExlbmd0aCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLAogICAgdHlwZTogMiwKICAgIG9wdGlvbmFsOiB0cnVlLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdyc2Fwc3Muc2FsdExlbmd0aC5zYWx0TGVuZ3RoJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLkNsYXNzLklOVEVHRVIsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ3NhbHRMZW5ndGgnCiAgICB9XQogIH0sIHsKICAgIG5hbWU6ICdyc2Fwc3MudHJhaWxlckZpZWxkJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICB0eXBlOiAzLAogICAgb3B0aW9uYWw6IHRydWUsCiAgICB2YWx1ZTogW3sKICAgICAgbmFtZTogJ3JzYXBzcy50cmFpbGVyLnRyYWlsZXInLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuQ2xhc3MuSU5URUdFUiwKICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICBjYXB0dXJlOiAndHJhaWxlcicKICAgIH1dCiAgfV0KfTsKCi8vIHZhbGlkYXRvciBmb3IgYSBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8gc3RydWN0dXJlCnZhciBjZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm9WYWxpZGF0b3IgPSB7CiAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0SW5mbycsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICBjYXB0dXJlQXNuMTogJ2NlcnRpZmljYXRpb25SZXF1ZXN0SW5mbycsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvLmludGVnZXInLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAnY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvVmVyc2lvbicKICB9LCB7CiAgICAvLyBOYW1lIChzdWJqZWN0KSAoUkROU2VxdWVuY2UpCiAgICBuYW1lOiAnQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvLnN1YmplY3QnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICBjYXB0dXJlQXNuMTogJ2NlcnRpZmljYXRpb25SZXF1ZXN0SW5mb1N1YmplY3QnCiAgfSwKICAvLyBTdWJqZWN0UHVibGljS2V5SW5mbwogIHB1YmxpY0tleVZhbGlkYXRvciwKICB7CiAgICBuYW1lOiAnQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvLmF0dHJpYnV0ZXMnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgIHR5cGU6IDAsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIG9wdGlvbmFsOiB0cnVlLAogICAgY2FwdHVyZTogJ2NlcnRpZmljYXRpb25SZXF1ZXN0SW5mb0F0dHJpYnV0ZXMnLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8uYXR0cmlidXRlcycsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgICAgdmFsdWU6IFt7CiAgICAgICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0SW5mby5hdHRyaWJ1dGVzLnR5cGUnLAogICAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZQogICAgICB9LCB7CiAgICAgICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0SW5mby5hdHRyaWJ1dGVzLnZhbHVlJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLlNFVCwKICAgICAgICBjb25zdHJ1Y3RlZDogdHJ1ZQogICAgICB9XQogICAgfV0KICB9XQp9OwoKLy8gdmFsaWRhdG9yIGZvciBhIENlcnRpZmljYXRpb25SZXF1ZXN0IHN0cnVjdHVyZQp2YXIgY2VydGlmaWNhdGlvblJlcXVlc3RWYWxpZGF0b3IgPSB7CiAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0JywKICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogIGNvbnN0cnVjdGVkOiB0cnVlLAogIGNhcHR1cmVBc24xOiAnY3NyJywKICB2YWx1ZTogWwogICAgY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvVmFsaWRhdG9yLCB7CiAgICAvLyBBbGdvcml0aG1JZGVudGlmaWVyIChzaWduYXR1cmUgYWxnb3JpdGhtKQogICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0LnNpZ25hdHVyZUFsZ29yaXRobScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICAvLyBhbGdvcml0aG0KICAgICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0LnNpZ25hdHVyZUFsZ29yaXRobS5hbGdvcml0aG0nLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5PSUQsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ2NzclNpZ25hdHVyZU9pZCcKICAgIH0sIHsKICAgICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0LnNpZ25hdHVyZUFsZ29yaXRobS5wYXJhbWV0ZXJzJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICBvcHRpb25hbDogdHJ1ZSwKICAgICAgY2FwdHVyZUFzbjE6ICdjc3JTaWduYXR1cmVQYXJhbXMnCiAgICB9XQogIH0sIHsKICAgIC8vIHNpZ25hdHVyZQogICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0LnNpZ25hdHVyZScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuQklUU1RSSU5HLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ2NzclNpZ25hdHVyZScKICB9XQp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFJETlNlcXVlbmNlIG9mIEFTTi4xIERFUi1lbmNvZGVkIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUKICogc2V0cyBpbnRvIGFuIGFycmF5IHdpdGggb2JqZWN0cyB0aGF0IGhhdmUgdHlwZSBhbmQgdmFsdWUgcHJvcGVydGllcy4KICoKICogQHBhcmFtIHJkbiB0aGUgUkROU2VxdWVuY2UgdG8gY29udmVydC4KICogQHBhcmFtIG1kIGEgbWVzc2FnZSBkaWdlc3QgdG8gYXBwZW5kIHR5cGUgYW5kIHZhbHVlIHRvIGlmIHByb3ZpZGVkLgogKi8KcGtpLlJETkF0dHJpYnV0ZXNBc0FycmF5ID0gZnVuY3Rpb24ocmRuLCBtZCkgewogIHZhciBydmFsID0gW107CgogIC8vIGVhY2ggdmFsdWUgaW4gJ3JkbicgaW4gaXMgYSBTRVQgb2YgUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZQogIHZhciBzZXQsIGF0dHIsIG9iajsKICBmb3IodmFyIHNpID0gMDsgc2kgPCByZG4udmFsdWUubGVuZ3RoOyArK3NpKSB7CiAgICAvLyBnZXQgdGhlIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUgc2V0CiAgICBzZXQgPSByZG4udmFsdWVbc2ldOwoKICAgIC8vIGVhY2ggdmFsdWUgaW4gdGhlIFNFVCBpcyBhbiBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgc2VxdWVuY2UKICAgIC8vIGNvbnRhaW5pbmcgZmlyc3QgYSB0eXBlIChhbiBPSUQpIGFuZCBzZWNvbmQgYSB2YWx1ZSAoZGVmaW5lZCBieQogICAgLy8gdGhlIE9JRCkKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBzZXQudmFsdWUubGVuZ3RoOyArK2kpIHsKICAgICAgb2JqID0ge307CiAgICAgIGF0dHIgPSBzZXQudmFsdWVbaV07CiAgICAgIG9iai50eXBlID0gYXNuMS5kZXJUb09pZChhdHRyLnZhbHVlWzBdLnZhbHVlKTsKICAgICAgb2JqLnZhbHVlID0gYXR0ci52YWx1ZVsxXS52YWx1ZTsKICAgICAgb2JqLnZhbHVlVGFnQ2xhc3MgPSBhdHRyLnZhbHVlWzFdLnR5cGU7CiAgICAgIC8vIGlmIHRoZSBPSUQgaXMga25vd24sIGdldCBpdHMgbmFtZSBhbmQgc2hvcnQgbmFtZQogICAgICBpZihvYmoudHlwZSBpbiBvaWRzKSB7CiAgICAgICAgb2JqLm5hbWUgPSBvaWRzW29iai50eXBlXTsKICAgICAgICBpZihvYmoubmFtZSBpbiBfc2hvcnROYW1lcykgewogICAgICAgICAgb2JqLnNob3J0TmFtZSA9IF9zaG9ydE5hbWVzW29iai5uYW1lXTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYobWQpIHsKICAgICAgICBtZC51cGRhdGUob2JqLnR5cGUpOwogICAgICAgIG1kLnVwZGF0ZShvYmoudmFsdWUpOwogICAgICB9CiAgICAgIHJ2YWwucHVzaChvYmopOwogICAgfQogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ29udmVydHMgQVNOLjEgQ1JJQXR0cmlidXRlcyBpbnRvIGFuIGFycmF5IHdpdGggb2JqZWN0cyB0aGF0IGhhdmUgdHlwZSBhbmQKICogdmFsdWUgcHJvcGVydGllcy4KICoKICogQHBhcmFtIGF0dHJpYnV0ZXMgdGhlIENSSUF0dHJpYnV0ZXMgdG8gY29udmVydC4KICovCnBraS5DUklBdHRyaWJ1dGVzQXNBcnJheSA9IGZ1bmN0aW9uKGF0dHJpYnV0ZXMpIHsKICB2YXIgcnZhbCA9IFtdOwoKICAvLyBlYWNoIHZhbHVlIGluICdhdHRyaWJ1dGVzJyBpbiBpcyBhIFNFUVVFTkNFIHdpdGggYW4gT0lEIGFuZCBhIFNFVAogIGZvcih2YXIgc2kgPSAwOyBzaSA8IGF0dHJpYnV0ZXMubGVuZ3RoOyArK3NpKSB7CiAgICAvLyBnZXQgdGhlIGF0dHJpYnV0ZSBzZXF1ZW5jZQogICAgdmFyIHNlcSA9IGF0dHJpYnV0ZXNbc2ldOwoKICAgIC8vIGVhY2ggdmFsdWUgaW4gdGhlIFNFUVVFTkNFIGNvbnRhaW5pbmcgZmlyc3QgYSB0eXBlIChhbiBPSUQpIGFuZAogICAgLy8gc2Vjb25kIGEgc2V0IG9mIHZhbHVlcyAoZGVmaW5lZCBieSB0aGUgT0lEKQogICAgdmFyIHR5cGUgPSBhc24xLmRlclRvT2lkKHNlcS52YWx1ZVswXS52YWx1ZSk7CiAgICB2YXIgdmFsdWVzID0gc2VxLnZhbHVlWzFdLnZhbHVlOwogICAgZm9yKHZhciB2aSA9IDA7IHZpIDwgdmFsdWVzLmxlbmd0aDsgKyt2aSkgewogICAgICB2YXIgb2JqID0ge307CiAgICAgIG9iai50eXBlID0gdHlwZTsKICAgICAgb2JqLnZhbHVlID0gdmFsdWVzW3ZpXS52YWx1ZTsKICAgICAgb2JqLnZhbHVlVGFnQ2xhc3MgPSB2YWx1ZXNbdmldLnR5cGU7CiAgICAgIC8vIGlmIHRoZSBPSUQgaXMga25vd24sIGdldCBpdHMgbmFtZSBhbmQgc2hvcnQgbmFtZQogICAgICBpZihvYmoudHlwZSBpbiBvaWRzKSB7CiAgICAgICAgb2JqLm5hbWUgPSBvaWRzW29iai50eXBlXTsKICAgICAgICBpZihvYmoubmFtZSBpbiBfc2hvcnROYW1lcykgewogICAgICAgICAgb2JqLnNob3J0TmFtZSA9IF9zaG9ydE5hbWVzW29iai5uYW1lXTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLy8gcGFyc2UgZXh0ZW5zaW9ucwogICAgICBpZihvYmoudHlwZSA9PT0gb2lkcy5leHRlbnNpb25SZXF1ZXN0KSB7CiAgICAgICAgb2JqLmV4dGVuc2lvbnMgPSBbXTsKICAgICAgICBmb3IodmFyIGVpID0gMDsgZWkgPCBvYmoudmFsdWUubGVuZ3RoOyArK2VpKSB7CiAgICAgICAgICBvYmouZXh0ZW5zaW9ucy5wdXNoKHBraS5jZXJ0aWZpY2F0ZUV4dGVuc2lvbkZyb21Bc24xKG9iai52YWx1ZVtlaV0pKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcnZhbC5wdXNoKG9iaik7CiAgICB9CiAgfQoKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGFuIGlzc3VlciBvciBzdWJqZWN0IGF0dHJpYnV0ZSBmcm9tIGl0cyBuYW1lLCB0eXBlLCBvciBzaG9ydCBuYW1lLgogKgogKiBAcGFyYW0gb2JqIHRoZSBpc3N1ZXIgb3Igc3ViamVjdCBvYmplY3QuCiAqIEBwYXJhbSBvcHRpb25zIGEgc2hvcnQgbmFtZSBzdHJpbmcgb3IgYW4gb2JqZWN0IHdpdGg6CiAqICAgICAgICAgIHNob3J0TmFtZSB0aGUgc2hvcnQgbmFtZSBmb3IgdGhlIGF0dHJpYnV0ZS4KICogICAgICAgICAgbmFtZSB0aGUgbmFtZSBmb3IgdGhlIGF0dHJpYnV0ZS4KICogICAgICAgICAgdHlwZSB0aGUgdHlwZSBmb3IgdGhlIGF0dHJpYnV0ZS4KICoKICogQHJldHVybiB0aGUgYXR0cmlidXRlLgogKi8KZnVuY3Rpb24gX2dldEF0dHJpYnV0ZShvYmosIG9wdGlvbnMpIHsKICBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpIHsKICAgIG9wdGlvbnMgPSB7c2hvcnROYW1lOiBvcHRpb25zfTsKICB9CgogIHZhciBydmFsID0gbnVsbDsKICB2YXIgYXR0cjsKICBmb3IodmFyIGkgPSAwOyBydmFsID09PSBudWxsICYmIGkgPCBvYmouYXR0cmlidXRlcy5sZW5ndGg7ICsraSkgewogICAgYXR0ciA9IG9iai5hdHRyaWJ1dGVzW2ldOwogICAgaWYob3B0aW9ucy50eXBlICYmIG9wdGlvbnMudHlwZSA9PT0gYXR0ci50eXBlKSB7CiAgICAgIHJ2YWwgPSBhdHRyOwogICAgfSBlbHNlIGlmKG9wdGlvbnMubmFtZSAmJiBvcHRpb25zLm5hbWUgPT09IGF0dHIubmFtZSkgewogICAgICBydmFsID0gYXR0cjsKICAgIH0gZWxzZSBpZihvcHRpb25zLnNob3J0TmFtZSAmJiBvcHRpb25zLnNob3J0TmFtZSA9PT0gYXR0ci5zaG9ydE5hbWUpIHsKICAgICAgcnZhbCA9IGF0dHI7CiAgICB9CiAgfQogIHJldHVybiBydmFsOwp9CgovKioKICogQ29udmVydHMgc2lnbmF0dXJlIHBhcmFtZXRlcnMgZnJvbSBBU04uMSBzdHJ1Y3R1cmUuCiAqCiAqIEN1cnJlbnRseSBvbmx5IFJTQVNTQS1QU1Mgc3VwcG9ydGVkLiAgVGhlIFBLQ1MjMSB2MS41IHNpZ25hdHVyZSBzY2hlbWUgaGFkCiAqIG5vIHBhcmFtZXRlcnMuCiAqCiAqIFJTQVNTQS1QU1MtcGFyYW1zICA6Oj0gIFNFUVVFTkNFICB7CiAqICAgaGFzaEFsZ29yaXRobSAgICAgIFswXSBIYXNoQWxnb3JpdGhtIERFRkFVTFQKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYTFJZGVudGlmaWVyLAogKiAgIG1hc2tHZW5BbGdvcml0aG0gICBbMV0gTWFza0dlbkFsZ29yaXRobSBERUZBVUxUCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZ2YxU0hBMUlkZW50aWZpZXIsCiAqICAgc2FsdExlbmd0aCAgICAgICAgIFsyXSBJTlRFR0VSIERFRkFVTFQgMjAsCiAqICAgdHJhaWxlckZpZWxkICAgICAgIFszXSBJTlRFR0VSIERFRkFVTFQgMQogKiB9CiAqCiAqIEhhc2hBbGdvcml0aG0gIDo6PSAgQWxnb3JpdGhtSWRlbnRpZmllcgogKgogKiBNYXNrR2VuQWxnb3JpdGhtICA6Oj0gIEFsZ29yaXRobUlkZW50aWZpZXIKICoKICogQWxnb3JpdGhtSWRlbnRpZmVyIDo6PSBTRVFVRU5DRSB7CiAqICAgYWxnb3JpdGhtIE9CSkVDVCBJREVOVElGSUVSLAogKiAgIHBhcmFtZXRlcnMgQU5ZIERFRklORUQgQlkgYWxnb3JpdGhtIE9QVElPTkFMCiAqIH0KICoKICogQHBhcmFtIG9pZCBUaGUgT0lEIHNwZWNpZnlpbmcgdGhlIHNpZ25hdHVyZSBhbGdvcml0aG0KICogQHBhcmFtIG9iaiBUaGUgQVNOLjEgc3RydWN0dXJlIGhvbGRpbmcgdGhlIHBhcmFtZXRlcnMKICogQHBhcmFtIGZpbGxEZWZhdWx0cyBXaGV0aGVyIHRvIHVzZSByZXR1cm4gZGVmYXVsdCB2YWx1ZXMgd2hlcmUgb21pdHRlZAogKiBAcmV0dXJuIHNpZ25hdHVyZSBwYXJhbWV0ZXIgb2JqZWN0CiAqLwp2YXIgX3JlYWRTaWduYXR1cmVQYXJhbWV0ZXJzID0gZnVuY3Rpb24ob2lkLCBvYmosIGZpbGxEZWZhdWx0cykgewogIHZhciBwYXJhbXMgPSB7fTsKCiAgaWYob2lkICE9PSBvaWRzWydSU0FTU0EtUFNTJ10pIHsKICAgIHJldHVybiBwYXJhbXM7CiAgfQoKICBpZihmaWxsRGVmYXVsdHMpIHsKICAgIHBhcmFtcyA9IHsKICAgICAgaGFzaDogewogICAgICAgIGFsZ29yaXRobU9pZDogb2lkc1snc2hhMSddCiAgICAgIH0sCiAgICAgIG1nZjogewogICAgICAgIGFsZ29yaXRobU9pZDogb2lkc1snbWdmMSddLAogICAgICAgIGhhc2g6IHsKICAgICAgICAgIGFsZ29yaXRobU9pZDogb2lkc1snc2hhMSddCiAgICAgICAgfQogICAgICB9LAogICAgICBzYWx0TGVuZ3RoOiAyMAogICAgfTsKICB9CgogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgcnNhc3NhUHNzUGFyYW1ldGVyVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIFJTQVNTQS1QU1MgcGFyYW1ldGVyIGJsb2NrLicpOwogICAgZXJyb3IuZXJyb3JzID0gZXJyb3JzOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICBpZihjYXB0dXJlLmhhc2hPaWQgIT09IHVuZGVmaW5lZCkgewogICAgcGFyYW1zLmhhc2ggPSBwYXJhbXMuaGFzaCB8fCB7fTsKICAgIHBhcmFtcy5oYXNoLmFsZ29yaXRobU9pZCA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5oYXNoT2lkKTsKICB9CgogIGlmKGNhcHR1cmUubWFza0dlbk9pZCAhPT0gdW5kZWZpbmVkKSB7CiAgICBwYXJhbXMubWdmID0gcGFyYW1zLm1nZiB8fCB7fTsKICAgIHBhcmFtcy5tZ2YuYWxnb3JpdGhtT2lkID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLm1hc2tHZW5PaWQpOwogICAgcGFyYW1zLm1nZi5oYXNoID0gcGFyYW1zLm1nZi5oYXNoIHx8IHt9OwogICAgcGFyYW1zLm1nZi5oYXNoLmFsZ29yaXRobU9pZCA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5tYXNrR2VuSGFzaE9pZCk7CiAgfQoKICBpZihjYXB0dXJlLnNhbHRMZW5ndGggIT09IHVuZGVmaW5lZCkgewogICAgcGFyYW1zLnNhbHRMZW5ndGggPSBjYXB0dXJlLnNhbHRMZW5ndGguY2hhckNvZGVBdCgwKTsKICB9CgogIHJldHVybiBwYXJhbXM7Cn07CgovKioKICogQ29udmVydHMgYW4gWC41MDkgY2VydGlmaWNhdGUgZnJvbSBQRU0gZm9ybWF0LgogKgogKiBOb3RlOiBJZiB0aGUgY2VydGlmaWNhdGUgaXMgdG8gYmUgdmVyaWZpZWQgdGhlbiBjb21wdXRlIGhhc2ggc2hvdWxkCiAqIGJlIHNldCB0byB0cnVlLiBUaGlzIHdpbGwgc2NhbiB0aGUgVEJTQ2VydGlmaWNhdGUgcGFydCBvZiB0aGUgQVNOLjEKICogb2JqZWN0IHdoaWxlIGl0IGlzIGNvbnZlcnRlZCBzbyBpdCBkb2Vzbid0IG5lZWQgdG8gYmUgY29udmVydGVkIGJhY2sKICogdG8gQVNOLjEtREVSLWVuY29kaW5nIGxhdGVyLgogKgogKiBAcGFyYW0gcGVtIHRoZSBQRU0tZm9ybWF0dGVkIGNlcnRpZmljYXRlLgogKiBAcGFyYW0gY29tcHV0ZUhhc2ggdHJ1ZSB0byBjb21wdXRlIHRoZSBoYXNoIGZvciB2ZXJpZmljYXRpb24uCiAqIEBwYXJhbSBzdHJpY3QgdHJ1ZSB0byBiZSBzdHJpY3Qgd2hlbiBjaGVja2luZyBBU04uMSB2YWx1ZSBsZW5ndGhzLCBmYWxzZSB0bwogKiAgICAgICAgICBhbGxvdyB0cnVuY2F0ZWQgdmFsdWVzIChkZWZhdWx0OiB0cnVlKS4KICoKICogQHJldHVybiB0aGUgY2VydGlmaWNhdGUuCiAqLwpwa2kuY2VydGlmaWNhdGVGcm9tUGVtID0gZnVuY3Rpb24ocGVtLCBjb21wdXRlSGFzaCwgc3RyaWN0KSB7CiAgdmFyIG1zZyA9IGZvcmdlLnBlbS5kZWNvZGUocGVtKVswXTsKCiAgaWYobXNnLnR5cGUgIT09ICdDRVJUSUZJQ0FURScgJiYKICAgIG1zZy50eXBlICE9PSAnWDUwOSBDRVJUSUZJQ0FURScgJiYKICAgIG1zZy50eXBlICE9PSAnVFJVU1RFRCBDRVJUSUZJQ0FURScpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ291bGQgbm90IGNvbnZlcnQgY2VydGlmaWNhdGUgZnJvbSBQRU07IFBFTSBoZWFkZXIgdHlwZSAnICsKICAgICAgJ2lzIG5vdCAiQ0VSVElGSUNBVEUiLCAiWDUwOSBDRVJUSUZJQ0FURSIsIG9yICJUUlVTVEVEIENFUlRJRklDQVRFIi4nKTsKICAgIGVycm9yLmhlYWRlclR5cGUgPSBtc2cudHlwZTsKICAgIHRocm93IGVycm9yOwogIH0KICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IGNlcnRpZmljYXRlIGZyb20gUEVNOyBQRU0gaXMgZW5jcnlwdGVkLicpOwogIH0KCiAgLy8gY29udmVydCBERVIgdG8gQVNOLjEgb2JqZWN0CiAgdmFyIG9iaiA9IGFzbjEuZnJvbURlcihtc2cuYm9keSwgc3RyaWN0KTsKCiAgcmV0dXJuIHBraS5jZXJ0aWZpY2F0ZUZyb21Bc24xKG9iaiwgY29tcHV0ZUhhc2gpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFguNTA5IGNlcnRpZmljYXRlIHRvIFBFTSBmb3JtYXQuCiAqCiAqIEBwYXJhbSBjZXJ0IHRoZSBjZXJ0aWZpY2F0ZS4KICogQHBhcmFtIG1heGxpbmUgdGhlIG1heGltdW0gY2hhcmFjdGVycyBwZXIgbGluZSwgZGVmYXVsdHMgdG8gNjQuCiAqCiAqIEByZXR1cm4gdGhlIFBFTS1mb3JtYXR0ZWQgY2VydGlmaWNhdGUuCiAqLwpwa2kuY2VydGlmaWNhdGVUb1BlbSA9IGZ1bmN0aW9uKGNlcnQsIG1heGxpbmUpIHsKICAvLyBjb252ZXJ0IHRvIEFTTi4xLCB0aGVuIERFUiwgdGhlbiBQRU0tZW5jb2RlCiAgdmFyIG1zZyA9IHsKICAgIHR5cGU6ICdDRVJUSUZJQ0FURScsCiAgICBib2R5OiBhc24xLnRvRGVyKHBraS5jZXJ0aWZpY2F0ZVRvQXNuMShjZXJ0KSkuZ2V0Qnl0ZXMoKQogIH07CiAgcmV0dXJuIGZvcmdlLnBlbS5lbmNvZGUobXNnLCB7bWF4bGluZTogbWF4bGluZX0pOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFJTQSBwdWJsaWMga2V5IGZyb20gUEVNIGZvcm1hdC4KICoKICogQHBhcmFtIHBlbSB0aGUgUEVNLWZvcm1hdHRlZCBwdWJsaWMga2V5LgogKgogKiBAcmV0dXJuIHRoZSBwdWJsaWMga2V5LgogKi8KcGtpLnB1YmxpY0tleUZyb21QZW0gPSBmdW5jdGlvbihwZW0pIHsKICB2YXIgbXNnID0gZm9yZ2UucGVtLmRlY29kZShwZW0pWzBdOwoKICBpZihtc2cudHlwZSAhPT0gJ1BVQkxJQyBLRVknICYmIG1zZy50eXBlICE9PSAnUlNBIFBVQkxJQyBLRVknKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IHB1YmxpYyBrZXkgZnJvbSBQRU07IFBFTSBoZWFkZXIgJyArCiAgICAgICd0eXBlIGlzIG5vdCAiUFVCTElDIEtFWSIgb3IgIlJTQSBQVUJMSUMgS0VZIi4nKTsKICAgIGVycm9yLmhlYWRlclR5cGUgPSBtc2cudHlwZTsKICAgIHRocm93IGVycm9yOwogIH0KICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IHB1YmxpYyBrZXkgZnJvbSBQRU07IFBFTSBpcyBlbmNyeXB0ZWQuJyk7CiAgfQoKICAvLyBjb252ZXJ0IERFUiB0byBBU04uMSBvYmplY3QKICB2YXIgb2JqID0gYXNuMS5mcm9tRGVyKG1zZy5ib2R5KTsKCiAgcmV0dXJuIHBraS5wdWJsaWNLZXlGcm9tQXNuMShvYmopOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFJTQSBwdWJsaWMga2V5IHRvIFBFTSBmb3JtYXQgKHVzaW5nIGEgU3ViamVjdFB1YmxpY0tleUluZm8pLgogKgogKiBAcGFyYW0ga2V5IHRoZSBwdWJsaWMga2V5LgogKiBAcGFyYW0gbWF4bGluZSB0aGUgbWF4aW11bSBjaGFyYWN0ZXJzIHBlciBsaW5lLCBkZWZhdWx0cyB0byA2NC4KICoKICogQHJldHVybiB0aGUgUEVNLWZvcm1hdHRlZCBwdWJsaWMga2V5LgogKi8KcGtpLnB1YmxpY0tleVRvUGVtID0gZnVuY3Rpb24oa2V5LCBtYXhsaW5lKSB7CiAgLy8gY29udmVydCB0byBBU04uMSwgdGhlbiBERVIsIHRoZW4gUEVNLWVuY29kZQogIHZhciBtc2cgPSB7CiAgICB0eXBlOiAnUFVCTElDIEtFWScsCiAgICBib2R5OiBhc24xLnRvRGVyKHBraS5wdWJsaWNLZXlUb0FzbjEoa2V5KSkuZ2V0Qnl0ZXMoKQogIH07CiAgcmV0dXJuIGZvcmdlLnBlbS5lbmNvZGUobXNnLCB7bWF4bGluZTogbWF4bGluZX0pOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFJTQSBwdWJsaWMga2V5IHRvIFBFTSBmb3JtYXQgKHVzaW5nIGFuIFJTQVB1YmxpY0tleSkuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHB1YmxpYyBrZXkuCiAqIEBwYXJhbSBtYXhsaW5lIHRoZSBtYXhpbXVtIGNoYXJhY3RlcnMgcGVyIGxpbmUsIGRlZmF1bHRzIHRvIDY0LgogKgogKiBAcmV0dXJuIHRoZSBQRU0tZm9ybWF0dGVkIHB1YmxpYyBrZXkuCiAqLwpwa2kucHVibGljS2V5VG9SU0FQdWJsaWNLZXlQZW0gPSBmdW5jdGlvbihrZXksIG1heGxpbmUpIHsKICAvLyBjb252ZXJ0IHRvIEFTTi4xLCB0aGVuIERFUiwgdGhlbiBQRU0tZW5jb2RlCiAgdmFyIG1zZyA9IHsKICAgIHR5cGU6ICdSU0EgUFVCTElDIEtFWScsCiAgICBib2R5OiBhc24xLnRvRGVyKHBraS5wdWJsaWNLZXlUb1JTQVB1YmxpY0tleShrZXkpKS5nZXRCeXRlcygpCiAgfTsKICByZXR1cm4gZm9yZ2UucGVtLmVuY29kZShtc2csIHttYXhsaW5lOiBtYXhsaW5lfSk7Cn07CgovKioKICogR2V0cyBhIGZpbmdlcnByaW50IGZvciB0aGUgZ2l2ZW4gcHVibGljIGtleS4KICoKICogQHBhcmFtIG9wdGlvbnMgdGhlIG9wdGlvbnMgdG8gdXNlLgogKiAgICAgICAgICBbbWRdIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3QgdG8gdXNlIChkZWZhdWx0cyB0byBmb3JnZS5tZC5zaGExKS4KICogICAgICAgICAgW3R5cGVdIHRoZSB0eXBlIG9mIGZpbmdlcnByaW50LCBzdWNoIGFzICdSU0FQdWJsaWNLZXknLAogKiAgICAgICAgICAgICdTdWJqZWN0UHVibGljS2V5SW5mbycgKGRlZmF1bHRzIHRvICdSU0FQdWJsaWNLZXknKS4KICogICAgICAgICAgW2VuY29kaW5nXSBhbiBhbHRlcm5hdGl2ZSBvdXRwdXQgZW5jb2RpbmcsIHN1Y2ggYXMgJ2hleCcKICogICAgICAgICAgICAoZGVmYXVsdHMgdG8gbm9uZSwgb3V0cHV0cyBhIGJ5dGUgYnVmZmVyKS4KICogICAgICAgICAgW2RlbGltaXRlcl0gdGhlIGRlbGltaXRlciB0byB1c2UgYmV0d2VlbiBieXRlcyBmb3IgJ2hleCcgZW5jb2RlZAogKiAgICAgICAgICAgIG91dHB1dCwgZWc6ICc6JyAoZGVmYXVsdHMgdG8gbm9uZSkuCiAqCiAqIEByZXR1cm4gdGhlIGZpbmdlcnByaW50IGFzIGEgYnl0ZSBidWZmZXIgb3Igb3RoZXIgZW5jb2RpbmcgYmFzZWQgb24gb3B0aW9ucy4KICovCnBraS5nZXRQdWJsaWNLZXlGaW5nZXJwcmludCA9IGZ1bmN0aW9uKGtleSwgb3B0aW9ucykgewogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIHZhciBtZCA9IG9wdGlvbnMubWQgfHwgZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICB2YXIgdHlwZSA9IG9wdGlvbnMudHlwZSB8fCAnUlNBUHVibGljS2V5JzsKCiAgdmFyIGJ5dGVzOwogIHN3aXRjaCh0eXBlKSB7CiAgY2FzZSAnUlNBUHVibGljS2V5JzoKICAgIGJ5dGVzID0gYXNuMS50b0Rlcihwa2kucHVibGljS2V5VG9SU0FQdWJsaWNLZXkoa2V5KSkuZ2V0Qnl0ZXMoKTsKICAgIGJyZWFrOwogIGNhc2UgJ1N1YmplY3RQdWJsaWNLZXlJbmZvJzoKICAgIGJ5dGVzID0gYXNuMS50b0Rlcihwa2kucHVibGljS2V5VG9Bc24xKGtleSkpLmdldEJ5dGVzKCk7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGZpbmdlcnByaW50IHR5cGUgIicgKyBvcHRpb25zLnR5cGUgKyAnIi4nKTsKICB9CgogIC8vIGhhc2ggcHVibGljIGtleSBieXRlcwogIG1kLnN0YXJ0KCk7CiAgbWQudXBkYXRlKGJ5dGVzKTsKICB2YXIgZGlnZXN0ID0gbWQuZGlnZXN0KCk7CiAgaWYob3B0aW9ucy5lbmNvZGluZyA9PT0gJ2hleCcpIHsKICAgIHZhciBoZXggPSBkaWdlc3QudG9IZXgoKTsKICAgIGlmKG9wdGlvbnMuZGVsaW1pdGVyKSB7CiAgICAgIHJldHVybiBoZXgubWF0Y2goLy57Mn0vZykuam9pbihvcHRpb25zLmRlbGltaXRlcik7CiAgICB9CiAgICByZXR1cm4gaGV4OwogIH0gZWxzZSBpZihvcHRpb25zLmVuY29kaW5nID09PSAnYmluYXJ5JykgewogICAgcmV0dXJuIGRpZ2VzdC5nZXRCeXRlcygpOwogIH0gZWxzZSBpZihvcHRpb25zLmVuY29kaW5nKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2RpbmcgIicgKyBvcHRpb25zLmVuY29kaW5nICsgJyIuJyk7CiAgfQogIHJldHVybiBkaWdlc3Q7Cn07CgovKioKICogQ29udmVydHMgYSBQS0NTIzEwIGNlcnRpZmljYXRpb24gcmVxdWVzdCAoQ1NSKSBmcm9tIFBFTSBmb3JtYXQuCiAqCiAqIE5vdGU6IElmIHRoZSBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QgaXMgdG8gYmUgdmVyaWZpZWQgdGhlbiBjb21wdXRlIGhhc2gKICogc2hvdWxkIGJlIHNldCB0byB0cnVlLiBUaGlzIHdpbGwgc2NhbiB0aGUgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIHBhcnQgb2YKICogdGhlIEFTTi4xIG9iamVjdCB3aGlsZSBpdCBpcyBjb252ZXJ0ZWQgc28gaXQgZG9lc24ndCBuZWVkIHRvIGJlIGNvbnZlcnRlZAogKiBiYWNrIHRvIEFTTi4xLURFUi1lbmNvZGluZyBsYXRlci4KICoKICogQHBhcmFtIHBlbSB0aGUgUEVNLWZvcm1hdHRlZCBjZXJ0aWZpY2F0ZS4KICogQHBhcmFtIGNvbXB1dGVIYXNoIHRydWUgdG8gY29tcHV0ZSB0aGUgaGFzaCBmb3IgdmVyaWZpY2F0aW9uLgogKiBAcGFyYW0gc3RyaWN0IHRydWUgdG8gYmUgc3RyaWN0IHdoZW4gY2hlY2tpbmcgQVNOLjEgdmFsdWUgbGVuZ3RocywgZmFsc2UgdG8KICogICAgICAgICAgYWxsb3cgdHJ1bmNhdGVkIHZhbHVlcyAoZGVmYXVsdDogdHJ1ZSkuCiAqCiAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRpb24gcmVxdWVzdCAoQ1NSKS4KICovCnBraS5jZXJ0aWZpY2F0aW9uUmVxdWVzdEZyb21QZW0gPSBmdW5jdGlvbihwZW0sIGNvbXB1dGVIYXNoLCBzdHJpY3QpIHsKICB2YXIgbXNnID0gZm9yZ2UucGVtLmRlY29kZShwZW0pWzBdOwoKICBpZihtc2cudHlwZSAhPT0gJ0NFUlRJRklDQVRFIFJFUVVFU1QnKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IGNlcnRpZmljYXRpb24gcmVxdWVzdCBmcm9tIFBFTTsgJyArCiAgICAgICdQRU0gaGVhZGVyIHR5cGUgaXMgbm90ICJDRVJUSUZJQ0FURSBSRVFVRVNUIi4nKTsKICAgIGVycm9yLmhlYWRlclR5cGUgPSBtc2cudHlwZTsKICAgIHRocm93IGVycm9yOwogIH0KICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IGNlcnRpZmljYXRpb24gcmVxdWVzdCBmcm9tIFBFTTsgJyArCiAgICAgICdQRU0gaXMgZW5jcnlwdGVkLicpOwogIH0KCiAgLy8gY29udmVydCBERVIgdG8gQVNOLjEgb2JqZWN0CiAgdmFyIG9iaiA9IGFzbjEuZnJvbURlcihtc2cuYm9keSwgc3RyaWN0KTsKCiAgcmV0dXJuIHBraS5jZXJ0aWZpY2F0aW9uUmVxdWVzdEZyb21Bc24xKG9iaiwgY29tcHV0ZUhhc2gpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgUEtDUyMxMCBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QgKENTUikgdG8gUEVNIGZvcm1hdC4KICoKICogQHBhcmFtIGNzciB0aGUgY2VydGlmaWNhdGlvbiByZXF1ZXN0LgogKiBAcGFyYW0gbWF4bGluZSB0aGUgbWF4aW11bSBjaGFyYWN0ZXJzIHBlciBsaW5lLCBkZWZhdWx0cyB0byA2NC4KICoKICogQHJldHVybiB0aGUgUEVNLWZvcm1hdHRlZCBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QuCiAqLwpwa2kuY2VydGlmaWNhdGlvblJlcXVlc3RUb1BlbSA9IGZ1bmN0aW9uKGNzciwgbWF4bGluZSkgewogIC8vIGNvbnZlcnQgdG8gQVNOLjEsIHRoZW4gREVSLCB0aGVuIFBFTS1lbmNvZGUKICB2YXIgbXNnID0gewogICAgdHlwZTogJ0NFUlRJRklDQVRFIFJFUVVFU1QnLAogICAgYm9keTogYXNuMS50b0Rlcihwa2kuY2VydGlmaWNhdGlvblJlcXVlc3RUb0FzbjEoY3NyKSkuZ2V0Qnl0ZXMoKQogIH07CiAgcmV0dXJuIGZvcmdlLnBlbS5lbmNvZGUobXNnLCB7bWF4bGluZTogbWF4bGluZX0pOwp9OwoKLyoqCiAqIENyZWF0ZXMgYW4gZW1wdHkgWC41MDl2MyBSU0EgY2VydGlmaWNhdGUuCiAqCiAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRlLgogKi8KcGtpLmNyZWF0ZUNlcnRpZmljYXRlID0gZnVuY3Rpb24oKSB7CiAgdmFyIGNlcnQgPSB7fTsKICBjZXJ0LnZlcnNpb24gPSAweDAyOwogIGNlcnQuc2VyaWFsTnVtYmVyID0gJzAwJzsKICBjZXJ0LnNpZ25hdHVyZU9pZCA9IG51bGw7CiAgY2VydC5zaWduYXR1cmUgPSBudWxsOwogIGNlcnQuc2lnaW5mbyA9IHt9OwogIGNlcnQuc2lnaW5mby5hbGdvcml0aG1PaWQgPSBudWxsOwogIGNlcnQudmFsaWRpdHkgPSB7fTsKICBjZXJ0LnZhbGlkaXR5Lm5vdEJlZm9yZSA9IG5ldyBEYXRlKCk7CiAgY2VydC52YWxpZGl0eS5ub3RBZnRlciA9IG5ldyBEYXRlKCk7CgogIGNlcnQuaXNzdWVyID0ge307CiAgY2VydC5pc3N1ZXIuZ2V0RmllbGQgPSBmdW5jdGlvbihzbikgewogICAgcmV0dXJuIF9nZXRBdHRyaWJ1dGUoY2VydC5pc3N1ZXIsIHNuKTsKICB9OwogIGNlcnQuaXNzdWVyLmFkZEZpZWxkID0gZnVuY3Rpb24oYXR0cikgewogICAgX2ZpbGxNaXNzaW5nRmllbGRzKFthdHRyXSk7CiAgICBjZXJ0Lmlzc3Vlci5hdHRyaWJ1dGVzLnB1c2goYXR0cik7CiAgfTsKICBjZXJ0Lmlzc3Vlci5hdHRyaWJ1dGVzID0gW107CiAgY2VydC5pc3N1ZXIuaGFzaCA9IG51bGw7CgogIGNlcnQuc3ViamVjdCA9IHt9OwogIGNlcnQuc3ViamVjdC5nZXRGaWVsZCA9IGZ1bmN0aW9uKHNuKSB7CiAgICByZXR1cm4gX2dldEF0dHJpYnV0ZShjZXJ0LnN1YmplY3QsIHNuKTsKICB9OwogIGNlcnQuc3ViamVjdC5hZGRGaWVsZCA9IGZ1bmN0aW9uKGF0dHIpIHsKICAgIF9maWxsTWlzc2luZ0ZpZWxkcyhbYXR0cl0pOwogICAgY2VydC5zdWJqZWN0LmF0dHJpYnV0ZXMucHVzaChhdHRyKTsKICB9OwogIGNlcnQuc3ViamVjdC5hdHRyaWJ1dGVzID0gW107CiAgY2VydC5zdWJqZWN0Lmhhc2ggPSBudWxsOwoKICBjZXJ0LmV4dGVuc2lvbnMgPSBbXTsKICBjZXJ0LnB1YmxpY0tleSA9IG51bGw7CiAgY2VydC5tZCA9IG51bGw7CgogIC8qKgogICAqIFNldHMgdGhlIHN1YmplY3Qgb2YgdGhpcyBjZXJ0aWZpY2F0ZS4KICAgKgogICAqIEBwYXJhbSBhdHRycyB0aGUgYXJyYXkgb2Ygc3ViamVjdCBhdHRyaWJ1dGVzIHRvIHVzZS4KICAgKiBAcGFyYW0gdW5pcXVlSWQgYW4gb3B0aW9uYWwgYSB1bmlxdWUgSUQgdG8gdXNlLgogICAqLwogIGNlcnQuc2V0U3ViamVjdCA9IGZ1bmN0aW9uKGF0dHJzLCB1bmlxdWVJZCkgewogICAgLy8gc2V0IG5ldyBhdHRyaWJ1dGVzLCBjbGVhciBoYXNoCiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoYXR0cnMpOwogICAgY2VydC5zdWJqZWN0LmF0dHJpYnV0ZXMgPSBhdHRyczsKICAgIGRlbGV0ZSBjZXJ0LnN1YmplY3QudW5pcXVlSWQ7CiAgICBpZih1bmlxdWVJZCkgewogICAgICBjZXJ0LnN1YmplY3QudW5pcXVlSWQgPSB1bmlxdWVJZDsKICAgIH0KICAgIGNlcnQuc3ViamVjdC5oYXNoID0gbnVsbDsKICB9OwoKICAvKioKICAgKiBTZXRzIHRoZSBpc3N1ZXIgb2YgdGhpcyBjZXJ0aWZpY2F0ZS4KICAgKgogICAqIEBwYXJhbSBhdHRycyB0aGUgYXJyYXkgb2YgaXNzdWVyIGF0dHJpYnV0ZXMgdG8gdXNlLgogICAqIEBwYXJhbSB1bmlxdWVJZCBhbiBvcHRpb25hbCBhIHVuaXF1ZSBJRCB0byB1c2UuCiAgICovCiAgY2VydC5zZXRJc3N1ZXIgPSBmdW5jdGlvbihhdHRycywgdW5pcXVlSWQpIHsKICAgIC8vIHNldCBuZXcgYXR0cmlidXRlcywgY2xlYXIgaGFzaAogICAgX2ZpbGxNaXNzaW5nRmllbGRzKGF0dHJzKTsKICAgIGNlcnQuaXNzdWVyLmF0dHJpYnV0ZXMgPSBhdHRyczsKICAgIGRlbGV0ZSBjZXJ0Lmlzc3Vlci51bmlxdWVJZDsKICAgIGlmKHVuaXF1ZUlkKSB7CiAgICAgIGNlcnQuaXNzdWVyLnVuaXF1ZUlkID0gdW5pcXVlSWQ7CiAgICB9CiAgICBjZXJ0Lmlzc3Vlci5oYXNoID0gbnVsbDsKICB9OwoKICAvKioKICAgKiBTZXRzIHRoZSBleHRlbnNpb25zIG9mIHRoaXMgY2VydGlmaWNhdGUuCiAgICoKICAgKiBAcGFyYW0gZXh0cyB0aGUgYXJyYXkgb2YgZXh0ZW5zaW9ucyB0byB1c2UuCiAgICovCiAgY2VydC5zZXRFeHRlbnNpb25zID0gZnVuY3Rpb24oZXh0cykgewogICAgZm9yKHZhciBpID0gMDsgaSA8IGV4dHMubGVuZ3RoOyArK2kpIHsKICAgICAgX2ZpbGxNaXNzaW5nRXh0ZW5zaW9uRmllbGRzKGV4dHNbaV0sIHtjZXJ0OiBjZXJ0fSk7CiAgICB9CiAgICAvLyBzZXQgbmV3IGV4dGVuc2lvbnMKICAgIGNlcnQuZXh0ZW5zaW9ucyA9IGV4dHM7CiAgfTsKCiAgLyoqCiAgICogR2V0cyBhbiBleHRlbnNpb24gYnkgaXRzIG5hbWUgb3IgaWQuCiAgICoKICAgKiBAcGFyYW0gb3B0aW9ucyB0aGUgbmFtZSB0byB1c2Ugb3IgYW4gb2JqZWN0IHdpdGg6CiAgICogICAgICAgICAgbmFtZSB0aGUgbmFtZSB0byB1c2UuCiAgICogICAgICAgICAgaWQgdGhlIGlkIHRvIHVzZS4KICAgKgogICAqIEByZXR1cm4gdGhlIGV4dGVuc2lvbiBvciBudWxsIGlmIG5vdCBmb3VuZC4KICAgKi8KICBjZXJ0LmdldEV4dGVuc2lvbiA9IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgIGlmKHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJykgewogICAgICBvcHRpb25zID0ge25hbWU6IG9wdGlvbnN9OwogICAgfQoKICAgIHZhciBydmFsID0gbnVsbDsKICAgIHZhciBleHQ7CiAgICBmb3IodmFyIGkgPSAwOyBydmFsID09PSBudWxsICYmIGkgPCBjZXJ0LmV4dGVuc2lvbnMubGVuZ3RoOyArK2kpIHsKICAgICAgZXh0ID0gY2VydC5leHRlbnNpb25zW2ldOwogICAgICBpZihvcHRpb25zLmlkICYmIGV4dC5pZCA9PT0gb3B0aW9ucy5pZCkgewogICAgICAgIHJ2YWwgPSBleHQ7CiAgICAgIH0gZWxzZSBpZihvcHRpb25zLm5hbWUgJiYgZXh0Lm5hbWUgPT09IG9wdGlvbnMubmFtZSkgewogICAgICAgIHJ2YWwgPSBleHQ7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBydmFsOwogIH07CgogIC8qKgogICAqIFNpZ25zIHRoaXMgY2VydGlmaWNhdGUgdXNpbmcgdGhlIGdpdmVuIHByaXZhdGUga2V5LgogICAqCiAgICogQHBhcmFtIGtleSB0aGUgcHJpdmF0ZSBrZXkgdG8gc2lnbiB3aXRoLgogICAqIEBwYXJhbSBtZCB0aGUgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0IHRvIHVzZSAoZGVmYXVsdHMgdG8gZm9yZ2UubWQuc2hhMSkuCiAgICovCiAgY2VydC5zaWduID0gZnVuY3Rpb24oa2V5LCBtZCkgewogICAgLy8gVE9ETzogZ2V0IHNpZ25hdHVyZSBPSUQgZnJvbSBwcml2YXRlIGtleQogICAgY2VydC5tZCA9IG1kIHx8IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICB2YXIgYWxnb3JpdGhtT2lkID0gb2lkc1tjZXJ0Lm1kLmFsZ29yaXRobSArICdXaXRoUlNBRW5jcnlwdGlvbiddOwogICAgaWYoIWFsZ29yaXRobU9pZCkgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb21wdXRlIGNlcnRpZmljYXRlIGRpZ2VzdC4gJyArCiAgICAgICAgJ1Vua25vd24gbWVzc2FnZSBkaWdlc3QgYWxnb3JpdGhtIE9JRC4nKTsKICAgICAgZXJyb3IuYWxnb3JpdGhtID0gY2VydC5tZC5hbGdvcml0aG07CiAgICAgIHRocm93IGVycm9yOwogICAgfQogICAgY2VydC5zaWduYXR1cmVPaWQgPSBjZXJ0LnNpZ2luZm8uYWxnb3JpdGhtT2lkID0gYWxnb3JpdGhtT2lkOwoKICAgIC8vIGdldCBUQlNDZXJ0aWZpY2F0ZSwgY29udmVydCB0byBERVIKICAgIGNlcnQudGJzQ2VydGlmaWNhdGUgPSBwa2kuZ2V0VEJTQ2VydGlmaWNhdGUoY2VydCk7CiAgICB2YXIgYnl0ZXMgPSBhc24xLnRvRGVyKGNlcnQudGJzQ2VydGlmaWNhdGUpOwoKICAgIC8vIGRpZ2VzdCBhbmQgc2lnbgogICAgY2VydC5tZC51cGRhdGUoYnl0ZXMuZ2V0Qnl0ZXMoKSk7CiAgICBjZXJ0LnNpZ25hdHVyZSA9IGtleS5zaWduKGNlcnQubWQpOwogIH07CgogIC8qKgogICAqIEF0dGVtcHRzIHZlcmlmeSB0aGUgc2lnbmF0dXJlIG9uIHRoZSBwYXNzZWQgY2VydGlmaWNhdGUgdXNpbmcgdGhpcwogICAqIGNlcnRpZmljYXRlJ3MgcHVibGljIGtleS4KICAgKgogICAqIEBwYXJhbSBjaGlsZCB0aGUgY2VydGlmaWNhdGUgdG8gdmVyaWZ5LgogICAqCiAgICogQHJldHVybiB0cnVlIGlmIHZlcmlmaWVkLCBmYWxzZSBpZiBub3QuCiAgICovCiAgY2VydC52ZXJpZnkgPSBmdW5jdGlvbihjaGlsZCkgewogICAgdmFyIHJ2YWwgPSBmYWxzZTsKCiAgICBpZighY2VydC5pc3N1ZWQoY2hpbGQpKSB7CiAgICAgIHZhciBpc3N1ZXIgPSBjaGlsZC5pc3N1ZXI7CiAgICAgIHZhciBzdWJqZWN0ID0gY2VydC5zdWJqZWN0OwogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1RoZSBwYXJlbnQgY2VydGlmaWNhdGUgZGlkIG5vdCBpc3N1ZSB0aGUgZ2l2ZW4gY2hpbGQgJyArCiAgICAgICAgJ2NlcnRpZmljYXRlOyB0aGUgY2hpbGQgY2VydGlmaWNhdGVcJ3MgaXNzdWVyIGRvZXMgbm90IG1hdGNoIHRoZSAnICsKICAgICAgICAncGFyZW50XCdzIHN1YmplY3QuJyk7CiAgICAgIGVycm9yLmV4cGVjdGVkSXNzdWVyID0gaXNzdWVyLmF0dHJpYnV0ZXM7CiAgICAgIGVycm9yLmFjdHVhbElzc3VlciA9IHN1YmplY3QuYXR0cmlidXRlczsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgdmFyIG1kID0gY2hpbGQubWQ7CiAgICBpZihtZCA9PT0gbnVsbCkgewogICAgICAvLyBjaGVjayBzaWduYXR1cmUgT0lEIGZvciBzdXBwb3J0ZWQgc2lnbmF0dXJlIHR5cGVzCiAgICAgIGlmKGNoaWxkLnNpZ25hdHVyZU9pZCBpbiBvaWRzKSB7CiAgICAgICAgdmFyIG9pZCA9IG9pZHNbY2hpbGQuc2lnbmF0dXJlT2lkXTsKICAgICAgICBzd2l0Y2gob2lkKSB7CiAgICAgICAgY2FzZSAnc2hhMVdpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICAgIG1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ21kNVdpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICAgIG1kID0gZm9yZ2UubWQubWQ1LmNyZWF0ZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAnc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24nOgogICAgICAgICAgbWQgPSBmb3JnZS5tZC5zaGEyNTYuY3JlYXRlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICdzaGE1MTJXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgICBtZCA9IGZvcmdlLm1kLnNoYTUxMi5jcmVhdGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ1JTQVNTQS1QU1MnOgogICAgICAgICAgbWQgPSBmb3JnZS5tZC5zaGEyNTYuY3JlYXRlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYobWQgPT09IG51bGwpIHsKICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb21wdXRlIGNlcnRpZmljYXRlIGRpZ2VzdC4gJyArCiAgICAgICAgICAnVW5rbm93biBzaWduYXR1cmUgT0lELicpOwogICAgICAgIGVycm9yLnNpZ25hdHVyZU9pZCA9IGNoaWxkLnNpZ25hdHVyZU9pZDsKICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgfQoKICAgICAgLy8gcHJvZHVjZSBERVIgZm9ybWF0dGVkIFRCU0NlcnRpZmljYXRlIGFuZCBkaWdlc3QgaXQKICAgICAgdmFyIHRic0NlcnRpZmljYXRlID0gY2hpbGQudGJzQ2VydGlmaWNhdGUgfHwgcGtpLmdldFRCU0NlcnRpZmljYXRlKGNoaWxkKTsKICAgICAgdmFyIGJ5dGVzID0gYXNuMS50b0Rlcih0YnNDZXJ0aWZpY2F0ZSk7CiAgICAgIG1kLnVwZGF0ZShieXRlcy5nZXRCeXRlcygpKTsKICAgIH0KCiAgICBpZihtZCAhPT0gbnVsbCkgewogICAgICB2YXIgc2NoZW1lOwoKICAgICAgc3dpdGNoKGNoaWxkLnNpZ25hdHVyZU9pZCkgewogICAgICBjYXNlIG9pZHMuc2hhMVdpdGhSU0FFbmNyeXB0aW9uOgogICAgICAgIHNjaGVtZSA9IHVuZGVmaW5lZDsgIC8qIHVzZSBQS0NTIzEgdjEuNSBwYWRkaW5nIHNjaGVtZSAqLwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIG9pZHNbJ1JTQVNTQS1QU1MnXToKICAgICAgICB2YXIgaGFzaCwgbWdmOwoKICAgICAgICAvKiBpbml0aWFsaXplIG1nZiAqLwogICAgICAgIGhhc2ggPSBvaWRzW2NoaWxkLnNpZ25hdHVyZVBhcmFtZXRlcnMubWdmLmhhc2guYWxnb3JpdGhtT2lkXTsKICAgICAgICBpZihoYXNoID09PSB1bmRlZmluZWQgfHwgZm9yZ2UubWRbaGFzaF0gPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBNR0YgaGFzaCBmdW5jdGlvbi4nKTsKICAgICAgICAgIGVycm9yLm9pZCA9IGNoaWxkLnNpZ25hdHVyZVBhcmFtZXRlcnMubWdmLmhhc2guYWxnb3JpdGhtT2lkOwogICAgICAgICAgZXJyb3IubmFtZSA9IGhhc2g7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CgogICAgICAgIG1nZiA9IG9pZHNbY2hpbGQuc2lnbmF0dXJlUGFyYW1ldGVycy5tZ2YuYWxnb3JpdGhtT2lkXTsKICAgICAgICBpZihtZ2YgPT09IHVuZGVmaW5lZCB8fCBmb3JnZS5tZ2ZbbWdmXSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIE1HRiBmdW5jdGlvbi4nKTsKICAgICAgICAgIGVycm9yLm9pZCA9IGNoaWxkLnNpZ25hdHVyZVBhcmFtZXRlcnMubWdmLmFsZ29yaXRobU9pZDsKICAgICAgICAgIGVycm9yLm5hbWUgPSBtZ2Y7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CgogICAgICAgIG1nZiA9IGZvcmdlLm1nZlttZ2ZdLmNyZWF0ZShmb3JnZS5tZFtoYXNoXS5jcmVhdGUoKSk7CgogICAgICAgIC8qIGluaXRpYWxpemUgaGFzaCBmdW5jdGlvbiAqLwogICAgICAgIGhhc2ggPSBvaWRzW2NoaWxkLnNpZ25hdHVyZVBhcmFtZXRlcnMuaGFzaC5hbGdvcml0aG1PaWRdOwogICAgICAgIGlmKGhhc2ggPT09IHVuZGVmaW5lZCB8fCBmb3JnZS5tZFtoYXNoXSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICB0aHJvdyB7CiAgICAgICAgICAgIG1lc3NhZ2U6ICdVbnN1cHBvcnRlZCBSU0FTU0EtUFNTIGhhc2ggZnVuY3Rpb24uJywKICAgICAgICAgICAgb2lkOiBjaGlsZC5zaWduYXR1cmVQYXJhbWV0ZXJzLmhhc2guYWxnb3JpdGhtT2lkLAogICAgICAgICAgICBuYW1lOiBoYXNoCiAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgc2NoZW1lID0gZm9yZ2UucHNzLmNyZWF0ZShmb3JnZS5tZFtoYXNoXS5jcmVhdGUoKSwgbWdmLAogICAgICAgICAgY2hpbGQuc2lnbmF0dXJlUGFyYW1ldGVycy5zYWx0TGVuZ3RoKTsKICAgICAgICBicmVhazsKICAgICAgfQoKICAgICAgLy8gdmVyaWZ5IHNpZ25hdHVyZSBvbiBjZXJ0IHVzaW5nIHB1YmxpYyBrZXkKICAgICAgcnZhbCA9IGNlcnQucHVibGljS2V5LnZlcmlmeSgKICAgICAgICBtZC5kaWdlc3QoKS5nZXRCeXRlcygpLCBjaGlsZC5zaWduYXR1cmUsIHNjaGVtZSk7CiAgICB9CgogICAgcmV0dXJuIHJ2YWw7CiAgfTsKCiAgLyoqCiAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgY2VydGlmaWNhdGUncyBpc3N1ZXIgbWF0Y2hlcyB0aGUgcGFzc2VkCiAgICogY2VydGlmaWNhdGUncyBzdWJqZWN0LiBOb3RlIHRoYXQgbm8gc2lnbmF0dXJlIGNoZWNrIGlzIHBlcmZvcm1lZC4KICAgKgogICAqIEBwYXJhbSBwYXJlbnQgdGhlIGNlcnRpZmljYXRlIHRvIGNoZWNrLgogICAqCiAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgY2VydGlmaWNhdGUncyBpc3N1ZXIgbWF0Y2hlcyB0aGUgcGFzc2VkIGNlcnRpZmljYXRlJ3MKICAgKiAgICAgICAgIHN1YmplY3QuCiAgICovCiAgY2VydC5pc0lzc3VlciA9IGZ1bmN0aW9uKHBhcmVudCkgewogICAgdmFyIHJ2YWwgPSBmYWxzZTsKCiAgICB2YXIgaSA9IGNlcnQuaXNzdWVyOwogICAgdmFyIHMgPSBwYXJlbnQuc3ViamVjdDsKCiAgICAvLyBjb21wYXJlIGhhc2hlcyBpZiBwcmVzZW50CiAgICBpZihpLmhhc2ggJiYgcy5oYXNoKSB7CiAgICAgIHJ2YWwgPSAoaS5oYXNoID09PSBzLmhhc2gpOwogICAgfSBlbHNlIGlmKGkuYXR0cmlidXRlcy5sZW5ndGggPT09IHMuYXR0cmlidXRlcy5sZW5ndGgpIHsKICAgICAgLy8gYWxsIGF0dHJpYnV0ZXMgYXJlIHRoZSBzYW1lIHNvIGlzc3VlciBtYXRjaGVzIHN1YmplY3QKICAgICAgcnZhbCA9IHRydWU7CiAgICAgIHZhciBpYXR0ciwgc2F0dHI7CiAgICAgIGZvcih2YXIgbiA9IDA7IHJ2YWwgJiYgbiA8IGkuYXR0cmlidXRlcy5sZW5ndGg7ICsrbikgewogICAgICAgIGlhdHRyID0gaS5hdHRyaWJ1dGVzW25dOwogICAgICAgIHNhdHRyID0gcy5hdHRyaWJ1dGVzW25dOwogICAgICAgIGlmKGlhdHRyLnR5cGUgIT09IHNhdHRyLnR5cGUgfHwgaWF0dHIudmFsdWUgIT09IHNhdHRyLnZhbHVlKSB7CiAgICAgICAgICAvLyBhdHRyaWJ1dGUgbWlzbWF0Y2gKICAgICAgICAgIHJ2YWwgPSBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcnZhbDsKICB9OwoKICAvKioKICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBjZXJ0aWZpY2F0ZSdzIHN1YmplY3QgbWF0Y2hlcyB0aGUgaXNzdWVyIG9mIHRoZQogICAqIGdpdmVuIGNlcnRpZmljYXRlKS4gTm90ZSB0aGF0IG5vdCBzaWduYXR1cmUgY2hlY2sgaXMgcGVyZm9ybWVkLgogICAqCiAgICogQHBhcmFtIGNoaWxkIHRoZSBjZXJ0aWZpY2F0ZSB0byBjaGVjay4KICAgKgogICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGNlcnRpZmljYXRlJ3Mgc3ViamVjdCBtYXRjaGVzIHRoZSBwYXNzZWQKICAgKiAgICAgICAgIGNlcnRpZmljYXRlJ3MgaXNzdWVyLgogICAqLwogIGNlcnQuaXNzdWVkID0gZnVuY3Rpb24oY2hpbGQpIHsKICAgIHJldHVybiBjaGlsZC5pc0lzc3VlcihjZXJ0KTsKICB9OwoKICAvKioKICAgKiBHZW5lcmF0ZXMgdGhlIHN1YmplY3RLZXlJZGVudGlmaWVyIGZvciB0aGlzIGNlcnRpZmljYXRlIGFzIGJ5dGUgYnVmZmVyLgogICAqCiAgICogQHJldHVybiB0aGUgc3ViamVjdEtleUlkZW50aWZpZXIgZm9yIHRoaXMgY2VydGlmaWNhdGUgYXMgYnl0ZSBidWZmZXIuCiAgICovCiAgY2VydC5nZW5lcmF0ZVN1YmplY3RLZXlJZGVudGlmaWVyID0gZnVuY3Rpb24oKSB7CiAgICAvKiBTZWU6IDQuMi4xLjIgc2VjdGlvbiBvZiB0aGUgdGhlIFJGQzMyODAsIGtleUlkZW50aWZpZXIgaXMgZWl0aGVyOgoKICAgICAgKDEpIFRoZSBrZXlJZGVudGlmaWVyIGlzIGNvbXBvc2VkIG9mIHRoZSAxNjAtYml0IFNIQS0xIGhhc2ggb2YgdGhlCiAgICAgICAgdmFsdWUgb2YgdGhlIEJJVCBTVFJJTkcgc3ViamVjdFB1YmxpY0tleSAoZXhjbHVkaW5nIHRoZSB0YWcsCiAgICAgICAgbGVuZ3RoLCBhbmQgbnVtYmVyIG9mIHVudXNlZCBiaXRzKS4KCiAgICAgICgyKSBUaGUga2V5SWRlbnRpZmllciBpcyBjb21wb3NlZCBvZiBhIGZvdXIgYml0IHR5cGUgZmllbGQgd2l0aAogICAgICAgIHRoZSB2YWx1ZSAwMTAwIGZvbGxvd2VkIGJ5IHRoZSBsZWFzdCBzaWduaWZpY2FudCA2MCBiaXRzIG9mIHRoZQogICAgICAgIFNIQS0xIGhhc2ggb2YgdGhlIHZhbHVlIG9mIHRoZSBCSVQgU1RSSU5HIHN1YmplY3RQdWJsaWNLZXkKICAgICAgICAoZXhjbHVkaW5nIHRoZSB0YWcsIGxlbmd0aCwgYW5kIG51bWJlciBvZiB1bnVzZWQgYml0IHN0cmluZyBiaXRzKS4KICAgICovCgogICAgLy8gc2tpcHBpbmcgdGhlIHRhZywgbGVuZ3RoLCBhbmQgbnVtYmVyIG9mIHVudXNlZCBiaXRzIGlzIHRoZSBzYW1lCiAgICAvLyBhcyBqdXN0IHVzaW5nIHRoZSBSU0FQdWJsaWNLZXkgKGZvciBSU0Ega2V5cywgd2hpY2ggYXJlIHRoZQogICAgLy8gb25seSBvbmVzIHN1cHBvcnRlZCkKICAgIHJldHVybiBwa2kuZ2V0UHVibGljS2V5RmluZ2VycHJpbnQoY2VydC5wdWJsaWNLZXksIHt0eXBlOiAnUlNBUHVibGljS2V5J30pOwogIH07CgogIC8qKgogICAqIFZlcmlmaWVzIHRoZSBzdWJqZWN0S2V5SWRlbnRpZmllciBleHRlbnNpb24gdmFsdWUgZm9yIHRoaXMgY2VydGlmaWNhdGUKICAgKiBhZ2FpbnN0IGl0cyBwdWJsaWMga2V5LiBJZiBubyBleHRlbnNpb24gaXMgZm91bmQsIGZhbHNlIHdpbGwgYmUKICAgKiByZXR1cm5lZC4KICAgKgogICAqIEByZXR1cm4gdHJ1ZSBpZiB2ZXJpZmllZCwgZmFsc2UgaWYgbm90LgogICAqLwogIGNlcnQudmVyaWZ5U3ViamVjdEtleUlkZW50aWZpZXIgPSBmdW5jdGlvbigpIHsKICAgIHZhciBvaWQgPSBvaWRzWydzdWJqZWN0S2V5SWRlbnRpZmllciddOwogICAgZm9yKHZhciBpID0gMDsgaSA8IGNlcnQuZXh0ZW5zaW9ucy5sZW5ndGg7ICsraSkgewogICAgICB2YXIgZXh0ID0gY2VydC5leHRlbnNpb25zW2ldOwogICAgICBpZihleHQuaWQgPT09IG9pZCkgewogICAgICAgIHZhciBza2kgPSBjZXJ0LmdlbmVyYXRlU3ViamVjdEtleUlkZW50aWZpZXIoKS5nZXRCeXRlcygpOwogICAgICAgIHJldHVybiAoZm9yZ2UudXRpbC5oZXhUb0J5dGVzKGV4dC5zdWJqZWN0S2V5SWRlbnRpZmllcikgPT09IHNraSk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBmYWxzZTsKICB9OwoKICByZXR1cm4gY2VydDsKfTsKCi8qKgogKiBDb252ZXJ0cyBhbiBYLjUwOXYzIFJTQSBjZXJ0aWZpY2F0ZSBmcm9tIGFuIEFTTi4xIG9iamVjdC4KICoKICogTm90ZTogSWYgdGhlIGNlcnRpZmljYXRlIGlzIHRvIGJlIHZlcmlmaWVkIHRoZW4gY29tcHV0ZSBoYXNoIHNob3VsZAogKiBiZSBzZXQgdG8gdHJ1ZS4gVGhlcmUgaXMgY3VycmVudGx5IG5vIGltcGxlbWVudGF0aW9uIGZvciBjb252ZXJ0aW5nCiAqIGEgY2VydGlmaWNhdGUgYmFjayB0byBBU04uMSBzbyB0aGUgVEJTQ2VydGlmaWNhdGUgcGFydCBvZiB0aGUgQVNOLjEKICogb2JqZWN0IG5lZWRzIHRvIGJlIHNjYW5uZWQgYmVmb3JlIHRoZSBjZXJ0IG9iamVjdCBpcyBjcmVhdGVkLgogKgogKiBAcGFyYW0gb2JqIHRoZSBhc24xIHJlcHJlc2VudGF0aW9uIG9mIGFuIFguNTA5djMgUlNBIGNlcnRpZmljYXRlLgogKiBAcGFyYW0gY29tcHV0ZUhhc2ggdHJ1ZSB0byBjb21wdXRlIHRoZSBoYXNoIGZvciB2ZXJpZmljYXRpb24uCiAqCiAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRlLgogKi8KcGtpLmNlcnRpZmljYXRlRnJvbUFzbjEgPSBmdW5jdGlvbihvYmosIGNvbXB1dGVIYXNoKSB7CiAgLy8gdmFsaWRhdGUgY2VydGlmaWNhdGUgYW5kIGNhcHR1cmUgZGF0YQogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgeDUwOUNlcnRpZmljYXRlVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIFguNTA5IGNlcnRpZmljYXRlLiAnICsKICAgICAgJ0FTTi4xIG9iamVjdCBpcyBub3QgYW4gWDUwOXYzIENlcnRpZmljYXRlLicpOwogICAgZXJyb3IuZXJyb3JzID0gZXJyb3JzOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICAvLyBlbnN1cmUgc2lnbmF0dXJlIGlzIG5vdCBpbnRlcnByZXRlZCBhcyBhbiBlbWJlZGRlZCBBU04uMSBvYmplY3QKICBpZih0eXBlb2YgY2FwdHVyZS5jZXJ0U2lnbmF0dXJlICE9PSAnc3RyaW5nJykgewogICAgdmFyIGNlcnRTaWduYXR1cmUgPSAnXHgwMCc7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgY2FwdHVyZS5jZXJ0U2lnbmF0dXJlLmxlbmd0aDsgKytpKSB7CiAgICAgIGNlcnRTaWduYXR1cmUgKz0gYXNuMS50b0RlcihjYXB0dXJlLmNlcnRTaWduYXR1cmVbaV0pLmdldEJ5dGVzKCk7CiAgICB9CiAgICBjYXB0dXJlLmNlcnRTaWduYXR1cmUgPSBjZXJ0U2lnbmF0dXJlOwogIH0KCiAgLy8gZ2V0IG9pZAogIHZhciBvaWQgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUucHVibGljS2V5T2lkKTsKICBpZihvaWQgIT09IHBraS5vaWRzWydyc2FFbmNyeXB0aW9uJ10pIHsKICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgcHVibGljIGtleS4gT0lEIGlzIG5vdCBSU0EuJyk7CiAgfQoKICAvLyBjcmVhdGUgY2VydGlmaWNhdGUKICB2YXIgY2VydCA9IHBraS5jcmVhdGVDZXJ0aWZpY2F0ZSgpOwogIGNlcnQudmVyc2lvbiA9IGNhcHR1cmUuY2VydFZlcnNpb24gPwogICAgY2FwdHVyZS5jZXJ0VmVyc2lvbi5jaGFyQ29kZUF0KDApIDogMDsKICB2YXIgc2VyaWFsID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5jZXJ0U2VyaWFsTnVtYmVyKTsKICBjZXJ0LnNlcmlhbE51bWJlciA9IHNlcmlhbC50b0hleCgpOwogIGNlcnQuc2lnbmF0dXJlT2lkID0gZm9yZ2UuYXNuMS5kZXJUb09pZChjYXB0dXJlLmNlcnRTaWduYXR1cmVPaWQpOwogIGNlcnQuc2lnbmF0dXJlUGFyYW1ldGVycyA9IF9yZWFkU2lnbmF0dXJlUGFyYW1ldGVycygKICAgIGNlcnQuc2lnbmF0dXJlT2lkLCBjYXB0dXJlLmNlcnRTaWduYXR1cmVQYXJhbXMsIHRydWUpOwogIGNlcnQuc2lnaW5mby5hbGdvcml0aG1PaWQgPSBmb3JnZS5hc24xLmRlclRvT2lkKGNhcHR1cmUuY2VydGluZm9TaWduYXR1cmVPaWQpOwogIGNlcnQuc2lnaW5mby5wYXJhbWV0ZXJzID0gX3JlYWRTaWduYXR1cmVQYXJhbWV0ZXJzKGNlcnQuc2lnaW5mby5hbGdvcml0aG1PaWQsCiAgICBjYXB0dXJlLmNlcnRpbmZvU2lnbmF0dXJlUGFyYW1zLCBmYWxzZSk7CiAgLy8gc2tpcCAidW51c2VkIGJpdHMiIGluIHNpZ25hdHVyZSB2YWx1ZSBCSVRTVFJJTkcKICB2YXIgc2lnbmF0dXJlID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5jZXJ0U2lnbmF0dXJlKTsKICArK3NpZ25hdHVyZS5yZWFkOwogIGNlcnQuc2lnbmF0dXJlID0gc2lnbmF0dXJlLmdldEJ5dGVzKCk7CgogIHZhciB2YWxpZGl0eSA9IFtdOwogIGlmKGNhcHR1cmUuY2VydFZhbGlkaXR5MVVUQ1RpbWUgIT09IHVuZGVmaW5lZCkgewogICAgdmFsaWRpdHkucHVzaChhc24xLnV0Y1RpbWVUb0RhdGUoY2FwdHVyZS5jZXJ0VmFsaWRpdHkxVVRDVGltZSkpOwogIH0KICBpZihjYXB0dXJlLmNlcnRWYWxpZGl0eTJHZW5lcmFsaXplZFRpbWUgIT09IHVuZGVmaW5lZCkgewogICAgdmFsaWRpdHkucHVzaChhc24xLmdlbmVyYWxpemVkVGltZVRvRGF0ZSgKICAgICAgY2FwdHVyZS5jZXJ0VmFsaWRpdHkyR2VuZXJhbGl6ZWRUaW1lKSk7CiAgfQogIGlmKGNhcHR1cmUuY2VydFZhbGlkaXR5M1VUQ1RpbWUgIT09IHVuZGVmaW5lZCkgewogICAgdmFsaWRpdHkucHVzaChhc24xLnV0Y1RpbWVUb0RhdGUoY2FwdHVyZS5jZXJ0VmFsaWRpdHkzVVRDVGltZSkpOwogIH0KICBpZihjYXB0dXJlLmNlcnRWYWxpZGl0eTRHZW5lcmFsaXplZFRpbWUgIT09IHVuZGVmaW5lZCkgewogICAgdmFsaWRpdHkucHVzaChhc24xLmdlbmVyYWxpemVkVGltZVRvRGF0ZSgKICAgICAgY2FwdHVyZS5jZXJ0VmFsaWRpdHk0R2VuZXJhbGl6ZWRUaW1lKSk7CiAgfQogIGlmKHZhbGlkaXR5Lmxlbmd0aCA+IDIpIHsKICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgbm90QmVmb3JlL25vdEFmdGVyIHZhbGlkaXR5IHRpbWVzOyBtb3JlICcgKwogICAgICAndGhhbiB0d28gdGltZXMgd2VyZSBwcm92aWRlZCBpbiB0aGUgY2VydGlmaWNhdGUuJyk7CiAgfQogIGlmKHZhbGlkaXR5Lmxlbmd0aCA8IDIpIHsKICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgbm90QmVmb3JlL25vdEFmdGVyIHZhbGlkaXR5IHRpbWVzOyB0aGV5ICcgKwogICAgICAnd2VyZSBub3QgcHJvdmlkZWQgYXMgZWl0aGVyIFVUQ1RpbWUgb3IgR2VuZXJhbGl6ZWRUaW1lLicpOwogIH0KICBjZXJ0LnZhbGlkaXR5Lm5vdEJlZm9yZSA9IHZhbGlkaXR5WzBdOwogIGNlcnQudmFsaWRpdHkubm90QWZ0ZXIgPSB2YWxpZGl0eVsxXTsKCiAgLy8ga2VlcCBUQlNDZXJ0aWZpY2F0ZSB0byBwcmVzZXJ2ZSBzaWduYXR1cmUgd2hlbiBleHBvcnRpbmcKICBjZXJ0LnRic0NlcnRpZmljYXRlID0gY2FwdHVyZS50YnNDZXJ0aWZpY2F0ZTsKCiAgaWYoY29tcHV0ZUhhc2gpIHsKICAgIC8vIGNoZWNrIHNpZ25hdHVyZSBPSUQgZm9yIHN1cHBvcnRlZCBzaWduYXR1cmUgdHlwZXMKICAgIGNlcnQubWQgPSBudWxsOwogICAgaWYoY2VydC5zaWduYXR1cmVPaWQgaW4gb2lkcykgewogICAgICB2YXIgb2lkID0gb2lkc1tjZXJ0LnNpZ25hdHVyZU9pZF07CiAgICAgIHN3aXRjaChvaWQpIHsKICAgICAgY2FzZSAnc2hhMVdpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICBjZXJ0Lm1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnbWQ1V2l0aFJTQUVuY3J5cHRpb24nOgogICAgICAgIGNlcnQubWQgPSBmb3JnZS5tZC5tZDUuY3JlYXRlKCk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgJ3NoYTI1NldpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICBjZXJ0Lm1kID0gZm9yZ2UubWQuc2hhMjU2LmNyZWF0ZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdzaGE1MTJXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgY2VydC5tZCA9IGZvcmdlLm1kLnNoYTUxMi5jcmVhdGUoKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnUlNBU1NBLVBTUyc6CiAgICAgICAgY2VydC5tZCA9IGZvcmdlLm1kLnNoYTI1Ni5jcmVhdGUoKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogICAgaWYoY2VydC5tZCA9PT0gbnVsbCkgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb21wdXRlIGNlcnRpZmljYXRlIGRpZ2VzdC4gJyArCiAgICAgICAgJ1Vua25vd24gc2lnbmF0dXJlIE9JRC4nKTsKICAgICAgZXJyb3Iuc2lnbmF0dXJlT2lkID0gY2VydC5zaWduYXR1cmVPaWQ7CiAgICAgIHRocm93IGVycm9yOwogICAgfQoKICAgIC8vIHByb2R1Y2UgREVSIGZvcm1hdHRlZCBUQlNDZXJ0aWZpY2F0ZSBhbmQgZGlnZXN0IGl0CiAgICB2YXIgYnl0ZXMgPSBhc24xLnRvRGVyKGNlcnQudGJzQ2VydGlmaWNhdGUpOwogICAgY2VydC5tZC51cGRhdGUoYnl0ZXMuZ2V0Qnl0ZXMoKSk7CiAgfQoKICAvLyBoYW5kbGUgaXNzdWVyLCBidWlsZCBpc3N1ZXIgbWVzc2FnZSBkaWdlc3QKICB2YXIgaW1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICBjZXJ0Lmlzc3Vlci5nZXRGaWVsZCA9IGZ1bmN0aW9uKHNuKSB7CiAgICByZXR1cm4gX2dldEF0dHJpYnV0ZShjZXJ0Lmlzc3Vlciwgc24pOwogIH07CiAgY2VydC5pc3N1ZXIuYWRkRmllbGQgPSBmdW5jdGlvbihhdHRyKSB7CiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoW2F0dHJdKTsKICAgIGNlcnQuaXNzdWVyLmF0dHJpYnV0ZXMucHVzaChhdHRyKTsKICB9OwogIGNlcnQuaXNzdWVyLmF0dHJpYnV0ZXMgPSBwa2kuUkROQXR0cmlidXRlc0FzQXJyYXkoY2FwdHVyZS5jZXJ0SXNzdWVyLCBpbWQpOwogIGlmKGNhcHR1cmUuY2VydElzc3VlclVuaXF1ZUlkKSB7CiAgICBjZXJ0Lmlzc3Vlci51bmlxdWVJZCA9IGNhcHR1cmUuY2VydElzc3VlclVuaXF1ZUlkOwogIH0KICBjZXJ0Lmlzc3Vlci5oYXNoID0gaW1kLmRpZ2VzdCgpLnRvSGV4KCk7CgogIC8vIGhhbmRsZSBzdWJqZWN0LCBidWlsZCBzdWJqZWN0IG1lc3NhZ2UgZGlnZXN0CiAgdmFyIHNtZCA9IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgY2VydC5zdWJqZWN0LmdldEZpZWxkID0gZnVuY3Rpb24oc24pIHsKICAgIHJldHVybiBfZ2V0QXR0cmlidXRlKGNlcnQuc3ViamVjdCwgc24pOwogIH07CiAgY2VydC5zdWJqZWN0LmFkZEZpZWxkID0gZnVuY3Rpb24oYXR0cikgewogICAgX2ZpbGxNaXNzaW5nRmllbGRzKFthdHRyXSk7CiAgICBjZXJ0LnN1YmplY3QuYXR0cmlidXRlcy5wdXNoKGF0dHIpOwogIH07CiAgY2VydC5zdWJqZWN0LmF0dHJpYnV0ZXMgPSBwa2kuUkROQXR0cmlidXRlc0FzQXJyYXkoY2FwdHVyZS5jZXJ0U3ViamVjdCwgc21kKTsKICBpZihjYXB0dXJlLmNlcnRTdWJqZWN0VW5pcXVlSWQpIHsKICAgIGNlcnQuc3ViamVjdC51bmlxdWVJZCA9IGNhcHR1cmUuY2VydFN1YmplY3RVbmlxdWVJZDsKICB9CiAgY2VydC5zdWJqZWN0Lmhhc2ggPSBzbWQuZGlnZXN0KCkudG9IZXgoKTsKCiAgLy8gaGFuZGxlIGV4dGVuc2lvbnMKICBpZihjYXB0dXJlLmNlcnRFeHRlbnNpb25zKSB7CiAgICBjZXJ0LmV4dGVuc2lvbnMgPSBwa2kuY2VydGlmaWNhdGVFeHRlbnNpb25zRnJvbUFzbjEoY2FwdHVyZS5jZXJ0RXh0ZW5zaW9ucyk7CiAgfSBlbHNlIHsKICAgIGNlcnQuZXh0ZW5zaW9ucyA9IFtdOwogIH0KCiAgLy8gY29udmVydCBSU0EgcHVibGljIGtleSBmcm9tIEFTTi4xCiAgY2VydC5wdWJsaWNLZXkgPSBwa2kucHVibGljS2V5RnJvbUFzbjEoY2FwdHVyZS5zdWJqZWN0UHVibGljS2V5SW5mbyk7CgogIHJldHVybiBjZXJ0Owp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIEFTTi4xIGV4dGVuc2lvbnMgb2JqZWN0ICh3aXRoIGV4dGVuc2lvbiBzZXF1ZW5jZXMgYXMgaXRzCiAqIHZhbHVlcykgaW50byBhbiBhcnJheSBvZiBleHRlbnNpb24gb2JqZWN0cyB3aXRoIHR5cGVzIGFuZCB2YWx1ZXMuCiAqCiAqIFN1cHBvcnRlZCBleHRlbnNpb25zOgogKgogKiBpZC1jZS1rZXlVc2FnZSBPQkpFQ1QgSURFTlRJRklFUiA6Oj0gIHsgaWQtY2UgMTUgfQogKiBLZXlVc2FnZSA6Oj0gQklUIFNUUklORyB7CiAqICAgZGlnaXRhbFNpZ25hdHVyZSAgICAgICAgKDApLAogKiAgIG5vblJlcHVkaWF0aW9uICAgICAgICAgICgxKSwKICogICBrZXlFbmNpcGhlcm1lbnQgICAgICAgICAoMiksCiAqICAgZGF0YUVuY2lwaGVybWVudCAgICAgICAgKDMpLAogKiAgIGtleUFncmVlbWVudCAgICAgICAgICAgICg0KSwKICogICBrZXlDZXJ0U2lnbiAgICAgICAgICAgICAoNSksCiAqICAgY1JMU2lnbiAgICAgICAgICAgICAgICAgKDYpLAogKiAgIGVuY2lwaGVyT25seSAgICAgICAgICAgICg3KSwKICogICBkZWNpcGhlck9ubHkgICAgICAgICAgICAoOCkKICogfQogKgogKiBpZC1jZS1iYXNpY0NvbnN0cmFpbnRzIE9CSkVDVCBJREVOVElGSUVSIDo6PSAgeyBpZC1jZSAxOSB9CiAqIEJhc2ljQ29uc3RyYWludHMgOjo9IFNFUVVFTkNFIHsKICogICBjQSAgICAgICAgICAgICAgICAgICAgICBCT09MRUFOIERFRkFVTFQgRkFMU0UsCiAqICAgcGF0aExlbkNvbnN0cmFpbnQgICAgICAgSU5URUdFUiAoMC4uTUFYKSBPUFRJT05BTAogKiB9CiAqCiAqIHN1YmplY3RBbHROYW1lIEVYVEVOU0lPTiA6Oj0gewogKiAgIFNZTlRBWCBHZW5lcmFsTmFtZXMKICogICBJREVOVElGSUVEIEJZIGlkLWNlLXN1YmplY3RBbHROYW1lCiAqIH0KICoKICogR2VuZXJhbE5hbWVzIDo6PSBTRVFVRU5DRSBTSVpFICgxLi5NQVgpIE9GIEdlbmVyYWxOYW1lCiAqCiAqIEdlbmVyYWxOYW1lIDo6PSBDSE9JQ0UgewogKiAgIG90aGVyTmFtZSAgICAgIFswXSBJTlNUQU5DRSBPRiBPVEhFUi1OQU1FLAogKiAgIHJmYzgyMk5hbWUgICAgIFsxXSBJQTVTdHJpbmcsCiAqICAgZE5TTmFtZSAgICAgICAgWzJdIElBNVN0cmluZywKICogICB4NDAwQWRkcmVzcyAgICBbM10gT1JBZGRyZXNzLAogKiAgIGRpcmVjdG9yeU5hbWUgIFs0XSBOYW1lLAogKiAgIGVkaVBhcnR5TmFtZSAgIFs1XSBFRElQYXJ0eU5hbWUsCiAqICAgdW5pZm9ybVJlc291cmNlSWRlbnRpZmllciBbNl0gSUE1U3RyaW5nLAogKiAgIElQQWRkcmVzcyAgICAgIFs3XSBPQ1RFVCBTVFJJTkcsCiAqICAgcmVnaXN0ZXJlZElEICAgWzhdIE9CSkVDVCBJREVOVElGSUVSCiAqIH0KICoKICogT1RIRVItTkFNRSA6Oj0gVFlQRS1JREVOVElGSUVSCiAqCiAqIEVESVBhcnR5TmFtZSA6Oj0gU0VRVUVOQ0UgewogKiAgIG5hbWVBc3NpZ25lciBbMF0gRGlyZWN0b3J5U3RyaW5nIHt1Yi1uYW1lfSBPUFRJT05BTCwKICogICBwYXJ0eU5hbWUgICAgWzFdIERpcmVjdG9yeVN0cmluZyB7dWItbmFtZX0KICogfQogKgogKiBAcGFyYW0gZXh0cyB0aGUgZXh0ZW5zaW9ucyBBU04uMSB3aXRoIGV4dGVuc2lvbiBzZXF1ZW5jZXMgdG8gcGFyc2UuCiAqCiAqIEByZXR1cm4gdGhlIGFycmF5LgogKi8KcGtpLmNlcnRpZmljYXRlRXh0ZW5zaW9uc0Zyb21Bc24xID0gZnVuY3Rpb24oZXh0cykgewogIHZhciBydmFsID0gW107CiAgZm9yKHZhciBpID0gMDsgaSA8IGV4dHMudmFsdWUubGVuZ3RoOyArK2kpIHsKICAgIC8vIGdldCBleHRlbnNpb24gc2VxdWVuY2UKICAgIHZhciBleHRzZXEgPSBleHRzLnZhbHVlW2ldOwogICAgZm9yKHZhciBlaSA9IDA7IGVpIDwgZXh0c2VxLnZhbHVlLmxlbmd0aDsgKytlaSkgewogICAgICBydmFsLnB1c2gocGtpLmNlcnRpZmljYXRlRXh0ZW5zaW9uRnJvbUFzbjEoZXh0c2VxLnZhbHVlW2VpXSkpOwogICAgfQogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogUGFyc2VzIGEgc2luZ2xlIGNlcnRpZmljYXRlIGV4dGVuc2lvbiBmcm9tIEFTTi4xLgogKgogKiBAcGFyYW0gZXh0IHRoZSBleHRlbnNpb24gaW4gQVNOLjEgZm9ybWF0LgogKgogKiBAcmV0dXJuIHRoZSBwYXJzZWQgZXh0ZW5zaW9uIGFzIGFuIG9iamVjdC4KICovCnBraS5jZXJ0aWZpY2F0ZUV4dGVuc2lvbkZyb21Bc24xID0gZnVuY3Rpb24oZXh0KSB7CiAgLy8gYW4gZXh0ZW5zaW9uIGhhczoKICAvLyBbMF0gZXh0bklEICAgICAgT0JKRUNUIElERU5USUZJRVIKICAvLyBbMV0gY3JpdGljYWwgICAgQk9PTEVBTiBERUZBVUxUIEZBTFNFCiAgLy8gWzJdIGV4dG5WYWx1ZSAgIE9DVEVUIFNUUklORwogIHZhciBlID0ge307CiAgZS5pZCA9IGFzbjEuZGVyVG9PaWQoZXh0LnZhbHVlWzBdLnZhbHVlKTsKICBlLmNyaXRpY2FsID0gZmFsc2U7CiAgaWYoZXh0LnZhbHVlWzFdLnR5cGUgPT09IGFzbjEuVHlwZS5CT09MRUFOKSB7CiAgICBlLmNyaXRpY2FsID0gKGV4dC52YWx1ZVsxXS52YWx1ZS5jaGFyQ29kZUF0KDApICE9PSAweDAwKTsKICAgIGUudmFsdWUgPSBleHQudmFsdWVbMl0udmFsdWU7CiAgfSBlbHNlIHsKICAgIGUudmFsdWUgPSBleHQudmFsdWVbMV0udmFsdWU7CiAgfQogIC8vIGlmIHRoZSBvaWQgaXMga25vd24sIGdldCBpdHMgbmFtZQogIGlmKGUuaWQgaW4gb2lkcykgewogICAgZS5uYW1lID0gb2lkc1tlLmlkXTsKCiAgICAvLyBoYW5kbGUga2V5IHVzYWdlCiAgICBpZihlLm5hbWUgPT09ICdrZXlVc2FnZScpIHsKICAgICAgLy8gZ2V0IHZhbHVlIGFzIEJJVCBTVFJJTkcKICAgICAgdmFyIGV2ID0gYXNuMS5mcm9tRGVyKGUudmFsdWUpOwogICAgICB2YXIgYjIgPSAweDAwOwogICAgICB2YXIgYjMgPSAweDAwOwogICAgICBpZihldi52YWx1ZS5sZW5ndGggPiAxKSB7CiAgICAgICAgLy8gc2tpcCBmaXJzdCBieXRlLCBqdXN0IGluZGljYXRlcyB1bnVzZWQgYml0cyB3aGljaAogICAgICAgIC8vIHdpbGwgYmUgcGFkZGVkIHdpdGggMHMgYW55d2F5CiAgICAgICAgLy8gZ2V0IGJ5dGVzIHdpdGggZmxhZyBiaXRzCiAgICAgICAgYjIgPSBldi52YWx1ZS5jaGFyQ29kZUF0KDEpOwogICAgICAgIGIzID0gZXYudmFsdWUubGVuZ3RoID4gMiA/IGV2LnZhbHVlLmNoYXJDb2RlQXQoMikgOiAwOwogICAgICB9CiAgICAgIC8vIHNldCBmbGFncwogICAgICBlLmRpZ2l0YWxTaWduYXR1cmUgPSAoYjIgJiAweDgwKSA9PT0gMHg4MDsKICAgICAgZS5ub25SZXB1ZGlhdGlvbiA9IChiMiAmIDB4NDApID09PSAweDQwOwogICAgICBlLmtleUVuY2lwaGVybWVudCA9IChiMiAmIDB4MjApID09PSAweDIwOwogICAgICBlLmRhdGFFbmNpcGhlcm1lbnQgPSAoYjIgJiAweDEwKSA9PT0gMHgxMDsKICAgICAgZS5rZXlBZ3JlZW1lbnQgPSAoYjIgJiAweDA4KSA9PT0gMHgwODsKICAgICAgZS5rZXlDZXJ0U2lnbiA9IChiMiAmIDB4MDQpID09PSAweDA0OwogICAgICBlLmNSTFNpZ24gPSAoYjIgJiAweDAyKSA9PT0gMHgwMjsKICAgICAgZS5lbmNpcGhlck9ubHkgPSAoYjIgJiAweDAxKSA9PT0gMHgwMTsKICAgICAgZS5kZWNpcGhlck9ubHkgPSAoYjMgJiAweDgwKSA9PT0gMHg4MDsKICAgIH0gZWxzZSBpZihlLm5hbWUgPT09ICdiYXNpY0NvbnN0cmFpbnRzJykgewogICAgICAvLyBoYW5kbGUgYmFzaWMgY29uc3RyYWludHMKICAgICAgLy8gZ2V0IHZhbHVlIGFzIFNFUVVFTkNFCiAgICAgIHZhciBldiA9IGFzbjEuZnJvbURlcihlLnZhbHVlKTsKICAgICAgLy8gZ2V0IGNBIEJPT0xFQU4gZmxhZyAoZGVmYXVsdHMgdG8gZmFsc2UpCiAgICAgIGlmKGV2LnZhbHVlLmxlbmd0aCA+IDAgJiYgZXYudmFsdWVbMF0udHlwZSA9PT0gYXNuMS5UeXBlLkJPT0xFQU4pIHsKICAgICAgICBlLmNBID0gKGV2LnZhbHVlWzBdLnZhbHVlLmNoYXJDb2RlQXQoMCkgIT09IDB4MDApOwogICAgICB9IGVsc2UgewogICAgICAgIGUuY0EgPSBmYWxzZTsKICAgICAgfQogICAgICAvLyBnZXQgcGF0aCBsZW5ndGggY29uc3RyYWludAogICAgICB2YXIgdmFsdWUgPSBudWxsOwogICAgICBpZihldi52YWx1ZS5sZW5ndGggPiAwICYmIGV2LnZhbHVlWzBdLnR5cGUgPT09IGFzbjEuVHlwZS5JTlRFR0VSKSB7CiAgICAgICAgdmFsdWUgPSBldi52YWx1ZVswXS52YWx1ZTsKICAgICAgfSBlbHNlIGlmKGV2LnZhbHVlLmxlbmd0aCA+IDEpIHsKICAgICAgICB2YWx1ZSA9IGV2LnZhbHVlWzFdLnZhbHVlOwogICAgICB9CiAgICAgIGlmKHZhbHVlICE9PSBudWxsKSB7CiAgICAgICAgZS5wYXRoTGVuQ29uc3RyYWludCA9IGFzbjEuZGVyVG9JbnRlZ2VyKHZhbHVlKTsKICAgICAgfQogICAgfSBlbHNlIGlmKGUubmFtZSA9PT0gJ2V4dEtleVVzYWdlJykgewogICAgICAvLyBoYW5kbGUgZXh0S2V5VXNhZ2UKICAgICAgLy8gdmFsdWUgaXMgYSBTRVFVRU5DRSBvZiBPSURzCiAgICAgIHZhciBldiA9IGFzbjEuZnJvbURlcihlLnZhbHVlKTsKICAgICAgZm9yKHZhciB2aSA9IDA7IHZpIDwgZXYudmFsdWUubGVuZ3RoOyArK3ZpKSB7CiAgICAgICAgdmFyIG9pZCA9IGFzbjEuZGVyVG9PaWQoZXYudmFsdWVbdmldLnZhbHVlKTsKICAgICAgICBpZihvaWQgaW4gb2lkcykgewogICAgICAgICAgZVtvaWRzW29pZF1dID0gdHJ1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZVtvaWRdID0gdHJ1ZTsKICAgICAgICB9CiAgICAgIH0KICAgIH0gZWxzZSBpZihlLm5hbWUgPT09ICduc0NlcnRUeXBlJykgewogICAgICAvLyBoYW5kbGUgbnNDZXJ0VHlwZQogICAgICAvLyBnZXQgdmFsdWUgYXMgQklUIFNUUklORwogICAgICB2YXIgZXYgPSBhc24xLmZyb21EZXIoZS52YWx1ZSk7CiAgICAgIHZhciBiMiA9IDB4MDA7CiAgICAgIGlmKGV2LnZhbHVlLmxlbmd0aCA+IDEpIHsKICAgICAgICAvLyBza2lwIGZpcnN0IGJ5dGUsIGp1c3QgaW5kaWNhdGVzIHVudXNlZCBiaXRzIHdoaWNoCiAgICAgICAgLy8gd2lsbCBiZSBwYWRkZWQgd2l0aCAwcyBhbnl3YXkKICAgICAgICAvLyBnZXQgYnl0ZXMgd2l0aCBmbGFnIGJpdHMKICAgICAgICBiMiA9IGV2LnZhbHVlLmNoYXJDb2RlQXQoMSk7CiAgICAgIH0KICAgICAgLy8gc2V0IGZsYWdzCiAgICAgIGUuY2xpZW50ID0gKGIyICYgMHg4MCkgPT09IDB4ODA7CiAgICAgIGUuc2VydmVyID0gKGIyICYgMHg0MCkgPT09IDB4NDA7CiAgICAgIGUuZW1haWwgPSAoYjIgJiAweDIwKSA9PT0gMHgyMDsKICAgICAgZS5vYmpzaWduID0gKGIyICYgMHgxMCkgPT09IDB4MTA7CiAgICAgIGUucmVzZXJ2ZWQgPSAoYjIgJiAweDA4KSA9PT0gMHgwODsKICAgICAgZS5zc2xDQSA9IChiMiAmIDB4MDQpID09PSAweDA0OwogICAgICBlLmVtYWlsQ0EgPSAoYjIgJiAweDAyKSA9PT0gMHgwMjsKICAgICAgZS5vYmpDQSA9IChiMiAmIDB4MDEpID09PSAweDAxOwogICAgfSBlbHNlIGlmKAogICAgICBlLm5hbWUgPT09ICdzdWJqZWN0QWx0TmFtZScgfHwKICAgICAgZS5uYW1lID09PSAnaXNzdWVyQWx0TmFtZScpIHsKICAgICAgLy8gaGFuZGxlIHN1YmplY3RBbHROYW1lL2lzc3VlckFsdE5hbWUKICAgICAgZS5hbHROYW1lcyA9IFtdOwoKICAgICAgLy8gZXYgaXMgYSBTWU5UQVggU0VRVUVOQ0UKICAgICAgdmFyIGduOwogICAgICB2YXIgZXYgPSBhc24xLmZyb21EZXIoZS52YWx1ZSk7CiAgICAgIGZvcih2YXIgbiA9IDA7IG4gPCBldi52YWx1ZS5sZW5ndGg7ICsrbikgewogICAgICAgIC8vIGdldCBHZW5lcmFsTmFtZQogICAgICAgIGduID0gZXYudmFsdWVbbl07CgogICAgICAgIHZhciBhbHROYW1lID0gewogICAgICAgICAgdHlwZTogZ24udHlwZSwKICAgICAgICAgIHZhbHVlOiBnbi52YWx1ZQogICAgICAgIH07CiAgICAgICAgZS5hbHROYW1lcy5wdXNoKGFsdE5hbWUpOwoKICAgICAgICAvLyBOb3RlOiBTdXBwb3J0IGZvciB0eXBlcyAxLDIsNiw3LDgKICAgICAgICBzd2l0Y2goZ24udHlwZSkgewogICAgICAgIC8vIHJmYzgyMk5hbWUKICAgICAgICBjYXNlIDE6CiAgICAgICAgLy8gZE5TTmFtZQogICAgICAgIGNhc2UgMjoKICAgICAgICAvLyB1bmlmb3JtUmVzb3VyY2VJZGVudGlmaWVyIChVUkkpCiAgICAgICAgY2FzZSA2OgogICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gSVBBZGRyZXNzCiAgICAgICAgY2FzZSA3OgogICAgICAgICAgLy8gY29udmVydCB0byBJUHY0L0lQdjYgc3RyaW5nIHJlcHJlc2VudGF0aW9uCiAgICAgICAgICBhbHROYW1lLmlwID0gZm9yZ2UudXRpbC5ieXRlc1RvSVAoZ24udmFsdWUpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gcmVnaXN0ZXJlZElECiAgICAgICAgY2FzZSA4OgogICAgICAgICAgYWx0TmFtZS5vaWQgPSBhc24xLmRlclRvT2lkKGduLnZhbHVlKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAvLyB1bnN1cHBvcnRlZAogICAgICAgIH0KICAgICAgfQogICAgfSBlbHNlIGlmKGUubmFtZSA9PT0gJ3N1YmplY3RLZXlJZGVudGlmaWVyJykgewogICAgICAvLyB2YWx1ZSBpcyBhbiBPQ1RFVFNUUklORyB3L3RoZSBoYXNoIG9mIHRoZSBrZXktdHlwZSBzcGVjaWZpYwogICAgICAvLyBwdWJsaWMga2V5IHN0cnVjdHVyZSAoZWc6IFJTQVB1YmxpY0tleSkKICAgICAgdmFyIGV2ID0gYXNuMS5mcm9tRGVyKGUudmFsdWUpOwogICAgICBlLnN1YmplY3RLZXlJZGVudGlmaWVyID0gZm9yZ2UudXRpbC5ieXRlc1RvSGV4KGV2LnZhbHVlKTsKICAgIH0KICB9CiAgcmV0dXJuIGU7Cn07CgovKioKICogQ29udmVydHMgYSBQS0NTIzEwIGNlcnRpZmljYXRpb24gcmVxdWVzdCAoQ1NSKSBmcm9tIGFuIEFTTi4xIG9iamVjdC4KICoKICogTm90ZTogSWYgdGhlIGNlcnRpZmljYXRpb24gcmVxdWVzdCBpcyB0byBiZSB2ZXJpZmllZCB0aGVuIGNvbXB1dGUgaGFzaAogKiBzaG91bGQgYmUgc2V0IHRvIHRydWUuIFRoZXJlIGlzIGN1cnJlbnRseSBubyBpbXBsZW1lbnRhdGlvbiBmb3IgY29udmVydGluZwogKiBhIGNlcnRpZmljYXRlIGJhY2sgdG8gQVNOLjEgc28gdGhlIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyBwYXJ0IG9mIHRoZQogKiBBU04uMSBvYmplY3QgbmVlZHMgdG8gYmUgc2Nhbm5lZCBiZWZvcmUgdGhlIGNzciBvYmplY3QgaXMgY3JlYXRlZC4KICoKICogQHBhcmFtIG9iaiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhIFBLQ1MjMTAgY2VydGlmaWNhdGlvbiByZXF1ZXN0IChDU1IpLgogKiBAcGFyYW0gY29tcHV0ZUhhc2ggdHJ1ZSB0byBjb21wdXRlIHRoZSBoYXNoIGZvciB2ZXJpZmljYXRpb24uCiAqCiAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRpb24gcmVxdWVzdCAoQ1NSKS4KICovCnBraS5jZXJ0aWZpY2F0aW9uUmVxdWVzdEZyb21Bc24xID0gZnVuY3Rpb24ob2JqLCBjb21wdXRlSGFzaCkgewogIC8vIHZhbGlkYXRlIGNlcnRpZmljYXRpb24gcmVxdWVzdCBhbmQgY2FwdHVyZSBkYXRhCiAgdmFyIGNhcHR1cmUgPSB7fTsKICB2YXIgZXJyb3JzID0gW107CiAgaWYoIWFzbjEudmFsaWRhdGUob2JqLCBjZXJ0aWZpY2F0aW9uUmVxdWVzdFZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzEwIGNlcnRpZmljYXRlIHJlcXVlc3QuICcgKwogICAgICAnQVNOLjEgb2JqZWN0IGlzIG5vdCBhIFBLQ1MjMTAgQ2VydGlmaWNhdGlvblJlcXVlc3QuJyk7CiAgICBlcnJvci5lcnJvcnMgPSBlcnJvcnM7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIC8vIGVuc3VyZSBzaWduYXR1cmUgaXMgbm90IGludGVycHJldGVkIGFzIGFuIGVtYmVkZGVkIEFTTi4xIG9iamVjdAogIGlmKHR5cGVvZiBjYXB0dXJlLmNzclNpZ25hdHVyZSAhPT0gJ3N0cmluZycpIHsKICAgIHZhciBjc3JTaWduYXR1cmUgPSAnXHgwMCc7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgY2FwdHVyZS5jc3JTaWduYXR1cmUubGVuZ3RoOyArK2kpIHsKICAgICAgY3NyU2lnbmF0dXJlICs9IGFzbjEudG9EZXIoY2FwdHVyZS5jc3JTaWduYXR1cmVbaV0pLmdldEJ5dGVzKCk7CiAgICB9CiAgICBjYXB0dXJlLmNzclNpZ25hdHVyZSA9IGNzclNpZ25hdHVyZTsKICB9CgogIC8vIGdldCBvaWQKICB2YXIgb2lkID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLnB1YmxpY0tleU9pZCk7CiAgaWYob2lkICE9PSBwa2kub2lkcy5yc2FFbmNyeXB0aW9uKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIHB1YmxpYyBrZXkuIE9JRCBpcyBub3QgUlNBLicpOwogIH0KCiAgLy8gY3JlYXRlIGNlcnRpZmljYXRpb24gcmVxdWVzdAogIHZhciBjc3IgPSBwa2kuY3JlYXRlQ2VydGlmaWNhdGlvblJlcXVlc3QoKTsKICBjc3IudmVyc2lvbiA9IGNhcHR1cmUuY3NyVmVyc2lvbiA/IGNhcHR1cmUuY3NyVmVyc2lvbi5jaGFyQ29kZUF0KDApIDogMDsKICBjc3Iuc2lnbmF0dXJlT2lkID0gZm9yZ2UuYXNuMS5kZXJUb09pZChjYXB0dXJlLmNzclNpZ25hdHVyZU9pZCk7CiAgY3NyLnNpZ25hdHVyZVBhcmFtZXRlcnMgPSBfcmVhZFNpZ25hdHVyZVBhcmFtZXRlcnMoCiAgICBjc3Iuc2lnbmF0dXJlT2lkLCBjYXB0dXJlLmNzclNpZ25hdHVyZVBhcmFtcywgdHJ1ZSk7CiAgY3NyLnNpZ2luZm8uYWxnb3JpdGhtT2lkID0gZm9yZ2UuYXNuMS5kZXJUb09pZChjYXB0dXJlLmNzclNpZ25hdHVyZU9pZCk7CiAgY3NyLnNpZ2luZm8ucGFyYW1ldGVycyA9IF9yZWFkU2lnbmF0dXJlUGFyYW1ldGVycygKICAgIGNzci5zaWdpbmZvLmFsZ29yaXRobU9pZCwgY2FwdHVyZS5jc3JTaWduYXR1cmVQYXJhbXMsIGZhbHNlKTsKICAvLyBza2lwICJ1bnVzZWQgYml0cyIgaW4gc2lnbmF0dXJlIHZhbHVlIEJJVFNUUklORwogIHZhciBzaWduYXR1cmUgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLmNzclNpZ25hdHVyZSk7CiAgKytzaWduYXR1cmUucmVhZDsKICBjc3Iuc2lnbmF0dXJlID0gc2lnbmF0dXJlLmdldEJ5dGVzKCk7CgogIC8vIGtlZXAgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIHRvIHByZXNlcnZlIHNpZ25hdHVyZSB3aGVuIGV4cG9ydGluZwogIGNzci5jZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8gPSBjYXB0dXJlLmNlcnRpZmljYXRpb25SZXF1ZXN0SW5mbzsKCiAgaWYoY29tcHV0ZUhhc2gpIHsKICAgIC8vIGNoZWNrIHNpZ25hdHVyZSBPSUQgZm9yIHN1cHBvcnRlZCBzaWduYXR1cmUgdHlwZXMKICAgIGNzci5tZCA9IG51bGw7CiAgICBpZihjc3Iuc2lnbmF0dXJlT2lkIGluIG9pZHMpIHsKICAgICAgdmFyIG9pZCA9IG9pZHNbY3NyLnNpZ25hdHVyZU9pZF07CiAgICAgIHN3aXRjaChvaWQpIHsKICAgICAgY2FzZSAnc2hhMVdpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICBjc3IubWQgPSBmb3JnZS5tZC5zaGExLmNyZWF0ZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdtZDVXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgY3NyLm1kID0gZm9yZ2UubWQubWQ1LmNyZWF0ZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgY3NyLm1kID0gZm9yZ2UubWQuc2hhMjU2LmNyZWF0ZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdzaGE1MTJXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgY3NyLm1kID0gZm9yZ2UubWQuc2hhNTEyLmNyZWF0ZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdSU0FTU0EtUFNTJzoKICAgICAgICBjc3IubWQgPSBmb3JnZS5tZC5zaGEyNTYuY3JlYXRlKCk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIGlmKGNzci5tZCA9PT0gbnVsbCkgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb21wdXRlIGNlcnRpZmljYXRpb24gcmVxdWVzdCBkaWdlc3QuICcgKwogICAgICAgICdVbmtub3duIHNpZ25hdHVyZSBPSUQuJyk7CiAgICAgIGVycm9yLnNpZ25hdHVyZU9pZCA9IGNzci5zaWduYXR1cmVPaWQ7CiAgICAgIHRocm93IGVycm9yOwogICAgfQoKICAgIC8vIHByb2R1Y2UgREVSIGZvcm1hdHRlZCBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8gYW5kIGRpZ2VzdCBpdAogICAgdmFyIGJ5dGVzID0gYXNuMS50b0Rlcihjc3IuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvKTsKICAgIGNzci5tZC51cGRhdGUoYnl0ZXMuZ2V0Qnl0ZXMoKSk7CiAgfQoKICAvLyBoYW5kbGUgc3ViamVjdCwgYnVpbGQgc3ViamVjdCBtZXNzYWdlIGRpZ2VzdAogIHZhciBzbWQgPSBmb3JnZS5tZC5zaGExLmNyZWF0ZSgpOwogIGNzci5zdWJqZWN0LmdldEZpZWxkID0gZnVuY3Rpb24oc24pIHsKICAgIHJldHVybiBfZ2V0QXR0cmlidXRlKGNzci5zdWJqZWN0LCBzbik7CiAgfTsKICBjc3Iuc3ViamVjdC5hZGRGaWVsZCA9IGZ1bmN0aW9uKGF0dHIpIHsKICAgIF9maWxsTWlzc2luZ0ZpZWxkcyhbYXR0cl0pOwogICAgY3NyLnN1YmplY3QuYXR0cmlidXRlcy5wdXNoKGF0dHIpOwogIH07CiAgY3NyLnN1YmplY3QuYXR0cmlidXRlcyA9IHBraS5SRE5BdHRyaWJ1dGVzQXNBcnJheSgKICAgIGNhcHR1cmUuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvU3ViamVjdCwgc21kKTsKICBjc3Iuc3ViamVjdC5oYXNoID0gc21kLmRpZ2VzdCgpLnRvSGV4KCk7CgogIC8vIGNvbnZlcnQgUlNBIHB1YmxpYyBrZXkgZnJvbSBBU04uMQogIGNzci5wdWJsaWNLZXkgPSBwa2kucHVibGljS2V5RnJvbUFzbjEoY2FwdHVyZS5zdWJqZWN0UHVibGljS2V5SW5mbyk7CgogIC8vIGNvbnZlcnQgYXR0cmlidXRlcyBmcm9tIEFTTi4xCiAgY3NyLmdldEF0dHJpYnV0ZSA9IGZ1bmN0aW9uKHNuKSB7CiAgICByZXR1cm4gX2dldEF0dHJpYnV0ZShjc3IsIHNuKTsKICB9OwogIGNzci5hZGRBdHRyaWJ1dGUgPSBmdW5jdGlvbihhdHRyKSB7CiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoW2F0dHJdKTsKICAgIGNzci5hdHRyaWJ1dGVzLnB1c2goYXR0cik7CiAgfTsKICBjc3IuYXR0cmlidXRlcyA9IHBraS5DUklBdHRyaWJ1dGVzQXNBcnJheSgKICAgIGNhcHR1cmUuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvQXR0cmlidXRlcyB8fCBbXSk7CgogIHJldHVybiBjc3I7Cn07CgovKioKICogQ3JlYXRlcyBhbiBlbXB0eSBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QgKGEgQ1NSIG9yIGNlcnRpZmljYXRlIHNpZ25pbmcKICogcmVxdWVzdCkuIE9uY2UgY3JlYXRlZCwgaXRzIHB1YmxpYyBrZXkgYW5kIGF0dHJpYnV0ZXMgY2FuIGJlIHNldCBhbmQgdGhlbgogKiBpdCBjYW4gYmUgc2lnbmVkLgogKgogKiBAcmV0dXJuIHRoZSBlbXB0eSBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QuCiAqLwpwa2kuY3JlYXRlQ2VydGlmaWNhdGlvblJlcXVlc3QgPSBmdW5jdGlvbigpIHsKICB2YXIgY3NyID0ge307CiAgY3NyLnZlcnNpb24gPSAweDAwOwogIGNzci5zaWduYXR1cmVPaWQgPSBudWxsOwogIGNzci5zaWduYXR1cmUgPSBudWxsOwogIGNzci5zaWdpbmZvID0ge307CiAgY3NyLnNpZ2luZm8uYWxnb3JpdGhtT2lkID0gbnVsbDsKCiAgY3NyLnN1YmplY3QgPSB7fTsKICBjc3Iuc3ViamVjdC5nZXRGaWVsZCA9IGZ1bmN0aW9uKHNuKSB7CiAgICByZXR1cm4gX2dldEF0dHJpYnV0ZShjc3Iuc3ViamVjdCwgc24pOwogIH07CiAgY3NyLnN1YmplY3QuYWRkRmllbGQgPSBmdW5jdGlvbihhdHRyKSB7CiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoW2F0dHJdKTsKICAgIGNzci5zdWJqZWN0LmF0dHJpYnV0ZXMucHVzaChhdHRyKTsKICB9OwogIGNzci5zdWJqZWN0LmF0dHJpYnV0ZXMgPSBbXTsKICBjc3Iuc3ViamVjdC5oYXNoID0gbnVsbDsKCiAgY3NyLnB1YmxpY0tleSA9IG51bGw7CiAgY3NyLmF0dHJpYnV0ZXMgPSBbXTsKICBjc3IuZ2V0QXR0cmlidXRlID0gZnVuY3Rpb24oc24pIHsKICAgIHJldHVybiBfZ2V0QXR0cmlidXRlKGNzciwgc24pOwogIH07CiAgY3NyLmFkZEF0dHJpYnV0ZSA9IGZ1bmN0aW9uKGF0dHIpIHsKICAgIF9maWxsTWlzc2luZ0ZpZWxkcyhbYXR0cl0pOwogICAgY3NyLmF0dHJpYnV0ZXMucHVzaChhdHRyKTsKICB9OwogIGNzci5tZCA9IG51bGw7CgogIC8qKgogICAqIFNldHMgdGhlIHN1YmplY3Qgb2YgdGhpcyBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QuCiAgICoKICAgKiBAcGFyYW0gYXR0cnMgdGhlIGFycmF5IG9mIHN1YmplY3QgYXR0cmlidXRlcyB0byB1c2UuCiAgICovCiAgY3NyLnNldFN1YmplY3QgPSBmdW5jdGlvbihhdHRycykgewogICAgLy8gc2V0IG5ldyBhdHRyaWJ1dGVzCiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoYXR0cnMpOwogICAgY3NyLnN1YmplY3QuYXR0cmlidXRlcyA9IGF0dHJzOwogICAgY3NyLnN1YmplY3QuaGFzaCA9IG51bGw7CiAgfTsKCiAgLyoqCiAgICogU2V0cyB0aGUgYXR0cmlidXRlcyBvZiB0aGlzIGNlcnRpZmljYXRpb24gcmVxdWVzdC4KICAgKgogICAqIEBwYXJhbSBhdHRycyB0aGUgYXJyYXkgb2YgYXR0cmlidXRlcyB0byB1c2UuCiAgICovCiAgY3NyLnNldEF0dHJpYnV0ZXMgPSBmdW5jdGlvbihhdHRycykgewogICAgLy8gc2V0IG5ldyBhdHRyaWJ1dGVzCiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoYXR0cnMpOwogICAgY3NyLmF0dHJpYnV0ZXMgPSBhdHRyczsKICB9OwoKICAvKioKICAgKiBTaWducyB0aGlzIGNlcnRpZmljYXRpb24gcmVxdWVzdCB1c2luZyB0aGUgZ2l2ZW4gcHJpdmF0ZSBrZXkuCiAgICoKICAgKiBAcGFyYW0ga2V5IHRoZSBwcml2YXRlIGtleSB0byBzaWduIHdpdGguCiAgICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3QgdG8gdXNlIChkZWZhdWx0cyB0byBmb3JnZS5tZC5zaGExKS4KICAgKi8KICBjc3Iuc2lnbiA9IGZ1bmN0aW9uKGtleSwgbWQpIHsKICAgIC8vIFRPRE86IGdldCBzaWduYXR1cmUgT0lEIGZyb20gcHJpdmF0ZSBrZXkKICAgIGNzci5tZCA9IG1kIHx8IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICB2YXIgYWxnb3JpdGhtT2lkID0gb2lkc1tjc3IubWQuYWxnb3JpdGhtICsgJ1dpdGhSU0FFbmNyeXB0aW9uJ107CiAgICBpZighYWxnb3JpdGhtT2lkKSB7CiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ291bGQgbm90IGNvbXB1dGUgY2VydGlmaWNhdGlvbiByZXF1ZXN0IGRpZ2VzdC4gJyArCiAgICAgICAgJ1Vua25vd24gbWVzc2FnZSBkaWdlc3QgYWxnb3JpdGhtIE9JRC4nKTsKICAgICAgZXJyb3IuYWxnb3JpdGhtID0gY3NyLm1kLmFsZ29yaXRobTsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CiAgICBjc3Iuc2lnbmF0dXJlT2lkID0gY3NyLnNpZ2luZm8uYWxnb3JpdGhtT2lkID0gYWxnb3JpdGhtT2lkOwoKICAgIC8vIGdldCBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8sIGNvbnZlcnQgdG8gREVSCiAgICBjc3IuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvID0gcGtpLmdldENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyhjc3IpOwogICAgdmFyIGJ5dGVzID0gYXNuMS50b0Rlcihjc3IuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvKTsKCiAgICAvLyBkaWdlc3QgYW5kIHNpZ24KICAgIGNzci5tZC51cGRhdGUoYnl0ZXMuZ2V0Qnl0ZXMoKSk7CiAgICBjc3Iuc2lnbmF0dXJlID0ga2V5LnNpZ24oY3NyLm1kKTsKICB9OwoKICAvKioKICAgKiBBdHRlbXB0cyB2ZXJpZnkgdGhlIHNpZ25hdHVyZSBvbiB0aGUgcGFzc2VkIGNlcnRpZmljYXRpb24gcmVxdWVzdCB1c2luZwogICAqIGl0cyBwdWJsaWMga2V5LgogICAqCiAgICogQSBDU1IgdGhhdCBoYXMgYmVlbiBleHBvcnRlZCB0byBhIGZpbGUgaW4gUEVNIGZvcm1hdCBjYW4gYmUgdmVyaWZpZWQgdXNpbmcKICAgKiBPcGVuU1NMIHVzaW5nIHRoaXMgY29tbWFuZDoKICAgKgogICAqIG9wZW5zc2wgcmVxIC1pbiA8dGhlLWNzci1wZW0tZmlsZT4gLXZlcmlmeSAtbm9vdXQgLXRleHQKICAgKgogICAqIEByZXR1cm4gdHJ1ZSBpZiB2ZXJpZmllZCwgZmFsc2UgaWYgbm90LgogICAqLwogIGNzci52ZXJpZnkgPSBmdW5jdGlvbigpIHsKICAgIHZhciBydmFsID0gZmFsc2U7CgogICAgdmFyIG1kID0gY3NyLm1kOwogICAgaWYobWQgPT09IG51bGwpIHsKICAgICAgLy8gY2hlY2sgc2lnbmF0dXJlIE9JRCBmb3Igc3VwcG9ydGVkIHNpZ25hdHVyZSB0eXBlcwogICAgICBpZihjc3Iuc2lnbmF0dXJlT2lkIGluIG9pZHMpIHsKICAgICAgICAvLyBUT0RPOiBjcmVhdGUgRFJZIGBPSUQgdG8gbWRgIGZ1bmN0aW9uCiAgICAgICAgdmFyIG9pZCA9IG9pZHNbY3NyLnNpZ25hdHVyZU9pZF07CiAgICAgICAgc3dpdGNoKG9pZCkgewogICAgICAgIGNhc2UgJ3NoYTFXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgICBtZCA9IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICdtZDVXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgICBtZCA9IGZvcmdlLm1kLm1kNS5jcmVhdGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ3NoYTI1NldpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICAgIG1kID0gZm9yZ2UubWQuc2hhMjU2LmNyZWF0ZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAnc2hhNTEyV2l0aFJTQUVuY3J5cHRpb24nOgogICAgICAgICAgbWQgPSBmb3JnZS5tZC5zaGE1MTIuY3JlYXRlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICdSU0FTU0EtUFNTJzoKICAgICAgICAgIG1kID0gZm9yZ2UubWQuc2hhMjU2LmNyZWF0ZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmKG1kID09PSBudWxsKSB7CiAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDb3VsZCBub3QgY29tcHV0ZSBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QgZGlnZXN0LiAnICsKICAgICAgICAgICdVbmtub3duIHNpZ25hdHVyZSBPSUQuJyk7CiAgICAgICAgZXJyb3Iuc2lnbmF0dXJlT2lkID0gY3NyLnNpZ25hdHVyZU9pZDsKICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgfQoKICAgICAgLy8gcHJvZHVjZSBERVIgZm9ybWF0dGVkIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyBhbmQgZGlnZXN0IGl0CiAgICAgIHZhciBjcmkgPSBjc3IuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIHx8CiAgICAgICAgcGtpLmdldENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyhjc3IpOwogICAgICB2YXIgYnl0ZXMgPSBhc24xLnRvRGVyKGNyaSk7CiAgICAgIG1kLnVwZGF0ZShieXRlcy5nZXRCeXRlcygpKTsKICAgIH0KCiAgICBpZihtZCAhPT0gbnVsbCkgewogICAgICB2YXIgc2NoZW1lOwoKICAgICAgc3dpdGNoKGNzci5zaWduYXR1cmVPaWQpIHsKICAgICAgY2FzZSBvaWRzLnNoYTFXaXRoUlNBRW5jcnlwdGlvbjoKICAgICAgICAvKiB1c2UgUEtDUyMxIHYxLjUgcGFkZGluZyBzY2hlbWUgKi8KICAgICAgICBicmVhazsKICAgICAgY2FzZSBvaWRzWydSU0FTU0EtUFNTJ106CiAgICAgICAgdmFyIGhhc2gsIG1nZjsKCiAgICAgICAgLyogaW5pdGlhbGl6ZSBtZ2YgKi8KICAgICAgICBoYXNoID0gb2lkc1tjc3Iuc2lnbmF0dXJlUGFyYW1ldGVycy5tZ2YuaGFzaC5hbGdvcml0aG1PaWRdOwogICAgICAgIGlmKGhhc2ggPT09IHVuZGVmaW5lZCB8fCBmb3JnZS5tZFtoYXNoXSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIE1HRiBoYXNoIGZ1bmN0aW9uLicpOwogICAgICAgICAgZXJyb3Iub2lkID0gY3NyLnNpZ25hdHVyZVBhcmFtZXRlcnMubWdmLmhhc2guYWxnb3JpdGhtT2lkOwogICAgICAgICAgZXJyb3IubmFtZSA9IGhhc2g7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CgogICAgICAgIG1nZiA9IG9pZHNbY3NyLnNpZ25hdHVyZVBhcmFtZXRlcnMubWdmLmFsZ29yaXRobU9pZF07CiAgICAgICAgaWYobWdmID09PSB1bmRlZmluZWQgfHwgZm9yZ2UubWdmW21nZl0gPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBNR0YgZnVuY3Rpb24uJyk7CiAgICAgICAgICBlcnJvci5vaWQgPSBjc3Iuc2lnbmF0dXJlUGFyYW1ldGVycy5tZ2YuYWxnb3JpdGhtT2lkOwogICAgICAgICAgZXJyb3IubmFtZSA9IG1nZjsKICAgICAgICAgIHRocm93IGVycm9yOwogICAgICAgIH0KCiAgICAgICAgbWdmID0gZm9yZ2UubWdmW21nZl0uY3JlYXRlKGZvcmdlLm1kW2hhc2hdLmNyZWF0ZSgpKTsKCiAgICAgICAgLyogaW5pdGlhbGl6ZSBoYXNoIGZ1bmN0aW9uICovCiAgICAgICAgaGFzaCA9IG9pZHNbY3NyLnNpZ25hdHVyZVBhcmFtZXRlcnMuaGFzaC5hbGdvcml0aG1PaWRdOwogICAgICAgIGlmKGhhc2ggPT09IHVuZGVmaW5lZCB8fCBmb3JnZS5tZFtoYXNoXSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIFJTQVNTQS1QU1MgaGFzaCBmdW5jdGlvbi4nKTsKICAgICAgICAgIGVycm9yLm9pZCA9IGNzci5zaWduYXR1cmVQYXJhbWV0ZXJzLmhhc2guYWxnb3JpdGhtT2lkOwogICAgICAgICAgZXJyb3IubmFtZSA9IGhhc2g7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CgogICAgICAgIHNjaGVtZSA9IGZvcmdlLnBzcy5jcmVhdGUoZm9yZ2UubWRbaGFzaF0uY3JlYXRlKCksIG1nZiwKICAgICAgICAgIGNzci5zaWduYXR1cmVQYXJhbWV0ZXJzLnNhbHRMZW5ndGgpOwogICAgICAgIGJyZWFrOwogICAgICB9CgogICAgICAvLyB2ZXJpZnkgc2lnbmF0dXJlIG9uIGNzciB1c2luZyBpdHMgcHVibGljIGtleQogICAgICBydmFsID0gY3NyLnB1YmxpY0tleS52ZXJpZnkoCiAgICAgICAgbWQuZGlnZXN0KCkuZ2V0Qnl0ZXMoKSwgY3NyLnNpZ25hdHVyZSwgc2NoZW1lKTsKICAgIH0KCiAgICByZXR1cm4gcnZhbDsKICB9OwoKICByZXR1cm4gY3NyOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFguNTA5IHN1YmplY3Qgb3IgaXNzdWVyIHRvIGFuIEFTTi4xIFJETlNlcXVlbmNlLgogKgogKiBAcGFyYW0gb2JqIHRoZSBzdWJqZWN0IG9yIGlzc3VlciAoZGlzdGluZ3Vpc2hlZCBuYW1lKS4KICoKICogQHJldHVybiB0aGUgQVNOLjEgUkROU2VxdWVuY2UuCiAqLwpmdW5jdGlvbiBfZG5Ub0FzbjEob2JqKSB7CiAgLy8gY3JlYXRlIGFuIGVtcHR5IFJETlNlcXVlbmNlCiAgdmFyIHJ2YWwgPSBhc24xLmNyZWF0ZSgKICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFtdKTsKCiAgLy8gaXRlcmF0ZSBvdmVyIGF0dHJpYnV0ZXMKICB2YXIgYXR0ciwgc2V0OwogIHZhciBhdHRycyA9IG9iai5hdHRyaWJ1dGVzOwogIGZvcih2YXIgaSA9IDA7IGkgPCBhdHRycy5sZW5ndGg7ICsraSkgewogICAgYXR0ciA9IGF0dHJzW2ldOwogICAgdmFyIHZhbHVlID0gYXR0ci52YWx1ZTsKCiAgICAvLyByZXVzZSB0YWcgY2xhc3MgZm9yIGF0dHJpYnV0ZSB2YWx1ZSBpZiBhdmFpbGFibGUKICAgIHZhciB2YWx1ZVRhZ0NsYXNzID0gYXNuMS5UeXBlLlBSSU5UQUJMRVNUUklORzsKICAgIGlmKCd2YWx1ZVRhZ0NsYXNzJyBpbiBhdHRyKSB7CiAgICAgIHZhbHVlVGFnQ2xhc3MgPSBhdHRyLnZhbHVlVGFnQ2xhc3M7CgogICAgICBpZih2YWx1ZVRhZ0NsYXNzID09PSBhc24xLlR5cGUuVVRGOCkgewogICAgICAgIHZhbHVlID0gZm9yZ2UudXRpbC5lbmNvZGVVdGY4KHZhbHVlKTsKICAgICAgfQogICAgICAvLyBGSVhNRTogaGFuZGxlIG1vcmUgZW5jb2RpbmdzCiAgICB9CgogICAgLy8gY3JlYXRlIGEgUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZSBzZXQKICAgIC8vIGVhY2ggdmFsdWUgaW4gdGhlIHNldCBpcyBhbiBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgZmlyc3QKICAgIC8vIGNvbnRhaW5pbmcgdGhlIHR5cGUgKGFuIE9JRCkgYW5kIHNlY29uZCB0aGUgdmFsdWUKICAgIHNldCA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VULCB0cnVlLCBbCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAvLyBBdHRyaWJ1dGVUeXBlCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgYXNuMS5vaWRUb0RlcihhdHRyLnR5cGUpLmdldEJ5dGVzKCkpLAogICAgICAgIC8vIEF0dHJpYnV0ZVZhbHVlCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIHZhbHVlVGFnQ2xhc3MsIGZhbHNlLCB2YWx1ZSkKICAgICAgXSkKICAgIF0pOwogICAgcnZhbC52YWx1ZS5wdXNoKHNldCk7CiAgfQoKICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIEdldHMgYWxsIHByaW50YWJsZSBhdHRyaWJ1dGVzICh0eXBpY2FsbHkgb2YgYW4gaXNzdWVyIG9yIHN1YmplY3QpIGluIGEKICogc2ltcGxpZmllZCBKU09OIGZvcm1hdCBmb3IgZGlzcGxheS4KICoKICogQHBhcmFtIGF0dHJzIHRoZSBhdHRyaWJ1dGVzLgogKgogKiBAcmV0dXJuIHRoZSBKU09OIGZvciBkaXNwbGF5LgogKi8KZnVuY3Rpb24gX2dldEF0dHJpYnV0ZXNBc0pzb24oYXR0cnMpIHsKICB2YXIgcnZhbCA9IHt9OwogIGZvcih2YXIgaSA9IDA7IGkgPCBhdHRycy5sZW5ndGg7ICsraSkgewogICAgdmFyIGF0dHIgPSBhdHRyc1tpXTsKICAgIGlmKGF0dHIuc2hvcnROYW1lICYmICgKICAgICAgYXR0ci52YWx1ZVRhZ0NsYXNzID09PSBhc24xLlR5cGUuVVRGOCB8fAogICAgICBhdHRyLnZhbHVlVGFnQ2xhc3MgPT09IGFzbjEuVHlwZS5QUklOVEFCTEVTVFJJTkcgfHwKICAgICAgYXR0ci52YWx1ZVRhZ0NsYXNzID09PSBhc24xLlR5cGUuSUE1U1RSSU5HKSkgewogICAgICB2YXIgdmFsdWUgPSBhdHRyLnZhbHVlOwogICAgICBpZihhdHRyLnZhbHVlVGFnQ2xhc3MgPT09IGFzbjEuVHlwZS5VVEY4KSB7CiAgICAgICAgdmFsdWUgPSBmb3JnZS51dGlsLmVuY29kZVV0ZjgoYXR0ci52YWx1ZSk7CiAgICAgIH0KICAgICAgaWYoIShhdHRyLnNob3J0TmFtZSBpbiBydmFsKSkgewogICAgICAgIHJ2YWxbYXR0ci5zaG9ydE5hbWVdID0gdmFsdWU7CiAgICAgIH0gZWxzZSBpZihmb3JnZS51dGlsLmlzQXJyYXkocnZhbFthdHRyLnNob3J0TmFtZV0pKSB7CiAgICAgICAgcnZhbFthdHRyLnNob3J0TmFtZV0ucHVzaCh2YWx1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcnZhbFthdHRyLnNob3J0TmFtZV0gPSBbcnZhbFthdHRyLnNob3J0TmFtZV0sIHZhbHVlXTsKICAgICAgfQogICAgfQogIH0KICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIEZpbGxzIGluIG1pc3NpbmcgZmllbGRzIGluIGF0dHJpYnV0ZXMuCiAqCiAqIEBwYXJhbSBhdHRycyB0aGUgYXR0cmlidXRlcyB0byBmaWxsIG1pc3NpbmcgZmllbGRzIGluLgogKi8KZnVuY3Rpb24gX2ZpbGxNaXNzaW5nRmllbGRzKGF0dHJzKSB7CiAgdmFyIGF0dHI7CiAgZm9yKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgKytpKSB7CiAgICBhdHRyID0gYXR0cnNbaV07CgogICAgLy8gcG9wdWxhdGUgbWlzc2luZyBuYW1lCiAgICBpZih0eXBlb2YgYXR0ci5uYW1lID09PSAndW5kZWZpbmVkJykgewogICAgICBpZihhdHRyLnR5cGUgJiYgYXR0ci50eXBlIGluIHBraS5vaWRzKSB7CiAgICAgICAgYXR0ci5uYW1lID0gcGtpLm9pZHNbYXR0ci50eXBlXTsKICAgICAgfSBlbHNlIGlmKGF0dHIuc2hvcnROYW1lICYmIGF0dHIuc2hvcnROYW1lIGluIF9zaG9ydE5hbWVzKSB7CiAgICAgICAgYXR0ci5uYW1lID0gcGtpLm9pZHNbX3Nob3J0TmFtZXNbYXR0ci5zaG9ydE5hbWVdXTsKICAgICAgfQogICAgfQoKICAgIC8vIHBvcHVsYXRlIG1pc3NpbmcgdHlwZSAoT0lEKQogICAgaWYodHlwZW9mIGF0dHIudHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgaWYoYXR0ci5uYW1lICYmIGF0dHIubmFtZSBpbiBwa2kub2lkcykgewogICAgICAgIGF0dHIudHlwZSA9IHBraS5vaWRzW2F0dHIubmFtZV07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdBdHRyaWJ1dGUgdHlwZSBub3Qgc3BlY2lmaWVkLicpOwogICAgICAgIGVycm9yLmF0dHJpYnV0ZSA9IGF0dHI7CiAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgIH0KICAgIH0KCiAgICAvLyBwb3B1bGF0ZSBtaXNzaW5nIHNob3J0bmFtZQogICAgaWYodHlwZW9mIGF0dHIuc2hvcnROYW1lID09PSAndW5kZWZpbmVkJykgewogICAgICBpZihhdHRyLm5hbWUgJiYgYXR0ci5uYW1lIGluIF9zaG9ydE5hbWVzKSB7CiAgICAgICAgYXR0ci5zaG9ydE5hbWUgPSBfc2hvcnROYW1lc1thdHRyLm5hbWVdOwogICAgICB9CiAgICB9CgogICAgLy8gY29udmVydCBleHRlbnNpb25zIHRvIHZhbHVlCiAgICBpZihhdHRyLnR5cGUgPT09IG9pZHMuZXh0ZW5zaW9uUmVxdWVzdCkgewogICAgICBhdHRyLnZhbHVlQ29uc3RydWN0ZWQgPSB0cnVlOwogICAgICBhdHRyLnZhbHVlVGFnQ2xhc3MgPSBhc24xLlR5cGUuU0VRVUVOQ0U7CiAgICAgIGlmKCFhdHRyLnZhbHVlICYmIGF0dHIuZXh0ZW5zaW9ucykgewogICAgICAgIGF0dHIudmFsdWUgPSBbXTsKICAgICAgICBmb3IodmFyIGVpID0gMDsgZWkgPCBhdHRyLmV4dGVuc2lvbnMubGVuZ3RoOyArK2VpKSB7CiAgICAgICAgICBhdHRyLnZhbHVlLnB1c2gocGtpLmNlcnRpZmljYXRlRXh0ZW5zaW9uVG9Bc24xKAogICAgICAgICAgICBfZmlsbE1pc3NpbmdFeHRlbnNpb25GaWVsZHMoYXR0ci5leHRlbnNpb25zW2VpXSkpKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBpZih0eXBlb2YgYXR0ci52YWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdBdHRyaWJ1dGUgdmFsdWUgbm90IHNwZWNpZmllZC4nKTsKICAgICAgZXJyb3IuYXR0cmlidXRlID0gYXR0cjsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CiAgfQp9CgovKioKICogRmlsbHMgaW4gbWlzc2luZyBmaWVsZHMgaW4gY2VydGlmaWNhdGUgZXh0ZW5zaW9ucy4KICoKICogQHBhcmFtIGUgdGhlIGV4dGVuc2lvbi4KICogQHBhcmFtIFtvcHRpb25zXSB0aGUgb3B0aW9ucyB0byB1c2UuCiAqICAgICAgICAgIFtjZXJ0XSB0aGUgY2VydGlmaWNhdGUgdGhlIGV4dGVuc2lvbnMgYXJlIGZvci4KICoKICogQHJldHVybiB0aGUgZXh0ZW5zaW9uLgogKi8KZnVuY3Rpb24gX2ZpbGxNaXNzaW5nRXh0ZW5zaW9uRmllbGRzKGUsIG9wdGlvbnMpIHsKICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKCiAgLy8gcG9wdWxhdGUgbWlzc2luZyBuYW1lCiAgaWYodHlwZW9mIGUubmFtZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIGlmKGUuaWQgJiYgZS5pZCBpbiBwa2kub2lkcykgewogICAgICBlLm5hbWUgPSBwa2kub2lkc1tlLmlkXTsKICAgIH0KICB9CgogIC8vIHBvcHVsYXRlIG1pc3NpbmcgaWQKICBpZih0eXBlb2YgZS5pZCA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIGlmKGUubmFtZSAmJiBlLm5hbWUgaW4gcGtpLm9pZHMpIHsKICAgICAgZS5pZCA9IHBraS5vaWRzW2UubmFtZV07CiAgICB9IGVsc2UgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0V4dGVuc2lvbiBJRCBub3Qgc3BlY2lmaWVkLicpOwogICAgICBlcnJvci5leHRlbnNpb24gPSBlOwogICAgICB0aHJvdyBlcnJvcjsKICAgIH0KICB9CgogIGlmKHR5cGVvZiBlLnZhbHVlICE9PSAndW5kZWZpbmVkJykgewogICAgcmV0dXJuIGU7CiAgfQoKICAvLyBoYW5kbGUgbWlzc2luZyB2YWx1ZToKCiAgLy8gdmFsdWUgaXMgYSBCSVQgU1RSSU5HCiAgaWYoZS5uYW1lID09PSAna2V5VXNhZ2UnKSB7CiAgICAvLyBidWlsZCBmbGFncwogICAgdmFyIHVudXNlZCA9IDA7CiAgICB2YXIgYjIgPSAweDAwOwogICAgdmFyIGIzID0gMHgwMDsKICAgIGlmKGUuZGlnaXRhbFNpZ25hdHVyZSkgewogICAgICBiMiB8PSAweDgwOwogICAgICB1bnVzZWQgPSA3OwogICAgfQogICAgaWYoZS5ub25SZXB1ZGlhdGlvbikgewogICAgICBiMiB8PSAweDQwOwogICAgICB1bnVzZWQgPSA2OwogICAgfQogICAgaWYoZS5rZXlFbmNpcGhlcm1lbnQpIHsKICAgICAgYjIgfD0gMHgyMDsKICAgICAgdW51c2VkID0gNTsKICAgIH0KICAgIGlmKGUuZGF0YUVuY2lwaGVybWVudCkgewogICAgICBiMiB8PSAweDEwOwogICAgICB1bnVzZWQgPSA0OwogICAgfQogICAgaWYoZS5rZXlBZ3JlZW1lbnQpIHsKICAgICAgYjIgfD0gMHgwODsKICAgICAgdW51c2VkID0gMzsKICAgIH0KICAgIGlmKGUua2V5Q2VydFNpZ24pIHsKICAgICAgYjIgfD0gMHgwNDsKICAgICAgdW51c2VkID0gMjsKICAgIH0KICAgIGlmKGUuY1JMU2lnbikgewogICAgICBiMiB8PSAweDAyOwogICAgICB1bnVzZWQgPSAxOwogICAgfQogICAgaWYoZS5lbmNpcGhlck9ubHkpIHsKICAgICAgYjIgfD0gMHgwMTsKICAgICAgdW51c2VkID0gMDsKICAgIH0KICAgIGlmKGUuZGVjaXBoZXJPbmx5KSB7CiAgICAgIGIzIHw9IDB4ODA7CiAgICAgIHVudXNlZCA9IDc7CiAgICB9CgogICAgLy8gY3JlYXRlIGJpdCBzdHJpbmcKICAgIHZhciB2YWx1ZSA9IFN0cmluZy5mcm9tQ2hhckNvZGUodW51c2VkKTsKICAgIGlmKGIzICE9PSAwKSB7CiAgICAgIHZhbHVlICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYjIpICsgU3RyaW5nLmZyb21DaGFyQ29kZShiMyk7CiAgICB9IGVsc2UgaWYoYjIgIT09IDApIHsKICAgICAgdmFsdWUgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShiMik7CiAgICB9CiAgICBlLnZhbHVlID0gYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuQklUU1RSSU5HLCBmYWxzZSwgdmFsdWUpOwogIH0gZWxzZSBpZihlLm5hbWUgPT09ICdiYXNpY0NvbnN0cmFpbnRzJykgewogICAgLy8gYmFzaWNDb25zdHJhaW50cyBpcyBhIFNFUVVFTkNFCiAgICBlLnZhbHVlID0gYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFtdKTsKICAgIC8vIGNBIEJPT0xFQU4gZmxhZyBkZWZhdWx0cyB0byBmYWxzZQogICAgaWYoZS5jQSkgewogICAgICBlLnZhbHVlLnZhbHVlLnB1c2goYXNuMS5jcmVhdGUoCiAgICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5CT09MRUFOLCBmYWxzZSwKICAgICAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RkYpKSk7CiAgICB9CiAgICBpZigncGF0aExlbkNvbnN0cmFpbnQnIGluIGUpIHsKICAgICAgZS52YWx1ZS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIoZS5wYXRoTGVuQ29uc3RyYWludCkuZ2V0Qnl0ZXMoKSkpOwogICAgfQogIH0gZWxzZSBpZihlLm5hbWUgPT09ICdleHRLZXlVc2FnZScpIHsKICAgIC8vIGV4dEtleVVzYWdlIGlzIGEgU0VRVUVOQ0Ugb2YgT0lEcwogICAgZS52YWx1ZSA9IGFzbjEuY3JlYXRlKAogICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbXSk7CiAgICB2YXIgc2VxID0gZS52YWx1ZS52YWx1ZTsKICAgIGZvcih2YXIga2V5IGluIGUpIHsKICAgICAgaWYoZVtrZXldICE9PSB0cnVlKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgLy8ga2V5IGlzIG5hbWUgaW4gT0lEIG1hcAogICAgICBpZihrZXkgaW4gb2lkcykgewogICAgICAgIHNlcS5wdXNoKGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELAogICAgICAgICAgZmFsc2UsIGFzbjEub2lkVG9EZXIob2lkc1trZXldKS5nZXRCeXRlcygpKSk7CiAgICAgIH0gZWxzZSBpZihrZXkuaW5kZXhPZignLicpICE9PSAtMSkgewogICAgICAgIC8vIGFzc3VtZSBrZXkgaXMgYW4gT0lECiAgICAgICAgc2VxLnB1c2goYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsCiAgICAgICAgICBmYWxzZSwgYXNuMS5vaWRUb0RlcihrZXkpLmdldEJ5dGVzKCkpKTsKICAgICAgfQogICAgfQogIH0gZWxzZSBpZihlLm5hbWUgPT09ICduc0NlcnRUeXBlJykgewogICAgLy8gbnNDZXJ0VHlwZSBpcyBhIEJJVCBTVFJJTkcKICAgIC8vIGJ1aWxkIGZsYWdzCiAgICB2YXIgdW51c2VkID0gMDsKICAgIHZhciBiMiA9IDB4MDA7CgogICAgaWYoZS5jbGllbnQpIHsKICAgICAgYjIgfD0gMHg4MDsKICAgICAgdW51c2VkID0gNzsKICAgIH0KICAgIGlmKGUuc2VydmVyKSB7CiAgICAgIGIyIHw9IDB4NDA7CiAgICAgIHVudXNlZCA9IDY7CiAgICB9CiAgICBpZihlLmVtYWlsKSB7CiAgICAgIGIyIHw9IDB4MjA7CiAgICAgIHVudXNlZCA9IDU7CiAgICB9CiAgICBpZihlLm9ianNpZ24pIHsKICAgICAgYjIgfD0gMHgxMDsKICAgICAgdW51c2VkID0gNDsKICAgIH0KICAgIGlmKGUucmVzZXJ2ZWQpIHsKICAgICAgYjIgfD0gMHgwODsKICAgICAgdW51c2VkID0gMzsKICAgIH0KICAgIGlmKGUuc3NsQ0EpIHsKICAgICAgYjIgfD0gMHgwNDsKICAgICAgdW51c2VkID0gMjsKICAgIH0KICAgIGlmKGUuZW1haWxDQSkgewogICAgICBiMiB8PSAweDAyOwogICAgICB1bnVzZWQgPSAxOwogICAgfQogICAgaWYoZS5vYmpDQSkgewogICAgICBiMiB8PSAweDAxOwogICAgICB1bnVzZWQgPSAwOwogICAgfQoKICAgIC8vIGNyZWF0ZSBiaXQgc3RyaW5nCiAgICB2YXIgdmFsdWUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHVudXNlZCk7CiAgICBpZihiMiAhPT0gMCkgewogICAgICB2YWx1ZSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGIyKTsKICAgIH0KICAgIGUudmFsdWUgPSBhc24xLmNyZWF0ZSgKICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5CSVRTVFJJTkcsIGZhbHNlLCB2YWx1ZSk7CiAgfSBlbHNlIGlmKGUubmFtZSA9PT0gJ3N1YmplY3RBbHROYW1lJyB8fCBlLm5hbWUgPT09ICdpc3N1ZXJBbHROYW1lJykgewogICAgLy8gU1lOVEFYIFNFUVVFTkNFCiAgICBlLnZhbHVlID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgW10pOwoKICAgIHZhciBhbHROYW1lOwogICAgZm9yKHZhciBuID0gMDsgbiA8IGUuYWx0TmFtZXMubGVuZ3RoOyArK24pIHsKICAgICAgYWx0TmFtZSA9IGUuYWx0TmFtZXNbbl07CiAgICAgIHZhciB2YWx1ZSA9IGFsdE5hbWUudmFsdWU7CiAgICAgIC8vIGhhbmRsZSBJUAogICAgICBpZihhbHROYW1lLnR5cGUgPT09IDcgJiYgYWx0TmFtZS5pcCkgewogICAgICAgIHZhbHVlID0gZm9yZ2UudXRpbC5ieXRlc0Zyb21JUChhbHROYW1lLmlwKTsKICAgICAgICBpZih2YWx1ZSA9PT0gbnVsbCkgewogICAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKAogICAgICAgICAgICAnRXh0ZW5zaW9uICJpcCIgdmFsdWUgaXMgbm90IGEgdmFsaWQgSVB2NCBvciBJUHY2IGFkZHJlc3MuJyk7CiAgICAgICAgICBlcnJvci5leHRlbnNpb24gPSBlOwogICAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgICAgfQogICAgICB9IGVsc2UgaWYoYWx0TmFtZS50eXBlID09PSA4KSB7CiAgICAgICAgLy8gaGFuZGxlIE9JRAogICAgICAgIGlmKGFsdE5hbWUub2lkKSB7CiAgICAgICAgICB2YWx1ZSA9IGFzbjEub2lkVG9EZXIoYXNuMS5vaWRUb0RlcihhbHROYW1lLm9pZCkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBkZXByZWNhdGVkIC4uLiBjb252ZXJ0IHZhbHVlIHRvIE9JRAogICAgICAgICAgdmFsdWUgPSBhc24xLm9pZFRvRGVyKHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZS52YWx1ZS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgICAgIGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgYWx0TmFtZS50eXBlLCBmYWxzZSwKICAgICAgICB2YWx1ZSkpOwogICAgfQogIH0gZWxzZSBpZihlLm5hbWUgPT09ICdzdWJqZWN0S2V5SWRlbnRpZmllcicgJiYgb3B0aW9ucy5jZXJ0KSB7CiAgICB2YXIgc2tpID0gb3B0aW9ucy5jZXJ0LmdlbmVyYXRlU3ViamVjdEtleUlkZW50aWZpZXIoKTsKICAgIGUuc3ViamVjdEtleUlkZW50aWZpZXIgPSBza2kudG9IZXgoKTsKICAgIC8vIE9DVEVUU1RSSU5HIHcvZGlnZXN0CiAgICBlLnZhbHVlID0gYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLCBza2kuZ2V0Qnl0ZXMoKSk7CiAgfQoKICAvLyBlbnN1cmUgdmFsdWUgaGFzIGJlZW4gZGVmaW5lZCBieSBub3cKICBpZih0eXBlb2YgZS52YWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignRXh0ZW5zaW9uIHZhbHVlIG5vdCBzcGVjaWZpZWQuJyk7CiAgICBlcnJvci5leHRlbnNpb24gPSBlOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICByZXR1cm4gZTsKfQoKLyoqCiAqIENvbnZlcnQgc2lnbmF0dXJlIHBhcmFtZXRlcnMgb2JqZWN0IHRvIEFTTi4xCiAqCiAqIEBwYXJhbSB7U3RyaW5nfSBvaWQgU2lnbmF0dXJlIGFsZ29yaXRobSBPSUQKICogQHBhcmFtIHBhcmFtcyBUaGUgc2lnbmF0dXJlIHBhcmFtZXRycyBvYmplY3QKICogQHJldHVybiBBU04uMSBvYmplY3QgcmVwcmVzZW50aW5nIHNpZ25hdHVyZSBwYXJhbWV0ZXJzCiAqLwpmdW5jdGlvbiBfc2lnbmF0dXJlUGFyYW1ldGVyc1RvQXNuMShvaWQsIHBhcmFtcykgewogIHN3aXRjaChvaWQpIHsKICBjYXNlIG9pZHNbJ1JTQVNTQS1QU1MnXToKICAgIHZhciBwYXJ0cyA9IFtdOwoKICAgIGlmKHBhcmFtcy5oYXNoLmFsZ29yaXRobU9pZCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgIHBhcnRzLnB1c2goYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAwLCB0cnVlLCBbCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgICBhc24xLm9pZFRvRGVyKHBhcmFtcy5oYXNoLmFsZ29yaXRobU9pZCkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgICAgICBdKQogICAgICBdKSk7CiAgICB9CgogICAgaWYocGFyYW1zLm1nZi5hbGdvcml0aG1PaWQgIT09IHVuZGVmaW5lZCkgewogICAgICBwYXJ0cy5wdXNoKGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMSwgdHJ1ZSwgWwogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgICAgYXNuMS5vaWRUb0RlcihwYXJhbXMubWdmLmFsZ29yaXRobU9pZCkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgICAgICBhc24xLm9pZFRvRGVyKHBhcmFtcy5tZ2YuaGFzaC5hbGdvcml0aG1PaWQpLmdldEJ5dGVzKCkpLAogICAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgICAgICAgIF0pCiAgICAgICAgXSkKICAgICAgXSkpOwogICAgfQoKICAgIGlmKHBhcmFtcy5zYWx0TGVuZ3RoICE9PSB1bmRlZmluZWQpIHsKICAgICAgcGFydHMucHVzaChhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDIsIHRydWUsIFsKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIocGFyYW1zLnNhbHRMZW5ndGgpLmdldEJ5dGVzKCkpCiAgICAgIF0pKTsKICAgIH0KCiAgICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgcGFydHMpOwoKICBkZWZhdWx0OgogICAgcmV0dXJuIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuTlVMTCwgZmFsc2UsICcnKTsKICB9Cn0KCi8qKgogKiBDb252ZXJ0cyBhIGNlcnRpZmljYXRpb24gcmVxdWVzdCdzIGF0dHJpYnV0ZXMgdG8gYW4gQVNOLjEgc2V0IG9mCiAqIENSSUF0dHJpYnV0ZXMuCiAqCiAqIEBwYXJhbSBjc3IgY2VydGlmaWNhdGlvbiByZXF1ZXN0LgogKgogKiBAcmV0dXJuIHRoZSBBU04uMSBzZXQgb2YgQ1JJQXR0cmlidXRlcy4KICovCmZ1bmN0aW9uIF9DUklBdHRyaWJ1dGVzVG9Bc24xKGNzcikgewogIC8vIGNyZWF0ZSBhbiBlbXB0eSBjb250ZXh0LXNwZWNpZmljIGNvbnRhaW5lcgogIHZhciBydmFsID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAwLCB0cnVlLCBbXSk7CgogIC8vIG5vIGF0dHJpYnV0ZXMsIHJldHVybiBlbXB0eSBjb250YWluZXIKICBpZihjc3IuYXR0cmlidXRlcy5sZW5ndGggPT09IDApIHsKICAgIHJldHVybiBydmFsOwogIH0KCiAgLy8gZWFjaCBhdHRyaWJ1dGUgaGFzIGEgc2VxdWVuY2Ugd2l0aCBhIHR5cGUgYW5kIGEgc2V0IG9mIHZhbHVlcwogIHZhciBhdHRycyA9IGNzci5hdHRyaWJ1dGVzOwogIGZvcih2YXIgaSA9IDA7IGkgPCBhdHRycy5sZW5ndGg7ICsraSkgewogICAgdmFyIGF0dHIgPSBhdHRyc1tpXTsKICAgIHZhciB2YWx1ZSA9IGF0dHIudmFsdWU7CgogICAgLy8gcmV1c2UgdGFnIGNsYXNzIGZvciBhdHRyaWJ1dGUgdmFsdWUgaWYgYXZhaWxhYmxlCiAgICB2YXIgdmFsdWVUYWdDbGFzcyA9IGFzbjEuVHlwZS5VVEY4OwogICAgaWYoJ3ZhbHVlVGFnQ2xhc3MnIGluIGF0dHIpIHsKICAgICAgdmFsdWVUYWdDbGFzcyA9IGF0dHIudmFsdWVUYWdDbGFzczsKICAgIH0KICAgIGlmKHZhbHVlVGFnQ2xhc3MgPT09IGFzbjEuVHlwZS5VVEY4KSB7CiAgICAgIHZhbHVlID0gZm9yZ2UudXRpbC5lbmNvZGVVdGY4KHZhbHVlKTsKICAgIH0KICAgIHZhciB2YWx1ZUNvbnN0cnVjdGVkID0gZmFsc2U7CiAgICBpZigndmFsdWVDb25zdHJ1Y3RlZCcgaW4gYXR0cikgewogICAgICB2YWx1ZUNvbnN0cnVjdGVkID0gYXR0ci52YWx1ZUNvbnN0cnVjdGVkOwogICAgfQogICAgLy8gRklYTUU6IGhhbmRsZSBtb3JlIGVuY29kaW5ncwoKICAgIC8vIGNyZWF0ZSBhIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUgc2V0CiAgICAvLyBlYWNoIHZhbHVlIGluIHRoZSBzZXQgaXMgYW4gQXR0cmlidXRlVHlwZUFuZFZhbHVlIGZpcnN0CiAgICAvLyBjb250YWluaW5nIHRoZSB0eXBlIChhbiBPSUQpIGFuZCBzZWNvbmQgdGhlIHZhbHVlCiAgICB2YXIgc2VxID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAvLyBBdHRyaWJ1dGVUeXBlCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICBhc24xLm9pZFRvRGVyKGF0dHIudHlwZSkuZ2V0Qnl0ZXMoKSksCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VULCB0cnVlLCBbCiAgICAgICAgLy8gQXR0cmlidXRlVmFsdWUKICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCB2YWx1ZVRhZ0NsYXNzLCB2YWx1ZUNvbnN0cnVjdGVkLCB2YWx1ZSkKICAgICAgXSkKICAgIF0pOwogICAgcnZhbC52YWx1ZS5wdXNoKHNlcSk7CiAgfQoKICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIEdldHMgdGhlIEFTTi4xIFRCU0NlcnRpZmljYXRlIHBhcnQgb2YgYW4gWC41MDl2MyBjZXJ0aWZpY2F0ZS4KICoKICogQHBhcmFtIGNlcnQgdGhlIGNlcnRpZmljYXRlLgogKgogKiBAcmV0dXJuIHRoZSBhc24xIFRCU0NlcnRpZmljYXRlLgogKi8KcGtpLmdldFRCU0NlcnRpZmljYXRlID0gZnVuY3Rpb24oY2VydCkgewogIC8vIFRCU0NlcnRpZmljYXRlCiAgdmFyIHRicyA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgIC8vIHZlcnNpb24KICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMCwgdHJ1ZSwgWwogICAgICAvLyBpbnRlZ2VyCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIoY2VydC52ZXJzaW9uKS5nZXRCeXRlcygpKQogICAgXSksCiAgICAvLyBzZXJpYWxOdW1iZXIKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgIGZvcmdlLnV0aWwuaGV4VG9CeXRlcyhjZXJ0LnNlcmlhbE51bWJlcikpLAogICAgLy8gc2lnbmF0dXJlCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIGFsZ29yaXRobQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgYXNuMS5vaWRUb0RlcihjZXJ0LnNpZ2luZm8uYWxnb3JpdGhtT2lkKS5nZXRCeXRlcygpKSwKICAgICAgLy8gcGFyYW1ldGVycwogICAgICBfc2lnbmF0dXJlUGFyYW1ldGVyc1RvQXNuMSgKICAgICAgICBjZXJ0LnNpZ2luZm8uYWxnb3JpdGhtT2lkLCBjZXJ0LnNpZ2luZm8ucGFyYW1ldGVycykKICAgIF0pLAogICAgLy8gaXNzdWVyCiAgICBfZG5Ub0FzbjEoY2VydC5pc3N1ZXIpLAogICAgLy8gdmFsaWRpdHkKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgLy8gbm90QmVmb3JlCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuVVRDVElNRSwgZmFsc2UsCiAgICAgICAgYXNuMS5kYXRlVG9VdGNUaW1lKGNlcnQudmFsaWRpdHkubm90QmVmb3JlKSksCiAgICAgIC8vIG5vdEFmdGVyCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuVVRDVElNRSwgZmFsc2UsCiAgICAgICAgYXNuMS5kYXRlVG9VdGNUaW1lKGNlcnQudmFsaWRpdHkubm90QWZ0ZXIpKQogICAgXSksCiAgICAvLyBzdWJqZWN0CiAgICBfZG5Ub0FzbjEoY2VydC5zdWJqZWN0KSwKICAgIC8vIFN1YmplY3RQdWJsaWNLZXlJbmZvCiAgICBwa2kucHVibGljS2V5VG9Bc24xKGNlcnQucHVibGljS2V5KQogIF0pOwoKICBpZihjZXJ0Lmlzc3Vlci51bmlxdWVJZCkgewogICAgLy8gaXNzdWVyVW5pcXVlSUQgKG9wdGlvbmFsKQogICAgdGJzLnZhbHVlLnB1c2goCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMSwgdHJ1ZSwgWwogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuQklUU1RSSU5HLCBmYWxzZSwKICAgICAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwMCkgKwogICAgICAgICAgY2VydC5pc3N1ZXIudW5pcXVlSWQKICAgICAgICApCiAgICAgIF0pCiAgICApOwogIH0KICBpZihjZXJ0LnN1YmplY3QudW5pcXVlSWQpIHsKICAgIC8vIHN1YmplY3RVbmlxdWVJRCAob3B0aW9uYWwpCiAgICB0YnMudmFsdWUucHVzaCgKICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAyLCB0cnVlLCBbCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5CSVRTVFJJTkcsIGZhbHNlLAogICAgICAgICAgU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKSArCiAgICAgICAgICBjZXJ0LnN1YmplY3QudW5pcXVlSWQKICAgICAgICApCiAgICAgIF0pCiAgICApOwogIH0KCiAgaWYoY2VydC5leHRlbnNpb25zLmxlbmd0aCA+IDApIHsKICAgIC8vIGV4dGVuc2lvbnMgKG9wdGlvbmFsKQogICAgdGJzLnZhbHVlLnB1c2gocGtpLmNlcnRpZmljYXRlRXh0ZW5zaW9uc1RvQXNuMShjZXJ0LmV4dGVuc2lvbnMpKTsKICB9CgogIHJldHVybiB0YnM7Cn07CgovKioKICogR2V0cyB0aGUgQVNOLjEgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIHBhcnQgb2YgYQogKiBQS0NTIzEwIENlcnRpZmljYXRpb25SZXF1ZXN0LgogKgogKiBAcGFyYW0gY3NyIHRoZSBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QuCiAqCiAqIEByZXR1cm4gdGhlIGFzbjEgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvLgogKi8KcGtpLmdldENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyA9IGZ1bmN0aW9uKGNzcikgewogIC8vIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbwogIHZhciBjcmkgPSBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAvLyB2ZXJzaW9uCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBhc24xLmludGVnZXJUb0Rlcihjc3IudmVyc2lvbikuZ2V0Qnl0ZXMoKSksCiAgICAvLyBzdWJqZWN0CiAgICBfZG5Ub0FzbjEoY3NyLnN1YmplY3QpLAogICAgLy8gU3ViamVjdFB1YmxpY0tleUluZm8KICAgIHBraS5wdWJsaWNLZXlUb0FzbjEoY3NyLnB1YmxpY0tleSksCiAgICAvLyBhdHRyaWJ1dGVzCiAgICBfQ1JJQXR0cmlidXRlc1RvQXNuMShjc3IpCiAgXSk7CgogIHJldHVybiBjcmk7Cn07CgovKioKICogQ29udmVydHMgYSBEaXN0aW5ndWlzaGVkTmFtZSAoc3ViamVjdCBvciBpc3N1ZXIpIHRvIGFuIEFTTi4xIG9iamVjdC4KICoKICogQHBhcmFtIGRuIHRoZSBEaXN0aW5ndWlzaGVkTmFtZS4KICoKICogQHJldHVybiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhIERpc3Rpbmd1aXNoZWROYW1lLgogKi8KcGtpLmRpc3Rpbmd1aXNoZWROYW1lVG9Bc24xID0gZnVuY3Rpb24oZG4pIHsKICByZXR1cm4gX2RuVG9Bc24xKGRuKTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhbiBYLjUwOXYzIFJTQSBjZXJ0aWZpY2F0ZSB0byBhbiBBU04uMSBvYmplY3QuCiAqCiAqIEBwYXJhbSBjZXJ0IHRoZSBjZXJ0aWZpY2F0ZS4KICoKICogQHJldHVybiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhbiBYLjUwOXYzIFJTQSBjZXJ0aWZpY2F0ZS4KICovCnBraS5jZXJ0aWZpY2F0ZVRvQXNuMSA9IGZ1bmN0aW9uKGNlcnQpIHsKICAvLyBwcmVmZXIgY2FjaGVkIFRCU0NlcnRpZmljYXRlIG92ZXIgZ2VuZXJhdGluZyBvbmUKICB2YXIgdGJzQ2VydGlmaWNhdGUgPSBjZXJ0LnRic0NlcnRpZmljYXRlIHx8IHBraS5nZXRUQlNDZXJ0aWZpY2F0ZShjZXJ0KTsKCiAgLy8gQ2VydGlmaWNhdGUKICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgLy8gVEJTQ2VydGlmaWNhdGUKICAgIHRic0NlcnRpZmljYXRlLAogICAgLy8gQWxnb3JpdGhtSWRlbnRpZmllciAoc2lnbmF0dXJlIGFsZ29yaXRobSkKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgLy8gYWxnb3JpdGhtCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICBhc24xLm9pZFRvRGVyKGNlcnQuc2lnbmF0dXJlT2lkKS5nZXRCeXRlcygpKSwKICAgICAgLy8gcGFyYW1ldGVycwogICAgICBfc2lnbmF0dXJlUGFyYW1ldGVyc1RvQXNuMShjZXJ0LnNpZ25hdHVyZU9pZCwgY2VydC5zaWduYXR1cmVQYXJhbWV0ZXJzKQogICAgXSksCiAgICAvLyBTaWduYXR1cmVWYWx1ZQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5CSVRTVFJJTkcsIGZhbHNlLAogICAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDApICsgY2VydC5zaWduYXR1cmUpCiAgXSk7Cn07CgovKioKICogQ29udmVydHMgWC41MDl2MyBjZXJ0aWZpY2F0ZSBleHRlbnNpb25zIHRvIEFTTi4xLgogKgogKiBAcGFyYW0gZXh0cyB0aGUgZXh0ZW5zaW9ucyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBleHRlbnNpb25zIGluIEFTTi4xIGZvcm1hdC4KICovCnBraS5jZXJ0aWZpY2F0ZUV4dGVuc2lvbnNUb0FzbjEgPSBmdW5jdGlvbihleHRzKSB7CiAgLy8gY3JlYXRlIHRvcC1sZXZlbCBleHRlbnNpb24gY29udGFpbmVyCiAgdmFyIHJ2YWwgPSBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDMsIHRydWUsIFtdKTsKCiAgLy8gY3JlYXRlIGV4dGVuc2lvbiBzZXF1ZW5jZSAoc3RvcmVzIGEgc2VxdWVuY2UgZm9yIGVhY2ggZXh0ZW5zaW9uKQogIHZhciBzZXEgPSBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbXSk7CiAgcnZhbC52YWx1ZS5wdXNoKHNlcSk7CgogIGZvcih2YXIgaSA9IDA7IGkgPCBleHRzLmxlbmd0aDsgKytpKSB7CiAgICBzZXEudmFsdWUucHVzaChwa2kuY2VydGlmaWNhdGVFeHRlbnNpb25Ub0FzbjEoZXh0c1tpXSkpOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ29udmVydHMgYSBzaW5nbGUgY2VydGlmaWNhdGUgZXh0ZW5zaW9uIHRvIEFTTi4xLgogKgogKiBAcGFyYW0gZXh0IHRoZSBleHRlbnNpb24gdG8gY29udmVydC4KICoKICogQHJldHVybiB0aGUgZXh0ZW5zaW9uIGluIEFTTi4xIGZvcm1hdC4KICovCnBraS5jZXJ0aWZpY2F0ZUV4dGVuc2lvblRvQXNuMSA9IGZ1bmN0aW9uKGV4dCkgewogIC8vIGNyZWF0ZSBhIHNlcXVlbmNlIGZvciBlYWNoIGV4dGVuc2lvbgogIHZhciBleHRzZXEgPSBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbXSk7CgogIC8vIGV4dG5JRCAoT0lEKQogIGV4dHNlcS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgYXNuMS5vaWRUb0RlcihleHQuaWQpLmdldEJ5dGVzKCkpKTsKCiAgLy8gY3JpdGljYWwgZGVmYXVsdHMgdG8gZmFsc2UKICBpZihleHQuY3JpdGljYWwpIHsKICAgIC8vIGNyaXRpY2FsIEJPT0xFQU4gREVGQVVMVCBGQUxTRQogICAgZXh0c2VxLnZhbHVlLnB1c2goYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuQk9PTEVBTiwgZmFsc2UsCiAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoMHhGRikpKTsKICB9CgogIHZhciB2YWx1ZSA9IGV4dC52YWx1ZTsKICBpZih0eXBlb2YgZXh0LnZhbHVlICE9PSAnc3RyaW5nJykgewogICAgLy8gdmFsdWUgaXMgYXNuLjEKICAgIHZhbHVlID0gYXNuMS50b0Rlcih2YWx1ZSkuZ2V0Qnl0ZXMoKTsKICB9CgogIC8vIGV4dG5WYWx1ZSAoT0NURVQgU1RSSU5HKQogIGV4dHNlcS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsIHZhbHVlKSk7CgogIHJldHVybiBleHRzZXE7Cn07CgovKioKICogQ29udmVydHMgYSBQS0NTIzEwIGNlcnRpZmljYXRpb24gcmVxdWVzdCB0byBhbiBBU04uMSBvYmplY3QuCiAqCiAqIEBwYXJhbSBjc3IgdGhlIGNlcnRpZmljYXRpb24gcmVxdWVzdC4KICoKICogQHJldHVybiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhIGNlcnRpZmljYXRpb24gcmVxdWVzdC4KICovCnBraS5jZXJ0aWZpY2F0aW9uUmVxdWVzdFRvQXNuMSA9IGZ1bmN0aW9uKGNzcikgewogIC8vIHByZWZlciBjYWNoZWQgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIG92ZXIgZ2VuZXJhdGluZyBvbmUKICB2YXIgY3JpID0gY3NyLmNlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyB8fAogICAgcGtpLmdldENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyhjc3IpOwoKICAvLyBDZXJ0aWZpY2F0ZQogIHJldHVybiBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAvLyBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8KICAgIGNyaSwKICAgIC8vIEFsZ29yaXRobUlkZW50aWZpZXIgKHNpZ25hdHVyZSBhbGdvcml0aG0pCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIGFsZ29yaXRobQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgYXNuMS5vaWRUb0Rlcihjc3Iuc2lnbmF0dXJlT2lkKS5nZXRCeXRlcygpKSwKICAgICAgLy8gcGFyYW1ldGVycwogICAgICBfc2lnbmF0dXJlUGFyYW1ldGVyc1RvQXNuMShjc3Iuc2lnbmF0dXJlT2lkLCBjc3Iuc2lnbmF0dXJlUGFyYW1ldGVycykKICAgIF0pLAogICAgLy8gc2lnbmF0dXJlCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLkJJVFNUUklORywgZmFsc2UsCiAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwMCkgKyBjc3Iuc2lnbmF0dXJlKQogIF0pOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBDQSBzdG9yZS4KICoKICogQHBhcmFtIGNlcnRzIGFuIG9wdGlvbmFsIGFycmF5IG9mIGNlcnRpZmljYXRlIG9iamVjdHMgb3IgUEVNLWZvcm1hdHRlZAogKiAgICAgICAgICBjZXJ0aWZpY2F0ZSBzdHJpbmdzIHRvIGFkZCB0byB0aGUgQ0Egc3RvcmUuCiAqCiAqIEByZXR1cm4gdGhlIENBIHN0b3JlLgogKi8KcGtpLmNyZWF0ZUNhU3RvcmUgPSBmdW5jdGlvbihjZXJ0cykgewogIC8vIGNyZWF0ZSBDQSBzdG9yZQogIHZhciBjYVN0b3JlID0gewogICAgLy8gc3RvcmVkIGNlcnRpZmljYXRlcwogICAgY2VydHM6IHt9CiAgfTsKCiAgLyoqCiAgICogR2V0cyB0aGUgY2VydGlmaWNhdGUgdGhhdCBpc3N1ZWQgdGhlIHBhc3NlZCBjZXJ0aWZpY2F0ZSBvciBpdHMKICAgKiAncGFyZW50Jy4KICAgKgogICAqIEBwYXJhbSBjZXJ0IHRoZSBjZXJ0aWZpY2F0ZSB0byBnZXQgdGhlIHBhcmVudCBmb3IuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBwYXJlbnQgY2VydGlmaWNhdGUgb3IgbnVsbCBpZiBub25lIHdhcyBmb3VuZC4KICAgKi8KICBjYVN0b3JlLmdldElzc3VlciA9IGZ1bmN0aW9uKGNlcnQpIHsKICAgIHZhciBydmFsID0gZ2V0QnlTdWJqZWN0KGNlcnQuaXNzdWVyKTsKCiAgICAvLyBzZWUgaWYgdGhlcmUgYXJlIG11bHRpcGxlIG1hdGNoZXMKICAgIC8qaWYoZm9yZ2UudXRpbC5pc0FycmF5KHJ2YWwpKSB7CiAgICAgIC8vIFRPRE86IHJlc29sdmUgbXVsdGlwbGUgbWF0Y2hlcyBieSBjaGVja2luZwogICAgICAvLyBhdXRob3JpdHlLZXkvc3ViamVjdEtleS9pc3N1ZXJVbmlxdWVJRC9vdGhlciBpZGVudGlmaWVycywgZXRjLgogICAgICAvLyBGSVhNRTogb3IgYWx0ZXJuYXRpdmVseSBkbyBhdXRob3JpdHkga2V5IG1hcHBpbmcKICAgICAgLy8gaWYgcG9zc2libGUgKFguNTA5djEgY2VydHMgY2FuJ3Qgd29yaz8pCiAgICAgIHRocm93IG5ldyBFcnJvcignUmVzb2x2aW5nIG11bHRpcGxlIGlzc3VlciBtYXRjaGVzIG5vdCBpbXBsZW1lbnRlZCB5ZXQuJyk7CiAgICB9Ki8KCiAgICByZXR1cm4gcnZhbDsKICB9OwoKICAvKioKICAgKiBBZGRzIGEgdHJ1c3RlZCBjZXJ0aWZpY2F0ZSB0byB0aGUgc3RvcmUuCiAgICoKICAgKiBAcGFyYW0gY2VydCB0aGUgY2VydGlmaWNhdGUgdG8gYWRkIGFzIGEgdHJ1c3RlZCBjZXJ0aWZpY2F0ZSAoZWl0aGVyIGEKICAgKiAgICAgICAgICBwa2kuY2VydGlmaWNhdGUgb2JqZWN0IG9yIGEgUEVNLWZvcm1hdHRlZCBjZXJ0aWZpY2F0ZSkuCiAgICovCiAgY2FTdG9yZS5hZGRDZXJ0aWZpY2F0ZSA9IGZ1bmN0aW9uKGNlcnQpIHsKICAgIC8vIGNvbnZlcnQgZnJvbSBwZW0gaWYgbmVjZXNzYXJ5CiAgICBpZih0eXBlb2YgY2VydCA9PT0gJ3N0cmluZycpIHsKICAgICAgY2VydCA9IGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUZyb21QZW0oY2VydCk7CiAgICB9CgogICAgLy8gcHJvZHVjZSBzdWJqZWN0IGhhc2ggaWYgaXQgZG9lc24ndCBleGlzdAogICAgaWYoIWNlcnQuc3ViamVjdC5oYXNoKSB7CiAgICAgIHZhciBtZCA9IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICAgIGNlcnQuc3ViamVjdC5hdHRyaWJ1dGVzID0gIHBraS5SRE5BdHRyaWJ1dGVzQXNBcnJheSgKICAgICAgICBfZG5Ub0FzbjEoY2VydC5zdWJqZWN0KSwgbWQpOwogICAgICBjZXJ0LnN1YmplY3QuaGFzaCA9IG1kLmRpZ2VzdCgpLnRvSGV4KCk7CiAgICB9CgogICAgaWYoY2VydC5zdWJqZWN0Lmhhc2ggaW4gY2FTdG9yZS5jZXJ0cykgewogICAgICAvLyBzdWJqZWN0IGhhc2ggYWxyZWFkeSBleGlzdHMsIGFwcGVuZCB0byBhcnJheQogICAgICB2YXIgdG1wID0gY2FTdG9yZS5jZXJ0c1tjZXJ0LnN1YmplY3QuaGFzaF07CiAgICAgIGlmKCFmb3JnZS51dGlsLmlzQXJyYXkodG1wKSkgewogICAgICAgIHRtcCA9IFt0bXBdOwogICAgICB9CiAgICAgIHRtcC5wdXNoKGNlcnQpOwogICAgfSBlbHNlIHsKICAgICAgY2FTdG9yZS5jZXJ0c1tjZXJ0LnN1YmplY3QuaGFzaF0gPSBjZXJ0OwogICAgfQogIH07CgogIC8qKgogICAqIENoZWNrcyB0byBzZWUgaWYgdGhlIGdpdmVuIGNlcnRpZmljYXRlIGlzIGluIHRoZSBzdG9yZS4KICAgKgogICAqIEBwYXJhbSBjZXJ0IHRoZSBjZXJ0aWZpY2F0ZSB0byBjaGVjay4KICAgKgogICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY2VydGlmaWNhdGUgaXMgaW4gdGhlIHN0b3JlLCBmYWxzZSBpZiBub3QuCiAgICovCiAgY2FTdG9yZS5oYXNDZXJ0aWZpY2F0ZSA9IGZ1bmN0aW9uKGNlcnQpIHsKICAgIHZhciBtYXRjaCA9IGdldEJ5U3ViamVjdChjZXJ0LnN1YmplY3QpOwogICAgaWYoIW1hdGNoKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmKCFmb3JnZS51dGlsLmlzQXJyYXkobWF0Y2gpKSB7CiAgICAgIG1hdGNoID0gW21hdGNoXTsKICAgIH0KICAgIC8vIGNvbXBhcmUgREVSLWVuY29kaW5nIG9mIGNlcnRpZmljYXRlcwogICAgdmFyIGRlcjEgPSBhc24xLnRvRGVyKHBraS5jZXJ0aWZpY2F0ZVRvQXNuMShjZXJ0KSkuZ2V0Qnl0ZXMoKTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtYXRjaC5sZW5ndGg7ICsraSkgewogICAgICB2YXIgZGVyMiA9IGFzbjEudG9EZXIocGtpLmNlcnRpZmljYXRlVG9Bc24xKG1hdGNoW2ldKSkuZ2V0Qnl0ZXMoKTsKICAgICAgaWYoZGVyMSA9PT0gZGVyMikgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfTsKCiAgZnVuY3Rpb24gZ2V0QnlTdWJqZWN0KHN1YmplY3QpIHsKICAgIC8vIHByb2R1Y2Ugc3ViamVjdCBoYXNoIGlmIGl0IGRvZXNuJ3QgZXhpc3QKICAgIGlmKCFzdWJqZWN0Lmhhc2gpIHsKICAgICAgdmFyIG1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICAgICAgc3ViamVjdC5hdHRyaWJ1dGVzID0gIHBraS5SRE5BdHRyaWJ1dGVzQXNBcnJheShfZG5Ub0FzbjEoc3ViamVjdCksIG1kKTsKICAgICAgc3ViamVjdC5oYXNoID0gbWQuZGlnZXN0KCkudG9IZXgoKTsKICAgIH0KICAgIHJldHVybiBjYVN0b3JlLmNlcnRzW3N1YmplY3QuaGFzaF0gfHwgbnVsbDsKICB9CgogIC8vIGF1dG8tYWRkIHBhc3NlZCBpbiBjZXJ0cwogIGlmKGNlcnRzKSB7CiAgICAvLyBwYXJzZSBQRU0tZm9ybWF0dGVkIGNlcnRpZmljYXRlcyBhcyBuZWNlc3NhcnkKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBjZXJ0cy5sZW5ndGg7ICsraSkgewogICAgICB2YXIgY2VydCA9IGNlcnRzW2ldOwogICAgICBjYVN0b3JlLmFkZENlcnRpZmljYXRlKGNlcnQpOwogICAgfQogIH0KCiAgcmV0dXJuIGNhU3RvcmU7Cn07CgovKioKICogQ2VydGlmaWNhdGUgdmVyaWZpY2F0aW9uIGVycm9ycywgYmFzZWQgb24gVExTLgogKi8KcGtpLmNlcnRpZmljYXRlRXJyb3IgPSB7CiAgYmFkX2NlcnRpZmljYXRlOiAnZm9yZ2UucGtpLkJhZENlcnRpZmljYXRlJywKICB1bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZTogJ2ZvcmdlLnBraS5VbnN1cHBvcnRlZENlcnRpZmljYXRlJywKICBjZXJ0aWZpY2F0ZV9yZXZva2VkOiAnZm9yZ2UucGtpLkNlcnRpZmljYXRlUmV2b2tlZCcsCiAgY2VydGlmaWNhdGVfZXhwaXJlZDogJ2ZvcmdlLnBraS5DZXJ0aWZpY2F0ZUV4cGlyZWQnLAogIGNlcnRpZmljYXRlX3Vua25vd246ICdmb3JnZS5wa2kuQ2VydGlmaWNhdGVVbmtub3duJywKICB1bmtub3duX2NhOiAnZm9yZ2UucGtpLlVua25vd25DZXJ0aWZpY2F0ZUF1dGhvcml0eScKfTsKCi8qKgogKiBWZXJpZmllcyBhIGNlcnRpZmljYXRlIGNoYWluIGFnYWluc3QgdGhlIGdpdmVuIENlcnRpZmljYXRlIEF1dGhvcml0eSBzdG9yZQogKiB3aXRoIGFuIG9wdGlvbmFsIGN1c3RvbSB2ZXJpZnkgY2FsbGJhY2suCiAqCiAqIEBwYXJhbSBjYVN0b3JlIGEgY2VydGlmaWNhdGUgc3RvcmUgdG8gdmVyaWZ5IGFnYWluc3QuCiAqIEBwYXJhbSBjaGFpbiB0aGUgY2VydGlmaWNhdGUgY2hhaW4gdG8gdmVyaWZ5LCB3aXRoIHRoZSByb290IG9yIGhpZ2hlc3QKICogICAgICAgICAgYXV0aG9yaXR5IGF0IHRoZSBlbmQgKGFuIGFycmF5IG9mIGNlcnRpZmljYXRlcykuCiAqIEBwYXJhbSB2ZXJpZnkgY2FsbGVkIGZvciBldmVyeSBjZXJ0aWZpY2F0ZSBpbiB0aGUgY2hhaW4uCiAqCiAqIFRoZSB2ZXJpZnkgY2FsbGJhY2sgaGFzIHRoZSBmb2xsb3dpbmcgc2lnbmF0dXJlOgogKgogKiB2ZXJpZmllZCAtIFNldCB0byB0cnVlIGlmIGNlcnRpZmljYXRlIHdhcyB2ZXJpZmllZCwgb3RoZXJ3aXNlIHRoZQogKiAgIHBraS5jZXJ0aWZpY2F0ZUVycm9yIGZvciB3aHkgdGhlIGNlcnRpZmljYXRlIGZhaWxlZC4KICogZGVwdGggLSBUaGUgY3VycmVudCBpbmRleCBpbiB0aGUgY2hhaW4sIHdoZXJlIDAgaXMgdGhlIGVuZCBwb2ludCdzIGNlcnQuCiAqIGNlcnRzIC0gVGhlIGNlcnRpZmljYXRlIGNoYWluLCAqTk9URSogYW4gZW1wdHkgY2hhaW4gaW5kaWNhdGVzIGFuIGFub255bW91cwogKiAgIGVuZCBwb2ludC4KICoKICogVGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzIGFuZCBvbiBmYWlsdXJlIGVpdGhlciB0aGUgYXBwcm9wcmlhdGUKICogcGtpLmNlcnRpZmljYXRlRXJyb3Igb3IgYW4gb2JqZWN0IHdpdGggJ2Vycm9yJyBzZXQgdG8gdGhlIGFwcHJvcHJpYXRlCiAqIHBraS5jZXJ0aWZpY2F0ZUVycm9yIGFuZCAnbWVzc2FnZScgc2V0IHRvIGEgY3VzdG9tIGVycm9yIG1lc3NhZ2UuCiAqCiAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsLCBlcnJvciB0aHJvd24gaWYgbm90LgogKi8KcGtpLnZlcmlmeUNlcnRpZmljYXRlQ2hhaW4gPSBmdW5jdGlvbihjYVN0b3JlLCBjaGFpbiwgdmVyaWZ5KSB7CiAgLyogRnJvbTogUkZDMzI4MCAtIEludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUgQ2VydGlmaWNhdGUKICAgIFNlY3Rpb24gNjogQ2VydGlmaWNhdGlvbiBQYXRoIFZhbGlkYXRpb24KICAgIFNlZSBpbmxpbmUgcGFyZW50aGV0aWNhbHMgcmVsYXRlZCB0byB0aGlzIHBhcnRpY3VsYXIgaW1wbGVtZW50YXRpb24uCgogICAgVGhlIHByaW1hcnkgZ29hbCBvZiBwYXRoIHZhbGlkYXRpb24gaXMgdG8gdmVyaWZ5IHRoZSBiaW5kaW5nIGJldHdlZW4KICAgIGEgc3ViamVjdCBkaXN0aW5ndWlzaGVkIG5hbWUgb3IgYSBzdWJqZWN0IGFsdGVybmF0aXZlIG5hbWUgYW5kIHN1YmplY3QKICAgIHB1YmxpYyBrZXksIGFzIHJlcHJlc2VudGVkIGluIHRoZSBlbmQgZW50aXR5IGNlcnRpZmljYXRlLCBiYXNlZCBvbiB0aGUKICAgIHB1YmxpYyBrZXkgb2YgdGhlIHRydXN0IGFuY2hvci4gVGhpcyByZXF1aXJlcyBvYnRhaW5pbmcgYSBzZXF1ZW5jZSBvZgogICAgY2VydGlmaWNhdGVzIHRoYXQgc3VwcG9ydCB0aGF0IGJpbmRpbmcuIFRoYXQgc2VxdWVuY2Ugc2hvdWxkIGJlIHByb3ZpZGVkCiAgICBpbiB0aGUgcGFzc2VkICdjaGFpbicuIFRoZSB0cnVzdCBhbmNob3Igc2hvdWxkIGJlIGluIHRoZSBnaXZlbiBDQQogICAgc3RvcmUuIFRoZSAnZW5kIGVudGl0eScgY2VydGlmaWNhdGUgaXMgdGhlIGNlcnRpZmljYXRlIHByb3ZpZGVkIGJ5IHRoZQogICAgZW5kIHBvaW50ICh0eXBpY2FsbHkgYSBzZXJ2ZXIpIGFuZCBpcyB0aGUgZmlyc3QgaW4gdGhlIGNoYWluLgoKICAgIFRvIG1lZXQgdGhpcyBnb2FsLCB0aGUgcGF0aCB2YWxpZGF0aW9uIHByb2Nlc3MgdmVyaWZpZXMsIGFtb25nIG90aGVyCiAgICB0aGluZ3MsIHRoYXQgYSBwcm9zcGVjdGl2ZSBjZXJ0aWZpY2F0aW9uIHBhdGggKGEgc2VxdWVuY2Ugb2YgbgogICAgY2VydGlmaWNhdGVzIG9yIGEgJ2NoYWluJykgc2F0aXNmaWVzIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCiAgICAoYSkgZm9yIGFsbCB4IGluIHsxLCAuLi4sIG4tMX0sIHRoZSBzdWJqZWN0IG9mIGNlcnRpZmljYXRlIHggaXMKICAgICAgICAgIHRoZSBpc3N1ZXIgb2YgY2VydGlmaWNhdGUgeCsxOwoKICAgIChiKSBjZXJ0aWZpY2F0ZSAxIGlzIGlzc3VlZCBieSB0aGUgdHJ1c3QgYW5jaG9yOwoKICAgIChjKSBjZXJ0aWZpY2F0ZSBuIGlzIHRoZSBjZXJ0aWZpY2F0ZSB0byBiZSB2YWxpZGF0ZWQ7IGFuZAoKICAgIChkKSBmb3IgYWxsIHggaW4gezEsIC4uLiwgbn0sIHRoZSBjZXJ0aWZpY2F0ZSB3YXMgdmFsaWQgYXQgdGhlCiAgICAgICAgICB0aW1lIGluIHF1ZXN0aW9uLgoKICAgIE5vdGUgdGhhdCBoZXJlICduJyBpcyBpbmRleCAwIGluIHRoZSBjaGFpbiBhbmQgMSBpcyB0aGUgbGFzdCBjZXJ0aWZpY2F0ZQogICAgaW4gdGhlIGNoYWluIGFuZCBpdCBtdXN0IGJlIHNpZ25lZCBieSBhIGNlcnRpZmljYXRlIGluIHRoZSBjb25uZWN0aW9uJ3MKICAgIENBIHN0b3JlLgoKICAgIFRoZSBwYXRoIHZhbGlkYXRpb24gcHJvY2VzcyBhbHNvIGRldGVybWluZXMgdGhlIHNldCBvZiBjZXJ0aWZpY2F0ZQogICAgcG9saWNpZXMgdGhhdCBhcmUgdmFsaWQgZm9yIHRoaXMgcGF0aCwgYmFzZWQgb24gdGhlIGNlcnRpZmljYXRlIHBvbGljaWVzCiAgICBleHRlbnNpb24sIHBvbGljeSBtYXBwaW5nIGV4dGVuc2lvbiwgcG9saWN5IGNvbnN0cmFpbnRzIGV4dGVuc2lvbiwgYW5kCiAgICBpbmhpYml0IGFueS1wb2xpY3kgZXh0ZW5zaW9uLgoKICAgIE5vdGU6IFBvbGljeSBtYXBwaW5nIGV4dGVuc2lvbiBub3Qgc3VwcG9ydGVkIChOb3QgUmVxdWlyZWQpLgoKICAgIE5vdGU6IElmIHRoZSBjZXJ0aWZpY2F0ZSBoYXMgYW4gdW5zdXBwb3J0ZWQgY3JpdGljYWwgZXh0ZW5zaW9uLCB0aGVuIGl0CiAgICBtdXN0IGJlIHJlamVjdGVkLgoKICAgIE5vdGU6IEEgY2VydGlmaWNhdGUgaXMgc2VsZi1pc3N1ZWQgaWYgdGhlIEROcyB0aGF0IGFwcGVhciBpbiB0aGUgc3ViamVjdAogICAgYW5kIGlzc3VlciBmaWVsZHMgYXJlIGlkZW50aWNhbCBhbmQgYXJlIG5vdCBlbXB0eS4KCiAgICBUaGUgcGF0aCB2YWxpZGF0aW9uIGFsZ29yaXRobSBhc3N1bWVzIHRoZSBmb2xsb3dpbmcgc2V2ZW4gaW5wdXRzIGFyZQogICAgcHJvdmlkZWQgdG8gdGhlIHBhdGggcHJvY2Vzc2luZyBsb2dpYy4gV2hhdCB0aGlzIHNwZWNpZmljIGltcGxlbWVudGF0aW9uCiAgICB3aWxsIHVzZSBpcyBwcm92aWRlZCBwYXJlbnRoZXRpY2FsbHk6CgogICAgKGEpIGEgcHJvc3BlY3RpdmUgY2VydGlmaWNhdGlvbiBwYXRoIG9mIGxlbmd0aCBuICh0aGUgJ2NoYWluJykKICAgIChiKSB0aGUgY3VycmVudCBkYXRlL3RpbWU6ICgnbm93JykuCiAgICAoYykgdXNlci1pbml0aWFsLXBvbGljeS1zZXQ6IEEgc2V0IG9mIGNlcnRpZmljYXRlIHBvbGljeSBpZGVudGlmaWVycwogICAgICAgICAgbmFtaW5nIHRoZSBwb2xpY2llcyB0aGF0IGFyZSBhY2NlcHRhYmxlIHRvIHRoZSBjZXJ0aWZpY2F0ZSB1c2VyLgogICAgICAgICAgVGhlIHVzZXItaW5pdGlhbC1wb2xpY3ktc2V0IGNvbnRhaW5zIHRoZSBzcGVjaWFsIHZhbHVlIGFueS1wb2xpY3kKICAgICAgICAgIGlmIHRoZSB1c2VyIGlzIG5vdCBjb25jZXJuZWQgYWJvdXQgY2VydGlmaWNhdGUgcG9saWN5CiAgICAgICAgICAoTm90IGltcGxlbWVudGVkLiBBbnkgcG9saWN5IGlzIGFjY2VwdGVkKS4KICAgIChkKSB0cnVzdCBhbmNob3IgaW5mb3JtYXRpb24sIGRlc2NyaWJpbmcgYSBDQSB0aGF0IHNlcnZlcyBhcyBhIHRydXN0CiAgICAgICAgICBhbmNob3IgZm9yIHRoZSBjZXJ0aWZpY2F0aW9uIHBhdGguIFRoZSB0cnVzdCBhbmNob3IgaW5mb3JtYXRpb24KICAgICAgICAgIGluY2x1ZGVzOgoKICAgICAgKDEpICB0aGUgdHJ1c3RlZCBpc3N1ZXIgbmFtZSwKICAgICAgKDIpICB0aGUgdHJ1c3RlZCBwdWJsaWMga2V5IGFsZ29yaXRobSwKICAgICAgKDMpICB0aGUgdHJ1c3RlZCBwdWJsaWMga2V5LCBhbmQKICAgICAgKDQpICBvcHRpb25hbGx5LCB0aGUgdHJ1c3RlZCBwdWJsaWMga2V5IHBhcmFtZXRlcnMgYXNzb2NpYXRlZAogICAgICAgICAgICAgd2l0aCB0aGUgcHVibGljIGtleS4KCiAgICAgIChUcnVzdCBhbmNob3JzIGFyZSBwcm92aWRlZCB2aWEgY2VydGlmaWNhdGVzIGluIHRoZSBDQSBzdG9yZSkuCgogICAgICBUaGUgdHJ1c3QgYW5jaG9yIGluZm9ybWF0aW9uIG1heSBiZSBwcm92aWRlZCB0byB0aGUgcGF0aCBwcm9jZXNzaW5nCiAgICAgIHByb2NlZHVyZSBpbiB0aGUgZm9ybSBvZiBhIHNlbGYtc2lnbmVkIGNlcnRpZmljYXRlLiBUaGUgdHJ1c3RlZCBhbmNob3IKICAgICAgaW5mb3JtYXRpb24gaXMgdHJ1c3RlZCBiZWNhdXNlIGl0IHdhcyBkZWxpdmVyZWQgdG8gdGhlIHBhdGggcHJvY2Vzc2luZwogICAgICBwcm9jZWR1cmUgYnkgc29tZSB0cnVzdHdvcnRoeSBvdXQtb2YtYmFuZCBwcm9jZWR1cmUuIElmIHRoZSB0cnVzdGVkCiAgICAgIHB1YmxpYyBrZXkgYWxnb3JpdGhtIHJlcXVpcmVzIHBhcmFtZXRlcnMsIHRoZW4gdGhlIHBhcmFtZXRlcnMgYXJlCiAgICAgIHByb3ZpZGVkIGFsb25nIHdpdGggdGhlIHRydXN0ZWQgcHVibGljIGtleSAoTm8gcGFyYW1ldGVycyB1c2VkIGluIHRoaXMKICAgICAgaW1wbGVtZW50YXRpb24pLgoKICAgIChlKSBpbml0aWFsLXBvbGljeS1tYXBwaW5nLWluaGliaXQsIHdoaWNoIGluZGljYXRlcyBpZiBwb2xpY3kgbWFwcGluZyBpcwogICAgICAgICAgYWxsb3dlZCBpbiB0aGUgY2VydGlmaWNhdGlvbiBwYXRoLgogICAgICAgICAgKE5vdCBpbXBsZW1lbnRlZCwgbm8gcG9saWN5IGNoZWNraW5nKQoKICAgIChmKSBpbml0aWFsLWV4cGxpY2l0LXBvbGljeSwgd2hpY2ggaW5kaWNhdGVzIGlmIHRoZSBwYXRoIG11c3QgYmUgdmFsaWQKICAgICAgICAgIGZvciBhdCBsZWFzdCBvbmUgb2YgdGhlIGNlcnRpZmljYXRlIHBvbGljaWVzIGluIHRoZSB1c2VyLWluaXRpYWwtCiAgICAgICAgICBwb2xpY3ktc2V0LgogICAgICAgICAgKE5vdCBpbXBsZW1lbnRlZCwgbm8gcG9saWN5IGNoZWNraW5nKQoKICAgIChnKSBpbml0aWFsLWFueS1wb2xpY3ktaW5oaWJpdCwgd2hpY2ggaW5kaWNhdGVzIHdoZXRoZXIgdGhlCiAgICAgICAgICBhbnlQb2xpY3kgT0lEIHNob3VsZCBiZSBwcm9jZXNzZWQgaWYgaXQgaXMgaW5jbHVkZWQgaW4gYQogICAgICAgICAgY2VydGlmaWNhdGUuCiAgICAgICAgICAoTm90IGltcGxlbWVudGVkLCBzbyBhbnkgcG9saWN5IGlzIHZhbGlkIHByb3ZpZGVkIHRoYXQgaXQgaXMKICAgICAgICAgIG5vdCBtYXJrZWQgYXMgY3JpdGljYWwpICovCgogIC8qIEJhc2ljIFBhdGggUHJvY2Vzc2luZzoKCiAgICBGb3IgZWFjaCBjZXJ0aWZpY2F0ZSBpbiB0aGUgJ2NoYWluJywgdGhlIGZvbGxvd2luZyBpcyBjaGVja2VkOgoKICAgIDEuIFRoZSBjZXJ0aWZpY2F0ZSB2YWxpZGl0eSBwZXJpb2QgaW5jbHVkZXMgdGhlIGN1cnJlbnQgdGltZS4KICAgIDIuIFRoZSBjZXJ0aWZpY2F0ZSB3YXMgc2lnbmVkIGJ5IGl0cyBwYXJlbnQgKHdoZXJlIHRoZSBwYXJlbnQgaXMgZWl0aGVyCiAgICAgICB0aGUgbmV4dCBpbiB0aGUgY2hhaW4gb3IgZnJvbSB0aGUgQ0Egc3RvcmUpLiBBbGxvdyBwcm9jZXNzaW5nIHRvCiAgICAgICBjb250aW51ZSB0byB0aGUgbmV4dCBzdGVwIGlmIG5vIHBhcmVudCBpcyBmb3VuZCBidXQgdGhlIGNlcnRpZmljYXRlIGlzCiAgICAgICBpbiB0aGUgQ0Egc3RvcmUuCiAgICAzLiBUT0RPOiBUaGUgY2VydGlmaWNhdGUgaGFzIG5vdCBiZWVuIHJldm9rZWQuCiAgICA0LiBUaGUgY2VydGlmaWNhdGUgaXNzdWVyIG5hbWUgbWF0Y2hlcyB0aGUgcGFyZW50J3Mgc3ViamVjdCBuYW1lLgogICAgNS4gVE9ETzogSWYgdGhlIGNlcnRpZmljYXRlIGlzIHNlbGYtaXNzdWVkIGFuZCBub3QgdGhlIGZpbmFsIGNlcnRpZmljYXRlCiAgICAgICBpbiB0aGUgY2hhaW4sIHNraXAgdGhpcyBzdGVwLCBvdGhlcndpc2UgdmVyaWZ5IHRoYXQgdGhlIHN1YmplY3QgbmFtZQogICAgICAgaXMgd2l0aGluIG9uZSBvZiB0aGUgcGVybWl0dGVkIHN1YnRyZWVzIG9mIFguNTAwIGRpc3Rpbmd1aXNoZWQgbmFtZXMKICAgICAgIGFuZCB0aGF0IGVhY2ggb2YgdGhlIGFsdGVybmF0aXZlIG5hbWVzIGluIHRoZSBzdWJqZWN0QWx0TmFtZSBleHRlbnNpb24KICAgICAgIChjcml0aWNhbCBvciBub24tY3JpdGljYWwpIGlzIHdpdGhpbiBvbmUgb2YgdGhlIHBlcm1pdHRlZCBzdWJ0cmVlcyBmb3IKICAgICAgIHRoYXQgbmFtZSB0eXBlLgogICAgNi4gVE9ETzogSWYgdGhlIGNlcnRpZmljYXRlIGlzIHNlbGYtaXNzdWVkIGFuZCBub3QgdGhlIGZpbmFsIGNlcnRpZmljYXRlCiAgICAgICBpbiB0aGUgY2hhaW4sIHNraXAgdGhpcyBzdGVwLCBvdGhlcndpc2UgdmVyaWZ5IHRoYXQgdGhlIHN1YmplY3QgbmFtZQogICAgICAgaXMgbm90IHdpdGhpbiBvbmUgb2YgdGhlIGV4Y2x1ZGVkIHN1YnRyZWVzIGZvciBYLjUwMCBkaXN0aW5ndWlzaGVkCiAgICAgICBuYW1lcyBhbmQgbm9uZSBvZiB0aGUgc3ViamVjdEFsdE5hbWUgZXh0ZW5zaW9uIG5hbWVzIGFyZSBleGNsdWRlZCBmb3IKICAgICAgIHRoYXQgbmFtZSB0eXBlLgogICAgNy4gVGhlIG90aGVyIHN0ZXBzIGluIHRoZSBhbGdvcml0aG0gZm9yIGJhc2ljIHBhdGggcHJvY2Vzc2luZyBpbnZvbHZlCiAgICAgICBoYW5kbGluZyB0aGUgcG9saWN5IGV4dGVuc2lvbiB3aGljaCBpcyBub3QgcHJlc2VudGx5IHN1cHBvcnRlZCBpbiB0aGlzCiAgICAgICBpbXBsZW1lbnRhdGlvbi4gSW5zdGVhZCwgaWYgYSBjcml0aWNhbCBwb2xpY3kgZXh0ZW5zaW9uIGlzIGZvdW5kLCB0aGUKICAgICAgIGNlcnRpZmljYXRlIGlzIHJlamVjdGVkIGFzIG5vdCBzdXBwb3J0ZWQuCiAgICA4LiBJZiB0aGUgY2VydGlmaWNhdGUgaXMgbm90IHRoZSBmaXJzdCBvciBpZiBpdHMgdGhlIG9ubHkgY2VydGlmaWNhdGUgaW4KICAgICAgIHRoZSBjaGFpbiAoaGF2aW5nIG5vIHBhcmVudCBmcm9tIHRoZSBDQSBzdG9yZSBvciBpcyBzZWxmLXNpZ25lZCkgYW5kIGl0CiAgICAgICBoYXMgYSBjcml0aWNhbCBrZXkgdXNhZ2UgZXh0ZW5zaW9uLCB2ZXJpZnkgdGhhdCB0aGUga2V5Q2VydFNpZ24gYml0IGlzCiAgICAgICBzZXQuIElmIHRoZSBrZXkgdXNhZ2UgZXh0ZW5zaW9uIGV4aXN0cywgdmVyaWZ5IHRoYXQgdGhlIGJhc2ljCiAgICAgICBjb25zdHJhaW50cyBleHRlbnNpb24gZXhpc3RzLiBJZiB0aGUgYmFzaWMgY29uc3RyYWludHMgZXh0ZW5zaW9uIGV4aXN0cywKICAgICAgIHZlcmlmeSB0aGF0IHRoZSBjQSBmbGFnIGlzIHNldC4gSWYgcGF0aExlbkNvbnN0cmFpbnQgaXMgc2V0LCBlbnN1cmUgdGhhdAogICAgICAgdGhlIG51bWJlciBvZiBjZXJ0aWZpY2F0ZXMgdGhhdCBwcmVjZWRlIGluIHRoZSBjaGFpbiAoY29tZSBlYXJsaWVyCiAgICAgICBpbiB0aGUgY2hhaW4gYXMgaW1wbGVtZW50ZWQgYmVsb3cpLCBleGNsdWRpbmcgdGhlIHZlcnkgZmlyc3QgaW4gdGhlCiAgICAgICBjaGFpbiAodHlwaWNhbGx5IHRoZSBlbmQtZW50aXR5IG9uZSksIGlzbid0IGdyZWF0ZXIgdGhhbiB0aGUKICAgICAgIHBhdGhMZW5Db25zdHJhaW50LiBUaGlzIGNvbnN0cmFpbnQgbGltaXRzIHRoZSBudW1iZXIgb2YgaW50ZXJtZWRpYXRlCiAgICAgICBDQXMgdGhhdCBtYXkgYXBwZWFyIGJlbG93IGEgQ0EgYmVmb3JlIG9ubHkgZW5kLWVudGl0eSBjZXJ0aWZpY2F0ZXMKICAgICAgIG1heSBiZSBpc3N1ZWQuICovCgogIC8vIGNvcHkgY2VydCBjaGFpbiByZWZlcmVuY2VzIHRvIGFub3RoZXIgYXJyYXkgdG8gcHJvdGVjdCBhZ2FpbnN0IGNoYW5nZXMKICAvLyBpbiB2ZXJpZnkgY2FsbGJhY2sKICBjaGFpbiA9IGNoYWluLnNsaWNlKDApOwogIHZhciBjZXJ0cyA9IGNoYWluLnNsaWNlKDApOwoKICAvLyBnZXQgY3VycmVudCBkYXRlCiAgdmFyIG5vdyA9IG5ldyBEYXRlKCk7CgogIC8vIHZlcmlmeSBlYWNoIGNlcnQgaW4gdGhlIGNoYWluIHVzaW5nIGl0cyBwYXJlbnQsIHdoZXJlIHRoZSBwYXJlbnQKICAvLyBpcyBlaXRoZXIgdGhlIG5leHQgaW4gdGhlIGNoYWluIG9yIGZyb20gdGhlIENBIHN0b3JlCiAgdmFyIGZpcnN0ID0gdHJ1ZTsKICB2YXIgZXJyb3IgPSBudWxsOwogIHZhciBkZXB0aCA9IDA7CiAgZG8gewogICAgdmFyIGNlcnQgPSBjaGFpbi5zaGlmdCgpOwogICAgdmFyIHBhcmVudCA9IG51bGw7CiAgICB2YXIgc2VsZlNpZ25lZCA9IGZhbHNlOwoKICAgIC8vIDEuIGNoZWNrIHZhbGlkIHRpbWUKICAgIGlmKG5vdyA8IGNlcnQudmFsaWRpdHkubm90QmVmb3JlIHx8IG5vdyA+IGNlcnQudmFsaWRpdHkubm90QWZ0ZXIpIHsKICAgICAgZXJyb3IgPSB7CiAgICAgICAgbWVzc2FnZTogJ0NlcnRpZmljYXRlIGlzIG5vdCB2YWxpZCB5ZXQgb3IgaGFzIGV4cGlyZWQuJywKICAgICAgICBlcnJvcjogcGtpLmNlcnRpZmljYXRlRXJyb3IuY2VydGlmaWNhdGVfZXhwaXJlZCwKICAgICAgICBub3RCZWZvcmU6IGNlcnQudmFsaWRpdHkubm90QmVmb3JlLAogICAgICAgIG5vdEFmdGVyOiBjZXJ0LnZhbGlkaXR5Lm5vdEFmdGVyLAogICAgICAgIG5vdzogbm93CiAgICAgIH07CiAgICB9CgogICAgLy8gMi4gdmVyaWZ5IHdpdGggcGFyZW50IGZyb20gY2hhaW4gb3IgQ0Egc3RvcmUKICAgIGlmKGVycm9yID09PSBudWxsKSB7CiAgICAgIHBhcmVudCA9IGNoYWluWzBdIHx8IGNhU3RvcmUuZ2V0SXNzdWVyKGNlcnQpOwogICAgICBpZihwYXJlbnQgPT09IG51bGwpIHsKICAgICAgICAvLyBjaGVjayBmb3Igc2VsZi1zaWduZWQgY2VydAogICAgICAgIGlmKGNlcnQuaXNJc3N1ZXIoY2VydCkpIHsKICAgICAgICAgIHNlbGZTaWduZWQgPSB0cnVlOwogICAgICAgICAgcGFyZW50ID0gY2VydDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmKHBhcmVudCkgewogICAgICAgIC8vIEZJWE1FOiBjdXJyZW50IENBIHN0b3JlIGltcGxlbWVudGF0aW9uIG1pZ2h0IGhhdmUgbXVsdGlwbGUKICAgICAgICAvLyBjZXJ0aWZpY2F0ZXMgd2hlcmUgdGhlIGlzc3VlciBjYW4ndCBiZSBkZXRlcm1pbmVkIGZyb20gdGhlCiAgICAgICAgLy8gY2VydGlmaWNhdGUgKGhhcHBlbnMgcmFyZWx5IHdpdGgsIGVnOiBvbGQgY2VydGlmaWNhdGVzKSBzbyBub3JtYWxpemUKICAgICAgICAvLyBieSBhbHdheXMgcHV0dGluZyBwYXJlbnRzIGludG8gYW4gYXJyYXkKICAgICAgICAvLyBUT0RPOiB0aGVyZSdzIG1heSBiZSBhbiBleHRyZW1lIGRlZ2VuZXJhdGUgY2FzZSBjdXJyZW50bHkgdW5jb3ZlcmVkCiAgICAgICAgLy8gd2hlcmUgYW4gb2xkIGludGVybWVkaWF0ZSBjZXJ0aWZpY2F0ZSBzZWVtcyB0byBoYXZlIGEgbWF0Y2hpbmcgcGFyZW50CiAgICAgICAgLy8gYnV0IG5vbmUgb2YgdGhlIHBhcmVudHMgYWN0dWFsbHkgdmVyaWZ5IC4uLiBidXQgdGhlIGludGVybWVkaWF0ZQogICAgICAgIC8vIGlzIGluIHRoZSBDQSBhbmQgaXQgc2hvdWxkIHBhc3MgdGhpcyBjaGVjazsgbmVlZHMgaW52ZXN0aWdhdGlvbgogICAgICAgIHZhciBwYXJlbnRzID0gcGFyZW50OwogICAgICAgIGlmKCFmb3JnZS51dGlsLmlzQXJyYXkocGFyZW50cykpIHsKICAgICAgICAgIHBhcmVudHMgPSBbcGFyZW50c107CiAgICAgICAgfQoKICAgICAgICAvLyB0cnkgdG8gdmVyaWZ5IHdpdGggZWFjaCBwb3NzaWJsZSBwYXJlbnQgKHR5cGljYWxseSBvbmx5IG9uZSkKICAgICAgICB2YXIgdmVyaWZpZWQgPSBmYWxzZTsKICAgICAgICB3aGlsZSghdmVyaWZpZWQgJiYgcGFyZW50cy5sZW5ndGggPiAwKSB7CiAgICAgICAgICBwYXJlbnQgPSBwYXJlbnRzLnNoaWZ0KCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICB2ZXJpZmllZCA9IHBhcmVudC52ZXJpZnkoY2VydCk7CiAgICAgICAgICB9IGNhdGNoKGV4KSB7CiAgICAgICAgICAgIC8vIGZhaWx1cmUgdG8gdmVyaWZ5LCBkb24ndCBjYXJlIHdoeSwgdHJ5IG5leHQgb25lCiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZighdmVyaWZpZWQpIHsKICAgICAgICAgIGVycm9yID0gewogICAgICAgICAgICBtZXNzYWdlOiAnQ2VydGlmaWNhdGUgc2lnbmF0dXJlIGlzIGludmFsaWQuJywKICAgICAgICAgICAgZXJyb3I6IHBraS5jZXJ0aWZpY2F0ZUVycm9yLmJhZF9jZXJ0aWZpY2F0ZQogICAgICAgICAgfTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmKGVycm9yID09PSBudWxsICYmICghcGFyZW50IHx8IHNlbGZTaWduZWQpICYmCiAgICAgICAgIWNhU3RvcmUuaGFzQ2VydGlmaWNhdGUoY2VydCkpIHsKICAgICAgICAvLyBubyBwYXJlbnQgaXNzdWVyIGFuZCBjZXJ0aWZpY2F0ZSBpdHNlbGYgaXMgbm90IHRydXN0ZWQKICAgICAgICBlcnJvciA9IHsKICAgICAgICAgIG1lc3NhZ2U6ICdDZXJ0aWZpY2F0ZSBpcyBub3QgdHJ1c3RlZC4nLAogICAgICAgICAgZXJyb3I6IHBraS5jZXJ0aWZpY2F0ZUVycm9yLnVua25vd25fY2EKICAgICAgICB9OwogICAgICB9CiAgICB9CgogICAgLy8gVE9ETzogMy4gY2hlY2sgcmV2b2tlZAoKICAgIC8vIDQuIGNoZWNrIGZvciBtYXRjaGluZyBpc3N1ZXIvc3ViamVjdAogICAgaWYoZXJyb3IgPT09IG51bGwgJiYgcGFyZW50ICYmICFjZXJ0LmlzSXNzdWVyKHBhcmVudCkpIHsKICAgICAgLy8gcGFyZW50IGlzIG5vdCBpc3N1ZXIKICAgICAgZXJyb3IgPSB7CiAgICAgICAgbWVzc2FnZTogJ0NlcnRpZmljYXRlIGlzc3VlciBpcyBpbnZhbGlkLicsCiAgICAgICAgZXJyb3I6IHBraS5jZXJ0aWZpY2F0ZUVycm9yLmJhZF9jZXJ0aWZpY2F0ZQogICAgICB9OwogICAgfQoKICAgIC8vIDUuIFRPRE86IGNoZWNrIG5hbWVzIHdpdGggcGVybWl0dGVkIG5hbWVzIHRyZWUKCiAgICAvLyA2LiBUT0RPOiBjaGVjayBuYW1lcyBhZ2FpbnN0IGV4Y2x1ZGVkIG5hbWVzIHRyZWUKCiAgICAvLyA3LiBjaGVjayBmb3IgdW5zdXBwb3J0ZWQgY3JpdGljYWwgZXh0ZW5zaW9ucwogICAgaWYoZXJyb3IgPT09IG51bGwpIHsKICAgICAgLy8gc3VwcG9ydGVkIGV4dGVuc2lvbnMKICAgICAgdmFyIHNlID0gewogICAgICAgIGtleVVzYWdlOiB0cnVlLAogICAgICAgIGJhc2ljQ29uc3RyYWludHM6IHRydWUKICAgICAgfTsKICAgICAgZm9yKHZhciBpID0gMDsgZXJyb3IgPT09IG51bGwgJiYgaSA8IGNlcnQuZXh0ZW5zaW9ucy5sZW5ndGg7ICsraSkgewogICAgICAgIHZhciBleHQgPSBjZXJ0LmV4dGVuc2lvbnNbaV07CiAgICAgICAgaWYoZXh0LmNyaXRpY2FsICYmICEoZXh0Lm5hbWUgaW4gc2UpKSB7CiAgICAgICAgICBlcnJvciA9IHsKICAgICAgICAgICAgbWVzc2FnZToKICAgICAgICAgICAgICAnQ2VydGlmaWNhdGUgaGFzIGFuIHVuc3VwcG9ydGVkIGNyaXRpY2FsIGV4dGVuc2lvbi4nLAogICAgICAgICAgICBlcnJvcjogcGtpLmNlcnRpZmljYXRlRXJyb3IudW5zdXBwb3J0ZWRfY2VydGlmaWNhdGUKICAgICAgICAgIH07CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgLy8gOC4gY2hlY2sgZm9yIENBIGlmIGNlcnQgaXMgbm90IGZpcnN0IG9yIGlzIHRoZSBvbmx5IGNlcnRpZmljYXRlCiAgICAvLyByZW1haW5pbmcgaW4gY2hhaW4gd2l0aCBubyBwYXJlbnQgb3IgaXMgc2VsZi1zaWduZWQKICAgIGlmKGVycm9yID09PSBudWxsICYmCiAgICAgICghZmlyc3QgfHwgKGNoYWluLmxlbmd0aCA9PT0gMCAmJiAoIXBhcmVudCB8fCBzZWxmU2lnbmVkKSkpKSB7CiAgICAgIC8vIGZpcnN0IGNoZWNrIGtleVVzYWdlIGV4dGVuc2lvbiBhbmQgdGhlbiBiYXNpYyBjb25zdHJhaW50cwogICAgICB2YXIgYmNFeHQgPSBjZXJ0LmdldEV4dGVuc2lvbignYmFzaWNDb25zdHJhaW50cycpOwogICAgICB2YXIga2V5VXNhZ2VFeHQgPSBjZXJ0LmdldEV4dGVuc2lvbigna2V5VXNhZ2UnKTsKICAgICAgaWYoa2V5VXNhZ2VFeHQgIT09IG51bGwpIHsKICAgICAgICAvLyBrZXlDZXJ0U2lnbiBtdXN0IGJlIHRydWUgYW5kIHRoZXJlIG11c3QgYmUgYSBiYXNpYwogICAgICAgIC8vIGNvbnN0cmFpbnRzIGV4dGVuc2lvbgogICAgICAgIGlmKCFrZXlVc2FnZUV4dC5rZXlDZXJ0U2lnbiB8fCBiY0V4dCA9PT0gbnVsbCkgewogICAgICAgICAgLy8gYmFkIGNlcnRpZmljYXRlCiAgICAgICAgICBlcnJvciA9IHsKICAgICAgICAgICAgbWVzc2FnZToKICAgICAgICAgICAgICAnQ2VydGlmaWNhdGUga2V5VXNhZ2Ugb3IgYmFzaWNDb25zdHJhaW50cyBjb25mbGljdCAnICsKICAgICAgICAgICAgICAnb3IgaW5kaWNhdGUgdGhhdCB0aGUgY2VydGlmaWNhdGUgaXMgbm90IGEgQ0EuICcgKwogICAgICAgICAgICAgICdJZiB0aGUgY2VydGlmaWNhdGUgaXMgdGhlIG9ubHkgb25lIGluIHRoZSBjaGFpbiBvciAnICsKICAgICAgICAgICAgICAnaXNuXCd0IHRoZSBmaXJzdCB0aGVuIHRoZSBjZXJ0aWZpY2F0ZSBtdXN0IGJlIGEgJyArCiAgICAgICAgICAgICAgJ3ZhbGlkIENBLicsCiAgICAgICAgICAgIGVycm9yOiBwa2kuY2VydGlmaWNhdGVFcnJvci5iYWRfY2VydGlmaWNhdGUKICAgICAgICAgIH07CiAgICAgICAgfQogICAgICB9CiAgICAgIC8vIGJhc2ljIGNvbnN0cmFpbnRzIGNBIGZsYWcgbXVzdCBiZSBzZXQKICAgICAgaWYoZXJyb3IgPT09IG51bGwgJiYgYmNFeHQgIT09IG51bGwgJiYgIWJjRXh0LmNBKSB7CiAgICAgICAgLy8gYmFkIGNlcnRpZmljYXRlCiAgICAgICAgZXJyb3IgPSB7CiAgICAgICAgICBtZXNzYWdlOgogICAgICAgICAgICAnQ2VydGlmaWNhdGUgYmFzaWNDb25zdHJhaW50cyBpbmRpY2F0ZXMgdGhlIGNlcnRpZmljYXRlICcgKwogICAgICAgICAgICAnaXMgbm90IGEgQ0EuJywKICAgICAgICAgIGVycm9yOiBwa2kuY2VydGlmaWNhdGVFcnJvci5iYWRfY2VydGlmaWNhdGUKICAgICAgICB9OwogICAgICB9CiAgICAgIC8vIGlmIGVycm9yIGlzIG5vdCBudWxsIGFuZCBrZXlVc2FnZSBpcyBhdmFpbGFibGUsIHRoZW4gd2Uga25vdyBpdAogICAgICAvLyBoYXMga2V5Q2VydFNpZ24gYW5kIHRoZXJlIGlzIGEgYmFzaWMgY29uc3RyYWludHMgZXh0ZW5zaW9uIHRvbywKICAgICAgLy8gd2hpY2ggbWVhbnMgd2UgY2FuIGNoZWNrIHBhdGhMZW5Db25zdHJhaW50IChpZiBpdCBleGlzdHMpCiAgICAgIGlmKGVycm9yID09PSBudWxsICYmIGtleVVzYWdlRXh0ICE9PSBudWxsICYmCiAgICAgICAgJ3BhdGhMZW5Db25zdHJhaW50JyBpbiBiY0V4dCkgewogICAgICAgIC8vIHBhdGhMZW4gaXMgdGhlIG1heGltdW0gIyBvZiBpbnRlcm1lZGlhdGUgQ0EgY2VydHMgdGhhdCBjYW4gYmUKICAgICAgICAvLyBmb3VuZCBiZXR3ZWVuIHRoZSBjdXJyZW50IGNlcnRpZmljYXRlIGFuZCB0aGUgZW5kLWVudGl0eSAoZGVwdGggMCkKICAgICAgICAvLyBjZXJ0aWZpY2F0ZTsgdGhpcyBudW1iZXIgZG9lcyBub3QgaW5jbHVkZSB0aGUgZW5kLWVudGl0eSAoZGVwdGggMCwKICAgICAgICAvLyBsYXN0IGluIHRoZSBjaGFpbikgZXZlbiBpZiBpdCBoYXBwZW5zIHRvIGJlIGEgQ0EgY2VydGlmaWNhdGUgaXRzZWxmCiAgICAgICAgdmFyIHBhdGhMZW4gPSBkZXB0aCAtIDE7CiAgICAgICAgaWYocGF0aExlbiA+IGJjRXh0LnBhdGhMZW5Db25zdHJhaW50KSB7CiAgICAgICAgICAvLyBwYXRoTGVuQ29uc3RyYWludCB2aW9sYXRlZCwgYmFkIGNlcnRpZmljYXRlCiAgICAgICAgICBlcnJvciA9IHsKICAgICAgICAgICAgbWVzc2FnZToKICAgICAgICAgICAgICAnQ2VydGlmaWNhdGUgYmFzaWNDb25zdHJhaW50cyBwYXRoTGVuQ29uc3RyYWludCB2aW9sYXRlZC4nLAogICAgICAgICAgICBlcnJvcjogcGtpLmNlcnRpZmljYXRlRXJyb3IuYmFkX2NlcnRpZmljYXRlCiAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIC8vIGNhbGwgYXBwbGljYXRpb24gY2FsbGJhY2sKICAgIHZhciB2ZmQgPSAoZXJyb3IgPT09IG51bGwpID8gdHJ1ZSA6IGVycm9yLmVycm9yOwogICAgdmFyIHJldCA9IHZlcmlmeSA/IHZlcmlmeSh2ZmQsIGRlcHRoLCBjZXJ0cykgOiB2ZmQ7CiAgICBpZihyZXQgPT09IHRydWUpIHsKICAgICAgLy8gY2xlYXIgYW55IHNldCBlcnJvcgogICAgICBlcnJvciA9IG51bGw7CiAgICB9IGVsc2UgewogICAgICAvLyBpZiBwYXNzZWQgYmFzaWMgdGVzdHMsIHNldCBkZWZhdWx0IG1lc3NhZ2UgYW5kIGFsZXJ0CiAgICAgIGlmKHZmZCA9PT0gdHJ1ZSkgewogICAgICAgIGVycm9yID0gewogICAgICAgICAgbWVzc2FnZTogJ1RoZSBhcHBsaWNhdGlvbiByZWplY3RlZCB0aGUgY2VydGlmaWNhdGUuJywKICAgICAgICAgIGVycm9yOiBwa2kuY2VydGlmaWNhdGVFcnJvci5iYWRfY2VydGlmaWNhdGUKICAgICAgICB9OwogICAgICB9CgogICAgICAvLyBjaGVjayBmb3IgY3VzdG9tIGVycm9yIGluZm8KICAgICAgaWYocmV0IHx8IHJldCA9PT0gMCkgewogICAgICAgIC8vIHNldCBjdXN0b20gbWVzc2FnZSBhbmQgZXJyb3IKICAgICAgICBpZih0eXBlb2YgcmV0ID09PSAnb2JqZWN0JyAmJiAhZm9yZ2UudXRpbC5pc0FycmF5KHJldCkpIHsKICAgICAgICAgIGlmKHJldC5tZXNzYWdlKSB7CiAgICAgICAgICAgICBlcnJvci5tZXNzYWdlID0gcmV0Lm1lc3NhZ2U7CiAgICAgICAgICB9CiAgICAgICAgICBpZihyZXQuZXJyb3IpIHsKICAgICAgICAgICAgZXJyb3IuZXJyb3IgPSByZXQuZXJyb3I7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmKHR5cGVvZiByZXQgPT09ICdzdHJpbmcnKSB7CiAgICAgICAgICAvLyBzZXQgY3VzdG9tIGVycm9yCiAgICAgICAgICBlcnJvci5lcnJvciA9IHJldDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIHRocm93IGVycm9yCiAgICAgIHRocm93IGVycm9yOwogICAgfQoKICAgIC8vIG5vIGxvbmdlciBmaXJzdCBjZXJ0IGluIGNoYWluCiAgICBmaXJzdCA9IGZhbHNlOwogICAgKytkZXB0aDsKICB9IHdoaWxlKGNoYWluLmxlbmd0aCA+IDApOwoKICByZXR1cm4gdHJ1ZTsKfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3g1MDknOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZS5wa2k7CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3g1MDknLFsKICAncmVxdWlyZScsCiAgJ21vZHVsZScsCiAgJy4vYWVzJywKICAnLi9hc24xJywKICAnLi9kZXMnLAogICcuL21kJywKICAnLi9tZ2YnLAogICcuL29pZHMnLAogICcuL3BlbScsCiAgJy4vcHNzJywKICAnLi9yc2EnLAogICcuL3V0aWwnCl0sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIEphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgUEtDUyMxMi4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICogQGF1dGhvciBTdGVmYW4gU2llZ2wgPHN0ZXNpZUBicm9rZW5waXBlLmRlPgogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKiBDb3B5cmlnaHQgKGMpIDIwMTIgU3RlZmFuIFNpZWdsIDxzdGVzaWVAYnJva2VucGlwZS5kZT4KICoKICogVGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIFBLQ1MjMTIgaXMgYXMgZm9sbG93cwogKiAoc2VlIGZ0cDovL2Z0cC5yc2FzZWN1cml0eS5jb20vcHViL3BrY3MvcGtjcy0xMi9wa2NzLTEyLXRjMS5wZGYgZm9yIGRldGFpbHMpCiAqCiAqIFBGWCA6Oj0gU0VRVUVOQ0UgewogKiAgIHZlcnNpb24gIElOVEVHRVIge3YzKDMpfSh2MywuLi4pLAogKiAgIGF1dGhTYWZlIENvbnRlbnRJbmZvLAogKiAgIG1hY0RhdGEgIE1hY0RhdGEgT1BUSU9OQUwKICogfQogKgogKiBNYWNEYXRhIDo6PSBTRVFVRU5DRSB7CiAqICAgbWFjIERpZ2VzdEluZm8sCiAqICAgbWFjU2FsdCBPQ1RFVCBTVFJJTkcsCiAqICAgaXRlcmF0aW9ucyBJTlRFR0VSIERFRkFVTFQgMQogKiB9CiAqIE5vdGU6IFRoZSBpdGVyYXRpb25zIGRlZmF1bHQgaXMgZm9yIGhpc3RvcmljYWwgcmVhc29ucyBhbmQgaXRzIHVzZSBpcwogKiBkZXByZWNhdGVkLiBBIGhpZ2hlciB2YWx1ZSwgbGlrZSAxMDI0LCBpcyByZWNvbW1lbmRlZC4KICoKICogRGlnZXN0SW5mbyBpcyBkZWZpbmVkIGluIFBLQ1MjNyBhcyBmb2xsb3dzOgogKgogKiBEaWdlc3RJbmZvIDo6PSBTRVFVRU5DRSB7CiAqICAgZGlnZXN0QWxnb3JpdGhtIERpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXIsCiAqICAgZGlnZXN0IERpZ2VzdAogKiB9CiAqCiAqIERpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXIgOjo9IEFsZ29yaXRobUlkZW50aWZpZXIKICoKICogVGhlIEFsZ29yaXRobUlkZW50aWZpZXIgY29udGFpbnMgYW4gT2JqZWN0IElkZW50aWZpZXIgKE9JRCkgYW5kIHBhcmFtZXRlcnMKICogZm9yIHRoZSBhbGdvcml0aG0sIGlmIGFueS4gSW4gdGhlIGNhc2Ugb2YgU0hBMSB0aGVyZSBpcyBub25lLgogKgogKiBBbGdvcml0aG1JZGVudGlmZXIgOjo9IFNFUVVFTkNFIHsKICogICAgYWxnb3JpdGhtIE9CSkVDVCBJREVOVElGSUVSLAogKiAgICBwYXJhbWV0ZXJzIEFOWSBERUZJTkVEIEJZIGFsZ29yaXRobSBPUFRJT05BTAogKiB9CiAqCiAqIERpZ2VzdCA6Oj0gT0NURVQgU1RSSU5HCiAqCiAqCiAqIENvbnRlbnRJbmZvIDo6PSBTRVFVRU5DRSB7CiAqICAgY29udGVudFR5cGUgQ29udGVudFR5cGUsCiAqICAgY29udGVudCAgICAgWzBdIEVYUExJQ0lUIEFOWSBERUZJTkVEIEJZIGNvbnRlbnRUeXBlIE9QVElPTkFMCiAqIH0KICoKICogQ29udGVudFR5cGUgOjo9IE9CSkVDVCBJREVOVElGSUVSCiAqCiAqIEF1dGhlbnRpY2F0ZWRTYWZlIDo6PSBTRVFVRU5DRSBPRiBDb250ZW50SW5mbwogKiAtLSBEYXRhIGlmIHVuZW5jcnlwdGVkCiAqIC0tIEVuY3J5cHRlZERhdGEgaWYgcGFzc3dvcmQtZW5jcnlwdGVkCiAqIC0tIEVudmVsb3BlZERhdGEgaWYgcHVibGljIGtleS1lbmNyeXB0ZWQKICoKICoKICogU2FmZUNvbnRlbnRzIDo6PSBTRVFVRU5DRSBPRiBTYWZlQmFnCiAqCiAqIFNhZmVCYWcgOjo9IFNFUVVFTkNFIHsKICogICBiYWdJZCAgICAgQkFHLVRZUEUuJmlkICh7UEtDUzEyQmFnU2V0fSkKICogICBiYWdWYWx1ZSAgWzBdIEVYUExJQ0lUIEJBRy1UWVBFLiZUeXBlKHtQS0NTMTJCYWdTZXR9e0BiYWdJZH0pLAogKiAgIGJhZ0F0dHJpYnV0ZXMgU0VUIE9GIFBLQ1MxMkF0dHJpYnV0ZSBPUFRJT05BTAogKiB9CiAqCiAqIFBLQ1MxMkF0dHJpYnV0ZSA6Oj0gU0VRVUVOQ0UgewogKiAgIGF0dHJJZCBBVFRSSUJVVEUuJmlkICh7UEtDUzEyQXR0clNldH0pLAogKiAgIGF0dHJWYWx1ZXMgU0VUIE9GIEFUVFJJQlVURS4mVHlwZSAoe1BLQ1MxMkF0dHJTZXR9e0BhdHRySWR9KQogKiB9IC0tIFRoaXMgdHlwZSBpcyBjb21wYXRpYmxlIHdpdGggdGhlIFguNTAwIHR5cGUg4oCZQXR0cmlidXRl4oCZCiAqCiAqIFBLQ1MxMkF0dHJTZXQgQVRUUklCVVRFIDo6PSB7CiAqICAgZnJpZW5kbHlOYW1lIHwgLS0gZnJvbSBQS0NTICM5CiAqICAgbG9jYWxLZXlJZCwgLS0gZnJvbSBQS0NTICM5CiAqICAgLi4uIC0tIE90aGVyIGF0dHJpYnV0ZXMgYXJlIGFsbG93ZWQKICogfQogKgogKiBDZXJ0QmFnIDo6PSBTRVFVRU5DRSB7CiAqICAgY2VydElkICAgIEJBRy1UWVBFLiZpZCAgICh7Q2VydFR5cGVzfSksCiAqICAgY2VydFZhbHVlIFswXSBFWFBMSUNJVCBCQUctVFlQRS4mVHlwZSAoe0NlcnRUeXBlc317QGNlcnRJZH0pCiAqIH0KICoKICogeDUwOUNlcnRpZmljYXRlIEJBRy1UWVBFIDo6PSB7T0NURVQgU1RSSU5HIElERU5USUZJRUQgQlkge2NlcnRUeXBlcyAxfX0KICogICAtLSBERVItZW5jb2RlZCBYLjUwOSBjZXJ0aWZpY2F0ZSBzdG9yZWQgaW4gT0NURVQgU1RSSU5HCiAqCiAqIHNkc2lDZXJ0aWZpY2F0ZSBCQUctVFlQRSA6Oj0ge0lBNVN0cmluZyBJREVOVElGSUVEIEJZIHtjZXJ0VHlwZXMgMn19CiAqIC0tIEJhc2U2NC1lbmNvZGVkIFNEU0kgY2VydGlmaWNhdGUgc3RvcmVkIGluIElBNVN0cmluZwogKgogKiBDZXJ0VHlwZXMgQkFHLVRZUEUgOjo9IHsKICogICB4NTA5Q2VydGlmaWNhdGUgfAogKiAgIHNkc2lDZXJ0aWZpY2F0ZSwKICogICAuLi4gLS0gRm9yIGZ1dHVyZSBleHRlbnNpb25zCiAqIH0KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovLyBzaG9ydGN1dCBmb3IgYXNuLjEgJiBQS0kgQVBJCnZhciBhc24xID0gZm9yZ2UuYXNuMTsKdmFyIHBraSA9IGZvcmdlLnBraTsKCi8vIHNob3J0Y3V0IGZvciBQS0NTIzEyIEFQSQp2YXIgcDEyID0gZm9yZ2UucGtjczEyID0gZm9yZ2UucGtjczEyIHx8IHt9OwoKdmFyIGNvbnRlbnRJbmZvVmFsaWRhdG9yID0gewogIG5hbWU6ICdDb250ZW50SW5mbycsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwgIC8vIGEgQ29udGVudEluZm8KICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdDb250ZW50SW5mby5jb250ZW50VHlwZScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ2NvbnRlbnRUeXBlJwogIH0sIHsKICAgIG5hbWU6ICdDb250ZW50SW5mby5jb250ZW50JywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIGNhcHR1cmVBc24xOiAnY29udGVudCcKICB9XQp9OwoKdmFyIHBmeFZhbGlkYXRvciA9IHsKICBuYW1lOiAnUEZYJywKICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogIGNvbnN0cnVjdGVkOiB0cnVlLAogIHZhbHVlOiBbewogICAgbmFtZTogJ1BGWC52ZXJzaW9uJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5JTlRFR0VSLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ZlcnNpb24nCiAgfSwKICBjb250ZW50SW5mb1ZhbGlkYXRvciwgewogICAgbmFtZTogJ1BGWC5tYWNEYXRhJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgb3B0aW9uYWw6IHRydWUsCiAgICBjYXB0dXJlQXNuMTogJ21hYycsCiAgICB2YWx1ZTogW3sKICAgICAgbmFtZTogJ1BGWC5tYWNEYXRhLm1hYycsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLCAgLy8gRGlnZXN0SW5mbwogICAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgICAgdmFsdWU6IFt7CiAgICAgICAgbmFtZTogJ1BGWC5tYWNEYXRhLm1hYy5kaWdlc3RBbGdvcml0aG0nLAogICAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsICAvLyBEaWdlc3RBbGdvcml0aG1JZGVudGlmaWVyCiAgICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgICAgdmFsdWU6IFt7CiAgICAgICAgICBuYW1lOiAnUEZYLm1hY0RhdGEubWFjLmRpZ2VzdEFsZ29yaXRobS5hbGdvcml0aG0nLAogICAgICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICAgICAgdHlwZTogYXNuMS5UeXBlLk9JRCwKICAgICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICAgIGNhcHR1cmU6ICdtYWNBbGdvcml0aG0nCiAgICAgICAgfSwgewogICAgICAgICAgbmFtZTogJ1BGWC5tYWNEYXRhLm1hYy5kaWdlc3RBbGdvcml0aG0ucGFyYW1ldGVycycsCiAgICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgICBjYXB0dXJlQXNuMTogJ21hY0FsZ29yaXRobVBhcmFtZXRlcnMnCiAgICAgICAgfV0KICAgICAgfSwgewogICAgICAgIG5hbWU6ICdQRlgubWFjRGF0YS5tYWMuZGlnZXN0JywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBjYXB0dXJlOiAnbWFjRGlnZXN0JwogICAgICB9XQogICAgfSwgewogICAgICBuYW1lOiAnUEZYLm1hY0RhdGEubWFjU2FsdCcsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdtYWNTYWx0JwogICAgfSwgewogICAgICBuYW1lOiAnUEZYLm1hY0RhdGEuaXRlcmF0aW9ucycsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgb3B0aW9uYWw6IHRydWUsCiAgICAgIGNhcHR1cmU6ICdtYWNJdGVyYXRpb25zJwogICAgfV0KICB9XQp9OwoKdmFyIHNhZmVCYWdWYWxpZGF0b3IgPSB7CiAgbmFtZTogJ1NhZmVCYWcnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnU2FmZUJhZy5iYWdJZCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ2JhZ0lkJwogIH0sIHsKICAgIG5hbWU6ICdTYWZlQmFnLmJhZ1ZhbHVlJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIGNhcHR1cmVBc24xOiAnYmFnVmFsdWUnCiAgfSwgewogICAgbmFtZTogJ1NhZmVCYWcuYmFnQXR0cmlidXRlcycsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VULAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICBvcHRpb25hbDogdHJ1ZSwKICAgIGNhcHR1cmU6ICdiYWdBdHRyaWJ1dGVzJwogIH1dCn07Cgp2YXIgYXR0cmlidXRlVmFsaWRhdG9yID0gewogIG5hbWU6ICdBdHRyaWJ1dGUnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnQXR0cmlidXRlLmF0dHJJZCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ29pZCcKICB9LCB7CiAgICBuYW1lOiAnQXR0cmlidXRlLmF0dHJWYWx1ZXMnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLlNFVCwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgY2FwdHVyZTogJ3ZhbHVlcycKICB9XQp9OwoKdmFyIGNlcnRCYWdWYWxpZGF0b3IgPSB7CiAgbmFtZTogJ0NlcnRCYWcnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnQ2VydEJhZy5jZXJ0SWQnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLk9JRCwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdjZXJ0SWQnCiAgfSwgewogICAgbmFtZTogJ0NlcnRCYWcuY2VydFZhbHVlJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIC8qIFNvIGZhciB3ZSBvbmx5IHN1cHBvcnQgWC41MDkgY2VydGlmaWNhdGVzICh3aGljaCBhcmUgd3JhcHBlZCBpbgogICAgICAgYW4gT0NURVQgU1RSSU5HLCBoZW5jZSBoYXJkIGNvZGUgdGhhdCBoZXJlKS4gKi8KICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnQ2VydEJhZy5jZXJ0VmFsdWVbMF0nLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuQ2xhc3MuT0NURVRTVFJJTkcsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ2NlcnQnCiAgICB9XQogIH1dCn07CgovKioKICogU2VhcmNoIFNhZmVDb250ZW50cyBzdHJ1Y3R1cmUgZm9yIGJhZ3Mgd2l0aCBtYXRjaGluZyBhdHRyaWJ1dGVzLgogKgogKiBUaGUgc2VhcmNoIGNhbiBvcHRpb25hbGx5IGJlIG5hcnJvd2VkIGJ5IGEgY2VydGFpbiBiYWcgdHlwZS4KICoKICogQHBhcmFtIHNhZmVDb250ZW50cyB0aGUgU2FmZUNvbnRlbnRzIHN0cnVjdHVyZSB0byBzZWFyY2ggaW4uCiAqIEBwYXJhbSBhdHRyTmFtZSB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIGNvbXBhcmUgYWdhaW5zdC4KICogQHBhcmFtIGF0dHJWYWx1ZSB0aGUgYXR0cmlidXRlIHZhbHVlIHRvIHNlYXJjaCBmb3IuCiAqIEBwYXJhbSBbYmFnVHlwZV0gYmFnIHR5cGUgdG8gbmFycm93IHNlYXJjaCBieS4KICoKICogQHJldHVybiBhbiBhcnJheSBvZiBtYXRjaGluZyBiYWdzLgogKi8KZnVuY3Rpb24gX2dldEJhZ3NCeUF0dHJpYnV0ZShzYWZlQ29udGVudHMsIGF0dHJOYW1lLCBhdHRyVmFsdWUsIGJhZ1R5cGUpIHsKICB2YXIgcmVzdWx0ID0gW107CgogIGZvcih2YXIgaSA9IDA7IGkgPCBzYWZlQ29udGVudHMubGVuZ3RoOyBpICsrKSB7CiAgICBmb3IodmFyIGogPSAwOyBqIDwgc2FmZUNvbnRlbnRzW2ldLnNhZmVCYWdzLmxlbmd0aDsgaiArKykgewogICAgICB2YXIgYmFnID0gc2FmZUNvbnRlbnRzW2ldLnNhZmVCYWdzW2pdOwogICAgICBpZihiYWdUeXBlICE9PSB1bmRlZmluZWQgJiYgYmFnLnR5cGUgIT09IGJhZ1R5cGUpIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICAvLyBvbmx5IGZpbHRlciBieSBiYWcgdHlwZSwgbm8gYXR0cmlidXRlIHNwZWNpZmllZAogICAgICBpZihhdHRyTmFtZSA9PT0gbnVsbCkgewogICAgICAgIHJlc3VsdC5wdXNoKGJhZyk7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgaWYoYmFnLmF0dHJpYnV0ZXNbYXR0ck5hbWVdICE9PSB1bmRlZmluZWQgJiYKICAgICAgICBiYWcuYXR0cmlidXRlc1thdHRyTmFtZV0uaW5kZXhPZihhdHRyVmFsdWUpID49IDApIHsKICAgICAgICByZXN1bHQucHVzaChiYWcpOwogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogQ29udmVydHMgYSBQS0NTIzEyIFBGWCBpbiBBU04uMSBub3RhdGlvbiBpbnRvIGEgUEZYIG9iamVjdC4KICoKICogQHBhcmFtIG9iaiBUaGUgUEtDUyMxMiBQRlggaW4gQVNOLjEgbm90YXRpb24uCiAqIEBwYXJhbSBzdHJpY3QgdHJ1ZSB0byB1c2Ugc3RyaWN0IERFUiBkZWNvZGluZywgZmFsc2Ugbm90IHRvIChkZWZhdWx0OiB0cnVlKS4KICogQHBhcmFtIHtTdHJpbmd9IHBhc3N3b3JkIFBhc3N3b3JkIHRvIGRlY3J5cHQgd2l0aCAob3B0aW9uYWwpLgogKgogKiBAcmV0dXJuIFBLQ1MjMTIgUEZYIG9iamVjdC4KICovCnAxMi5wa2NzMTJGcm9tQXNuMSA9IGZ1bmN0aW9uKG9iaiwgc3RyaWN0LCBwYXNzd29yZCkgewogIC8vIGhhbmRsZSBhcmdzCiAgaWYodHlwZW9mIHN0cmljdCA9PT0gJ3N0cmluZycpIHsKICAgIHBhc3N3b3JkID0gc3RyaWN0OwogICAgc3RyaWN0ID0gdHJ1ZTsKICB9IGVsc2UgaWYoc3RyaWN0ID09PSB1bmRlZmluZWQpIHsKICAgIHN0cmljdCA9IHRydWU7CiAgfQoKICAvLyB2YWxpZGF0ZSBQRlggYW5kIGNhcHR1cmUgZGF0YQogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgcGZ4VmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIFBLQ1MjMTIgUEZYLiAnICsKICAgICAgJ0FTTi4xIG9iamVjdCBpcyBub3QgYW4gUEtDUyMxMiBQRlguJyk7CiAgICBlcnJvci5lcnJvcnMgPSBlcnJvcjsKICAgIHRocm93IGVycm9yOwogIH0KCiAgdmFyIHBmeCA9IHsKICAgIHZlcnNpb246IGNhcHR1cmUudmVyc2lvbi5jaGFyQ29kZUF0KDApLAogICAgc2FmZUNvbnRlbnRzOiBbXSwKCiAgICAvKioKICAgICAqIEdldHMgYmFncyB3aXRoIG1hdGNoaW5nIGF0dHJpYnV0ZXMuCiAgICAgKgogICAgICogQHBhcmFtIGZpbHRlciB0aGUgYXR0cmlidXRlcyB0byBmaWx0ZXIgYnk6CiAgICAgKiAgICAgICAgICBbbG9jYWxLZXlJZF0gdGhlIGxvY2FsS2V5SWQgdG8gc2VhcmNoIGZvci4KICAgICAqICAgICAgICAgIFtsb2NhbEtleUlkSGV4XSB0aGUgbG9jYWxLZXlJZCBpbiBoZXggdG8gc2VhcmNoIGZvci4KICAgICAqICAgICAgICAgIFtmcmllbmRseU5hbWVdIHRoZSBmcmllbmRseSBuYW1lIHRvIHNlYXJjaCBmb3IuCiAgICAgKiAgICAgICAgICBbYmFnVHlwZV0gYmFnIHR5cGUgdG8gbmFycm93IGVhY2ggYXR0cmlidXRlIHNlYXJjaCBieS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGEgbWFwIG9mIGF0dHJpYnV0ZSB0eXBlIHRvIGFuIGFycmF5IG9mIG1hdGNoaW5nIGJhZ3Mgb3IsIGlmIG5vCiAgICAgKiAgICAgICAgICAgYXR0cmlidXRlIHdhcyBnaXZlbiBidXQgYSBiYWcgdHlwZSwgdGhlIG1hcCBrZXkgd2lsbCBiZSB0aGUKICAgICAqICAgICAgICAgICBiYWcgdHlwZS4KICAgICAqLwogICAgZ2V0QmFnczogZnVuY3Rpb24oZmlsdGVyKSB7CiAgICAgIHZhciBydmFsID0ge307CgogICAgICB2YXIgbG9jYWxLZXlJZDsKICAgICAgaWYoJ2xvY2FsS2V5SWQnIGluIGZpbHRlcikgewogICAgICAgIGxvY2FsS2V5SWQgPSBmaWx0ZXIubG9jYWxLZXlJZDsKICAgICAgfSBlbHNlIGlmKCdsb2NhbEtleUlkSGV4JyBpbiBmaWx0ZXIpIHsKICAgICAgICBsb2NhbEtleUlkID0gZm9yZ2UudXRpbC5oZXhUb0J5dGVzKGZpbHRlci5sb2NhbEtleUlkSGV4KTsKICAgICAgfQoKICAgICAgLy8gZmlsdGVyIG9uIGJhZ1R5cGUgb25seQogICAgICBpZihsb2NhbEtleUlkID09PSB1bmRlZmluZWQgJiYgISgnZnJpZW5kbHlOYW1lJyBpbiBmaWx0ZXIpICYmCiAgICAgICAgJ2JhZ1R5cGUnIGluIGZpbHRlcikgewogICAgICAgIHJ2YWxbZmlsdGVyLmJhZ1R5cGVdID0gX2dldEJhZ3NCeUF0dHJpYnV0ZSgKICAgICAgICAgIHBmeC5zYWZlQ29udGVudHMsIG51bGwsIG51bGwsIGZpbHRlci5iYWdUeXBlKTsKICAgICAgfQoKICAgICAgaWYobG9jYWxLZXlJZCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgcnZhbC5sb2NhbEtleUlkID0gX2dldEJhZ3NCeUF0dHJpYnV0ZSgKICAgICAgICAgIHBmeC5zYWZlQ29udGVudHMsICdsb2NhbEtleUlkJywKICAgICAgICAgIGxvY2FsS2V5SWQsIGZpbHRlci5iYWdUeXBlKTsKICAgICAgfQogICAgICBpZignZnJpZW5kbHlOYW1lJyBpbiBmaWx0ZXIpIHsKICAgICAgICBydmFsLmZyaWVuZGx5TmFtZSA9IF9nZXRCYWdzQnlBdHRyaWJ1dGUoCiAgICAgICAgICBwZnguc2FmZUNvbnRlbnRzLCAnZnJpZW5kbHlOYW1lJywKICAgICAgICAgIGZpbHRlci5mcmllbmRseU5hbWUsIGZpbHRlci5iYWdUeXBlKTsKICAgICAgfQoKICAgICAgcmV0dXJuIHJ2YWw7CiAgICB9LAoKICAgIC8qKgogICAgICogREVQUkVDQVRFRDogdXNlIGdldEJhZ3MoKSBpbnN0ZWFkLgogICAgICoKICAgICAqIEdldCBiYWdzIHdpdGggbWF0Y2hpbmcgZnJpZW5kbHlOYW1lIGF0dHJpYnV0ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gZnJpZW5kbHlOYW1lIHRoZSBmcmllbmRseSBuYW1lIHRvIHNlYXJjaCBmb3IuCiAgICAgKiBAcGFyYW0gW2JhZ1R5cGVdIGJhZyB0eXBlIHRvIG5hcnJvdyBzZWFyY2ggYnkuCiAgICAgKgogICAgICogQHJldHVybiBhbiBhcnJheSBvZiBiYWdzIHdpdGggbWF0Y2hpbmcgZnJpZW5kbHlOYW1lIGF0dHJpYnV0ZS4KICAgICAqLwogICAgZ2V0QmFnc0J5RnJpZW5kbHlOYW1lOiBmdW5jdGlvbihmcmllbmRseU5hbWUsIGJhZ1R5cGUpIHsKICAgICAgcmV0dXJuIF9nZXRCYWdzQnlBdHRyaWJ1dGUoCiAgICAgICAgcGZ4LnNhZmVDb250ZW50cywgJ2ZyaWVuZGx5TmFtZScsIGZyaWVuZGx5TmFtZSwgYmFnVHlwZSk7CiAgICB9LAoKICAgIC8qKgogICAgICogREVQUkVDQVRFRDogdXNlIGdldEJhZ3MoKSBpbnN0ZWFkLgogICAgICoKICAgICAqIEdldCBiYWdzIHdpdGggbWF0Y2hpbmcgbG9jYWxLZXlJZCBhdHRyaWJ1dGUuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2FsS2V5SWQgdGhlIGxvY2FsS2V5SWQgdG8gc2VhcmNoIGZvci4KICAgICAqIEBwYXJhbSBbYmFnVHlwZV0gYmFnIHR5cGUgdG8gbmFycm93IHNlYXJjaCBieS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIGJhZ3Mgd2l0aCBtYXRjaGluZyBsb2NhbEtleUlkIGF0dHJpYnV0ZS4KICAgICAqLwogICAgZ2V0QmFnc0J5TG9jYWxLZXlJZDogZnVuY3Rpb24obG9jYWxLZXlJZCwgYmFnVHlwZSkgewogICAgICByZXR1cm4gX2dldEJhZ3NCeUF0dHJpYnV0ZSgKICAgICAgICBwZnguc2FmZUNvbnRlbnRzLCAnbG9jYWxLZXlJZCcsIGxvY2FsS2V5SWQsIGJhZ1R5cGUpOwogICAgfQogIH07CgogIGlmKGNhcHR1cmUudmVyc2lvbi5jaGFyQ29kZUF0KDApICE9PSAzKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1BLQ1MjMTIgUEZYIG9mIHZlcnNpb24gb3RoZXIgdGhhbiAzIG5vdCBzdXBwb3J0ZWQuJyk7CiAgICBlcnJvci52ZXJzaW9uID0gY2FwdHVyZS52ZXJzaW9uLmNoYXJDb2RlQXQoMCk7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIGlmKGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5jb250ZW50VHlwZSkgIT09IHBraS5vaWRzLmRhdGEpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignT25seSBQS0NTIzEyIFBGWCBpbiBwYXNzd29yZCBpbnRlZ3JpdHkgbW9kZSBzdXBwb3J0ZWQuJyk7CiAgICBlcnJvci5vaWQgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUuY29udGVudFR5cGUpOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICB2YXIgZGF0YSA9IGNhcHR1cmUuY29udGVudC52YWx1ZVswXTsKICBpZihkYXRhLnRhZ0NsYXNzICE9PSBhc24xLkNsYXNzLlVOSVZFUlNBTCB8fAogICAgIGRhdGEudHlwZSAhPT0gYXNuMS5UeXBlLk9DVEVUU1RSSU5HKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BLQ1MjMTIgYXV0aFNhZmUgY29udGVudCBkYXRhIGlzIG5vdCBhbiBPQ1RFVCBTVFJJTkcuJyk7CiAgfQogIGRhdGEgPSBfZGVjb2RlUGtjczdEYXRhKGRhdGEpOwoKICAvLyBjaGVjayBmb3IgTUFDCiAgaWYoY2FwdHVyZS5tYWMpIHsKICAgIHZhciBtZCA9IG51bGw7CiAgICB2YXIgbWFjS2V5Qnl0ZXMgPSAwOwogICAgdmFyIG1hY0FsZ29yaXRobSA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5tYWNBbGdvcml0aG0pOwogICAgc3dpdGNoKG1hY0FsZ29yaXRobSkgewogICAgY2FzZSBwa2kub2lkcy5zaGExOgogICAgICBtZCA9IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICAgIG1hY0tleUJ5dGVzID0gMjA7CiAgICAgIGJyZWFrOwogICAgY2FzZSBwa2kub2lkcy5zaGEyNTY6CiAgICAgIG1kID0gZm9yZ2UubWQuc2hhMjU2LmNyZWF0ZSgpOwogICAgICBtYWNLZXlCeXRlcyA9IDMyOwogICAgICBicmVhazsKICAgIGNhc2UgcGtpLm9pZHMuc2hhMzg0OgogICAgICBtZCA9IGZvcmdlLm1kLnNoYTM4NC5jcmVhdGUoKTsKICAgICAgbWFjS2V5Qnl0ZXMgPSA0ODsKICAgICAgYnJlYWs7CiAgICBjYXNlIHBraS5vaWRzLnNoYTUxMjoKICAgICAgbWQgPSBmb3JnZS5tZC5zaGE1MTIuY3JlYXRlKCk7CiAgICAgIG1hY0tleUJ5dGVzID0gNjQ7CiAgICAgIGJyZWFrOwogICAgY2FzZSBwa2kub2lkcy5tZDU6CiAgICAgIG1kID0gZm9yZ2UubWQubWQ1LmNyZWF0ZSgpOwogICAgICBtYWNLZXlCeXRlcyA9IDE2OwogICAgICBicmVhazsKICAgIH0KICAgIGlmKG1kID09PSBudWxsKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignUEtDUyMxMiB1c2VzIHVuc3VwcG9ydGVkIE1BQyBhbGdvcml0aG06ICcgKyBtYWNBbGdvcml0aG0pOwogICAgfQoKICAgIC8vIHZlcmlmeSBNQUMgKGl0ZXJhdGlvbnMgZGVmYXVsdCB0byAxKQogICAgdmFyIG1hY1NhbHQgPSBuZXcgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKGNhcHR1cmUubWFjU2FsdCk7CiAgICB2YXIgbWFjSXRlcmF0aW9ucyA9ICgoJ21hY0l0ZXJhdGlvbnMnIGluIGNhcHR1cmUpID8KICAgICAgcGFyc2VJbnQoZm9yZ2UudXRpbC5ieXRlc1RvSGV4KGNhcHR1cmUubWFjSXRlcmF0aW9ucyksIDE2KSA6IDEpOwogICAgdmFyIG1hY0tleSA9IHAxMi5nZW5lcmF0ZUtleSgKICAgICAgcGFzc3dvcmQsIG1hY1NhbHQsIDMsIG1hY0l0ZXJhdGlvbnMsIG1hY0tleUJ5dGVzLCBtZCk7CiAgICB2YXIgbWFjID0gZm9yZ2UuaG1hYy5jcmVhdGUoKTsKICAgIG1hYy5zdGFydChtZCwgbWFjS2V5KTsKICAgIG1hYy51cGRhdGUoZGF0YS52YWx1ZSk7CiAgICB2YXIgbWFjVmFsdWUgPSBtYWMuZ2V0TWFjKCk7CiAgICBpZihtYWNWYWx1ZS5nZXRCeXRlcygpICE9PSBjYXB0dXJlLm1hY0RpZ2VzdCkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BLQ1MjMTIgTUFDIGNvdWxkIG5vdCBiZSB2ZXJpZmllZC4gSW52YWxpZCBwYXNzd29yZD8nKTsKICAgIH0KICB9CgogIF9kZWNvZGVBdXRoZW50aWNhdGVkU2FmZShwZngsIGRhdGEudmFsdWUsIHN0cmljdCwgcGFzc3dvcmQpOwogIHJldHVybiBwZng7Cn07CgovKioKICogRGVjb2RlcyBQS0NTIzcgRGF0YS4gUEtDUyM3IChSRkMgMjMxNSkgZGVmaW5lcyAiRGF0YSIgYXMgYW4gT0NURVQgU1RSSU5HLAogKiBidXQgaXQgaXMgc29tZXRpbWVzIGFuIE9DVEVUIFNUUklORyB0aGF0IGlzIGNvbXBvc2VkL2NvbnN0cnVjdGVkIG9mIGNodW5rcywKICogZWFjaCBpdHMgb3duIE9DVEVUIFNUUklORy4gVGhpcyBpcyBCRVItZW5jb2RpbmcgdnMuIERFUi1lbmNvZGluZy4gVGhpcwogKiBmdW5jdGlvbiB0cmFuc2Zvcm1zIHRoaXMgY29ybmVyLWNhc2UgaW50byB0aGUgdXN1YWwgc2ltcGxlLAogKiBub24tY29tcG9zZWQvY29uc3RydWN0ZWQgT0NURVQgU1RSSU5HLgogKgogKiBUaGlzIGZ1bmN0aW9uIG1heSBiZSBtb3ZlZCB0byBBU04uMSBhdCBzb21lIHBvaW50IHRvIGJldHRlciBkZWFsIHdpdGgKICogbW9yZSBCRVItZW5jb2RpbmcgaXNzdWVzLCBzaG91bGQgdGhleSBhcmlzZS4KICoKICogQHBhcmFtIGRhdGEgdGhlIEFTTi4xIERhdGEgb2JqZWN0IHRvIHRyYW5zZm9ybS4KICovCmZ1bmN0aW9uIF9kZWNvZGVQa2NzN0RhdGEoZGF0YSkgewogIC8vIGhhbmRsZSBzcGVjaWFsIGNhc2Ugb2YgImNodW5rZWQiIGRhdGEgY29udGVudDogYW4gb2N0ZXQgc3RyaW5nIGNvbXBvc2VkCiAgLy8gb2Ygb3RoZXIgb2N0ZXQgc3RyaW5ncwogIGlmKGRhdGEuY29tcG9zZWQgfHwgZGF0YS5jb25zdHJ1Y3RlZCkgewogICAgdmFyIHZhbHVlID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBkYXRhLnZhbHVlLmxlbmd0aDsgKytpKSB7CiAgICAgIHZhbHVlLnB1dEJ5dGVzKGRhdGEudmFsdWVbaV0udmFsdWUpOwogICAgfQogICAgZGF0YS5jb21wb3NlZCA9IGRhdGEuY29uc3RydWN0ZWQgPSBmYWxzZTsKICAgIGRhdGEudmFsdWUgPSB2YWx1ZS5nZXRCeXRlcygpOwogIH0KICByZXR1cm4gZGF0YTsKfQoKLyoqCiAqIERlY29kZSBQS0NTIzEyIEF1dGhlbnRpY2F0ZWRTYWZlIChCRVIgZW5jb2RlZCkgaW50byBQRlggb2JqZWN0LgogKgogKiBUaGUgQXV0aGVudGljYXRlZFNhZmUgaXMgYSBCRVItZW5jb2RlZCBTRVFVRU5DRSBPRiBDb250ZW50SW5mby4KICoKICogQHBhcmFtIHBmeCBUaGUgUEtDUyMxMiBQRlggb2JqZWN0IHRvIGZpbGwuCiAqIEBwYXJhbSB7U3RyaW5nfSBhdXRoU2FmZSBCRVItZW5jb2RlZCBBdXRoZW50aWNhdGVkU2FmZS4KICogQHBhcmFtIHN0cmljdCB0cnVlIHRvIHVzZSBzdHJpY3QgREVSIGRlY29kaW5nLCBmYWxzZSBub3QgdG8uCiAqIEBwYXJhbSB7U3RyaW5nfSBwYXNzd29yZCBQYXNzd29yZCB0byBkZWNyeXB0IHdpdGggKG9wdGlvbmFsKS4KICovCmZ1bmN0aW9uIF9kZWNvZGVBdXRoZW50aWNhdGVkU2FmZShwZngsIGF1dGhTYWZlLCBzdHJpY3QsIHBhc3N3b3JkKSB7CiAgYXV0aFNhZmUgPSBhc24xLmZyb21EZXIoYXV0aFNhZmUsIHN0cmljdCk7ICAvKiBhY3R1YWxseSBpdCdzIEJFUiBlbmNvZGVkICovCgogIGlmKGF1dGhTYWZlLnRhZ0NsYXNzICE9PSBhc24xLkNsYXNzLlVOSVZFUlNBTCB8fAogICAgIGF1dGhTYWZlLnR5cGUgIT09IGFzbjEuVHlwZS5TRVFVRU5DRSB8fAogICAgIGF1dGhTYWZlLmNvbnN0cnVjdGVkICE9PSB0cnVlKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BLQ1MjMTIgQXV0aGVudGljYXRlZFNhZmUgZXhwZWN0ZWQgdG8gYmUgYSAnICsKICAgICAgJ1NFUVVFTkNFIE9GIENvbnRlbnRJbmZvJyk7CiAgfQoKICBmb3IodmFyIGkgPSAwOyBpIDwgYXV0aFNhZmUudmFsdWUubGVuZ3RoOyBpICsrKSB7CiAgICB2YXIgY29udGVudEluZm8gPSBhdXRoU2FmZS52YWx1ZVtpXTsKCiAgICAvLyB2YWxpZGF0ZSBjb250ZW50SW5mbyBhbmQgY2FwdHVyZSBkYXRhCiAgICB2YXIgY2FwdHVyZSA9IHt9OwogICAgdmFyIGVycm9ycyA9IFtdOwogICAgaWYoIWFzbjEudmFsaWRhdGUoY29udGVudEluZm8sIGNvbnRlbnRJbmZvVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgQ29udGVudEluZm8uJyk7CiAgICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgdmFyIG9iaiA9IHsKICAgICAgZW5jcnlwdGVkOiBmYWxzZQogICAgfTsKICAgIHZhciBzYWZlQ29udGVudHMgPSBudWxsOwogICAgdmFyIGRhdGEgPSBjYXB0dXJlLmNvbnRlbnQudmFsdWVbMF07CiAgICBzd2l0Y2goYXNuMS5kZXJUb09pZChjYXB0dXJlLmNvbnRlbnRUeXBlKSkgewogICAgY2FzZSBwa2kub2lkcy5kYXRhOgogICAgICBpZihkYXRhLnRhZ0NsYXNzICE9PSBhc24xLkNsYXNzLlVOSVZFUlNBTCB8fAogICAgICAgICBkYXRhLnR5cGUgIT09IGFzbjEuVHlwZS5PQ1RFVFNUUklORykgewogICAgICAgIHRocm93IG5ldyBFcnJvcignUEtDUyMxMiBTYWZlQ29udGVudHMgRGF0YSBpcyBub3QgYW4gT0NURVQgU1RSSU5HLicpOwogICAgICB9CiAgICAgIHNhZmVDb250ZW50cyA9IF9kZWNvZGVQa2NzN0RhdGEoZGF0YSkudmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSBwa2kub2lkcy5lbmNyeXB0ZWREYXRhOgogICAgICBzYWZlQ29udGVudHMgPSBfZGVjcnlwdFNhZmVDb250ZW50cyhkYXRhLCBwYXNzd29yZCk7CiAgICAgIG9iai5lbmNyeXB0ZWQgPSB0cnVlOwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgUEtDUyMxMiBjb250ZW50VHlwZS4nKTsKICAgICAgZXJyb3IuY29udGVudFR5cGUgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUuY29udGVudFR5cGUpOwogICAgICB0aHJvdyBlcnJvcjsKICAgIH0KCiAgICBvYmouc2FmZUJhZ3MgPSBfZGVjb2RlU2FmZUNvbnRlbnRzKHNhZmVDb250ZW50cywgc3RyaWN0LCBwYXNzd29yZCk7CiAgICBwZnguc2FmZUNvbnRlbnRzLnB1c2gob2JqKTsKICB9Cn0KCi8qKgogKiBEZWNyeXB0IFBLQ1MjNyBFbmNyeXB0ZWREYXRhIHN0cnVjdHVyZS4KICoKICogQHBhcmFtIGRhdGEgQVNOLjEgZW5jb2RlZCBFbmNyeXB0ZWRDb250ZW50SW5mbyBvYmplY3QuCiAqIEBwYXJhbSBwYXNzd29yZCBUaGUgdXNlci1wcm92aWRlZCBwYXNzd29yZC4KICoKICogQHJldHVybiBUaGUgZGVjcnlwdGVkIFNhZmVDb250ZW50cyAoQVNOLjEgb2JqZWN0KS4KICovCmZ1bmN0aW9uIF9kZWNyeXB0U2FmZUNvbnRlbnRzKGRhdGEsIHBhc3N3b3JkKSB7CiAgdmFyIGNhcHR1cmUgPSB7fTsKICB2YXIgZXJyb3JzID0gW107CiAgaWYoIWFzbjEudmFsaWRhdGUoCiAgICBkYXRhLCBmb3JnZS5wa2NzNy5hc24xLmVuY3J5cHRlZERhdGFWYWxpZGF0b3IsIGNhcHR1cmUsIGVycm9ycykpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgRW5jcnlwdGVkQ29udGVudEluZm8uJyk7CiAgICBlcnJvci5lcnJvcnMgPSBlcnJvcnM7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIHZhciBvaWQgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUuY29udGVudFR5cGUpOwogIGlmKG9pZCAhPT0gcGtpLm9pZHMuZGF0YSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKAogICAgICAnUEtDUyMxMiBFbmNyeXB0ZWRDb250ZW50SW5mbyBDb250ZW50VHlwZSBpcyBub3QgRGF0YS4nKTsKICAgIGVycm9yLm9pZCA9IG9pZDsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gZ2V0IGNpcGhlcgogIG9pZCA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5lbmNBbGdvcml0aG0pOwogIHZhciBjaXBoZXIgPSBwa2kucGJlLmdldENpcGhlcihvaWQsIGNhcHR1cmUuZW5jUGFyYW1ldGVyLCBwYXNzd29yZCk7CgogIC8vIGdldCBlbmNyeXB0ZWQgZGF0YQogIHZhciBlbmNyeXB0ZWRDb250ZW50QXNuMSA9IF9kZWNvZGVQa2NzN0RhdGEoY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50QXNuMSk7CiAgdmFyIGVuY3J5cHRlZCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGVuY3J5cHRlZENvbnRlbnRBc24xLnZhbHVlKTsKCiAgY2lwaGVyLnVwZGF0ZShlbmNyeXB0ZWQpOwogIGlmKCFjaXBoZXIuZmluaXNoKCkpIHsKICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGRlY3J5cHQgUEtDUyMxMiBTYWZlQ29udGVudHMuJyk7CiAgfQoKICByZXR1cm4gY2lwaGVyLm91dHB1dC5nZXRCeXRlcygpOwp9CgovKioKICogRGVjb2RlIFBLQ1MjMTIgU2FmZUNvbnRlbnRzIChCRVItZW5jb2RlZCkgaW50byBhcnJheSBvZiBCYWcgb2JqZWN0cy4KICoKICogVGhlIHNhZmVDb250ZW50cyBpcyBhIEJFUi1lbmNvZGVkIFNFUVVFTkNFIE9GIFNhZmVCYWcuCiAqCiAqIEBwYXJhbSB7U3RyaW5nfSBzYWZlQ29udGVudHMgQkVSLWVuY29kZWQgc2FmZUNvbnRlbnRzLgogKiBAcGFyYW0gc3RyaWN0IHRydWUgdG8gdXNlIHN0cmljdCBERVIgZGVjb2RpbmcsIGZhbHNlIG5vdCB0by4KICogQHBhcmFtIHtTdHJpbmd9IHBhc3N3b3JkIFBhc3N3b3JkIHRvIGRlY3J5cHQgd2l0aCAob3B0aW9uYWwpLgogKgogKiBAcmV0dXJuIHtBcnJheX0gQXJyYXkgb2YgQmFnIG9iamVjdHMuCiAqLwpmdW5jdGlvbiBfZGVjb2RlU2FmZUNvbnRlbnRzKHNhZmVDb250ZW50cywgc3RyaWN0LCBwYXNzd29yZCkgewogIC8vIGlmIHN0cmljdCBhbmQgbm8gc2FmZSBjb250ZW50cywgcmV0dXJuIGVtcHR5IHNhZmVzCiAgaWYoIXN0cmljdCAmJiBzYWZlQ29udGVudHMubGVuZ3RoID09PSAwKSB7CiAgICByZXR1cm4gW107CiAgfQoKICAvLyBhY3R1YWxseSBpdCdzIEJFUi1lbmNvZGVkCiAgc2FmZUNvbnRlbnRzID0gYXNuMS5mcm9tRGVyKHNhZmVDb250ZW50cywgc3RyaWN0KTsKCiAgaWYoc2FmZUNvbnRlbnRzLnRhZ0NsYXNzICE9PSBhc24xLkNsYXNzLlVOSVZFUlNBTCB8fAogICAgc2FmZUNvbnRlbnRzLnR5cGUgIT09IGFzbjEuVHlwZS5TRVFVRU5DRSB8fAogICAgc2FmZUNvbnRlbnRzLmNvbnN0cnVjdGVkICE9PSB0cnVlKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICdQS0NTIzEyIFNhZmVDb250ZW50cyBleHBlY3RlZCB0byBiZSBhIFNFUVVFTkNFIE9GIFNhZmVCYWcuJyk7CiAgfQoKICB2YXIgcmVzID0gW107CiAgZm9yKHZhciBpID0gMDsgaSA8IHNhZmVDb250ZW50cy52YWx1ZS5sZW5ndGg7IGkrKykgewogICAgdmFyIHNhZmVCYWcgPSBzYWZlQ29udGVudHMudmFsdWVbaV07CgogICAgLy8gdmFsaWRhdGUgU2FmZUJhZyBhbmQgY2FwdHVyZSBkYXRhCiAgICB2YXIgY2FwdHVyZSA9IHt9OwogICAgdmFyIGVycm9ycyA9IFtdOwogICAgaWYoIWFzbjEudmFsaWRhdGUoc2FmZUJhZywgc2FmZUJhZ1ZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIFNhZmVCYWcuJyk7CiAgICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgLyogQ3JlYXRlIGJhZyBvYmplY3QgYW5kIHB1c2ggdG8gcmVzdWx0IGFycmF5LiAqLwogICAgdmFyIGJhZyA9IHsKICAgICAgdHlwZTogYXNuMS5kZXJUb09pZChjYXB0dXJlLmJhZ0lkKSwKICAgICAgYXR0cmlidXRlczogX2RlY29kZUJhZ0F0dHJpYnV0ZXMoY2FwdHVyZS5iYWdBdHRyaWJ1dGVzKQogICAgfTsKICAgIHJlcy5wdXNoKGJhZyk7CgogICAgdmFyIHZhbGlkYXRvciwgZGVjb2RlcjsKICAgIHZhciBiYWdBc24xID0gY2FwdHVyZS5iYWdWYWx1ZS52YWx1ZVswXTsKICAgIHN3aXRjaChiYWcudHlwZSkgewogICAgICBjYXNlIHBraS5vaWRzLnBrY3M4U2hyb3VkZWRLZXlCYWc6CiAgICAgICAgLyogYmFnQXNuMSBoYXMgYSBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbywgd2hpY2ggd2UgbmVlZCB0byBkZWNyeXB0LgogICAgICAgICAgIEFmdGVyd2FyZHMgd2UgY2FuIGhhbmRsZSBpdCBsaWtlIGEga2V5QmFnLAogICAgICAgICAgIHdoaWNoIGlzIGEgUHJpdmF0ZUtleUluZm8uICovCiAgICAgICAgYmFnQXNuMSA9IHBraS5kZWNyeXB0UHJpdmF0ZUtleUluZm8oYmFnQXNuMSwgcGFzc3dvcmQpOwogICAgICAgIGlmKGJhZ0FzbjEgPT09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcigKICAgICAgICAgICAgJ1VuYWJsZSB0byBkZWNyeXB0IFBLQ1MjOCBTaHJvdWRlZEtleUJhZywgd3JvbmcgcGFzc3dvcmQ/Jyk7CiAgICAgICAgfQoKICAgICAgICAvKiBmYWxsIHRocm91Z2ggKi8KICAgICAgY2FzZSBwa2kub2lkcy5rZXlCYWc6CiAgICAgICAgLyogQSBQS0NTIzEyIGtleUJhZyBpcyBhIHNpbXBsZSBQcml2YXRlS2V5SW5mbyBhcyB1bmRlcnN0b29kIGJ5IG91cgogICAgICAgICAgIFBLSSBtb2R1bGUsIGhlbmNlIHdlIGRvbid0IGhhdmUgdG8gZG8gdmFsaWRhdGlvbi9jYXB0dXJpbmcgaGVyZSwKICAgICAgICAgICBqdXN0IHBhc3Mgd2hhdCB3ZSBhbHJlYWR5IGdvdC4gKi8KICAgICAgICB0cnkgewogICAgICAgICAgYmFnLmtleSA9IHBraS5wcml2YXRlS2V5RnJvbUFzbjEoYmFnQXNuMSk7CiAgICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgICAvLyBpZ25vcmUgdW5rbm93biBrZXkgdHlwZSwgcGFzcyBhc24xIHZhbHVlCiAgICAgICAgICBiYWcua2V5ID0gbnVsbDsKICAgICAgICAgIGJhZy5hc24xID0gYmFnQXNuMTsKICAgICAgICB9CiAgICAgICAgY29udGludWU7ICAvKiBOb3RoaW5nIG1vcmUgdG8gZG8uICovCgogICAgICBjYXNlIHBraS5vaWRzLmNlcnRCYWc6CiAgICAgICAgLyogQSBQS0NTIzEyIGNlcnRCYWcgY2FuIHdyYXAgYm90aCBYLjUwOSBhbmQgc2RzaSBjZXJ0aWZpY2F0ZXMuCiAgICAgICAgICAgVGhlcmVmb3JlIHB1dCB0aGUgU2FmZUJhZyBjb250ZW50IHRocm91Z2ggYW5vdGhlciB2YWxpZGF0b3IgdG8KICAgICAgICAgICBjYXB0dXJlIHRoZSBmaWVsZHMuICBBZnRlcndhcmRzIGNoZWNrICYgc3RvcmUgdGhlIHJlc3VsdHMuICovCiAgICAgICAgdmFsaWRhdG9yID0gY2VydEJhZ1ZhbGlkYXRvcjsKICAgICAgICBkZWNvZGVyID0gZnVuY3Rpb24oKSB7CiAgICAgICAgICBpZihhc24xLmRlclRvT2lkKGNhcHR1cmUuY2VydElkKSAhPT0gcGtpLm9pZHMueDUwOUNlcnRpZmljYXRlKSB7CiAgICAgICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcigKICAgICAgICAgICAgICAnVW5zdXBwb3J0ZWQgY2VydGlmaWNhdGUgdHlwZSwgb25seSBYLjUwOSBzdXBwb3J0ZWQuJyk7CiAgICAgICAgICAgIGVycm9yLm9pZCA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5jZXJ0SWQpOwogICAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyB0cnVlPXByb2R1Y2UgY2VydCBoYXNoCiAgICAgICAgICB2YXIgY2VydEFzbjEgPSBhc24xLmZyb21EZXIoY2FwdHVyZS5jZXJ0LCBzdHJpY3QpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYmFnLmNlcnQgPSBwa2kuY2VydGlmaWNhdGVGcm9tQXNuMShjZXJ0QXNuMSwgdHJ1ZSk7CiAgICAgICAgICB9IGNhdGNoKGUpIHsKICAgICAgICAgICAgLy8gaWdub3JlIHVua25vd24gY2VydCB0eXBlLCBwYXNzIGFzbjEgdmFsdWUKICAgICAgICAgICAgYmFnLmNlcnQgPSBudWxsOwogICAgICAgICAgICBiYWcuYXNuMSA9IGNlcnRBc24xOwogICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgYnJlYWs7CgogICAgICBkZWZhdWx0OgogICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgUEtDUyMxMiBTYWZlQmFnIHR5cGUuJyk7CiAgICAgICAgZXJyb3Iub2lkID0gYmFnLnR5cGU7CiAgICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgLyogVmFsaWRhdGUgU2FmZUJhZyB2YWx1ZSAoaS5lLiBDZXJ0QmFnLCBldGMuKSBhbmQgY2FwdHVyZSBkYXRhIGlmIG5lZWRlZC4gKi8KICAgIGlmKHZhbGlkYXRvciAhPT0gdW5kZWZpbmVkICYmCiAgICAgICAhYXNuMS52YWxpZGF0ZShiYWdBc24xLCB2YWxpZGF0b3IsIGNhcHR1cmUsIGVycm9ycykpIHsKICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzEyICcgKyB2YWxpZGF0b3IubmFtZSk7CiAgICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgLyogQ2FsbCBkZWNvZGVyIGZ1bmN0aW9uIGZyb20gYWJvdmUgdG8gc3RvcmUgdGhlIHJlc3VsdHMuICovCiAgICBkZWNvZGVyKCk7CiAgfQoKICByZXR1cm4gcmVzOwp9CgovKioKICogRGVjb2RlIFBLQ1MjMTIgU0VUIE9GIFBLQ1MxMkF0dHJpYnV0ZSBpbnRvIEphdmFTY3JpcHQgb2JqZWN0LgogKgogKiBAcGFyYW0gYXR0cmlidXRlcyBTRVQgT0YgUEtDUzEyQXR0cmlidXRlIChBU04uMSBvYmplY3QpLgogKgogKiBAcmV0dXJuIHRoZSBkZWNvZGVkIGF0dHJpYnV0ZXMuCiAqLwpmdW5jdGlvbiBfZGVjb2RlQmFnQXR0cmlidXRlcyhhdHRyaWJ1dGVzKSB7CiAgdmFyIGRlY29kZWRBdHRycyA9IHt9OwoKICBpZihhdHRyaWJ1dGVzICE9PSB1bmRlZmluZWQpIHsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgKytpKSB7CiAgICAgIHZhciBjYXB0dXJlID0ge307CiAgICAgIHZhciBlcnJvcnMgPSBbXTsKICAgICAgaWYoIWFzbjEudmFsaWRhdGUoYXR0cmlidXRlc1tpXSwgYXR0cmlidXRlVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzEyIEJhZ0F0dHJpYnV0ZS4nKTsKICAgICAgICBlcnJvci5lcnJvcnMgPSBlcnJvcnM7CiAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgIH0KCiAgICAgIHZhciBvaWQgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUub2lkKTsKICAgICAgaWYocGtpLm9pZHNbb2lkXSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgLy8gdW5zdXBwb3J0ZWQgYXR0cmlidXRlIHR5cGUsIGlnbm9yZS4KICAgICAgICBjb250aW51ZTsKICAgICAgfQoKICAgICAgZGVjb2RlZEF0dHJzW3BraS5vaWRzW29pZF1dID0gW107CiAgICAgIGZvcih2YXIgaiA9IDA7IGogPCBjYXB0dXJlLnZhbHVlcy5sZW5ndGg7ICsraikgewogICAgICAgIGRlY29kZWRBdHRyc1twa2kub2lkc1tvaWRdXS5wdXNoKGNhcHR1cmUudmFsdWVzW2pdLnZhbHVlKTsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIGRlY29kZWRBdHRyczsKfQoKLyoqCiAqIFdyYXBzIGEgcHJpdmF0ZSBrZXkgYW5kIGNlcnRpZmljYXRlIGluIGEgUEtDUyMxMiBQRlggd3JhcHBlci4gSWYgYQogKiBwYXNzd29yZCBpcyBwcm92aWRlZCB0aGVuIHRoZSBwcml2YXRlIGtleSB3aWxsIGJlIGVuY3J5cHRlZC4KICoKICogQW4gZW50aXJlIGNlcnRpZmljYXRlIGNoYWluIG1heSBhbHNvIGJlIGluY2x1ZGVkLiBUbyBkbyB0aGlzLCBwYXNzCiAqIGFuIGFycmF5IGZvciB0aGUgImNlcnQiIHBhcmFtZXRlciB3aGVyZSB0aGUgZmlyc3QgY2VydGlmaWNhdGUgaXMKICogdGhlIG9uZSB0aGF0IGlzIHBhaXJlZCB3aXRoIHRoZSBwcml2YXRlIGtleSBhbmQgZWFjaCBzdWJzZXF1ZW50IG9uZQogKiB2ZXJpZmllcyB0aGUgcHJldmlvdXMgb25lLiBUaGUgY2VydGlmaWNhdGVzIG1heSBiZSBpbiBQRU0gZm9ybWF0IG9yCiAqIGhhdmUgYmVlbiBhbHJlYWR5IHBhcnNlZCBieSBGb3JnZS4KICoKICogQHRvZG8gaW1wbGVtZW50IHBhc3N3b3JkLWJhc2VkLWVuY3J5cHRpb24gZm9yIHRoZSB3aG9sZSBwYWNrYWdlCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHByaXZhdGUga2V5LgogKiBAcGFyYW0gY2VydCB0aGUgY2VydGlmaWNhdGUgKG1heSBiZSBhbiBhcnJheSBvZiBjZXJ0aWZpY2F0ZXMgaW4gb3JkZXIKICogICAgICAgICAgdG8gc3BlY2lmeSBhIGNlcnRpZmljYXRlIGNoYWluKS4KICogQHBhcmFtIHBhc3N3b3JkIHRoZSBwYXNzd29yZCB0byB1c2UsIG51bGwgZm9yIG5vbmUuCiAqIEBwYXJhbSBvcHRpb25zOgogKiAgICAgICAgICBhbGdvcml0aG0gdGhlIGVuY3J5cHRpb24gYWxnb3JpdGhtIHRvIHVzZQogKiAgICAgICAgICAgICgnYWVzMTI4JywgJ2FlczE5MicsICdhZXMyNTYnLCAnM2RlcycpLCBkZWZhdWx0cyB0byAnYWVzMTI4Jy4KICogICAgICAgICAgY291bnQgdGhlIGl0ZXJhdGlvbiBjb3VudCB0byB1c2UuCiAqICAgICAgICAgIHNhbHRTaXplIHRoZSBzYWx0IHNpemUgdG8gdXNlLgogKiAgICAgICAgICB1c2VNYWMgdHJ1ZSB0byBpbmNsdWRlIGEgTUFDLCBmYWxzZSBub3QgdG8sIGRlZmF1bHRzIHRvIHRydWUuCiAqICAgICAgICAgIGxvY2FsS2V5SWQgdGhlIGxvY2FsIGtleSBJRCB0byB1c2UsIGluIGhleC4KICogICAgICAgICAgZnJpZW5kbHlOYW1lIHRoZSBmcmllbmRseSBuYW1lIHRvIHVzZS4KICogICAgICAgICAgZ2VuZXJhdGVMb2NhbEtleUlkIHRydWUgdG8gZ2VuZXJhdGUgYSByYW5kb20gbG9jYWwga2V5IElELAogKiAgICAgICAgICAgIGZhbHNlIG5vdCB0bywgZGVmYXVsdHMgdG8gdHJ1ZS4KICoKICogQHJldHVybiB0aGUgUEtDUyMxMiBQRlggQVNOLjEgb2JqZWN0LgogKi8KcDEyLnRvUGtjczEyQXNuMSA9IGZ1bmN0aW9uKGtleSwgY2VydCwgcGFzc3dvcmQsIG9wdGlvbnMpIHsKICAvLyBzZXQgZGVmYXVsdCBvcHRpb25zCiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgb3B0aW9ucy5zYWx0U2l6ZSA9IG9wdGlvbnMuc2FsdFNpemUgfHwgODsKICBvcHRpb25zLmNvdW50ID0gb3B0aW9ucy5jb3VudCB8fCAyMDQ4OwogIG9wdGlvbnMuYWxnb3JpdGhtID0gb3B0aW9ucy5hbGdvcml0aG0gfHwgb3B0aW9ucy5lbmNBbGdvcml0aG0gfHwgJ2FlczEyOCc7CiAgaWYoISgndXNlTWFjJyBpbiBvcHRpb25zKSkgewogICAgb3B0aW9ucy51c2VNYWMgPSB0cnVlOwogIH0KICBpZighKCdsb2NhbEtleUlkJyBpbiBvcHRpb25zKSkgewogICAgb3B0aW9ucy5sb2NhbEtleUlkID0gbnVsbDsKICB9CiAgaWYoISgnZ2VuZXJhdGVMb2NhbEtleUlkJyBpbiBvcHRpb25zKSkgewogICAgb3B0aW9ucy5nZW5lcmF0ZUxvY2FsS2V5SWQgPSB0cnVlOwogIH0KCiAgdmFyIGxvY2FsS2V5SWQgPSBvcHRpb25zLmxvY2FsS2V5SWQ7CiAgdmFyIGJhZ0F0dHJzOwogIGlmKGxvY2FsS2V5SWQgIT09IG51bGwpIHsKICAgIGxvY2FsS2V5SWQgPSBmb3JnZS51dGlsLmhleFRvQnl0ZXMobG9jYWxLZXlJZCk7CiAgfSBlbHNlIGlmKG9wdGlvbnMuZ2VuZXJhdGVMb2NhbEtleUlkKSB7CiAgICAvLyB1c2UgU0hBLTEgb2YgcGFpcmVkIGNlcnQsIGlmIGF2YWlsYWJsZQogICAgaWYoY2VydCkgewogICAgICB2YXIgcGFpcmVkQ2VydCA9IGZvcmdlLnV0aWwuaXNBcnJheShjZXJ0KSA/IGNlcnRbMF0gOiBjZXJ0OwogICAgICBpZih0eXBlb2YgcGFpcmVkQ2VydCA9PT0gJ3N0cmluZycpIHsKICAgICAgICBwYWlyZWRDZXJ0ID0gcGtpLmNlcnRpZmljYXRlRnJvbVBlbShwYWlyZWRDZXJ0KTsKICAgICAgfQogICAgICB2YXIgc2hhMSA9IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICAgIHNoYTEudXBkYXRlKGFzbjEudG9EZXIocGtpLmNlcnRpZmljYXRlVG9Bc24xKHBhaXJlZENlcnQpKS5nZXRCeXRlcygpKTsKICAgICAgbG9jYWxLZXlJZCA9IHNoYTEuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIEZJWE1FOiBjb25zaWRlciB1c2luZyBTSEEtMSBvZiBwdWJsaWMga2V5ICh3aGljaCBjYW4gYmUgZ2VuZXJhdGVkCiAgICAgIC8vIGZyb20gcHJpdmF0ZSBrZXkgY29tcG9uZW50cyksIHNlZTogY2VydC5nZW5lcmF0ZVN1YmplY3RLZXlJZGVudGlmaWVyCiAgICAgIC8vIGdlbmVyYXRlIHJhbmRvbSBieXRlcwogICAgICBsb2NhbEtleUlkID0gZm9yZ2UucmFuZG9tLmdldEJ5dGVzKDIwKTsKICAgIH0KICB9CgogIHZhciBhdHRycyA9IFtdOwogIGlmKGxvY2FsS2V5SWQgIT09IG51bGwpIHsKICAgIGF0dHJzLnB1c2goCiAgICAgIC8vIGxvY2FsS2V5SUQKICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgIC8vIGF0dHJJZAogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgIGFzbjEub2lkVG9EZXIocGtpLm9pZHMubG9jYWxLZXlJZCkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgLy8gYXR0clZhbHVlcwogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VULCB0cnVlLCBbCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLCBmYWxzZSwKICAgICAgICAgICAgbG9jYWxLZXlJZCkKICAgICAgICBdKQogICAgICBdKSk7CiAgfQogIGlmKCdmcmllbmRseU5hbWUnIGluIG9wdGlvbnMpIHsKICAgIGF0dHJzLnB1c2goCiAgICAgIC8vIGZyaWVuZGx5TmFtZQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgLy8gYXR0cklkCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5mcmllbmRseU5hbWUpLmdldEJ5dGVzKCkpLAogICAgICAgIC8vIGF0dHJWYWx1ZXMKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFVCwgdHJ1ZSwgWwogICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5CTVBTVFJJTkcsIGZhbHNlLAogICAgICAgICAgICBvcHRpb25zLmZyaWVuZGx5TmFtZSkKICAgICAgICBdKQogICAgICBdKSk7CiAgfQoKICBpZihhdHRycy5sZW5ndGggPiAwKSB7CiAgICBiYWdBdHRycyA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VULCB0cnVlLCBhdHRycyk7CiAgfQoKICAvLyBjb2xsZWN0IGNvbnRlbnRzIGZvciBBdXRoZW50aWNhdGVkU2FmZQogIHZhciBjb250ZW50cyA9IFtdOwoKICAvLyBjcmVhdGUgc2FmZSBiYWcocykgZm9yIGNlcnRpZmljYXRlIGNoYWluCiAgdmFyIGNoYWluID0gW107CiAgaWYoY2VydCAhPT0gbnVsbCkgewogICAgaWYoZm9yZ2UudXRpbC5pc0FycmF5KGNlcnQpKSB7CiAgICAgIGNoYWluID0gY2VydDsKICAgIH0gZWxzZSB7CiAgICAgIGNoYWluID0gW2NlcnRdOwogICAgfQogIH0KCiAgdmFyIGNlcnRTYWZlQmFncyA9IFtdOwogIGZvcih2YXIgaSA9IDA7IGkgPCBjaGFpbi5sZW5ndGg7ICsraSkgewogICAgLy8gY29udmVydCBjZXJ0IGZyb20gUEVNIGFzIG5lY2Vzc2FyeQogICAgY2VydCA9IGNoYWluW2ldOwogICAgaWYodHlwZW9mIGNlcnQgPT09ICdzdHJpbmcnKSB7CiAgICAgIGNlcnQgPSBwa2kuY2VydGlmaWNhdGVGcm9tUGVtKGNlcnQpOwogICAgfQoKICAgIC8vIFNhZmVCYWcKICAgIHZhciBjZXJ0QmFnQXR0cnMgPSAoaSA9PT0gMCkgPyBiYWdBdHRycyA6IHVuZGVmaW5lZDsKICAgIHZhciBjZXJ0QXNuMSA9IHBraS5jZXJ0aWZpY2F0ZVRvQXNuMShjZXJ0KTsKICAgIHZhciBjZXJ0U2FmZUJhZyA9CiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAvLyBiYWdJZAogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgIGFzbjEub2lkVG9EZXIocGtpLm9pZHMuY2VydEJhZykuZ2V0Qnl0ZXMoKSksCiAgICAgICAgLy8gYmFnVmFsdWUKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFsKICAgICAgICAgIC8vIENlcnRCYWcKICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAgICAgLy8gY2VydElkCiAgICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgICAgICBhc24xLm9pZFRvRGVyKHBraS5vaWRzLng1MDlDZXJ0aWZpY2F0ZSkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgICAgIC8vIGNlcnRWYWx1ZSAoeDUwOUNlcnRpZmljYXRlKQogICAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFsKICAgICAgICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLAogICAgICAgICAgICAgICAgYXNuMS50b0RlcihjZXJ0QXNuMSkuZ2V0Qnl0ZXMoKSkKICAgICAgICAgICAgXSldKV0pLAogICAgICAgIC8vIGJhZ0F0dHJpYnV0ZXMgKE9QVElPTkFMKQogICAgICAgIGNlcnRCYWdBdHRycwogICAgICBdKTsKICAgIGNlcnRTYWZlQmFncy5wdXNoKGNlcnRTYWZlQmFnKTsKICB9CgogIGlmKGNlcnRTYWZlQmFncy5sZW5ndGggPiAwKSB7CiAgICAvLyBTYWZlQ29udGVudHMKICAgIHZhciBjZXJ0U2FmZUNvbnRlbnRzID0gYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIGNlcnRTYWZlQmFncyk7CgogICAgLy8gQ29udGVudEluZm8KICAgIHZhciBjZXJ0Q0kgPQogICAgICAvLyBQS0NTIzcgQ29udGVudEluZm8KICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgIC8vIGNvbnRlbnRUeXBlCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgLy8gT0lEIGZvciB0aGUgY29udGVudCB0eXBlIGlzICdkYXRhJwogICAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5kYXRhKS5nZXRCeXRlcygpKSwKICAgICAgICAvLyBjb250ZW50CiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAwLCB0cnVlLCBbCiAgICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsCiAgICAgICAgICAgIGFzbjEudG9EZXIoY2VydFNhZmVDb250ZW50cykuZ2V0Qnl0ZXMoKSkKICAgICAgICBdKQogICAgICBdKTsKICAgIGNvbnRlbnRzLnB1c2goY2VydENJKTsKICB9CgogIC8vIGNyZWF0ZSBzYWZlIGNvbnRlbnRzIGZvciBwcml2YXRlIGtleQogIHZhciBrZXlCYWcgPSBudWxsOwogIGlmKGtleSAhPT0gbnVsbCkgewogICAgLy8gU2FmZUJhZwogICAgdmFyIHBrQXNuMSA9IHBraS53cmFwUnNhUHJpdmF0ZUtleShwa2kucHJpdmF0ZUtleVRvQXNuMShrZXkpKTsKICAgIGlmKHBhc3N3b3JkID09PSBudWxsKSB7CiAgICAgIC8vIG5vIGVuY3J5cHRpb24KICAgICAga2V5QmFnID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgIC8vIGJhZ0lkCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5rZXlCYWcpLmdldEJ5dGVzKCkpLAogICAgICAgIC8vIGJhZ1ZhbHVlCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAwLCB0cnVlLCBbCiAgICAgICAgICAvLyBQcml2YXRlS2V5SW5mbwogICAgICAgICAgcGtBc24xCiAgICAgICAgXSksCiAgICAgICAgLy8gYmFnQXR0cmlidXRlcyAoT1BUSU9OQUwpCiAgICAgICAgYmFnQXR0cnMKICAgICAgXSk7CiAgICB9IGVsc2UgewogICAgICAvLyBlbmNyeXB0ZWQgUHJpdmF0ZUtleUluZm8KICAgICAga2V5QmFnID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgIC8vIGJhZ0lkCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5wa2NzOFNocm91ZGVkS2V5QmFnKS5nZXRCeXRlcygpKSwKICAgICAgICAvLyBiYWdWYWx1ZQogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMCwgdHJ1ZSwgWwogICAgICAgICAgLy8gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8KICAgICAgICAgIHBraS5lbmNyeXB0UHJpdmF0ZUtleUluZm8ocGtBc24xLCBwYXNzd29yZCwgb3B0aW9ucykKICAgICAgICBdKSwKICAgICAgICAvLyBiYWdBdHRyaWJ1dGVzIChPUFRJT05BTCkKICAgICAgICBiYWdBdHRycwogICAgICBdKTsKICAgIH0KCiAgICAvLyBTYWZlQ29udGVudHMKICAgIHZhciBrZXlTYWZlQ29udGVudHMgPQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBba2V5QmFnXSk7CgogICAgLy8gQ29udGVudEluZm8KICAgIHZhciBrZXlDSSA9CiAgICAgIC8vIFBLQ1MjNyBDb250ZW50SW5mbwogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgLy8gY29udGVudFR5cGUKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgICAvLyBPSUQgZm9yIHRoZSBjb250ZW50IHR5cGUgaXMgJ2RhdGEnCiAgICAgICAgICBhc24xLm9pZFRvRGVyKHBraS5vaWRzLmRhdGEpLmdldEJ5dGVzKCkpLAogICAgICAgIC8vIGNvbnRlbnQKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFsKICAgICAgICAgIGFzbjEuY3JlYXRlKAogICAgICAgICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLCBmYWxzZSwKICAgICAgICAgICAgYXNuMS50b0RlcihrZXlTYWZlQ29udGVudHMpLmdldEJ5dGVzKCkpCiAgICAgICAgXSkKICAgICAgXSk7CiAgICBjb250ZW50cy5wdXNoKGtleUNJKTsKICB9CgogIC8vIGNyZWF0ZSBBdXRoZW50aWNhdGVkU2FmZSBieSBzdHJpbmdpbmcgdG9nZXRoZXIgdGhlIGNvbnRlbnRzCiAgdmFyIHNhZmUgPSBhc24xLmNyZWF0ZSgKICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIGNvbnRlbnRzKTsKCiAgdmFyIG1hY0RhdGE7CiAgaWYob3B0aW9ucy51c2VNYWMpIHsKICAgIC8vIE1hY0RhdGEKICAgIHZhciBzaGExID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICAgIHZhciBtYWNTYWx0ID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigKICAgICAgZm9yZ2UucmFuZG9tLmdldEJ5dGVzKG9wdGlvbnMuc2FsdFNpemUpKTsKICAgIHZhciBjb3VudCA9IG9wdGlvbnMuY291bnQ7CiAgICAvLyAxNjAtYml0IGtleQogICAgdmFyIGtleSA9IHAxMi5nZW5lcmF0ZUtleShwYXNzd29yZCwgbWFjU2FsdCwgMywgY291bnQsIDIwKTsKICAgIHZhciBtYWMgPSBmb3JnZS5obWFjLmNyZWF0ZSgpOwogICAgbWFjLnN0YXJ0KHNoYTEsIGtleSk7CiAgICBtYWMudXBkYXRlKGFzbjEudG9EZXIoc2FmZSkuZ2V0Qnl0ZXMoKSk7CiAgICB2YXIgbWFjVmFsdWUgPSBtYWMuZ2V0TWFjKCk7CiAgICBtYWNEYXRhID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAvLyBtYWMgRGlnZXN0SW5mbwogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgLy8gZGlnZXN0QWxnb3JpdGhtCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgICAgLy8gYWxnb3JpdGhtID0gU0hBLTEKICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5zaGExKS5nZXRCeXRlcygpKSwKICAgICAgICAgIC8vIHBhcmFtZXRlcnMgPSBOdWxsCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgICAgICBdKSwKICAgICAgICAvLyBkaWdlc3QKICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsCiAgICAgICAgICBmYWxzZSwgbWFjVmFsdWUuZ2V0Qnl0ZXMoKSkKICAgICAgXSksCiAgICAgIC8vIG1hY1NhbHQgT0NURVQgU1RSSU5HCiAgICAgIGFzbjEuY3JlYXRlKAogICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLCBtYWNTYWx0LmdldEJ5dGVzKCkpLAogICAgICAvLyBpdGVyYXRpb25zIElOVEVHRVIgKFhYWDogT25seSBzdXBwb3J0IGNvdW50IDwgNjU1MzYpCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIoY291bnQpLmdldEJ5dGVzKCkKICAgICAgKQogICAgXSk7CiAgfQoKICAvLyBQRlgKICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgLy8gdmVyc2lvbiAoMykKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgIGFzbjEuaW50ZWdlclRvRGVyKDMpLmdldEJ5dGVzKCkpLAogICAgLy8gUEtDUyM3IENvbnRlbnRJbmZvCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIGNvbnRlbnRUeXBlCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAvLyBPSUQgZm9yIHRoZSBjb250ZW50IHR5cGUgaXMgJ2RhdGEnCiAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5kYXRhKS5nZXRCeXRlcygpKSwKICAgICAgLy8gY29udGVudAogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFsKICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLAogICAgICAgICAgYXNuMS50b0RlcihzYWZlKS5nZXRCeXRlcygpKQogICAgICBdKQogICAgXSksCiAgICBtYWNEYXRhCiAgXSk7Cn07CgovKioKICogRGVyaXZlcyBhIFBLQ1MjMTIga2V5LgogKgogKiBAcGFyYW0gcGFzc3dvcmQgdGhlIHBhc3N3b3JkIHRvIGRlcml2ZSB0aGUga2V5IG1hdGVyaWFsIGZyb20sIG51bGwgb3IKICogICAgICAgICAgdW5kZWZpbmVkIGZvciBub25lLgogKiBAcGFyYW0gc2FsdCB0aGUgc2FsdCwgYXMgYSBCeXRlQnVmZmVyLCB0byB1c2UuCiAqIEBwYXJhbSBpZCB0aGUgUEtDUyMxMiBJRCBieXRlICgxID0ga2V5IG1hdGVyaWFsLCAyID0gSVYsIDMgPSBNQUMpLgogKiBAcGFyYW0gaXRlciB0aGUgaXRlcmF0aW9uIGNvdW50LgogKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGRlcml2ZSBmcm9tIHRoZSBwYXNzd29yZC4KICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCB0byB1c2UsIGRlZmF1bHRzIHRvIFNIQS0xLgogKgogKiBAcmV0dXJuIGEgQnl0ZUJ1ZmZlciB3aXRoIHRoZSBieXRlcyBkZXJpdmVkIGZyb20gdGhlIHBhc3N3b3JkLgogKi8KcDEyLmdlbmVyYXRlS2V5ID0gZm9yZ2UucGJlLmdlbmVyYXRlUGtjczEyS2V5OwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAncGtjczEyJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3BrY3MxMicsWwogICdyZXF1aXJlJywKICAnbW9kdWxlJywKICAnLi9hc24xJywKICAnLi9obWFjJywKICAnLi9vaWRzJywKICAnLi9wa2NzN2FzbjEnLAogICcuL3BiZScsCiAgJy4vcmFuZG9tJywKICAnLi9yc2EnLAogICcuL3NoYTEnLAogICcuL3V0aWwnLAogICcuL3g1MDknCl0sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIEphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgYSBiYXNpYyBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLCBpbmNsdWRpbmcKICogc3VwcG9ydCBmb3IgUlNBIHB1YmxpYyBhbmQgcHJpdmF0ZSBrZXlzLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxMyBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8vIHNob3J0Y3V0IGZvciBhc24uMSBBUEkKdmFyIGFzbjEgPSBmb3JnZS5hc24xOwoKLyogUHVibGljIEtleSBJbmZyYXN0cnVjdHVyZSAoUEtJKSBpbXBsZW1lbnRhdGlvbi4gKi8KdmFyIHBraSA9IGZvcmdlLnBraSA9IGZvcmdlLnBraSB8fCB7fTsKCi8qKgogKiBOT1RFOiBUSElTIE1FVEhPRCBJUyBERVBSRUNBVEVELiBVc2UgcGVtLmRlY29kZSgpIGluc3RlYWQuCiAqCiAqIENvbnZlcnRzIFBFTS1mb3JtYXR0ZWQgZGF0YSB0byBERVIuCiAqCiAqIEBwYXJhbSBwZW0gdGhlIFBFTS1mb3JtYXR0ZWQgZGF0YS4KICoKICogQHJldHVybiB0aGUgREVSLWZvcm1hdHRlZCBkYXRhLgogKi8KcGtpLnBlbVRvRGVyID0gZnVuY3Rpb24ocGVtKSB7CiAgdmFyIG1zZyA9IGZvcmdlLnBlbS5kZWNvZGUocGVtKVswXTsKICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IFBFTSB0byBERVI7IFBFTSBpcyBlbmNyeXB0ZWQuJyk7CiAgfQogIHJldHVybiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihtc2cuYm9keSk7Cn07CgovKioKICogQ29udmVydHMgYW4gUlNBIHByaXZhdGUga2V5IGZyb20gUEVNIGZvcm1hdC4KICoKICogQHBhcmFtIHBlbSB0aGUgUEVNLWZvcm1hdHRlZCBwcml2YXRlIGtleS4KICoKICogQHJldHVybiB0aGUgcHJpdmF0ZSBrZXkuCiAqLwpwa2kucHJpdmF0ZUtleUZyb21QZW0gPSBmdW5jdGlvbihwZW0pIHsKICB2YXIgbXNnID0gZm9yZ2UucGVtLmRlY29kZShwZW0pWzBdOwoKICBpZihtc2cudHlwZSAhPT0gJ1BSSVZBVEUgS0VZJyAmJiBtc2cudHlwZSAhPT0gJ1JTQSBQUklWQVRFIEtFWScpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ291bGQgbm90IGNvbnZlcnQgcHJpdmF0ZSBrZXkgZnJvbSBQRU07IFBFTSAnICsKICAgICAgJ2hlYWRlciB0eXBlIGlzIG5vdCAiUFJJVkFURSBLRVkiIG9yICJSU0EgUFJJVkFURSBLRVkiLicpOwogICAgZXJyb3IuaGVhZGVyVHlwZSA9IG1zZy50eXBlOwogICAgdGhyb3cgZXJyb3I7CiAgfQogIGlmKG1zZy5wcm9jVHlwZSAmJiBtc2cucHJvY1R5cGUudHlwZSA9PT0gJ0VOQ1JZUFRFRCcpIHsKICAgIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGNvbnZlcnQgcHJpdmF0ZSBrZXkgZnJvbSBQRU07IFBFTSBpcyBlbmNyeXB0ZWQuJyk7CiAgfQoKICAvLyBjb252ZXJ0IERFUiB0byBBU04uMSBvYmplY3QKICB2YXIgb2JqID0gYXNuMS5mcm9tRGVyKG1zZy5ib2R5KTsKCiAgcmV0dXJuIHBraS5wcml2YXRlS2V5RnJvbUFzbjEob2JqKTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhbiBSU0EgcHJpdmF0ZSBrZXkgdG8gUEVNIGZvcm1hdC4KICoKICogQHBhcmFtIGtleSB0aGUgcHJpdmF0ZSBrZXkuCiAqIEBwYXJhbSBtYXhsaW5lIHRoZSBtYXhpbXVtIGNoYXJhY3RlcnMgcGVyIGxpbmUsIGRlZmF1bHRzIHRvIDY0LgogKgogKiBAcmV0dXJuIHRoZSBQRU0tZm9ybWF0dGVkIHByaXZhdGUga2V5LgogKi8KcGtpLnByaXZhdGVLZXlUb1BlbSA9IGZ1bmN0aW9uKGtleSwgbWF4bGluZSkgewogIC8vIGNvbnZlcnQgdG8gQVNOLjEsIHRoZW4gREVSLCB0aGVuIFBFTS1lbmNvZGUKICB2YXIgbXNnID0gewogICAgdHlwZTogJ1JTQSBQUklWQVRFIEtFWScsCiAgICBib2R5OiBhc24xLnRvRGVyKHBraS5wcml2YXRlS2V5VG9Bc24xKGtleSkpLmdldEJ5dGVzKCkKICB9OwogIHJldHVybiBmb3JnZS5wZW0uZW5jb2RlKG1zZywge21heGxpbmU6IG1heGxpbmV9KTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhIFByaXZhdGVLZXlJbmZvIHRvIFBFTSBmb3JtYXQuCiAqCiAqIEBwYXJhbSBwa2kgdGhlIFByaXZhdGVLZXlJbmZvLgogKiBAcGFyYW0gbWF4bGluZSB0aGUgbWF4aW11bSBjaGFyYWN0ZXJzIHBlciBsaW5lLCBkZWZhdWx0cyB0byA2NC4KICoKICogQHJldHVybiB0aGUgUEVNLWZvcm1hdHRlZCBwcml2YXRlIGtleS4KICovCnBraS5wcml2YXRlS2V5SW5mb1RvUGVtID0gZnVuY3Rpb24ocGtpLCBtYXhsaW5lKSB7CiAgLy8gY29udmVydCB0byBERVIsIHRoZW4gUEVNLWVuY29kZQogIHZhciBtc2cgPSB7CiAgICB0eXBlOiAnUFJJVkFURSBLRVknLAogICAgYm9keTogYXNuMS50b0Rlcihwa2kpLmdldEJ5dGVzKCkKICB9OwogIHJldHVybiBmb3JnZS5wZW0uZW5jb2RlKG1zZywge21heGxpbmU6IG1heGxpbmV9KTsKfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3BraSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9wa2knLFsKICAncmVxdWlyZScsCiAgJ21vZHVsZScsCiAgJy4vYXNuMScsCiAgJy4vb2lkcycsCiAgJy4vcGJlJywKICAnLi9wZW0nLAogICcuL3Bia2RmMicsCiAgJy4vcGtjczEyJywKICAnLi9wc3MnLAogICcuL3JzYScsCiAgJy4vdXRpbCcsCiAgJy4veDUwOScKXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogQSBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIFRyYW5zcG9ydCBMYXllciBTZWN1cml0eSAoVExTKS4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDA5LTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICoKICogVGhlIFRMUyBIYW5kc2hha2UgUHJvdG9jb2wgaW52b2x2ZXMgdGhlIGZvbGxvd2luZyBzdGVwczoKICoKICogLSBFeGNoYW5nZSBoZWxsbyBtZXNzYWdlcyB0byBhZ3JlZSBvbiBhbGdvcml0aG1zLCBleGNoYW5nZSByYW5kb20gdmFsdWVzLAogKiBhbmQgY2hlY2sgZm9yIHNlc3Npb24gcmVzdW1wdGlvbi4KICoKICogLSBFeGNoYW5nZSB0aGUgbmVjZXNzYXJ5IGNyeXB0b2dyYXBoaWMgcGFyYW1ldGVycyB0byBhbGxvdyB0aGUgY2xpZW50IGFuZAogKiBzZXJ2ZXIgdG8gYWdyZWUgb24gYSBwcmVtYXN0ZXIgc2VjcmV0LgogKgogKiAtIEV4Y2hhbmdlIGNlcnRpZmljYXRlcyBhbmQgY3J5cHRvZ3JhcGhpYyBpbmZvcm1hdGlvbiB0byBhbGxvdyB0aGUgY2xpZW50CiAqIGFuZCBzZXJ2ZXIgdG8gYXV0aGVudGljYXRlIHRoZW1zZWx2ZXMuCiAqCiAqIC0gR2VuZXJhdGUgYSBtYXN0ZXIgc2VjcmV0IGZyb20gdGhlIHByZW1hc3RlciBzZWNyZXQgYW5kIGV4Y2hhbmdlZCByYW5kb20KICogdmFsdWVzLgogKgogKiAtIFByb3ZpZGUgc2VjdXJpdHkgcGFyYW1ldGVycyB0byB0aGUgcmVjb3JkIGxheWVyLgogKgogKiAtIEFsbG93IHRoZSBjbGllbnQgYW5kIHNlcnZlciB0byB2ZXJpZnkgdGhhdCB0aGVpciBwZWVyIGhhcyBjYWxjdWxhdGVkIHRoZQogKiBzYW1lIHNlY3VyaXR5IHBhcmFtZXRlcnMgYW5kIHRoYXQgdGhlIGhhbmRzaGFrZSBvY2N1cnJlZCB3aXRob3V0IHRhbXBlcmluZwogKiBieSBhbiBhdHRhY2tlci4KICoKICogVXAgdG8gNCBkaWZmZXJlbnQgbWVzc2FnZXMgbWF5IGJlIHNlbnQgZHVyaW5nIGEga2V5IGV4Y2hhbmdlLiBUaGUgc2VydmVyCiAqIGNlcnRpZmljYXRlLCB0aGUgc2VydmVyIGtleSBleGNoYW5nZSwgdGhlIGNsaWVudCBjZXJ0aWZpY2F0ZSwgYW5kIHRoZQogKiBjbGllbnQga2V5IGV4Y2hhbmdlLgogKgogKiBBIHR5cGljYWwgaGFuZHNoYWtlIChmcm9tIHRoZSBjbGllbnQncyBwZXJzcGVjdGl2ZSkuCiAqCiAqIDEuIENsaWVudCBzZW5kcyBDbGllbnRIZWxsby4KICogMi4gQ2xpZW50IHJlY2VpdmVzIFNlcnZlckhlbGxvLgogKiAzLiBDbGllbnQgcmVjZWl2ZXMgb3B0aW9uYWwgQ2VydGlmaWNhdGUuCiAqIDQuIENsaWVudCByZWNlaXZlcyBvcHRpb25hbCBTZXJ2ZXJLZXlFeGNoYW5nZS4KICogNS4gQ2xpZW50IHJlY2VpdmVzIFNlcnZlckhlbGxvRG9uZS4KICogNi4gQ2xpZW50IHNlbmRzIG9wdGlvbmFsIENlcnRpZmljYXRlLgogKiA3LiBDbGllbnQgc2VuZHMgQ2xpZW50S2V5RXhjaGFuZ2UuCiAqIDguIENsaWVudCBzZW5kcyBvcHRpb25hbCBDZXJ0aWZpY2F0ZVZlcmlmeS4KICogOS4gQ2xpZW50IHNlbmRzIENoYW5nZUNpcGhlclNwZWMuCiAqIDEwLiBDbGllbnQgc2VuZHMgRmluaXNoZWQuCiAqIDExLiBDbGllbnQgcmVjZWl2ZXMgQ2hhbmdlQ2lwaGVyU3BlYy4KICogMTIuIENsaWVudCByZWNlaXZlcyBGaW5pc2hlZC4KICogMTMuIENsaWVudCBzZW5kcy9yZWNlaXZlcyBhcHBsaWNhdGlvbiBkYXRhLgogKgogKiBUbyByZXVzZSBhbiBleGlzdGluZyBzZXNzaW9uOgogKgogKiAxLiBDbGllbnQgc2VuZHMgQ2xpZW50SGVsbG8gd2l0aCBzZXNzaW9uIElEIGZvciByZXVzZS4KICogMi4gQ2xpZW50IHJlY2VpdmVzIFNlcnZlckhlbGxvIHdpdGggc2FtZSBzZXNzaW9uIElEIGlmIHJldXNpbmcuCiAqIDMuIENsaWVudCByZWNlaXZlcyBDaGFuZ2VDaXBoZXJTcGVjIG1lc3NhZ2UgaWYgcmV1c2luZy4KICogNC4gQ2xpZW50IHJlY2VpdmVzIEZpbmlzaGVkLgogKiA1LiBDbGllbnQgc2VuZHMgQ2hhbmdlQ2lwaGVyU3BlYy4KICogNi4gQ2xpZW50IHNlbmRzIEZpbmlzaGVkLgogKgogKiBOb3RlOiBDbGllbnQgaWdub3JlcyBIZWxsb1JlcXVlc3QgaWYgaW4gdGhlIG1pZGRsZSBvZiBhIGhhbmRzaGFrZS4KICoKICogUmVjb3JkIExheWVyOgogKgogKiBUaGUgcmVjb3JkIGxheWVyIGZyYWdtZW50cyBpbmZvcm1hdGlvbiBibG9ja3MgaW50byBUTFNQbGFpbnRleHQgcmVjb3JkcwogKiBjYXJyeWluZyBkYXRhIGluIGNodW5rcyBvZiAyXjE0IGJ5dGVzIG9yIGxlc3MuIENsaWVudCBtZXNzYWdlIGJvdW5kYXJpZXMgYXJlCiAqIG5vdCBwcmVzZXJ2ZWQgaW4gdGhlIHJlY29yZCBsYXllciAoaS5lLiwgbXVsdGlwbGUgY2xpZW50IG1lc3NhZ2VzIG9mIHRoZQogKiBzYW1lIENvbnRlbnRUeXBlIE1BWSBiZSBjb2FsZXNjZWQgaW50byBhIHNpbmdsZSBUTFNQbGFpbnRleHQgcmVjb3JkLCBvciBhCiAqIHNpbmdsZSBtZXNzYWdlIE1BWSBiZSBmcmFnbWVudGVkIGFjcm9zcyBzZXZlcmFsIHJlY29yZHMpLgogKgogKiBzdHJ1Y3QgewogKiAgIHVpbnQ4IG1ham9yOwogKiAgIHVpbnQ4IG1pbm9yOwogKiB9IFByb3RvY29sVmVyc2lvbjsKICoKICogc3RydWN0IHsKICogICBDb250ZW50VHlwZSB0eXBlOwogKiAgIFByb3RvY29sVmVyc2lvbiB2ZXJzaW9uOwogKiAgIHVpbnQxNiBsZW5ndGg7CiAqICAgb3BhcXVlIGZyYWdtZW50W1RMU1BsYWludGV4dC5sZW5ndGhdOwogKiB9IFRMU1BsYWludGV4dDsKICoKICogdHlwZToKICogICBUaGUgaGlnaGVyLWxldmVsIHByb3RvY29sIHVzZWQgdG8gcHJvY2VzcyB0aGUgZW5jbG9zZWQgZnJhZ21lbnQuCiAqCiAqIHZlcnNpb246CiAqICAgVGhlIHZlcnNpb24gb2YgdGhlIHByb3RvY29sIGJlaW5nIGVtcGxveWVkLiBUTFMgVmVyc2lvbiAxLjIgdXNlcyB2ZXJzaW9uCiAqICAgezMsIDN9LiBUTFMgVmVyc2lvbiAxLjAgdXNlcyB2ZXJzaW9uIHszLCAxfS4gTm90ZSB0aGF0IGEgY2xpZW50IHRoYXQKICogICBzdXBwb3J0cyBtdWx0aXBsZSB2ZXJzaW9ucyBvZiBUTFMgbWF5IG5vdCBrbm93IHdoYXQgdmVyc2lvbiB3aWxsIGJlCiAqICAgZW1wbG95ZWQgYmVmb3JlIGl0IHJlY2VpdmVzIHRoZSBTZXJ2ZXJIZWxsby4KICoKICogbGVuZ3RoOgogKiAgIFRoZSBsZW5ndGggKGluIGJ5dGVzKSBvZiB0aGUgZm9sbG93aW5nIFRMU1BsYWludGV4dC5mcmFnbWVudC4gVGhlIGxlbmd0aAogKiAgIE1VU1QgTk9UIGV4Y2VlZCAyXjE0ID0gMTYzODQgYnl0ZXMuCiAqCiAqIGZyYWdtZW50OgogKiAgIFRoZSBhcHBsaWNhdGlvbiBkYXRhLiBUaGlzIGRhdGEgaXMgdHJhbnNwYXJlbnQgYW5kIHRyZWF0ZWQgYXMgYW4KICogICBpbmRlcGVuZGVudCBibG9jayB0byBiZSBkZWFsdCB3aXRoIGJ5IHRoZSBoaWdoZXItbGV2ZWwgcHJvdG9jb2wgc3BlY2lmaWVkCiAqICAgYnkgdGhlIHR5cGUgZmllbGQuCiAqCiAqIEltcGxlbWVudGF0aW9ucyBNVVNUIE5PVCBzZW5kIHplcm8tbGVuZ3RoIGZyYWdtZW50cyBvZiBIYW5kc2hha2UsIEFsZXJ0LCBvcgogKiBDaGFuZ2VDaXBoZXJTcGVjIGNvbnRlbnQgdHlwZXMuIFplcm8tbGVuZ3RoIGZyYWdtZW50cyBvZiBBcHBsaWNhdGlvbiBkYXRhCiAqIE1BWSBiZSBzZW50IGFzIHRoZXkgYXJlIHBvdGVudGlhbGx5IHVzZWZ1bCBhcyBhIHRyYWZmaWMgYW5hbHlzaXMKICogY291bnRlcm1lYXN1cmUuCiAqCiAqIE5vdGU6IERhdGEgb2YgZGlmZmVyZW50IFRMUyByZWNvcmQgbGF5ZXIgY29udGVudCB0eXBlcyBNQVkgYmUgaW50ZXJsZWF2ZWQuCiAqIEFwcGxpY2F0aW9uIGRhdGEgaXMgZ2VuZXJhbGx5IG9mIGxvd2VyIHByZWNlZGVuY2UgZm9yIHRyYW5zbWlzc2lvbiB0aGFuCiAqIG90aGVyIGNvbnRlbnQgdHlwZXMuIEhvd2V2ZXIsIHJlY29yZHMgTVVTVCBiZSBkZWxpdmVyZWQgdG8gdGhlIG5ldHdvcmsgaW4KICogdGhlIHNhbWUgb3JkZXIgYXMgdGhleSBhcmUgcHJvdGVjdGVkIGJ5IHRoZSByZWNvcmQgbGF5ZXIuIFJlY2lwaWVudHMgTVVTVAogKiByZWNlaXZlIGFuZCBwcm9jZXNzIGludGVybGVhdmVkIGFwcGxpY2F0aW9uIGxheWVyIHRyYWZmaWMgZHVyaW5nIGhhbmRzaGFrZXMKICogc3Vic2VxdWVudCB0byB0aGUgZmlyc3Qgb25lIG9uIGEgY29ubmVjdGlvbi4KICoKICogc3RydWN0IHsKICogICBDb250ZW50VHlwZSB0eXBlOyAgICAgICAvLyBzYW1lIGFzIFRMU1BsYWludGV4dC50eXBlCiAqICAgUHJvdG9jb2xWZXJzaW9uIHZlcnNpb247Ly8gc2FtZSBhcyBUTFNQbGFpbnRleHQudmVyc2lvbgogKiAgIHVpbnQxNiBsZW5ndGg7CiAqICAgb3BhcXVlIGZyYWdtZW50W1RMU0NvbXByZXNzZWQubGVuZ3RoXTsKICogfSBUTFNDb21wcmVzc2VkOwogKgogKiBsZW5ndGg6CiAqICAgVGhlIGxlbmd0aCAoaW4gYnl0ZXMpIG9mIHRoZSBmb2xsb3dpbmcgVExTQ29tcHJlc3NlZC5mcmFnbWVudC4KICogICBUaGUgbGVuZ3RoIE1VU1QgTk9UIGV4Y2VlZCAyXjE0ICsgMTAyNC4KICoKICogZnJhZ21lbnQ6CiAqICAgVGhlIGNvbXByZXNzZWQgZm9ybSBvZiBUTFNQbGFpbnRleHQuZnJhZ21lbnQuCiAqCiAqIE5vdGU6IEEgQ29tcHJlc3Npb25NZXRob2QubnVsbCBvcGVyYXRpb24gaXMgYW4gaWRlbnRpdHkgb3BlcmF0aW9uOyBubyBmaWVsZHMKICogYXJlIGFsdGVyZWQuIEluIHRoaXMgaW1wbGVtZW50YXRpb24sIHNpbmNlIG5vIGNvbXByZXNzaW9uIGlzIHN1cHBvcnRlZCwKICogdW5jb21wcmVzc2VkIHJlY29yZHMgYXJlIGFsd2F5cyB0aGUgc2FtZSBhcyBjb21wcmVzc2VkIHJlY29yZHMuCiAqCiAqIEVuY3J5cHRpb24gSW5mb3JtYXRpb246CiAqCiAqIFRoZSBlbmNyeXB0aW9uIGFuZCBNQUMgZnVuY3Rpb25zIHRyYW5zbGF0ZSBhIFRMU0NvbXByZXNzZWQgc3RydWN0dXJlIGludG8gYQogKiBUTFNDaXBoZXJ0ZXh0LiBUaGUgZGVjcnlwdGlvbiBmdW5jdGlvbnMgcmV2ZXJzZSB0aGUgcHJvY2Vzcy4gVGhlIE1BQyBvZiB0aGUKICogcmVjb3JkIGFsc28gaW5jbHVkZXMgYSBzZXF1ZW5jZSBudW1iZXIgc28gdGhhdCBtaXNzaW5nLCBleHRyYSwgb3IgcmVwZWF0ZWQKICogbWVzc2FnZXMgYXJlIGRldGVjdGFibGUuCiAqCiAqIHN0cnVjdCB7CiAqICAgQ29udGVudFR5cGUgdHlwZTsKICogICBQcm90b2NvbFZlcnNpb24gdmVyc2lvbjsKICogICB1aW50MTYgbGVuZ3RoOwogKiAgIHNlbGVjdCAoU2VjdXJpdHlQYXJhbWV0ZXJzLmNpcGhlcl90eXBlKSB7CiAqICAgICBjYXNlIHN0cmVhbTogR2VuZXJpY1N0cmVhbUNpcGhlcjsKICogICAgIGNhc2UgYmxvY2s6ICBHZW5lcmljQmxvY2tDaXBoZXI7CiAqICAgICBjYXNlIGFlYWQ6ICAgR2VuZXJpY0FFQURDaXBoZXI7CiAqICAgfSBmcmFnbWVudDsKICogfSBUTFNDaXBoZXJ0ZXh0OwogKgogKiB0eXBlOgogKiAgIFRoZSB0eXBlIGZpZWxkIGlzIGlkZW50aWNhbCB0byBUTFNDb21wcmVzc2VkLnR5cGUuCiAqCiAqIHZlcnNpb246CiAqICAgVGhlIHZlcnNpb24gZmllbGQgaXMgaWRlbnRpY2FsIHRvIFRMU0NvbXByZXNzZWQudmVyc2lvbi4KICoKICogbGVuZ3RoOgogKiAgIFRoZSBsZW5ndGggKGluIGJ5dGVzKSBvZiB0aGUgZm9sbG93aW5nIFRMU0NpcGhlcnRleHQuZnJhZ21lbnQuCiAqICAgVGhlIGxlbmd0aCBNVVNUIE5PVCBleGNlZWQgMl4xNCArIDIwNDguCiAqCiAqIGZyYWdtZW50OgogKiAgIFRoZSBlbmNyeXB0ZWQgZm9ybSBvZiBUTFNDb21wcmVzc2VkLmZyYWdtZW50LCB3aXRoIHRoZSBNQUMuCiAqCiAqIE5vdGU6IE9ubHkgQ0JDIEJsb2NrIENpcGhlcnMgYXJlIHN1cHBvcnRlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uLgogKgogKiBUaGUgVExTQ29tcHJlc3NlZC5mcmFnbWVudCBzdHJ1Y3R1cmVzIGFyZSBjb252ZXJ0ZWQgdG8vZnJvbSBibG9jawogKiBUTFNDaXBoZXJ0ZXh0LmZyYWdtZW50IHN0cnVjdHVyZXMuCiAqCiAqIHN0cnVjdCB7CiAqICAgb3BhcXVlIElWW1NlY3VyaXR5UGFyYW1ldGVycy5yZWNvcmRfaXZfbGVuZ3RoXTsKICogICBibG9jay1jaXBoZXJlZCBzdHJ1Y3QgewogKiAgICAgb3BhcXVlIGNvbnRlbnRbVExTQ29tcHJlc3NlZC5sZW5ndGhdOwogKiAgICAgb3BhcXVlIE1BQ1tTZWN1cml0eVBhcmFtZXRlcnMubWFjX2xlbmd0aF07CiAqICAgICB1aW50OCBwYWRkaW5nW0dlbmVyaWNCbG9ja0NpcGhlci5wYWRkaW5nX2xlbmd0aF07CiAqICAgICB1aW50OCBwYWRkaW5nX2xlbmd0aDsKICogICB9OwogKiB9IEdlbmVyaWNCbG9ja0NpcGhlcjsKICoKICogVGhlIE1BQyBpcyBnZW5lcmF0ZWQgYXMgZGVzY3JpYmVkIGluIFNlY3Rpb24gNi4yLjMuMS4KICoKICogSVY6CiAqICAgVGhlIEluaXRpYWxpemF0aW9uIFZlY3RvciAoSVYpIFNIT1VMRCBiZSBjaG9zZW4gYXQgcmFuZG9tLCBhbmQgTVVTVCBiZQogKiAgIHVucHJlZGljdGFibGUuIE5vdGUgdGhhdCBpbiB2ZXJzaW9ucyBvZiBUTFMgcHJpb3IgdG8gMS4xLCB0aGVyZSB3YXMgbm8KICogICBJViBmaWVsZCwgYW5kIHRoZSBsYXN0IGNpcGhlcnRleHQgYmxvY2sgb2YgdGhlIHByZXZpb3VzIHJlY29yZCAodGhlICJDQkMKICogICByZXNpZHVlIikgd2FzIHVzZWQgYXMgdGhlIElWLiBUaGlzIHdhcyBjaGFuZ2VkIHRvIHByZXZlbnQgdGhlIGF0dGFja3MKICogICBkZXNjcmliZWQgaW4gW0NCQ0FUVF0uIEZvciBibG9jayBjaXBoZXJzLCB0aGUgSVYgbGVuZ3RoIGlzIG9mIGxlbmd0aAogKiAgIFNlY3VyaXR5UGFyYW1ldGVycy5yZWNvcmRfaXZfbGVuZ3RoLCB3aGljaCBpcyBlcXVhbCB0byB0aGUKICogICBTZWN1cml0eVBhcmFtZXRlcnMuYmxvY2tfc2l6ZS4KICoKICogcGFkZGluZzoKICogICBQYWRkaW5nIHRoYXQgaXMgYWRkZWQgdG8gZm9yY2UgdGhlIGxlbmd0aCBvZiB0aGUgcGxhaW50ZXh0IHRvIGJlIGFuCiAqICAgaW50ZWdyYWwgbXVsdGlwbGUgb2YgdGhlIGJsb2NrIGNpcGhlcidzIGJsb2NrIGxlbmd0aC4gVGhlIHBhZGRpbmcgTUFZIGJlCiAqICAgYW55IGxlbmd0aCB1cCB0byAyNTUgYnl0ZXMsIGFzIGxvbmcgYXMgaXQgcmVzdWx0cyBpbiB0aGUKICogICBUTFNDaXBoZXJ0ZXh0Lmxlbmd0aCBiZWluZyBhbiBpbnRlZ3JhbCBtdWx0aXBsZSBvZiB0aGUgYmxvY2sgbGVuZ3RoLgogKiAgIExlbmd0aHMgbG9uZ2VyIHRoYW4gbmVjZXNzYXJ5IG1pZ2h0IGJlIGRlc2lyYWJsZSB0byBmcnVzdHJhdGUgYXR0YWNrcyBvbgogKiAgIGEgcHJvdG9jb2wgdGhhdCBhcmUgYmFzZWQgb24gYW5hbHlzaXMgb2YgdGhlIGxlbmd0aHMgb2YgZXhjaGFuZ2VkCiAqICAgbWVzc2FnZXMuIEVhY2ggdWludDggaW4gdGhlIHBhZGRpbmcgZGF0YSB2ZWN0b3IgTVVTVCBiZSBmaWxsZWQgd2l0aCB0aGUKICogICBwYWRkaW5nIGxlbmd0aCB2YWx1ZS4gVGhlIHJlY2VpdmVyIE1VU1QgY2hlY2sgdGhpcyBwYWRkaW5nIGFuZCBNVVNUIHVzZQogKiAgIHRoZSBiYWRfcmVjb3JkX21hYyBhbGVydCB0byBpbmRpY2F0ZSBwYWRkaW5nIGVycm9ycy4KICoKICogcGFkZGluZ19sZW5ndGg6CiAqICAgVGhlIHBhZGRpbmcgbGVuZ3RoIE1VU1QgYmUgc3VjaCB0aGF0IHRoZSB0b3RhbCBzaXplIG9mIHRoZQogKiAgIEdlbmVyaWNCbG9ja0NpcGhlciBzdHJ1Y3R1cmUgaXMgYSBtdWx0aXBsZSBvZiB0aGUgY2lwaGVyJ3MgYmxvY2sgbGVuZ3RoLgogKiAgIExlZ2FsIHZhbHVlcyByYW5nZSBmcm9tIHplcm8gdG8gMjU1LCBpbmNsdXNpdmUuIFRoaXMgbGVuZ3RoIHNwZWNpZmllcyB0aGUKICogICBsZW5ndGggb2YgdGhlIHBhZGRpbmcgZmllbGQgZXhjbHVzaXZlIG9mIHRoZSBwYWRkaW5nX2xlbmd0aCBmaWVsZCBpdHNlbGYuCiAqCiAqIFRoZSBlbmNyeXB0ZWQgZGF0YSBsZW5ndGggKFRMU0NpcGhlcnRleHQubGVuZ3RoKSBpcyBvbmUgbW9yZSB0aGFuIHRoZSBzdW0gb2YKICogU2VjdXJpdHlQYXJhbWV0ZXJzLmJsb2NrX2xlbmd0aCwgVExTQ29tcHJlc3NlZC5sZW5ndGgsCiAqIFNlY3VyaXR5UGFyYW1ldGVycy5tYWNfbGVuZ3RoLCBhbmQgcGFkZGluZ19sZW5ndGguCiAqCiAqIEV4YW1wbGU6IElmIHRoZSBibG9jayBsZW5ndGggaXMgOCBieXRlcywgdGhlIGNvbnRlbnQgbGVuZ3RoCiAqIChUTFNDb21wcmVzc2VkLmxlbmd0aCkgaXMgNjEgYnl0ZXMsIGFuZCB0aGUgTUFDIGxlbmd0aCBpcyAyMCBieXRlcywgdGhlbiB0aGUKICogbGVuZ3RoIGJlZm9yZSBwYWRkaW5nIGlzIDgyIGJ5dGVzICh0aGlzIGRvZXMgbm90IGluY2x1ZGUgdGhlIElWLiBUaHVzLCB0aGUKICogcGFkZGluZyBsZW5ndGggbW9kdWxvIDggbXVzdCBiZSBlcXVhbCB0byA2IGluIG9yZGVyIHRvIG1ha2UgdGhlIHRvdGFsIGxlbmd0aAogKiBhbiBldmVuIG11bHRpcGxlIG9mIDggYnl0ZXMgKHRoZSBibG9jayBsZW5ndGgpLiBUaGUgcGFkZGluZyBsZW5ndGggY2FuIGJlCiAqIDYsIDE0LCAyMiwgYW5kIHNvIG9uLCB0aHJvdWdoIDI1NC4gSWYgdGhlIHBhZGRpbmcgbGVuZ3RoIHdlcmUgdGhlIG1pbmltdW0KICogbmVjZXNzYXJ5LCA2LCB0aGUgcGFkZGluZyB3b3VsZCBiZSA2IGJ5dGVzLCBlYWNoIGNvbnRhaW5pbmcgdGhlIHZhbHVlIDYuCiAqIFRodXMsIHRoZSBsYXN0IDggb2N0ZXRzIG9mIHRoZSBHZW5lcmljQmxvY2tDaXBoZXIgYmVmb3JlIGJsb2NrIGVuY3J5cHRpb24KICogd291bGQgYmUgeHggMDYgMDYgMDYgMDYgMDYgMDYgMDYsIHdoZXJlIHh4IGlzIHRoZSBsYXN0IG9jdGV0IG9mIHRoZSBNQUMuCiAqCiAqIE5vdGU6IFdpdGggYmxvY2sgY2lwaGVycyBpbiBDQkMgbW9kZSAoQ2lwaGVyIEJsb2NrIENoYWluaW5nKSwgaXQgaXMgY3JpdGljYWwKICogdGhhdCB0aGUgZW50aXJlIHBsYWludGV4dCBvZiB0aGUgcmVjb3JkIGJlIGtub3duIGJlZm9yZSBhbnkgY2lwaGVydGV4dCBpcwogKiB0cmFuc21pdHRlZC4gT3RoZXJ3aXNlLCBpdCBpcyBwb3NzaWJsZSBmb3IgdGhlIGF0dGFja2VyIHRvIG1vdW50IHRoZSBhdHRhY2sKICogZGVzY3JpYmVkIGluIFtDQkNBVFRdLgogKgogKiBJbXBsZW1lbnRhdGlvbiBub3RlOiBDYW52ZWwgZXQgYWwuIFtDQkNUSU1FXSBoYXZlIGRlbW9uc3RyYXRlZCBhIHRpbWluZwogKiBhdHRhY2sgb24gQ0JDIHBhZGRpbmcgYmFzZWQgb24gdGhlIHRpbWUgcmVxdWlyZWQgdG8gY29tcHV0ZSB0aGUgTUFDLiBJbgogKiBvcmRlciB0byBkZWZlbmQgYWdhaW5zdCB0aGlzIGF0dGFjaywgaW1wbGVtZW50YXRpb25zIE1VU1QgZW5zdXJlIHRoYXQKICogcmVjb3JkIHByb2Nlc3NpbmcgdGltZSBpcyBlc3NlbnRpYWxseSB0aGUgc2FtZSB3aGV0aGVyIG9yIG5vdCB0aGUgcGFkZGluZwogKiBpcyBjb3JyZWN0LiBJbiBnZW5lcmFsLCB0aGUgYmVzdCB3YXkgdG8gZG8gdGhpcyBpcyB0byBjb21wdXRlIHRoZSBNQUMgZXZlbgogKiBpZiB0aGUgcGFkZGluZyBpcyBpbmNvcnJlY3QsIGFuZCBvbmx5IHRoZW4gcmVqZWN0IHRoZSBwYWNrZXQuIEZvciBpbnN0YW5jZSwKICogaWYgdGhlIHBhZCBhcHBlYXJzIHRvIGJlIGluY29ycmVjdCwgdGhlIGltcGxlbWVudGF0aW9uIG1pZ2h0IGFzc3VtZSBhCiAqIHplcm8tbGVuZ3RoIHBhZCBhbmQgdGhlbiBjb21wdXRlIHRoZSBNQUMuIFRoaXMgbGVhdmVzIGEgc21hbGwgdGltaW5nCiAqIGNoYW5uZWwsIHNpbmNlIE1BQyBwZXJmb3JtYW5jZSBkZXBlbmRzLCB0byBzb21lIGV4dGVudCwgb24gdGhlIHNpemUgb2YgdGhlCiAqIGRhdGEgZnJhZ21lbnQsIGJ1dCBpdCBpcyBub3QgYmVsaWV2ZWQgdG8gYmUgbGFyZ2UgZW5vdWdoIHRvIGJlIGV4cGxvaXRhYmxlLAogKiBkdWUgdG8gdGhlIGxhcmdlIGJsb2NrIHNpemUgb2YgZXhpc3RpbmcgTUFDcyBhbmQgdGhlIHNtYWxsIHNpemUgb2YgdGhlCiAqIHRpbWluZyBzaWduYWwuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKLyoqCiAqIEdlbmVyYXRlcyBwc2V1ZG8gcmFuZG9tIGJ5dGVzIGJ5IG1peGluZyB0aGUgcmVzdWx0IG9mIHR3byBoYXNoIGZ1bmN0aW9ucywKICogTUQ1IGFuZCBTSEEtMS4KICoKICogcHJmX1RMUzEoc2VjcmV0LCBsYWJlbCwgc2VlZCkgPQogKiAgIFBfTUQ1KFMxLCBsYWJlbCArIHNlZWQpIFhPUiBQX1NIQS0xKFMyLCBsYWJlbCArIHNlZWQpOwogKgogKiBFYWNoIFBfaGFzaCBmdW5jdGlvbiBmdW5jdGlvbnMgYXMgZm9sbG93czoKICoKICogUF9oYXNoKHNlY3JldCwgc2VlZCkgPSBITUFDX2hhc2goc2VjcmV0LCBBKDEpICsgc2VlZCkgKwogKiAgICAgICAgICAgICAgICAgICAgICAgIEhNQUNfaGFzaChzZWNyZXQsIEEoMikgKyBzZWVkKSArCiAqICAgICAgICAgICAgICAgICAgICAgICAgSE1BQ19oYXNoKHNlY3JldCwgQSgzKSArIHNlZWQpICsgLi4uCiAqIEEoKSBpcyBkZWZpbmVkIGFzOgogKiAgIEEoMCkgPSBzZWVkCiAqICAgQShpKSA9IEhNQUNfaGFzaChzZWNyZXQsIEEoaS0xKSkKICoKICogVGhlICcrJyBvcGVyYXRvciBkZW5vdGVzIGNvbmNhdGVuYXRpb24uCiAqCiAqIEFzIG1hbnkgaXRlcmF0aW9ucyBBKE4pIGFzIGFyZSBuZWVkZWQgYXJlIHBlcmZvcm1lZCB0byBnZW5lcmF0ZSBlbm91Z2gKICogcHNldWRvIHJhbmRvbSBieXRlIG91dHB1dC4gSWYgYW4gaXRlcmF0aW9uIGNyZWF0ZXMgbW9yZSBkYXRhIHRoYW4gaXMKICogbmVjZXNzYXJ5LCB0aGVuIGl0IGlzIHRydW5jYXRlZC4KICoKICogVGhlcmVmb3JlOgogKiBBKDEpID0gSE1BQ19oYXNoKHNlY3JldCwgQSgwKSkKICogICAgICA9IEhNQUNfaGFzaChzZWNyZXQsIHNlZWQpCiAqIEEoMikgPSBITUFDX2hhc2goc2VjcmV0LCBBKDEpKQogKiAgICAgID0gSE1BQ19oYXNoKHNlY3JldCwgSE1BQ19oYXNoKHNlY3JldCwgc2VlZCkpCiAqCiAqIFRoZXJlZm9yZToKICogUF9oYXNoKHNlY3JldCwgc2VlZCkgPQogKiAgIEhNQUNfaGFzaChzZWNyZXQsIEhNQUNfaGFzaChzZWNyZXQsIEEoMCkpICsgc2VlZCkgKwogKiAgIEhNQUNfaGFzaChzZWNyZXQsIEhNQUNfaGFzaChzZWNyZXQsIEEoMSkpICsgc2VlZCkgKwogKiAgIC4uLgogKgogKiBUaGVyZWZvcmU6CiAqIFBfaGFzaChzZWNyZXQsIHNlZWQpID0KICogICBITUFDX2hhc2goc2VjcmV0LCBITUFDX2hhc2goc2VjcmV0LCBzZWVkKSArIHNlZWQpICsKICogICBITUFDX2hhc2goc2VjcmV0LCBITUFDX2hhc2goc2VjcmV0LCBITUFDX2hhc2goc2VjcmV0LCBzZWVkKSkgKyBzZWVkKSArCiAqICAgLi4uCiAqCiAqIEBwYXJhbSBzZWNyZXQgdGhlIHNlY3JldCB0byB1c2UuCiAqIEBwYXJhbSBsYWJlbCB0aGUgbGFiZWwgdG8gdXNlLgogKiBAcGFyYW0gc2VlZCB0aGUgc2VlZCB2YWx1ZSB0byB1c2UuCiAqIEBwYXJhbSBsZW5ndGggdGhlIG51bWJlciBvZiBieXRlcyB0byBnZW5lcmF0ZS4KICoKICogQHJldHVybiB0aGUgcHNldWRvIHJhbmRvbSBieXRlcyBpbiBhIGJ5dGUgYnVmZmVyLgogKi8KdmFyIHByZl9UTFMxID0gZnVuY3Rpb24oc2VjcmV0LCBsYWJlbCwgc2VlZCwgbGVuZ3RoKSB7CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwoKICAvKiBGb3IgVExTIDEuMCwgdGhlIHNlY3JldCBpcyBzcGxpdCBpbiBoYWxmLCBpbnRvIHR3byBzZWNyZXRzIG9mIGVxdWFsCiAgICBsZW5ndGguIElmIHRoZSBzZWNyZXQgaGFzIGFuIG9kZCBsZW5ndGggdGhlbiB0aGUgbGFzdCBieXRlIG9mIHRoZSBmaXJzdAogICAgaGFsZiB3aWxsIGJlIHRoZSBzYW1lIGFzIHRoZSBmaXJzdCBieXRlIG9mIHRoZSBzZWNvbmQuIFRoZSBsZW5ndGggb2YgdGhlCiAgICB0d28gc2VjcmV0cyBpcyBoYWxmIG9mIHRoZSBzZWNyZXQgcm91bmRlZCB1cC4gKi8KICB2YXIgaWR4ID0gKHNlY3JldC5sZW5ndGggPj4gMSk7CiAgdmFyIHNsZW4gPSBpZHggKyAoc2VjcmV0Lmxlbmd0aCAmIDEpOwogIHZhciBzMSA9IHNlY3JldC5zdWJzdHIoMCwgc2xlbik7CiAgdmFyIHMyID0gc2VjcmV0LnN1YnN0cihpZHgsIHNsZW4pOwogIHZhciBhaSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdmFyIGhtYWMgPSBmb3JnZS5obWFjLmNyZWF0ZSgpOwogIHNlZWQgPSBsYWJlbCArIHNlZWQ7CgogIC8vIGRldGVybWluZSB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMgdGhhdCBtdXN0IGJlIHBlcmZvcm1lZCB0byBnZW5lcmF0ZQogIC8vIGVub3VnaCBvdXRwdXQgYnl0ZXMsIG1kNSBjcmVhdGVzIDE2IGJ5dGUgaGFzaGVzLCBzaGExIGNyZWF0ZXMgMjAKICB2YXIgbWQ1aXRyID0gTWF0aC5jZWlsKGxlbmd0aCAvIDE2KTsKICB2YXIgc2hhMWl0ciA9IE1hdGguY2VpbChsZW5ndGggLyAyMCk7CgogIC8vIGRvIG1kNSBpdGVyYXRpb25zCiAgaG1hYy5zdGFydCgnTUQ1JywgczEpOwogIHZhciBtZDVieXRlcyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgYWkucHV0Qnl0ZXMoc2VlZCk7CiAgZm9yKHZhciBpID0gMDsgaSA8IG1kNWl0cjsgKytpKSB7CiAgICAvLyBITUFDX2hhc2goc2VjcmV0LCBBKGktMSkpCiAgICBobWFjLnN0YXJ0KG51bGwsIG51bGwpOwogICAgaG1hYy51cGRhdGUoYWkuZ2V0Qnl0ZXMoKSk7CiAgICBhaS5wdXRCdWZmZXIoaG1hYy5kaWdlc3QoKSk7CgogICAgLy8gSE1BQ19oYXNoKHNlY3JldCwgQShpKSArIHNlZWQpCiAgICBobWFjLnN0YXJ0KG51bGwsIG51bGwpOwogICAgaG1hYy51cGRhdGUoYWkuYnl0ZXMoKSArIHNlZWQpOwogICAgbWQ1Ynl0ZXMucHV0QnVmZmVyKGhtYWMuZGlnZXN0KCkpOwogIH0KCiAgLy8gZG8gc2hhMSBpdGVyYXRpb25zCiAgaG1hYy5zdGFydCgnU0hBMScsIHMyKTsKICB2YXIgc2hhMWJ5dGVzID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBhaS5jbGVhcigpOwogIGFpLnB1dEJ5dGVzKHNlZWQpOwogIGZvcih2YXIgaSA9IDA7IGkgPCBzaGExaXRyOyArK2kpIHsKICAgIC8vIEhNQUNfaGFzaChzZWNyZXQsIEEoaS0xKSkKICAgIGhtYWMuc3RhcnQobnVsbCwgbnVsbCk7CiAgICBobWFjLnVwZGF0ZShhaS5nZXRCeXRlcygpKTsKICAgIGFpLnB1dEJ1ZmZlcihobWFjLmRpZ2VzdCgpKTsKCiAgICAvLyBITUFDX2hhc2goc2VjcmV0LCBBKGkpICsgc2VlZCkKICAgIGhtYWMuc3RhcnQobnVsbCwgbnVsbCk7CiAgICBobWFjLnVwZGF0ZShhaS5ieXRlcygpICsgc2VlZCk7CiAgICBzaGExYnl0ZXMucHV0QnVmZmVyKGhtYWMuZGlnZXN0KCkpOwogIH0KCiAgLy8gWE9SIHRoZSBtZDUgYnl0ZXMgd2l0aCB0aGUgc2hhMSBieXRlcwogIHJ2YWwucHV0Qnl0ZXMoZm9yZ2UudXRpbC54b3JCeXRlcygKICAgIG1kNWJ5dGVzLmdldEJ5dGVzKCksIHNoYTFieXRlcy5nZXRCeXRlcygpLCBsZW5ndGgpKTsKCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2VuZXJhdGVzIHBzZXVkbyByYW5kb20gYnl0ZXMgdXNpbmcgYSBTSEEyNTYgYWxnb3JpdGhtLiBGb3IgVExTIDEuMi4KICoKICogQHBhcmFtIHNlY3JldCB0aGUgc2VjcmV0IHRvIHVzZS4KICogQHBhcmFtIGxhYmVsIHRoZSBsYWJlbCB0byB1c2UuCiAqIEBwYXJhbSBzZWVkIHRoZSBzZWVkIHZhbHVlIHRvIHVzZS4KICogQHBhcmFtIGxlbmd0aCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGdlbmVyYXRlLgogKgogKiBAcmV0dXJuIHRoZSBwc2V1ZG8gcmFuZG9tIGJ5dGVzIGluIGEgYnl0ZSBidWZmZXIuCiAqLwp2YXIgcHJmX3NoYTI1NiA9IGZ1bmN0aW9uKHNlY3JldCwgbGFiZWwsIHNlZWQsIGxlbmd0aCkgewogICAvLyBGSVhNRTogaW1wbGVtZW50IG1lIGZvciBUTFMgMS4yCn07CgovKioKICogR2V0cyBhIE1BQyBmb3IgYSByZWNvcmQgdXNpbmcgdGhlIFNIQS0xIGhhc2ggYWxnb3JpdGhtLgogKgogKiBAcGFyYW0ga2V5IHRoZSBtYWMga2V5LgogKiBAcGFyYW0gc3RhdGUgdGhlIHNlcXVlbmNlIG51bWJlciAoYXJyYXkgb2YgdHdvIDMyLWJpdCBpbnRlZ2VycykuCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICoKICogQHJldHVybiB0aGUgc2hhLTEgaGFzaCAoMjAgYnl0ZXMpIGZvciB0aGUgZ2l2ZW4gcmVjb3JkLgogKi8KdmFyIGhtYWNfc2hhMSA9IGZ1bmN0aW9uKGtleSwgc2VxTnVtLCByZWNvcmQpIHsKICAvKiBNQUMgaXMgY29tcHV0ZWQgbGlrZSBzbzoKICBITUFDX2hhc2goCiAgICBrZXksIHNlcU51bSArCiAgICAgIFRMU0NvbXByZXNzZWQudHlwZSArCiAgICAgIFRMU0NvbXByZXNzZWQudmVyc2lvbiArCiAgICAgIFRMU0NvbXByZXNzZWQubGVuZ3RoICsKICAgICAgVExTQ29tcHJlc3NlZC5mcmFnbWVudCkKICAqLwogIHZhciBobWFjID0gZm9yZ2UuaG1hYy5jcmVhdGUoKTsKICBobWFjLnN0YXJ0KCdTSEExJywga2V5KTsKICB2YXIgYiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgYi5wdXRJbnQzMihzZXFOdW1bMF0pOwogIGIucHV0SW50MzIoc2VxTnVtWzFdKTsKICBiLnB1dEJ5dGUocmVjb3JkLnR5cGUpOwogIGIucHV0Qnl0ZShyZWNvcmQudmVyc2lvbi5tYWpvcik7CiAgYi5wdXRCeXRlKHJlY29yZC52ZXJzaW9uLm1pbm9yKTsKICBiLnB1dEludDE2KHJlY29yZC5sZW5ndGgpOwogIGIucHV0Qnl0ZXMocmVjb3JkLmZyYWdtZW50LmJ5dGVzKCkpOwogIGhtYWMudXBkYXRlKGIuZ2V0Qnl0ZXMoKSk7CiAgcmV0dXJuIGhtYWMuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKfTsKCi8qKgogKiBDb21wcmVzc2VzIHRoZSBUTFNQbGFpbnRleHQgcmVjb3JkIGludG8gYSBUTFNDb21wcmVzc2VkIHJlY29yZCB1c2luZyB0aGUKICogZGVmbGF0ZSBhbGdvcml0aG0uCiAqCiAqIEBwYXJhbSBjIHRoZSBUTFMgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgVExTUGxhaW50ZXh0IHJlY29yZCB0byBjb21wcmVzcy4KICogQHBhcmFtIHMgdGhlIENvbm5lY3Rpb25TdGF0ZSB0byB1c2UuCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KdmFyIGRlZmxhdGUgPSBmdW5jdGlvbihjLCByZWNvcmQsIHMpIHsKICB2YXIgcnZhbCA9IGZhbHNlOwoKICB0cnkgewogICAgdmFyIGJ5dGVzID0gYy5kZWZsYXRlKHJlY29yZC5mcmFnbWVudC5nZXRCeXRlcygpKTsKICAgIHJlY29yZC5mcmFnbWVudCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGJ5dGVzKTsKICAgIHJlY29yZC5sZW5ndGggPSBieXRlcy5sZW5ndGg7CiAgICBydmFsID0gdHJ1ZTsKICB9IGNhdGNoKGV4KSB7CiAgICAvLyBkZWZsYXRlIGVycm9yLCBmYWlsIG91dAogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogRGVjb21wcmVzc2VzIHRoZSBUTFNDb21wcmVzc2VkIHJlY29yZCBpbnRvIGEgVExTUGxhaW50ZXh0IHJlY29yZCB1c2luZyB0aGUKICogZGVmbGF0ZSBhbGdvcml0aG0uCiAqCiAqIEBwYXJhbSBjIHRoZSBUTFMgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgVExTQ29tcHJlc3NlZCByZWNvcmQgdG8gZGVjb21wcmVzcy4KICogQHBhcmFtIHMgdGhlIENvbm5lY3Rpb25TdGF0ZSB0byB1c2UuCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KdmFyIGluZmxhdGUgPSBmdW5jdGlvbihjLCByZWNvcmQsIHMpIHsKICB2YXIgcnZhbCA9IGZhbHNlOwoKICB0cnkgewogICAgdmFyIGJ5dGVzID0gYy5pbmZsYXRlKHJlY29yZC5mcmFnbWVudC5nZXRCeXRlcygpKTsKICAgIHJlY29yZC5mcmFnbWVudCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGJ5dGVzKTsKICAgIHJlY29yZC5sZW5ndGggPSBieXRlcy5sZW5ndGg7CiAgICBydmFsID0gdHJ1ZTsKICB9IGNhdGNoKGV4KSB7CiAgICAvLyBpbmZsYXRlIGVycm9yLCBmYWlsIG91dAogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogUmVhZHMgYSBUTFMgdmFyaWFibGUtbGVuZ3RoIHZlY3RvciBmcm9tIGEgYnl0ZSBidWZmZXIuCiAqCiAqIFZhcmlhYmxlLWxlbmd0aCB2ZWN0b3JzIGFyZSBkZWZpbmVkIGJ5IHNwZWNpZnlpbmcgYSBzdWJyYW5nZSBvZiBsZWdhbAogKiBsZW5ndGhzLCBpbmNsdXNpdmVseSwgdXNpbmcgdGhlIG5vdGF0aW9uIDxmbG9vci4uY2VpbGluZz4uIFdoZW4gdGhlc2UgYXJlCiAqIGVuY29kZWQsIHRoZSBhY3R1YWwgbGVuZ3RoIHByZWNlZGVzIHRoZSB2ZWN0b3IncyBjb250ZW50cyBpbiB0aGUgYnl0ZQogKiBzdHJlYW0uIFRoZSBsZW5ndGggd2lsbCBiZSBpbiB0aGUgZm9ybSBvZiBhIG51bWJlciBjb25zdW1pbmcgYXMgbWFueSBieXRlcwogKiBhcyByZXF1aXJlZCB0byBob2xkIHRoZSB2ZWN0b3IncyBzcGVjaWZpZWQgbWF4aW11bSAoY2VpbGluZykgbGVuZ3RoLiBBCiAqIHZhcmlhYmxlLWxlbmd0aCB2ZWN0b3Igd2l0aCBhbiBhY3R1YWwgbGVuZ3RoIGZpZWxkIG9mIHplcm8gaXMgcmVmZXJyZWQgdG8KICogYXMgYW4gZW1wdHkgdmVjdG9yLgogKgogKiBAcGFyYW0gYiB0aGUgYnl0ZSBidWZmZXIuCiAqIEBwYXJhbSBsZW5CeXRlcyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkIHRvIHN0b3JlIHRoZSBsZW5ndGguCiAqCiAqIEByZXR1cm4gdGhlIHJlc3VsdGluZyBieXRlIGJ1ZmZlci4KICovCnZhciByZWFkVmVjdG9yID0gZnVuY3Rpb24oYiwgbGVuQnl0ZXMpIHsKICB2YXIgbGVuID0gMDsKICBzd2l0Y2gobGVuQnl0ZXMpIHsKICBjYXNlIDE6CiAgICBsZW4gPSBiLmdldEJ5dGUoKTsKICAgIGJyZWFrOwogIGNhc2UgMjoKICAgIGxlbiA9IGIuZ2V0SW50MTYoKTsKICAgIGJyZWFrOwogIGNhc2UgMzoKICAgIGxlbiA9IGIuZ2V0SW50MjQoKTsKICAgIGJyZWFrOwogIGNhc2UgNDoKICAgIGxlbiA9IGIuZ2V0SW50MzIoKTsKICAgIGJyZWFrOwogIH0KCiAgLy8gcmVhZCB2ZWN0b3IgYnl0ZXMgaW50byBhIG5ldyBidWZmZXIKICByZXR1cm4gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoYi5nZXRCeXRlcyhsZW4pKTsKfTsKCi8qKgogKiBXcml0ZXMgYSBUTFMgdmFyaWFibGUtbGVuZ3RoIHZlY3RvciB0byBhIGJ5dGUgYnVmZmVyLgogKgogKiBAcGFyYW0gYiB0aGUgYnl0ZSBidWZmZXIuCiAqIEBwYXJhbSBsZW5CeXRlcyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkIHRvIHN0b3JlIHRoZSBsZW5ndGguCiAqIEBwYXJhbSB2IHRoZSBieXRlIGJ1ZmZlciB2ZWN0b3IuCiAqLwp2YXIgd3JpdGVWZWN0b3IgPSBmdW5jdGlvbihiLCBsZW5CeXRlcywgdikgewogIC8vIGVuY29kZSBsZW5ndGggYXQgdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3IsIHdoZXJlIHRoZSBudW1iZXIgb2YgYnl0ZXMgZm9yCiAgLy8gdGhlIGxlbmd0aCBpcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgaXQgd291bGQgdGFrZSB0byBlbmNvZGUgdGhlCiAgLy8gdmVjdG9yJ3MgY2VpbGluZwogIGIucHV0SW50KHYubGVuZ3RoKCksIGxlbkJ5dGVzIDw8IDMpOwogIGIucHV0QnVmZmVyKHYpOwp9OwoKLyoqCiAqIFRoZSB0bHMgaW1wbGVtZW50YXRpb24uCiAqLwp2YXIgdGxzID0ge307CgovKioKICogVmVyc2lvbjogVExTIDEuMiA9IDMuMywgVExTIDEuMSA9IDMuMiwgVExTIDEuMCA9IDMuMS4gQm90aCBUTFMgMS4xIGFuZAogKiBUTFMgMS4yIHdlcmUgc3RpbGwgdG9vIG5ldyAoaWU6IG9wZW5TU0wgZGlkbid0IGltcGxlbWVudCB0aGVtKSBhdCB0aGUgdGltZQogKiBvZiB0aGlzIGltcGxlbWVudGF0aW9uIHNvIFRMUyAxLjAgd2FzIGltcGxlbWVudGVkIGluc3RlYWQuCiAqLwp0bHMuVmVyc2lvbnMgPSB7CiAgVExTXzFfMDoge21ham9yOiAzLCBtaW5vcjogMX0sCiAgVExTXzFfMToge21ham9yOiAzLCBtaW5vcjogMn0sCiAgVExTXzFfMjoge21ham9yOiAzLCBtaW5vcjogM30KfTsKdGxzLlN1cHBvcnRlZFZlcnNpb25zID0gWwogIHRscy5WZXJzaW9ucy5UTFNfMV8xLAogIHRscy5WZXJzaW9ucy5UTFNfMV8wCl07CnRscy5WZXJzaW9uID0gdGxzLlN1cHBvcnRlZFZlcnNpb25zWzBdOwoKLyoqCiAqIE1heGltdW0gZnJhZ21lbnQgc2l6ZS4gVHJ1ZSBtYXhpbXVtIGlzIDE2Mzg0LCBidXQgd2UgZnJhZ21lbnQgYmVmb3JlIHRoYXQKICogdG8gYWxsb3cgZm9yIHVudXN1YWwgc21hbGwgaW5jcmVhc2VzIGR1cmluZyBjb21wcmVzc2lvbi4KICovCnRscy5NYXhGcmFnbWVudCA9IDE2Mzg0IC0gMTAyNDsKCi8qKgogKiBXaGV0aGVyIHRoaXMgZW50aXR5IGlzIGNvbnNpZGVyZWQgdGhlICJjbGllbnQiIG9yICJzZXJ2ZXIiLgogKiBlbnVtIHsgc2VydmVyLCBjbGllbnQgfSBDb25uZWN0aW9uRW5kOwogKi8KdGxzLkNvbm5lY3Rpb25FbmQgPSB7CiAgc2VydmVyOiAwLAogIGNsaWVudDogMQp9OwoKLyoqCiAqIFBzZXVkby1yYW5kb20gZnVuY3Rpb24gYWxnb3JpdGhtIHVzZWQgdG8gZ2VuZXJhdGUga2V5cyBmcm9tIHRoZSBtYXN0ZXIKICogc2VjcmV0LgogKiBlbnVtIHsgdGxzX3ByZl9zaGEyNTYgfSBQUkZBbGdvcml0aG07CiAqLwp0bHMuUFJGQWxnb3JpdGhtID0gewogIHRsc19wcmZfc2hhMjU2OiAwCn07CgovKioKICogQnVsayBlbmNyeXB0aW9uIGFsZ29yaXRobXMuCiAqIGVudW0geyBudWxsLCByYzQsIGRlczMsIGFlcyB9IEJ1bGtDaXBoZXJBbGdvcml0aG07CiAqLwp0bHMuQnVsa0NpcGhlckFsZ29yaXRobSA9IHsKICBub25lOiBudWxsLAogIHJjNDogMCwKICBkZXMzOiAxLAogIGFlczogMgp9OwoKLyoqCiAqIENpcGhlciB0eXBlcy4KICogZW51bSB7IHN0cmVhbSwgYmxvY2ssIGFlYWQgfSBDaXBoZXJUeXBlOwogKi8KdGxzLkNpcGhlclR5cGUgPSB7CiAgc3RyZWFtOiAwLAogIGJsb2NrOiAxLAogIGFlYWQ6IDIKfTsKCi8qKgogKiBNQUMgKE1lc3NhZ2UgQXV0aGVudGljYXRpb24gQ29kZSkgYWxnb3JpdGhtcy4KICogZW51bSB7IG51bGwsIGhtYWNfbWQ1LCBobWFjX3NoYTEsIGhtYWNfc2hhMjU2LAogKiAgIGhtYWNfc2hhMzg0LCBobWFjX3NoYTUxMn0gTUFDQWxnb3JpdGhtOwogKi8KdGxzLk1BQ0FsZ29yaXRobSA9IHsKICBub25lOiBudWxsLAogIGhtYWNfbWQ1OiAwLAogIGhtYWNfc2hhMTogMSwKICBobWFjX3NoYTI1NjogMiwKICBobWFjX3NoYTM4NDogMywKICBobWFjX3NoYTUxMjogNAp9OwoKLyoqCiAqIENvbXByZXNzaW9uIGFsZ29yaXRobXMuCiAqIGVudW0geyBudWxsKDApLCBkZWZsYXRlKDEpLCAoMjU1KSB9IENvbXByZXNzaW9uTWV0aG9kOwogKi8KdGxzLkNvbXByZXNzaW9uTWV0aG9kID0gewogIG5vbmU6IDAsCiAgZGVmbGF0ZTogMQp9OwoKLyoqCiAqIFRMUyByZWNvcmQgY29udGVudCB0eXBlcy4KICogZW51bSB7CiAqICAgY2hhbmdlX2NpcGhlcl9zcGVjKDIwKSwgYWxlcnQoMjEpLCBoYW5kc2hha2UoMjIpLAogKiAgIGFwcGxpY2F0aW9uX2RhdGEoMjMpLCAoMjU1KQogKiB9IENvbnRlbnRUeXBlOwogKi8KdGxzLkNvbnRlbnRUeXBlID0gewogIGNoYW5nZV9jaXBoZXJfc3BlYzogMjAsCiAgYWxlcnQ6IDIxLAogIGhhbmRzaGFrZTogMjIsCiAgYXBwbGljYXRpb25fZGF0YTogMjMsCiAgaGVhcnRiZWF0OiAyNAp9OwoKLyoqCiAqIFRMUyBoYW5kc2hha2UgdHlwZXMuCiAqIGVudW0gewogKiAgIGhlbGxvX3JlcXVlc3QoMCksIGNsaWVudF9oZWxsbygxKSwgc2VydmVyX2hlbGxvKDIpLAogKiAgIGNlcnRpZmljYXRlKDExKSwgc2VydmVyX2tleV9leGNoYW5nZSAoMTIpLAogKiAgIGNlcnRpZmljYXRlX3JlcXVlc3QoMTMpLCBzZXJ2ZXJfaGVsbG9fZG9uZSgxNCksCiAqICAgY2VydGlmaWNhdGVfdmVyaWZ5KDE1KSwgY2xpZW50X2tleV9leGNoYW5nZSgxNiksCiAqICAgZmluaXNoZWQoMjApLCAoMjU1KQogKiB9IEhhbmRzaGFrZVR5cGU7CiAqLwp0bHMuSGFuZHNoYWtlVHlwZSA9IHsKICBoZWxsb19yZXF1ZXN0OiAwLAogIGNsaWVudF9oZWxsbzogMSwKICBzZXJ2ZXJfaGVsbG86IDIsCiAgY2VydGlmaWNhdGU6IDExLAogIHNlcnZlcl9rZXlfZXhjaGFuZ2U6IDEyLAogIGNlcnRpZmljYXRlX3JlcXVlc3Q6IDEzLAogIHNlcnZlcl9oZWxsb19kb25lOiAxNCwKICBjZXJ0aWZpY2F0ZV92ZXJpZnk6IDE1LAogIGNsaWVudF9rZXlfZXhjaGFuZ2U6IDE2LAogIGZpbmlzaGVkOiAyMAp9OwoKLyoqCiAqIFRMUyBBbGVydCBQcm90b2NvbC4KICoKICogZW51bSB7IHdhcm5pbmcoMSksIGZhdGFsKDIpLCAoMjU1KSB9IEFsZXJ0TGV2ZWw7CiAqCiAqIGVudW0gewogKiAgIGNsb3NlX25vdGlmeSgwKSwKICogICB1bmV4cGVjdGVkX21lc3NhZ2UoMTApLAogKiAgIGJhZF9yZWNvcmRfbWFjKDIwKSwKICogICBkZWNyeXB0aW9uX2ZhaWxlZCgyMSksCiAqICAgcmVjb3JkX292ZXJmbG93KDIyKSwKICogICBkZWNvbXByZXNzaW9uX2ZhaWx1cmUoMzApLAogKiAgIGhhbmRzaGFrZV9mYWlsdXJlKDQwKSwKICogICBiYWRfY2VydGlmaWNhdGUoNDIpLAogKiAgIHVuc3VwcG9ydGVkX2NlcnRpZmljYXRlKDQzKSwKICogICBjZXJ0aWZpY2F0ZV9yZXZva2VkKDQ0KSwKICogICBjZXJ0aWZpY2F0ZV9leHBpcmVkKDQ1KSwKICogICBjZXJ0aWZpY2F0ZV91bmtub3duKDQ2KSwKICogICBpbGxlZ2FsX3BhcmFtZXRlcig0NyksCiAqICAgdW5rbm93bl9jYSg0OCksCiAqICAgYWNjZXNzX2RlbmllZCg0OSksCiAqICAgZGVjb2RlX2Vycm9yKDUwKSwKICogICBkZWNyeXB0X2Vycm9yKDUxKSwKICogICBleHBvcnRfcmVzdHJpY3Rpb24oNjApLAogKiAgIHByb3RvY29sX3ZlcnNpb24oNzApLAogKiAgIGluc3VmZmljaWVudF9zZWN1cml0eSg3MSksCiAqICAgaW50ZXJuYWxfZXJyb3IoODApLAogKiAgIHVzZXJfY2FuY2VsZWQoOTApLAogKiAgIG5vX3JlbmVnb3RpYXRpb24oMTAwKSwKICogICAoMjU1KQogKiB9IEFsZXJ0RGVzY3JpcHRpb247CiAqCiAqIHN0cnVjdCB7CiAqICAgQWxlcnRMZXZlbCBsZXZlbDsKICogICBBbGVydERlc2NyaXB0aW9uIGRlc2NyaXB0aW9uOwogKiB9IEFsZXJ0OwogKi8KdGxzLkFsZXJ0ID0ge307CnRscy5BbGVydC5MZXZlbCA9IHsKICB3YXJuaW5nOiAxLAogIGZhdGFsOiAyCn07CnRscy5BbGVydC5EZXNjcmlwdGlvbiA9IHsKICBjbG9zZV9ub3RpZnk6IDAsCiAgdW5leHBlY3RlZF9tZXNzYWdlOiAxMCwKICBiYWRfcmVjb3JkX21hYzogMjAsCiAgZGVjcnlwdGlvbl9mYWlsZWQ6IDIxLAogIHJlY29yZF9vdmVyZmxvdzogMjIsCiAgZGVjb21wcmVzc2lvbl9mYWlsdXJlOiAzMCwKICBoYW5kc2hha2VfZmFpbHVyZTogNDAsCiAgYmFkX2NlcnRpZmljYXRlOiA0MiwKICB1bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZTogNDMsCiAgY2VydGlmaWNhdGVfcmV2b2tlZDogNDQsCiAgY2VydGlmaWNhdGVfZXhwaXJlZDogNDUsCiAgY2VydGlmaWNhdGVfdW5rbm93bjogNDYsCiAgaWxsZWdhbF9wYXJhbWV0ZXI6IDQ3LAogIHVua25vd25fY2E6IDQ4LAogIGFjY2Vzc19kZW5pZWQ6IDQ5LAogIGRlY29kZV9lcnJvcjogNTAsCiAgZGVjcnlwdF9lcnJvcjogNTEsCiAgZXhwb3J0X3Jlc3RyaWN0aW9uOiA2MCwKICBwcm90b2NvbF92ZXJzaW9uOiA3MCwKICBpbnN1ZmZpY2llbnRfc2VjdXJpdHk6IDcxLAogIGludGVybmFsX2Vycm9yOiA4MCwKICB1c2VyX2NhbmNlbGVkOiA5MCwKICBub19yZW5lZ290aWF0aW9uOiAxMDAKfTsKCi8qKgogKiBUTFMgSGVhcnRiZWF0IE1lc3NhZ2UgdHlwZXMuCiAqIGVudW0gewogKiAgIGhlYXJ0YmVhdF9yZXF1ZXN0KDEpLAogKiAgIGhlYXJ0YmVhdF9yZXNwb25zZSgyKSwKICogICAoMjU1KQogKiB9IEhlYXJ0YmVhdE1lc3NhZ2VUeXBlOwogKi8KdGxzLkhlYXJ0YmVhdE1lc3NhZ2VUeXBlID0gewogIGhlYXJ0YmVhdF9yZXF1ZXN0OiAxLAogIGhlYXJ0YmVhdF9yZXNwb25zZTogMgp9OwoKLyoqCiAqIFN1cHBvcnRlZCBjaXBoZXIgc3VpdGVzLgogKi8KdGxzLkNpcGhlclN1aXRlcyA9IHt9OwoKLyoqCiAqIEdldHMgYSBzdXBwb3J0ZWQgY2lwaGVyIHN1aXRlIGZyb20gaXRzIDIgYnl0ZSBJRC4KICoKICogQHBhcmFtIHR3b0J5dGVzIHR3byBieXRlcyBpbiBhIHN0cmluZy4KICoKICogQHJldHVybiB0aGUgbWF0Y2hpbmcgc3VwcG9ydGVkIGNpcGhlciBzdWl0ZSBvciBudWxsLgogKi8KdGxzLmdldENpcGhlclN1aXRlID0gZnVuY3Rpb24odHdvQnl0ZXMpIHsKICB2YXIgcnZhbCA9IG51bGw7CiAgZm9yKHZhciBrZXkgaW4gdGxzLkNpcGhlclN1aXRlcykgewogICAgdmFyIGNzID0gdGxzLkNpcGhlclN1aXRlc1trZXldOwogICAgaWYoY3MuaWRbMF0gPT09IHR3b0J5dGVzLmNoYXJDb2RlQXQoMCkgJiYKICAgICAgY3MuaWRbMV0gPT09IHR3b0J5dGVzLmNoYXJDb2RlQXQoMSkpIHsKICAgICAgcnZhbCA9IGNzOwogICAgICBicmVhazsKICAgIH0KICB9CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ2FsbGVkIHdoZW4gYW4gdW5leHBlY3RlZCByZWNvcmQgaXMgZW5jb3VudGVyZWQuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gcmVjb3JkIHRoZSByZWNvcmQuCiAqLwp0bHMuaGFuZGxlVW5leHBlY3RlZCA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogIC8vIGlmIGNvbm5lY3Rpb24gaXMgY2xpZW50IGFuZCBjbG9zZWQsIGlnbm9yZSB1bmV4cGVjdGVkIG1lc3NhZ2VzCiAgdmFyIGlnbm9yZSA9ICghYy5vcGVuICYmIGMuZW50aXR5ID09PSB0bHMuQ29ubmVjdGlvbkVuZC5jbGllbnQpOwogIGlmKCFpZ25vcmUpIHsKICAgIGMuZXJyb3IoYywgewogICAgICBtZXNzYWdlOiAnVW5leHBlY3RlZCBtZXNzYWdlLiBSZWNlaXZlZCBUTFMgcmVjb3JkIG91dCBvZiBvcmRlci4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi51bmV4cGVjdGVkX21lc3NhZ2UKICAgICAgfQogICAgfSk7CiAgfQp9OwoKLyoqCiAqIENhbGxlZCB3aGVuIGEgY2xpZW50IHJlY2VpdmVzIGEgSGVsbG9SZXF1ZXN0IHJlY29yZC4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZS4KICovCnRscy5oYW5kbGVIZWxsb1JlcXVlc3QgPSBmdW5jdGlvbihjLCByZWNvcmQsIGxlbmd0aCkgewogIC8vIGlnbm9yZSByZW5lZ290aWF0aW9uIHJlcXVlc3RzIGZyb20gdGhlIHNlcnZlciBkdXJpbmcgYSBoYW5kc2hha2UsIGJ1dAogIC8vIGlmIGhhbmRzaGFraW5nLCBzZW5kIGEgd2FybmluZyBhbGVydCB0aGF0IHJlbmVnb3RhdGlvbiBpcyBkZW5pZWQKICBpZighYy5oYW5kc2hha2luZyAmJiBjLmhhbmRzaGFrZXMgPiAwKSB7CiAgICAvLyBzZW5kIGFsZXJ0IHdhcm5pbmcKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlQWxlcnQoYywgewogICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC53YXJuaW5nLAogICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5ub19yZW5lZ290aWF0aW9uCiAgICB9KSk7CiAgICB0bHMuZmx1c2goYyk7CiAgfQoKICAvLyBjb250aW51ZQogIGMucHJvY2VzcygpOwp9OwoKLyoqCiAqIFBhcnNlcyBhIGhlbGxvIG1lc3NhZ2UgZnJvbSBhIENsaWVudEhlbGxvIG9yIFNlcnZlckhlbGxvIHJlY29yZC4KICoKICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkIHRvIHBhcnNlLgogKgogKiBAcmV0dXJuIHRoZSBwYXJzZWQgbWVzc2FnZS4KICovCnRscy5wYXJzZUhlbGxvTWVzc2FnZSA9IGZ1bmN0aW9uKGMsIHJlY29yZCwgbGVuZ3RoKSB7CiAgdmFyIG1zZyA9IG51bGw7CgogIHZhciBjbGllbnQgPSAoYy5lbnRpdHkgPT09IHRscy5Db25uZWN0aW9uRW5kLmNsaWVudCk7CgogIC8vIG1pbmltdW0gb2YgMzggYnl0ZXMgaW4gbWVzc2FnZQogIGlmKGxlbmd0aCA8IDM4KSB7CiAgICBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogY2xpZW50ID8KICAgICAgICAnSW52YWxpZCBTZXJ2ZXJIZWxsbyBtZXNzYWdlLiBNZXNzYWdlIHRvbyBzaG9ydC4nIDoKICAgICAgICAnSW52YWxpZCBDbGllbnRIZWxsbyBtZXNzYWdlLiBNZXNzYWdlIHRvbyBzaG9ydC4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5pbGxlZ2FsX3BhcmFtZXRlcgogICAgICB9CiAgICB9KTsKICB9IGVsc2UgewogICAgLy8gdXNlICdyZW1haW5pbmcnIHRvIGNhbGN1bGF0ZSAjIG9mIHJlbWFpbmluZyBieXRlcyBpbiB0aGUgbWVzc2FnZQogICAgdmFyIGIgPSByZWNvcmQuZnJhZ21lbnQ7CiAgICB2YXIgcmVtYWluaW5nID0gYi5sZW5ndGgoKTsKICAgIG1zZyA9IHsKICAgICAgdmVyc2lvbjogewogICAgICAgIG1ham9yOiBiLmdldEJ5dGUoKSwKICAgICAgICBtaW5vcjogYi5nZXRCeXRlKCkKICAgICAgfSwKICAgICAgcmFuZG9tOiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihiLmdldEJ5dGVzKDMyKSksCiAgICAgIHNlc3Npb25faWQ6IHJlYWRWZWN0b3IoYiwgMSksCiAgICAgIGV4dGVuc2lvbnM6IFtdCiAgICB9OwogICAgaWYoY2xpZW50KSB7CiAgICAgIG1zZy5jaXBoZXJfc3VpdGUgPSBiLmdldEJ5dGVzKDIpOwogICAgICBtc2cuY29tcHJlc3Npb25fbWV0aG9kID0gYi5nZXRCeXRlKCk7CiAgICB9IGVsc2UgewogICAgICBtc2cuY2lwaGVyX3N1aXRlcyA9IHJlYWRWZWN0b3IoYiwgMik7CiAgICAgIG1zZy5jb21wcmVzc2lvbl9tZXRob2RzID0gcmVhZFZlY3RvcihiLCAxKTsKICAgIH0KCiAgICAvLyByZWFkIGV4dGVuc2lvbnMgaWYgdGhlcmUgYXJlIGFueSBieXRlcyBsZWZ0IGluIHRoZSBtZXNzYWdlCiAgICByZW1haW5pbmcgPSBsZW5ndGggLSAocmVtYWluaW5nIC0gYi5sZW5ndGgoKSk7CiAgICBpZihyZW1haW5pbmcgPiAwKSB7CiAgICAgIC8vIHBhcnNlIGV4dGVuc2lvbnMKICAgICAgdmFyIGV4dHMgPSByZWFkVmVjdG9yKGIsIDIpOwogICAgICB3aGlsZShleHRzLmxlbmd0aCgpID4gMCkgewogICAgICAgIG1zZy5leHRlbnNpb25zLnB1c2goewogICAgICAgICAgdHlwZTogW2V4dHMuZ2V0Qnl0ZSgpLCBleHRzLmdldEJ5dGUoKV0sCiAgICAgICAgICBkYXRhOiByZWFkVmVjdG9yKGV4dHMsIDIpCiAgICAgICAgfSk7CiAgICAgIH0KCiAgICAgIC8vIFRPRE86IG1ha2UgZXh0ZW5zaW9uIHN1cHBvcnQgbW9kdWxhcgogICAgICBpZighY2xpZW50KSB7CiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IG1zZy5leHRlbnNpb25zLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICB2YXIgZXh0ID0gbXNnLmV4dGVuc2lvbnNbaV07CgogICAgICAgICAgLy8gc3VwcG9ydCBTTkkgZXh0ZW5zaW9uCiAgICAgICAgICBpZihleHQudHlwZVswXSA9PT0gMHgwMCAmJiBleHQudHlwZVsxXSA9PT0gMHgwMCkgewogICAgICAgICAgICAvLyBnZXQgc2VydmVyIG5hbWUgbGlzdAogICAgICAgICAgICB2YXIgc25sID0gcmVhZFZlY3RvcihleHQuZGF0YSwgMik7CiAgICAgICAgICAgIHdoaWxlKHNubC5sZW5ndGgoKSA+IDApIHsKICAgICAgICAgICAgICAvLyByZWFkIHNlcnZlciBuYW1lIHR5cGUKICAgICAgICAgICAgICB2YXIgc25UeXBlID0gc25sLmdldEJ5dGUoKTsKCiAgICAgICAgICAgICAgLy8gb25seSBIb3N0TmFtZSB0eXBlICgweDAwKSBpcyBrbm93biwgYnJlYWsgb3V0IGlmCiAgICAgICAgICAgICAgLy8gYW5vdGhlciB0eXBlIGlzIGRldGVjdGVkCiAgICAgICAgICAgICAgaWYoc25UeXBlICE9PSAweDAwKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIGFkZCBob3N0IG5hbWUgdG8gc2VydmVyIG5hbWUgbGlzdAogICAgICAgICAgICAgIGMuc2Vzc2lvbi5leHRlbnNpb25zLnNlcnZlcl9uYW1lLnNlcnZlck5hbWVMaXN0LnB1c2goCiAgICAgICAgICAgICAgICByZWFkVmVjdG9yKHNubCwgMikuZ2V0Qnl0ZXMoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICAvLyB2ZXJzaW9uIGFscmVhZHkgc2V0LCBkbyBub3QgYWxsb3cgdmVyc2lvbiBjaGFuZ2UKICAgIGlmKGMuc2Vzc2lvbi52ZXJzaW9uKSB7CiAgICAgIGlmKG1zZy52ZXJzaW9uLm1ham9yICE9PSBjLnNlc3Npb24udmVyc2lvbi5tYWpvciB8fAogICAgICAgIG1zZy52ZXJzaW9uLm1pbm9yICE9PSBjLnNlc3Npb24udmVyc2lvbi5taW5vcikgewogICAgICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgICAgIG1lc3NhZ2U6ICdUTFMgdmVyc2lvbiBjaGFuZ2UgaXMgZGlzYWxsb3dlZCBkdXJpbmcgcmVuZWdvdGlhdGlvbi4nLAogICAgICAgICAgc2VuZDogdHJ1ZSwKICAgICAgICAgIGFsZXJ0OiB7CiAgICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiB0bHMuQWxlcnQuRGVzY3JpcHRpb24ucHJvdG9jb2xfdmVyc2lvbgogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICB9CiAgICB9CgogICAgLy8gZ2V0IHRoZSBjaG9zZW4gKFNlcnZlckhlbGxvKSBjaXBoZXIgc3VpdGUKICAgIGlmKGNsaWVudCkgewogICAgICAvLyBGSVhNRTogc2hvdWxkIGJlIGNoZWNraW5nIGNvbmZpZ3VyZWQgYWNjZXB0YWJsZSBjaXBoZXIgc3VpdGVzCiAgICAgIGMuc2Vzc2lvbi5jaXBoZXJTdWl0ZSA9IHRscy5nZXRDaXBoZXJTdWl0ZShtc2cuY2lwaGVyX3N1aXRlKTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIGdldCBhIHN1cHBvcnRlZCBwcmVmZXJyZWQgKENsaWVudEhlbGxvKSBjaXBoZXIgc3VpdGUKICAgICAgLy8gY2hvb3NlIHRoZSBmaXJzdCBzdXBwb3J0ZWQgY2lwaGVyIHN1aXRlCiAgICAgIHZhciB0bXAgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihtc2cuY2lwaGVyX3N1aXRlcy5ieXRlcygpKTsKICAgICAgd2hpbGUodG1wLmxlbmd0aCgpID4gMCkgewogICAgICAgIC8vIEZJWE1FOiBzaG91bGQgYmUgY2hlY2tpbmcgY29uZmlndXJlZCBhY2NlcHRhYmxlIHN1aXRlcwogICAgICAgIC8vIGNpcGhlciBzdWl0ZXMgdGFrZSB1cCAyIGJ5dGVzCiAgICAgICAgYy5zZXNzaW9uLmNpcGhlclN1aXRlID0gdGxzLmdldENpcGhlclN1aXRlKHRtcC5nZXRCeXRlcygyKSk7CiAgICAgICAgaWYoYy5zZXNzaW9uLmNpcGhlclN1aXRlICE9PSBudWxsKSB7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICAvLyBjaXBoZXIgc3VpdGUgbm90IHN1cHBvcnRlZAogICAgaWYoYy5zZXNzaW9uLmNpcGhlclN1aXRlID09PSBudWxsKSB7CiAgICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgICBtZXNzYWdlOiAnTm8gY2lwaGVyIHN1aXRlcyBpbiBjb21tb24uJywKICAgICAgICBzZW5kOiB0cnVlLAogICAgICAgIGFsZXJ0OiB7CiAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5oYW5kc2hha2VfZmFpbHVyZQogICAgICAgIH0sCiAgICAgICAgY2lwaGVyU3VpdGU6IGZvcmdlLnV0aWwuYnl0ZXNUb0hleChtc2cuY2lwaGVyX3N1aXRlKQogICAgICB9KTsKICAgIH0KCiAgICAvLyBUT0RPOiBoYW5kbGUgY29tcHJlc3Npb24gbWV0aG9kcwogICAgaWYoY2xpZW50KSB7CiAgICAgIGMuc2Vzc2lvbi5jb21wcmVzc2lvbk1ldGhvZCA9IG1zZy5jb21wcmVzc2lvbl9tZXRob2Q7CiAgICB9IGVsc2UgewogICAgICAvLyBubyBjb21wcmVzc2lvbgogICAgICBjLnNlc3Npb24uY29tcHJlc3Npb25NZXRob2QgPSB0bHMuQ29tcHJlc3Npb25NZXRob2Qubm9uZTsKICAgIH0KICB9CgogIHJldHVybiBtc2c7Cn07CgovKioKICogQ3JlYXRlcyBzZWN1cml0eSBwYXJhbWV0ZXJzIGZvciB0aGUgZ2l2ZW4gY29ubmVjdGlvbiBiYXNlZCBvbiB0aGUgZ2l2ZW4KICogaGVsbG8gbWVzc2FnZS4KICoKICogQHBhcmFtIGMgdGhlIFRMUyBjb25uZWN0aW9uLgogKiBAcGFyYW0gbXNnIHRoZSBoZWxsbyBtZXNzYWdlLgogKi8KdGxzLmNyZWF0ZVNlY3VyaXR5UGFyYW1ldGVycyA9IGZ1bmN0aW9uKGMsIG1zZykgewogIC8qIE5vdGU6IHNlY3VyaXR5IHBhcmFtcyBhcmUgZnJvbSBUTFMgMS4yLCBzb21lIHZhbHVlcyBsaWtlIHByZl9hbGdvcml0aG0KICBhcmUgaWdub3JlZCBmb3IgVExTIDEuMC8xLjEgYW5kIHRoZSBidWlsdGluIGFzIHNwZWNpZmllZCBpbiB0aGUgc3BlYyBpcwogIHVzZWQuICovCgogIC8vIFRPRE86IGhhbmRsZSBvdGhlciBvcHRpb25zIGZyb20gc2VydmVyIHdoZW4gbW9yZSBzdXBwb3J0ZWQKCiAgLy8gZ2V0IGNsaWVudCBhbmQgc2VydmVyIHJhbmRvbXMKICB2YXIgY2xpZW50ID0gKGMuZW50aXR5ID09PSB0bHMuQ29ubmVjdGlvbkVuZC5jbGllbnQpOwogIHZhciBtc2dSYW5kb20gPSBtc2cucmFuZG9tLmJ5dGVzKCk7CiAgdmFyIGNSYW5kb20gPSBjbGllbnQgPyBjLnNlc3Npb24uc3AuY2xpZW50X3JhbmRvbSA6IG1zZ1JhbmRvbTsKICB2YXIgc1JhbmRvbSA9IGNsaWVudCA/IG1zZ1JhbmRvbSA6IHRscy5jcmVhdGVSYW5kb20oKS5nZXRCeXRlcygpOwoKICAvLyBjcmVhdGUgbmV3IHNlY3VyaXR5IHBhcmFtZXRlcnMKICBjLnNlc3Npb24uc3AgPSB7CiAgICBlbnRpdHk6IGMuZW50aXR5LAogICAgcHJmX2FsZ29yaXRobTogdGxzLlBSRkFsZ29yaXRobS50bHNfcHJmX3NoYTI1NiwKICAgIGJ1bGtfY2lwaGVyX2FsZ29yaXRobTogbnVsbCwKICAgIGNpcGhlcl90eXBlOiBudWxsLAogICAgZW5jX2tleV9sZW5ndGg6IG51bGwsCiAgICBibG9ja19sZW5ndGg6IG51bGwsCiAgICBmaXhlZF9pdl9sZW5ndGg6IG51bGwsCiAgICByZWNvcmRfaXZfbGVuZ3RoOiBudWxsLAogICAgbWFjX2FsZ29yaXRobTogbnVsbCwKICAgIG1hY19sZW5ndGg6IG51bGwsCiAgICBtYWNfa2V5X2xlbmd0aDogbnVsbCwKICAgIGNvbXByZXNzaW9uX2FsZ29yaXRobTogYy5zZXNzaW9uLmNvbXByZXNzaW9uTWV0aG9kLAogICAgcHJlX21hc3Rlcl9zZWNyZXQ6IG51bGwsCiAgICBtYXN0ZXJfc2VjcmV0OiBudWxsLAogICAgY2xpZW50X3JhbmRvbTogY1JhbmRvbSwKICAgIHNlcnZlcl9yYW5kb206IHNSYW5kb20KICB9Owp9OwoKLyoqCiAqIENhbGxlZCB3aGVuIGEgY2xpZW50IHJlY2VpdmVzIGEgU2VydmVySGVsbG8gcmVjb3JkLgogKgogKiBXaGVuIGEgU2VydmVySGVsbG8gbWVzc2FnZSB3aWxsIGJlIHNlbnQ6CiAqICAgVGhlIHNlcnZlciB3aWxsIHNlbmQgdGhpcyBtZXNzYWdlIGluIHJlc3BvbnNlIHRvIGEgY2xpZW50IGhlbGxvIG1lc3NhZ2UKICogICB3aGVuIGl0IHdhcyBhYmxlIHRvIGZpbmQgYW4gYWNjZXB0YWJsZSBzZXQgb2YgYWxnb3JpdGhtcy4gSWYgaXQgY2Fubm90CiAqICAgZmluZCBzdWNoIGEgbWF0Y2gsIGl0IHdpbGwgcmVzcG9uZCB3aXRoIGEgaGFuZHNoYWtlIGZhaWx1cmUgYWxlcnQuCiAqCiAqIHVpbnQyNCBsZW5ndGg7CiAqIHN0cnVjdCB7CiAqICAgUHJvdG9jb2xWZXJzaW9uIHNlcnZlcl92ZXJzaW9uOwogKiAgIFJhbmRvbSByYW5kb207CiAqICAgU2Vzc2lvbklEIHNlc3Npb25faWQ7CiAqICAgQ2lwaGVyU3VpdGUgY2lwaGVyX3N1aXRlOwogKiAgIENvbXByZXNzaW9uTWV0aG9kIGNvbXByZXNzaW9uX21ldGhvZDsKICogICBzZWxlY3QoZXh0ZW5zaW9uc19wcmVzZW50KSB7CiAqICAgICBjYXNlIGZhbHNlOgogKiAgICAgICBzdHJ1Y3Qge307CiAqICAgICBjYXNlIHRydWU6CiAqICAgICAgIEV4dGVuc2lvbiBleHRlbnNpb25zPDAuLjJeMTYtMT47CiAqICAgfTsKICogfSBTZXJ2ZXJIZWxsbzsKICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZS4KICovCnRscy5oYW5kbGVTZXJ2ZXJIZWxsbyA9IGZ1bmN0aW9uKGMsIHJlY29yZCwgbGVuZ3RoKSB7CiAgdmFyIG1zZyA9IHRscy5wYXJzZUhlbGxvTWVzc2FnZShjLCByZWNvcmQsIGxlbmd0aCk7CiAgaWYoYy5mYWlsKSB7CiAgICByZXR1cm47CiAgfQoKICAvLyBlbnN1cmUgc2VydmVyIHZlcnNpb24gaXMgY29tcGF0aWJsZQogIGlmKG1zZy52ZXJzaW9uLm1pbm9yIDw9IGMudmVyc2lvbi5taW5vcikgewogICAgYy52ZXJzaW9uLm1pbm9yID0gbXNnLnZlcnNpb24ubWlub3I7CiAgfSBlbHNlIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ0luY29tcGF0aWJsZSBUTFMgdmVyc2lvbi4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5wcm90b2NvbF92ZXJzaW9uCiAgICAgIH0KICAgIH0pOwogIH0KCiAgLy8gaW5kaWNhdGUgc2Vzc2lvbiB2ZXJzaW9uIGhhcyBiZWVuIHNldAogIGMuc2Vzc2lvbi52ZXJzaW9uID0gYy52ZXJzaW9uOwoKICAvLyBnZXQgdGhlIHNlc3Npb24gSUQgZnJvbSB0aGUgbWVzc2FnZQogIHZhciBzZXNzaW9uSWQgPSBtc2cuc2Vzc2lvbl9pZC5ieXRlcygpOwoKICAvLyBpZiB0aGUgc2Vzc2lvbiBJRCBpcyBub3QgYmxhbmsgYW5kIG1hdGNoZXMgdGhlIGNhY2hlZCBvbmUsIHJlc3VtZQogIC8vIHRoZSBzZXNzaW9uCiAgaWYoc2Vzc2lvbklkLmxlbmd0aCA+IDAgJiYgc2Vzc2lvbklkID09PSBjLnNlc3Npb24uaWQpIHsKICAgIC8vIHJlc3VtaW5nIHNlc3Npb24sIGV4cGVjdCBhIENoYW5nZUNpcGhlclNwZWMgbmV4dAogICAgYy5leHBlY3QgPSBTQ0M7CiAgICBjLnNlc3Npb24ucmVzdW1pbmcgPSB0cnVlOwoKICAgIC8vIGdldCBuZXcgc2VydmVyIHJhbmRvbQogICAgYy5zZXNzaW9uLnNwLnNlcnZlcl9yYW5kb20gPSBtc2cucmFuZG9tLmJ5dGVzKCk7CiAgfSBlbHNlIHsKICAgIC8vIG5vdCByZXN1bWluZywgZXhwZWN0IGEgc2VydmVyIENlcnRpZmljYXRlIG1lc3NhZ2UgbmV4dAogICAgYy5leHBlY3QgPSBTQ0U7CiAgICBjLnNlc3Npb24ucmVzdW1pbmcgPSBmYWxzZTsKCiAgICAvLyBjcmVhdGUgbmV3IHNlY3VyaXR5IHBhcmFtZXRlcnMKICAgIHRscy5jcmVhdGVTZWN1cml0eVBhcmFtZXRlcnMoYywgbXNnKTsKICB9CgogIC8vIHNldCBuZXcgc2Vzc2lvbiBJRAogIGMuc2Vzc2lvbi5pZCA9IHNlc3Npb25JZDsKCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIHNlcnZlciByZWNlaXZlcyBhIENsaWVudEhlbGxvIHJlY29yZC4KICoKICogV2hlbiBhIENsaWVudEhlbGxvIG1lc3NhZ2Ugd2lsbCBiZSBzZW50OgogKiAgIFdoZW4gYSBjbGllbnQgZmlyc3QgY29ubmVjdHMgdG8gYSBzZXJ2ZXIgaXQgaXMgcmVxdWlyZWQgdG8gc2VuZCB0aGUKICogICBjbGllbnQgaGVsbG8gYXMgaXRzIGZpcnN0IG1lc3NhZ2UuIFRoZSBjbGllbnQgY2FuIGFsc28gc2VuZCBhIGNsaWVudAogKiAgIGhlbGxvIGluIHJlc3BvbnNlIHRvIGEgaGVsbG8gcmVxdWVzdCBvciBvbiBpdHMgb3duIGluaXRpYXRpdmUgaW4gb3JkZXIKICogICB0byByZW5lZ290aWF0ZSB0aGUgc2VjdXJpdHkgcGFyYW1ldGVycyBpbiBhbiBleGlzdGluZyBjb25uZWN0aW9uLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlLgogKi8KdGxzLmhhbmRsZUNsaWVudEhlbGxvID0gZnVuY3Rpb24oYywgcmVjb3JkLCBsZW5ndGgpIHsKICB2YXIgbXNnID0gdGxzLnBhcnNlSGVsbG9NZXNzYWdlKGMsIHJlY29yZCwgbGVuZ3RoKTsKICBpZihjLmZhaWwpIHsKICAgIHJldHVybjsKICB9CgogIC8vIGdldCB0aGUgc2Vzc2lvbiBJRCBmcm9tIHRoZSBtZXNzYWdlCiAgdmFyIHNlc3Npb25JZCA9IG1zZy5zZXNzaW9uX2lkLmJ5dGVzKCk7CgogIC8vIHNlZSBpZiB0aGUgZ2l2ZW4gc2Vzc2lvbiBJRCBpcyBpbiB0aGUgY2FjaGUKICB2YXIgc2Vzc2lvbiA9IG51bGw7CiAgaWYoYy5zZXNzaW9uQ2FjaGUpIHsKICAgIHNlc3Npb24gPSBjLnNlc3Npb25DYWNoZS5nZXRTZXNzaW9uKHNlc3Npb25JZCk7CiAgICBpZihzZXNzaW9uID09PSBudWxsKSB7CiAgICAgIC8vIHNlc3Npb24gSUQgbm90IGZvdW5kCiAgICAgIHNlc3Npb25JZCA9ICcnOwogICAgfSBlbHNlIGlmKHNlc3Npb24udmVyc2lvbi5tYWpvciAhPT0gbXNnLnZlcnNpb24ubWFqb3IgfHwKICAgICAgc2Vzc2lvbi52ZXJzaW9uLm1pbm9yID4gbXNnLnZlcnNpb24ubWlub3IpIHsKICAgICAgLy8gaWYgc2Vzc2lvbiB2ZXJzaW9uIGlzIGluY29tcGF0aWJsZSB3aXRoIGNsaWVudCB2ZXJzaW9uLCBkbyBub3QgcmVzdW1lCiAgICAgIHNlc3Npb24gPSBudWxsOwogICAgICBzZXNzaW9uSWQgPSAnJzsKICAgIH0KICB9CgogIC8vIG5vIHNlc3Npb24gZm91bmQgdG8gcmVzdW1lLCBnZW5lcmF0ZSBhIG5ldyBzZXNzaW9uIElECiAgaWYoc2Vzc2lvbklkLmxlbmd0aCA9PT0gMCkgewogICAgc2Vzc2lvbklkID0gZm9yZ2UucmFuZG9tLmdldEJ5dGVzKDMyKTsKICB9CgogIC8vIHVwZGF0ZSBzZXNzaW9uCiAgYy5zZXNzaW9uLmlkID0gc2Vzc2lvbklkOwogIGMuc2Vzc2lvbi5jbGllbnRIZWxsb1ZlcnNpb24gPSBtc2cudmVyc2lvbjsKICBjLnNlc3Npb24uc3AgPSB7fTsKICBpZihzZXNzaW9uKSB7CiAgICAvLyB1c2UgdmVyc2lvbiBhbmQgc2VjdXJpdHkgcGFyYW1ldGVycyBmcm9tIHJlc3VtZWQgc2Vzc2lvbgogICAgYy52ZXJzaW9uID0gYy5zZXNzaW9uLnZlcnNpb24gPSBzZXNzaW9uLnZlcnNpb247CiAgICBjLnNlc3Npb24uc3AgPSBzZXNzaW9uLnNwOwogIH0gZWxzZSB7CiAgICAvLyB1c2UgaGlnaGVzdCBjb21wYXRpYmxlIG1pbm9yIHZlcnNpb24KICAgIHZhciB2ZXJzaW9uOwogICAgZm9yKHZhciBpID0gMTsgaSA8IHRscy5TdXBwb3J0ZWRWZXJzaW9ucy5sZW5ndGg7ICsraSkgewogICAgICB2ZXJzaW9uID0gdGxzLlN1cHBvcnRlZFZlcnNpb25zW2ldOwogICAgICBpZih2ZXJzaW9uLm1pbm9yIDw9IG1zZy52ZXJzaW9uLm1pbm9yKSB7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIGMudmVyc2lvbiA9IHttYWpvcjogdmVyc2lvbi5tYWpvciwgbWlub3I6IHZlcnNpb24ubWlub3J9OwogICAgYy5zZXNzaW9uLnZlcnNpb24gPSBjLnZlcnNpb247CiAgfQoKICAvLyBpZiBhIHNlc3Npb24gaXMgc2V0LCByZXN1bWUgaXQKICBpZihzZXNzaW9uICE9PSBudWxsKSB7CiAgICAvLyByZXN1bWluZyBzZXNzaW9uLCBleHBlY3QgYSBDaGFuZ2VDaXBoZXJTcGVjIG5leHQKICAgIGMuZXhwZWN0ID0gQ0NDOwogICAgYy5zZXNzaW9uLnJlc3VtaW5nID0gdHJ1ZTsKCiAgICAvLyBnZXQgbmV3IGNsaWVudCByYW5kb20KICAgIGMuc2Vzc2lvbi5zcC5jbGllbnRfcmFuZG9tID0gbXNnLnJhbmRvbS5ieXRlcygpOwogIH0gZWxzZSB7CiAgICAvLyBub3QgcmVzdW1pbmcsIGV4cGVjdCBhIENlcnRpZmljYXRlIG9yIENsaWVudEtleUV4Y2hhbmdlCiAgICBjLmV4cGVjdCA9IChjLnZlcmlmeUNsaWVudCAhPT0gZmFsc2UpID8gQ0NFIDogQ0tFOwogICAgYy5zZXNzaW9uLnJlc3VtaW5nID0gZmFsc2U7CgogICAgLy8gY3JlYXRlIG5ldyBzZWN1cml0eSBwYXJhbWV0ZXJzCiAgICB0bHMuY3JlYXRlU2VjdXJpdHlQYXJhbWV0ZXJzKGMsIG1zZyk7CiAgfQoKICAvLyBjb25uZWN0aW9uIG5vdyBvcGVuCiAgYy5vcGVuID0gdHJ1ZTsKCiAgLy8gcXVldWUgc2VydmVyIGhlbGxvCiAgdGxzLnF1ZXVlKGMsIHRscy5jcmVhdGVSZWNvcmQoYywgewogICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhhbmRzaGFrZSwKICAgIGRhdGE6IHRscy5jcmVhdGVTZXJ2ZXJIZWxsbyhjKQogIH0pKTsKCiAgaWYoYy5zZXNzaW9uLnJlc3VtaW5nKSB7CiAgICAvLyBxdWV1ZSBjaGFuZ2UgY2lwaGVyIHNwZWMgbWVzc2FnZQogICAgdGxzLnF1ZXVlKGMsIHRscy5jcmVhdGVSZWNvcmQoYywgewogICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuY2hhbmdlX2NpcGhlcl9zcGVjLAogICAgICBkYXRhOiB0bHMuY3JlYXRlQ2hhbmdlQ2lwaGVyU3BlYygpCiAgICB9KSk7CgogICAgLy8gY3JlYXRlIHBlbmRpbmcgc3RhdGUKICAgIGMuc3RhdGUucGVuZGluZyA9IHRscy5jcmVhdGVDb25uZWN0aW9uU3RhdGUoYyk7CgogICAgLy8gY2hhbmdlIGN1cnJlbnQgd3JpdGUgc3RhdGUgdG8gcGVuZGluZyB3cml0ZSBzdGF0ZQogICAgYy5zdGF0ZS5jdXJyZW50LndyaXRlID0gYy5zdGF0ZS5wZW5kaW5nLndyaXRlOwoKICAgIC8vIHF1ZXVlIGZpbmlzaGVkCiAgICB0bHMucXVldWUoYywgdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICAgIHR5cGU6IHRscy5Db250ZW50VHlwZS5oYW5kc2hha2UsCiAgICAgIGRhdGE6IHRscy5jcmVhdGVGaW5pc2hlZChjKQogICAgfSkpOwogIH0gZWxzZSB7CiAgICAvLyBxdWV1ZSBzZXJ2ZXIgY2VydGlmaWNhdGUKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhhbmRzaGFrZSwKICAgICAgZGF0YTogdGxzLmNyZWF0ZUNlcnRpZmljYXRlKGMpCiAgICB9KSk7CgogICAgaWYoIWMuZmFpbCkgewogICAgICAvLyBxdWV1ZSBzZXJ2ZXIga2V5IGV4Y2hhbmdlCiAgICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuaGFuZHNoYWtlLAogICAgICAgIGRhdGE6IHRscy5jcmVhdGVTZXJ2ZXJLZXlFeGNoYW5nZShjKQogICAgICB9KSk7CgogICAgICAvLyByZXF1ZXN0IGNsaWVudCBjZXJ0aWZpY2F0ZSBpZiBzZXQKICAgICAgaWYoYy52ZXJpZnlDbGllbnQgIT09IGZhbHNlKSB7CiAgICAgICAgLy8gcXVldWUgY2VydGlmaWNhdGUgcmVxdWVzdAogICAgICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgICAgIHR5cGU6IHRscy5Db250ZW50VHlwZS5oYW5kc2hha2UsCiAgICAgICAgICBkYXRhOiB0bHMuY3JlYXRlQ2VydGlmaWNhdGVSZXF1ZXN0KGMpCiAgICAgICAgfSkpOwogICAgICB9CgogICAgICAvLyBxdWV1ZSBzZXJ2ZXIgaGVsbG8gZG9uZQogICAgICB0bHMucXVldWUoYywgdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhhbmRzaGFrZSwKICAgICAgICBkYXRhOiB0bHMuY3JlYXRlU2VydmVySGVsbG9Eb25lKGMpCiAgICAgIH0pKTsKICAgIH0KICB9CgogIC8vIHNlbmQgcmVjb3JkcwogIHRscy5mbHVzaChjKTsKCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIGNsaWVudCByZWNlaXZlcyBhIENlcnRpZmljYXRlIHJlY29yZC4KICoKICogV2hlbiB0aGlzIG1lc3NhZ2Ugd2lsbCBiZSBzZW50OgogKiAgIFRoZSBzZXJ2ZXIgbXVzdCBzZW5kIGEgY2VydGlmaWNhdGUgd2hlbmV2ZXIgdGhlIGFncmVlZC11cG9uIGtleSBleGNoYW5nZQogKiAgIG1ldGhvZCBpcyBub3QgYW4gYW5vbnltb3VzIG9uZS4gVGhpcyBtZXNzYWdlIHdpbGwgYWx3YXlzIGltbWVkaWF0ZWx5CiAqICAgZm9sbG93IHRoZSBzZXJ2ZXIgaGVsbG8gbWVzc2FnZS4KICoKICogTWVhbmluZyBvZiB0aGlzIG1lc3NhZ2U6CiAqICAgVGhlIGNlcnRpZmljYXRlIHR5cGUgbXVzdCBiZSBhcHByb3ByaWF0ZSBmb3IgdGhlIHNlbGVjdGVkIGNpcGhlciBzdWl0ZSdzCiAqICAga2V5IGV4Y2hhbmdlIGFsZ29yaXRobSwgYW5kIGlzIGdlbmVyYWxseSBhbiBYLjUwOXYzIGNlcnRpZmljYXRlLiBJdCBtdXN0CiAqICAgY29udGFpbiBhIGtleSB3aGljaCBtYXRjaGVzIHRoZSBrZXkgZXhjaGFuZ2UgbWV0aG9kLCBhcyBmb2xsb3dzLiBVbmxlc3MKICogICBvdGhlcndpc2Ugc3BlY2lmaWVkLCB0aGUgc2lnbmluZyBhbGdvcml0aG0gZm9yIHRoZSBjZXJ0aWZpY2F0ZSBtdXN0IGJlCiAqICAgdGhlIHNhbWUgYXMgdGhlIGFsZ29yaXRobSBmb3IgdGhlIGNlcnRpZmljYXRlIGtleS4gVW5sZXNzIG90aGVyd2lzZQogKiAgIHNwZWNpZmllZCwgdGhlIHB1YmxpYyBrZXkgbWF5IGJlIG9mIGFueSBsZW5ndGguCiAqCiAqIG9wYXF1ZSBBU04uMUNlcnQ8MS4uMl4yNC0xPjsKICogc3RydWN0IHsKICogICBBU04uMUNlcnQgY2VydGlmaWNhdGVfbGlzdDwxLi4yXjI0LTE+OwogKiB9IENlcnRpZmljYXRlOwogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlLgogKi8KdGxzLmhhbmRsZUNlcnRpZmljYXRlID0gZnVuY3Rpb24oYywgcmVjb3JkLCBsZW5ndGgpIHsKICAvLyBtaW5pbXVtIG9mIDMgYnl0ZXMgaW4gbWVzc2FnZQogIGlmKGxlbmd0aCA8IDMpIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ0ludmFsaWQgQ2VydGlmaWNhdGUgbWVzc2FnZS4gTWVzc2FnZSB0b28gc2hvcnQuJywKICAgICAgc2VuZDogdHJ1ZSwKICAgICAgYWxlcnQ6IHsKICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgIGRlc2NyaXB0aW9uOiB0bHMuQWxlcnQuRGVzY3JpcHRpb24uaWxsZWdhbF9wYXJhbWV0ZXIKICAgICAgfQogICAgfSk7CiAgfQoKICB2YXIgYiA9IHJlY29yZC5mcmFnbWVudDsKICB2YXIgbXNnID0gewogICAgY2VydGlmaWNhdGVfbGlzdDogcmVhZFZlY3RvcihiLCAzKQogIH07CgogIC8qIFRoZSBzZW5kZXIncyBjZXJ0aWZpY2F0ZSB3aWxsIGJlIGZpcnN0IGluIHRoZSBsaXN0IChjaGFpbiksIGVhY2gKICAgIHN1YnNlcXVlbnQgb25lIHRoYXQgZm9sbG93cyB3aWxsIGNlcnRpZnkgdGhlIHByZXZpb3VzIG9uZSwgYnV0IHJvb3QKICAgIGNlcnRpZmljYXRlcyAoc2VsZi1zaWduZWQpIHRoYXQgc3BlY2lmeSB0aGUgY2VydGlmaWNhdGUgYXV0aG9yaXR5IG1heQogICAgYmUgb21pdHRlZCB1bmRlciB0aGUgYXNzdW1wdGlvbiB0aGF0IGNsaWVudHMgbXVzdCBhbHJlYWR5IHBvc3Nlc3MgaXQuICovCiAgdmFyIGNlcnQsIGFzbjE7CiAgdmFyIGNlcnRzID0gW107CiAgdHJ5IHsKICAgIHdoaWxlKG1zZy5jZXJ0aWZpY2F0ZV9saXN0Lmxlbmd0aCgpID4gMCkgewogICAgICAvLyBlYWNoIGVudHJ5IGluIG1zZy5jZXJ0aWZpY2F0ZV9saXN0IGlzIGEgdmVjdG9yIHdpdGggMyBsZW4gYnl0ZXMKICAgICAgY2VydCA9IHJlYWRWZWN0b3IobXNnLmNlcnRpZmljYXRlX2xpc3QsIDMpOwogICAgICBhc24xID0gZm9yZ2UuYXNuMS5mcm9tRGVyKGNlcnQpOwogICAgICBjZXJ0ID0gZm9yZ2UucGtpLmNlcnRpZmljYXRlRnJvbUFzbjEoYXNuMSwgdHJ1ZSk7CiAgICAgIGNlcnRzLnB1c2goY2VydCk7CiAgICB9CiAgfSBjYXRjaChleCkgewogICAgcmV0dXJuIGMuZXJyb3IoYywgewogICAgICBtZXNzYWdlOiAnQ291bGQgbm90IHBhcnNlIGNlcnRpZmljYXRlIGxpc3QuJywKICAgICAgY2F1c2U6IGV4LAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5iYWRfY2VydGlmaWNhdGUKICAgICAgfQogICAgfSk7CiAgfQoKICAvLyBlbnN1cmUgYXQgbGVhc3QgMSBjZXJ0aWZpY2F0ZSB3YXMgcHJvdmlkZWQgaWYgaW4gY2xpZW50LW1vZGUKICAvLyBvciBpZiB2ZXJpZnlDbGllbnQgd2FzIHNldCB0byB0cnVlIHRvIHJlcXVpcmUgYSBjZXJ0aWZpY2F0ZQogIC8vIChhcyBvcHBvc2VkIHRvICdvcHRpb25hbCcpCiAgdmFyIGNsaWVudCA9IChjLmVudGl0eSA9PT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KTsKICBpZigoY2xpZW50IHx8IGMudmVyaWZ5Q2xpZW50ID09PSB0cnVlKSAmJiBjZXJ0cy5sZW5ndGggPT09IDApIHsKICAgIC8vIGVycm9yLCBubyBjZXJ0aWZpY2F0ZQogICAgYy5lcnJvcihjLCB7CiAgICAgIG1lc3NhZ2U6IGNsaWVudCA/CiAgICAgICAgJ05vIHNlcnZlciBjZXJ0aWZpY2F0ZSBwcm92aWRlZC4nIDoKICAgICAgICAnTm8gY2xpZW50IGNlcnRpZmljYXRlIHByb3ZpZGVkLicsCiAgICAgIHNlbmQ6IHRydWUsCiAgICAgIGFsZXJ0OiB7CiAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmlsbGVnYWxfcGFyYW1ldGVyCiAgICAgIH0KICAgIH0pOwogIH0gZWxzZSBpZihjZXJ0cy5sZW5ndGggPT09IDApIHsKICAgIC8vIG5vIGNlcnRzIHRvIHZlcmlmeQogICAgLy8gZXhwZWN0IGEgU2VydmVyS2V5RXhjaGFuZ2Ugb3IgQ2xpZW50S2V5RXhjaGFuZ2UgbWVzc2FnZSBuZXh0CiAgICBjLmV4cGVjdCA9IGNsaWVudCA/IFNLRSA6IENLRTsKICB9IGVsc2UgewogICAgLy8gc2F2ZSBjZXJ0aWZpY2F0ZSBpbiBzZXNzaW9uCiAgICBpZihjbGllbnQpIHsKICAgICAgYy5zZXNzaW9uLnNlcnZlckNlcnRpZmljYXRlID0gY2VydHNbMF07CiAgICB9IGVsc2UgewogICAgICBjLnNlc3Npb24uY2xpZW50Q2VydGlmaWNhdGUgPSBjZXJ0c1swXTsKICAgIH0KCiAgICBpZih0bHMudmVyaWZ5Q2VydGlmaWNhdGVDaGFpbihjLCBjZXJ0cykpIHsKICAgICAgLy8gZXhwZWN0IGEgU2VydmVyS2V5RXhjaGFuZ2Ugb3IgQ2xpZW50S2V5RXhjaGFuZ2UgbWVzc2FnZSBuZXh0CiAgICAgIGMuZXhwZWN0ID0gY2xpZW50ID8gU0tFIDogQ0tFOwogICAgfQogIH0KCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIGNsaWVudCByZWNlaXZlcyBhIFNlcnZlcktleUV4Y2hhbmdlIHJlY29yZC4KICoKICogV2hlbiB0aGlzIG1lc3NhZ2Ugd2lsbCBiZSBzZW50OgogKiAgIFRoaXMgbWVzc2FnZSB3aWxsIGJlIHNlbnQgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIHNlcnZlciBjZXJ0aWZpY2F0ZQogKiAgIG1lc3NhZ2UgKG9yIHRoZSBzZXJ2ZXIgaGVsbG8gbWVzc2FnZSwgaWYgdGhpcyBpcyBhbiBhbm9ueW1vdXMKICogICBuZWdvdGlhdGlvbikuCiAqCiAqICAgVGhlIHNlcnZlciBrZXkgZXhjaGFuZ2UgbWVzc2FnZSBpcyBzZW50IGJ5IHRoZSBzZXJ2ZXIgb25seSB3aGVuIHRoZQogKiAgIHNlcnZlciBjZXJ0aWZpY2F0ZSBtZXNzYWdlIChpZiBzZW50KSBkb2VzIG5vdCBjb250YWluIGVub3VnaCBkYXRhIHRvCiAqICAgYWxsb3cgdGhlIGNsaWVudCB0byBleGNoYW5nZSBhIHByZW1hc3RlciBzZWNyZXQuCiAqCiAqIE1lYW5pbmcgb2YgdGhpcyBtZXNzYWdlOgogKiAgIFRoaXMgbWVzc2FnZSBjb252ZXlzIGNyeXB0b2dyYXBoaWMgaW5mb3JtYXRpb24gdG8gYWxsb3cgdGhlIGNsaWVudCB0bwogKiAgIGNvbW11bmljYXRlIHRoZSBwcmVtYXN0ZXIgc2VjcmV0OiBlaXRoZXIgYW4gUlNBIHB1YmxpYyBrZXkgdG8gZW5jcnlwdAogKiAgIHRoZSBwcmVtYXN0ZXIgc2VjcmV0IHdpdGgsIG9yIGEgRGlmZmllLUhlbGxtYW4gcHVibGljIGtleSB3aXRoIHdoaWNoIHRoZQogKiAgIGNsaWVudCBjYW4gY29tcGxldGUgYSBrZXkgZXhjaGFuZ2UgKHdpdGggdGhlIHJlc3VsdCBiZWluZyB0aGUgcHJlbWFzdGVyCiAqICAgc2VjcmV0LikKICoKICogZW51bSB7CiAqICAgZGhlX2RzcywgZGhlX3JzYSwgZGhfYW5vbiwgcnNhLCBkaF9kc3MsIGRoX3JzYQogKiB9IEtleUV4Y2hhbmdlQWxnb3JpdGhtOwogKgogKiBzdHJ1Y3QgewogKiAgIG9wYXF1ZSBkaF9wPDEuLjJeMTYtMT47CiAqICAgb3BhcXVlIGRoX2c8MS4uMl4xNi0xPjsKICogICBvcGFxdWUgZGhfWXM8MS4uMl4xNi0xPjsKICogfSBTZXJ2ZXJESFBhcmFtczsKICoKICogc3RydWN0IHsKICogICBzZWxlY3QoS2V5RXhjaGFuZ2VBbGdvcml0aG0pIHsKICogICAgIGNhc2UgZGhfYW5vbjoKICogICAgICAgU2VydmVyREhQYXJhbXMgcGFyYW1zOwogKiAgICAgY2FzZSBkaGVfZHNzOgogKiAgICAgY2FzZSBkaGVfcnNhOgogKiAgICAgICBTZXJ2ZXJESFBhcmFtcyBwYXJhbXM7CiAqICAgICAgIGRpZ2l0YWxseS1zaWduZWQgc3RydWN0IHsKICogICAgICAgICBvcGFxdWUgY2xpZW50X3JhbmRvbVszMl07CiAqICAgICAgICAgb3BhcXVlIHNlcnZlcl9yYW5kb21bMzJdOwogKiAgICAgICAgIFNlcnZlckRIUGFyYW1zIHBhcmFtczsKICogICAgICAgfSBzaWduZWRfcGFyYW1zOwogKiAgICAgY2FzZSByc2E6CiAqICAgICBjYXNlIGRoX2RzczoKICogICAgIGNhc2UgZGhfcnNhOgogKiAgICAgICBzdHJ1Y3Qge307CiAqICAgfTsKICogfSBTZXJ2ZXJLZXlFeGNoYW5nZTsKICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZS4KICovCnRscy5oYW5kbGVTZXJ2ZXJLZXlFeGNoYW5nZSA9IGZ1bmN0aW9uKGMsIHJlY29yZCwgbGVuZ3RoKSB7CiAgLy8gdGhpcyBpbXBsZW1lbnRhdGlvbiBvbmx5IHN1cHBvcnRzIFJTQSwgbm8gRGlmZmllLUhlbGxtYW4gc3VwcG9ydAogIC8vIHNvIGFueSBsZW5ndGggPiAwIGlzIGludmFsaWQKICBpZihsZW5ndGggPiAwKSB7CiAgICByZXR1cm4gYy5lcnJvcihjLCB7CiAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIGtleSBwYXJhbWV0ZXJzLiBPbmx5IFJTQSBpcyBzdXBwb3J0ZWQuJywKICAgICAgc2VuZDogdHJ1ZSwKICAgICAgYWxlcnQ6IHsKICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgIGRlc2NyaXB0aW9uOiB0bHMuQWxlcnQuRGVzY3JpcHRpb24udW5zdXBwb3J0ZWRfY2VydGlmaWNhdGUKICAgICAgfQogICAgfSk7CiAgfQoKICAvLyBleHBlY3QgYW4gb3B0aW9uYWwgQ2VydGlmaWNhdGVSZXF1ZXN0IG1lc3NhZ2UgbmV4dAogIGMuZXhwZWN0ID0gU0NSOwoKICAvLyBjb250aW51ZQogIGMucHJvY2VzcygpOwp9OwoKLyoqCiAqIENhbGxlZCB3aGVuIGEgY2xpZW50IHJlY2VpdmVzIGEgQ2xpZW50S2V5RXhjaGFuZ2UgcmVjb3JkLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlLgogKi8KdGxzLmhhbmRsZUNsaWVudEtleUV4Y2hhbmdlID0gZnVuY3Rpb24oYywgcmVjb3JkLCBsZW5ndGgpIHsKICAvLyB0aGlzIGltcGxlbWVudGF0aW9uIG9ubHkgc3VwcG9ydHMgUlNBLCBubyBEaWZmaWUtSGVsbG1hbiBzdXBwb3J0CiAgLy8gc28gYW55IGxlbmd0aCA8IDQ4IGlzIGludmFsaWQKICBpZihsZW5ndGggPCA0OCkgewogICAgcmV0dXJuIGMuZXJyb3IoYywgewogICAgICBtZXNzYWdlOiAnSW52YWxpZCBrZXkgcGFyYW1ldGVycy4gT25seSBSU0EgaXMgc3VwcG9ydGVkLicsCiAgICAgIHNlbmQ6IHRydWUsCiAgICAgIGFsZXJ0OiB7CiAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLnVuc3VwcG9ydGVkX2NlcnRpZmljYXRlCiAgICAgIH0KICAgIH0pOwogIH0KCiAgdmFyIGIgPSByZWNvcmQuZnJhZ21lbnQ7CiAgdmFyIG1zZyA9IHsKICAgIGVuY19wcmVfbWFzdGVyX3NlY3JldDogcmVhZFZlY3RvcihiLCAyKS5nZXRCeXRlcygpCiAgfTsKCiAgLy8gZG8gcnNhIGRlY3J5cHRpb24KICB2YXIgcHJpdmF0ZUtleSA9IG51bGw7CiAgaWYoYy5nZXRQcml2YXRlS2V5KSB7CiAgICB0cnkgewogICAgICBwcml2YXRlS2V5ID0gYy5nZXRQcml2YXRlS2V5KGMsIGMuc2Vzc2lvbi5zZXJ2ZXJDZXJ0aWZpY2F0ZSk7CiAgICAgIHByaXZhdGVLZXkgPSBmb3JnZS5wa2kucHJpdmF0ZUtleUZyb21QZW0ocHJpdmF0ZUtleSk7CiAgICB9IGNhdGNoKGV4KSB7CiAgICAgIGMuZXJyb3IoYywgewogICAgICAgIG1lc3NhZ2U6ICdDb3VsZCBub3QgZ2V0IHByaXZhdGUga2V5LicsCiAgICAgICAgY2F1c2U6IGV4LAogICAgICAgIHNlbmQ6IHRydWUsCiAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yCiAgICAgICAgfQogICAgICB9KTsKICAgIH0KICB9CgogIGlmKHByaXZhdGVLZXkgPT09IG51bGwpIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ05vIHByaXZhdGUga2V5IHNldC4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5pbnRlcm5hbF9lcnJvcgogICAgICB9CiAgICB9KTsKICB9CgogIHRyeSB7CiAgICAvLyBkZWNyeXB0IDQ4LWJ5dGUgcHJlLW1hc3RlciBzZWNyZXQKICAgIHZhciBzcCA9IGMuc2Vzc2lvbi5zcDsKICAgIHNwLnByZV9tYXN0ZXJfc2VjcmV0ID0gcHJpdmF0ZUtleS5kZWNyeXB0KG1zZy5lbmNfcHJlX21hc3Rlcl9zZWNyZXQpOwoKICAgIC8vIGVuc3VyZSBjbGllbnQgaGVsbG8gdmVyc2lvbiBtYXRjaGVzIGZpcnN0IDIgYnl0ZXMKICAgIHZhciB2ZXJzaW9uID0gYy5zZXNzaW9uLmNsaWVudEhlbGxvVmVyc2lvbjsKICAgIGlmKHZlcnNpb24ubWFqb3IgIT09IHNwLnByZV9tYXN0ZXJfc2VjcmV0LmNoYXJDb2RlQXQoMCkgfHwKICAgICAgdmVyc2lvbi5taW5vciAhPT0gc3AucHJlX21hc3Rlcl9zZWNyZXQuY2hhckNvZGVBdCgxKSkgewogICAgICAvLyBlcnJvciwgZG8gbm90IHNlbmQgYWxlcnQgKHNlZSBCTEVJIGF0dGFjayBiZWxvdykKICAgICAgdGhyb3cgbmV3IEVycm9yKCdUTFMgdmVyc2lvbiByb2xsYmFjayBhdHRhY2sgZGV0ZWN0ZWQuJyk7CiAgICB9CiAgfSBjYXRjaChleCkgewogICAgLyogTm90ZTogRGFuaWVsIEJsZWljaGVuYmFjaGVyIFtCTEVJXSBjYW4gYmUgdXNlZCB0byBhdHRhY2sgYQogICAgICBUTFMgc2VydmVyIHdoaWNoIGlzIHVzaW5nIFBLQ1MjMSBlbmNvZGVkIFJTQSwgc28gaW5zdGVhZCBvZgogICAgICBmYWlsaW5nIGhlcmUsIHdlIGdlbmVyYXRlIDQ4IHJhbmRvbSBieXRlcyBhbmQgdXNlIHRoYXQgYXMKICAgICAgdGhlIHByZS1tYXN0ZXIgc2VjcmV0LiAqLwogICAgc3AucHJlX21hc3Rlcl9zZWNyZXQgPSBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMoNDgpOwogIH0KCiAgLy8gZXhwZWN0IGEgQ2VydGlmaWNhdGVWZXJpZnkgbWVzc2FnZSBpZiBhIENlcnRpZmljYXRlIHdhcyByZWNlaXZlZCB0aGF0CiAgLy8gZG9lcyBub3QgaGF2ZSBmaXhlZCBEaWZmaWUtSGVsbG1hbiBwYXJhbXMsIG90aGVyd2lzZSBleHBlY3QKICAvLyBDaGFuZ2VDaXBoZXJTcGVjCiAgYy5leHBlY3QgPSBDQ0M7CiAgaWYoYy5zZXNzaW9uLmNsaWVudENlcnRpZmljYXRlICE9PSBudWxsKSB7CiAgICAvLyBvbmx5IFJTQSBzdXBwb3J0LCBzbyBleHBlY3QgQ2VydGlmaWNhdGVWZXJpZnkKICAgIC8vIFRPRE86IHN1cHBvcnQgRGlmZmllLUhlbGxtYW4KICAgIGMuZXhwZWN0ID0gQ0NWOwogIH0KCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIGNsaWVudCByZWNlaXZlcyBhIENlcnRpZmljYXRlUmVxdWVzdCByZWNvcmQuCiAqCiAqIFdoZW4gdGhpcyBtZXNzYWdlIHdpbGwgYmUgc2VudDoKICogICBBIG5vbi1hbm9ueW1vdXMgc2VydmVyIGNhbiBvcHRpb25hbGx5IHJlcXVlc3QgYSBjZXJ0aWZpY2F0ZSBmcm9tIHRoZQogKiAgIGNsaWVudCwgaWYgYXBwcm9wcmlhdGUgZm9yIHRoZSBzZWxlY3RlZCBjaXBoZXIgc3VpdGUuIFRoaXMgbWVzc2FnZSwgaWYKICogICBzZW50LCB3aWxsIGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUgU2VydmVyIEtleSBFeGNoYW5nZSBtZXNzYWdlIChpZiBpdCBpcwogKiAgIHNlbnQ7IG90aGVyd2lzZSwgdGhlIFNlcnZlciBDZXJ0aWZpY2F0ZSBtZXNzYWdlKS4KICoKICogZW51bSB7CiAqICAgcnNhX3NpZ24oMSksIGRzc19zaWduKDIpLCByc2FfZml4ZWRfZGgoMyksIGRzc19maXhlZF9kaCg0KSwKICogICByc2FfZXBoZW1lcmFsX2RoX1JFU0VSVkVEKDUpLCBkc3NfZXBoZW1lcmFsX2RoX1JFU0VSVkVEKDYpLAogKiAgIGZvcnRlenphX2Rtc19SRVNFUlZFRCgyMCksICgyNTUpCiAqIH0gQ2xpZW50Q2VydGlmaWNhdGVUeXBlOwogKgogKiBvcGFxdWUgRGlzdGluZ3Vpc2hlZE5hbWU8MS4uMl4xNi0xPjsKICoKICogc3RydWN0IHsKICogICBDbGllbnRDZXJ0aWZpY2F0ZVR5cGUgY2VydGlmaWNhdGVfdHlwZXM8MS4uMl44LTE+OwogKiAgIFNpZ25hdHVyZUFuZEhhc2hBbGdvcml0aG0gc3VwcG9ydGVkX3NpZ25hdHVyZV9hbGdvcml0aG1zPDJeMTYtMT47CiAqICAgRGlzdGluZ3Vpc2hlZE5hbWUgY2VydGlmaWNhdGVfYXV0aG9yaXRpZXM8MC4uMl4xNi0xPjsKICogfSBDZXJ0aWZpY2F0ZVJlcXVlc3Q7CiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gcmVjb3JkIHRoZSByZWNvcmQuCiAqIEBwYXJhbSBsZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgaGFuZHNoYWtlIG1lc3NhZ2UuCiAqLwp0bHMuaGFuZGxlQ2VydGlmaWNhdGVSZXF1ZXN0ID0gZnVuY3Rpb24oYywgcmVjb3JkLCBsZW5ndGgpIHsKICAvLyBtaW5pbXVtIG9mIDMgYnl0ZXMgaW4gbWVzc2FnZQogIGlmKGxlbmd0aCA8IDMpIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ0ludmFsaWQgQ2VydGlmaWNhdGVSZXF1ZXN0LiBNZXNzYWdlIHRvbyBzaG9ydC4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5pbGxlZ2FsX3BhcmFtZXRlcgogICAgICB9CiAgICB9KTsKICB9CgogIC8vIFRPRE86IFRMUyAxLjIrIGhhcyBkaWZmZXJlbnQgZm9ybWF0IGluY2x1ZGluZwogIC8vIFNpZ25hdHVyZUFuZEhhc2hBbGdvcml0aG0gYWZ0ZXIgY2VydCB0eXBlcwogIHZhciBiID0gcmVjb3JkLmZyYWdtZW50OwogIHZhciBtc2cgPSB7CiAgICBjZXJ0aWZpY2F0ZV90eXBlczogcmVhZFZlY3RvcihiLCAxKSwKICAgIGNlcnRpZmljYXRlX2F1dGhvcml0aWVzOiByZWFkVmVjdG9yKGIsIDIpCiAgfTsKCiAgLy8gc2F2ZSBjZXJ0aWZpY2F0ZSByZXF1ZXN0IGluIHNlc3Npb24KICBjLnNlc3Npb24uY2VydGlmaWNhdGVSZXF1ZXN0ID0gbXNnOwoKICAvLyBleHBlY3QgYSBTZXJ2ZXJIZWxsb0RvbmUgbWVzc2FnZSBuZXh0CiAgYy5leHBlY3QgPSBTSEQ7CgogIC8vIGNvbnRpbnVlCiAgYy5wcm9jZXNzKCk7Cn07CgovKioKICogQ2FsbGVkIHdoZW4gYSBzZXJ2ZXIgcmVjZWl2ZXMgYSBDZXJ0aWZpY2F0ZVZlcmlmeSByZWNvcmQuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gcmVjb3JkIHRoZSByZWNvcmQuCiAqIEBwYXJhbSBsZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgaGFuZHNoYWtlIG1lc3NhZ2UuCiAqLwp0bHMuaGFuZGxlQ2VydGlmaWNhdGVWZXJpZnkgPSBmdW5jdGlvbihjLCByZWNvcmQsIGxlbmd0aCkgewogIGlmKGxlbmd0aCA8IDIpIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ0ludmFsaWQgQ2VydGlmaWNhdGVWZXJpZnkuIE1lc3NhZ2UgdG9vIHNob3J0LicsCiAgICAgIHNlbmQ6IHRydWUsCiAgICAgIGFsZXJ0OiB7CiAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmlsbGVnYWxfcGFyYW1ldGVyCiAgICAgIH0KICAgIH0pOwogIH0KCiAgLy8gcmV3aW5kIHRvIGdldCBmdWxsIGJ5dGVzIGZvciBtZXNzYWdlIHNvIGl0IGNhbiBiZSBtYW51YWxseQogIC8vIGRpZ2VzdGVkIGJlbG93IChzcGVjaWFsIGNhc2UgZm9yIENlcnRpZmljYXRlVmVyaWZ5IG1lc3NhZ2VzIGJlY2F1c2UKICAvLyB0aGV5IG11c3QgYmUgZGlnZXN0ZWQgKmFmdGVyKiBoYW5kbGluZyBhcyBvcHBvc2VkIHRvIGFsbCBvdGhlcnMpCiAgdmFyIGIgPSByZWNvcmQuZnJhZ21lbnQ7CiAgYi5yZWFkIC09IDQ7CiAgdmFyIG1zZ0J5dGVzID0gYi5ieXRlcygpOwogIGIucmVhZCArPSA0OwoKICB2YXIgbXNnID0gewogICAgc2lnbmF0dXJlOiByZWFkVmVjdG9yKGIsIDIpLmdldEJ5dGVzKCkKICB9OwoKICAvLyBUT0RPOiBhZGQgc3VwcG9ydCBmb3IgRFNBCgogIC8vIGdlbmVyYXRlIGRhdGEgdG8gdmVyaWZ5CiAgdmFyIHZlcmlmeSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdmVyaWZ5LnB1dEJ1ZmZlcihjLnNlc3Npb24ubWQ1LmRpZ2VzdCgpKTsKICB2ZXJpZnkucHV0QnVmZmVyKGMuc2Vzc2lvbi5zaGExLmRpZ2VzdCgpKTsKICB2ZXJpZnkgPSB2ZXJpZnkuZ2V0Qnl0ZXMoKTsKCiAgdHJ5IHsKICAgIHZhciBjZXJ0ID0gYy5zZXNzaW9uLmNsaWVudENlcnRpZmljYXRlOwogICAgLypiID0gZm9yZ2UucGtpLnJzYS5kZWNyeXB0KAogICAgICBtc2cuc2lnbmF0dXJlLCBjZXJ0LnB1YmxpY0tleSwgdHJ1ZSwgdmVyaWZ5Lmxlbmd0aCk7CiAgICBpZihiICE9PSB2ZXJpZnkpIHsqLwogICAgaWYoIWNlcnQucHVibGljS2V5LnZlcmlmeSh2ZXJpZnksIG1zZy5zaWduYXR1cmUsICdOT05FJykpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKCdDZXJ0aWZpY2F0ZVZlcmlmeSBzaWduYXR1cmUgZG9lcyBub3QgbWF0Y2guJyk7CiAgICB9CgogICAgLy8gZGlnZXN0IG1lc3NhZ2Ugbm93IHRoYXQgaXQgaGFzIGJlZW4gaGFuZGxlZAogICAgYy5zZXNzaW9uLm1kNS51cGRhdGUobXNnQnl0ZXMpOwogICAgYy5zZXNzaW9uLnNoYTEudXBkYXRlKG1zZ0J5dGVzKTsKICB9IGNhdGNoKGV4KSB7CiAgICByZXR1cm4gYy5lcnJvcihjLCB7CiAgICAgIG1lc3NhZ2U6ICdCYWQgc2lnbmF0dXJlIGluIENlcnRpZmljYXRlVmVyaWZ5LicsCiAgICAgIHNlbmQ6IHRydWUsCiAgICAgIGFsZXJ0OiB7CiAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmhhbmRzaGFrZV9mYWlsdXJlCiAgICAgIH0KICAgIH0pOwogIH0KCiAgLy8gZXhwZWN0IENoYW5nZUNpcGhlclNwZWMKICBjLmV4cGVjdCA9IENDQzsKCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIGNsaWVudCByZWNlaXZlcyBhIFNlcnZlckhlbGxvRG9uZSByZWNvcmQuCiAqCiAqIFdoZW4gdGhpcyBtZXNzYWdlIHdpbGwgYmUgc2VudDoKICogICBUaGUgc2VydmVyIGhlbGxvIGRvbmUgbWVzc2FnZSBpcyBzZW50IGJ5IHRoZSBzZXJ2ZXIgdG8gaW5kaWNhdGUgdGhlIGVuZAogKiAgIG9mIHRoZSBzZXJ2ZXIgaGVsbG8gYW5kIGFzc29jaWF0ZWQgbWVzc2FnZXMuIEFmdGVyIHNlbmRpbmcgdGhpcyBtZXNzYWdlCiAqICAgdGhlIHNlcnZlciB3aWxsIHdhaXQgZm9yIGEgY2xpZW50IHJlc3BvbnNlLgogKgogKiBNZWFuaW5nIG9mIHRoaXMgbWVzc2FnZToKICogICBUaGlzIG1lc3NhZ2UgbWVhbnMgdGhhdCB0aGUgc2VydmVyIGlzIGRvbmUgc2VuZGluZyBtZXNzYWdlcyB0byBzdXBwb3J0CiAqICAgdGhlIGtleSBleGNoYW5nZSwgYW5kIHRoZSBjbGllbnQgY2FuIHByb2NlZWQgd2l0aCBpdHMgcGhhc2Ugb2YgdGhlIGtleQogKiAgIGV4Y2hhbmdlLgogKgogKiAgIFVwb24gcmVjZWlwdCBvZiB0aGUgc2VydmVyIGhlbGxvIGRvbmUgbWVzc2FnZSB0aGUgY2xpZW50IHNob3VsZCB2ZXJpZnkKICogICB0aGF0IHRoZSBzZXJ2ZXIgcHJvdmlkZWQgYSB2YWxpZCBjZXJ0aWZpY2F0ZSBpZiByZXF1aXJlZCBhbmQgY2hlY2sgdGhhdAogKiAgIHRoZSBzZXJ2ZXIgaGVsbG8gcGFyYW1ldGVycyBhcmUgYWNjZXB0YWJsZS4KICoKICogc3RydWN0IHt9IFNlcnZlckhlbGxvRG9uZTsKICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZS4KICovCnRscy5oYW5kbGVTZXJ2ZXJIZWxsb0RvbmUgPSBmdW5jdGlvbihjLCByZWNvcmQsIGxlbmd0aCkgewogIC8vIGxlbiBtdXN0IGJlIDAgYnl0ZXMKICBpZihsZW5ndGggPiAwKSB7CiAgICByZXR1cm4gYy5lcnJvcihjLCB7CiAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIFNlcnZlckhlbGxvRG9uZSBtZXNzYWdlLiBJbnZhbGlkIGxlbmd0aC4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5yZWNvcmRfb3ZlcmZsb3cKICAgICAgfQogICAgfSk7CiAgfQoKICBpZihjLnNlcnZlckNlcnRpZmljYXRlID09PSBudWxsKSB7CiAgICAvLyBubyBzZXJ2ZXIgY2VydGlmaWNhdGUgd2FzIHByb3ZpZGVkCiAgICB2YXIgZXJyb3IgPSB7CiAgICAgIG1lc3NhZ2U6ICdObyBzZXJ2ZXIgY2VydGlmaWNhdGUgcHJvdmlkZWQuIE5vdCBlbm91Z2ggc2VjdXJpdHkuJywKICAgICAgc2VuZDogdHJ1ZSwKICAgICAgYWxlcnQ6IHsKICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgIGRlc2NyaXB0aW9uOiB0bHMuQWxlcnQuRGVzY3JpcHRpb24uaW5zdWZmaWNpZW50X3NlY3VyaXR5CiAgICAgIH0KICAgIH07CgogICAgLy8gY2FsbCBhcHBsaWNhdGlvbiBjYWxsYmFjawogICAgdmFyIGRlcHRoID0gMDsKICAgIHZhciByZXQgPSBjLnZlcmlmeShjLCBlcnJvci5hbGVydC5kZXNjcmlwdGlvbiwgZGVwdGgsIFtdKTsKICAgIGlmKHJldCAhPT0gdHJ1ZSkgewogICAgICAvLyBjaGVjayBmb3IgY3VzdG9tIGFsZXJ0IGluZm8KICAgICAgaWYocmV0IHx8IHJldCA9PT0gMCkgewogICAgICAgIC8vIHNldCBjdXN0b20gbWVzc2FnZSBhbmQgYWxlcnQgZGVzY3JpcHRpb24KICAgICAgICBpZih0eXBlb2YgcmV0ID09PSAnb2JqZWN0JyAmJiAhZm9yZ2UudXRpbC5pc0FycmF5KHJldCkpIHsKICAgICAgICAgIGlmKHJldC5tZXNzYWdlKSB7CiAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgPSByZXQubWVzc2FnZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmKHJldC5hbGVydCkgewogICAgICAgICAgICBlcnJvci5hbGVydC5kZXNjcmlwdGlvbiA9IHJldC5hbGVydDsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYodHlwZW9mIHJldCA9PT0gJ251bWJlcicpIHsKICAgICAgICAgIC8vIHNldCBjdXN0b20gYWxlcnQgZGVzY3JpcHRpb24KICAgICAgICAgIGVycm9yLmFsZXJ0LmRlc2NyaXB0aW9uID0gcmV0OwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gc2VuZCBlcnJvcgogICAgICByZXR1cm4gYy5lcnJvcihjLCBlcnJvcik7CiAgICB9CiAgfQoKICAvLyBjcmVhdGUgY2xpZW50IGNlcnRpZmljYXRlIG1lc3NhZ2UgaWYgcmVxdWVzdGVkCiAgaWYoYy5zZXNzaW9uLmNlcnRpZmljYXRlUmVxdWVzdCAhPT0gbnVsbCkgewogICAgcmVjb3JkID0gdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICAgIHR5cGU6IHRscy5Db250ZW50VHlwZS5oYW5kc2hha2UsCiAgICAgIGRhdGE6IHRscy5jcmVhdGVDZXJ0aWZpY2F0ZShjKQogICAgfSk7CiAgICB0bHMucXVldWUoYywgcmVjb3JkKTsKICB9CgogIC8vIGNyZWF0ZSBjbGllbnQga2V5IGV4Y2hhbmdlIG1lc3NhZ2UKICByZWNvcmQgPSB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuaGFuZHNoYWtlLAogICAgIGRhdGE6IHRscy5jcmVhdGVDbGllbnRLZXlFeGNoYW5nZShjKQogIH0pOwogIHRscy5xdWV1ZShjLCByZWNvcmQpOwoKICAvLyBleHBlY3Qgbm8gbWVzc2FnZXMgdW50aWwgdGhlIGZvbGxvd2luZyBjYWxsYmFjayBoYXMgYmVlbiBjYWxsZWQKICBjLmV4cGVjdCA9IFNFUjsKCiAgLy8gY3JlYXRlIGNhbGxiYWNrIHRvIGhhbmRsZSBjbGllbnQgc2lnbmF0dXJlIChmb3IgY2xpZW50LWNlcnRzKQogIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uKGMsIHNpZ25hdHVyZSkgewogICAgaWYoYy5zZXNzaW9uLmNlcnRpZmljYXRlUmVxdWVzdCAhPT0gbnVsbCAmJgogICAgICBjLnNlc3Npb24uY2xpZW50Q2VydGlmaWNhdGUgIT09IG51bGwpIHsKICAgICAgLy8gY3JlYXRlIGNlcnRpZmljYXRlIHZlcmlmeSBtZXNzYWdlCiAgICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuaGFuZHNoYWtlLAogICAgICAgIGRhdGE6IHRscy5jcmVhdGVDZXJ0aWZpY2F0ZVZlcmlmeShjLCBzaWduYXR1cmUpCiAgICAgIH0pKTsKICAgIH0KCiAgICAvLyBjcmVhdGUgY2hhbmdlIGNpcGhlciBzcGVjIG1lc3NhZ2UKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmNoYW5nZV9jaXBoZXJfc3BlYywKICAgICAgZGF0YTogdGxzLmNyZWF0ZUNoYW5nZUNpcGhlclNwZWMoKQogICAgfSkpOwoKICAgIC8vIGNyZWF0ZSBwZW5kaW5nIHN0YXRlCiAgICBjLnN0YXRlLnBlbmRpbmcgPSB0bHMuY3JlYXRlQ29ubmVjdGlvblN0YXRlKGMpOwoKICAgIC8vIGNoYW5nZSBjdXJyZW50IHdyaXRlIHN0YXRlIHRvIHBlbmRpbmcgd3JpdGUgc3RhdGUKICAgIGMuc3RhdGUuY3VycmVudC53cml0ZSA9IGMuc3RhdGUucGVuZGluZy53cml0ZTsKCiAgICAvLyBjcmVhdGUgZmluaXNoZWQgbWVzc2FnZQogICAgdGxzLnF1ZXVlKGMsIHRscy5jcmVhdGVSZWNvcmQoYywgewogICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuaGFuZHNoYWtlLAogICAgICBkYXRhOiB0bHMuY3JlYXRlRmluaXNoZWQoYykKICAgIH0pKTsKCiAgICAvLyBleHBlY3QgYSBzZXJ2ZXIgQ2hhbmdlQ2lwaGVyU3BlYyBtZXNzYWdlIG5leHQKICAgIGMuZXhwZWN0ID0gU0NDOwoKICAgIC8vIHNlbmQgcmVjb3JkcwogICAgdGxzLmZsdXNoKGMpOwoKICAgIC8vIGNvbnRpbnVlCiAgICBjLnByb2Nlc3MoKTsKICB9OwoKICAvLyBpZiB0aGVyZSBpcyBubyBjZXJ0aWZpY2F0ZSByZXF1ZXN0IG9yIG5vIGNsaWVudCBjZXJ0aWZpY2F0ZSwgZG8KICAvLyBjYWxsYmFjayBpbW1lZGlhdGVseQogIGlmKGMuc2Vzc2lvbi5jZXJ0aWZpY2F0ZVJlcXVlc3QgPT09IG51bGwgfHwKICAgIGMuc2Vzc2lvbi5jbGllbnRDZXJ0aWZpY2F0ZSA9PT0gbnVsbCkgewogICAgcmV0dXJuIGNhbGxiYWNrKGMsIG51bGwpOwogIH0KCiAgLy8gb3RoZXJ3aXNlIGdldCB0aGUgY2xpZW50IHNpZ25hdHVyZQogIHRscy5nZXRDbGllbnRTaWduYXR1cmUoYywgY2FsbGJhY2spOwp9OwoKLyoqCiAqIENhbGxlZCB3aGVuIGEgQ2hhbmdlQ2lwaGVyU3BlYyByZWNvcmQgaXMgcmVjZWl2ZWQuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gcmVjb3JkIHRoZSByZWNvcmQuCiAqLwp0bHMuaGFuZGxlQ2hhbmdlQ2lwaGVyU3BlYyA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogIGlmKHJlY29yZC5mcmFnbWVudC5nZXRCeXRlKCkgIT09IDB4MDEpIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ0ludmFsaWQgQ2hhbmdlQ2lwaGVyU3BlYyBtZXNzYWdlIHJlY2VpdmVkLicsCiAgICAgIHNlbmQ6IHRydWUsCiAgICAgIGFsZXJ0OiB7CiAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmlsbGVnYWxfcGFyYW1ldGVyCiAgICAgIH0KICAgIH0pOwogIH0KCiAgLy8gY3JlYXRlIHBlbmRpbmcgc3RhdGUgaWY6CiAgLy8gMS4gUmVzdW1pbmcgc2Vzc2lvbiBpbiBjbGllbnQgbW9kZSBPUgogIC8vIDIuIE5PVCByZXN1bWluZyBzZXNzaW9uIGluIHNlcnZlciBtb2RlCiAgdmFyIGNsaWVudCA9IChjLmVudGl0eSA9PT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KTsKICBpZigoYy5zZXNzaW9uLnJlc3VtaW5nICYmIGNsaWVudCkgfHwgKCFjLnNlc3Npb24ucmVzdW1pbmcgJiYgIWNsaWVudCkpIHsKICAgIGMuc3RhdGUucGVuZGluZyA9IHRscy5jcmVhdGVDb25uZWN0aW9uU3RhdGUoYyk7CiAgfQoKICAvLyBjaGFuZ2UgY3VycmVudCByZWFkIHN0YXRlIHRvIHBlbmRpbmcgcmVhZCBzdGF0ZQogIGMuc3RhdGUuY3VycmVudC5yZWFkID0gYy5zdGF0ZS5wZW5kaW5nLnJlYWQ7CgogIC8vIGNsZWFyIHBlbmRpbmcgc3RhdGUgaWY6CiAgLy8gMS4gTk9UIHJlc3VtaW5nIHNlc3Npb24gaW4gY2xpZW50IG1vZGUgT1IKICAvLyAyLiByZXN1bWluZyBhIHNlc3Npb24gaW4gc2VydmVyIG1vZGUKICBpZigoIWMuc2Vzc2lvbi5yZXN1bWluZyAmJiBjbGllbnQpIHx8IChjLnNlc3Npb24ucmVzdW1pbmcgJiYgIWNsaWVudCkpIHsKICAgIGMuc3RhdGUucGVuZGluZyA9IG51bGw7CiAgfQoKICAvLyBleHBlY3QgYSBGaW5pc2hlZCByZWNvcmQgbmV4dAogIGMuZXhwZWN0ID0gY2xpZW50ID8gU0ZJIDogQ0ZJOwoKICAvLyBjb250aW51ZQogIGMucHJvY2VzcygpOwp9OwoKLyoqCiAqIENhbGxlZCB3aGVuIGEgRmluaXNoZWQgcmVjb3JkIGlzIHJlY2VpdmVkLgogKgogKiBXaGVuIHRoaXMgbWVzc2FnZSB3aWxsIGJlIHNlbnQ6CiAqICAgQSBmaW5pc2hlZCBtZXNzYWdlIGlzIGFsd2F5cyBzZW50IGltbWVkaWF0ZWx5IGFmdGVyIGEgY2hhbmdlCiAqICAgY2lwaGVyIHNwZWMgbWVzc2FnZSB0byB2ZXJpZnkgdGhhdCB0aGUga2V5IGV4Y2hhbmdlIGFuZAogKiAgIGF1dGhlbnRpY2F0aW9uIHByb2Nlc3NlcyB3ZXJlIHN1Y2Nlc3NmdWwuIEl0IGlzIGVzc2VudGlhbCB0aGF0IGEKICogICBjaGFuZ2UgY2lwaGVyIHNwZWMgbWVzc2FnZSBiZSByZWNlaXZlZCBiZXR3ZWVuIHRoZSBvdGhlcgogKiAgIGhhbmRzaGFrZSBtZXNzYWdlcyBhbmQgdGhlIEZpbmlzaGVkIG1lc3NhZ2UuCiAqCiAqIE1lYW5pbmcgb2YgdGhpcyBtZXNzYWdlOgogKiAgIFRoZSBmaW5pc2hlZCBtZXNzYWdlIGlzIHRoZSBmaXJzdCBwcm90ZWN0ZWQgd2l0aCB0aGUganVzdC0KICogICBuZWdvdGlhdGVkIGFsZ29yaXRobXMsIGtleXMsIGFuZCBzZWNyZXRzLiBSZWNpcGllbnRzIG9mIGZpbmlzaGVkCiAqICAgbWVzc2FnZXMgbXVzdCB2ZXJpZnkgdGhhdCB0aGUgY29udGVudHMgYXJlIGNvcnJlY3QuICBPbmNlIGEgc2lkZQogKiAgIGhhcyBzZW50IGl0cyBGaW5pc2hlZCBtZXNzYWdlIGFuZCByZWNlaXZlZCBhbmQgdmFsaWRhdGVkIHRoZQogKiAgIEZpbmlzaGVkIG1lc3NhZ2UgZnJvbSBpdHMgcGVlciwgaXQgbWF5IGJlZ2luIHRvIHNlbmQgYW5kIHJlY2VpdmUKICogICBhcHBsaWNhdGlvbiBkYXRhIG92ZXIgdGhlIGNvbm5lY3Rpb24uCiAqCiAqIHN0cnVjdCB7CiAqICAgb3BhcXVlIHZlcmlmeV9kYXRhW3ZlcmlmeV9kYXRhX2xlbmd0aF07CiAqIH0gRmluaXNoZWQ7CiAqCiAqIHZlcmlmeV9kYXRhCiAqICAgUFJGKG1hc3Rlcl9zZWNyZXQsIGZpbmlzaGVkX2xhYmVsLCBIYXNoKGhhbmRzaGFrZV9tZXNzYWdlcykpCiAqICAgICBbMC4udmVyaWZ5X2RhdGFfbGVuZ3RoLTFdOwogKgogKiBmaW5pc2hlZF9sYWJlbAogKiAgIEZvciBGaW5pc2hlZCBtZXNzYWdlcyBzZW50IGJ5IHRoZSBjbGllbnQsIHRoZSBzdHJpbmcKICogICAiY2xpZW50IGZpbmlzaGVkIi4gRm9yIEZpbmlzaGVkIG1lc3NhZ2VzIHNlbnQgYnkgdGhlIHNlcnZlciwgdGhlCiAqICAgc3RyaW5nICJzZXJ2ZXIgZmluaXNoZWQiLgogKgogKiB2ZXJpZnlfZGF0YV9sZW5ndGggZGVwZW5kcyBvbiB0aGUgY2lwaGVyIHN1aXRlLiBJZiBpdCBpcyBub3Qgc3BlY2lmaWVkCiAqIGJ5IHRoZSBjaXBoZXIgc3VpdGUsIHRoZW4gaXQgaXMgMTIuIFZlcnNpb25zIG9mIFRMUyA8IDEuMiBhbHdheXMgdXNlZAogKiAxMiBieXRlcy4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZS4KICovCnRscy5oYW5kbGVGaW5pc2hlZCA9IGZ1bmN0aW9uKGMsIHJlY29yZCwgbGVuZ3RoKSB7CiAgLy8gcmV3aW5kIHRvIGdldCBmdWxsIGJ5dGVzIGZvciBtZXNzYWdlIHNvIGl0IGNhbiBiZSBtYW51YWxseQogIC8vIGRpZ2VzdGVkIGJlbG93IChzcGVjaWFsIGNhc2UgZm9yIEZpbmlzaGVkIG1lc3NhZ2VzIGJlY2F1c2UgdGhleQogIC8vIG11c3QgYmUgZGlnZXN0ZWQgKmFmdGVyKiBoYW5kbGluZyBhcyBvcHBvc2VkIHRvIGFsbCBvdGhlcnMpCiAgdmFyIGIgPSByZWNvcmQuZnJhZ21lbnQ7CiAgYi5yZWFkIC09IDQ7CiAgdmFyIG1zZ0J5dGVzID0gYi5ieXRlcygpOwogIGIucmVhZCArPSA0OwoKICAvLyBtZXNzYWdlIGNvbnRhaW5zIG9ubHkgdmVyaWZ5X2RhdGEKICB2YXIgdmQgPSByZWNvcmQuZnJhZ21lbnQuZ2V0Qnl0ZXMoKTsKCiAgLy8gZW5zdXJlIHZlcmlmeSBkYXRhIGlzIGNvcnJlY3QKICBiID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBiLnB1dEJ1ZmZlcihjLnNlc3Npb24ubWQ1LmRpZ2VzdCgpKTsKICBiLnB1dEJ1ZmZlcihjLnNlc3Npb24uc2hhMS5kaWdlc3QoKSk7CgogIC8vIHNldCBsYWJlbCBiYXNlZCBvbiBlbnRpdHkgdHlwZQogIHZhciBjbGllbnQgPSAoYy5lbnRpdHkgPT09IHRscy5Db25uZWN0aW9uRW5kLmNsaWVudCk7CiAgdmFyIGxhYmVsID0gY2xpZW50ID8gJ3NlcnZlciBmaW5pc2hlZCcgOiAnY2xpZW50IGZpbmlzaGVkJzsKCiAgLy8gVE9ETzogZGV0ZXJtaW5lIHByZiBmdW5jdGlvbiBhbmQgdmVyaWZ5IGxlbmd0aCBmb3IgVExTIDEuMgogIHZhciBzcCA9IGMuc2Vzc2lvbi5zcDsKICB2YXIgdmRsID0gMTI7CiAgdmFyIHByZiA9IHByZl9UTFMxOwogIGIgPSBwcmYoc3AubWFzdGVyX3NlY3JldCwgbGFiZWwsIGIuZ2V0Qnl0ZXMoKSwgdmRsKTsKICBpZihiLmdldEJ5dGVzKCkgIT09IHZkKSB7CiAgICByZXR1cm4gYy5lcnJvcihjLCB7CiAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIHZlcmlmeV9kYXRhIGluIEZpbmlzaGVkIG1lc3NhZ2UuJywKICAgICAgc2VuZDogdHJ1ZSwKICAgICAgYWxlcnQ6IHsKICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgIGRlc2NyaXB0aW9uOiB0bHMuQWxlcnQuRGVzY3JpcHRpb24uZGVjcnlwdF9lcnJvcgogICAgICB9CiAgICB9KTsKICB9CgogIC8vIGRpZ2VzdCBmaW5pc2hlZCBtZXNzYWdlIG5vdyB0aGF0IGl0IGhhcyBiZWVuIGhhbmRsZWQKICBjLnNlc3Npb24ubWQ1LnVwZGF0ZShtc2dCeXRlcyk7CiAgYy5zZXNzaW9uLnNoYTEudXBkYXRlKG1zZ0J5dGVzKTsKCiAgLy8gcmVzdW1pbmcgc2Vzc2lvbiBhcyBjbGllbnQgb3IgTk9UIHJlc3VtaW5nIHNlc3Npb24gYXMgc2VydmVyCiAgaWYoKGMuc2Vzc2lvbi5yZXN1bWluZyAmJiBjbGllbnQpIHx8ICghYy5zZXNzaW9uLnJlc3VtaW5nICYmICFjbGllbnQpKSB7CiAgICAvLyBjcmVhdGUgY2hhbmdlIGNpcGhlciBzcGVjIG1lc3NhZ2UKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmNoYW5nZV9jaXBoZXJfc3BlYywKICAgICAgZGF0YTogdGxzLmNyZWF0ZUNoYW5nZUNpcGhlclNwZWMoKQogICAgfSkpOwoKICAgIC8vIGNoYW5nZSBjdXJyZW50IHdyaXRlIHN0YXRlIHRvIHBlbmRpbmcgd3JpdGUgc3RhdGUsIGNsZWFyIHBlbmRpbmcKICAgIGMuc3RhdGUuY3VycmVudC53cml0ZSA9IGMuc3RhdGUucGVuZGluZy53cml0ZTsKICAgIGMuc3RhdGUucGVuZGluZyA9IG51bGw7CgogICAgLy8gY3JlYXRlIGZpbmlzaGVkIG1lc3NhZ2UKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhhbmRzaGFrZSwKICAgICAgZGF0YTogdGxzLmNyZWF0ZUZpbmlzaGVkKGMpCiAgICB9KSk7CiAgfQoKICAvLyBleHBlY3QgYXBwbGljYXRpb24gZGF0YSBuZXh0CiAgYy5leHBlY3QgPSBjbGllbnQgPyBTQUQgOiBDQUQ7CgogIC8vIGhhbmRzaGFrZSBjb21wbGV0ZQogIGMuaGFuZHNoYWtpbmcgPSBmYWxzZTsKICArK2MuaGFuZHNoYWtlczsKCiAgLy8gc2F2ZSBhY2Nlc3MgdG8gcGVlciBjZXJ0aWZpY2F0ZQogIGMucGVlckNlcnRpZmljYXRlID0gY2xpZW50ID8KICAgIGMuc2Vzc2lvbi5zZXJ2ZXJDZXJ0aWZpY2F0ZSA6IGMuc2Vzc2lvbi5jbGllbnRDZXJ0aWZpY2F0ZTsKCiAgLy8gc2VuZCByZWNvcmRzCiAgdGxzLmZsdXNoKGMpOwoKICAvLyBub3cgY29ubmVjdGVkCiAgYy5pc0Nvbm5lY3RlZCA9IHRydWU7CiAgYy5jb25uZWN0ZWQoYyk7CgogIC8vIGNvbnRpbnVlCiAgYy5wcm9jZXNzKCk7Cn07CgovKioKICogQ2FsbGVkIHdoZW4gYW4gQWxlcnQgcmVjb3JkIGlzIHJlY2VpdmVkLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKi8KdGxzLmhhbmRsZUFsZXJ0ID0gZnVuY3Rpb24oYywgcmVjb3JkKSB7CiAgLy8gcmVhZCBhbGVydAogIHZhciBiID0gcmVjb3JkLmZyYWdtZW50OwogIHZhciBhbGVydCA9IHsKICAgIGxldmVsOiBiLmdldEJ5dGUoKSwKICAgIGRlc2NyaXB0aW9uOiBiLmdldEJ5dGUoKQogIH07CgogIC8vIFRPRE86IGNvbnNpZGVyIHVzaW5nIGEgdGFibGU/CiAgLy8gZ2V0IGFwcHJvcHJpYXRlIG1lc3NhZ2UKICB2YXIgbXNnOwogIHN3aXRjaChhbGVydC5kZXNjcmlwdGlvbikgewogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmNsb3NlX25vdGlmeToKICAgIG1zZyA9ICdDb25uZWN0aW9uIGNsb3NlZC4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24udW5leHBlY3RlZF9tZXNzYWdlOgogICAgbXNnID0gJ1VuZXhwZWN0ZWQgbWVzc2FnZS4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uYmFkX3JlY29yZF9tYWM6CiAgICBtc2cgPSAnQmFkIHJlY29yZCBNQUMuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmRlY3J5cHRpb25fZmFpbGVkOgogICAgbXNnID0gJ0RlY3J5cHRpb24gZmFpbGVkLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5yZWNvcmRfb3ZlcmZsb3c6CiAgICBtc2cgPSAnUmVjb3JkIG92ZXJmbG93Lic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5kZWNvbXByZXNzaW9uX2ZhaWx1cmU6CiAgICBtc2cgPSAnRGVjb21wcmVzc2lvbiBmYWlsZWQuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmhhbmRzaGFrZV9mYWlsdXJlOgogICAgbXNnID0gJ0hhbmRzaGFrZSBmYWlsdXJlLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5iYWRfY2VydGlmaWNhdGU6CiAgICBtc2cgPSAnQmFkIGNlcnRpZmljYXRlLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi51bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZToKICAgIG1zZyA9ICdVbnN1cHBvcnRlZCBjZXJ0aWZpY2F0ZS4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uY2VydGlmaWNhdGVfcmV2b2tlZDoKICAgIG1zZyA9ICdDZXJ0aWZpY2F0ZSByZXZva2VkLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5jZXJ0aWZpY2F0ZV9leHBpcmVkOgogICAgbXNnID0gJ0NlcnRpZmljYXRlIGV4cGlyZWQuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmNlcnRpZmljYXRlX3Vua25vd246CiAgICBtc2cgPSAnQ2VydGlmaWNhdGUgdW5rbm93bi4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uaWxsZWdhbF9wYXJhbWV0ZXI6CiAgICBtc2cgPSAnSWxsZWdhbCBwYXJhbWV0ZXIuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLnVua25vd25fY2E6CiAgICBtc2cgPSAnVW5rbm93biBjZXJ0aWZpY2F0ZSBhdXRob3JpdHkuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmFjY2Vzc19kZW5pZWQ6CiAgICBtc2cgPSAnQWNjZXNzIGRlbmllZC4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uZGVjb2RlX2Vycm9yOgogICAgbXNnID0gJ0RlY29kZSBlcnJvci4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uZGVjcnlwdF9lcnJvcjoKICAgIG1zZyA9ICdEZWNyeXB0IGVycm9yLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5leHBvcnRfcmVzdHJpY3Rpb246CiAgICBtc2cgPSAnRXhwb3J0IHJlc3RyaWN0aW9uLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5wcm90b2NvbF92ZXJzaW9uOgogICAgbXNnID0gJ1Vuc3VwcG9ydGVkIHByb3RvY29sIHZlcnNpb24uJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmluc3VmZmljaWVudF9zZWN1cml0eToKICAgIG1zZyA9ICdJbnN1ZmZpY2llbnQgc2VjdXJpdHkuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yOgogICAgbXNnID0gJ0ludGVybmFsIGVycm9yLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi51c2VyX2NhbmNlbGVkOgogICAgbXNnID0gJ1VzZXIgY2FuY2VsZWQuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLm5vX3JlbmVnb3RpYXRpb246CiAgICBtc2cgPSAnUmVuZWdvdGlhdGlvbiBub3Qgc3VwcG9ydGVkLic7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgbXNnID0gJ1Vua25vd24gZXJyb3IuJzsKICAgIGJyZWFrOwogIH0KCiAgLy8gY2xvc2UgY29ubmVjdGlvbiBvbiBjbG9zZV9ub3RpZnksIG5vdCBhbiBlcnJvcgogIGlmKGFsZXJ0LmRlc2NyaXB0aW9uID09PSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uY2xvc2Vfbm90aWZ5KSB7CiAgICByZXR1cm4gYy5jbG9zZSgpOwogIH0KCiAgLy8gY2FsbCBlcnJvciBoYW5kbGVyCiAgYy5lcnJvcihjLCB7CiAgICBtZXNzYWdlOiBtc2csCiAgICBzZW5kOiBmYWxzZSwKICAgIC8vIG9yaWdpbiBpcyB0aGUgb3Bwb3NpdGUgZW5kCiAgICBvcmlnaW46IChjLmVudGl0eSA9PT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KSA/ICdzZXJ2ZXInIDogJ2NsaWVudCcsCiAgICBhbGVydDogYWxlcnQKICB9KTsKCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIEhhbmRzaGFrZSByZWNvcmQgaXMgcmVjZWl2ZWQuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gcmVjb3JkIHRoZSByZWNvcmQuCiAqLwp0bHMuaGFuZGxlSGFuZHNoYWtlID0gZnVuY3Rpb24oYywgcmVjb3JkKSB7CiAgLy8gZ2V0IHRoZSBoYW5kc2hha2UgdHlwZSBhbmQgbWVzc2FnZSBsZW5ndGgKICB2YXIgYiA9IHJlY29yZC5mcmFnbWVudDsKICB2YXIgdHlwZSA9IGIuZ2V0Qnl0ZSgpOwogIHZhciBsZW5ndGggPSBiLmdldEludDI0KCk7CgogIC8vIHNlZSBpZiB0aGUgcmVjb3JkIGZyYWdtZW50IGRvZXNuJ3QgeWV0IGNvbnRhaW4gdGhlIGZ1bGwgbWVzc2FnZQogIGlmKGxlbmd0aCA+IGIubGVuZ3RoKCkpIHsKICAgIC8vIGNhY2hlIHRoZSByZWNvcmQsIGNsZWFyIGl0cyBmcmFnbWVudCwgYW5kIHJlc2V0IHRoZSBidWZmZXIgcmVhZAogICAgLy8gcG9pbnRlciBiZWZvcmUgdGhlIHR5cGUgYW5kIGxlbmd0aCB3ZXJlIHJlYWQKICAgIGMuZnJhZ21lbnRlZCA9IHJlY29yZDsKICAgIHJlY29yZC5mcmFnbWVudCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBiLnJlYWQgLT0gNDsKCiAgICAvLyBjb250aW51ZQogICAgcmV0dXJuIGMucHJvY2VzcygpOwogIH0KCiAgLy8gZnVsbCBtZXNzYWdlIG5vdyBhdmFpbGFibGUsIGNsZWFyIGNhY2hlLCByZXNldCByZWFkIHBvaW50ZXIgdG8KICAvLyBiZWZvcmUgdHlwZSBhbmQgbGVuZ3RoCiAgYy5mcmFnbWVudGVkID0gbnVsbDsKICBiLnJlYWQgLT0gNDsKCiAgLy8gc2F2ZSB0aGUgaGFuZHNoYWtlIGJ5dGVzIGZvciBkaWdlc3Rpb24gYWZ0ZXIgaGFuZGxlciBpcyBmb3VuZAogIC8vIChpbmNsdWRlIHR5cGUgYW5kIGxlbmd0aCBvZiBoYW5kc2hha2UgbXNnKQogIHZhciBieXRlcyA9IGIuYnl0ZXMobGVuZ3RoICsgNCk7CgogIC8vIHJlc3RvcmUgcmVhZCBwb2ludGVyCiAgYi5yZWFkICs9IDQ7CgogIC8vIGhhbmRsZSBleHBlY3RlZCBtZXNzYWdlCiAgaWYodHlwZSBpbiBoc1RhYmxlW2MuZW50aXR5XVtjLmV4cGVjdF0pIHsKICAgIC8vIGluaXRpYWxpemUgc2VydmVyIHNlc3Npb24KICAgIGlmKGMuZW50aXR5ID09PSB0bHMuQ29ubmVjdGlvbkVuZC5zZXJ2ZXIgJiYgIWMub3BlbiAmJiAhYy5mYWlsKSB7CiAgICAgIGMuaGFuZHNoYWtpbmcgPSB0cnVlOwogICAgICBjLnNlc3Npb24gPSB7CiAgICAgICAgdmVyc2lvbjogbnVsbCwKICAgICAgICBleHRlbnNpb25zOiB7CiAgICAgICAgICBzZXJ2ZXJfbmFtZTogewogICAgICAgICAgICBzZXJ2ZXJOYW1lTGlzdDogW10KICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGNpcGhlclN1aXRlOiBudWxsLAogICAgICAgIGNvbXByZXNzaW9uTWV0aG9kOiBudWxsLAogICAgICAgIHNlcnZlckNlcnRpZmljYXRlOiBudWxsLAogICAgICAgIGNsaWVudENlcnRpZmljYXRlOiBudWxsLAogICAgICAgIG1kNTogZm9yZ2UubWQubWQ1LmNyZWF0ZSgpLAogICAgICAgIHNoYTE6IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCkKICAgICAgfTsKICAgIH0KCiAgICAvKiBVcGRhdGUgaGFuZHNoYWtlIG1lc3NhZ2VzIGRpZ2VzdC4gRmluaXNoZWQgYW5kIENlcnRpZmljYXRlVmVyaWZ5CiAgICAgIG1lc3NhZ2VzIGFyZSBub3QgZGlnZXN0ZWQgaGVyZS4gVGhleSBjYW4ndCBiZSBkaWdlc3RlZCBhcyBwYXJ0IG9mCiAgICAgIHRoZSB2ZXJpZnlfZGF0YSB0aGF0IHRoZXkgY29udGFpbi4gVGhlc2UgbWVzc2FnZXMgYXJlIG1hbnVhbGx5CiAgICAgIGRpZ2VzdGVkIGluIHRoZWlyIGhhbmRsZXJzLiBIZWxsb1JlcXVlc3QgbWVzc2FnZXMgYXJlIHNpbXBseSBuZXZlcgogICAgICBpbmNsdWRlZCBpbiB0aGUgaGFuZHNoYWtlIG1lc3NhZ2UgZGlnZXN0IGFjY29yZGluZyB0byBzcGVjLiAqLwogICAgaWYodHlwZSAhPT0gdGxzLkhhbmRzaGFrZVR5cGUuaGVsbG9fcmVxdWVzdCAmJgogICAgICB0eXBlICE9PSB0bHMuSGFuZHNoYWtlVHlwZS5jZXJ0aWZpY2F0ZV92ZXJpZnkgJiYKICAgICAgdHlwZSAhPT0gdGxzLkhhbmRzaGFrZVR5cGUuZmluaXNoZWQpIHsKICAgICAgYy5zZXNzaW9uLm1kNS51cGRhdGUoYnl0ZXMpOwogICAgICBjLnNlc3Npb24uc2hhMS51cGRhdGUoYnl0ZXMpOwogICAgfQoKICAgIC8vIGhhbmRsZSBzcGVjaWZpYyBoYW5kc2hha2UgdHlwZSByZWNvcmQKICAgIGhzVGFibGVbYy5lbnRpdHldW2MuZXhwZWN0XVt0eXBlXShjLCByZWNvcmQsIGxlbmd0aCk7CiAgfSBlbHNlIHsKICAgIC8vIHVuZXhwZWN0ZWQgcmVjb3JkCiAgICB0bHMuaGFuZGxlVW5leHBlY3RlZChjLCByZWNvcmQpOwogIH0KfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhbiBBcHBsaWNhdGlvbkRhdGEgcmVjb3JkIGlzIHJlY2VpdmVkLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKi8KdGxzLmhhbmRsZUFwcGxpY2F0aW9uRGF0YSA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogIC8vIGJ1ZmZlciBkYXRhLCBub3RpZnkgdGhhdCBpdHMgcmVhZHkKICBjLmRhdGEucHV0QnVmZmVyKHJlY29yZC5mcmFnbWVudCk7CiAgYy5kYXRhUmVhZHkoYyk7CgogIC8vIGNvbnRpbnVlCiAgYy5wcm9jZXNzKCk7Cn07CgovKioKICogQ2FsbGVkIHdoZW4gYSBIZWFydGJlYXQgcmVjb3JkIGlzIHJlY2VpdmVkLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKi8KdGxzLmhhbmRsZUhlYXJ0YmVhdCA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogIC8vIGdldCB0aGUgaGVhcnRiZWF0IHR5cGUgYW5kIHBheWxvYWQKICB2YXIgYiA9IHJlY29yZC5mcmFnbWVudDsKICB2YXIgdHlwZSA9IGIuZ2V0Qnl0ZSgpOwogIHZhciBsZW5ndGggPSBiLmdldEludDE2KCk7CiAgdmFyIHBheWxvYWQgPSBiLmdldEJ5dGVzKGxlbmd0aCk7CgogIGlmKHR5cGUgPT09IHRscy5IZWFydGJlYXRNZXNzYWdlVHlwZS5oZWFydGJlYXRfcmVxdWVzdCkgewogICAgLy8gZGlzY2FyZCByZXF1ZXN0IGR1cmluZyBoYW5kc2hha2Ugb3IgaWYgbGVuZ3RoIGlzIHRvbyBsYXJnZQogICAgaWYoYy5oYW5kc2hha2luZyB8fCBsZW5ndGggPiBwYXlsb2FkLmxlbmd0aCkgewogICAgICAvLyBjb250aW51ZQogICAgICByZXR1cm4gYy5wcm9jZXNzKCk7CiAgICB9CiAgICAvLyByZXRyYW5zbWl0IHBheWxvYWQKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhlYXJ0YmVhdCwKICAgICAgZGF0YTogdGxzLmNyZWF0ZUhlYXJ0YmVhdCgKICAgICAgICB0bHMuSGVhcnRiZWF0TWVzc2FnZVR5cGUuaGVhcnRiZWF0X3Jlc3BvbnNlLCBwYXlsb2FkKQogICAgfSkpOwogICAgdGxzLmZsdXNoKGMpOwogIH0gZWxzZSBpZih0eXBlID09PSB0bHMuSGVhcnRiZWF0TWVzc2FnZVR5cGUuaGVhcnRiZWF0X3Jlc3BvbnNlKSB7CiAgICAvLyBjaGVjayBwYXlsb2FkIGFnYWluc3QgZXhwZWN0ZWQgcGF5bG9hZCwgZGlzY2FyZCBoZWFydGJlYXQgaWYgbm8gbWF0Y2gKICAgIGlmKHBheWxvYWQgIT09IGMuZXhwZWN0ZWRIZWFydGJlYXRQYXlsb2FkKSB7CiAgICAgIC8vIGNvbnRpbnVlCiAgICAgIHJldHVybiBjLnByb2Nlc3MoKTsKICAgIH0KCiAgICAvLyBub3RpZnkgdGhhdCBhIHZhbGlkIGhlYXJ0YmVhdCB3YXMgcmVjZWl2ZWQKICAgIGlmKGMuaGVhcnRiZWF0UmVjZWl2ZWQpIHsKICAgICAgYy5oZWFydGJlYXRSZWNlaXZlZChjLCBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihwYXlsb2FkKSk7CiAgICB9CiAgfQoKICAvLyBjb250aW51ZQogIGMucHJvY2VzcygpOwp9OwoKLyoqCiAqIFRoZSB0cmFuc2lzdGlvbmFsIHN0YXRlIHRhYmxlcyBmb3IgcmVjZWl2aW5nIFRMUyByZWNvcmRzLiBJdCBtYXBzIHRoZQogKiBjdXJyZW50IFRMUyBlbmdpbmUgc3RhdGUgYW5kIGEgcmVjZWl2ZWQgcmVjb3JkIHRvIGEgZnVuY3Rpb24gdG8gaGFuZGxlIHRoZQogKiByZWNvcmQgYW5kIHVwZGF0ZSB0aGUgc3RhdGUuCiAqCiAqIEZvciBpbnN0YW5jZSwgaWYgdGhlIGN1cnJlbnQgc3RhdGUgaXMgU0hFLCB0aGVuIHRoZSBUTFMgZW5naW5lIGlzIGV4cGVjdGluZwogKiBhIFNlcnZlckhlbGxvIHJlY29yZC4gT25jZSBhIHJlY29yZCBpcyByZWNlaXZlZCwgdGhlIGhhbmRsZXIgZnVuY3Rpb24gaXMKICogbG9va2VkIHVwIHVzaW5nIHRoZSBzdGF0ZSBTSEUgYW5kIHRoZSByZWNvcmQncyBjb250ZW50IHR5cGUuCiAqCiAqIFRoZSByZXN1bHRpbmcgZnVuY3Rpb24gd2lsbCBlaXRoZXIgYmUgYW4gZXJyb3IgaGFuZGxlciBvciBhIHJlY29yZCBoYW5kbGVyLgogKiBUaGUgZnVuY3Rpb24gd2lsbCB0YWtlIHdoYXRldmVyIGFjdGlvbiBpcyBhcHByb3ByaWF0ZSBhbmQgdXBkYXRlIHRoZSBzdGF0ZQogKiBmb3IgdGhlIG5leHQgcmVjb3JkLgogKgogKiBUaGUgc3RhdGVzIGFyZSBhbGwgYmFzZWQgb24gcG9zc2libGUgc2VydmVyIHJlY29yZCB0eXBlcy4gTm90ZSB0aGF0IHRoZQogKiBjbGllbnQgd2lsbCBuZXZlciBzcGVjaWZpY2FsbHkgZXhwZWN0IHRvIHJlY2VpdmUgYSBIZWxsb1JlcXVlc3Qgb3IgYW4gYWxlcnQKICogZnJvbSB0aGUgc2VydmVyIHNvIHRoZXJlIGlzIG5vIHN0YXRlIHRoYXQgcmVmbGVjdHMgdGhpcy4gVGhlc2UgbWVzc2FnZXMgbWF5CiAqIG9jY3VyIGF0IGFueSB0aW1lLgogKgogKiBUaGVyZSBhcmUgdHdvIHRhYmxlcyBmb3IgbWFwcGluZyBzdGF0ZXMgYmVjYXVzZSB0aGVyZSBpcyBhIHNlY29uZCB0aWVyIG9mCiAqIHR5cGVzIGZvciBoYW5kc2hha2UgbWVzc2FnZXMuIE9uY2UgYSByZWNvcmQgd2l0aCBhIGNvbnRlbnQgdHlwZSBvZiBoYW5kc2hha2UKICogaXMgcmVjZWl2ZWQsIHRoZSBoYW5kc2hha2UgcmVjb3JkIGhhbmRsZXIgd2lsbCBsb29rIHVwIHRoZSBoYW5kc2hha2UgdHlwZSBpbgogKiB0aGUgc2Vjb25kYXJ5IG1hcCB0byBnZXQgaXRzIGFwcHJvcHJpYXRlIGhhbmRsZXIuCiAqCiAqIFZhbGlkIG1lc3NhZ2Ugb3JkZXJzIGFyZSBhcyBmb2xsb3dzOgogKgogKiA9PT09PT09PT09PT09PT09PT09PT09PUZVTEwgSEFORFNIQUtFPT09PT09PT09PT09PT09PT09PT09PQogKiBDbGllbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlcnZlcgogKgogKiBDbGllbnRIZWxsbyAgICAgICAgICAgICAgICAgIC0tLS0tLS0tPgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXJ2ZXJIZWxsbwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENlcnRpZmljYXRlKgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlcnZlcktleUV4Y2hhbmdlKgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVSZXF1ZXN0KgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwtLS0tLS0tLSAgICAgIFNlcnZlckhlbGxvRG9uZQogKiBDZXJ0aWZpY2F0ZSoKICogQ2xpZW50S2V5RXhjaGFuZ2UKICogQ2VydGlmaWNhdGVWZXJpZnkqCiAqIFtDaGFuZ2VDaXBoZXJTcGVjXQogKiBGaW5pc2hlZCAgICAgICAgICAgICAgICAgICAgIC0tLS0tLS0tPgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtDaGFuZ2VDaXBoZXJTcGVjXQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwtLS0tLS0tLSAgICAgICAgICAgICBGaW5pc2hlZAogKiBBcHBsaWNhdGlvbiBEYXRhICAgICAgICAgICAgIDwtLS0tLS0tPiAgICAgQXBwbGljYXRpb24gRGF0YQogKgogKiA9PT09PT09PT09PT09PT09PT09PT1TRVNTSU9OIFJFU1VNUFRJT049PT09PT09PT09PT09PT09PT09PT0KICogQ2xpZW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VydmVyCiAqCiAqIENsaWVudEhlbGxvICAgICAgICAgICAgICAgICAgIC0tLS0tLS0tPgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VydmVySGVsbG8KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW0NoYW5nZUNpcGhlclNwZWNdCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwtLS0tLS0tLSAgICAgICAgICAgICBGaW5pc2hlZAogKiBbQ2hhbmdlQ2lwaGVyU3BlY10KICogRmluaXNoZWQgICAgICAgICAgICAgICAgICAgICAgLS0tLS0tLS0+CiAqIEFwcGxpY2F0aW9uIERhdGEgICAgICAgICAgICAgIDwtLS0tLS0tPiAgICAgQXBwbGljYXRpb24gRGF0YQogKi8KLy8gY2xpZW50IGV4cGVjdCBzdGF0ZXMgKGluZGljYXRlIHdoaWNoIHJlY29yZHMgYXJlIGV4cGVjdGVkIHRvIGJlIHJlY2VpdmVkKQp2YXIgU0hFID0gMDsgLy8gcmN2IHNlcnZlciBoZWxsbwp2YXIgU0NFID0gMTsgLy8gcmN2IHNlcnZlciBjZXJ0aWZpY2F0ZQp2YXIgU0tFID0gMjsgLy8gcmN2IHNlcnZlciBrZXkgZXhjaGFuZ2UKdmFyIFNDUiA9IDM7IC8vIHJjdiBjZXJ0aWZpY2F0ZSByZXF1ZXN0CnZhciBTSEQgPSA0OyAvLyByY3Ygc2VydmVyIGhlbGxvIGRvbmUKdmFyIFNDQyA9IDU7IC8vIHJjdiBjaGFuZ2UgY2lwaGVyIHNwZWMKdmFyIFNGSSA9IDY7IC8vIHJjdiBmaW5pc2hlZAp2YXIgU0FEID0gNzsgLy8gcmN2IGFwcGxpY2F0aW9uIGRhdGEKdmFyIFNFUiA9IDg7IC8vIG5vdCBleHBlY3RpbmcgYW55IG1lc3NhZ2VzIGF0IHRoaXMgcG9pbnQKCi8vIHNlcnZlciBleHBlY3Qgc3RhdGVzCnZhciBDSEUgPSAwOyAvLyByY3YgY2xpZW50IGhlbGxvCnZhciBDQ0UgPSAxOyAvLyByY3YgY2xpZW50IGNlcnRpZmljYXRlCnZhciBDS0UgPSAyOyAvLyByY3YgY2xpZW50IGtleSBleGNoYW5nZQp2YXIgQ0NWID0gMzsgLy8gcmN2IGNlcnRpZmljYXRlIHZlcmlmeQp2YXIgQ0NDID0gNDsgLy8gcmN2IGNoYW5nZSBjaXBoZXIgc3BlYwp2YXIgQ0ZJID0gNTsgLy8gcmN2IGZpbmlzaGVkCnZhciBDQUQgPSA2OyAvLyByY3YgYXBwbGljYXRpb24gZGF0YQp2YXIgQ0VSID0gNzsgLy8gbm90IGV4cGVjdGluZyBhbnkgbWVzc2FnZXMgYXQgdGhpcyBwb2ludAoKLy8gbWFwIGNsaWVudCBjdXJyZW50IGV4cGVjdCBzdGF0ZSBhbmQgY29udGVudCB0eXBlIHRvIGZ1bmN0aW9uCnZhciBfXyA9IHRscy5oYW5kbGVVbmV4cGVjdGVkOwp2YXIgUjAgPSB0bHMuaGFuZGxlQ2hhbmdlQ2lwaGVyU3BlYzsKdmFyIFIxID0gdGxzLmhhbmRsZUFsZXJ0Owp2YXIgUjIgPSB0bHMuaGFuZGxlSGFuZHNoYWtlOwp2YXIgUjMgPSB0bHMuaGFuZGxlQXBwbGljYXRpb25EYXRhOwp2YXIgUjQgPSB0bHMuaGFuZGxlSGVhcnRiZWF0Owp2YXIgY3RUYWJsZSA9IFtdOwpjdFRhYmxlW3Rscy5Db25uZWN0aW9uRW5kLmNsaWVudF0gPSBbCi8vICAgICAgQ0MsQUwsSFMsQUQsSEIKLypTSEUqL1tfXyxSMSxSMixfXyxSNF0sCi8qU0NFKi9bX18sUjEsUjIsX18sUjRdLAovKlNLRSovW19fLFIxLFIyLF9fLFI0XSwKLypTQ1IqL1tfXyxSMSxSMixfXyxSNF0sCi8qU0hEKi9bX18sUjEsUjIsX18sUjRdLAovKlNDQyovW1IwLFIxLF9fLF9fLFI0XSwKLypTRkkqL1tfXyxSMSxSMixfXyxSNF0sCi8qU0FEKi9bX18sUjEsUjIsUjMsUjRdLAovKlNFUiovW19fLFIxLFIyLF9fLFI0XQpdOwoKLy8gbWFwIHNlcnZlciBjdXJyZW50IGV4cGVjdCBzdGF0ZSBhbmQgY29udGVudCB0eXBlIHRvIGZ1bmN0aW9uCmN0VGFibGVbdGxzLkNvbm5lY3Rpb25FbmQuc2VydmVyXSA9IFsKLy8gICAgICBDQyxBTCxIUyxBRAovKkNIRSovW19fLFIxLFIyLF9fLFI0XSwKLypDQ0UqL1tfXyxSMSxSMixfXyxSNF0sCi8qQ0tFKi9bX18sUjEsUjIsX18sUjRdLAovKkNDViovW19fLFIxLFIyLF9fLFI0XSwKLypDQ0MqL1tSMCxSMSxfXyxfXyxSNF0sCi8qQ0ZJKi9bX18sUjEsUjIsX18sUjRdLAovKkNBRCovW19fLFIxLFIyLFIzLFI0XSwKLypDRVIqL1tfXyxSMSxSMixfXyxSNF0KXTsKCi8vIG1hcCBjbGllbnQgY3VycmVudCBleHBlY3Qgc3RhdGUgYW5kIGhhbmRzaGFrZSB0eXBlIHRvIGZ1bmN0aW9uCnZhciBIMCA9IHRscy5oYW5kbGVIZWxsb1JlcXVlc3Q7CnZhciBIMSA9IHRscy5oYW5kbGVTZXJ2ZXJIZWxsbzsKdmFyIEgyID0gdGxzLmhhbmRsZUNlcnRpZmljYXRlOwp2YXIgSDMgPSB0bHMuaGFuZGxlU2VydmVyS2V5RXhjaGFuZ2U7CnZhciBINCA9IHRscy5oYW5kbGVDZXJ0aWZpY2F0ZVJlcXVlc3Q7CnZhciBINSA9IHRscy5oYW5kbGVTZXJ2ZXJIZWxsb0RvbmU7CnZhciBINiA9IHRscy5oYW5kbGVGaW5pc2hlZDsKdmFyIGhzVGFibGUgPSBbXTsKaHNUYWJsZVt0bHMuQ29ubmVjdGlvbkVuZC5jbGllbnRdID0gWwovLyAgICAgIEhSLDAxLFNILDAzLDA0LDA1LDA2LDA3LDA4LDA5LDEwLFNDLFNLLENSLEhELDE1LENLLDE3LDE4LDE5LEZJCi8qU0hFKi9bX18sX18sSDEsX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX19dLAovKlNDRSovW0gwLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLEgyLEgzLEg0LEg1LF9fLF9fLF9fLF9fLF9fLF9fXSwKLypTS0UqL1tIMCxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxIMyxINCxINSxfXyxfXyxfXyxfXyxfXyxfX10sCi8qU0NSKi9bSDAsX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sSDQsSDUsX18sX18sX18sX18sX18sX19dLAovKlNIRCovW0gwLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLEg1LF9fLF9fLF9fLF9fLF9fLF9fXSwKLypTQ0MqL1tIMCxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfX10sCi8qU0ZJKi9bSDAsX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sSDZdLAovKlNBRCovW0gwLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fXSwKLypTRVIqL1tIMCxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfX10KXTsKCi8vIG1hcCBzZXJ2ZXIgY3VycmVudCBleHBlY3Qgc3RhdGUgYW5kIGhhbmRzaGFrZSB0eXBlIHRvIGZ1bmN0aW9uCi8vIE5vdGU6IENBRFtDSF0gZG9lcyBub3QgbWFwIHRvIEZCIGJlY2F1c2UgcmVuZWdvdGF0aW9uIGlzIHByb2hpYml0ZWQKdmFyIEg3ID0gdGxzLmhhbmRsZUNsaWVudEhlbGxvOwp2YXIgSDggPSB0bHMuaGFuZGxlQ2xpZW50S2V5RXhjaGFuZ2U7CnZhciBIOSA9IHRscy5oYW5kbGVDZXJ0aWZpY2F0ZVZlcmlmeTsKaHNUYWJsZVt0bHMuQ29ubmVjdGlvbkVuZC5zZXJ2ZXJdID0gWwovLyAgICAgIDAxLENILDAyLDAzLDA0LDA1LDA2LDA3LDA4LDA5LDEwLENDLDEyLDEzLDE0LENWLENLLDE3LDE4LDE5LEZJCi8qQ0hFKi9bX18sSDcsX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX19dLAovKkNDRSovW19fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLEgyLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fXSwKLypDS0UqL1tfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxIOCxfXyxfXyxfXyxfX10sCi8qQ0NWKi9bX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sSDksX18sX18sX18sX18sX19dLAovKkNDQyovW19fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fXSwKLypDRkkqL1tfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxINl0sCi8qQ0FEKi9bX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX19dLAovKkNFUiovW19fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fXQpdOwoKLyoqCiAqIEdlbmVyYXRlcyB0aGUgbWFzdGVyX3NlY3JldCBhbmQga2V5cyB1c2luZyB0aGUgZ2l2ZW4gc2VjdXJpdHkgcGFyYW1ldGVycy4KICoKICogVGhlIHNlY3VyaXR5IHBhcmFtZXRlcnMgZm9yIGEgVExTIGNvbm5lY3Rpb24gc3RhdGUgYXJlIGRlZmluZWQgYXMgc3VjaDoKICoKICogc3RydWN0IHsKICogICBDb25uZWN0aW9uRW5kICAgICAgICAgIGVudGl0eTsKICogICBQUkZBbGdvcml0aG0gICAgICAgICAgIHByZl9hbGdvcml0aG07CiAqICAgQnVsa0NpcGhlckFsZ29yaXRobSAgICBidWxrX2NpcGhlcl9hbGdvcml0aG07CiAqICAgQ2lwaGVyVHlwZSAgICAgICAgICAgICBjaXBoZXJfdHlwZTsKICogICB1aW50OCAgICAgICAgICAgICAgICAgIGVuY19rZXlfbGVuZ3RoOwogKiAgIHVpbnQ4ICAgICAgICAgICAgICAgICAgYmxvY2tfbGVuZ3RoOwogKiAgIHVpbnQ4ICAgICAgICAgICAgICAgICAgZml4ZWRfaXZfbGVuZ3RoOwogKiAgIHVpbnQ4ICAgICAgICAgICAgICAgICAgcmVjb3JkX2l2X2xlbmd0aDsKICogICBNQUNBbGdvcml0aG0gICAgICAgICAgIG1hY19hbGdvcml0aG07CiAqICAgdWludDggICAgICAgICAgICAgICAgICBtYWNfbGVuZ3RoOwogKiAgIHVpbnQ4ICAgICAgICAgICAgICAgICAgbWFjX2tleV9sZW5ndGg7CiAqICAgQ29tcHJlc3Npb25NZXRob2QgICAgICBjb21wcmVzc2lvbl9hbGdvcml0aG07CiAqICAgb3BhcXVlICAgICAgICAgICAgICAgICBtYXN0ZXJfc2VjcmV0WzQ4XTsKICogICBvcGFxdWUgICAgICAgICAgICAgICAgIGNsaWVudF9yYW5kb21bMzJdOwogKiAgIG9wYXF1ZSAgICAgICAgICAgICAgICAgc2VydmVyX3JhbmRvbVszMl07CiAqIH0gU2VjdXJpdHlQYXJhbWV0ZXJzOwogKgogKiBOb3RlIHRoYXQgdGhpcyBkZWZpbml0aW9uIGlzIGZyb20gVExTIDEuMi4gSW4gVExTIDEuMCBzb21lIG9mIHRoZXNlCiAqIHBhcmFtZXRlcnMgYXJlIGlnbm9yZWQgYmVjYXVzZSwgZm9yIGluc3RhbmNlLCB0aGUgUFJGQWxnb3JpdGhtIGlzIGEKICogYnVpbHRpbi1maXhlZCBhbGdvcml0aG0gY29tYmluaW5nIGl0ZXJhdGlvbnMgb2YgTUQ1IGFuZCBTSEEtMSBpbiBUTFMgMS4wLgogKgogKiBUaGUgUmVjb3JkIFByb3RvY29sIHJlcXVpcmVzIGFuIGFsZ29yaXRobSB0byBnZW5lcmF0ZSBrZXlzIHJlcXVpcmVkIGJ5IHRoZQogKiBjdXJyZW50IGNvbm5lY3Rpb24gc3RhdGUuCiAqCiAqIFRoZSBtYXN0ZXIgc2VjcmV0IGlzIGV4cGFuZGVkIGludG8gYSBzZXF1ZW5jZSBvZiBzZWN1cmUgYnl0ZXMsIHdoaWNoIGlzIHRoZW4KICogc3BsaXQgdG8gYSBjbGllbnQgd3JpdGUgTUFDIGtleSwgYSBzZXJ2ZXIgd3JpdGUgTUFDIGtleSwgYSBjbGllbnQgd3JpdGUKICogZW5jcnlwdGlvbiBrZXksIGFuZCBhIHNlcnZlciB3cml0ZSBlbmNyeXB0aW9uIGtleS4gSW4gVExTIDEuMCBhIGNsaWVudCB3cml0ZQogKiBJViBhbmQgc2VydmVyIHdyaXRlIElWIGFyZSBhbHNvIGdlbmVyYXRlZC4gRWFjaCBvZiB0aGVzZSBpcyBnZW5lcmF0ZWQgZnJvbQogKiB0aGUgYnl0ZSBzZXF1ZW5jZSBpbiB0aGF0IG9yZGVyLiBVbnVzZWQgdmFsdWVzIGFyZSBlbXB0eS4gSW4gVExTIDEuMiwgc29tZQogKiBBRUFEIGNpcGhlcnMgbWF5IGFkZGl0aW9uYWxseSByZXF1aXJlIGEgY2xpZW50IHdyaXRlIElWIGFuZCBhIHNlcnZlciB3cml0ZQogKiBJViAoc2VlIFNlY3Rpb24gNi4yLjMuMykuCiAqCiAqIFdoZW4ga2V5cywgTUFDIGtleXMsIGFuZCBJVnMgYXJlIGdlbmVyYXRlZCwgdGhlIG1hc3RlciBzZWNyZXQgaXMgdXNlZCBhcyBhbgogKiBlbnRyb3B5IHNvdXJjZS4KICoKICogVG8gZ2VuZXJhdGUgdGhlIGtleSBtYXRlcmlhbCwgY29tcHV0ZToKICoKICogbWFzdGVyX3NlY3JldCA9IFBSRihwcmVfbWFzdGVyX3NlY3JldCwgIm1hc3RlciBzZWNyZXQiLAogKiAgICAgICAgICAgICAgICAgICAgIENsaWVudEhlbGxvLnJhbmRvbSArIFNlcnZlckhlbGxvLnJhbmRvbSkKICoKICoga2V5X2Jsb2NrID0gUFJGKFNlY3VyaXR5UGFyYW1ldGVycy5tYXN0ZXJfc2VjcmV0LAogKiAgICAgICAgICAgICAgICAgImtleSBleHBhbnNpb24iLAogKiAgICAgICAgICAgICAgICAgU2VjdXJpdHlQYXJhbWV0ZXJzLnNlcnZlcl9yYW5kb20gKwogKiAgICAgICAgICAgICAgICAgU2VjdXJpdHlQYXJhbWV0ZXJzLmNsaWVudF9yYW5kb20pOwogKgogKiB1bnRpbCBlbm91Z2ggb3V0cHV0IGhhcyBiZWVuIGdlbmVyYXRlZC4gVGhlbiwgdGhlIGtleV9ibG9jayBpcwogKiBwYXJ0aXRpb25lZCBhcyBmb2xsb3dzOgogKgogKiBjbGllbnRfd3JpdGVfTUFDX2tleVtTZWN1cml0eVBhcmFtZXRlcnMubWFjX2tleV9sZW5ndGhdCiAqIHNlcnZlcl93cml0ZV9NQUNfa2V5W1NlY3VyaXR5UGFyYW1ldGVycy5tYWNfa2V5X2xlbmd0aF0KICogY2xpZW50X3dyaXRlX2tleVtTZWN1cml0eVBhcmFtZXRlcnMuZW5jX2tleV9sZW5ndGhdCiAqIHNlcnZlcl93cml0ZV9rZXlbU2VjdXJpdHlQYXJhbWV0ZXJzLmVuY19rZXlfbGVuZ3RoXQogKiBjbGllbnRfd3JpdGVfSVZbU2VjdXJpdHlQYXJhbWV0ZXJzLmZpeGVkX2l2X2xlbmd0aF0KICogc2VydmVyX3dyaXRlX0lWW1NlY3VyaXR5UGFyYW1ldGVycy5maXhlZF9pdl9sZW5ndGhdCiAqCiAqIEluIFRMUyAxLjIsIHRoZSBjbGllbnRfd3JpdGVfSVYgYW5kIHNlcnZlcl93cml0ZV9JViBhcmUgb25seSBnZW5lcmF0ZWQgZm9yCiAqIGltcGxpY2l0IG5vbmNlIHRlY2huaXF1ZXMgYXMgZGVzY3JpYmVkIGluIFNlY3Rpb24gMy4yLjEgb2YgW0FFQURdLiBUaGlzCiAqIGltcGxlbWVudGF0aW9uIHVzZXMgVExTIDEuMCBzbyBJVnMgYXJlIGdlbmVyYXRlZC4KICoKICogSW1wbGVtZW50YXRpb24gbm90ZTogVGhlIGN1cnJlbnRseSBkZWZpbmVkIGNpcGhlciBzdWl0ZSB3aGljaCByZXF1aXJlcyB0aGUKICogbW9zdCBtYXRlcmlhbCBpcyBBRVNfMjU2X0NCQ19TSEEyNTYuIEl0IHJlcXVpcmVzIDIgeCAzMiBieXRlIGtleXMgYW5kIDIgeCAzMgogKiBieXRlIE1BQyBrZXlzLCBmb3IgYSB0b3RhbCAxMjggYnl0ZXMgb2Yga2V5IG1hdGVyaWFsLiBJbiBUTFMgMS4wIGl0IGFsc28KICogcmVxdWlyZXMgMiB4IDE2IGJ5dGUgSVZzLCBzbyBpdCBhY3R1YWxseSB0YWtlcyAxNjAgYnl0ZXMgb2Yga2V5IG1hdGVyaWFsLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHNwIHRoZSBzZWN1cml0eSBwYXJhbWV0ZXJzIHRvIHVzZS4KICoKICogQHJldHVybiB0aGUgc2VjdXJpdHkga2V5cy4KICovCnRscy5nZW5lcmF0ZUtleXMgPSBmdW5jdGlvbihjLCBzcCkgewogIC8vIFRMU19SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEgKHJlcXVpcmVkIHRvIGJlIGNvbXBsaWFudCB3aXRoIFRMUyAxLjIpICYKICAvLyBUTFNfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBIGFyZSB0aGUgb25seSBjaXBoZXIgc3VpdGVzIGltcGxlbWVudGVkCiAgLy8gYXQgcHJlc2VudAoKICAvLyBUTFNfREhFX0RTU19XSVRIXzNERVNfRURFX0NCQ19TSEEgaXMgcmVxdWlyZWQgdG8gYmUgY29tcGxpYW50IHdpdGgKICAvLyBUTFMgMS4wIGJ1dCB3ZSBkb24ndCBjYXJlIHJpZ2h0IG5vdyBiZWNhdXNlIEFFUyBpcyBiZXR0ZXIgYW5kIHdlIGhhdmUKICAvLyBhbiBpbXBsZW1lbnRhdGlvbiBmb3IgaXQKCiAgLy8gVE9ETzogVExTIDEuMiBpbXBsZW1lbnRhdGlvbgogIC8qCiAgLy8gZGV0ZXJtaW5lIHRoZSBQUkYKICB2YXIgcHJmOwogIHN3aXRjaChzcC5wcmZfYWxnb3JpdGhtKSB7CiAgY2FzZSB0bHMuUFJGQWxnb3JpdGhtLnRsc19wcmZfc2hhMjU2OgogICAgcHJmID0gcHJmX3NoYTI1NjsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgUFJGJyk7CiAgfQogICovCgogIC8vIFRMUyAxLjAvMS4xIGltcGxlbWVudGF0aW9uCiAgdmFyIHByZiA9IHByZl9UTFMxOwoKICAvLyBjb25jYXRlbmF0ZSBzZXJ2ZXIgYW5kIGNsaWVudCByYW5kb20KICB2YXIgcmFuZG9tID0gc3AuY2xpZW50X3JhbmRvbSArIHNwLnNlcnZlcl9yYW5kb207CgogIC8vIG9ubHkgY3JlYXRlIG1hc3RlciBzZWNyZXQgaWYgc2Vzc2lvbiBpcyBuZXcKICBpZighYy5zZXNzaW9uLnJlc3VtaW5nKSB7CiAgICAvLyBjcmVhdGUgbWFzdGVyIHNlY3JldCwgY2xlYW4gdXAgcHJlLW1hc3RlciBzZWNyZXQKICAgIHNwLm1hc3Rlcl9zZWNyZXQgPSBwcmYoCiAgICAgIHNwLnByZV9tYXN0ZXJfc2VjcmV0LCAnbWFzdGVyIHNlY3JldCcsIHJhbmRvbSwgNDgpLmJ5dGVzKCk7CiAgICBzcC5wcmVfbWFzdGVyX3NlY3JldCA9IG51bGw7CiAgfQoKICAvLyBnZW5lcmF0ZSB0aGUgYW1vdW50IG9mIGtleSBtYXRlcmlhbCBuZWVkZWQKICByYW5kb20gPSBzcC5zZXJ2ZXJfcmFuZG9tICsgc3AuY2xpZW50X3JhbmRvbTsKICB2YXIgbGVuZ3RoID0gMiAqIHNwLm1hY19rZXlfbGVuZ3RoICsgMiAqIHNwLmVuY19rZXlfbGVuZ3RoOwoKICAvLyBpbmNsdWRlIElWIGZvciBUTFMvMS4wCiAgdmFyIHRsczEwID0gKGMudmVyc2lvbi5tYWpvciA9PT0gdGxzLlZlcnNpb25zLlRMU18xXzAubWFqb3IgJiYKICAgIGMudmVyc2lvbi5taW5vciA9PT0gdGxzLlZlcnNpb25zLlRMU18xXzAubWlub3IpOwogIGlmKHRsczEwKSB7CiAgICBsZW5ndGggKz0gMiAqIHNwLmZpeGVkX2l2X2xlbmd0aDsKICB9CiAgdmFyIGttID0gcHJmKHNwLm1hc3Rlcl9zZWNyZXQsICdrZXkgZXhwYW5zaW9uJywgcmFuZG9tLCBsZW5ndGgpOwoKICAvLyBzcGxpdCB0aGUga2V5IG1hdGVyaWFsIGludG8gdGhlIE1BQyBhbmQgZW5jcnlwdGlvbiBrZXlzCiAgdmFyIHJ2YWwgPSB7CiAgICBjbGllbnRfd3JpdGVfTUFDX2tleToga20uZ2V0Qnl0ZXMoc3AubWFjX2tleV9sZW5ndGgpLAogICAgc2VydmVyX3dyaXRlX01BQ19rZXk6IGttLmdldEJ5dGVzKHNwLm1hY19rZXlfbGVuZ3RoKSwKICAgIGNsaWVudF93cml0ZV9rZXk6IGttLmdldEJ5dGVzKHNwLmVuY19rZXlfbGVuZ3RoKSwKICAgIHNlcnZlcl93cml0ZV9rZXk6IGttLmdldEJ5dGVzKHNwLmVuY19rZXlfbGVuZ3RoKQogIH07CgogIC8vIGluY2x1ZGUgVExTIDEuMCBJVnMKICBpZih0bHMxMCkgewogICAgcnZhbC5jbGllbnRfd3JpdGVfSVYgPSBrbS5nZXRCeXRlcyhzcC5maXhlZF9pdl9sZW5ndGgpOwogICAgcnZhbC5zZXJ2ZXJfd3JpdGVfSVYgPSBrbS5nZXRCeXRlcyhzcC5maXhlZF9pdl9sZW5ndGgpOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ3JlYXRlcyBhIG5ldyBpbml0aWFsaXplZCBUTFMgY29ubmVjdGlvbiBzdGF0ZS4gQSBjb25uZWN0aW9uIHN0YXRlIGhhcwogKiBhIHJlYWQgbW9kZSBhbmQgYSB3cml0ZSBtb2RlLgogKgogKiBjb21wcmVzc2lvbiBzdGF0ZToKICogICBUaGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgY29tcHJlc3Npb24gYWxnb3JpdGhtLgogKgogKiBjaXBoZXIgc3RhdGU6CiAqICAgVGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGVuY3J5cHRpb24gYWxnb3JpdGhtLiBUaGlzIHdpbGwgY29uc2lzdCBvZiB0aGUKICogICBzY2hlZHVsZWQga2V5IGZvciB0aGF0IGNvbm5lY3Rpb24uIEZvciBzdHJlYW0gY2lwaGVycywgdGhpcyB3aWxsIGFsc28KICogICBjb250YWluIHdoYXRldmVyIHN0YXRlIGluZm9ybWF0aW9uIGlzIG5lY2Vzc2FyeSB0byBhbGxvdyB0aGUgc3RyZWFtIHRvCiAqICAgY29udGludWUgdG8gZW5jcnlwdCBvciBkZWNyeXB0IGRhdGEuCiAqCiAqIE1BQyBrZXk6CiAqICAgVGhlIE1BQyBrZXkgZm9yIHRoZSBjb25uZWN0aW9uLgogKgogKiBzZXF1ZW5jZSBudW1iZXI6CiAqICAgRWFjaCBjb25uZWN0aW9uIHN0YXRlIGNvbnRhaW5zIGEgc2VxdWVuY2UgbnVtYmVyLCB3aGljaCBpcyBtYWludGFpbmVkCiAqICAgc2VwYXJhdGVseSBmb3IgcmVhZCBhbmQgd3JpdGUgc3RhdGVzLiBUaGUgc2VxdWVuY2UgbnVtYmVyIE1VU1QgYmUgc2V0IHRvCiAqICAgemVybyB3aGVuZXZlciBhIGNvbm5lY3Rpb24gc3RhdGUgaXMgbWFkZSB0aGUgYWN0aXZlIHN0YXRlLiBTZXF1ZW5jZQogKiAgIG51bWJlcnMgYXJlIG9mIHR5cGUgdWludDY0IGFuZCBtYXkgbm90IGV4Y2VlZCAyXjY0LTEuIFNlcXVlbmNlIG51bWJlcnMgZG8KICogICBub3Qgd3JhcC4gSWYgYSBUTFMgaW1wbGVtZW50YXRpb24gd291bGQgbmVlZCB0byB3cmFwIGEgc2VxdWVuY2UgbnVtYmVyLAogKiAgIGl0IG11c3QgcmVuZWdvdGlhdGUgaW5zdGVhZC4gQSBzZXF1ZW5jZSBudW1iZXIgaXMgaW5jcmVtZW50ZWQgYWZ0ZXIgZWFjaAogKiAgIHJlY29yZDogc3BlY2lmaWNhbGx5LCB0aGUgZmlyc3QgcmVjb3JkIHRyYW5zbWl0dGVkIHVuZGVyIGEgcGFydGljdWxhcgogKiAgIGNvbm5lY3Rpb24gc3RhdGUgTVVTVCB1c2Ugc2VxdWVuY2UgbnVtYmVyIDAuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBuZXcgaW5pdGlhbGl6ZWQgVExTIGNvbm5lY3Rpb24gc3RhdGUuCiAqLwp0bHMuY3JlYXRlQ29ubmVjdGlvblN0YXRlID0gZnVuY3Rpb24oYykgewogIHZhciBjbGllbnQgPSAoYy5lbnRpdHkgPT09IHRscy5Db25uZWN0aW9uRW5kLmNsaWVudCk7CgogIHZhciBjcmVhdGVNb2RlID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgbW9kZSA9IHsKICAgICAgLy8gdHdvIDMyLWJpdCBudW1iZXJzLCBmaXJzdCBpcyBtb3N0IHNpZ25pZmljYW50CiAgICAgIHNlcXVlbmNlTnVtYmVyOiBbMCwgMF0sCiAgICAgIG1hY0tleTogbnVsbCwKICAgICAgbWFjTGVuZ3RoOiAwLAogICAgICBtYWNGdW5jdGlvbjogbnVsbCwKICAgICAgY2lwaGVyU3RhdGU6IG51bGwsCiAgICAgIGNpcGhlckZ1bmN0aW9uOiBmdW5jdGlvbihyZWNvcmQpIHtyZXR1cm4gdHJ1ZTt9LAogICAgICBjb21wcmVzc2lvblN0YXRlOiBudWxsLAogICAgICBjb21wcmVzc0Z1bmN0aW9uOiBmdW5jdGlvbihyZWNvcmQpIHtyZXR1cm4gdHJ1ZTt9LAogICAgICB1cGRhdGVTZXF1ZW5jZU51bWJlcjogZnVuY3Rpb24oKSB7CiAgICAgICAgaWYobW9kZS5zZXF1ZW5jZU51bWJlclsxXSA9PT0gMHhGRkZGRkZGRikgewogICAgICAgICAgbW9kZS5zZXF1ZW5jZU51bWJlclsxXSA9IDA7CiAgICAgICAgICArK21vZGUuc2VxdWVuY2VOdW1iZXJbMF07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICsrbW9kZS5zZXF1ZW5jZU51bWJlclsxXTsKICAgICAgICB9CiAgICAgIH0KICAgIH07CiAgICByZXR1cm4gbW9kZTsKICB9OwogIHZhciBzdGF0ZSA9IHsKICAgIHJlYWQ6IGNyZWF0ZU1vZGUoKSwKICAgIHdyaXRlOiBjcmVhdGVNb2RlKCkKICB9OwoKICAvLyB1cGRhdGUgZnVuY3Rpb24gaW4gcmVhZCBtb2RlIHdpbGwgZGVjcnlwdCB0aGVuIGRlY29tcHJlc3MgYSByZWNvcmQKICBzdGF0ZS5yZWFkLnVwZGF0ZSA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogICAgaWYoIXN0YXRlLnJlYWQuY2lwaGVyRnVuY3Rpb24ocmVjb3JkLCBzdGF0ZS5yZWFkKSkgewogICAgICBjLmVycm9yKGMsIHsKICAgICAgICBtZXNzYWdlOiAnQ291bGQgbm90IGRlY3J5cHQgcmVjb3JkIG9yIGJhZCBNQUMuJywKICAgICAgICBzZW5kOiB0cnVlLAogICAgICAgIGFsZXJ0OiB7CiAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgICAgLy8gZG9lc24ndCBtYXR0ZXIgaWYgZGVjcnlwdGlvbiBmYWlsZWQgb3IgTUFDIHdhcwogICAgICAgICAgLy8gaW52YWxpZCwgcmV0dXJuIHRoZSBzYW1lIGVycm9yIHNvIGFzIG5vdCB0byByZXZlYWwKICAgICAgICAgIC8vIHdoaWNoIG9uZSBvY2N1cnJlZAogICAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5iYWRfcmVjb3JkX21hYwogICAgICAgIH0KICAgICAgfSk7CiAgICB9IGVsc2UgaWYoIXN0YXRlLnJlYWQuY29tcHJlc3NGdW5jdGlvbihjLCByZWNvcmQsIHN0YXRlLnJlYWQpKSB7CiAgICAgIGMuZXJyb3IoYywgewogICAgICAgIG1lc3NhZ2U6ICdDb3VsZCBub3QgZGVjb21wcmVzcyByZWNvcmQuJywKICAgICAgICBzZW5kOiB0cnVlLAogICAgICAgIGFsZXJ0OiB7CiAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5kZWNvbXByZXNzaW9uX2ZhaWx1cmUKICAgICAgICB9CiAgICAgIH0pOwogICAgfQogICAgcmV0dXJuICFjLmZhaWw7CiAgfTsKCiAgLy8gdXBkYXRlIGZ1bmN0aW9uIGluIHdyaXRlIG1vZGUgd2lsbCBjb21wcmVzcyB0aGVuIGVuY3J5cHQgYSByZWNvcmQKICBzdGF0ZS53cml0ZS51cGRhdGUgPSBmdW5jdGlvbihjLCByZWNvcmQpIHsKICAgIGlmKCFzdGF0ZS53cml0ZS5jb21wcmVzc0Z1bmN0aW9uKGMsIHJlY29yZCwgc3RhdGUud3JpdGUpKSB7CiAgICAgIC8vIGVycm9yLCBidXQgZG8gbm90IHNlbmQgYWxlcnQgc2luY2UgaXQgd291bGQgcmVxdWlyZQogICAgICAvLyBjb21wcmVzc2lvbiBhcyB3ZWxsCiAgICAgIGMuZXJyb3IoYywgewogICAgICAgIG1lc3NhZ2U6ICdDb3VsZCBub3QgY29tcHJlc3MgcmVjb3JkLicsCiAgICAgICAgc2VuZDogZmFsc2UsCiAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yCiAgICAgICAgfQogICAgICB9KTsKICAgIH0gZWxzZSBpZighc3RhdGUud3JpdGUuY2lwaGVyRnVuY3Rpb24ocmVjb3JkLCBzdGF0ZS53cml0ZSkpIHsKICAgICAgLy8gZXJyb3IsIGJ1dCBkbyBub3Qgc2VuZCBhbGVydCBzaW5jZSBpdCB3b3VsZCByZXF1aXJlCiAgICAgIC8vIGVuY3J5cHRpb24gYXMgd2VsbAogICAgICBjLmVycm9yKGMsIHsKICAgICAgICBtZXNzYWdlOiAnQ291bGQgbm90IGVuY3J5cHQgcmVjb3JkLicsCiAgICAgICAgc2VuZDogZmFsc2UsCiAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yCiAgICAgICAgfQogICAgICB9KTsKICAgIH0KICAgIHJldHVybiAhYy5mYWlsOwogIH07CgogIC8vIGhhbmRsZSBzZWN1cml0eSBwYXJhbWV0ZXJzCiAgaWYoYy5zZXNzaW9uKSB7CiAgICB2YXIgc3AgPSBjLnNlc3Npb24uc3A7CiAgICBjLnNlc3Npb24uY2lwaGVyU3VpdGUuaW5pdFNlY3VyaXR5UGFyYW1ldGVycyhzcCk7CgogICAgLy8gZ2VuZXJhdGUga2V5cwogICAgc3Aua2V5cyA9IHRscy5nZW5lcmF0ZUtleXMoYywgc3ApOwogICAgc3RhdGUucmVhZC5tYWNLZXkgPSBjbGllbnQgPwogICAgICBzcC5rZXlzLnNlcnZlcl93cml0ZV9NQUNfa2V5IDogc3Aua2V5cy5jbGllbnRfd3JpdGVfTUFDX2tleTsKICAgIHN0YXRlLndyaXRlLm1hY0tleSA9IGNsaWVudCA/CiAgICAgIHNwLmtleXMuY2xpZW50X3dyaXRlX01BQ19rZXkgOiBzcC5rZXlzLnNlcnZlcl93cml0ZV9NQUNfa2V5OwoKICAgIC8vIGNpcGhlciBzdWl0ZSBzZXR1cAogICAgYy5zZXNzaW9uLmNpcGhlclN1aXRlLmluaXRDb25uZWN0aW9uU3RhdGUoc3RhdGUsIGMsIHNwKTsKCiAgICAvLyBjb21wcmVzc2lvbiBzZXR1cAogICAgc3dpdGNoKHNwLmNvbXByZXNzaW9uX2FsZ29yaXRobSkgewogICAgY2FzZSB0bHMuQ29tcHJlc3Npb25NZXRob2Qubm9uZToKICAgICAgYnJlYWs7CiAgICBjYXNlIHRscy5Db21wcmVzc2lvbk1ldGhvZC5kZWZsYXRlOgogICAgICBzdGF0ZS5yZWFkLmNvbXByZXNzRnVuY3Rpb24gPSBpbmZsYXRlOwogICAgICBzdGF0ZS53cml0ZS5jb21wcmVzc0Z1bmN0aW9uID0gZGVmbGF0ZTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGNvbXByZXNzaW9uIGFsZ29yaXRobS4nKTsKICAgIH0KICB9CgogIHJldHVybiBzdGF0ZTsKfTsKCi8qKgogKiBDcmVhdGVzIGEgUmFuZG9tIHN0cnVjdHVyZS4KICoKICogc3RydWN0IHsKICogICB1aW50MzIgZ210X3VuaXhfdGltZTsKICogICBvcGFxdWUgcmFuZG9tX2J5dGVzWzI4XTsKICogfSBSYW5kb207CiAqCiAqIGdtdF91bml4X3RpbWU6CiAqICAgVGhlIGN1cnJlbnQgdGltZSBhbmQgZGF0ZSBpbiBzdGFuZGFyZCBVTklYIDMyLWJpdCBmb3JtYXQgKHNlY29uZHMgc2luY2UKICogICB0aGUgbWlkbmlnaHQgc3RhcnRpbmcgSmFuIDEsIDE5NzAsIFVUQywgaWdub3JpbmcgbGVhcCBzZWNvbmRzKSBhY2NvcmRpbmcKICogICB0byB0aGUgc2VuZGVyJ3MgaW50ZXJuYWwgY2xvY2suIENsb2NrcyBhcmUgbm90IHJlcXVpcmVkIHRvIGJlIHNldAogKiAgIGNvcnJlY3RseSBieSB0aGUgYmFzaWMgVExTIHByb3RvY29sOyBoaWdoZXItbGV2ZWwgb3IgYXBwbGljYXRpb24KICogICBwcm90b2NvbHMgbWF5IGRlZmluZSBhZGRpdGlvbmFsIHJlcXVpcmVtZW50cy4gTm90ZSB0aGF0LCBmb3IgaGlzdG9yaWNhbAogKiAgIHJlYXNvbnMsIHRoZSBkYXRhIGVsZW1lbnQgaXMgbmFtZWQgdXNpbmcgR01ULCB0aGUgcHJlZGVjZXNzb3Igb2YgdGhlCiAqICAgY3VycmVudCB3b3JsZHdpZGUgdGltZSBiYXNlLCBVVEMuCiAqIHJhbmRvbV9ieXRlczoKICogICAyOCBieXRlcyBnZW5lcmF0ZWQgYnkgYSBzZWN1cmUgcmFuZG9tIG51bWJlciBnZW5lcmF0b3IuCiAqCiAqIEByZXR1cm4gdGhlIFJhbmRvbSBzdHJ1Y3R1cmUgYXMgYSBieXRlIGFycmF5LgogKi8KdGxzLmNyZWF0ZVJhbmRvbSA9IGZ1bmN0aW9uKCkgewogIC8vIGdldCBVVEMgbWlsbGlzZWNvbmRzCiAgdmFyIGQgPSBuZXcgRGF0ZSgpOwogIHZhciB1dGMgPSArZCArIGQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwMDAwOwogIHZhciBydmFsID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBydmFsLnB1dEludDMyKHV0Yyk7CiAgcnZhbC5wdXRCeXRlcyhmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMoMjgpKTsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDcmVhdGVzIGEgVExTIHJlY29yZCB3aXRoIHRoZSBnaXZlbiB0eXBlIGFuZCBkYXRhLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIG9wdGlvbnM6CiAqICAgdHlwZTogdGhlIHJlY29yZCB0eXBlLgogKiAgIGRhdGE6IHRoZSBwbGFpbiB0ZXh0IGRhdGEgaW4gYSBieXRlIGJ1ZmZlci4KICoKICogQHJldHVybiB0aGUgY3JlYXRlZCByZWNvcmQuCiAqLwp0bHMuY3JlYXRlUmVjb3JkID0gZnVuY3Rpb24oYywgb3B0aW9ucykgewogIGlmKCFvcHRpb25zLmRhdGEpIHsKICAgIHJldHVybiBudWxsOwogIH0KICB2YXIgcmVjb3JkID0gewogICAgdHlwZTogb3B0aW9ucy50eXBlLAogICAgdmVyc2lvbjogewogICAgICBtYWpvcjogYy52ZXJzaW9uLm1ham9yLAogICAgICBtaW5vcjogYy52ZXJzaW9uLm1pbm9yCiAgICB9LAogICAgbGVuZ3RoOiBvcHRpb25zLmRhdGEubGVuZ3RoKCksCiAgICBmcmFnbWVudDogb3B0aW9ucy5kYXRhCiAgfTsKICByZXR1cm4gcmVjb3JkOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBUTFMgYWxlcnQgcmVjb3JkLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIGFsZXJ0OgogKiAgIGxldmVsOiB0aGUgVExTIGFsZXJ0IGxldmVsLgogKiAgIGRlc2NyaXB0aW9uOiB0aGUgVExTIGFsZXJ0IGRlc2NyaXB0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBjcmVhdGVkIGFsZXJ0IHJlY29yZC4KICovCnRscy5jcmVhdGVBbGVydCA9IGZ1bmN0aW9uKGMsIGFsZXJ0KSB7CiAgdmFyIGIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIGIucHV0Qnl0ZShhbGVydC5sZXZlbCk7CiAgYi5wdXRCeXRlKGFsZXJ0LmRlc2NyaXB0aW9uKTsKICByZXR1cm4gdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuYWxlcnQsCiAgICBkYXRhOiBiCiAgfSk7Cn07CgovKiBUaGUgc3RydWN0dXJlIG9mIGEgVExTIGhhbmRzaGFrZSBtZXNzYWdlLgogKgogKiBzdHJ1Y3QgewogKiAgICBIYW5kc2hha2VUeXBlIG1zZ190eXBlOyAgICAvLyBoYW5kc2hha2UgdHlwZQogKiAgICB1aW50MjQgbGVuZ3RoOyAgICAgICAgICAgICAvLyBieXRlcyBpbiBtZXNzYWdlCiAqICAgIHNlbGVjdChIYW5kc2hha2VUeXBlKSB7CiAqICAgICAgIGNhc2UgaGVsbG9fcmVxdWVzdDogICAgICAgSGVsbG9SZXF1ZXN0OwogKiAgICAgICBjYXNlIGNsaWVudF9oZWxsbzogICAgICAgIENsaWVudEhlbGxvOwogKiAgICAgICBjYXNlIHNlcnZlcl9oZWxsbzogICAgICAgIFNlcnZlckhlbGxvOwogKiAgICAgICBjYXNlIGNlcnRpZmljYXRlOiAgICAgICAgIENlcnRpZmljYXRlOwogKiAgICAgICBjYXNlIHNlcnZlcl9rZXlfZXhjaGFuZ2U6IFNlcnZlcktleUV4Y2hhbmdlOwogKiAgICAgICBjYXNlIGNlcnRpZmljYXRlX3JlcXVlc3Q6IENlcnRpZmljYXRlUmVxdWVzdDsKICogICAgICAgY2FzZSBzZXJ2ZXJfaGVsbG9fZG9uZTogICBTZXJ2ZXJIZWxsb0RvbmU7CiAqICAgICAgIGNhc2UgY2VydGlmaWNhdGVfdmVyaWZ5OiAgQ2VydGlmaWNhdGVWZXJpZnk7CiAqICAgICAgIGNhc2UgY2xpZW50X2tleV9leGNoYW5nZTogQ2xpZW50S2V5RXhjaGFuZ2U7CiAqICAgICAgIGNhc2UgZmluaXNoZWQ6ICAgICAgICAgICAgRmluaXNoZWQ7CiAqICAgIH0gYm9keTsKICogfSBIYW5kc2hha2U7CiAqLwoKLyoqCiAqIENyZWF0ZXMgYSBDbGllbnRIZWxsbyBtZXNzYWdlLgogKgogKiBvcGFxdWUgU2Vzc2lvbklEPDAuLjMyPjsKICogZW51bSB7IG51bGwoMCksIGRlZmxhdGUoMSksICgyNTUpIH0gQ29tcHJlc3Npb25NZXRob2Q7CiAqIHVpbnQ4IENpcGhlclN1aXRlWzJdOwogKgogKiBzdHJ1Y3QgewogKiAgIFByb3RvY29sVmVyc2lvbiBjbGllbnRfdmVyc2lvbjsKICogICBSYW5kb20gcmFuZG9tOwogKiAgIFNlc3Npb25JRCBzZXNzaW9uX2lkOwogKiAgIENpcGhlclN1aXRlIGNpcGhlcl9zdWl0ZXM8Mi4uMl4xNi0yPjsKICogICBDb21wcmVzc2lvbk1ldGhvZCBjb21wcmVzc2lvbl9tZXRob2RzPDEuLjJeOC0xPjsKICogICBzZWxlY3QoZXh0ZW5zaW9uc19wcmVzZW50KSB7CiAqICAgICBjYXNlIGZhbHNlOgogKiAgICAgICBzdHJ1Y3Qge307CiAqICAgICBjYXNlIHRydWU6CiAqICAgICAgIEV4dGVuc2lvbiBleHRlbnNpb25zPDAuLjJeMTYtMT47CiAqICAgfTsKICogfSBDbGllbnRIZWxsbzsKICoKICogVGhlIGV4dGVuc2lvbiBmb3JtYXQgZm9yIGV4dGVuZGVkIGNsaWVudCBoZWxsb3MgYW5kIHNlcnZlciBoZWxsb3MgaXM6CiAqCiAqIHN0cnVjdCB7CiAqICAgRXh0ZW5zaW9uVHlwZSBleHRlbnNpb25fdHlwZTsKICogICBvcGFxdWUgZXh0ZW5zaW9uX2RhdGE8MC4uMl4xNi0xPjsKICogfSBFeHRlbnNpb247CiAqCiAqIEhlcmU6CiAqCiAqIC0gImV4dGVuc2lvbl90eXBlIiBpZGVudGlmaWVzIHRoZSBwYXJ0aWN1bGFyIGV4dGVuc2lvbiB0eXBlLgogKiAtICJleHRlbnNpb25fZGF0YSIgY29udGFpbnMgaW5mb3JtYXRpb24gc3BlY2lmaWMgdG8gdGhlIHBhcnRpY3VsYXIKICogZXh0ZW5zaW9uIHR5cGUuCiAqCiAqIFRoZSBleHRlbnNpb24gdHlwZXMgZGVmaW5lZCBpbiB0aGlzIGRvY3VtZW50IGFyZToKICoKICogZW51bSB7CiAqICAgc2VydmVyX25hbWUoMCksIG1heF9mcmFnbWVudF9sZW5ndGgoMSksCiAqICAgY2xpZW50X2NlcnRpZmljYXRlX3VybCgyKSwgdHJ1c3RlZF9jYV9rZXlzKDMpLAogKiAgIHRydW5jYXRlZF9obWFjKDQpLCBzdGF0dXNfcmVxdWVzdCg1KSwgKDY1NTM1KQogKiB9IEV4dGVuc2lvblR5cGU7CiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBDbGllbnRIZWxsbyBieXRlIGJ1ZmZlci4KICovCnRscy5jcmVhdGVDbGllbnRIZWxsbyA9IGZ1bmN0aW9uKGMpIHsKICAvLyBzYXZlIGhlbGxvIHZlcnNpb24KICBjLnNlc3Npb24uY2xpZW50SGVsbG9WZXJzaW9uID0gewogICAgbWFqb3I6IGMudmVyc2lvbi5tYWpvciwKICAgIG1pbm9yOiBjLnZlcnNpb24ubWlub3IKICB9OwoKICAvLyBjcmVhdGUgc3VwcG9ydGVkIGNpcGhlciBzdWl0ZXMKICB2YXIgY2lwaGVyU3VpdGVzID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBmb3IodmFyIGkgPSAwOyBpIDwgYy5jaXBoZXJTdWl0ZXMubGVuZ3RoOyArK2kpIHsKICAgIHZhciBjcyA9IGMuY2lwaGVyU3VpdGVzW2ldOwogICAgY2lwaGVyU3VpdGVzLnB1dEJ5dGUoY3MuaWRbMF0pOwogICAgY2lwaGVyU3VpdGVzLnB1dEJ5dGUoY3MuaWRbMV0pOwogIH0KICB2YXIgY1N1aXRlcyA9IGNpcGhlclN1aXRlcy5sZW5ndGgoKTsKCiAgLy8gY3JlYXRlIHN1cHBvcnRlZCBjb21wcmVzc2lvbiBtZXRob2RzLCBudWxsIGFsd2F5cyBzdXBwb3J0ZWQsIGJ1dAogIC8vIGFsc28gc3VwcG9ydCBkZWZsYXRlIGlmIGNvbm5lY3Rpb24gaGFzIGluZmxhdGUgYW5kIGRlZmxhdGUgbWV0aG9kcwogIHZhciBjb21wcmVzc2lvbk1ldGhvZHMgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIGNvbXByZXNzaW9uTWV0aG9kcy5wdXRCeXRlKHRscy5Db21wcmVzc2lvbk1ldGhvZC5ub25lKTsKICAvLyBGSVhNRTogZGVmbGF0ZSBzdXBwb3J0IGRpc2FibGVkIHVudGlsIGlzc3VlcyB3aXRoIHJhdyBkZWZsYXRlIGRhdGEKICAvLyB3aXRob3V0IHpsaWIgaGVhZGVycyBhcmUgcmVzb2x2ZWQKICAvKgogIGlmKGMuaW5mbGF0ZSAhPT0gbnVsbCAmJiBjLmRlZmxhdGUgIT09IG51bGwpIHsKICAgIGNvbXByZXNzaW9uTWV0aG9kcy5wdXRCeXRlKHRscy5Db21wcmVzc2lvbk1ldGhvZC5kZWZsYXRlKTsKICB9CiAgKi8KICB2YXIgY01ldGhvZHMgPSBjb21wcmVzc2lvbk1ldGhvZHMubGVuZ3RoKCk7CgogIC8vIGNyZWF0ZSBUTFMgU05JIChzZXJ2ZXIgbmFtZSBpbmRpY2F0aW9uKSBleHRlbnNpb24gaWYgdmlydHVhbCBob3N0CiAgLy8gaGFzIGJlZW4gc3BlY2lmaWVkLCBzZWUgUkZDIDM1NDYKICB2YXIgZXh0ZW5zaW9ucyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgaWYoYy52aXJ0dWFsSG9zdCkgewogICAgLy8gY3JlYXRlIGV4dGVuc2lvbiBzdHJ1Y3QKICAgIHZhciBleHQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgZXh0LnB1dEJ5dGUoMHgwMCk7IC8vIHR5cGUgc2VydmVyX25hbWUgKEV4dGVuc2lvblR5cGUgaXMgMiBieXRlcykKICAgIGV4dC5wdXRCeXRlKDB4MDApOwoKICAgIC8qIEluIG9yZGVyIHRvIHByb3ZpZGUgdGhlIHNlcnZlciBuYW1lLCBjbGllbnRzIE1BWSBpbmNsdWRlIGFuCiAgICAgKiBleHRlbnNpb24gb2YgdHlwZSAic2VydmVyX25hbWUiIGluIHRoZSAoZXh0ZW5kZWQpIGNsaWVudCBoZWxsby4KICAgICAqIFRoZSAiZXh0ZW5zaW9uX2RhdGEiIGZpZWxkIG9mIHRoaXMgZXh0ZW5zaW9uIFNIQUxMIGNvbnRhaW4KICAgICAqICJTZXJ2ZXJOYW1lTGlzdCIgd2hlcmU6CiAgICAgKgogICAgICogc3RydWN0IHsKICAgICAqICAgTmFtZVR5cGUgbmFtZV90eXBlOwogICAgICogICBzZWxlY3QobmFtZV90eXBlKSB7CiAgICAgKiAgICAgY2FzZSBob3N0X25hbWU6IEhvc3ROYW1lOwogICAgICogICB9IG5hbWU7CiAgICAgKiB9IFNlcnZlck5hbWU7CiAgICAgKgogICAgICogZW51bSB7CiAgICAgKiAgIGhvc3RfbmFtZSgwKSwgKDI1NSkKICAgICAqIH0gTmFtZVR5cGU7CiAgICAgKgogICAgICogb3BhcXVlIEhvc3ROYW1lPDEuLjJeMTYtMT47CiAgICAgKgogICAgICogc3RydWN0IHsKICAgICAqICAgU2VydmVyTmFtZSBzZXJ2ZXJfbmFtZV9saXN0PDEuLjJeMTYtMT4KICAgICAqIH0gU2VydmVyTmFtZUxpc3Q7CiAgICAgKi8KICAgIHZhciBzZXJ2ZXJOYW1lID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIHNlcnZlck5hbWUucHV0Qnl0ZSgweDAwKTsgLy8gdHlwZSBob3N0X25hbWUKICAgIHdyaXRlVmVjdG9yKHNlcnZlck5hbWUsIDIsIGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGMudmlydHVhbEhvc3QpKTsKCiAgICAvLyBTZXJ2ZXJOYW1lTGlzdCBpcyBpbiBleHRlbnNpb25fZGF0YQogICAgdmFyIHNuTGlzdCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICB3cml0ZVZlY3Rvcihzbkxpc3QsIDIsIHNlcnZlck5hbWUpOwogICAgd3JpdGVWZWN0b3IoZXh0LCAyLCBzbkxpc3QpOwogICAgZXh0ZW5zaW9ucy5wdXRCdWZmZXIoZXh0KTsKICB9CiAgdmFyIGV4dExlbmd0aCA9IGV4dGVuc2lvbnMubGVuZ3RoKCk7CiAgaWYoZXh0TGVuZ3RoID4gMCkgewogICAgLy8gYWRkIGV4dGVuc2lvbiB2ZWN0b3IgbGVuZ3RoCiAgICBleHRMZW5ndGggKz0gMjsKICB9CgogIC8vIGRldGVybWluZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlCiAgLy8gY2lwaGVyIHN1aXRlcyBhbmQgY29tcHJlc3Npb24gbWV0aG9kcyBzaXplIHdpbGwgbmVlZCB0byBiZQogIC8vIHVwZGF0ZWQgaWYgbW9yZSBnZXQgYWRkZWQgdG8gdGhlIGxpc3QKICB2YXIgc2Vzc2lvbklkID0gYy5zZXNzaW9uLmlkOwogIHZhciBsZW5ndGggPQogICAgc2Vzc2lvbklkLmxlbmd0aCArIDEgKyAvLyBzZXNzaW9uIElEIHZlY3RvcgogICAgMiArICAgICAgICAgICAgICAgICAgICAvLyB2ZXJzaW9uIChtYWpvciArIG1pbm9yKQogICAgNCArIDI4ICsgICAgICAgICAgICAgICAvLyByYW5kb20gdGltZSBhbmQgcmFuZG9tIGJ5dGVzCiAgICAyICsgY1N1aXRlcyArICAgICAgICAgIC8vIGNpcGhlciBzdWl0ZXMgdmVjdG9yCiAgICAxICsgY01ldGhvZHMgKyAgICAgICAgIC8vIGNvbXByZXNzaW9uIG1ldGhvZHMgdmVjdG9yCiAgICBleHRMZW5ndGg7ICAgICAgICAgICAgIC8vIGV4dGVuc2lvbnMgdmVjdG9yCgogIC8vIGJ1aWxkIHJlY29yZCBmcmFnbWVudAogIHZhciBydmFsID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBydmFsLnB1dEJ5dGUodGxzLkhhbmRzaGFrZVR5cGUuY2xpZW50X2hlbGxvKTsKICBydmFsLnB1dEludDI0KGxlbmd0aCk7ICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZHNoYWtlIGxlbmd0aAogIHJ2YWwucHV0Qnl0ZShjLnZlcnNpb24ubWFqb3IpOyAgICAgICAgICAgICAvLyBtYWpvciB2ZXJzaW9uCiAgcnZhbC5wdXRCeXRlKGMudmVyc2lvbi5taW5vcik7ICAgICAgICAgICAgIC8vIG1pbm9yIHZlcnNpb24KICBydmFsLnB1dEJ5dGVzKGMuc2Vzc2lvbi5zcC5jbGllbnRfcmFuZG9tKTsgLy8gcmFuZG9tIHRpbWUgKyBieXRlcwogIHdyaXRlVmVjdG9yKHJ2YWwsIDEsIGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKHNlc3Npb25JZCkpOwogIHdyaXRlVmVjdG9yKHJ2YWwsIDIsIGNpcGhlclN1aXRlcyk7CiAgd3JpdGVWZWN0b3IocnZhbCwgMSwgY29tcHJlc3Npb25NZXRob2RzKTsKICBpZihleHRMZW5ndGggPiAwKSB7CiAgICB3cml0ZVZlY3RvcihydmFsLCAyLCBleHRlbnNpb25zKTsKICB9CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ3JlYXRlcyBhIFNlcnZlckhlbGxvIG1lc3NhZ2UuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBTZXJ2ZXJIZWxsbyBieXRlIGJ1ZmZlci4KICovCnRscy5jcmVhdGVTZXJ2ZXJIZWxsbyA9IGZ1bmN0aW9uKGMpIHsKICAvLyBkZXRlcm1pbmUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZQogIHZhciBzZXNzaW9uSWQgPSBjLnNlc3Npb24uaWQ7CiAgdmFyIGxlbmd0aCA9CiAgICBzZXNzaW9uSWQubGVuZ3RoICsgMSArIC8vIHNlc3Npb24gSUQgdmVjdG9yCiAgICAyICsgICAgICAgICAgICAgICAgICAgIC8vIHZlcnNpb24gKG1ham9yICsgbWlub3IpCiAgICA0ICsgMjggKyAgICAgICAgICAgICAgIC8vIHJhbmRvbSB0aW1lIGFuZCByYW5kb20gYnl0ZXMKICAgIDIgKyAgICAgICAgICAgICAgICAgICAgLy8gY2hvc2VuIGNpcGhlciBzdWl0ZQogICAgMTsgICAgICAgICAgICAgICAgICAgICAvLyBjaG9zZW4gY29tcHJlc3Npb24gbWV0aG9kCgogIC8vIGJ1aWxkIHJlY29yZCBmcmFnbWVudAogIHZhciBydmFsID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBydmFsLnB1dEJ5dGUodGxzLkhhbmRzaGFrZVR5cGUuc2VydmVyX2hlbGxvKTsKICBydmFsLnB1dEludDI0KGxlbmd0aCk7ICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZHNoYWtlIGxlbmd0aAogIHJ2YWwucHV0Qnl0ZShjLnZlcnNpb24ubWFqb3IpOyAgICAgICAgICAgICAvLyBtYWpvciB2ZXJzaW9uCiAgcnZhbC5wdXRCeXRlKGMudmVyc2lvbi5taW5vcik7ICAgICAgICAgICAgIC8vIG1pbm9yIHZlcnNpb24KICBydmFsLnB1dEJ5dGVzKGMuc2Vzc2lvbi5zcC5zZXJ2ZXJfcmFuZG9tKTsgLy8gcmFuZG9tIHRpbWUgKyBieXRlcwogIHdyaXRlVmVjdG9yKHJ2YWwsIDEsIGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKHNlc3Npb25JZCkpOwogIHJ2YWwucHV0Qnl0ZShjLnNlc3Npb24uY2lwaGVyU3VpdGUuaWRbMF0pOwogIHJ2YWwucHV0Qnl0ZShjLnNlc3Npb24uY2lwaGVyU3VpdGUuaWRbMV0pOwogIHJ2YWwucHV0Qnl0ZShjLnNlc3Npb24uY29tcHJlc3Npb25NZXRob2QpOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBDZXJ0aWZpY2F0ZSBtZXNzYWdlLgogKgogKiBXaGVuIHRoaXMgbWVzc2FnZSB3aWxsIGJlIHNlbnQ6CiAqICAgVGhpcyBpcyB0aGUgZmlyc3QgbWVzc2FnZSB0aGUgY2xpZW50IGNhbiBzZW5kIGFmdGVyIHJlY2VpdmluZyBhIHNlcnZlcgogKiAgIGhlbGxvIGRvbmUgbWVzc2FnZSBhbmQgdGhlIGZpcnN0IG1lc3NhZ2UgdGhlIHNlcnZlciBjYW4gc2VuZCBhZnRlcgogKiAgIHNlbmRpbmcgYSBTZXJ2ZXJIZWxsby4gVGhpcyBjbGllbnQgbWVzc2FnZSBpcyBvbmx5IHNlbnQgaWYgdGhlIHNlcnZlcgogKiAgIHJlcXVlc3RzIGEgY2VydGlmaWNhdGUuIElmIG5vIHN1aXRhYmxlIGNlcnRpZmljYXRlIGlzIGF2YWlsYWJsZSwgdGhlCiAqICAgY2xpZW50IHNob3VsZCBzZW5kIGEgY2VydGlmaWNhdGUgbWVzc2FnZSBjb250YWluaW5nIG5vIGNlcnRpZmljYXRlcy4gSWYKICogICBjbGllbnQgYXV0aGVudGljYXRpb24gaXMgcmVxdWlyZWQgYnkgdGhlIHNlcnZlciBmb3IgdGhlIGhhbmRzaGFrZSB0bwogKiAgIGNvbnRpbnVlLCBpdCBtYXkgcmVzcG9uZCB3aXRoIGEgZmF0YWwgaGFuZHNoYWtlIGZhaWx1cmUgYWxlcnQuCiAqCiAqIG9wYXF1ZSBBU04uMUNlcnQ8MS4uMl4yNC0xPjsKICoKICogc3RydWN0IHsKICogICBBU04uMUNlcnQgY2VydGlmaWNhdGVfbGlzdDwwLi4yXjI0LTE+OwogKiB9IENlcnRpZmljYXRlOwogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgQ2VydGlmaWNhdGUgYnl0ZSBidWZmZXIuCiAqLwp0bHMuY3JlYXRlQ2VydGlmaWNhdGUgPSBmdW5jdGlvbihjKSB7CiAgLy8gVE9ETzogY2hlY2sgY2VydGlmaWNhdGUgcmVxdWVzdCB0byBlbnN1cmUgdHlwZXMgYXJlIHN1cHBvcnRlZAoKICAvLyBnZXQgYSBjZXJ0aWZpY2F0ZSAoYSBjZXJ0aWZpY2F0ZSBhcyBhIFBFTSBzdHJpbmcpCiAgdmFyIGNsaWVudCA9IChjLmVudGl0eSA9PT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KTsKICB2YXIgY2VydCA9IG51bGw7CiAgaWYoYy5nZXRDZXJ0aWZpY2F0ZSkgewogICAgdmFyIGhpbnQ7CiAgICBpZihjbGllbnQpIHsKICAgICAgaGludCA9IGMuc2Vzc2lvbi5jZXJ0aWZpY2F0ZVJlcXVlc3Q7CiAgICB9IGVsc2UgewogICAgICBoaW50ID0gYy5zZXNzaW9uLmV4dGVuc2lvbnMuc2VydmVyX25hbWUuc2VydmVyTmFtZUxpc3Q7CiAgICB9CiAgICBjZXJ0ID0gYy5nZXRDZXJ0aWZpY2F0ZShjLCBoaW50KTsKICB9CgogIC8vIGJ1ZmZlciB0byBob2xkIGNlcnRpZmljYXRlIGxpc3QKICB2YXIgY2VydExpc3QgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIGlmKGNlcnQgIT09IG51bGwpIHsKICAgIHRyeSB7CiAgICAgIC8vIG5vcm1hbGl6ZSBjZXJ0IHRvIGEgY2hhaW4gb2YgY2VydGlmaWNhdGVzCiAgICAgIGlmKCFmb3JnZS51dGlsLmlzQXJyYXkoY2VydCkpIHsKICAgICAgICBjZXJ0ID0gW2NlcnRdOwogICAgICB9CiAgICAgIHZhciBhc24xID0gbnVsbDsKICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGNlcnQubGVuZ3RoOyArK2kpIHsKICAgICAgICB2YXIgbXNnID0gZm9yZ2UucGVtLmRlY29kZShjZXJ0W2ldKVswXTsKICAgICAgICBpZihtc2cudHlwZSAhPT0gJ0NFUlRJRklDQVRFJyAmJgogICAgICAgICAgbXNnLnR5cGUgIT09ICdYNTA5IENFUlRJRklDQVRFJyAmJgogICAgICAgICAgbXNnLnR5cGUgIT09ICdUUlVTVEVEIENFUlRJRklDQVRFJykgewogICAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDb3VsZCBub3QgY29udmVydCBjZXJ0aWZpY2F0ZSBmcm9tIFBFTTsgUEVNICcgKwogICAgICAgICAgICAnaGVhZGVyIHR5cGUgaXMgbm90ICJDRVJUSUZJQ0FURSIsICJYNTA5IENFUlRJRklDQVRFIiwgb3IgJyArCiAgICAgICAgICAgICciVFJVU1RFRCBDRVJUSUZJQ0FURSIuJyk7CiAgICAgICAgICBlcnJvci5oZWFkZXJUeXBlID0gbXNnLnR5cGU7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CiAgICAgICAgaWYobXNnLnByb2NUeXBlICYmIG1zZy5wcm9jVHlwZS50eXBlID09PSAnRU5DUllQVEVEJykgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgY29udmVydCBjZXJ0aWZpY2F0ZSBmcm9tIFBFTTsgUEVNIGlzIGVuY3J5cHRlZC4nKTsKICAgICAgICB9CgogICAgICAgIHZhciBkZXIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihtc2cuYm9keSk7CiAgICAgICAgaWYoYXNuMSA9PT0gbnVsbCkgewogICAgICAgICAgYXNuMSA9IGZvcmdlLmFzbjEuZnJvbURlcihkZXIuYnl0ZXMoKSwgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgLy8gY2VydGlmaWNhdGUgZW50cnkgaXMgaXRzZWxmIGEgdmVjdG9yIHdpdGggMyBsZW5ndGggYnl0ZXMKICAgICAgICB2YXIgY2VydEJ1ZmZlciA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICAgICAgd3JpdGVWZWN0b3IoY2VydEJ1ZmZlciwgMywgZGVyKTsKCiAgICAgICAgLy8gYWRkIGNlcnQgdmVjdG9yIHRvIGNlcnQgbGlzdCB2ZWN0b3IKICAgICAgICBjZXJ0TGlzdC5wdXRCdWZmZXIoY2VydEJ1ZmZlcik7CiAgICAgIH0KCiAgICAgIC8vIHNhdmUgY2VydGlmaWNhdGUKICAgICAgY2VydCA9IGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUZyb21Bc24xKGFzbjEpOwogICAgICBpZihjbGllbnQpIHsKICAgICAgICBjLnNlc3Npb24uY2xpZW50Q2VydGlmaWNhdGUgPSBjZXJ0OwogICAgICB9IGVsc2UgewogICAgICAgIGMuc2Vzc2lvbi5zZXJ2ZXJDZXJ0aWZpY2F0ZSA9IGNlcnQ7CiAgICAgIH0KICAgIH0gY2F0Y2goZXgpIHsKICAgICAgcmV0dXJuIGMuZXJyb3IoYywgewogICAgICAgIG1lc3NhZ2U6ICdDb3VsZCBub3Qgc2VuZCBjZXJ0aWZpY2F0ZSBsaXN0LicsCiAgICAgICAgY2F1c2U6IGV4LAogICAgICAgIHNlbmQ6IHRydWUsCiAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmJhZF9jZXJ0aWZpY2F0ZQogICAgICAgIH0KICAgICAgfSk7CiAgICB9CiAgfQoKICAvLyBkZXRlcm1pbmUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZQogIHZhciBsZW5ndGggPSAzICsgY2VydExpc3QubGVuZ3RoKCk7IC8vIGNlcnQgbGlzdCB2ZWN0b3IKCiAgLy8gYnVpbGQgcmVjb3JkIGZyYWdtZW50CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHJ2YWwucHV0Qnl0ZSh0bHMuSGFuZHNoYWtlVHlwZS5jZXJ0aWZpY2F0ZSk7CiAgcnZhbC5wdXRJbnQyNChsZW5ndGgpOwogIHdyaXRlVmVjdG9yKHJ2YWwsIDMsIGNlcnRMaXN0KTsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDcmVhdGVzIGEgQ2xpZW50S2V5RXhjaGFuZ2UgbWVzc2FnZS4KICoKICogV2hlbiB0aGlzIG1lc3NhZ2Ugd2lsbCBiZSBzZW50OgogKiAgIFRoaXMgbWVzc2FnZSBpcyBhbHdheXMgc2VudCBieSB0aGUgY2xpZW50LiBJdCB3aWxsIGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUKICogICBjbGllbnQgY2VydGlmaWNhdGUgbWVzc2FnZSwgaWYgaXQgaXMgc2VudC4gT3RoZXJ3aXNlIGl0IHdpbGwgYmUgdGhlIGZpcnN0CiAqICAgbWVzc2FnZSBzZW50IGJ5IHRoZSBjbGllbnQgYWZ0ZXIgaXQgcmVjZWl2ZXMgdGhlIHNlcnZlciBoZWxsbyBkb25lCiAqICAgbWVzc2FnZS4KICoKICogTWVhbmluZyBvZiB0aGlzIG1lc3NhZ2U6CiAqICAgV2l0aCB0aGlzIG1lc3NhZ2UsIHRoZSBwcmVtYXN0ZXIgc2VjcmV0IGlzIHNldCwgZWl0aGVyIHRob3VnaCBkaXJlY3QKICogICB0cmFuc21pc3Npb24gb2YgdGhlIFJTQS1lbmNyeXB0ZWQgc2VjcmV0LCBvciBieSB0aGUgdHJhbnNtaXNzaW9uIG9mCiAqICAgRGlmZmllLUhlbGxtYW4gcGFyYW1ldGVycyB3aGljaCB3aWxsIGFsbG93IGVhY2ggc2lkZSB0byBhZ3JlZSB1cG9uIHRoZQogKiAgIHNhbWUgcHJlbWFzdGVyIHNlY3JldC4gV2hlbiB0aGUga2V5IGV4Y2hhbmdlIG1ldGhvZCBpcyBESF9SU0Egb3IgREhfRFNTLAogKiAgIGNsaWVudCBjZXJ0aWZpY2F0aW9uIGhhcyBiZWVuIHJlcXVlc3RlZCwgYW5kIHRoZSBjbGllbnQgd2FzIGFibGUgdG8KICogICByZXNwb25kIHdpdGggYSBjZXJ0aWZpY2F0ZSB3aGljaCBjb250YWluZWQgYSBEaWZmaWUtSGVsbG1hbiBwdWJsaWMga2V5CiAqICAgd2hvc2UgcGFyYW1ldGVycyAoZ3JvdXAgYW5kIGdlbmVyYXRvcikgbWF0Y2hlZCB0aG9zZSBzcGVjaWZpZWQgYnkgdGhlCiAqICAgc2VydmVyIGluIGl0cyBjZXJ0aWZpY2F0ZSwgdGhpcyBtZXNzYWdlIHdpbGwgbm90IGNvbnRhaW4gYW55IGRhdGEuCiAqCiAqIE1lYW5pbmcgb2YgdGhpcyBtZXNzYWdlOgogKiAgIElmIFJTQSBpcyBiZWluZyB1c2VkIGZvciBrZXkgYWdyZWVtZW50IGFuZCBhdXRoZW50aWNhdGlvbiwgdGhlIGNsaWVudAogKiAgIGdlbmVyYXRlcyBhIDQ4LWJ5dGUgcHJlbWFzdGVyIHNlY3JldCwgZW5jcnlwdHMgaXQgdXNpbmcgdGhlIHB1YmxpYyBrZXkKICogICBmcm9tIHRoZSBzZXJ2ZXIncyBjZXJ0aWZpY2F0ZSBvciB0aGUgdGVtcG9yYXJ5IFJTQSBrZXkgcHJvdmlkZWQgaW4gYQogKiAgIHNlcnZlciBrZXkgZXhjaGFuZ2UgbWVzc2FnZSwgYW5kIHNlbmRzIHRoZSByZXN1bHQgaW4gYW4gZW5jcnlwdGVkCiAqICAgcHJlbWFzdGVyIHNlY3JldCBtZXNzYWdlLiBUaGlzIHN0cnVjdHVyZSBpcyBhIHZhcmlhbnQgb2YgdGhlIGNsaWVudAogKiAgIGtleSBleGNoYW5nZSBtZXNzYWdlLCBub3QgYSBtZXNzYWdlIGluIGl0c2VsZi4KICoKICogc3RydWN0IHsKICogICBzZWxlY3QoS2V5RXhjaGFuZ2VBbGdvcml0aG0pIHsKICogICAgIGNhc2UgcnNhOiBFbmNyeXB0ZWRQcmVNYXN0ZXJTZWNyZXQ7CiAqICAgICBjYXNlIGRpZmZpZV9oZWxsbWFuOiBDbGllbnREaWZmaWVIZWxsbWFuUHVibGljOwogKiAgIH0gZXhjaGFuZ2Vfa2V5czsKICogfSBDbGllbnRLZXlFeGNoYW5nZTsKICoKICogc3RydWN0IHsKICogICBQcm90b2NvbFZlcnNpb24gY2xpZW50X3ZlcnNpb247CiAqICAgb3BhcXVlIHJhbmRvbVs0Nl07CiAqIH0gUHJlTWFzdGVyU2VjcmV0OwogKgogKiBzdHJ1Y3QgewogKiAgIHB1YmxpYy1rZXktZW5jcnlwdGVkIFByZU1hc3RlclNlY3JldCBwcmVfbWFzdGVyX3NlY3JldDsKICogfSBFbmNyeXB0ZWRQcmVNYXN0ZXJTZWNyZXQ7CiAqCiAqIEEgcHVibGljLWtleS1lbmNyeXB0ZWQgZWxlbWVudCBpcyBlbmNvZGVkIGFzIGEgdmVjdG9yIDwwLi4yXjE2LTE+LgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgQ2xpZW50S2V5RXhjaGFuZ2UgYnl0ZSBidWZmZXIuCiAqLwp0bHMuY3JlYXRlQ2xpZW50S2V5RXhjaGFuZ2UgPSBmdW5jdGlvbihjKSB7CiAgLy8gY3JlYXRlIGJ1ZmZlciB0byBlbmNyeXB0CiAgdmFyIGIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwoKICAvLyBhZGQgaGlnaGVzdCBjbGllbnQtc3VwcG9ydGVkIHByb3RvY29sIHRvIGhlbHAgc2VydmVyIGF2b2lkIHZlcnNpb24KICAvLyByb2xsYmFjayBhdHRhY2tzCiAgYi5wdXRCeXRlKGMuc2Vzc2lvbi5jbGllbnRIZWxsb1ZlcnNpb24ubWFqb3IpOwogIGIucHV0Qnl0ZShjLnNlc3Npb24uY2xpZW50SGVsbG9WZXJzaW9uLm1pbm9yKTsKCiAgLy8gZ2VuZXJhdGUgYW5kIGFkZCA0NiByYW5kb20gYnl0ZXMKICBiLnB1dEJ5dGVzKGZvcmdlLnJhbmRvbS5nZXRCeXRlcyg0NikpOwoKICAvLyBzYXZlIHByZS1tYXN0ZXIgc2VjcmV0CiAgdmFyIHNwID0gYy5zZXNzaW9uLnNwOwogIHNwLnByZV9tYXN0ZXJfc2VjcmV0ID0gYi5nZXRCeXRlcygpOwoKICAvLyBSU0EtZW5jcnlwdCB0aGUgcHJlLW1hc3RlciBzZWNyZXQKICB2YXIga2V5ID0gYy5zZXNzaW9uLnNlcnZlckNlcnRpZmljYXRlLnB1YmxpY0tleTsKICBiID0ga2V5LmVuY3J5cHQoc3AucHJlX21hc3Rlcl9zZWNyZXQpOwoKICAvKiBOb3RlOiBUaGUgZW5jcnlwdGVkIHByZS1tYXN0ZXIgc2VjcmV0IHdpbGwgYmUgc3RvcmVkIGluIGEKICAgIHB1YmxpYy1rZXktZW5jcnlwdGVkIG9wYXF1ZSB2ZWN0b3IgdGhhdCBoYXMgdGhlIGxlbmd0aCBwcmVmaXhlZCB1c2luZwogICAgMiBieXRlcywgc28gaW5jbHVkZSB0aG9zZSAyIGJ5dGVzIGluIHRoZSBoYW5kc2hha2UgbWVzc2FnZSBsZW5ndGguIFRoaXMKICAgIGlzIGRvbmUgYXMgYSBtaW5vciBvcHRpbWl6YXRpb24gaW5zdGVhZCBvZiBjYWxsaW5nIHdyaXRlVmVjdG9yKCkuICovCgogIC8vIGRldGVybWluZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlCiAgdmFyIGxlbmd0aCA9IGIubGVuZ3RoICsgMjsKCiAgLy8gYnVpbGQgcmVjb3JkIGZyYWdtZW50CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHJ2YWwucHV0Qnl0ZSh0bHMuSGFuZHNoYWtlVHlwZS5jbGllbnRfa2V5X2V4Y2hhbmdlKTsKICBydmFsLnB1dEludDI0KGxlbmd0aCk7CiAgLy8gYWRkIHZlY3RvciBsZW5ndGggYnl0ZXMKICBydmFsLnB1dEludDE2KGIubGVuZ3RoKTsKICBydmFsLnB1dEJ5dGVzKGIpOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBTZXJ2ZXJLZXlFeGNoYW5nZSBtZXNzYWdlLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgU2VydmVyS2V5RXhjaGFuZ2UgYnl0ZSBidWZmZXIuCiAqLwp0bHMuY3JlYXRlU2VydmVyS2V5RXhjaGFuZ2UgPSBmdW5jdGlvbihjKSB7CiAgLy8gdGhpcyBpbXBsZW1lbnRhdGlvbiBvbmx5IHN1cHBvcnRzIFJTQSwgbm8gRGlmZmllLUhlbGxtYW4gc3VwcG9ydCwKICAvLyBzbyB0aGlzIHJlY29yZCBpcyBlbXB0eQoKICAvLyBkZXRlcm1pbmUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZQogIHZhciBsZW5ndGggPSAwOwoKICAvLyBidWlsZCByZWNvcmQgZnJhZ21lbnQKICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgaWYobGVuZ3RoID4gMCkgewogICAgcnZhbC5wdXRCeXRlKHRscy5IYW5kc2hha2VUeXBlLnNlcnZlcl9rZXlfZXhjaGFuZ2UpOwogICAgcnZhbC5wdXRJbnQyNChsZW5ndGgpOwogIH0KICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIHRoZSBzaWduZWQgZGF0YSB1c2VkIHRvIHZlcmlmeSBhIGNsaWVudC1zaWRlIGNlcnRpZmljYXRlLiBTZWUKICogdGxzLmNyZWF0ZUNlcnRpZmljYXRlVmVyaWZ5KCkgZm9yIGRldGFpbHMuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gY2FsbGJhY2sgdGhlIGNhbGxiYWNrIHRvIGNhbGwgb25jZSB0aGUgc2lnbmVkIGRhdGEgaXMgcmVhZHkuCiAqLwp0bHMuZ2V0Q2xpZW50U2lnbmF0dXJlID0gZnVuY3Rpb24oYywgY2FsbGJhY2spIHsKICAvLyBnZW5lcmF0ZSBkYXRhIHRvIFJTQSBlbmNyeXB0CiAgdmFyIGIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIGIucHV0QnVmZmVyKGMuc2Vzc2lvbi5tZDUuZGlnZXN0KCkpOwogIGIucHV0QnVmZmVyKGMuc2Vzc2lvbi5zaGExLmRpZ2VzdCgpKTsKICBiID0gYi5nZXRCeXRlcygpOwoKICAvLyBjcmVhdGUgZGVmYXVsdCBzaWduaW5nIGZ1bmN0aW9uIGFzIG5lY2Vzc2FyeQogIGMuZ2V0U2lnbmF0dXJlID0gYy5nZXRTaWduYXR1cmUgfHwgZnVuY3Rpb24oYywgYiwgY2FsbGJhY2spIHsKICAgIC8vIGRvIHJzYSBlbmNyeXB0aW9uLCBjYWxsIGNhbGxiYWNrCiAgICB2YXIgcHJpdmF0ZUtleSA9IG51bGw7CiAgICBpZihjLmdldFByaXZhdGVLZXkpIHsKICAgICAgdHJ5IHsKICAgICAgICBwcml2YXRlS2V5ID0gYy5nZXRQcml2YXRlS2V5KGMsIGMuc2Vzc2lvbi5jbGllbnRDZXJ0aWZpY2F0ZSk7CiAgICAgICAgcHJpdmF0ZUtleSA9IGZvcmdlLnBraS5wcml2YXRlS2V5RnJvbVBlbShwcml2YXRlS2V5KTsKICAgICAgfSBjYXRjaChleCkgewogICAgICAgIGMuZXJyb3IoYywgewogICAgICAgICAgbWVzc2FnZTogJ0NvdWxkIG5vdCBnZXQgcHJpdmF0ZSBrZXkuJywKICAgICAgICAgIGNhdXNlOiBleCwKICAgICAgICAgIHNlbmQ6IHRydWUsCiAgICAgICAgICBhbGVydDogewogICAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yCiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KICAgIGlmKHByaXZhdGVLZXkgPT09IG51bGwpIHsKICAgICAgYy5lcnJvcihjLCB7CiAgICAgICAgbWVzc2FnZTogJ05vIHByaXZhdGUga2V5IHNldC4nLAogICAgICAgIHNlbmQ6IHRydWUsCiAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yCiAgICAgICAgfQogICAgICB9KTsKICAgIH0gZWxzZSB7CiAgICAgIGIgPSBwcml2YXRlS2V5LnNpZ24oYiwgbnVsbCk7CiAgICB9CiAgICBjYWxsYmFjayhjLCBiKTsKICB9OwoKICAvLyBnZXQgY2xpZW50IHNpZ25hdHVyZQogIGMuZ2V0U2lnbmF0dXJlKGMsIGIsIGNhbGxiYWNrKTsKfTsKCi8qKgogKiBDcmVhdGVzIGEgQ2VydGlmaWNhdGVWZXJpZnkgbWVzc2FnZS4KICoKICogTWVhbmluZyBvZiB0aGlzIG1lc3NhZ2U6CiAqICAgVGhpcyBzdHJ1Y3R1cmUgY29udmV5cyB0aGUgY2xpZW50J3MgRGlmZmllLUhlbGxtYW4gcHVibGljIHZhbHVlCiAqICAgKFljKSBpZiBpdCB3YXMgbm90IGFscmVhZHkgaW5jbHVkZWQgaW4gdGhlIGNsaWVudCdzIGNlcnRpZmljYXRlLgogKiAgIFRoZSBlbmNvZGluZyB1c2VkIGZvciBZYyBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBlbnVtZXJhdGVkCiAqICAgUHVibGljVmFsdWVFbmNvZGluZy4gVGhpcyBzdHJ1Y3R1cmUgaXMgYSB2YXJpYW50IG9mIHRoZSBjbGllbnQKICogICBrZXkgZXhjaGFuZ2UgbWVzc2FnZSwgbm90IGEgbWVzc2FnZSBpbiBpdHNlbGYuCiAqCiAqIFdoZW4gdGhpcyBtZXNzYWdlIHdpbGwgYmUgc2VudDoKICogICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBwcm92aWRlIGV4cGxpY2l0IHZlcmlmaWNhdGlvbiBvZiBhIGNsaWVudAogKiAgIGNlcnRpZmljYXRlLiBUaGlzIG1lc3NhZ2UgaXMgb25seSBzZW50IGZvbGxvd2luZyBhIGNsaWVudAogKiAgIGNlcnRpZmljYXRlIHRoYXQgaGFzIHNpZ25pbmcgY2FwYWJpbGl0eSAoaS5lLiBhbGwgY2VydGlmaWNhdGVzCiAqICAgZXhjZXB0IHRob3NlIGNvbnRhaW5pbmcgZml4ZWQgRGlmZmllLUhlbGxtYW4gcGFyYW1ldGVycykuIFdoZW4KICogICBzZW50LCBpdCB3aWxsIGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUgY2xpZW50IGtleSBleGNoYW5nZSBtZXNzYWdlLgogKgogKiBzdHJ1Y3QgewogKiAgIFNpZ25hdHVyZSBzaWduYXR1cmU7CiAqIH0gQ2VydGlmaWNhdGVWZXJpZnk7CiAqCiAqIENlcnRpZmljYXRlVmVyaWZ5LnNpZ25hdHVyZS5tZDVfaGFzaAogKiAgIE1ENShoYW5kc2hha2VfbWVzc2FnZXMpOwogKgogKiBDZXJ0aWZpY2F0ZS5zaWduYXR1cmUuc2hhX2hhc2gKICogICBTSEEoaGFuZHNoYWtlX21lc3NhZ2VzKTsKICoKICogSGVyZSBoYW5kc2hha2VfbWVzc2FnZXMgcmVmZXJzIHRvIGFsbCBoYW5kc2hha2UgbWVzc2FnZXMgc2VudCBvcgogKiByZWNlaXZlZCBzdGFydGluZyBhdCBjbGllbnQgaGVsbG8gdXAgdG8gYnV0IG5vdCBpbmNsdWRpbmcgdGhpcwogKiBtZXNzYWdlLCBpbmNsdWRpbmcgdGhlIHR5cGUgYW5kIGxlbmd0aCBmaWVsZHMgb2YgdGhlIGhhbmRzaGFrZQogKiBtZXNzYWdlcy4KICoKICogc2VsZWN0KFNpZ25hdHVyZUFsZ29yaXRobSkgewogKiAgIGNhc2UgYW5vbnltb3VzOiBzdHJ1Y3QgeyB9OwogKiAgIGNhc2UgcnNhOgogKiAgICAgZGlnaXRhbGx5LXNpZ25lZCBzdHJ1Y3QgewogKiAgICAgICBvcGFxdWUgbWQ1X2hhc2hbMTZdOwogKiAgICAgICBvcGFxdWUgc2hhX2hhc2hbMjBdOwogKiAgICAgfTsKICogICBjYXNlIGRzYToKICogICAgIGRpZ2l0YWxseS1zaWduZWQgc3RydWN0IHsKICogICAgICAgb3BhcXVlIHNoYV9oYXNoWzIwXTsKICogICAgIH07CiAqIH0gU2lnbmF0dXJlOwogKgogKiBJbiBkaWdpdGFsIHNpZ25pbmcsIG9uZS13YXkgaGFzaCBmdW5jdGlvbnMgYXJlIHVzZWQgYXMgaW5wdXQgZm9yIGEKICogc2lnbmluZyBhbGdvcml0aG0uIEEgZGlnaXRhbGx5LXNpZ25lZCBlbGVtZW50IGlzIGVuY29kZWQgYXMgYW4gb3BhcXVlCiAqIHZlY3RvciA8MC4uMl4xNi0xPiwgd2hlcmUgdGhlIGxlbmd0aCBpcyBzcGVjaWZpZWQgYnkgdGhlIHNpZ25pbmcKICogYWxnb3JpdGhtIGFuZCBrZXkuCiAqCiAqIEluIFJTQSBzaWduaW5nLCBhIDM2LWJ5dGUgc3RydWN0dXJlIG9mIHR3byBoYXNoZXMgKG9uZSBTSEEgYW5kIG9uZQogKiBNRDUpIGlzIHNpZ25lZCAoZW5jcnlwdGVkIHdpdGggdGhlIHByaXZhdGUga2V5KS4gSXQgaXMgZW5jb2RlZCB3aXRoCiAqIFBLQ1MgIzEgYmxvY2sgdHlwZSAwIG9yIHR5cGUgMSBhcyBkZXNjcmliZWQgaW4gW1BLQ1MxXS4KICoKICogSW4gRFNTLCB0aGUgMjAgYnl0ZXMgb2YgdGhlIFNIQSBoYXNoIGFyZSBydW4gZGlyZWN0bHkgdGhyb3VnaCB0aGUKICogRGlnaXRhbCBTaWduaW5nIEFsZ29yaXRobSB3aXRoIG5vIGFkZGl0aW9uYWwgaGFzaGluZy4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSBzaWduYXR1cmUgdGhlIHNpZ25hdHVyZSB0byBpbmNsdWRlIGluIHRoZSBtZXNzYWdlLgogKgogKiBAcmV0dXJuIHRoZSBDZXJ0aWZpY2F0ZVZlcmlmeSBieXRlIGJ1ZmZlci4KICovCnRscy5jcmVhdGVDZXJ0aWZpY2F0ZVZlcmlmeSA9IGZ1bmN0aW9uKGMsIHNpZ25hdHVyZSkgewogIC8qIE5vdGU6IFRoZSBzaWduYXR1cmUgd2lsbCBiZSBzdG9yZWQgaW4gYSAiZGlnaXRhbGx5LXNpZ25lZCIgb3BhcXVlCiAgICB2ZWN0b3IgdGhhdCBoYXMgdGhlIGxlbmd0aCBwcmVmaXhlZCB1c2luZyAyIGJ5dGVzLCBzbyBpbmNsdWRlIHRob3NlCiAgICAyIGJ5dGVzIGluIHRoZSBoYW5kc2hha2UgbWVzc2FnZSBsZW5ndGguIFRoaXMgaXMgZG9uZSBhcyBhIG1pbm9yCiAgICBvcHRpbWl6YXRpb24gaW5zdGVhZCBvZiBjYWxsaW5nIHdyaXRlVmVjdG9yKCkuICovCgogIC8vIGRldGVybWluZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlCiAgdmFyIGxlbmd0aCA9IHNpZ25hdHVyZS5sZW5ndGggKyAyOwoKICAvLyBidWlsZCByZWNvcmQgZnJhZ21lbnQKICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgcnZhbC5wdXRCeXRlKHRscy5IYW5kc2hha2VUeXBlLmNlcnRpZmljYXRlX3ZlcmlmeSk7CiAgcnZhbC5wdXRJbnQyNChsZW5ndGgpOwogIC8vIGFkZCB2ZWN0b3IgbGVuZ3RoIGJ5dGVzCiAgcnZhbC5wdXRJbnQxNihzaWduYXR1cmUubGVuZ3RoKTsKICBydmFsLnB1dEJ5dGVzKHNpZ25hdHVyZSk7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ3JlYXRlcyBhIENlcnRpZmljYXRlUmVxdWVzdCBtZXNzYWdlLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgQ2VydGlmaWNhdGVSZXF1ZXN0IGJ5dGUgYnVmZmVyLgogKi8KdGxzLmNyZWF0ZUNlcnRpZmljYXRlUmVxdWVzdCA9IGZ1bmN0aW9uKGMpIHsKICAvLyBUT0RPOiBzdXBwb3J0IG90aGVyIGNlcnRpZmljYXRlIHR5cGVzCiAgdmFyIGNlcnRUeXBlcyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIGNvbW1vbiBSU0EgY2VydGlmaWNhdGUgdHlwZQogIGNlcnRUeXBlcy5wdXRCeXRlKDB4MDEpOwoKICAvLyBUT0RPOiB2ZXJpZnkgdGhhdCB0aGlzIGRhdGEgZm9ybWF0IGlzIGNvcnJlY3QKICAvLyBhZGQgZGlzdGluZ3Vpc2hlZCBuYW1lcyBmcm9tIENBIHN0b3JlCiAgdmFyIGNBcyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgZm9yKHZhciBrZXkgaW4gYy5jYVN0b3JlLmNlcnRzKSB7CiAgICB2YXIgY2VydCA9IGMuY2FTdG9yZS5jZXJ0c1trZXldOwogICAgdmFyIGRuID0gZm9yZ2UucGtpLmRpc3Rpbmd1aXNoZWROYW1lVG9Bc24xKGNlcnQuc3ViamVjdCk7CiAgICBjQXMucHV0QnVmZmVyKGZvcmdlLmFzbjEudG9EZXIoZG4pKTsKICB9CgogIC8vIFRPRE86IFRMUyAxLjIrIGhhcyBhIGRpZmZlcmVudCBmb3JtYXQKCiAgLy8gZGV0ZXJtaW5lIGxlbmd0aCBvZiB0aGUgaGFuZHNoYWtlIG1lc3NhZ2UKICB2YXIgbGVuZ3RoID0KICAgIDEgKyBjZXJ0VHlwZXMubGVuZ3RoKCkgKwogICAgMiArIGNBcy5sZW5ndGgoKTsKCiAgLy8gYnVpbGQgcmVjb3JkIGZyYWdtZW50CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHJ2YWwucHV0Qnl0ZSh0bHMuSGFuZHNoYWtlVHlwZS5jZXJ0aWZpY2F0ZV9yZXF1ZXN0KTsKICBydmFsLnB1dEludDI0KGxlbmd0aCk7CiAgd3JpdGVWZWN0b3IocnZhbCwgMSwgY2VydFR5cGVzKTsKICB3cml0ZVZlY3RvcihydmFsLCAyLCBjQXMpOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBTZXJ2ZXJIZWxsb0RvbmUgbWVzc2FnZS4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqCiAqIEByZXR1cm4gdGhlIFNlcnZlckhlbGxvRG9uZSBieXRlIGJ1ZmZlci4KICovCnRscy5jcmVhdGVTZXJ2ZXJIZWxsb0RvbmUgPSBmdW5jdGlvbihjKSB7CiAgLy8gYnVpbGQgcmVjb3JkIGZyYWdtZW50CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHJ2YWwucHV0Qnl0ZSh0bHMuSGFuZHNoYWtlVHlwZS5zZXJ2ZXJfaGVsbG9fZG9uZSk7CiAgcnZhbC5wdXRJbnQyNCgwKTsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDcmVhdGVzIGEgQ2hhbmdlQ2lwaGVyU3BlYyBtZXNzYWdlLgogKgogKiBUaGUgY2hhbmdlIGNpcGhlciBzcGVjIHByb3RvY29sIGV4aXN0cyB0byBzaWduYWwgdHJhbnNpdGlvbnMgaW4KICogY2lwaGVyaW5nIHN0cmF0ZWdpZXMuIFRoZSBwcm90b2NvbCBjb25zaXN0cyBvZiBhIHNpbmdsZSBtZXNzYWdlLAogKiB3aGljaCBpcyBlbmNyeXB0ZWQgYW5kIGNvbXByZXNzZWQgdW5kZXIgdGhlIGN1cnJlbnQgKG5vdCB0aGUgcGVuZGluZykKICogY29ubmVjdGlvbiBzdGF0ZS4gVGhlIG1lc3NhZ2UgY29uc2lzdHMgb2YgYSBzaW5nbGUgYnl0ZSBvZiB2YWx1ZSAxLgogKgogKiBzdHJ1Y3QgewogKiAgIGVudW0geyBjaGFuZ2VfY2lwaGVyX3NwZWMoMSksICgyNTUpIH0gdHlwZTsKICogfSBDaGFuZ2VDaXBoZXJTcGVjOwogKgogKiBAcmV0dXJuIHRoZSBDaGFuZ2VDaXBoZXJTcGVjIGJ5dGUgYnVmZmVyLgogKi8KdGxzLmNyZWF0ZUNoYW5nZUNpcGhlclNwZWMgPSBmdW5jdGlvbigpIHsKICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgcnZhbC5wdXRCeXRlKDB4MDEpOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBGaW5pc2hlZCBtZXNzYWdlLgogKgogKiBzdHJ1Y3QgewogKiAgIG9wYXF1ZSB2ZXJpZnlfZGF0YVsxMl07CiAqIH0gRmluaXNoZWQ7CiAqCiAqIHZlcmlmeV9kYXRhCiAqICAgUFJGKG1hc3Rlcl9zZWNyZXQsIGZpbmlzaGVkX2xhYmVsLCBNRDUoaGFuZHNoYWtlX21lc3NhZ2VzKSArCiAqICAgU0hBLTEoaGFuZHNoYWtlX21lc3NhZ2VzKSkgWzAuLjExXTsKICoKICogZmluaXNoZWRfbGFiZWwKICogICBGb3IgRmluaXNoZWQgbWVzc2FnZXMgc2VudCBieSB0aGUgY2xpZW50LCB0aGUgc3RyaW5nICJjbGllbnQKICogICBmaW5pc2hlZCIuIEZvciBGaW5pc2hlZCBtZXNzYWdlcyBzZW50IGJ5IHRoZSBzZXJ2ZXIsIHRoZQogKiAgIHN0cmluZyAic2VydmVyIGZpbmlzaGVkIi4KICoKICogaGFuZHNoYWtlX21lc3NhZ2VzCiAqICAgQWxsIG9mIHRoZSBkYXRhIGZyb20gYWxsIGhhbmRzaGFrZSBtZXNzYWdlcyB1cCB0byBidXQgbm90CiAqICAgaW5jbHVkaW5nIHRoaXMgbWVzc2FnZS4gVGhpcyBpcyBvbmx5IGRhdGEgdmlzaWJsZSBhdCB0aGUKICogICBoYW5kc2hha2UgbGF5ZXIgYW5kIGRvZXMgbm90IGluY2x1ZGUgcmVjb3JkIGxheWVyIGhlYWRlcnMuCiAqICAgVGhpcyBpcyB0aGUgY29uY2F0ZW5hdGlvbiBvZiBhbGwgdGhlIEhhbmRzaGFrZSBzdHJ1Y3R1cmVzIGFzCiAqICAgZGVmaW5lZCBpbiA3LjQgZXhjaGFuZ2VkIHRodXMgZmFyLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgRmluaXNoZWQgYnl0ZSBidWZmZXIuCiAqLwp0bHMuY3JlYXRlRmluaXNoZWQgPSBmdW5jdGlvbihjKSB7CiAgLy8gZ2VuZXJhdGUgdmVyaWZ5X2RhdGEKICB2YXIgYiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgYi5wdXRCdWZmZXIoYy5zZXNzaW9uLm1kNS5kaWdlc3QoKSk7CiAgYi5wdXRCdWZmZXIoYy5zZXNzaW9uLnNoYTEuZGlnZXN0KCkpOwoKICAvLyBUT0RPOiBkZXRlcm1pbmUgcHJmIGZ1bmN0aW9uIGFuZCB2ZXJpZnkgbGVuZ3RoIGZvciBUTFMgMS4yCiAgdmFyIGNsaWVudCA9IChjLmVudGl0eSA9PT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KTsKICB2YXIgc3AgPSBjLnNlc3Npb24uc3A7CiAgdmFyIHZkbCA9IDEyOwogIHZhciBwcmYgPSBwcmZfVExTMTsKICB2YXIgbGFiZWwgPSBjbGllbnQgPyAnY2xpZW50IGZpbmlzaGVkJyA6ICdzZXJ2ZXIgZmluaXNoZWQnOwogIGIgPSBwcmYoc3AubWFzdGVyX3NlY3JldCwgbGFiZWwsIGIuZ2V0Qnl0ZXMoKSwgdmRsKTsKCiAgLy8gYnVpbGQgcmVjb3JkIGZyYWdtZW50CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHJ2YWwucHV0Qnl0ZSh0bHMuSGFuZHNoYWtlVHlwZS5maW5pc2hlZCk7CiAgcnZhbC5wdXRJbnQyNChiLmxlbmd0aCgpKTsKICBydmFsLnB1dEJ1ZmZlcihiKTsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDcmVhdGVzIGEgSGVhcnRiZWF0TWVzc2FnZSAoU2VlIFJGQyA2NTIwKS4KICoKICogc3RydWN0IHsKICogICBIZWFydGJlYXRNZXNzYWdlVHlwZSB0eXBlOwogKiAgIHVpbnQxNiBwYXlsb2FkX2xlbmd0aDsKICogICBvcGFxdWUgcGF5bG9hZFtIZWFydGJlYXRNZXNzYWdlLnBheWxvYWRfbGVuZ3RoXTsKICogICBvcGFxdWUgcGFkZGluZ1twYWRkaW5nX2xlbmd0aF07CiAqIH0gSGVhcnRiZWF0TWVzc2FnZTsKICoKICogVGhlIHRvdGFsIGxlbmd0aCBvZiBhIEhlYXJ0YmVhdE1lc3NhZ2UgTVVTVCBOT1QgZXhjZWVkIDJeMTQgb3IKICogbWF4X2ZyYWdtZW50X2xlbmd0aCB3aGVuIG5lZ290aWF0ZWQgYXMgZGVmaW5lZCBpbiBbUkZDNjA2Nl0uCiAqCiAqIHR5cGU6IFRoZSBtZXNzYWdlIHR5cGUsIGVpdGhlciBoZWFydGJlYXRfcmVxdWVzdCBvciBoZWFydGJlYXRfcmVzcG9uc2UuCiAqCiAqIHBheWxvYWRfbGVuZ3RoOiBUaGUgbGVuZ3RoIG9mIHRoZSBwYXlsb2FkLgogKgogKiBwYXlsb2FkOiBUaGUgcGF5bG9hZCBjb25zaXN0cyBvZiBhcmJpdHJhcnkgY29udGVudC4KICoKICogcGFkZGluZzogVGhlIHBhZGRpbmcgaXMgcmFuZG9tIGNvbnRlbnQgdGhhdCBNVVNUIGJlIGlnbm9yZWQgYnkgdGhlCiAqICAgcmVjZWl2ZXIuIFRoZSBsZW5ndGggb2YgYSBIZWFydGJlYXRNZXNzYWdlIGlzIFRMU1BsYWludGV4dC5sZW5ndGgKICogICBmb3IgVExTIGFuZCBEVExTUGxhaW50ZXh0Lmxlbmd0aCBmb3IgRFRMUy4gRnVydGhlcm1vcmUsIHRoZQogKiAgIGxlbmd0aCBvZiB0aGUgdHlwZSBmaWVsZCBpcyAxIGJ5dGUsIGFuZCB0aGUgbGVuZ3RoIG9mIHRoZQogKiAgIHBheWxvYWRfbGVuZ3RoIGlzIDIuIFRoZXJlZm9yZSwgdGhlIHBhZGRpbmdfbGVuZ3RoIGlzCiAqICAgVExTUGxhaW50ZXh0Lmxlbmd0aCAtIHBheWxvYWRfbGVuZ3RoIC0gMyBmb3IgVExTIGFuZAogKiAgIERUTFNQbGFpbnRleHQubGVuZ3RoIC0gcGF5bG9hZF9sZW5ndGggLSAzIGZvciBEVExTLiBUaGUKICogICBwYWRkaW5nX2xlbmd0aCBNVVNUIGJlIGF0IGxlYXN0IDE2LgogKgogKiBUaGUgc2VuZGVyIG9mIGEgSGVhcnRiZWF0TWVzc2FnZSBNVVNUIHVzZSBhIHJhbmRvbSBwYWRkaW5nIG9mIGF0CiAqIGxlYXN0IDE2IGJ5dGVzLiBUaGUgcGFkZGluZyBvZiBhIHJlY2VpdmVkIEhlYXJ0YmVhdE1lc3NhZ2UgbWVzc2FnZQogKiBNVVNUIGJlIGlnbm9yZWQuCiAqCiAqIElmIHRoZSBwYXlsb2FkX2xlbmd0aCBvZiBhIHJlY2VpdmVkIEhlYXJ0YmVhdE1lc3NhZ2UgaXMgdG9vIGxhcmdlLAogKiB0aGUgcmVjZWl2ZWQgSGVhcnRiZWF0TWVzc2FnZSBNVVNUIGJlIGRpc2NhcmRlZCBzaWxlbnRseS4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSB0eXBlIHRoZSB0bHMuSGVhcnRiZWF0TWVzc2FnZVR5cGUuCiAqIEBwYXJhbSBwYXlsb2FkIHRoZSBoZWFydGJlYXQgZGF0YSB0byBzZW5kIGFzIHRoZSBwYXlsb2FkLgogKiBAcGFyYW0gW3BheWxvYWRMZW5ndGhdIHRoZSBwYXlsb2FkIGxlbmd0aCB0byB1c2UsIGRlZmF1bHRzIHRvIHRoZQogKiAgICAgICAgICBhY3R1YWwgcGF5bG9hZCBsZW5ndGguCiAqCiAqIEByZXR1cm4gdGhlIEhlYXJ0YmVhdFJlcXVlc3QgYnl0ZSBidWZmZXIuCiAqLwp0bHMuY3JlYXRlSGVhcnRiZWF0ID0gZnVuY3Rpb24odHlwZSwgcGF5bG9hZCwgcGF5bG9hZExlbmd0aCkgewogIGlmKHR5cGVvZiBwYXlsb2FkTGVuZ3RoID09PSAndW5kZWZpbmVkJykgewogICAgcGF5bG9hZExlbmd0aCA9IHBheWxvYWQubGVuZ3RoOwogIH0KICAvLyBidWlsZCByZWNvcmQgZnJhZ21lbnQKICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgcnZhbC5wdXRCeXRlKHR5cGUpOyAgICAgICAgICAgICAgIC8vIGhlYXJ0YmVhdCBtZXNzYWdlIHR5cGUKICBydmFsLnB1dEludDE2KHBheWxvYWRMZW5ndGgpOyAgICAgLy8gcGF5bG9hZCBsZW5ndGgKICBydmFsLnB1dEJ5dGVzKHBheWxvYWQpOyAgICAgICAgICAgLy8gcGF5bG9hZAogIC8vIHBhZGRpbmcKICB2YXIgcGxhaW50ZXh0TGVuZ3RoID0gcnZhbC5sZW5ndGgoKTsKICB2YXIgcGFkZGluZ0xlbmd0aCA9IE1hdGgubWF4KDE2LCBwbGFpbnRleHRMZW5ndGggLSBwYXlsb2FkTGVuZ3RoIC0gMyk7CiAgcnZhbC5wdXRCeXRlcyhmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMocGFkZGluZ0xlbmd0aCkpOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIEZyYWdtZW50cywgY29tcHJlc3NlcywgZW5jcnlwdHMsIGFuZCBxdWV1ZXMgYSByZWNvcmQgZm9yIGRlbGl2ZXJ5LgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkIHRvIHF1ZXVlLgogKi8KdGxzLnF1ZXVlID0gZnVuY3Rpb24oYywgcmVjb3JkKSB7CiAgLy8gZXJyb3IgZHVyaW5nIHJlY29yZCBjcmVhdGlvbgogIGlmKCFyZWNvcmQpIHsKICAgIHJldHVybjsKICB9CgogIC8vIGlmIHRoZSByZWNvcmQgaXMgYSBoYW5kc2hha2UgcmVjb3JkLCB1cGRhdGUgaGFuZHNoYWtlIGhhc2hlcwogIGlmKHJlY29yZC50eXBlID09PSB0bHMuQ29udGVudFR5cGUuaGFuZHNoYWtlKSB7CiAgICB2YXIgYnl0ZXMgPSByZWNvcmQuZnJhZ21lbnQuYnl0ZXMoKTsKICAgIGMuc2Vzc2lvbi5tZDUudXBkYXRlKGJ5dGVzKTsKICAgIGMuc2Vzc2lvbi5zaGExLnVwZGF0ZShieXRlcyk7CiAgICBieXRlcyA9IG51bGw7CiAgfQoKICAvLyBoYW5kbGUgcmVjb3JkIGZyYWdtZW50YXRpb24KICB2YXIgcmVjb3JkczsKICBpZihyZWNvcmQuZnJhZ21lbnQubGVuZ3RoKCkgPD0gdGxzLk1heEZyYWdtZW50KSB7CiAgICByZWNvcmRzID0gW3JlY29yZF07CiAgfSBlbHNlIHsKICAgIC8vIGZyYWdtZW50IGRhdGEgYXMgbG9uZyBhcyBpdCBpcyB0b28gbG9uZwogICAgcmVjb3JkcyA9IFtdOwogICAgdmFyIGRhdGEgPSByZWNvcmQuZnJhZ21lbnQuYnl0ZXMoKTsKICAgIHdoaWxlKGRhdGEubGVuZ3RoID4gdGxzLk1heEZyYWdtZW50KSB7CiAgICAgIHJlY29yZHMucHVzaCh0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgICB0eXBlOiByZWNvcmQudHlwZSwKICAgICAgICBkYXRhOiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihkYXRhLnNsaWNlKDAsIHRscy5NYXhGcmFnbWVudCkpCiAgICAgIH0pKTsKICAgICAgZGF0YSA9IGRhdGEuc2xpY2UodGxzLk1heEZyYWdtZW50KTsKICAgIH0KICAgIC8vIGFkZCBsYXN0IHJlY29yZAogICAgaWYoZGF0YS5sZW5ndGggPiAwKSB7CiAgICAgIHJlY29yZHMucHVzaCh0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgICB0eXBlOiByZWNvcmQudHlwZSwKICAgICAgICBkYXRhOiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihkYXRhKQogICAgICB9KSk7CiAgICB9CiAgfQoKICAvLyBjb21wcmVzcyBhbmQgZW5jcnlwdCBhbGwgZnJhZ21lbnRlZCByZWNvcmRzCiAgZm9yKHZhciBpID0gMDsgaSA8IHJlY29yZHMubGVuZ3RoICYmICFjLmZhaWw7ICsraSkgewogICAgLy8gdXBkYXRlIHRoZSByZWNvcmQgdXNpbmcgY3VycmVudCB3cml0ZSBzdGF0ZQogICAgdmFyIHJlYyA9IHJlY29yZHNbaV07CiAgICB2YXIgcyA9IGMuc3RhdGUuY3VycmVudC53cml0ZTsKICAgIGlmKHMudXBkYXRlKGMsIHJlYykpIHsKICAgICAgLy8gc3RvcmUgcmVjb3JkCiAgICAgIGMucmVjb3Jkcy5wdXNoKHJlYyk7CiAgICB9CiAgfQp9OwoKLyoqCiAqIEZsdXNoZXMgYWxsIHF1ZXVlZCByZWNvcmRzIHRvIHRoZSBvdXRwdXQgYnVmZmVyIGFuZCBjYWxscyB0aGUKICogdGxzRGF0YVJlYWR5KCkgaGFuZGxlciBvbiB0aGUgZ2l2ZW4gY29ubmVjdGlvbi4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KdGxzLmZsdXNoID0gZnVuY3Rpb24oYykgewogIGZvcih2YXIgaSA9IDA7IGkgPCBjLnJlY29yZHMubGVuZ3RoOyArK2kpIHsKICAgIHZhciByZWNvcmQgPSBjLnJlY29yZHNbaV07CgogICAgLy8gYWRkIHJlY29yZCBoZWFkZXIgYW5kIGZyYWdtZW50CiAgICBjLnRsc0RhdGEucHV0Qnl0ZShyZWNvcmQudHlwZSk7CiAgICBjLnRsc0RhdGEucHV0Qnl0ZShyZWNvcmQudmVyc2lvbi5tYWpvcik7CiAgICBjLnRsc0RhdGEucHV0Qnl0ZShyZWNvcmQudmVyc2lvbi5taW5vcik7CiAgICBjLnRsc0RhdGEucHV0SW50MTYocmVjb3JkLmZyYWdtZW50Lmxlbmd0aCgpKTsKICAgIGMudGxzRGF0YS5wdXRCdWZmZXIoYy5yZWNvcmRzW2ldLmZyYWdtZW50KTsKICB9CiAgYy5yZWNvcmRzID0gW107CiAgcmV0dXJuIGMudGxzRGF0YVJlYWR5KGMpOwp9OwoKLyoqCiAqIE1hcHMgYSBwa2kuY2VydGlmaWNhdGVFcnJvciB0byBhIHRscy5BbGVydC5EZXNjcmlwdGlvbi4KICoKICogQHBhcmFtIGVycm9yIHRoZSBlcnJvciB0byBtYXAuCiAqCiAqIEByZXR1cm4gdGhlIGFsZXJ0IGRlc2NyaXB0aW9uLgogKi8KdmFyIF9jZXJ0RXJyb3JUb0FsZXJ0RGVzYyA9IGZ1bmN0aW9uKGVycm9yKSB7CiAgc3dpdGNoKGVycm9yKSB7CiAgY2FzZSB0cnVlOgogICAgcmV0dXJuIHRydWU7CiAgY2FzZSBmb3JnZS5wa2kuY2VydGlmaWNhdGVFcnJvci5iYWRfY2VydGlmaWNhdGU6CiAgICByZXR1cm4gdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmJhZF9jZXJ0aWZpY2F0ZTsKICBjYXNlIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLnVuc3VwcG9ydGVkX2NlcnRpZmljYXRlOgogICAgcmV0dXJuIHRscy5BbGVydC5EZXNjcmlwdGlvbi51bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZTsKICBjYXNlIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLmNlcnRpZmljYXRlX3Jldm9rZWQ6CiAgICByZXR1cm4gdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmNlcnRpZmljYXRlX3Jldm9rZWQ7CiAgY2FzZSBmb3JnZS5wa2kuY2VydGlmaWNhdGVFcnJvci5jZXJ0aWZpY2F0ZV9leHBpcmVkOgogICAgcmV0dXJuIHRscy5BbGVydC5EZXNjcmlwdGlvbi5jZXJ0aWZpY2F0ZV9leHBpcmVkOwogIGNhc2UgZm9yZ2UucGtpLmNlcnRpZmljYXRlRXJyb3IuY2VydGlmaWNhdGVfdW5rbm93bjoKICAgIHJldHVybiB0bHMuQWxlcnQuRGVzY3JpcHRpb24uY2VydGlmaWNhdGVfdW5rbm93bjsKICBjYXNlIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLnVua25vd25fY2E6CiAgICByZXR1cm4gdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLnVua25vd25fY2E7CiAgZGVmYXVsdDoKICAgIHJldHVybiB0bHMuQWxlcnQuRGVzY3JpcHRpb24uYmFkX2NlcnRpZmljYXRlOwogIH0KfTsKCi8qKgogKiBNYXBzIGEgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uIHRvIGEgcGtpLmNlcnRpZmljYXRlRXJyb3IuCiAqCiAqIEBwYXJhbSBkZXNjIHRoZSBhbGVydCBkZXNjcmlwdGlvbi4KICoKICogQHJldHVybiB0aGUgY2VydGlmaWNhdGUgZXJyb3IuCiAqLwp2YXIgX2FsZXJ0RGVzY1RvQ2VydEVycm9yID0gZnVuY3Rpb24oZGVzYykgewogIHN3aXRjaChkZXNjKSB7CiAgY2FzZSB0cnVlOgogICAgcmV0dXJuIHRydWU7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uYmFkX2NlcnRpZmljYXRlOgogICAgcmV0dXJuIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLmJhZF9jZXJ0aWZpY2F0ZTsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi51bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZToKICAgIHJldHVybiBmb3JnZS5wa2kuY2VydGlmaWNhdGVFcnJvci51bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZTsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5jZXJ0aWZpY2F0ZV9yZXZva2VkOgogICAgcmV0dXJuIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLmNlcnRpZmljYXRlX3Jldm9rZWQ7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uY2VydGlmaWNhdGVfZXhwaXJlZDoKICAgIHJldHVybiBmb3JnZS5wa2kuY2VydGlmaWNhdGVFcnJvci5jZXJ0aWZpY2F0ZV9leHBpcmVkOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmNlcnRpZmljYXRlX3Vua25vd246CiAgICByZXR1cm4gZm9yZ2UucGtpLmNlcnRpZmljYXRlRXJyb3IuY2VydGlmaWNhdGVfdW5rbm93bjsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi51bmtub3duX2NhOgogICAgcmV0dXJuIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLnVua25vd25fY2E7CiAgZGVmYXVsdDoKICAgIHJldHVybiBmb3JnZS5wa2kuY2VydGlmaWNhdGVFcnJvci5iYWRfY2VydGlmaWNhdGU7CiAgfQp9OwoKLyoqCiAqIFZlcmlmaWVzIGEgY2VydGlmaWNhdGUgY2hhaW4gYWdhaW5zdCB0aGUgZ2l2ZW4gY29ubmVjdGlvbidzCiAqIENlcnRpZmljYXRlIEF1dGhvcml0eSBzdG9yZS4KICoKICogQHBhcmFtIGMgdGhlIFRMUyBjb25uZWN0aW9uLgogKiBAcGFyYW0gY2hhaW4gdGhlIGNlcnRpZmljYXRlIGNoYWluIHRvIHZlcmlmeSwgd2l0aCB0aGUgcm9vdCBvciBoaWdoZXN0CiAqICAgICAgICAgIGF1dGhvcml0eSBhdCB0aGUgZW5kLgogKgogKiBAcmV0dXJuIHRydWUgaWYgc3VjY2Vzc2Z1bCwgZmFsc2UgaWYgbm90LgogKi8KdGxzLnZlcmlmeUNlcnRpZmljYXRlQ2hhaW4gPSBmdW5jdGlvbihjLCBjaGFpbikgewogIHRyeSB7CiAgICAvLyB2ZXJpZnkgY2hhaW4KICAgIGZvcmdlLnBraS52ZXJpZnlDZXJ0aWZpY2F0ZUNoYWluKGMuY2FTdG9yZSwgY2hhaW4sCiAgICAgIGZ1bmN0aW9uIHZlcmlmeSh2ZmQsIGRlcHRoLCBjaGFpbikgewogICAgICAgIC8vIGNvbnZlcnQgcGtpLmNlcnRpZmljYXRlRXJyb3IgdG8gdGxzIGFsZXJ0IGRlc2NyaXB0aW9uCiAgICAgICAgdmFyIGRlc2MgPSBfY2VydEVycm9yVG9BbGVydERlc2ModmZkKTsKCiAgICAgICAgLy8gY2FsbCBhcHBsaWNhdGlvbiBjYWxsYmFjawogICAgICAgIHZhciByZXQgPSBjLnZlcmlmeShjLCB2ZmQsIGRlcHRoLCBjaGFpbik7CiAgICAgICAgaWYocmV0ICE9PSB0cnVlKSB7CiAgICAgICAgICBpZih0eXBlb2YgcmV0ID09PSAnb2JqZWN0JyAmJiAhZm9yZ2UudXRpbC5pc0FycmF5KHJldCkpIHsKICAgICAgICAgICAgLy8gdGhyb3cgY3VzdG9tIGVycm9yCiAgICAgICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignVGhlIGFwcGxpY2F0aW9uIHJlamVjdGVkIHRoZSBjZXJ0aWZpY2F0ZS4nKTsKICAgICAgICAgICAgZXJyb3Iuc2VuZCA9IHRydWU7CiAgICAgICAgICAgIGVycm9yLmFsZXJ0ID0gewogICAgICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5iYWRfY2VydGlmaWNhdGUKICAgICAgICAgICAgfTsKICAgICAgICAgICAgaWYocmV0Lm1lc3NhZ2UpIHsKICAgICAgICAgICAgICBlcnJvci5tZXNzYWdlID0gcmV0Lm1lc3NhZ2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYocmV0LmFsZXJ0KSB7CiAgICAgICAgICAgICAgZXJyb3IuYWxlcnQuZGVzY3JpcHRpb24gPSByZXQuYWxlcnQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgICAgICB9CgogICAgICAgICAgLy8gY29udmVydCB0bHMgYWxlcnQgZGVzY3JpcHRpb24gdG8gcGtpLmNlcnRpZmljYXRlRXJyb3IKICAgICAgICAgIGlmKHJldCAhPT0gdmZkKSB7CiAgICAgICAgICAgIHJldCA9IF9hbGVydERlc2NUb0NlcnRFcnJvcihyZXQpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSk7CiAgfSBjYXRjaChleCkgewogICAgLy8gYnVpbGQgdGxzIGVycm9yIGlmIG5vdCBhbHJlYWR5IGN1c3RvbWl6ZWQKICAgIHZhciBlcnIgPSBleDsKICAgIGlmKHR5cGVvZiBlcnIgIT09ICdvYmplY3QnIHx8IGZvcmdlLnV0aWwuaXNBcnJheShlcnIpKSB7CiAgICAgIGVyciA9IHsKICAgICAgICBzZW5kOiB0cnVlLAogICAgICAgIGFsZXJ0OiB7CiAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgICAgZGVzY3JpcHRpb246IF9jZXJ0RXJyb3JUb0FsZXJ0RGVzYyhleCkKICAgICAgICB9CiAgICAgIH07CiAgICB9CiAgICBpZighKCdzZW5kJyBpbiBlcnIpKSB7CiAgICAgIGVyci5zZW5kID0gdHJ1ZTsKICAgIH0KICAgIGlmKCEoJ2FsZXJ0JyBpbiBlcnIpKSB7CiAgICAgIGVyci5hbGVydCA9IHsKICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgIGRlc2NyaXB0aW9uOiBfY2VydEVycm9yVG9BbGVydERlc2MoZXJyLmVycm9yKQogICAgICB9OwogICAgfQoKICAgIC8vIHNlbmQgZXJyb3IKICAgIGMuZXJyb3IoYywgZXJyKTsKICB9CgogIHJldHVybiAhYy5mYWlsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgVExTIHNlc3Npb24gY2FjaGUuCiAqCiAqIEBwYXJhbSBjYWNoZSBvcHRpb25hbCBtYXAgb2Ygc2Vzc2lvbiBJRCB0byBjYWNoZWQgc2Vzc2lvbi4KICogQHBhcmFtIGNhcGFjaXR5IHRoZSBtYXhpbXVtIHNpemUgZm9yIHRoZSBjYWNoZSAoZGVmYXVsdDogMTAwKS4KICoKICogQHJldHVybiB0aGUgbmV3IFRMUyBzZXNzaW9uIGNhY2hlLgogKi8KdGxzLmNyZWF0ZVNlc3Npb25DYWNoZSA9IGZ1bmN0aW9uKGNhY2hlLCBjYXBhY2l0eSkgewogIHZhciBydmFsID0gbnVsbDsKCiAgLy8gYXNzdW1lIGlucHV0IGlzIGFscmVhZHkgYSBzZXNzaW9uIGNhY2hlIG9iamVjdAogIGlmKGNhY2hlICYmIGNhY2hlLmdldFNlc3Npb24gJiYgY2FjaGUuc2V0U2Vzc2lvbiAmJiBjYWNoZS5vcmRlcikgewogICAgcnZhbCA9IGNhY2hlOwogIH0gZWxzZSB7CiAgICAvLyBjcmVhdGUgY2FjaGUKICAgIHJ2YWwgPSB7fTsKICAgIHJ2YWwuY2FjaGUgPSBjYWNoZSB8fCB7fTsKICAgIHJ2YWwuY2FwYWNpdHkgPSBNYXRoLm1heChjYXBhY2l0eSB8fCAxMDAsIDEpOwogICAgcnZhbC5vcmRlciA9IFtdOwoKICAgIC8vIHN0b3JlIG9yZGVyIGZvciBzZXNzaW9ucywgZGVsZXRlIHNlc3Npb24gb3ZlcmZsb3cKICAgIGZvcih2YXIga2V5IGluIGNhY2hlKSB7CiAgICAgIGlmKHJ2YWwub3JkZXIubGVuZ3RoIDw9IGNhcGFjaXR5KSB7CiAgICAgICAgcnZhbC5vcmRlci5wdXNoKGtleSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGVsZXRlIGNhY2hlW2tleV07CiAgICAgIH0KICAgIH0KCiAgICAvLyBnZXQgYSBzZXNzaW9uIGZyb20gYSBzZXNzaW9uIElEIChvciBnZXQgYW55IHNlc3Npb24pCiAgICBydmFsLmdldFNlc3Npb24gPSBmdW5jdGlvbihzZXNzaW9uSWQpIHsKICAgICAgdmFyIHNlc3Npb24gPSBudWxsOwogICAgICB2YXIga2V5ID0gbnVsbDsKCiAgICAgIC8vIGlmIHNlc3Npb24gSUQgcHJvdmlkZWQsIHVzZSBpdAogICAgICBpZihzZXNzaW9uSWQpIHsKICAgICAgICBrZXkgPSBmb3JnZS51dGlsLmJ5dGVzVG9IZXgoc2Vzc2lvbklkKTsKICAgICAgfSBlbHNlIGlmKHJ2YWwub3JkZXIubGVuZ3RoID4gMCkgewogICAgICAgIC8vIGdldCBmaXJzdCBzZXNzaW9uIGZyb20gY2FjaGUKICAgICAgICBrZXkgPSBydmFsLm9yZGVyWzBdOwogICAgICB9CgogICAgICBpZihrZXkgIT09IG51bGwgJiYga2V5IGluIHJ2YWwuY2FjaGUpIHsKICAgICAgICAvLyBnZXQgY2FjaGVkIHNlc3Npb24gYW5kIHJlbW92ZSBmcm9tIGNhY2hlCiAgICAgICAgc2Vzc2lvbiA9IHJ2YWwuY2FjaGVba2V5XTsKICAgICAgICBkZWxldGUgcnZhbC5jYWNoZVtrZXldOwogICAgICAgIGZvcih2YXIgaSBpbiBydmFsLm9yZGVyKSB7CiAgICAgICAgICBpZihydmFsLm9yZGVyW2ldID09PSBrZXkpIHsKICAgICAgICAgICAgcnZhbC5vcmRlci5zcGxpY2UoaSwgMSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgcmV0dXJuIHNlc3Npb247CiAgICB9OwoKICAgIC8vIHNldCBhIHNlc3Npb24gaW4gdGhlIGNhY2hlCiAgICBydmFsLnNldFNlc3Npb24gPSBmdW5jdGlvbihzZXNzaW9uSWQsIHNlc3Npb24pIHsKICAgICAgLy8gcmVtb3ZlIHNlc3Npb24gZnJvbSBjYWNoZSBpZiBhdCBjYXBhY2l0eQogICAgICBpZihydmFsLm9yZGVyLmxlbmd0aCA9PT0gcnZhbC5jYXBhY2l0eSkgewogICAgICAgIHZhciBrZXkgPSBydmFsLm9yZGVyLnNoaWZ0KCk7CiAgICAgICAgZGVsZXRlIHJ2YWwuY2FjaGVba2V5XTsKICAgICAgfQogICAgICAvLyBhZGQgc2Vzc2lvbiB0byBjYWNoZQogICAgICB2YXIga2V5ID0gZm9yZ2UudXRpbC5ieXRlc1RvSGV4KHNlc3Npb25JZCk7CiAgICAgIHJ2YWwub3JkZXIucHVzaChrZXkpOwogICAgICBydmFsLmNhY2hlW2tleV0gPSBzZXNzaW9uOwogICAgfTsKICB9CgogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgVExTIGNvbm5lY3Rpb24uCiAqCiAqIFNlZSBwdWJsaWMgY3JlYXRlQ29ubmVjdGlvbigpIGRvY3MgZm9yIG1vcmUgZGV0YWlscy4KICoKICogQHBhcmFtIG9wdGlvbnMgdGhlIG9wdGlvbnMgZm9yIHRoaXMgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgbmV3IFRMUyBjb25uZWN0aW9uLgogKi8KdGxzLmNyZWF0ZUNvbm5lY3Rpb24gPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgdmFyIGNhU3RvcmUgPSBudWxsOwogIGlmKG9wdGlvbnMuY2FTdG9yZSkgewogICAgLy8gaWYgQ0Egc3RvcmUgaXMgYW4gYXJyYXksIGNvbnZlcnQgaXQgdG8gYSBDQSBzdG9yZSBvYmplY3QKICAgIGlmKGZvcmdlLnV0aWwuaXNBcnJheShvcHRpb25zLmNhU3RvcmUpKSB7CiAgICAgIGNhU3RvcmUgPSBmb3JnZS5wa2kuY3JlYXRlQ2FTdG9yZShvcHRpb25zLmNhU3RvcmUpOwogICAgfSBlbHNlIHsKICAgICAgY2FTdG9yZSA9IG9wdGlvbnMuY2FTdG9yZTsKICAgIH0KICB9IGVsc2UgewogICAgLy8gY3JlYXRlIGVtcHR5IENBIHN0b3JlCiAgICBjYVN0b3JlID0gZm9yZ2UucGtpLmNyZWF0ZUNhU3RvcmUoKTsKICB9CgogIC8vIHNldHVwIGRlZmF1bHQgY2lwaGVyIHN1aXRlcwogIHZhciBjaXBoZXJTdWl0ZXMgPSBvcHRpb25zLmNpcGhlclN1aXRlcyB8fCBudWxsOwogIGlmKGNpcGhlclN1aXRlcyA9PT0gbnVsbCkgewogICAgY2lwaGVyU3VpdGVzID0gW107CiAgICBmb3IodmFyIGtleSBpbiB0bHMuQ2lwaGVyU3VpdGVzKSB7CiAgICAgIGNpcGhlclN1aXRlcy5wdXNoKHRscy5DaXBoZXJTdWl0ZXNba2V5XSk7CiAgICB9CiAgfQoKICAvLyBzZXQgZGVmYXVsdCBlbnRpdHkKICB2YXIgZW50aXR5ID0gKG9wdGlvbnMuc2VydmVyIHx8IGZhbHNlKSA/CiAgICB0bHMuQ29ubmVjdGlvbkVuZC5zZXJ2ZXIgOiB0bHMuQ29ubmVjdGlvbkVuZC5jbGllbnQ7CgogIC8vIGNyZWF0ZSBzZXNzaW9uIGNhY2hlIGlmIHJlcXVlc3RlZAogIHZhciBzZXNzaW9uQ2FjaGUgPSBvcHRpb25zLnNlc3Npb25DYWNoZSA/CiAgICB0bHMuY3JlYXRlU2Vzc2lvbkNhY2hlKG9wdGlvbnMuc2Vzc2lvbkNhY2hlKSA6IG51bGw7CgogIC8vIGNyZWF0ZSBUTFMgY29ubmVjdGlvbgogIHZhciBjID0gewogICAgdmVyc2lvbjoge21ham9yOiB0bHMuVmVyc2lvbi5tYWpvciwgbWlub3I6IHRscy5WZXJzaW9uLm1pbm9yfSwKICAgIGVudGl0eTogZW50aXR5LAogICAgc2Vzc2lvbklkOiBvcHRpb25zLnNlc3Npb25JZCwKICAgIGNhU3RvcmU6IGNhU3RvcmUsCiAgICBzZXNzaW9uQ2FjaGU6IHNlc3Npb25DYWNoZSwKICAgIGNpcGhlclN1aXRlczogY2lwaGVyU3VpdGVzLAogICAgY29ubmVjdGVkOiBvcHRpb25zLmNvbm5lY3RlZCwKICAgIHZpcnR1YWxIb3N0OiBvcHRpb25zLnZpcnR1YWxIb3N0IHx8IG51bGwsCiAgICB2ZXJpZnlDbGllbnQ6IG9wdGlvbnMudmVyaWZ5Q2xpZW50IHx8IGZhbHNlLAogICAgdmVyaWZ5OiBvcHRpb25zLnZlcmlmeSB8fCBmdW5jdGlvbihjbiwgdmZkLCBkcHRoLCBjdHMpIHtyZXR1cm4gdmZkO30sCiAgICBnZXRDZXJ0aWZpY2F0ZTogb3B0aW9ucy5nZXRDZXJ0aWZpY2F0ZSB8fCBudWxsLAogICAgZ2V0UHJpdmF0ZUtleTogb3B0aW9ucy5nZXRQcml2YXRlS2V5IHx8IG51bGwsCiAgICBnZXRTaWduYXR1cmU6IG9wdGlvbnMuZ2V0U2lnbmF0dXJlIHx8IG51bGwsCiAgICBpbnB1dDogZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKSwKICAgIHRsc0RhdGE6IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCksCiAgICBkYXRhOiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpLAogICAgdGxzRGF0YVJlYWR5OiBvcHRpb25zLnRsc0RhdGFSZWFkeSwKICAgIGRhdGFSZWFkeTogb3B0aW9ucy5kYXRhUmVhZHksCiAgICBoZWFydGJlYXRSZWNlaXZlZDogb3B0aW9ucy5oZWFydGJlYXRSZWNlaXZlZCwKICAgIGNsb3NlZDogb3B0aW9ucy5jbG9zZWQsCiAgICBlcnJvcjogZnVuY3Rpb24oYywgZXgpIHsKICAgICAgLy8gc2V0IG9yaWdpbiBpZiBub3Qgc2V0CiAgICAgIGV4Lm9yaWdpbiA9IGV4Lm9yaWdpbiB8fAogICAgICAgICgoYy5lbnRpdHkgPT09IHRscy5Db25uZWN0aW9uRW5kLmNsaWVudCkgPyAnY2xpZW50JyA6ICdzZXJ2ZXInKTsKCiAgICAgIC8vIHNlbmQgVExTIGFsZXJ0CiAgICAgIGlmKGV4LnNlbmQpIHsKICAgICAgICB0bHMucXVldWUoYywgdGxzLmNyZWF0ZUFsZXJ0KGMsIGV4LmFsZXJ0KSk7CiAgICAgICAgdGxzLmZsdXNoKGMpOwogICAgICB9CgogICAgICAvLyBlcnJvciBpcyBmYXRhbCBieSBkZWZhdWx0CiAgICAgIHZhciBmYXRhbCA9IChleC5mYXRhbCAhPT0gZmFsc2UpOwogICAgICBpZihmYXRhbCkgewogICAgICAgIC8vIHNldCBmYWlsIGZsYWcKICAgICAgICBjLmZhaWwgPSB0cnVlOwogICAgICB9CgogICAgICAvLyBjYWxsIGVycm9yIGhhbmRsZXIgZmlyc3QKICAgICAgb3B0aW9ucy5lcnJvcihjLCBleCk7CgogICAgICBpZihmYXRhbCkgewogICAgICAgIC8vIGZhdGFsIGVycm9yLCBjbG9zZSBjb25uZWN0aW9uLCBkbyBub3QgY2xlYXIgZmFpbAogICAgICAgIGMuY2xvc2UoZmFsc2UpOwogICAgICB9CiAgICB9LAogICAgZGVmbGF0ZTogb3B0aW9ucy5kZWZsYXRlIHx8IG51bGwsCiAgICBpbmZsYXRlOiBvcHRpb25zLmluZmxhdGUgfHwgbnVsbAogIH07CgogIC8qKgogICAqIFJlc2V0cyBhIGNsb3NlZCBUTFMgY29ubmVjdGlvbiBmb3IgcmV1c2UuIENhbGxlZCBpbiBjLmNsb3NlKCkuCiAgICoKICAgKiBAcGFyYW0gY2xlYXJGYWlsIHRydWUgdG8gY2xlYXIgdGhlIGZhaWwgZmxhZyAoZGVmYXVsdDogdHJ1ZSkuCiAgICovCiAgYy5yZXNldCA9IGZ1bmN0aW9uKGNsZWFyRmFpbCkgewogICAgYy52ZXJzaW9uID0ge21ham9yOiB0bHMuVmVyc2lvbi5tYWpvciwgbWlub3I6IHRscy5WZXJzaW9uLm1pbm9yfTsKICAgIGMucmVjb3JkID0gbnVsbDsKICAgIGMuc2Vzc2lvbiA9IG51bGw7CiAgICBjLnBlZXJDZXJ0aWZpY2F0ZSA9IG51bGw7CiAgICBjLnN0YXRlID0gewogICAgICBwZW5kaW5nOiBudWxsLAogICAgICBjdXJyZW50OiBudWxsCiAgICB9OwogICAgYy5leHBlY3QgPSAoYy5lbnRpdHkgPT09IHRscy5Db25uZWN0aW9uRW5kLmNsaWVudCkgPyBTSEUgOiBDSEU7CiAgICBjLmZyYWdtZW50ZWQgPSBudWxsOwogICAgYy5yZWNvcmRzID0gW107CiAgICBjLm9wZW4gPSBmYWxzZTsKICAgIGMuaGFuZHNoYWtlcyA9IDA7CiAgICBjLmhhbmRzaGFraW5nID0gZmFsc2U7CiAgICBjLmlzQ29ubmVjdGVkID0gZmFsc2U7CiAgICBjLmZhaWwgPSAhKGNsZWFyRmFpbCB8fCB0eXBlb2YoY2xlYXJGYWlsKSA9PT0gJ3VuZGVmaW5lZCcpOwogICAgYy5pbnB1dC5jbGVhcigpOwogICAgYy50bHNEYXRhLmNsZWFyKCk7CiAgICBjLmRhdGEuY2xlYXIoKTsKICAgIGMuc3RhdGUuY3VycmVudCA9IHRscy5jcmVhdGVDb25uZWN0aW9uU3RhdGUoYyk7CiAgfTsKCiAgLy8gZG8gaW5pdGlhbCByZXNldCBvZiBjb25uZWN0aW9uCiAgYy5yZXNldCgpOwoKICAvKioKICAgKiBVcGRhdGVzIHRoZSBjdXJyZW50IFRMUyBlbmdpbmUgc3RhdGUgYmFzZWQgb24gdGhlIGdpdmVuIHJlY29yZC4KICAgKgogICAqIEBwYXJhbSBjIHRoZSBUTFMgY29ubmVjdGlvbi4KICAgKiBAcGFyYW0gcmVjb3JkIHRoZSBUTFMgcmVjb3JkIHRvIGFjdCBvbi4KICAgKi8KICB2YXIgX3VwZGF0ZSA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogICAgLy8gZ2V0IHJlY29yZCBoYW5kbGVyIChhbGlnbiB0eXBlIGluIHRhYmxlIGJ5IHN1YnRyYWN0aW5nIGxvd2VzdCkKICAgIHZhciBhbGlnbmVkID0gcmVjb3JkLnR5cGUgLSB0bHMuQ29udGVudFR5cGUuY2hhbmdlX2NpcGhlcl9zcGVjOwogICAgdmFyIGhhbmRsZXJzID0gY3RUYWJsZVtjLmVudGl0eV1bYy5leHBlY3RdOwogICAgaWYoYWxpZ25lZCBpbiBoYW5kbGVycykgewogICAgICBoYW5kbGVyc1thbGlnbmVkXShjLCByZWNvcmQpOwogICAgfSBlbHNlIHsKICAgICAgLy8gdW5leHBlY3RlZCByZWNvcmQKICAgICAgdGxzLmhhbmRsZVVuZXhwZWN0ZWQoYywgcmVjb3JkKTsKICAgIH0KICB9OwoKICAvKioKICAgKiBSZWFkcyB0aGUgcmVjb3JkIGhlYWRlciBhbmQgaW5pdGlhbGl6ZXMgdGhlIG5leHQgcmVjb3JkIG9uIHRoZSBnaXZlbgogICAqIGNvbm5lY3Rpb24uCiAgICoKICAgKiBAcGFyYW0gYyB0aGUgVExTIGNvbm5lY3Rpb24gd2l0aCB0aGUgbmV4dCByZWNvcmQuCiAgICoKICAgKiBAcmV0dXJuIDAgaWYgdGhlIGlucHV0IGRhdGEgY291bGQgYmUgcHJvY2Vzc2VkLCBvdGhlcndpc2UgdGhlCiAgICogICAgICAgICBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgZm9yIGRhdGEgdG8gYmUgcHJvY2Vzc2VkLgogICAqLwogIHZhciBfcmVhZFJlY29yZEhlYWRlciA9IGZ1bmN0aW9uKGMpIHsKICAgIHZhciBydmFsID0gMDsKCiAgICAvLyBnZXQgaW5wdXQgYnVmZmVyIGFuZCBpdHMgbGVuZ3RoCiAgICB2YXIgYiA9IGMuaW5wdXQ7CiAgICB2YXIgbGVuID0gYi5sZW5ndGgoKTsKCiAgICAvLyBuZWVkIGF0IGxlYXN0IDUgYnl0ZXMgdG8gaW5pdGlhbGl6ZSBhIHJlY29yZAogICAgaWYobGVuIDwgNSkgewogICAgICBydmFsID0gNSAtIGxlbjsKICAgIH0gZWxzZSB7CiAgICAgIC8vIGVub3VnaCBieXRlcyBmb3IgaGVhZGVyCiAgICAgIC8vIGluaXRpYWxpemUgcmVjb3JkCiAgICAgIGMucmVjb3JkID0gewogICAgICAgIHR5cGU6IGIuZ2V0Qnl0ZSgpLAogICAgICAgIHZlcnNpb246IHsKICAgICAgICAgIG1ham9yOiBiLmdldEJ5dGUoKSwKICAgICAgICAgIG1pbm9yOiBiLmdldEJ5dGUoKQogICAgICAgIH0sCiAgICAgICAgbGVuZ3RoOiBiLmdldEludDE2KCksCiAgICAgICAgZnJhZ21lbnQ6IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCksCiAgICAgICAgcmVhZHk6IGZhbHNlCiAgICAgIH07CgogICAgICAvLyBjaGVjayByZWNvcmQgdmVyc2lvbgogICAgICB2YXIgY29tcGF0aWJsZVZlcnNpb24gPSAoYy5yZWNvcmQudmVyc2lvbi5tYWpvciA9PT0gYy52ZXJzaW9uLm1ham9yKTsKICAgICAgaWYoY29tcGF0aWJsZVZlcnNpb24gJiYgYy5zZXNzaW9uICYmIGMuc2Vzc2lvbi52ZXJzaW9uKSB7CiAgICAgICAgLy8gc2Vzc2lvbiB2ZXJzaW9uIGFscmVhZHkgc2V0LCByZXF1aXJlIHNhbWUgbWlub3IgdmVyc2lvbgogICAgICAgIGNvbXBhdGlibGVWZXJzaW9uID0gKGMucmVjb3JkLnZlcnNpb24ubWlub3IgPT09IGMudmVyc2lvbi5taW5vcik7CiAgICAgIH0KICAgICAgaWYoIWNvbXBhdGlibGVWZXJzaW9uKSB7CiAgICAgICAgYy5lcnJvcihjLCB7CiAgICAgICAgICBtZXNzYWdlOiAnSW5jb21wYXRpYmxlIFRMUyB2ZXJzaW9uLicsCiAgICAgICAgICBzZW5kOiB0cnVlLAogICAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5wcm90b2NvbF92ZXJzaW9uCiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcnZhbDsKICB9OwoKICAvKioKICAgKiBSZWFkcyB0aGUgbmV4dCByZWNvcmQncyBjb250ZW50cyBhbmQgYXBwZW5kcyBpdHMgbWVzc2FnZSB0byBhbnkKICAgKiBwcmV2aW91c2x5IGZyYWdtZW50ZWQgbWVzc2FnZS4KICAgKgogICAqIEBwYXJhbSBjIHRoZSBUTFMgY29ubmVjdGlvbiB3aXRoIHRoZSBuZXh0IHJlY29yZC4KICAgKgogICAqIEByZXR1cm4gMCBpZiB0aGUgaW5wdXQgZGF0YSBjb3VsZCBiZSBwcm9jZXNzZWQsIG90aGVyd2lzZSB0aGUKICAgKiAgICAgICAgIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCBmb3IgZGF0YSB0byBiZSBwcm9jZXNzZWQuCiAgICovCiAgdmFyIF9yZWFkUmVjb3JkID0gZnVuY3Rpb24oYykgewogICAgdmFyIHJ2YWwgPSAwOwoKICAgIC8vIGVuc3VyZSB0aGVyZSBpcyBlbm91Z2ggaW5wdXQgZGF0YSB0byBnZXQgdGhlIGVudGlyZSByZWNvcmQKICAgIHZhciBiID0gYy5pbnB1dDsKICAgIHZhciBsZW4gPSBiLmxlbmd0aCgpOwogICAgaWYobGVuIDwgYy5yZWNvcmQubGVuZ3RoKSB7CiAgICAgIC8vIG5vdCBlbm91Z2ggZGF0YSB5ZXQsIHJldHVybiBob3cgbXVjaCBpcyByZXF1aXJlZAogICAgICBydmFsID0gYy5yZWNvcmQubGVuZ3RoIC0gbGVuOwogICAgfSBlbHNlIHsKICAgICAgLy8gdGhlcmUgaXMgZW5vdWdoIGRhdGEgdG8gcGFyc2UgdGhlIHBlbmRpbmcgcmVjb3JkCiAgICAgIC8vIGZpbGwgcmVjb3JkIGZyYWdtZW50IGFuZCBjb21wYWN0IGlucHV0IGJ1ZmZlcgogICAgICBjLnJlY29yZC5mcmFnbWVudC5wdXRCeXRlcyhiLmdldEJ5dGVzKGMucmVjb3JkLmxlbmd0aCkpOwogICAgICBiLmNvbXBhY3QoKTsKCiAgICAgIC8vIHVwZGF0ZSByZWNvcmQgdXNpbmcgY3VycmVudCByZWFkIHN0YXRlCiAgICAgIHZhciBzID0gYy5zdGF0ZS5jdXJyZW50LnJlYWQ7CiAgICAgIGlmKHMudXBkYXRlKGMsIGMucmVjb3JkKSkgewogICAgICAgIC8vIHNlZSBpZiB0aGVyZSBpcyBhIHByZXZpb3VzbHkgZnJhZ21lbnRlZCBtZXNzYWdlIHRoYXQgdGhlCiAgICAgICAgLy8gbmV3IHJlY29yZCdzIG1lc3NhZ2UgZnJhZ21lbnQgc2hvdWxkIGJlIGFwcGVuZGVkIHRvCiAgICAgICAgaWYoYy5mcmFnbWVudGVkICE9PSBudWxsKSB7CiAgICAgICAgICAvLyBpZiB0aGUgcmVjb3JkIHR5cGUgbWF0Y2hlcyBhIHByZXZpb3VzbHkgZnJhZ21lbnRlZAogICAgICAgICAgLy8gcmVjb3JkLCBhcHBlbmQgdGhlIHJlY29yZCBmcmFnbWVudCB0byBpdAogICAgICAgICAgaWYoYy5mcmFnbWVudGVkLnR5cGUgPT09IGMucmVjb3JkLnR5cGUpIHsKICAgICAgICAgICAgLy8gY29uY2F0ZW5hdGUgcmVjb3JkIGZyYWdtZW50cwogICAgICAgICAgICBjLmZyYWdtZW50ZWQuZnJhZ21lbnQucHV0QnVmZmVyKGMucmVjb3JkLmZyYWdtZW50KTsKICAgICAgICAgICAgYy5yZWNvcmQgPSBjLmZyYWdtZW50ZWQ7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBlcnJvciwgaW52YWxpZCBmcmFnbWVudGVkIHJlY29yZAogICAgICAgICAgICBjLmVycm9yKGMsIHsKICAgICAgICAgICAgICBtZXNzYWdlOiAnSW52YWxpZCBmcmFnbWVudGVkIHJlY29yZC4nLAogICAgICAgICAgICAgIHNlbmQ6IHRydWUsCiAgICAgICAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjoKICAgICAgICAgICAgICAgICAgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLnVuZXhwZWN0ZWRfbWVzc2FnZQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyByZWNvcmQgaXMgbm93IHJlYWR5CiAgICAgICAgYy5yZWNvcmQucmVhZHkgPSB0cnVlOwogICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJ2YWw7CiAgfTsKCiAgLyoqCiAgICogUGVyZm9ybXMgYSBoYW5kc2hha2UgdXNpbmcgdGhlIFRMUyBIYW5kc2hha2UgUHJvdG9jb2wsIGFzIGEgY2xpZW50LgogICAqCiAgICogVGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGlmIHRoZSBjb25uZWN0aW9uIGlzIGluIGNsaWVudCBtb2RlLgogICAqCiAgICogQHBhcmFtIHNlc3Npb25JZCB0aGUgc2Vzc2lvbiBJRCB0byB1c2UsIG51bGwgdG8gc3RhcnQgYSBuZXcgb25lLgogICAqLwogIGMuaGFuZHNoYWtlID0gZnVuY3Rpb24oc2Vzc2lvbklkKSB7CiAgICAvLyBlcnJvciB0byBjYWxsIHRoaXMgaW4gbm9uLWNsaWVudCBtb2RlCiAgICBpZihjLmVudGl0eSAhPT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KSB7CiAgICAgIC8vIG5vdCBmYXRhbCBlcnJvcgogICAgICBjLmVycm9yKGMsIHsKICAgICAgICBtZXNzYWdlOiAnQ2Fubm90IGluaXRpYXRlIGhhbmRzaGFrZSBhcyBhIHNlcnZlci4nLAogICAgICAgIGZhdGFsOiBmYWxzZQogICAgICB9KTsKICAgIH0gZWxzZSBpZihjLmhhbmRzaGFraW5nKSB7CiAgICAgIC8vIGhhbmRzaGFrZSBpcyBhbHJlYWR5IGluIHByb2dyZXNzLCBmYWlsIGJ1dCBub3QgZmF0YWwgZXJyb3IKICAgICAgYy5lcnJvcihjLCB7CiAgICAgICAgbWVzc2FnZTogJ0hhbmRzaGFrZSBhbHJlYWR5IGluIHByb2dyZXNzLicsCiAgICAgICAgZmF0YWw6IGZhbHNlCiAgICAgIH0pOwogICAgfSBlbHNlIHsKICAgICAgLy8gY2xlYXIgZmFpbCBmbGFnIG9uIHJldXNlCiAgICAgIGlmKGMuZmFpbCAmJiAhYy5vcGVuICYmIGMuaGFuZHNoYWtlcyA9PT0gMCkgewogICAgICAgIGMuZmFpbCA9IGZhbHNlOwogICAgICB9CgogICAgICAvLyBub3cgaGFuZHNoYWtpbmcKICAgICAgYy5oYW5kc2hha2luZyA9IHRydWU7CgogICAgICAvLyBkZWZhdWx0IHRvIGJsYW5rIChuZXcgc2Vzc2lvbikKICAgICAgc2Vzc2lvbklkID0gc2Vzc2lvbklkIHx8ICcnOwoKICAgICAgLy8gaWYgYSBzZXNzaW9uIElEIHdhcyBzcGVjaWZpZWQsIHRyeSB0byBmaW5kIGl0IGluIHRoZSBjYWNoZQogICAgICB2YXIgc2Vzc2lvbiA9IG51bGw7CiAgICAgIGlmKHNlc3Npb25JZC5sZW5ndGggPiAwKSB7CiAgICAgICAgaWYoYy5zZXNzaW9uQ2FjaGUpIHsKICAgICAgICAgIHNlc3Npb24gPSBjLnNlc3Npb25DYWNoZS5nZXRTZXNzaW9uKHNlc3Npb25JZCk7CiAgICAgICAgfQoKICAgICAgICAvLyBtYXRjaGluZyBzZXNzaW9uIG5vdCBmb3VuZCBpbiBjYWNoZSwgY2xlYXIgc2Vzc2lvbiBJRAogICAgICAgIGlmKHNlc3Npb24gPT09IG51bGwpIHsKICAgICAgICAgIHNlc3Npb25JZCA9ICcnOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gbm8gc2Vzc2lvbiBnaXZlbiwgZ3JhYiBhIHNlc3Npb24gZnJvbSB0aGUgY2FjaGUsIGlmIGF2YWlsYWJsZQogICAgICBpZihzZXNzaW9uSWQubGVuZ3RoID09PSAwICYmIGMuc2Vzc2lvbkNhY2hlKSB7CiAgICAgICAgc2Vzc2lvbiA9IGMuc2Vzc2lvbkNhY2hlLmdldFNlc3Npb24oKTsKICAgICAgICBpZihzZXNzaW9uICE9PSBudWxsKSB7CiAgICAgICAgICBzZXNzaW9uSWQgPSBzZXNzaW9uLmlkOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gc2V0IHVwIHNlc3Npb24KICAgICAgYy5zZXNzaW9uID0gewogICAgICAgIGlkOiBzZXNzaW9uSWQsCiAgICAgICAgdmVyc2lvbjogbnVsbCwKICAgICAgICBjaXBoZXJTdWl0ZTogbnVsbCwKICAgICAgICBjb21wcmVzc2lvbk1ldGhvZDogbnVsbCwKICAgICAgICBzZXJ2ZXJDZXJ0aWZpY2F0ZTogbnVsbCwKICAgICAgICBjZXJ0aWZpY2F0ZVJlcXVlc3Q6IG51bGwsCiAgICAgICAgY2xpZW50Q2VydGlmaWNhdGU6IG51bGwsCiAgICAgICAgc3A6IHt9LAogICAgICAgIG1kNTogZm9yZ2UubWQubWQ1LmNyZWF0ZSgpLAogICAgICAgIHNoYTE6IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCkKICAgICAgfTsKCiAgICAgIC8vIHVzZSBleGlzdGluZyBzZXNzaW9uIGluZm9ybWF0aW9uCiAgICAgIGlmKHNlc3Npb24pIHsKICAgICAgICAvLyBvbmx5IHVwZGF0ZSB2ZXJzaW9uIG9uIGNvbm5lY3Rpb24sIHNlc3Npb24gdmVyc2lvbiBub3QgeWV0IHNldAogICAgICAgIGMudmVyc2lvbiA9IHNlc3Npb24udmVyc2lvbjsKICAgICAgICBjLnNlc3Npb24uc3AgPSBzZXNzaW9uLnNwOwogICAgICB9CgogICAgICAvLyBnZW5lcmF0ZSBuZXcgY2xpZW50IHJhbmRvbQogICAgICBjLnNlc3Npb24uc3AuY2xpZW50X3JhbmRvbSA9IHRscy5jcmVhdGVSYW5kb20oKS5nZXRCeXRlcygpOwoKICAgICAgLy8gY29ubmVjdGlvbiBub3cgb3BlbgogICAgICBjLm9wZW4gPSB0cnVlOwoKICAgICAgLy8gc2VuZCBoZWxsbwogICAgICB0bHMucXVldWUoYywgdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhhbmRzaGFrZSwKICAgICAgICBkYXRhOiB0bHMuY3JlYXRlQ2xpZW50SGVsbG8oYykKICAgICAgfSkpOwogICAgICB0bHMuZmx1c2goYyk7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogQ2FsbGVkIHdoZW4gVExTIHByb3RvY29sIGRhdGEgaGFzIGJlZW4gcmVjZWl2ZWQgZnJvbSBzb21ld2hlcmUgYW5kIHNob3VsZAogICAqIGJlIHByb2Nlc3NlZCBieSB0aGUgVExTIGVuZ2luZS4KICAgKgogICAqIEBwYXJhbSBkYXRhIHRoZSBUTFMgcHJvdG9jb2wgZGF0YSwgYXMgYSBzdHJpbmcsIHRvIHByb2Nlc3MuCiAgICoKICAgKiBAcmV0dXJuIDAgaWYgdGhlIGRhdGEgY291bGQgYmUgcHJvY2Vzc2VkLCBvdGhlcndpc2UgdGhlIG51bWJlciBvZiBieXRlcwogICAqICAgICAgICAgcmVxdWlyZWQgZm9yIGRhdGEgdG8gYmUgcHJvY2Vzc2VkLgogICAqLwogIGMucHJvY2VzcyA9IGZ1bmN0aW9uKGRhdGEpIHsKICAgIHZhciBydmFsID0gMDsKCiAgICAvLyBidWZmZXIgaW5wdXQgZGF0YQogICAgaWYoZGF0YSkgewogICAgICBjLmlucHV0LnB1dEJ5dGVzKGRhdGEpOwogICAgfQoKICAgIC8vIHByb2Nlc3MgbmV4dCByZWNvcmQgaWYgbm8gZmFpbHVyZSwgcHJvY2VzcyB3aWxsIGJlIGNhbGxlZCBhZnRlcgogICAgLy8gZWFjaCByZWNvcmQgaXMgaGFuZGxlZCAoc2luY2UgaGFuZGxpbmcgY2FuIGJlIGFzeW5jaHJvbm91cykKICAgIGlmKCFjLmZhaWwpIHsKICAgICAgLy8gcmVzZXQgcmVjb3JkIGlmIHJlYWR5IGFuZCBub3cgZW1wdHkKICAgICAgaWYoYy5yZWNvcmQgIT09IG51bGwgJiYKICAgICAgICBjLnJlY29yZC5yZWFkeSAmJiBjLnJlY29yZC5mcmFnbWVudC5pc0VtcHR5KCkpIHsKICAgICAgICBjLnJlY29yZCA9IG51bGw7CiAgICAgIH0KCiAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIHBlbmRpbmcgcmVjb3JkLCB0cnkgdG8gcmVhZCByZWNvcmQgaGVhZGVyCiAgICAgIGlmKGMucmVjb3JkID09PSBudWxsKSB7CiAgICAgICAgcnZhbCA9IF9yZWFkUmVjb3JkSGVhZGVyKGMpOwogICAgICB9CgogICAgICAvLyByZWFkIHRoZSBuZXh0IHJlY29yZCAoaWYgcmVjb3JkIG5vdCB5ZXQgcmVhZHkpCiAgICAgIGlmKCFjLmZhaWwgJiYgYy5yZWNvcmQgIT09IG51bGwgJiYgIWMucmVjb3JkLnJlYWR5KSB7CiAgICAgICAgcnZhbCA9IF9yZWFkUmVjb3JkKGMpOwogICAgICB9CgogICAgICAvLyByZWNvcmQgcmVhZHkgdG8gYmUgaGFuZGxlZCwgdXBkYXRlIGVuZ2luZSBzdGF0ZQogICAgICBpZighYy5mYWlsICYmIGMucmVjb3JkICE9PSBudWxsICYmIGMucmVjb3JkLnJlYWR5KSB7CiAgICAgICAgX3VwZGF0ZShjLCBjLnJlY29yZCk7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcnZhbDsKICB9OwoKICAvKioKICAgKiBSZXF1ZXN0cyB0aGF0IGFwcGxpY2F0aW9uIGRhdGEgYmUgcGFja2FnZWQgaW50byBhIFRMUyByZWNvcmQuIFRoZQogICAqIHRsc0RhdGFSZWFkeSBoYW5kbGVyIHdpbGwgYmUgY2FsbGVkIHdoZW4gdGhlIFRMUyByZWNvcmQocykgaGF2ZSBiZWVuCiAgICogcHJlcGFyZWQuCiAgICoKICAgKiBAcGFyYW0gZGF0YSB0aGUgYXBwbGljYXRpb24gZGF0YSwgYXMgYSByYXcgJ2JpbmFyeScgZW5jb2RlZCBzdHJpbmcsIHRvCiAgICogICAgICAgICAgYmUgc2VudDsgdG8gc2VuZCB1dGYtMTYvdXRmLTggc3RyaW5nIGRhdGEsIHVzZSB0aGUgcmV0dXJuIHZhbHVlCiAgICogICAgICAgICAgb2YgdXRpbC5lbmNvZGVVdGY4KHN0cikuCiAgICoKICAgKiBAcmV0dXJuIHRydWUgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZS4KICAgKi8KICBjLnByZXBhcmUgPSBmdW5jdGlvbihkYXRhKSB7CiAgICB0bHMucXVldWUoYywgdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICAgIHR5cGU6IHRscy5Db250ZW50VHlwZS5hcHBsaWNhdGlvbl9kYXRhLAogICAgICBkYXRhOiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihkYXRhKQogICAgfSkpOwogICAgcmV0dXJuIHRscy5mbHVzaChjKTsKICB9OwoKICAvKioKICAgKiBSZXF1ZXN0cyB0aGF0IGEgaGVhcnRiZWF0IHJlcXVlc3QgYmUgcGFja2FnZWQgaW50byBhIFRMUyByZWNvcmQgZm9yCiAgICogdHJhbnNtaXNzaW9uLiBUaGUgdGxzRGF0YVJlYWR5IGhhbmRsZXIgd2lsbCBiZSBjYWxsZWQgd2hlbiBUTFMgcmVjb3JkKHMpCiAgICogaGF2ZSBiZWVuIHByZXBhcmVkLgogICAqCiAgICogV2hlbiBhIGhlYXJ0YmVhdCByZXNwb25zZSBoYXMgYmVlbiByZWNlaXZlZCwgdGhlIGhlYXJ0YmVhdFJlY2VpdmVkCiAgICogaGFuZGxlciB3aWxsIGJlIGNhbGxlZCB3aXRoIHRoZSBtYXRjaGluZyBwYXlsb2FkLiBUaGlzIGhhbmRsZXIgY2FuCiAgICogYmUgdXNlZCB0byBjbGVhciBhIHJldHJhbnNtaXNzaW9uIHRpbWVyLCBldGMuCiAgICoKICAgKiBAcGFyYW0gcGF5bG9hZCB0aGUgaGVhcnRiZWF0IGRhdGEgdG8gc2VuZCBhcyB0aGUgcGF5bG9hZCBpbiB0aGUgbWVzc2FnZS4KICAgKiBAcGFyYW0gW3BheWxvYWRMZW5ndGhdIHRoZSBwYXlsb2FkIGxlbmd0aCB0byB1c2UsIGRlZmF1bHRzIHRvIHRoZQogICAqICAgICAgICAgIGFjdHVhbCBwYXlsb2FkIGxlbmd0aC4KICAgKgogICAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogICAqLwogIGMucHJlcGFyZUhlYXJ0YmVhdFJlcXVlc3QgPSBmdW5jdGlvbihwYXlsb2FkLCBwYXlsb2FkTGVuZ3RoKSB7CiAgICBpZihwYXlsb2FkIGluc3RhbmNlb2YgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKSB7CiAgICAgIHBheWxvYWQgPSBwYXlsb2FkLmJ5dGVzKCk7CiAgICB9CiAgICBpZih0eXBlb2YgcGF5bG9hZExlbmd0aCA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgcGF5bG9hZExlbmd0aCA9IHBheWxvYWQubGVuZ3RoOwogICAgfQogICAgYy5leHBlY3RlZEhlYXJ0YmVhdFBheWxvYWQgPSBwYXlsb2FkOwogICAgdGxzLnF1ZXVlKGMsIHRscy5jcmVhdGVSZWNvcmQoYywgewogICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuaGVhcnRiZWF0LAogICAgICBkYXRhOiB0bHMuY3JlYXRlSGVhcnRiZWF0KAogICAgICAgIHRscy5IZWFydGJlYXRNZXNzYWdlVHlwZS5oZWFydGJlYXRfcmVxdWVzdCwgcGF5bG9hZCwgcGF5bG9hZExlbmd0aCkKICAgIH0pKTsKICAgIHJldHVybiB0bHMuZmx1c2goYyk7CiAgfTsKCiAgLyoqCiAgICogQ2xvc2VzIHRoZSBjb25uZWN0aW9uIChzZW5kcyBhIGNsb3NlX25vdGlmeSBhbGVydCkuCiAgICoKICAgKiBAcGFyYW0gY2xlYXJGYWlsIHRydWUgdG8gY2xlYXIgdGhlIGZhaWwgZmxhZyAoZGVmYXVsdDogdHJ1ZSkuCiAgICovCiAgYy5jbG9zZSA9IGZ1bmN0aW9uKGNsZWFyRmFpbCkgewogICAgLy8gc2F2ZSBzZXNzaW9uIGlmIGNvbm5lY3Rpb24gZGlkbid0IGZhaWwKICAgIGlmKCFjLmZhaWwgJiYgYy5zZXNzaW9uQ2FjaGUgJiYgYy5zZXNzaW9uKSB7CiAgICAgIC8vIG9ubHkgbmVlZCB0byBwcmVzZXJ2ZSBzZXNzaW9uIElELCB2ZXJzaW9uLCBhbmQgc2VjdXJpdHkgcGFyYW1zCiAgICAgIHZhciBzZXNzaW9uID0gewogICAgICAgIGlkOiBjLnNlc3Npb24uaWQsCiAgICAgICAgdmVyc2lvbjogYy5zZXNzaW9uLnZlcnNpb24sCiAgICAgICAgc3A6IGMuc2Vzc2lvbi5zcAogICAgICB9OwogICAgICBzZXNzaW9uLnNwLmtleXMgPSBudWxsOwogICAgICBjLnNlc3Npb25DYWNoZS5zZXRTZXNzaW9uKHNlc3Npb24uaWQsIHNlc3Npb24pOwogICAgfQoKICAgIGlmKGMub3BlbikgewogICAgICAvLyBjb25uZWN0aW9uIG5vIGxvbmdlciBvcGVuLCBjbGVhciBpbnB1dAogICAgICBjLm9wZW4gPSBmYWxzZTsKICAgICAgYy5pbnB1dC5jbGVhcigpOwoKICAgICAgLy8gaWYgY29ubmVjdGVkIG9yIGhhbmRzaGFraW5nLCBzZW5kIGFuIGFsZXJ0CiAgICAgIGlmKGMuaXNDb25uZWN0ZWQgfHwgYy5oYW5kc2hha2luZykgewogICAgICAgIGMuaXNDb25uZWN0ZWQgPSBjLmhhbmRzaGFraW5nID0gZmFsc2U7CgogICAgICAgIC8vIHNlbmQgY2xvc2Vfbm90aWZ5IGFsZXJ0CiAgICAgICAgdGxzLnF1ZXVlKGMsIHRscy5jcmVhdGVBbGVydChjLCB7CiAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLndhcm5pbmcsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmNsb3NlX25vdGlmeQogICAgICAgIH0pKTsKICAgICAgICB0bHMuZmx1c2goYyk7CiAgICAgIH0KCiAgICAgIC8vIGNhbGwgaGFuZGxlcgogICAgICBjLmNsb3NlZChjKTsKICAgIH0KCiAgICAvLyByZXNldCBUTFMgY29ubmVjdGlvbiwgZG8gbm90IGNsZWFyIGZhaWwgZmxhZwogICAgYy5yZXNldChjbGVhckZhaWwpOwogIH07CgogIHJldHVybiBjOwp9OwoKLyogVExTIEFQSSAqLwpmb3JnZS50bHMgPSBmb3JnZS50bHMgfHwge307CgovLyBleHBvc2Ugbm9uLWZ1bmN0aW9ucwpmb3IodmFyIGtleSBpbiB0bHMpIHsKICBpZih0eXBlb2YgdGxzW2tleV0gIT09ICdmdW5jdGlvbicpIHsKICAgIGZvcmdlLnRsc1trZXldID0gdGxzW2tleV07CiAgfQp9CgovLyBleHBvc2UgcHJmX3RsczEgZm9yIHRlc3RpbmcKZm9yZ2UudGxzLnByZl90bHMxID0gcHJmX1RMUzE7CgovLyBleHBvc2Ugc2hhMSBobWFjIG1ldGhvZApmb3JnZS50bHMuaG1hY19zaGExID0gaG1hY19zaGExOwoKLy8gZXhwb3NlIHNlc3Npb24gY2FjaGUgY3JlYXRpb24KZm9yZ2UudGxzLmNyZWF0ZVNlc3Npb25DYWNoZSA9IHRscy5jcmVhdGVTZXNzaW9uQ2FjaGU7CgovKioKICogQ3JlYXRlcyBhIG5ldyBUTFMgY29ubmVjdGlvbi4gVGhpcyBkb2VzIG5vdCBtYWtlIGFueSBhc3N1bXB0aW9ucyBhYm91dCB0aGUKICogdHJhbnNwb3J0IGxheWVyIHRoYXQgVExTIGlzIHdvcmtpbmcgb24gdG9wIG9mLCBpZTogaXQgZG9lcyBub3QgYXNzdW1lIHRoZXJlCiAqIGlzIGEgVENQL0lQIGNvbm5lY3Rpb24gb3IgZXN0YWJsaXNoIG9uZS4gQSBUTFMgY29ubmVjdGlvbiBpcyB0b3RhbGx5CiAqIGFic3RyYWN0ZWQgYXdheSBmcm9tIHRoZSBsYXllciBpcyBydW5zIG9uIHRvcCBvZiwgaXQgbWVyZWx5IGVzdGFibGlzaGVzIGEKICogc2VjdXJlIGNoYW5uZWwgYmV0d2VlbiBhIGNsaWVudCIgYW5kIGEgInNlcnZlciIuCiAqCiAqIEEgVExTIGNvbm5lY3Rpb24gY29udGFpbnMgNCBjb25uZWN0aW9uIHN0YXRlczogcGVuZGluZyByZWFkIGFuZCB3cml0ZSwgYW5kCiAqIGN1cnJlbnQgcmVhZCBhbmQgd3JpdGUuCiAqCiAqIEF0IGluaXRpYWxpemF0aW9uLCB0aGUgY3VycmVudCByZWFkIGFuZCB3cml0ZSBzdGF0ZXMgd2lsbCBiZSBudWxsLiBPbmx5IG9uY2UKICogdGhlIHNlY3VyaXR5IHBhcmFtZXRlcnMgaGF2ZSBiZWVuIHNldCBhbmQgdGhlIGtleXMgaGF2ZSBiZWVuIGdlbmVyYXRlZCBjYW4KICogdGhlIHBlbmRpbmcgc3RhdGVzIGJlIGNvbnZlcnRlZCBpbnRvIGN1cnJlbnQgc3RhdGVzLiBDdXJyZW50IHN0YXRlcyB3aWxsIGJlCiAqIHVwZGF0ZWQgZm9yIGVhY2ggcmVjb3JkIHByb2Nlc3NlZC4KICoKICogQSBjdXN0b20gY2VydGlmaWNhdGUgdmVyaWZ5IGNhbGxiYWNrIG1heSBiZSBwcm92aWRlZCB0byBjaGVjayBpbmZvcm1hdGlvbgogKiBsaWtlIHRoZSBjb21tb24gbmFtZSBvbiB0aGUgc2VydmVyJ3MgY2VydGlmaWNhdGUuIEl0IHdpbGwgYmUgY2FsbGVkIGZvcgogKiBldmVyeSBjZXJ0aWZpY2F0ZSBpbiB0aGUgY2hhaW4uIEl0IGhhcyB0aGUgZm9sbG93aW5nIHNpZ25hdHVyZToKICoKICogdmFyaWFibGUgZnVuYyhjLCBjZXJ0cywgaW5kZXgsIHByZVZlcmlmeSkKICogV2hlcmU6CiAqIGMgICAgICAgICBUaGUgVExTIGNvbm5lY3Rpb24KICogdmVyaWZpZWQgIFNldCB0byB0cnVlIGlmIGNlcnRpZmljYXRlIHdhcyB2ZXJpZmllZCwgb3RoZXJ3aXNlIHRoZSBhbGVydAogKiAgICAgICAgICAgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uIGZvciB3aHkgdGhlIGNlcnRpZmljYXRlIGZhaWxlZC4KICogZGVwdGggICAgIFRoZSBjdXJyZW50IGluZGV4IGluIHRoZSBjaGFpbiwgd2hlcmUgMCBpcyB0aGUgc2VydmVyJ3MgY2VydC4KICogY2VydHMgICAgIFRoZSBjZXJ0aWZpY2F0ZSBjaGFpbiwgKk5PVEUqIGlmIHRoZSBzZXJ2ZXIgd2FzIGFub255bW91cyB0aGVuCiAqICAgICAgICAgICB0aGUgY2hhaW4gd2lsbCBiZSBlbXB0eS4KICoKICogVGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzIGFuZCBvbiBmYWlsdXJlIGVpdGhlciB0aGUgYXBwcm9wcmlhdGUKICogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uIG9yIGFuIG9iamVjdCB3aXRoICdhbGVydCcgc2V0IHRvIHRoZSBhcHByb3ByaWF0ZQogKiB0bHMuQWxlcnQuRGVzY3JpcHRpb24gYW5kICdtZXNzYWdlJyBzZXQgdG8gYSBjdXN0b20gZXJyb3IgbWVzc2FnZS4gSWYgdHJ1ZQogKiBpcyBub3QgcmV0dXJuZWQgdGhlbiB0aGUgY29ubmVjdGlvbiB3aWxsIGFib3J0IHVzaW5nLCBpbiBvcmRlciBvZgogKiBhdmFpbGFiaWxpdHksIGZpcnN0IHRoZSByZXR1cm5lZCBhbGVydCBkZXNjcmlwdGlvbiwgc2Vjb25kIHRoZSBwcmVWZXJpZnkKICogYWxlcnQgZGVzY3JpcHRpb24sIGFuZCBsYXN0bHkgdGhlIGRlZmF1bHQgJ2JhZF9jZXJ0aWZpY2F0ZScuCiAqCiAqIFRoZXJlIGFyZSB0aHJlZSBjYWxsYmFja3MgdGhhdCBjYW4gYmUgdXNlZCB0byBtYWtlIHVzZSBvZiBjbGllbnQtc2lkZQogKiBjZXJ0aWZpY2F0ZXMgd2hlcmUgZWFjaCB0YWtlcyB0aGUgVExTIGNvbm5lY3Rpb24gYXMgdGhlIGZpcnN0IHBhcmFtZXRlcjoKICoKICogZ2V0Q2VydGlmaWNhdGUoY29ubiwgaGludCkKICogICBUaGUgc2Vjb25kIHBhcmFtZXRlciBpcyBhIGhpbnQgYXMgdG8gd2hpY2ggY2VydGlmaWNhdGUgc2hvdWxkIGJlCiAqICAgcmV0dXJuZWQuIElmIHRoZSBjb25uZWN0aW9uIGVudGl0eSBpcyBhIGNsaWVudCwgdGhlbiB0aGUgaGludCB3aWxsIGJlCiAqICAgdGhlIENlcnRpZmljYXRlUmVxdWVzdCBtZXNzYWdlIGZyb20gdGhlIHNlcnZlciB0aGF0IGlzIHBhcnQgb2YgdGhlCiAqICAgVExTIHByb3RvY29sLiBJZiB0aGUgY29ubmVjdGlvbiBlbnRpdHkgaXMgYSBzZXJ2ZXIsIHRoZW4gaXQgd2lsbCBiZQogKiAgIHRoZSBzZXJ2ZXJuYW1lIGxpc3QgcHJvdmlkZWQgdmlhIGFuIFNOSSBleHRlbnNpb24gdGhlIENsaWVudEhlbGxvLCBpZgogKiAgIG9uZSB3YXMgcHJvdmlkZWQgKGVtcHR5IGFycmF5IGlmIG5vdCkuIFRoZSBoaW50IGNhbiBiZSBleGFtaW5lZCB0bwogKiAgIGRldGVybWluZSB3aGljaCBjZXJ0aWZpY2F0ZSB0byB1c2UgKGFkdmFuY2VkKS4gTW9zdCBpbXBsZW1lbnRhdGlvbnMKICogICB3aWxsIGp1c3QgcmV0dXJuIGEgY2VydGlmaWNhdGUuIFRoZSByZXR1cm4gdmFsdWUgbXVzdCBiZSBhCiAqICAgUEVNLWZvcm1hdHRlZCBjZXJ0aWZpY2F0ZSBvciBhbiBhcnJheSBvZiBQRU0tZm9ybWF0dGVkIGNlcnRpZmljYXRlcwogKiAgIHRoYXQgY29uc3RpdHV0ZSBhIGNlcnRpZmljYXRlIGNoYWluLCB3aXRoIHRoZSBmaXJzdCBpbiB0aGUgYXJyYXkvY2hhaW4KICogICBiZWluZyB0aGUgY2xpZW50J3MgY2VydGlmaWNhdGUuCiAqIGdldFByaXZhdGVLZXkoY29ubiwgY2VydGlmaWNhdGUpCiAqICAgVGhlIHNlY29uZCBwYXJhbWV0ZXIgaXMgYW4gZm9yZ2UucGtpIFguNTA5IGNlcnRpZmljYXRlIG9iamVjdCB0aGF0CiAqICAgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSByZXF1ZXN0ZWQgcHJpdmF0ZSBrZXkuIFRoZSByZXR1cm4gdmFsdWUgbXVzdAogKiAgIGJlIGEgUEVNLWZvcm1hdHRlZCBwcml2YXRlIGtleS4KICogZ2V0U2lnbmF0dXJlKGNvbm4sIGJ5dGVzLCBjYWxsYmFjaykKICogICBUaGlzIGNhbGxiYWNrIGNhbiBiZSB1c2VkIGluc3RlYWQgb2YgZ2V0UHJpdmF0ZUtleSBpZiB0aGUgcHJpdmF0ZSBrZXkKICogICBpcyBub3QgZGlyZWN0bHkgYWNjZXNzaWJsZSBpbiBqYXZhc2NyaXB0IG9yIHNob3VsZCBub3QgYmUuIEZvcgogKiAgIGluc3RhbmNlLCBhIHNlY3VyZSBleHRlcm5hbCB3ZWIgc2VydmljZSBjb3VsZCBwcm92aWRlIHRoZSBzaWduYXR1cmUKICogICBpbiBleGNoYW5nZSBmb3IgYXBwcm9wcmlhdGUgY3JlZGVudGlhbHMuIFRoZSBzZWNvbmQgcGFyYW1ldGVyIGlzIGEKICogICBzdHJpbmcgb2YgYnl0ZXMgdG8gYmUgc2lnbmVkIHRoYXQgYXJlIHBhcnQgb2YgdGhlIFRMUyBwcm90b2NvbC4gVGhlc2UKICogICBieXRlcyBhcmUgdXNlZCB0byB2ZXJpZnkgdGhhdCB0aGUgcHJpdmF0ZSBrZXkgZm9yIHRoZSBwcmV2aW91c2x5CiAqICAgcHJvdmlkZWQgY2xpZW50LXNpZGUgY2VydGlmaWNhdGUgaXMgYWNjZXNzaWJsZSB0byB0aGUgY2xpZW50LiBUaGUKICogICBjYWxsYmFjayBpcyBhIGZ1bmN0aW9uIHRoYXQgdGFrZXMgMiBwYXJhbWV0ZXJzLCB0aGUgVExTIGNvbm5lY3Rpb24KICogICBhbmQgdGhlIFJTQSBlbmNyeXB0ZWQgKHNpZ25lZCkgYnl0ZXMgYXMgYSBzdHJpbmcuIFRoaXMgY2FsbGJhY2sgbXVzdAogKiAgIGJlIGNhbGxlZCBvbmNlIHRoZSBzaWduYXR1cmUgaXMgcmVhZHkuCiAqCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIGZvciB0aGlzIGNvbm5lY3Rpb246CiAqICAgc2VydmVyOiB0cnVlIGlmIHRoZSBjb25uZWN0aW9uIGlzIHNlcnZlci1zaWRlLCBmYWxzZSBmb3IgY2xpZW50LgogKiAgIHNlc3Npb25JZDogYSBzZXNzaW9uIElEIHRvIHJldXNlLCBudWxsIGZvciBhIG5ldyBjb25uZWN0aW9uLgogKiAgIGNhU3RvcmU6IGFuIGFycmF5IG9mIGNlcnRpZmljYXRlcyB0byB0cnVzdC4KICogICBzZXNzaW9uQ2FjaGU6IGEgc2Vzc2lvbiBjYWNoZSB0byB1c2UuCiAqICAgY2lwaGVyU3VpdGVzOiBhbiBvcHRpb25hbCBhcnJheSBvZiBjaXBoZXIgc3VpdGVzIHRvIHVzZSwKICogICAgIHNlZSB0bHMuQ2lwaGVyU3VpdGVzLgogKiAgIGNvbm5lY3RlZDogZnVuY3Rpb24oY29ubikgY2FsbGVkIHdoZW4gdGhlIGZpcnN0IGhhbmRzaGFrZSBjb21wbGV0ZXMuCiAqICAgdmlydHVhbEhvc3Q6IHRoZSB2aXJ0dWFsIHNlcnZlciBuYW1lIHRvIHVzZSBpbiBhIFRMUyBTTkkgZXh0ZW5zaW9uLgogKiAgIHZlcmlmeUNsaWVudDogdHJ1ZSB0byByZXF1aXJlIGEgY2xpZW50IGNlcnRpZmljYXRlIGluIHNlcnZlciBtb2RlLAogKiAgICAgJ29wdGlvbmFsJyB0byByZXF1ZXN0IG9uZSwgZmFsc2Ugbm90IHRvIChkZWZhdWx0OiBmYWxzZSkuCiAqICAgdmVyaWZ5OiBhIGhhbmRsZXIgdXNlZCB0byBjdXN0b20gdmVyaWZ5IGNlcnRpZmljYXRlcyBpbiB0aGUgY2hhaW4uCiAqICAgZ2V0Q2VydGlmaWNhdGU6IGFuIG9wdGlvbmFsIGNhbGxiYWNrIHVzZWQgdG8gZ2V0IGEgY2VydGlmaWNhdGUgb3IKICogICAgIGEgY2hhaW4gb2YgY2VydGlmaWNhdGVzIChhcyBhbiBhcnJheSkuCiAqICAgZ2V0UHJpdmF0ZUtleTogYW4gb3B0aW9uYWwgY2FsbGJhY2sgdXNlZCB0byBnZXQgYSBwcml2YXRlIGtleS4KICogICBnZXRTaWduYXR1cmU6IGFuIG9wdGlvbmFsIGNhbGxiYWNrIHVzZWQgdG8gZ2V0IGEgc2lnbmF0dXJlLgogKiAgIHRsc0RhdGFSZWFkeTogZnVuY3Rpb24oY29ubikgY2FsbGVkIHdoZW4gVExTIHByb3RvY29sIGRhdGEgaGFzIGJlZW4KICogICAgIHByZXBhcmVkIGFuZCBpcyByZWFkeSB0byBiZSB1c2VkICh0eXBpY2FsbHkgc2VudCBvdmVyIGEgc29ja2V0CiAqICAgICBjb25uZWN0aW9uIHRvIGl0cyBkZXN0aW5hdGlvbiksIHJlYWQgZnJvbSBjb25uLnRsc0RhdGEgYnVmZmVyLgogKiAgIGRhdGFSZWFkeTogZnVuY3Rpb24oY29ubikgY2FsbGVkIHdoZW4gYXBwbGljYXRpb24gZGF0YSBoYXMKICogICAgIGJlZW4gcGFyc2VkIGZyb20gYSBUTFMgcmVjb3JkIGFuZCBzaG91bGQgYmUgY29uc3VtZWQgYnkgdGhlCiAqICAgICBhcHBsaWNhdGlvbiwgcmVhZCBmcm9tIGNvbm4uZGF0YSBidWZmZXIuCiAqICAgY2xvc2VkOiBmdW5jdGlvbihjb25uKSBjYWxsZWQgd2hlbiB0aGUgY29ubmVjdGlvbiBoYXMgYmVlbiBjbG9zZWQuCiAqICAgZXJyb3I6IGZ1bmN0aW9uKGNvbm4sIGVycm9yKSBjYWxsZWQgd2hlbiB0aGVyZSB3YXMgYW4gZXJyb3IuCiAqICAgZGVmbGF0ZTogZnVuY3Rpb24oaW5CeXRlcykgaWYgcHJvdmlkZWQsIHdpbGwgZGVmbGF0ZSBUTFMgcmVjb3JkcyB1c2luZwogKiAgICAgdGhlIGRlZmxhdGUgYWxnb3JpdGhtIGlmIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgaXQuCiAqICAgaW5mbGF0ZTogZnVuY3Rpb24oaW5CeXRlcykgaWYgcHJvdmlkZWQsIHdpbGwgaW5mbGF0ZSBUTFMgcmVjb3JkcyB1c2luZwogKiAgICAgdGhlIGRlZmxhdGUgYWxnb3JpdGhtIGlmIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgaXQuCiAqCiAqIEByZXR1cm4gdGhlIG5ldyBUTFMgY29ubmVjdGlvbi4KICovCmZvcmdlLnRscy5jcmVhdGVDb25uZWN0aW9uID0gdGxzLmNyZWF0ZUNvbm5lY3Rpb247Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICd0bHMnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvdGxzJyxbCiAgJ3JlcXVpcmUnLAogICdtb2R1bGUnLAogICcuL2FzbjEnLAogICcuL2htYWMnLAogICcuL21kJywKICAnLi9wZW0nLAogICcuL3BraScsCiAgJy4vcmFuZG9tJywKICAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIEEgSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBBRVMgQ2lwaGVyIFN1aXRlcyBmb3IgVExTLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDktMjAxNSBEaWdpdGFsIEJhemFhciwgSW5jLgogKgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCnZhciB0bHMgPSBmb3JnZS50bHM7CgovKioKICogU3VwcG9ydGVkIGNpcGhlciBzdWl0ZXMuCiAqLwp0bHMuQ2lwaGVyU3VpdGVzWydUTFNfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBJ10gPSB7CiAgaWQ6IFsweDAwLDB4MmZdLAogIG5hbWU6ICdUTFNfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBJywKICBpbml0U2VjdXJpdHlQYXJhbWV0ZXJzOiBmdW5jdGlvbihzcCkgewogICAgc3AuYnVsa19jaXBoZXJfYWxnb3JpdGhtID0gdGxzLkJ1bGtDaXBoZXJBbGdvcml0aG0uYWVzOwogICAgc3AuY2lwaGVyX3R5cGUgPSB0bHMuQ2lwaGVyVHlwZS5ibG9jazsKICAgIHNwLmVuY19rZXlfbGVuZ3RoID0gMTY7CiAgICBzcC5ibG9ja19sZW5ndGggPSAxNjsKICAgIHNwLmZpeGVkX2l2X2xlbmd0aCA9IDE2OwogICAgc3AucmVjb3JkX2l2X2xlbmd0aCA9IDE2OwogICAgc3AubWFjX2FsZ29yaXRobSA9IHRscy5NQUNBbGdvcml0aG0uaG1hY19zaGExOwogICAgc3AubWFjX2xlbmd0aCA9IDIwOwogICAgc3AubWFjX2tleV9sZW5ndGggPSAyMDsKICB9LAogIGluaXRDb25uZWN0aW9uU3RhdGU6IGluaXRDb25uZWN0aW9uU3RhdGUKfTsKdGxzLkNpcGhlclN1aXRlc1snVExTX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSddID0gewogIGlkOiBbMHgwMCwweDM1XSwKICBuYW1lOiAnVExTX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQScsCiAgaW5pdFNlY3VyaXR5UGFyYW1ldGVyczogZnVuY3Rpb24oc3ApIHsKICAgIHNwLmJ1bGtfY2lwaGVyX2FsZ29yaXRobSA9IHRscy5CdWxrQ2lwaGVyQWxnb3JpdGhtLmFlczsKICAgIHNwLmNpcGhlcl90eXBlID0gdGxzLkNpcGhlclR5cGUuYmxvY2s7CiAgICBzcC5lbmNfa2V5X2xlbmd0aCA9IDMyOwogICAgc3AuYmxvY2tfbGVuZ3RoID0gMTY7CiAgICBzcC5maXhlZF9pdl9sZW5ndGggPSAxNjsKICAgIHNwLnJlY29yZF9pdl9sZW5ndGggPSAxNjsKICAgIHNwLm1hY19hbGdvcml0aG0gPSB0bHMuTUFDQWxnb3JpdGhtLmhtYWNfc2hhMTsKICAgIHNwLm1hY19sZW5ndGggPSAyMDsKICAgIHNwLm1hY19rZXlfbGVuZ3RoID0gMjA7CiAgfSwKICBpbml0Q29ubmVjdGlvblN0YXRlOiBpbml0Q29ubmVjdGlvblN0YXRlCn07CgpmdW5jdGlvbiBpbml0Q29ubmVjdGlvblN0YXRlKHN0YXRlLCBjLCBzcCkgewogIHZhciBjbGllbnQgPSAoYy5lbnRpdHkgPT09IGZvcmdlLnRscy5Db25uZWN0aW9uRW5kLmNsaWVudCk7CgogIC8vIGNpcGhlciBzZXR1cAogIHN0YXRlLnJlYWQuY2lwaGVyU3RhdGUgPSB7CiAgICBpbml0OiBmYWxzZSwKICAgIGNpcGhlcjogZm9yZ2UuY2lwaGVyLmNyZWF0ZURlY2lwaGVyKCdBRVMtQ0JDJywgY2xpZW50ID8KICAgICAgc3Aua2V5cy5zZXJ2ZXJfd3JpdGVfa2V5IDogc3Aua2V5cy5jbGllbnRfd3JpdGVfa2V5KSwKICAgIGl2OiBjbGllbnQgPyBzcC5rZXlzLnNlcnZlcl93cml0ZV9JViA6IHNwLmtleXMuY2xpZW50X3dyaXRlX0lWCiAgfTsKICBzdGF0ZS53cml0ZS5jaXBoZXJTdGF0ZSA9IHsKICAgIGluaXQ6IGZhbHNlLAogICAgY2lwaGVyOiBmb3JnZS5jaXBoZXIuY3JlYXRlQ2lwaGVyKCdBRVMtQ0JDJywgY2xpZW50ID8KICAgICAgc3Aua2V5cy5jbGllbnRfd3JpdGVfa2V5IDogc3Aua2V5cy5zZXJ2ZXJfd3JpdGVfa2V5KSwKICAgIGl2OiBjbGllbnQgPyBzcC5rZXlzLmNsaWVudF93cml0ZV9JViA6IHNwLmtleXMuc2VydmVyX3dyaXRlX0lWCiAgfTsKICBzdGF0ZS5yZWFkLmNpcGhlckZ1bmN0aW9uID0gZGVjcnlwdF9hZXNfY2JjX3NoYTE7CiAgc3RhdGUud3JpdGUuY2lwaGVyRnVuY3Rpb24gPSBlbmNyeXB0X2Flc19jYmNfc2hhMTsKCiAgLy8gTUFDIHNldHVwCiAgc3RhdGUucmVhZC5tYWNMZW5ndGggPSBzdGF0ZS53cml0ZS5tYWNMZW5ndGggPSBzcC5tYWNfbGVuZ3RoOwogIHN0YXRlLnJlYWQubWFjRnVuY3Rpb24gPSBzdGF0ZS53cml0ZS5tYWNGdW5jdGlvbiA9IHRscy5obWFjX3NoYTE7Cn0KCi8qKgogKiBFbmNyeXB0cyB0aGUgVExTQ29tcHJlc3NlZCByZWNvcmQgaW50byBhIFRMU0NpcGhlclRleHQgcmVjb3JkIHVzaW5nIEFFUwogKiBpbiBDQkMgbW9kZS4KICoKICogQHBhcmFtIHJlY29yZCB0aGUgVExTQ29tcHJlc3NlZCByZWNvcmQgdG8gZW5jcnlwdC4KICogQHBhcmFtIHMgdGhlIENvbm5lY3Rpb25TdGF0ZSB0byB1c2UuCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KZnVuY3Rpb24gZW5jcnlwdF9hZXNfY2JjX3NoYTEocmVjb3JkLCBzKSB7CiAgdmFyIHJ2YWwgPSBmYWxzZTsKCiAgLy8gYXBwZW5kIE1BQyB0byBmcmFnbWVudCwgdXBkYXRlIHNlcXVlbmNlIG51bWJlcgogIHZhciBtYWMgPSBzLm1hY0Z1bmN0aW9uKHMubWFjS2V5LCBzLnNlcXVlbmNlTnVtYmVyLCByZWNvcmQpOwogIHJlY29yZC5mcmFnbWVudC5wdXRCeXRlcyhtYWMpOwogIHMudXBkYXRlU2VxdWVuY2VOdW1iZXIoKTsKCiAgLy8gVExTIDEuMSsgdXNlIGFuIGV4cGxpY2l0IElWIGV2ZXJ5IHRpbWUgdG8gcHJvdGVjdCBhZ2FpbnN0IENCQyBhdHRhY2tzCiAgdmFyIGl2OwogIGlmKHJlY29yZC52ZXJzaW9uLm1pbm9yID09PSB0bHMuVmVyc2lvbnMuVExTXzFfMC5taW5vcikgewogICAgLy8gdXNlIHRoZSBwcmUtZ2VuZXJhdGVkIElWIHdoZW4gaW5pdGlhbGl6aW5nIGZvciBUTFMgMS4wLCBvdGhlcndpc2UgdXNlCiAgICAvLyB0aGUgcmVzaWR1ZSBmcm9tIHRoZSBwcmV2aW91cyBlbmNyeXB0aW9uCiAgICBpdiA9IHMuY2lwaGVyU3RhdGUuaW5pdCA/IG51bGwgOiBzLmNpcGhlclN0YXRlLml2OwogIH0gZWxzZSB7CiAgICBpdiA9IGZvcmdlLnJhbmRvbS5nZXRCeXRlc1N5bmMoMTYpOwogIH0KCiAgcy5jaXBoZXJTdGF0ZS5pbml0ID0gdHJ1ZTsKCiAgLy8gc3RhcnQgY2lwaGVyCiAgdmFyIGNpcGhlciA9IHMuY2lwaGVyU3RhdGUuY2lwaGVyOwogIGNpcGhlci5zdGFydCh7aXY6IGl2fSk7CgogIC8vIFRMUyAxLjErIHdyaXRlIElWIGludG8gb3V0cHV0CiAgaWYocmVjb3JkLnZlcnNpb24ubWlub3IgPj0gdGxzLlZlcnNpb25zLlRMU18xXzEubWlub3IpIHsKICAgIGNpcGhlci5vdXRwdXQucHV0Qnl0ZXMoaXYpOwogIH0KCiAgLy8gZG8gZW5jcnlwdGlvbiAoZGVmYXVsdCBwYWRkaW5nIGlzIGFwcHJvcHJpYXRlKQogIGNpcGhlci51cGRhdGUocmVjb3JkLmZyYWdtZW50KTsKICBpZihjaXBoZXIuZmluaXNoKGVuY3J5cHRfYWVzX2NiY19zaGExX3BhZGRpbmcpKSB7CiAgICAvLyBzZXQgcmVjb3JkIGZyYWdtZW50IHRvIGVuY3J5cHRlZCBvdXRwdXQKICAgIHJlY29yZC5mcmFnbWVudCA9IGNpcGhlci5vdXRwdXQ7CiAgICByZWNvcmQubGVuZ3RoID0gcmVjb3JkLmZyYWdtZW50Lmxlbmd0aCgpOwogICAgcnZhbCA9IHRydWU7CiAgfQoKICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIEhhbmRsZXMgcGFkZGluZyBmb3IgYWVzX2NiY19zaGExIGluIGVuY3J5cHQgbW9kZS4KICoKICogQHBhcmFtIGJsb2NrU2l6ZSB0aGUgYmxvY2sgc2l6ZS4KICogQHBhcmFtIGlucHV0IHRoZSBpbnB1dCBidWZmZXIuCiAqIEBwYXJhbSBkZWNyeXB0IHRydWUgaW4gZGVjcnlwdCBtb2RlLCBmYWxzZSBpbiBlbmNyeXB0IG1vZGUuCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KZnVuY3Rpb24gZW5jcnlwdF9hZXNfY2JjX3NoYTFfcGFkZGluZyhibG9ja1NpemUsIGlucHV0LCBkZWNyeXB0KSB7CiAgLyogVGhlIGVuY3J5cHRlZCBkYXRhIGxlbmd0aCAoVExTQ2lwaGVydGV4dC5sZW5ndGgpIGlzIG9uZSBtb3JlIHRoYW4gdGhlIHN1bQogICBvZiBTZWN1cml0eVBhcmFtZXRlcnMuYmxvY2tfbGVuZ3RoLCBUTFNDb21wcmVzc2VkLmxlbmd0aCwKICAgU2VjdXJpdHlQYXJhbWV0ZXJzLm1hY19sZW5ndGgsIGFuZCBwYWRkaW5nX2xlbmd0aC4KCiAgIFRoZSBwYWRkaW5nIG1heSBiZSBhbnkgbGVuZ3RoIHVwIHRvIDI1NSBieXRlcyBsb25nLCBhcyBsb25nIGFzIGl0IHJlc3VsdHMgaW4KICAgdGhlIFRMU0NpcGhlcnRleHQubGVuZ3RoIGJlaW5nIGFuIGludGVncmFsIG11bHRpcGxlIG9mIHRoZSBibG9jayBsZW5ndGguCiAgIExlbmd0aHMgbG9uZ2VyIHRoYW4gbmVjZXNzYXJ5IG1pZ2h0IGJlIGRlc2lyYWJsZSB0byBmcnVzdHJhdGUgYXR0YWNrcyBvbiBhCiAgIHByb3RvY29sIGJhc2VkIG9uIGFuYWx5c2lzIG9mIHRoZSBsZW5ndGhzIG9mIGV4Y2hhbmdlZCBtZXNzYWdlcy4gRWFjaCB1aW50OAogICBpbiB0aGUgcGFkZGluZyBkYXRhIHZlY3RvciBtdXN0IGJlIGZpbGxlZCB3aXRoIHRoZSBwYWRkaW5nIGxlbmd0aCB2YWx1ZS4KCiAgIFRoZSBwYWRkaW5nIGxlbmd0aCBzaG91bGQgYmUgc3VjaCB0aGF0IHRoZSB0b3RhbCBzaXplIG9mIHRoZQogICBHZW5lcmljQmxvY2tDaXBoZXIgc3RydWN0dXJlIGlzIGEgbXVsdGlwbGUgb2YgdGhlIGNpcGhlcidzIGJsb2NrIGxlbmd0aC4KICAgTGVnYWwgdmFsdWVzIHJhbmdlIGZyb20gemVybyB0byAyNTUsIGluY2x1c2l2ZS4gVGhpcyBsZW5ndGggc3BlY2lmaWVzIHRoZQogICBsZW5ndGggb2YgdGhlIHBhZGRpbmcgZmllbGQgZXhjbHVzaXZlIG9mIHRoZSBwYWRkaW5nX2xlbmd0aCBmaWVsZCBpdHNlbGYuCgogICBUaGlzIGlzIHNsaWdodGx5IGRpZmZlcmVudCBmcm9tIFBLQ1MjNyBiZWNhdXNlIHRoZSBwYWRkaW5nIHZhbHVlIGlzIDEKICAgbGVzcyB0aGFuIHRoZSBhY3R1YWwgbnVtYmVyIG9mIHBhZGRpbmcgYnl0ZXMgaWYgeW91IGluY2x1ZGUgdGhlCiAgIHBhZGRpbmdfbGVuZ3RoIHVpbnQ4IGl0c2VsZiBhcyBhIHBhZGRpbmcgYnl0ZS4gKi8KICBpZighZGVjcnlwdCkgewogICAgLy8gZ2V0IHRoZSBudW1iZXIgb2YgcGFkZGluZyBieXRlcyByZXF1aXJlZCB0byByZWFjaCB0aGUgYmxvY2tTaXplIGFuZAogICAgLy8gc3VidHJhY3QgMSBmb3IgdGhlIHBhZGRpbmcgdmFsdWUgKHRvIG1ha2Ugcm9vbSBmb3IgdGhlIHBhZGRpbmdfbGVuZ3RoCiAgICAvLyB1aW50OCkKICAgIHZhciBwYWRkaW5nID0gYmxvY2tTaXplIC0gKGlucHV0Lmxlbmd0aCgpICUgYmxvY2tTaXplKTsKICAgIGlucHV0LmZpbGxXaXRoQnl0ZShwYWRkaW5nIC0gMSwgcGFkZGluZyk7CiAgfQogIHJldHVybiB0cnVlOwp9CgovKioKICogSGFuZGxlcyBwYWRkaW5nIGZvciBhZXNfY2JjX3NoYTEgaW4gZGVjcnlwdCBtb2RlLgogKgogKiBAcGFyYW0gYmxvY2tTaXplIHRoZSBibG9jayBzaXplLgogKiBAcGFyYW0gb3V0cHV0IHRoZSBvdXRwdXQgYnVmZmVyLgogKiBAcGFyYW0gZGVjcnlwdCB0cnVlIGluIGRlY3J5cHQgbW9kZSwgZmFsc2UgaW4gZW5jcnlwdCBtb2RlLgogKgogKiBAcmV0dXJuIHRydWUgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZS4KICovCmZ1bmN0aW9uIGRlY3J5cHRfYWVzX2NiY19zaGExX3BhZGRpbmcoYmxvY2tTaXplLCBvdXRwdXQsIGRlY3J5cHQpIHsKICB2YXIgcnZhbCA9IHRydWU7CiAgaWYoZGVjcnlwdCkgewogICAgLyogVGhlIGxhc3QgYnl0ZSBpbiB0aGUgb3V0cHV0IHNwZWNpZmllcyB0aGUgbnVtYmVyIG9mIHBhZGRpbmcgYnl0ZXMgbm90CiAgICAgIGluY2x1ZGluZyBpdHNlbGYuIEVhY2ggb2YgdGhlIHBhZGRpbmcgYnl0ZXMgaGFzIHRoZSBzYW1lIHZhbHVlIGFzIHRoYXQKICAgICAgbGFzdCBieXRlIChrbm93biBhcyB0aGUgcGFkZGluZ19sZW5ndGgpLiBIZXJlIHdlIGNoZWNrIGFsbCBwYWRkaW5nCiAgICAgIGJ5dGVzIHRvIGVuc3VyZSB0aGV5IGhhdmUgdGhlIHZhbHVlIG9mIHBhZGRpbmdfbGVuZ3RoIGV2ZW4gaWYgb25lIG9mCiAgICAgIHRoZW0gaXMgYmFkIGluIG9yZGVyIHRvIHdhcmQtb2ZmIHRpbWluZyBhdHRhY2tzLiAqLwogICAgdmFyIGxlbiA9IG91dHB1dC5sZW5ndGgoKTsKICAgIHZhciBwYWRkaW5nTGVuZ3RoID0gb3V0cHV0Lmxhc3QoKTsKICAgIGZvcih2YXIgaSA9IGxlbiAtIDEgLSBwYWRkaW5nTGVuZ3RoOyBpIDwgbGVuIC0gMTsgKytpKSB7CiAgICAgIHJ2YWwgPSBydmFsICYmIChvdXRwdXQuYXQoaSkgPT0gcGFkZGluZ0xlbmd0aCk7CiAgICB9CiAgICBpZihydmFsKSB7CiAgICAgIC8vIHRyaW0gb2ZmIHBhZGRpbmcgYnl0ZXMgYW5kIGxhc3QgcGFkZGluZyBsZW5ndGggYnl0ZQogICAgICBvdXRwdXQudHJ1bmNhdGUocGFkZGluZ0xlbmd0aCArIDEpOwogICAgfQogIH0KICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIERlY3J5cHRzIGEgVExTQ2lwaGVyVGV4dCByZWNvcmQgaW50byBhIFRMU0NvbXByZXNzZWQgcmVjb3JkIHVzaW5nCiAqIEFFUyBpbiBDQkMgbW9kZS4KICoKICogQHBhcmFtIHJlY29yZCB0aGUgVExTQ2lwaGVyVGV4dCByZWNvcmQgdG8gZGVjcnlwdC4KICogQHBhcmFtIHMgdGhlIENvbm5lY3Rpb25TdGF0ZSB0byB1c2UuCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KdmFyIGNvdW50ID0gMDsKZnVuY3Rpb24gZGVjcnlwdF9hZXNfY2JjX3NoYTEocmVjb3JkLCBzKSB7CiAgdmFyIHJ2YWwgPSBmYWxzZTsKICArK2NvdW50OwoKICB2YXIgaXY7CiAgaWYocmVjb3JkLnZlcnNpb24ubWlub3IgPT09IHRscy5WZXJzaW9ucy5UTFNfMV8wLm1pbm9yKSB7CiAgICAvLyB1c2UgcHJlLWdlbmVyYXRlZCBJViB3aGVuIGluaXRpYWxpemluZyBmb3IgVExTIDEuMCwgb3RoZXJ3aXNlIHVzZSB0aGUKICAgIC8vIHJlc2lkdWUgZnJvbSB0aGUgcHJldmlvdXMgZGVjcnlwdGlvbgogICAgaXYgPSBzLmNpcGhlclN0YXRlLmluaXQgPyBudWxsIDogcy5jaXBoZXJTdGF0ZS5pdjsKICB9IGVsc2UgewogICAgLy8gVExTIDEuMSsgdXNlIGFuIGV4cGxpY2l0IElWIGV2ZXJ5IHRpbWUgdG8gcHJvdGVjdCBhZ2FpbnN0IENCQyBhdHRhY2tzCiAgICAvLyB0aGF0IGlzIGFwcGVuZGVkIHRvIHRoZSByZWNvcmQgZnJhZ21lbnQKICAgIGl2ID0gcmVjb3JkLmZyYWdtZW50LmdldEJ5dGVzKDE2KTsKICB9CgogIHMuY2lwaGVyU3RhdGUuaW5pdCA9IHRydWU7CgogIC8vIHN0YXJ0IGNpcGhlcgogIHZhciBjaXBoZXIgPSBzLmNpcGhlclN0YXRlLmNpcGhlcjsKICBjaXBoZXIuc3RhcnQoe2l2OiBpdn0pOwoKICAvLyBkbyBkZWNyeXB0aW9uCiAgY2lwaGVyLnVwZGF0ZShyZWNvcmQuZnJhZ21lbnQpOwogIHJ2YWwgPSBjaXBoZXIuZmluaXNoKGRlY3J5cHRfYWVzX2NiY19zaGExX3BhZGRpbmcpOwoKICAvLyBldmVuIGlmIGRlY3J5cHRpb24gZmFpbHMsIGtlZXAgZ29pbmcgdG8gbWluaW1pemUgdGltaW5nIGF0dGFja3MKCiAgLy8gZGVjcnlwdGVkIGRhdGE6CiAgLy8gZmlyc3QgKGxlbiAtIDIwKSBieXRlcyA9IGFwcGxpY2F0aW9uIGRhdGEKICAvLyBsYXN0IDIwIGJ5dGVzICAgICAgICAgID0gTUFDCiAgdmFyIG1hY0xlbiA9IHMubWFjTGVuZ3RoOwoKICAvLyBjcmVhdGUgYSByYW5kb20gTUFDIHRvIGNoZWNrIGFnYWluc3Qgc2hvdWxkIHRoZSBtYWMgbGVuZ3RoIGNoZWNrIGZhaWwKICAvLyBOb3RlOiBkbyB0aGlzIHJlZ2FyZGxlc3Mgb2YgdGhlIGZhaWx1cmUgdG8ga2VlcCB0aW1pbmcgY29uc2lzdGVudAogIHZhciBtYWMgPSBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXNTeW5jKG1hY0xlbik7CgogIC8vIGdldCBmcmFnbWVudCBhbmQgbWFjCiAgdmFyIGxlbiA9IGNpcGhlci5vdXRwdXQubGVuZ3RoKCk7CiAgaWYobGVuID49IG1hY0xlbikgewogICAgcmVjb3JkLmZyYWdtZW50ID0gY2lwaGVyLm91dHB1dC5nZXRCeXRlcyhsZW4gLSBtYWNMZW4pOwogICAgbWFjID0gY2lwaGVyLm91dHB1dC5nZXRCeXRlcyhtYWNMZW4pOwogIH0gZWxzZSB7CiAgICAvLyBiYWQgZGF0YSwgYnV0IGdldCBieXRlcyBhbnl3YXkgdG8gdHJ5IHRvIGtlZXAgdGltaW5nIGNvbnNpc3RlbnQKICAgIHJlY29yZC5mcmFnbWVudCA9IGNpcGhlci5vdXRwdXQuZ2V0Qnl0ZXMoKTsKICB9CiAgcmVjb3JkLmZyYWdtZW50ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIocmVjb3JkLmZyYWdtZW50KTsKICByZWNvcmQubGVuZ3RoID0gcmVjb3JkLmZyYWdtZW50Lmxlbmd0aCgpOwoKICAvLyBzZWUgaWYgZGF0YSBpbnRlZ3JpdHkgY2hlY2tzIG91dCwgdXBkYXRlIHNlcXVlbmNlIG51bWJlcgogIHZhciBtYWMyID0gcy5tYWNGdW5jdGlvbihzLm1hY0tleSwgcy5zZXF1ZW5jZU51bWJlciwgcmVjb3JkKTsKICBzLnVwZGF0ZVNlcXVlbmNlTnVtYmVyKCk7CiAgcnZhbCA9IGNvbXBhcmVNYWNzKHMubWFjS2V5LCBtYWMsIG1hYzIpICYmIHJ2YWw7CiAgcmV0dXJuIHJ2YWw7Cn0KCi8qKgogKiBTYWZlbHkgY29tcGFyZSB0d28gTUFDcy4gVGhpcyBmdW5jdGlvbiB3aWxsIGNvbXBhcmUgdHdvIE1BQ3MgaW4gYSB3YXkKICogdGhhdCBwcm90ZWN0cyBhZ2FpbnN0IHRpbWluZyBhdHRhY2tzLgogKgogKiBUT0RPOiBFeHBvc2UgZWxzZXdoZXJlIGFzIGEgdXRpbGl0eSBBUEkuCiAqCiAqIFNlZTogaHR0cHM6Ly93d3cubmNjZ3JvdXAudHJ1c3QvdXMvYWJvdXQtdXMvbmV3c3Jvb20tYW5kLWV2ZW50cy9ibG9nLzIwMTEvZmVicnVhcnkvZG91YmxlLWhtYWMtdmVyaWZpY2F0aW9uLwogKgogKiBAcGFyYW0ga2V5IHRoZSBNQUMga2V5IHRvIHVzZS4KICogQHBhcmFtIG1hYzEgYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMuCiAqIEBwYXJhbSBtYWMyIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzLgogKgogKiBAcmV0dXJuIHRydWUgaWYgdGhlIE1BQ3MgYXJlIHRoZSBzYW1lLCBmYWxzZSBpZiBub3QuCiAqLwpmdW5jdGlvbiBjb21wYXJlTWFjcyhrZXksIG1hYzEsIG1hYzIpIHsKICB2YXIgaG1hYyA9IGZvcmdlLmhtYWMuY3JlYXRlKCk7CgogIGhtYWMuc3RhcnQoJ1NIQTEnLCBrZXkpOwogIGhtYWMudXBkYXRlKG1hYzEpOwogIG1hYzEgPSBobWFjLmRpZ2VzdCgpLmdldEJ5dGVzKCk7CgogIGhtYWMuc3RhcnQobnVsbCwgbnVsbCk7CiAgaG1hYy51cGRhdGUobWFjMik7CiAgbWFjMiA9IGhtYWMuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKCiAgcmV0dXJuIG1hYzEgPT09IG1hYzI7Cn0KCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ2Flc0NpcGhlclN1aXRlcyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9hZXNDaXBoZXJTdWl0ZXMnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9hZXMnLCAnLi90bHMnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogRGVidWdnaW5nIHN1cHBvcnQgZm9yIHdlYiBhcHBsaWNhdGlvbnMuCiAqCiAqIEBhdXRob3IgRGF2aWQgSS4gTGVobiA8ZGxlaG5AZGlnaXRhbGJhemFhci5jb20+CiAqCiAqIENvcHlyaWdodCAyMDA4LTIwMTMgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovKiBERUJVRyBBUEkgKi8KZm9yZ2UuZGVidWcgPSBmb3JnZS5kZWJ1ZyB8fCB7fTsKCi8vIFByaXZhdGUgc3RvcmFnZSBmb3IgZGVidWdnaW5nLgovLyBVc2VmdWwgdG8gZXhwb3NlIGRhdGEgdGhhdCBpcyBvdGhlcndpc2UgdW52aWV3YWJsZSBiZWhpbmQgY2xvc3VyZXMuCi8vIE5PVEU6IHJlbWVtYmVyIHRoYXQgdGhpcyBjYW4gaG9sZCByZWZlcmVuY2VzIHRvIGRhdGEgYW5kIGNhdXNlIGxlYWtzIQovLyBmb3JtYXQgaXMgImZvcmdlLl9kZWJ1Zy48bW9kdWxlbmFtZT4uPGRhdGFuYW1lPiA9IGRhdGEiCi8vIEV4YW1wbGU6Ci8vIChmdW5jdGlvbigpIHsKLy8gICB2YXIgY2F0ID0gJ2ZvcmdlLnRlc3QuVGVzdCc7IC8vIGRlYnVnZ2luZyBjYXRlZ29yeQovLyAgIHZhciBzU3RhdGUgPSB7Li4ufTsgLy8gbG9jYWwgc3RhdGUKLy8gICBmb3JnZS5kZWJ1Zy5zZXQoY2F0LCAnc1N0YXRlJywgc1N0YXRlKTsKLy8gfSkoKTsKZm9yZ2UuZGVidWcuc3RvcmFnZSA9IHt9OwoKLyoqCiAqIEdldHMgZGVidWcgZGF0YS4gT21pdCBuYW1lIGZvciBhbGwgY2F0IGRhdGEgIE9taXQgbmFtZSBhbmQgY2F0IGZvcgogKiBhbGwgZGF0YS4KICoKICogQHBhcmFtIGNhdCBuYW1lIG9mIGRlYnVnZ2luZyBjYXRlZ29yeS4KICogQHBhcmFtIG5hbWUgbmFtZSBvZiBkYXRhIHRvIGdldCAob3B0aW9uYWwpLgogKiBAcmV0dXJuIG9iamVjdCB3aXRoIHJlcXVlc3RlZCBkZWJ1ZyBkYXRhIG9yIHVuZGVmaW5lZC4KICovCmZvcmdlLmRlYnVnLmdldCA9IGZ1bmN0aW9uKGNhdCwgbmFtZSkgewogIHZhciBydmFsOwogIGlmKHR5cGVvZihjYXQpID09PSAndW5kZWZpbmVkJykgewogICAgcnZhbCA9IGZvcmdlLmRlYnVnLnN0b3JhZ2U7CiAgfSBlbHNlIGlmKGNhdCBpbiBmb3JnZS5kZWJ1Zy5zdG9yYWdlKSB7CiAgICBpZih0eXBlb2YobmFtZSkgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIHJ2YWwgPSBmb3JnZS5kZWJ1Zy5zdG9yYWdlW2NhdF07CiAgICB9IGVsc2UgewogICAgICBydmFsID0gZm9yZ2UuZGVidWcuc3RvcmFnZVtjYXRdW25hbWVdOwogICAgfQogIH0KICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBTZXRzIGRlYnVnIGRhdGEuCiAqCiAqIEBwYXJhbSBjYXQgbmFtZSBvZiBkZWJ1Z2dpbmcgY2F0ZWdvcnkuCiAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgZGF0YSB0byBzZXQuCiAqIEBwYXJhbSBkYXRhIGRhdGEgdG8gc2V0LgogKi8KZm9yZ2UuZGVidWcuc2V0ID0gZnVuY3Rpb24oY2F0LCBuYW1lLCBkYXRhKSB7CiAgaWYoIShjYXQgaW4gZm9yZ2UuZGVidWcuc3RvcmFnZSkpIHsKICAgIGZvcmdlLmRlYnVnLnN0b3JhZ2VbY2F0XSA9IHt9OwogIH0KICBmb3JnZS5kZWJ1Zy5zdG9yYWdlW2NhdF1bbmFtZV0gPSBkYXRhOwp9OwoKLyoqCiAqIENsZWFycyBkZWJ1ZyBkYXRhLiBPbWl0IG5hbWUgZm9yIGFsbCBjYXQgZGF0YS4gT21pdCBuYW1lIGFuZCBjYXQgZm9yCiAqIGFsbCBkYXRhLgogKgogKiBAcGFyYW0gY2F0IG5hbWUgb2YgZGVidWdnaW5nIGNhdGVnb3J5LgogKiBAcGFyYW0gbmFtZSBuYW1lIG9mIGRhdGEgdG8gY2xlYXIgb3Igb21pdCB0byBjbGVhciBlbnRpcmUgY2F0ZWdvcnkuCiAqLwpmb3JnZS5kZWJ1Zy5jbGVhciA9IGZ1bmN0aW9uKGNhdCwgbmFtZSkgewogIGlmKHR5cGVvZihjYXQpID09PSAndW5kZWZpbmVkJykgewogICAgZm9yZ2UuZGVidWcuc3RvcmFnZSA9IHt9OwogIH0gZWxzZSBpZihjYXQgaW4gZm9yZ2UuZGVidWcuc3RvcmFnZSkgewogICAgaWYodHlwZW9mKG5hbWUpID09PSAndW5kZWZpbmVkJykgewogICAgICBkZWxldGUgZm9yZ2UuZGVidWcuc3RvcmFnZVtjYXRdOwogICAgfSBlbHNlIHsKICAgICAgZGVsZXRlIGZvcmdlLmRlYnVnLnN0b3JhZ2VbY2F0XVtuYW1lXTsKICAgIH0KICB9Cn07Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdkZWJ1Zyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9kZWJ1ZycsWydyZXF1aXJlJywgJ21vZHVsZSddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIFJTQS1LRU0uCiAqCiAqIEBhdXRob3IgTGF1dGFybyBDb3p6YW5pIFJvZHJpZ3VlegogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQgTGF1dGFybyBDb3p6YW5pIDxsYXV0YXJvLmNvenphbmlAc2N5dGwuY29tPgogKiBDb3B5cmlnaHQgKGMpIDIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7Cgpmb3JnZS5rZW0gPSBmb3JnZS5rZW0gfHwge307Cgp2YXIgQmlnSW50ZWdlciA9IGZvcmdlLmpzYm4uQmlnSW50ZWdlcjsKCi8qKgogKiBUaGUgQVBJIGZvciB0aGUgUlNBIEtleSBFbmNhcHN1bGF0aW9uIE1lY2hhbmlzbSAoUlNBLUtFTSkgZnJvbSBJU08gMTgwMzMtMi4KICovCmZvcmdlLmtlbS5yc2EgPSB7fTsKCi8qKgogKiBDcmVhdGVzIGFuIFJTQSBLRU0gQVBJIG9iamVjdCBmb3IgZ2VuZXJhdGluZyBhIHNlY3JldCBhc3ltbWV0cmljIGtleS4KICoKICogVGhlIHN5bW1ldHJpYyBrZXkgbWF5IGJlIGdlbmVyYXRlZCB2aWEgYSBjYWxsIHRvICdlbmNyeXB0Jywgd2hpY2ggd2lsbAogKiBwcm9kdWNlIGEgY2lwaGVydGV4dCB0byBiZSB0cmFuc21pdHRlZCB0byB0aGUgcmVjaXBpZW50IGFuZCBhIGtleSB0byBiZQogKiBrZXB0IHNlY3JldC4gVGhlIGNpcGhlcnRleHQgaXMgYSBwYXJhbWV0ZXIgdG8gYmUgcGFzc2VkIHRvICdkZWNyeXB0JyB3aGljaAogKiB3aWxsIHByb2R1Y2UgdGhlIHNhbWUgc2VjcmV0IGtleSBmb3IgdGhlIHJlY2lwaWVudCB0byB1c2UgdG8gZGVjcnlwdCBhCiAqIG1lc3NhZ2UgdGhhdCB3YXMgZW5jcnlwdGVkIHdpdGggdGhlIHNlY3JldCBrZXkuCiAqCiAqIEBwYXJhbSBrZGYgdGhlIEtERiBBUEkgdG8gdXNlIChlZzogbmV3IGZvcmdlLmtlbS5rZGYxKCkpLgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2UuCiAqICAgICAgICAgIFtwcm5nXSBhIGN1c3RvbSBjcnlwdG8tc2VjdXJlIHBzZXVkby1yYW5kb20gbnVtYmVyIGdlbmVyYXRvciB0byB1c2UsCiAqICAgICAgICAgICAgdGhhdCBtdXN0IGRlZmluZSAiZ2V0Qnl0ZXNTeW5jIi4KICovCmZvcmdlLmtlbS5yc2EuY3JlYXRlID0gZnVuY3Rpb24oa2RmLCBvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdmFyIHBybmcgPSBvcHRpb25zLnBybmcgfHwgZm9yZ2UucmFuZG9tOwoKICB2YXIga2VtID0ge307CgogIC8qKgogICAqIEdlbmVyYXRlcyBhIHNlY3JldCBrZXkgYW5kIGl0cyBlbmNhcHN1bGF0aW9uLgogICAqCiAgICogQHBhcmFtIHB1YmxpY0tleSB0aGUgUlNBIHB1YmxpYyBrZXkgdG8gZW5jcnlwdCB3aXRoLgogICAqIEBwYXJhbSBrZXlMZW5ndGggdGhlIGxlbmd0aCwgaW4gYnl0ZXMsIG9mIHRoZSBzZWNyZXQga2V5IHRvIGdlbmVyYXRlLgogICAqCiAgICogQHJldHVybiBhbiBvYmplY3Qgd2l0aDoKICAgKiAgIGVuY2Fwc3VsYXRpb246IHRoZSBjaXBoZXJ0ZXh0IGZvciBnZW5lcmF0aW5nIHRoZSBzZWNyZXQga2V5LCBhcyBhCiAgICogICAgIGJpbmFyeS1lbmNvZGVkIHN0cmluZyBvZiBieXRlcy4KICAgKiAgIGtleTogdGhlIHNlY3JldCBrZXkgdG8gdXNlIGZvciBlbmNyeXB0aW5nIGEgbWVzc2FnZS4KICAgKi8KICBrZW0uZW5jcnlwdCA9IGZ1bmN0aW9uKHB1YmxpY0tleSwga2V5TGVuZ3RoKSB7CiAgICAvLyBnZW5lcmF0ZSBhIHJhbmRvbSByIHdoZXJlIDEgPiByID4gbgogICAgdmFyIGJ5dGVMZW5ndGggPSBNYXRoLmNlaWwocHVibGljS2V5Lm4uYml0TGVuZ3RoKCkgLyA4KTsKICAgIHZhciByOwogICAgZG8gewogICAgICByID0gbmV3IEJpZ0ludGVnZXIoCiAgICAgICAgZm9yZ2UudXRpbC5ieXRlc1RvSGV4KHBybmcuZ2V0Qnl0ZXNTeW5jKGJ5dGVMZW5ndGgpKSwKICAgICAgICAxNikubW9kKHB1YmxpY0tleS5uKTsKICAgIH0gd2hpbGUoci5lcXVhbHMoQmlnSW50ZWdlci5aRVJPKSk7CgogICAgLy8gcHJlcGVuZCByIHdpdGggemVyb3MKICAgIHIgPSBmb3JnZS51dGlsLmhleFRvQnl0ZXMoci50b1N0cmluZygxNikpOwogICAgdmFyIHplcm9zID0gYnl0ZUxlbmd0aCAtIHIubGVuZ3RoOwogICAgaWYoemVyb3MgPiAwKSB7CiAgICAgIHIgPSBmb3JnZS51dGlsLmZpbGxTdHJpbmcoU3RyaW5nLmZyb21DaGFyQ29kZSgwKSwgemVyb3MpICsgcjsKICAgIH0KCiAgICAvLyBlbmNyeXB0IHRoZSByYW5kb20KICAgIHZhciBlbmNhcHN1bGF0aW9uID0gcHVibGljS2V5LmVuY3J5cHQociwgJ05PTkUnKTsKCiAgICAvLyBnZW5lcmF0ZSB0aGUgc2VjcmV0IGtleQogICAgdmFyIGtleSA9IGtkZi5nZW5lcmF0ZShyLCBrZXlMZW5ndGgpOwoKICAgIHJldHVybiB7ZW5jYXBzdWxhdGlvbjogZW5jYXBzdWxhdGlvbiwga2V5OiBrZXl9OwogIH07CgogIC8qKgogICAqIERlY3J5cHRzIGFuIGVuY2Fwc3VsYXRlZCBzZWNyZXQga2V5LgogICAqCiAgICogQHBhcmFtIHByaXZhdGVLZXkgdGhlIFJTQSBwcml2YXRlIGtleSB0byBkZWNyeXB0IHdpdGguCiAgICogQHBhcmFtIGVuY2Fwc3VsYXRpb24gdGhlIGNpcGhlcnRleHQgZm9yIGdlbmVyYXRpbmcgdGhlIHNlY3JldCBrZXksIGFzCiAgICogICAgICAgICAgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMuCiAgICogQHBhcmFtIGtleUxlbmd0aCB0aGUgbGVuZ3RoLCBpbiBieXRlcywgb2YgdGhlIHNlY3JldCBrZXkgdG8gZ2VuZXJhdGUuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBzZWNyZXQga2V5IGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzLgogICAqLwogIGtlbS5kZWNyeXB0ID0gZnVuY3Rpb24ocHJpdmF0ZUtleSwgZW5jYXBzdWxhdGlvbiwga2V5TGVuZ3RoKSB7CiAgICAvLyBkZWNyeXB0IHRoZSBlbmNhcHN1bGF0aW9uIGFuZCBnZW5lcmF0ZSB0aGUgc2VjcmV0IGtleQogICAgdmFyIHIgPSBwcml2YXRlS2V5LmRlY3J5cHQoZW5jYXBzdWxhdGlvbiwgJ05PTkUnKTsKICAgIHJldHVybiBrZGYuZ2VuZXJhdGUociwga2V5TGVuZ3RoKTsKICB9OwoKICByZXR1cm4ga2VtOwp9OwoKLy8gVE9ETzogYWRkIGZvcmdlLmtlbS5rZGYuY3JlYXRlKCdLREYxJywge21kOiAuLi4sIC4uLn0pIEFQST8KCi8qKgogKiBDcmVhdGVzIGEga2V5IGRlcml2YXRpb24gQVBJIG9iamVjdCB0aGF0IGltcGxlbWVudHMgS0RGMSBwZXIgSVNPIDE4MDMzLTIuCiAqCiAqIEBwYXJhbSBtZCB0aGUgaGFzaCBBUEkgdG8gdXNlLgogKiBAcGFyYW0gW2RpZ2VzdExlbmd0aF0gYW4gb3B0aW9uYWwgZGlnZXN0IGxlbmd0aCB0aGF0IG11c3QgYmUgcG9zaXRpdmUgYW5kCiAqICAgICAgICAgIGxlc3MgdGhhbiBvciBlcXVhbCB0byBtZC5kaWdlc3RMZW5ndGguCiAqCiAqIEByZXR1cm4gYSBLREYxIEFQSSBvYmplY3QuCiAqLwpmb3JnZS5rZW0ua2RmMSA9IGZ1bmN0aW9uKG1kLCBkaWdlc3RMZW5ndGgpIHsKICBfY3JlYXRlS0RGKHRoaXMsIG1kLCAwLCBkaWdlc3RMZW5ndGggfHwgbWQuZGlnZXN0TGVuZ3RoKTsKfTsKCi8qKgogKiBDcmVhdGVzIGEga2V5IGRlcml2YXRpb24gQVBJIG9iamVjdCB0aGF0IGltcGxlbWVudHMgS0RGMiBwZXIgSVNPIDE4MDMzLTIuCiAqCiAqIEBwYXJhbSBtZCB0aGUgaGFzaCBBUEkgdG8gdXNlLgogKiBAcGFyYW0gW2RpZ2VzdExlbmd0aF0gYW4gb3B0aW9uYWwgZGlnZXN0IGxlbmd0aCB0aGF0IG11c3QgYmUgcG9zaXRpdmUgYW5kCiAqICAgICAgICAgIGxlc3MgdGhhbiBvciBlcXVhbCB0byBtZC5kaWdlc3RMZW5ndGguCiAqCiAqIEByZXR1cm4gYSBLREYyIEFQSSBvYmplY3QuCiAqLwpmb3JnZS5rZW0ua2RmMiA9IGZ1bmN0aW9uKG1kLCBkaWdlc3RMZW5ndGgpIHsKICBfY3JlYXRlS0RGKHRoaXMsIG1kLCAxLCBkaWdlc3RMZW5ndGggfHwgbWQuZGlnZXN0TGVuZ3RoKTsKfTsKCi8qKgogKiBDcmVhdGVzIGEgS0RGMSBvciBLREYyIEFQSSBvYmplY3QuCiAqCiAqIEBwYXJhbSBtZCB0aGUgaGFzaCBBUEkgdG8gdXNlLgogKiBAcGFyYW0gY291bnRlclN0YXJ0IHRoZSBzdGFydGluZyBpbmRleCBmb3IgdGhlIGNvdW50ZXIuCiAqIEBwYXJhbSBkaWdlc3RMZW5ndGggdGhlIGRpZ2VzdCBsZW5ndGggdG8gdXNlLgogKgogKiBAcmV0dXJuIHRoZSBLREYgQVBJIG9iamVjdC4KICovCmZ1bmN0aW9uIF9jcmVhdGVLREYoa2RmLCBtZCwgY291bnRlclN0YXJ0LCBkaWdlc3RMZW5ndGgpIHsKICAvKioKICAgKiBHZW5lcmF0ZSBhIGtleSBvZiB0aGUgc3BlY2lmaWVkIGxlbmd0aC4KICAgKgogICAqIEBwYXJhbSB4IHRoZSBiaW5hcnktZW5jb2RlZCBieXRlIHN0cmluZyB0byBnZW5lcmF0ZSBhIGtleSBmcm9tLgogICAqIEBwYXJhbSBsZW5ndGggdGhlIG51bWJlciBvZiBieXRlcyB0byBnZW5lcmF0ZSAodGhlIHNpemUgb2YgdGhlIGtleSkuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBrZXkgYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcuCiAgICovCiAga2RmLmdlbmVyYXRlID0gZnVuY3Rpb24oeCwgbGVuZ3RoKSB7CiAgICB2YXIga2V5ID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwoKICAgIC8vIHJ1biBjb3VudGVyIGZyb20gY291bnRlclN0YXJ0IHRvIGNlaWwobGVuZ3RoIC8gSGFzaC5sZW4pCiAgICB2YXIgayA9IE1hdGguY2VpbChsZW5ndGggLyBkaWdlc3RMZW5ndGgpICsgY291bnRlclN0YXJ0OwoKICAgIHZhciBjID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwogICAgZm9yKHZhciBpID0gY291bnRlclN0YXJ0OyBpIDwgazsgKytpKSB7CiAgICAgIC8vIEkyT1NQKGksIDQpOiBjb252ZXJ0IGNvdW50ZXIgdG8gYW4gb2N0ZXQgc3RyaW5nIG9mIDQgb2N0ZXRzCiAgICAgIGMucHV0SW50MzIoaSk7CgogICAgICAvLyBkaWdlc3QgJ3gnIGFuZCB0aGUgY291bnRlciBhbmQgYWRkIHRoZSByZXN1bHQgdG8gdGhlIGtleQogICAgICBtZC5zdGFydCgpOwogICAgICBtZC51cGRhdGUoeCArIGMuZ2V0Qnl0ZXMoKSk7CiAgICAgIHZhciBoYXNoID0gbWQuZGlnZXN0KCk7CiAgICAgIGtleS5wdXRCeXRlcyhoYXNoLmdldEJ5dGVzKGRpZ2VzdExlbmd0aCkpOwogICAgfQoKICAgIC8vIHRydW5jYXRlIHRvIHRoZSBjb3JyZWN0IGtleSBsZW5ndGgKICAgIGtleS50cnVuY2F0ZShrZXkubGVuZ3RoKCkgLSBsZW5ndGgpOwogICAgcmV0dXJuIGtleS5nZXRCeXRlcygpOwogIH07Cn0KCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ2tlbSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9rZW0nLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi91dGlsJywnLi9yYW5kb20nLCcuL2pzYm4nXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogQ3Jvc3MtYnJvd3NlciBzdXBwb3J0IGZvciBsb2dnaW5nIGluIGEgd2ViIGFwcGxpY2F0aW9uLgogKgogKiBAYXV0aG9yIERhdmlkIEkuIExlaG4gPGRsZWhuQGRpZ2l0YWxiYXphYXIuY29tPgogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDgtMjAxMyBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8qIExPRyBBUEkgKi8KZm9yZ2UubG9nID0gZm9yZ2UubG9nIHx8IHt9OwoKLyoqCiAqIEFwcGxpY2F0aW9uIGxvZ2dpbmcgc3lzdGVtLgogKgogKiBFYWNoIGxvZ2dlciBsZXZlbCBhdmFpbGFibGUgYXMgaXQncyBvd24gZnVuY3Rpb24gb2YgdGhlIGZvcm06CiAqICAgZm9yZ2UubG9nLmxldmVsKGNhdGVnb3J5LCBhcmdzLi4uKQogKiBUaGUgY2F0ZWdvcnkgaXMgYW4gYXJiaXRyYXJ5IHN0cmluZywgYW5kIHRoZSBhcmdzIGFyZSB0aGUgc2FtZSBhcwogKiBGaXJlYnVnJ3MgY29uc29sZS5sb2cgQVBJLiBCeSBkZWZhdWx0IHRoZSBjYWxsIHdpbGwgYmUgb3V0cHV0IGFzOgogKiAgICdMRVZFTCBbY2F0ZWdvcnldIDxhcmdzWzBdPiwgYXJnc1sxXSwgLi4uJwogKiBUaGlzIGVuYWJsZXMgcHJvcGVyICUgZm9ybWF0dGluZyB2aWEgdGhlIGZpcnN0IGFyZ3VtZW50LgogKiBFYWNoIGNhdGVnb3J5IGlzIGVuYWJsZWQgYnkgZGVmYXVsdCBidXQgY2FuIGJlIGVuYWJsZWQgb3IgZGlzYWJsZWQgd2l0aAogKiB0aGUgc2V0Q2F0ZWdvcnlFbmFibGVkKCkgZnVuY3Rpb24uCiAqLwovLyBsaXN0IG9mIGtub3duIGxldmVscwpmb3JnZS5sb2cubGV2ZWxzID0gWwogICdub25lJywgJ2Vycm9yJywgJ3dhcm5pbmcnLCAnaW5mbycsICdkZWJ1ZycsICd2ZXJib3NlJywgJ21heCddOwovLyBpbmZvIG9uIHRoZSBsZXZlbHMgaW5kZXhlZCBieSBuYW1lOgovLyAgIGluZGV4OiBsZXZlbCBpbmRleAovLyAgIG5hbWU6IHVwcGVyY2FzZWQgZGlzcGxheSBuYW1lCnZhciBzTGV2ZWxJbmZvID0ge307Ci8vIGxpc3Qgb2YgbG9nZ2Vycwp2YXIgc0xvZ2dlcnMgPSBbXTsKLyoqCiAqIFN0YW5kYXJkIGNvbnNvbGUgbG9nZ2VyLiBJZiBubyBjb25zb2xlIHN1cHBvcnQgaXMgZW5hYmxlZCB0aGlzIHdpbGwKICogcmVtYWluIG51bGwuIENoZWNrIGJlZm9yZSB1c2luZy4KICovCnZhciBzQ29uc29sZUxvZ2dlciA9IG51bGw7CgovLyBsb2dnZXIgZmxhZ3MKLyoqCiAqIExvY2sgdGhlIGxldmVsIGF0IHRoZSBjdXJyZW50IHZhbHVlLiBVc2VkIGluIGNhc2VzIHdoZXJlIHVzZXIgY29uZmlnIG1heQogKiBzZXQgdGhlIGxldmVsIHN1Y2ggdGhhdCBvbmx5IGNyaXRpY2FsIG1lc3NhZ2VzIGFyZSBzZWVuIGJ1dCBtb3JlIHZlcmJvc2UKICogbWVzc2FnZXMgYXJlIG5lZWRlZCBmb3IgZGVidWdnaW5nIG9yIG90aGVyIHB1cnBvc2VzLgogKi8KZm9yZ2UubG9nLkxFVkVMX0xPQ0tFRCA9ICgxIDw8IDEpOwovKioKICogQWx3YXlzIGNhbGwgbG9nIGZ1bmN0aW9uLiBCeSBkZWZhdWx0LCB0aGUgbG9nZ2luZyBzeXN0ZW0gd2lsbCBjaGVjayB0aGUKICogbWVzc2FnZSBsZXZlbCBhZ2FpbnN0IGxvZ2dlci5sZXZlbCBiZWZvcmUgY2FsbGluZyB0aGUgbG9nIGZ1bmN0aW9uLiBUaGlzCiAqIGZsYWcgYWxsb3dzIHRoZSBmdW5jdGlvbiB0byBkbyBpdHMgb3duIGNoZWNrLgogKi8KZm9yZ2UubG9nLk5PX0xFVkVMX0NIRUNLID0gKDEgPDwgMik7Ci8qKgogKiBQZXJmb3JtIG1lc3NhZ2UgaW50ZXJwb2xhdGlvbiB3aXRoIHRoZSBwYXNzZWQgYXJndW1lbnRzLiAiJSIgc3R5bGUKICogZmllbGRzIGluIGxvZyBtZXNzYWdlcyB3aWxsIGJlIHJlcGxhY2VkIGJ5IGFyZ3VtZW50cyBhcyBuZWVkZWQuIFNvbWUKICogbG9nZ2Vycywgc3VjaCBhcyBGaXJlYnVnLCBtYXkgZG8gdGhpcyBhdXRvbWF0aWNhbGx5LiBUaGUgb3JpZ2luYWwgbG9nCiAqIG1lc3NhZ2Ugd2lsbCBiZSBhdmFpbGFibGUgYXMgJ21lc3NhZ2UnIGFuZCB0aGUgaW50ZXJwb2xhdGVkIHZlcnNpb24gd2lsbAogKiBiZSBhdmFpbGFibGUgYXMgJ2Z1bGxNZXNzYWdlJy4KICovCmZvcmdlLmxvZy5JTlRFUlBPTEFURSA9ICgxIDw8IDMpOwoKLy8gc2V0dXAgZWFjaCBsb2cgbGV2ZWwKZm9yKHZhciBpID0gMDsgaSA8IGZvcmdlLmxvZy5sZXZlbHMubGVuZ3RoOyArK2kpIHsKICB2YXIgbGV2ZWwgPSBmb3JnZS5sb2cubGV2ZWxzW2ldOwogIHNMZXZlbEluZm9bbGV2ZWxdID0gewogICAgaW5kZXg6IGksCiAgICBuYW1lOiBsZXZlbC50b1VwcGVyQ2FzZSgpCiAgfTsKfQoKLyoqCiAqIE1lc3NhZ2UgbG9nZ2VyLiBXaWxsIGRpc3BhdGNoIGEgbWVzc2FnZSB0byByZWdpc3RlcmVkIGxvZ2dlcnMgYXMgbmVlZGVkLgogKgogKiBAcGFyYW0gbWVzc2FnZSBtZXNzYWdlIG9iamVjdAogKi8KZm9yZ2UubG9nLmxvZ01lc3NhZ2UgPSBmdW5jdGlvbihtZXNzYWdlKSB7CiAgdmFyIG1lc3NhZ2VMZXZlbEluZGV4ID0gc0xldmVsSW5mb1ttZXNzYWdlLmxldmVsXS5pbmRleDsKICBmb3IodmFyIGkgPSAwOyBpIDwgc0xvZ2dlcnMubGVuZ3RoOyArK2kpIHsKICAgIHZhciBsb2dnZXIgPSBzTG9nZ2Vyc1tpXTsKICAgIGlmKGxvZ2dlci5mbGFncyAmIGZvcmdlLmxvZy5OT19MRVZFTF9DSEVDSykgewogICAgICBsb2dnZXIuZihtZXNzYWdlKTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIGdldCBsb2dnZXIgbGV2ZWwKICAgICAgdmFyIGxvZ2dlckxldmVsSW5kZXggPSBzTGV2ZWxJbmZvW2xvZ2dlci5sZXZlbF0uaW5kZXg7CiAgICAgIC8vIGNoZWNrIGxldmVsCiAgICAgIGlmKG1lc3NhZ2VMZXZlbEluZGV4IDw9IGxvZ2dlckxldmVsSW5kZXgpIHsKICAgICAgICAvLyBtZXNzYWdlIGNyaXRpY2FsIGVub3VnaCwgY2FsbCBsb2dnZXIKICAgICAgICBsb2dnZXIuZihsb2dnZXIsIG1lc3NhZ2UpOwogICAgICB9CiAgICB9CiAgfQp9OwoKLyoqCiAqIFNldHMgdGhlICdzdGFuZGFyZCcga2V5IG9uIGEgbWVzc2FnZSBvYmplY3QgdG86CiAqICJMRVZFTCBbY2F0ZWdvcnldICIgKyBtZXNzYWdlCiAqCiAqIEBwYXJhbSBtZXNzYWdlIGEgbWVzc2FnZSBsb2cgb2JqZWN0CiAqLwpmb3JnZS5sb2cucHJlcGFyZVN0YW5kYXJkID0gZnVuY3Rpb24obWVzc2FnZSkgewogIGlmKCEoJ3N0YW5kYXJkJyBpbiBtZXNzYWdlKSkgewogICAgbWVzc2FnZS5zdGFuZGFyZCA9CiAgICAgIHNMZXZlbEluZm9bbWVzc2FnZS5sZXZlbF0ubmFtZSArCiAgICAgIC8vJyAnICsgK21lc3NhZ2UudGltZXN0YW1wICsKICAgICAgJyBbJyArIG1lc3NhZ2UuY2F0ZWdvcnkgKyAnXSAnICsKICAgICAgbWVzc2FnZS5tZXNzYWdlOwogIH0KfTsKCi8qKgogKiBTZXRzIHRoZSAnZnVsbCcga2V5IG9uIGEgbWVzc2FnZSBvYmplY3QgdG8gdGhlIG9yaWdpbmFsIG1lc3NhZ2UKICogaW50ZXJwb2xhdGVkIHZpYSAlIGZvcm1hdHRpbmcgd2l0aCB0aGUgbWVzc2FnZSBhcmd1bWVudHMuCiAqCiAqIEBwYXJhbSBtZXNzYWdlIGEgbWVzc2FnZSBsb2cgb2JqZWN0LgogKi8KZm9yZ2UubG9nLnByZXBhcmVGdWxsID0gZnVuY3Rpb24obWVzc2FnZSkgewogIGlmKCEoJ2Z1bGwnIGluIG1lc3NhZ2UpKSB7CiAgICAvLyBjb3B5IGFyZ3MgYW5kIGluc2VydCBtZXNzYWdlIGF0IHRoZSBmcm9udAogICAgdmFyIGFyZ3MgPSBbbWVzc2FnZS5tZXNzYWdlXTsKICAgIGFyZ3MgPSBhcmdzLmNvbmNhdChbXSB8fCBtZXNzYWdlWydhcmd1bWVudHMnXSk7CiAgICAvLyBmb3JtYXQgdGhlIG1lc3NhZ2UKICAgIG1lc3NhZ2UuZnVsbCA9IGZvcmdlLnV0aWwuZm9ybWF0LmFwcGx5KHRoaXMsIGFyZ3MpOwogIH0KfTsKCi8qKgogKiBBcHBsaWVzIGJvdGggcHJlcGFyc2VTdGFuZGFyZCgpIGFuZCBwcmVwYXJlRnVsbCgpIHRvIGEgbWVzc2FnZSBvYmplY3QgYW5kCiAqIHN0b3JlIHJlc3VsdCBpbiAnc3RhbmRhcmRGdWxsJy4KICoKICogQHBhcmFtIG1lc3NhZ2UgYSBtZXNzYWdlIGxvZyBvYmplY3QuCiAqLwpmb3JnZS5sb2cucHJlcGFyZVN0YW5kYXJkRnVsbCA9IGZ1bmN0aW9uKG1lc3NhZ2UpIHsKICBpZighKCdzdGFuZGFyZEZ1bGwnIGluIG1lc3NhZ2UpKSB7CiAgICAvLyBGSVhNRSBpbXBsZW1lbnQgJ3N0YW5kYXJkRnVsbCcgbG9nZ2luZwogICAgZm9yZ2UubG9nLnByZXBhcmVTdGFuZGFyZChtZXNzYWdlKTsKICAgIG1lc3NhZ2Uuc3RhbmRhcmRGdWxsID0gbWVzc2FnZS5zdGFuZGFyZDsKICB9Cn07CgovLyBjcmVhdGUgbG9nIGxldmVsIGZ1bmN0aW9ucwppZih0cnVlKSB7CiAgLy8gbGV2ZWxzIGZvciB3aGljaCB3ZSB3YW50IGZ1bmN0aW9ucwogIHZhciBsZXZlbHMgPSBbJ2Vycm9yJywgJ3dhcm5pbmcnLCAnaW5mbycsICdkZWJ1ZycsICd2ZXJib3NlJ107CiAgZm9yKHZhciBpID0gMDsgaSA8IGxldmVscy5sZW5ndGg7ICsraSkgewogICAgLy8gd3JhcCBpbiBhIGZ1bmN0aW9uIHRvIGVuc3VyZSBwcm9wZXIgbGV2ZWwgdmFyIGlzIHBhc3NlZAogICAgKGZ1bmN0aW9uKGxldmVsKSB7CiAgICAgIC8vIGNyZWF0ZSBmdW5jdGlvbiBmb3IgdGhpcyBsZXZlbAogICAgICBmb3JnZS5sb2dbbGV2ZWxdID0gZnVuY3Rpb24oY2F0ZWdvcnksIG1lc3NhZ2UvKiwgYXJncy4uLiovKSB7CiAgICAgICAgLy8gY29udmVydCBhcmd1bWVudHMgdG8gcmVhbCBhcnJheSwgcmVtb3ZlIGNhdGVnb3J5IGFuZCBtZXNzYWdlCiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpLnNsaWNlKDIpOwogICAgICAgIC8vIGNyZWF0ZSBtZXNzYWdlIG9iamVjdAogICAgICAgIC8vIE5vdGU6IGludGVycG9sYXRpb24gYW5kIHN0YW5kYXJkIGZvcm1hdHRpbmcgaXMgZG9uZSBsYXppbHkKICAgICAgICB2YXIgbXNnID0gewogICAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLAogICAgICAgICAgbGV2ZWw6IGxldmVsLAogICAgICAgICAgY2F0ZWdvcnk6IGNhdGVnb3J5LAogICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSwKICAgICAgICAgICdhcmd1bWVudHMnOiBhcmdzCiAgICAgICAgICAvKnN0YW5kYXJkKi8KICAgICAgICAgIC8qZnVsbCovCiAgICAgICAgICAvKmZ1bGxNZXNzYWdlKi8KICAgICAgICB9OwogICAgICAgIC8vIHByb2Nlc3MgdGhpcyBtZXNzYWdlCiAgICAgICAgZm9yZ2UubG9nLmxvZ01lc3NhZ2UobXNnKTsKICAgICAgfTsKICAgIH0pKGxldmVsc1tpXSk7CiAgfQp9CgovKioKICogQ3JlYXRlcyBhIG5ldyBsb2dnZXIgd2l0aCBzcGVjaWZpZWQgY3VzdG9tIGxvZ2dpbmcgZnVuY3Rpb24uCiAqCiAqIFRoZSBsb2dnaW5nIGZ1bmN0aW9uIGhhcyBhIHNpZ25hdHVyZSBvZjoKICogICBmdW5jdGlvbihsb2dnZXIsIG1lc3NhZ2UpCiAqIGxvZ2dlcjogY3VycmVudCBsb2dnZXIKICogbWVzc2FnZTogb2JqZWN0OgogKiAgIGxldmVsOiBsZXZlbCBpZAogKiAgIGNhdGVnb3J5OiBjYXRlZ29yeQogKiAgIG1lc3NhZ2U6IHN0cmluZyBtZXNzYWdlCiAqICAgYXJndW1lbnRzOiBBcnJheSBvZiBleHRyYSBhcmd1bWVudHMKICogICBmdWxsTWVzc2FnZTogaW50ZXJwb2xhdGVkIG1lc3NhZ2UgYW5kIGFyZ3VtZW50cyBpZiBJTlRFUlBPTEFURSBmbGFnIHNldAogKgogKiBAcGFyYW0gbG9nRnVuY3Rpb24gYSBsb2dnaW5nIGZ1bmN0aW9uIHdoaWNoIHRha2VzIGEgbG9nIG1lc3NhZ2Ugb2JqZWN0CiAqICAgICAgICAgIGFzIGEgcGFyYW1ldGVyLgogKgogKiBAcmV0dXJuIGEgbG9nZ2VyIG9iamVjdC4KICovCmZvcmdlLmxvZy5tYWtlTG9nZ2VyID0gZnVuY3Rpb24obG9nRnVuY3Rpb24pIHsKICB2YXIgbG9nZ2VyID0gewogICAgZmxhZ3M6IDAsCiAgICBmOiBsb2dGdW5jdGlvbgogIH07CiAgZm9yZ2UubG9nLnNldExldmVsKGxvZ2dlciwgJ25vbmUnKTsKICByZXR1cm4gbG9nZ2VyOwp9OwoKLyoqCiAqIFNldHMgdGhlIGN1cnJlbnQgbG9nIGxldmVsIG9uIGEgbG9nZ2VyLgogKgogKiBAcGFyYW0gbG9nZ2VyIHRoZSB0YXJnZXQgbG9nZ2VyLgogKiBAcGFyYW0gbGV2ZWwgdGhlIG5ldyBtYXhpbXVtIGxvZyBsZXZlbCBhcyBhIHN0cmluZy4KICoKICogQHJldHVybiB0cnVlIGlmIHNldCwgZmFsc2UgaWYgbm90LgogKi8KZm9yZ2UubG9nLnNldExldmVsID0gZnVuY3Rpb24obG9nZ2VyLCBsZXZlbCkgewogIHZhciBydmFsID0gZmFsc2U7CiAgaWYobG9nZ2VyICYmICEobG9nZ2VyLmZsYWdzICYgZm9yZ2UubG9nLkxFVkVMX0xPQ0tFRCkpIHsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBmb3JnZS5sb2cubGV2ZWxzLmxlbmd0aDsgKytpKSB7CiAgICAgIHZhciBhVmFsaWRMZXZlbCA9IGZvcmdlLmxvZy5sZXZlbHNbaV07CiAgICAgIGlmKGxldmVsID09IGFWYWxpZExldmVsKSB7CiAgICAgICAgLy8gc2V0IGxldmVsCiAgICAgICAgbG9nZ2VyLmxldmVsID0gbGV2ZWw7CiAgICAgICAgcnZhbCA9IHRydWU7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIExvY2tzIHRoZSBsb2cgbGV2ZWwgYXQgaXRzIGN1cnJlbnQgdmFsdWUuCiAqCiAqIEBwYXJhbSBsb2dnZXIgdGhlIHRhcmdldCBsb2dnZXIuCiAqIEBwYXJhbSBsb2NrIGJvb2xlYW4gbG9jayB2YWx1ZSwgZGVmYXVsdCB0byB0cnVlLgogKi8KZm9yZ2UubG9nLmxvY2sgPSBmdW5jdGlvbihsb2dnZXIsIGxvY2spIHsKICBpZih0eXBlb2YgbG9jayA9PT0gJ3VuZGVmaW5lZCcgfHwgbG9jaykgewogICAgbG9nZ2VyLmZsYWdzIHw9IGZvcmdlLmxvZy5MRVZFTF9MT0NLRUQ7CiAgfSBlbHNlIHsKICAgIGxvZ2dlci5mbGFncyAmPSB+Zm9yZ2UubG9nLkxFVkVMX0xPQ0tFRDsKICB9Cn07CgovKioKICogQWRkcyBhIGxvZ2dlci4KICoKICogQHBhcmFtIGxvZ2dlciB0aGUgbG9nZ2VyIG9iamVjdC4KICovCmZvcmdlLmxvZy5hZGRMb2dnZXIgPSBmdW5jdGlvbihsb2dnZXIpIHsKICBzTG9nZ2Vycy5wdXNoKGxvZ2dlcik7Cn07CgovLyBzZXR1cCB0aGUgY29uc29sZSBsb2dnZXIgaWYgcG9zc2libGUsIGVsc2UgY3JlYXRlIGZha2UgY29uc29sZS5sb2cKaWYodHlwZW9mKGNvbnNvbGUpICE9PSAndW5kZWZpbmVkJyAmJiAnbG9nJyBpbiBjb25zb2xlKSB7CiAgdmFyIGxvZ2dlcjsKICBpZihjb25zb2xlLmVycm9yICYmIGNvbnNvbGUud2FybiAmJiBjb25zb2xlLmluZm8gJiYgY29uc29sZS5kZWJ1ZykgewogICAgLy8gbG9va3MgbGlrZSBGaXJlYnVnLXN0eWxlIGxvZ2dpbmcgaXMgYXZhaWxhYmxlCiAgICAvLyBsZXZlbCBoYW5kbGVycyBtYXAKICAgIHZhciBsZXZlbEhhbmRsZXJzID0gewogICAgICBlcnJvcjogY29uc29sZS5lcnJvciwKICAgICAgd2FybmluZzogY29uc29sZS53YXJuLAogICAgICBpbmZvOiBjb25zb2xlLmluZm8sCiAgICAgIGRlYnVnOiBjb25zb2xlLmRlYnVnLAogICAgICB2ZXJib3NlOiBjb25zb2xlLmRlYnVnCiAgICB9OwogICAgdmFyIGYgPSBmdW5jdGlvbihsb2dnZXIsIG1lc3NhZ2UpIHsKICAgICAgZm9yZ2UubG9nLnByZXBhcmVTdGFuZGFyZChtZXNzYWdlKTsKICAgICAgdmFyIGhhbmRsZXIgPSBsZXZlbEhhbmRsZXJzW21lc3NhZ2UubGV2ZWxdOwogICAgICAvLyBwcmVwZW5kIHN0YW5kYXJkIG1lc3NhZ2UgYW5kIGNvbmNhdCBhcmdzCiAgICAgIHZhciBhcmdzID0gW21lc3NhZ2Uuc3RhbmRhcmRdOwogICAgICBhcmdzID0gYXJncy5jb25jYXQobWVzc2FnZVsnYXJndW1lbnRzJ10uc2xpY2UoKSk7CiAgICAgIC8vIGFwcGx5IHRvIGxvdy1sZXZlbCBjb25zb2xlIGZ1bmN0aW9uCiAgICAgIGhhbmRsZXIuYXBwbHkoY29uc29sZSwgYXJncyk7CiAgICB9OwogICAgbG9nZ2VyID0gZm9yZ2UubG9nLm1ha2VMb2dnZXIoZik7CiAgfSBlbHNlIHsKICAgIC8vIG9ubHkgYXBwZWFyIHRvIGhhdmUgYmFzaWMgY29uc29sZS5sb2cKICAgIHZhciBmID0gZnVuY3Rpb24obG9nZ2VyLCBtZXNzYWdlKSB7CiAgICAgIGZvcmdlLmxvZy5wcmVwYXJlU3RhbmRhcmRGdWxsKG1lc3NhZ2UpOwogICAgICBjb25zb2xlLmxvZyhtZXNzYWdlLnN0YW5kYXJkRnVsbCk7CiAgICB9OwogICAgbG9nZ2VyID0gZm9yZ2UubG9nLm1ha2VMb2dnZXIoZik7CiAgfQogIGZvcmdlLmxvZy5zZXRMZXZlbChsb2dnZXIsICdkZWJ1ZycpOwogIGZvcmdlLmxvZy5hZGRMb2dnZXIobG9nZ2VyKTsKICBzQ29uc29sZUxvZ2dlciA9IGxvZ2dlcjsKfSBlbHNlIHsKICAvLyBkZWZpbmUgZmFrZSBjb25zb2xlLmxvZyB0byBhdm9pZCBwb3RlbnRpYWwgc2NyaXB0IGVycm9ycyBvbgogIC8vIGJyb3dzZXJzIHRoYXQgZG8gbm90IGhhdmUgY29uc29sZSBsb2dnaW5nCiAgY29uc29sZSA9IHsKICAgIGxvZzogZnVuY3Rpb24oKSB7fQogIH07Cn0KCi8qCiAqIENoZWNrIGZvciBsb2dnaW5nIGNvbnRyb2wgcXVlcnkgdmFycy4KICoKICogY29uc29sZS5sZXZlbD08bGV2ZWwtbmFtZT4KICogU2V0J3MgdGhlIGNvbnNvbGUgbG9nIGxldmVsIGJ5IG5hbWUuICBVc2VmdWwgdG8gb3ZlcnJpZGUgZGVmYXVsdHMgYW5kCiAqIGFsbG93IG1vcmUgdmVyYm9zZSBsb2dnaW5nIGJlZm9yZSBhIHVzZXIgY29uZmlnIGlzIGxvYWRlZC4KICoKICogY29uc29sZS5sb2NrPTx0cnVlfGZhbHNlPgogKiBMb2NrIHRoZSBjb25zb2xlIGxvZyBsZXZlbCBhdCB3aGF0ZXZlciBsZXZlbCBpdCBpcyBzZXQgYXQuICBUaGlzIGlzIHJ1bgogKiBhZnRlciBjb25zb2xlLmxldmVsIGlzIHByb2Nlc3NlZC4gIFVzZWZ1bCB0byBmb3JjZSBhIGxldmVsIG9mIHZlcmJvc2l0eQogKiB0aGF0IGNvdWxkIG90aGVyd2lzZSBiZSBsaW1pdGVkIGJ5IGEgdXNlciBjb25maWcuCiAqLwppZihzQ29uc29sZUxvZ2dlciAhPT0gbnVsbCkgewogIHZhciBxdWVyeSA9IGZvcmdlLnV0aWwuZ2V0UXVlcnlWYXJpYWJsZXMoKTsKICBpZignY29uc29sZS5sZXZlbCcgaW4gcXVlcnkpIHsKICAgIC8vIHNldCB3aXRoIGxhc3QgdmFsdWUKICAgIGZvcmdlLmxvZy5zZXRMZXZlbCgKICAgICAgc0NvbnNvbGVMb2dnZXIsIHF1ZXJ5Wydjb25zb2xlLmxldmVsJ10uc2xpY2UoLTEpWzBdKTsKICB9CiAgaWYoJ2NvbnNvbGUubG9jaycgaW4gcXVlcnkpIHsKICAgIC8vIHNldCB3aXRoIGxhc3QgdmFsdWUKICAgIHZhciBsb2NrID0gcXVlcnlbJ2NvbnNvbGUubG9jayddLnNsaWNlKC0xKVswXTsKICAgIGlmKGxvY2sgPT0gJ3RydWUnKSB7CiAgICAgIGZvcmdlLmxvZy5sb2NrKHNDb25zb2xlTG9nZ2VyKTsKICAgIH0KICB9Cn0KCi8vIHByb3ZpZGUgcHVibGljIGFjY2VzcyB0byBjb25zb2xlIGxvZ2dlcgpmb3JnZS5sb2cuY29uc29sZUxvZ2dlciA9IHNDb25zb2xlTG9nZ2VyOwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAnbG9nJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL2xvZycsWydyZXF1aXJlJywgJ21vZHVsZScsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBQS0NTIzcgdjEuNS4KICoKICogQGF1dGhvciBTdGVmYW4gU2llZ2wKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDEyIFN0ZWZhbiBTaWVnbCA8c3Rlc2llQGJyb2tlbnBpcGUuZGU+CiAqIENvcHlyaWdodCAoYykgMjAxMi0yMDE1IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqCiAqIEN1cnJlbnRseSB0aGlzIGltcGxlbWVudGF0aW9uIG9ubHkgc3VwcG9ydHMgQ29udGVudFR5cGUgb2YgRW52ZWxvcGVkRGF0YSwKICogRW5jcnlwdGVkRGF0YSwgb3IgU2lnbmVkRGF0YSBhdCB0aGUgcm9vdCBsZXZlbC4gVGhlIHRvcCBsZXZlbCBlbGVtZW50cyBtYXkKICogY29udGFpbiBvbmx5IGEgQ29udGVudEluZm8gb2YgQ29udGVudFR5cGUgRGF0YSwgaS5lLiBwbGFpbiBkYXRhLiBGdXJ0aGVyCiAqIG5lc3RpbmcgaXMgbm90ICh5ZXQpIHN1cHBvcnRlZC4KICoKICogVGhlIEZvcmdlIHZhbGlkYXRvcnMgZm9yIFBLQ1MgIzcncyBBU04uMSBzdHJ1Y3R1cmVzIGFyZSBhdmFpbGFibGUgZnJvbQogKiBhIHNlcGFyYXRlIGZpbGUgcGtjczdhc24xLmpzLCBzaW5jZSB0aG9zZSBhcmUgcmVmZXJlbmNlZCBmcm9tIG90aGVyCiAqIFBLQ1Mgc3RhbmRhcmRzIGxpa2UgUEtDUyAjMTIuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKLy8gc2hvcnRjdXQgZm9yIEFTTi4xIEFQSQp2YXIgYXNuMSA9IGZvcmdlLmFzbjE7CgovLyBzaG9ydGN1dCBmb3IgUEtDUyM3IEFQSQp2YXIgcDcgPSBmb3JnZS5wa2NzNyA9IGZvcmdlLnBrY3M3IHx8IHt9OwoKLyoqCiAqIENvbnZlcnRzIGEgUEtDUyM3IG1lc3NhZ2UgZnJvbSBQRU0gZm9ybWF0LgogKgogKiBAcGFyYW0gcGVtIHRoZSBQRU0tZm9ybWF0dGVkIFBLQ1MjNyBtZXNzYWdlLgogKgogKiBAcmV0dXJuIHRoZSBQS0NTIzcgbWVzc2FnZS4KICovCnA3Lm1lc3NhZ2VGcm9tUGVtID0gZnVuY3Rpb24ocGVtKSB7CiAgdmFyIG1zZyA9IGZvcmdlLnBlbS5kZWNvZGUocGVtKVswXTsKCiAgaWYobXNnLnR5cGUgIT09ICdQS0NTNycpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ291bGQgbm90IGNvbnZlcnQgUEtDUyM3IG1lc3NhZ2UgZnJvbSBQRU07IFBFTSAnICsKICAgICAgJ2hlYWRlciB0eXBlIGlzIG5vdCAiUEtDUyM3Ii4nKTsKICAgIGVycm9yLmhlYWRlclR5cGUgPSBtc2cudHlwZTsKICAgIHRocm93IGVycm9yOwogIH0KICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IFBLQ1MjNyBtZXNzYWdlIGZyb20gUEVNOyBQRU0gaXMgZW5jcnlwdGVkLicpOwogIH0KCiAgLy8gY29udmVydCBERVIgdG8gQVNOLjEgb2JqZWN0CiAgdmFyIG9iaiA9IGFzbjEuZnJvbURlcihtc2cuYm9keSk7CgogIHJldHVybiBwNy5tZXNzYWdlRnJvbUFzbjEob2JqKTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhIFBLQ1MjNyBtZXNzYWdlIHRvIFBFTSBmb3JtYXQuCiAqCiAqIEBwYXJhbSBtc2cgVGhlIFBLQ1MjNyBtZXNzYWdlIG9iamVjdAogKiBAcGFyYW0gbWF4bGluZSBUaGUgbWF4aW11bSBjaGFyYWN0ZXJzIHBlciBsaW5lLCBkZWZhdWx0cyB0byA2NC4KICoKICogQHJldHVybiBUaGUgUEVNLWZvcm1hdHRlZCBQS0NTIzcgbWVzc2FnZS4KICovCnA3Lm1lc3NhZ2VUb1BlbSA9IGZ1bmN0aW9uKG1zZywgbWF4bGluZSkgewogIC8vIGNvbnZlcnQgdG8gQVNOLjEsIHRoZW4gREVSLCB0aGVuIFBFTS1lbmNvZGUKICB2YXIgcGVtT2JqID0gewogICAgdHlwZTogJ1BLQ1M3JywKICAgIGJvZHk6IGFzbjEudG9EZXIobXNnLnRvQXNuMSgpKS5nZXRCeXRlcygpCiAgfTsKICByZXR1cm4gZm9yZ2UucGVtLmVuY29kZShwZW1PYmosIHttYXhsaW5lOiBtYXhsaW5lfSk7Cn07CgovKioKICogQ29udmVydHMgYSBQS0NTIzcgbWVzc2FnZSBmcm9tIGFuIEFTTi4xIG9iamVjdC4KICoKICogQHBhcmFtIG9iaiB0aGUgQVNOLjEgcmVwcmVzZW50YXRpb24gb2YgYSBDb250ZW50SW5mby4KICoKICogQHJldHVybiB0aGUgUEtDUyM3IG1lc3NhZ2UuCiAqLwpwNy5tZXNzYWdlRnJvbUFzbjEgPSBmdW5jdGlvbihvYmopIHsKICAvLyB2YWxpZGF0ZSByb290IGxldmVsIENvbnRlbnRJbmZvIGFuZCBjYXB0dXJlIGRhdGEKICB2YXIgY2FwdHVyZSA9IHt9OwogIHZhciBlcnJvcnMgPSBbXTsKICBpZighYXNuMS52YWxpZGF0ZShvYmosIHA3LmFzbjEuY29udGVudEluZm9WYWxpZGF0b3IsIGNhcHR1cmUsIGVycm9ycykpCiAgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzcgbWVzc2FnZS4gJyArCiAgICAgICdBU04uMSBvYmplY3QgaXMgbm90IGFuIFBLQ1MjNyBDb250ZW50SW5mby4nKTsKICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgIHRocm93IGVycm9yOwogIH0KCiAgdmFyIGNvbnRlbnRUeXBlID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLmNvbnRlbnRUeXBlKTsKICB2YXIgbXNnOwoKICBzd2l0Y2goY29udGVudFR5cGUpIHsKICAgIGNhc2UgZm9yZ2UucGtpLm9pZHMuZW52ZWxvcGVkRGF0YToKICAgICAgbXNnID0gcDcuY3JlYXRlRW52ZWxvcGVkRGF0YSgpOwogICAgICBicmVhazsKCiAgICBjYXNlIGZvcmdlLnBraS5vaWRzLmVuY3J5cHRlZERhdGE6CiAgICAgIG1zZyA9IHA3LmNyZWF0ZUVuY3J5cHRlZERhdGEoKTsKICAgICAgYnJlYWs7CgogICAgY2FzZSBmb3JnZS5wa2kub2lkcy5zaWduZWREYXRhOgogICAgICBtc2cgPSBwNy5jcmVhdGVTaWduZWREYXRhKCk7CiAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgUEtDUyM3IG1lc3NhZ2UuIENvbnRlbnRUeXBlIHdpdGggT0lEICcgKwogICAgICAgIGNvbnRlbnRUeXBlICsgJyBpcyBub3QgKHlldCkgc3VwcG9ydGVkLicpOwogIH0KCiAgbXNnLmZyb21Bc24xKGNhcHR1cmUuY29udGVudC52YWx1ZVswXSk7CiAgcmV0dXJuIG1zZzsKfTsKCnA3LmNyZWF0ZVNpZ25lZERhdGEgPSBmdW5jdGlvbigpIHsKICB2YXIgbXNnID0gbnVsbDsKICBtc2cgPSB7CiAgICB0eXBlOiBmb3JnZS5wa2kub2lkcy5zaWduZWREYXRhLAogICAgdmVyc2lvbjogMSwKICAgIGNlcnRpZmljYXRlczogW10sCiAgICBjcmxzOiBbXSwKICAgIC8vIFRPRE86IGFkZCBqc29uLWZvcm1hdHRlZCBzaWduZXIgc3R1ZmYgaGVyZT8KICAgIHNpZ25lcnM6IFtdLAogICAgLy8gcG9wdWxhdGVkIGR1cmluZyBzaWduKCkKICAgIGRpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXJzOiBbXSwKICAgIGNvbnRlbnRJbmZvOiBudWxsLAogICAgc2lnbmVySW5mb3M6IFtdLAoKICAgIGZyb21Bc24xOiBmdW5jdGlvbihvYmopIHsKICAgICAgLy8gdmFsaWRhdGUgU2lnbmVkRGF0YSBjb250ZW50IGJsb2NrIGFuZCBjYXB0dXJlIGRhdGEuCiAgICAgIF9mcm9tQXNuMShtc2csIG9iaiwgcDcuYXNuMS5zaWduZWREYXRhVmFsaWRhdG9yKTsKICAgICAgbXNnLmNlcnRpZmljYXRlcyA9IFtdOwogICAgICBtc2cuY3JscyA9IFtdOwogICAgICBtc2cuZGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllcnMgPSBbXTsKICAgICAgbXNnLmNvbnRlbnRJbmZvID0gbnVsbDsKICAgICAgbXNnLnNpZ25lckluZm9zID0gW107CgogICAgICB2YXIgY2VydHMgPSBtc2cucmF3Q2FwdHVyZS5jZXJ0aWZpY2F0ZXMudmFsdWU7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBjZXJ0cy5sZW5ndGg7ICsraSkgewogICAgICAgIG1zZy5jZXJ0aWZpY2F0ZXMucHVzaChmb3JnZS5wa2kuY2VydGlmaWNhdGVGcm9tQXNuMShjZXJ0c1tpXSkpOwogICAgICB9CgogICAgICAvLyBUT0RPOiBwYXJzZSBjcmxzCiAgICB9LAoKICAgIHRvQXNuMTogZnVuY3Rpb24oKSB7CiAgICAgIC8vIGRlZ2VuZXJhdGUgY2FzZSB3aXRoIG5vIGNvbnRlbnQKICAgICAgaWYoIW1zZy5jb250ZW50SW5mbykgewogICAgICAgIG1zZy5zaWduKCk7CiAgICAgIH0KCiAgICAgIHZhciBjZXJ0cyA9IFtdOwogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgbXNnLmNlcnRpZmljYXRlcy5sZW5ndGg7ICsraSkgewogICAgICAgIGNlcnRzLnB1c2goZm9yZ2UucGtpLmNlcnRpZmljYXRlVG9Bc24xKG1zZy5jZXJ0aWZpY2F0ZXNbaV0pKTsKICAgICAgfQoKICAgICAgdmFyIGNybHMgPSBbXTsKICAgICAgLy8gVE9ETzogaW1wbGVtZW50IENSTHMKCiAgICAgIC8vIFswXSBTaWduZWREYXRhCiAgICAgIHZhciBzaWduZWREYXRhID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAwLCB0cnVlLCBbCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgICAgLy8gVmVyc2lvbgogICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIobXNnLnZlcnNpb24pLmdldEJ5dGVzKCkpLAogICAgICAgICAgLy8gRGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllcnMKICAgICAgICAgIGFzbjEuY3JlYXRlKAogICAgICAgICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFVCwgdHJ1ZSwKICAgICAgICAgICAgbXNnLmRpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXJzKSwKICAgICAgICAgIC8vIENvbnRlbnRJbmZvCiAgICAgICAgICBtc2cuY29udGVudEluZm8KICAgICAgICBdKQogICAgICBdKTsKICAgICAgaWYoY2VydHMubGVuZ3RoID4gMCkgewogICAgICAgIC8vIFswXSBJTVBMSUNJVCBFeHRlbmRlZENlcnRpZmljYXRlc0FuZENlcnRpZmljYXRlcyBPUFRJT05BTAogICAgICAgIHNpZ25lZERhdGEudmFsdWVbMF0udmFsdWUucHVzaCgKICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMCwgdHJ1ZSwgY2VydHMpKTsKICAgICAgfQogICAgICBpZihjcmxzLmxlbmd0aCA+IDApIHsKICAgICAgICAvLyBbMV0gSU1QTElDSVQgQ2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdHMgT1BUSU9OQUwKICAgICAgICBzaWduZWREYXRhLnZhbHVlWzBdLnZhbHVlLnB1c2goCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDEsIHRydWUsIGNybHMpKTsKICAgICAgfQogICAgICAvLyBTaWduZXJJbmZvcwogICAgICBzaWduZWREYXRhLnZhbHVlWzBdLnZhbHVlLnB1c2goCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVQsIHRydWUsCiAgICAgICAgICBtc2cuc2lnbmVySW5mb3MpKTsKCiAgICAgIC8vIENvbnRlbnRJbmZvCiAgICAgIHJldHVybiBhc24xLmNyZWF0ZSgKICAgICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgICAvLyBDb250ZW50VHlwZQogICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgICBhc24xLm9pZFRvRGVyKG1zZy50eXBlKS5nZXRCeXRlcygpKSwKICAgICAgICAgIC8vIFswXSBTaWduZWREYXRhCiAgICAgICAgICBzaWduZWREYXRhCiAgICAgICAgXSk7CiAgICB9LAoKICAgIC8qKgogICAgICogQWRkIChhbm90aGVyKSBlbnRpdHkgdG8gbGlzdCBvZiBzaWduZXJzLgogICAgICoKICAgICAqIE5vdGU6IElmIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIGFyZSBwcm92aWRlZCwgdGhlbiwgcGVyIFJGQyAyMzE1LAogICAgICogdGhleSBtdXN0IGluY2x1ZGUgYXQgbGVhc3QgdHdvIGF0dHJpYnV0ZXM6IGNvbnRlbnQgdHlwZSBhbmQKICAgICAqIG1lc3NhZ2UgZGlnZXN0LiBUaGUgbWVzc2FnZSBkaWdlc3QgYXR0cmlidXRlIHZhbHVlIHdpbGwgYmUKICAgICAqIGF1dG8tY2FsY3VsYXRlZCBkdXJpbmcgc2lnbmluZyBhbmQgd2lsbCBiZSBpZ25vcmVkIGlmIHByb3ZpZGVkLgogICAgICoKICAgICAqIEhlcmUncyBhbiBleGFtcGxlIG9mIHByb3ZpZGluZyB0aGVzZSB0d28gYXR0cmlidXRlczoKICAgICAqCiAgICAgKiBmb3JnZS5wa2NzNy5jcmVhdGVTaWduZWREYXRhKCk7CiAgICAgKiBwNy5hZGRTaWduZXIoewogICAgICogICBpc3N1ZXI6IGNlcnQuaXNzdWVyLmF0dHJpYnV0ZXMsCiAgICAgKiAgIHNlcmlhbE51bWJlcjogY2VydC5zZXJpYWxOdW1iZXIsCiAgICAgKiAgIGtleTogcHJpdmF0ZUtleSwKICAgICAqICAgZGlnZXN0QWxnb3JpdGhtOiBmb3JnZS5wa2kub2lkcy5zaGExLAogICAgICogICBhdXRoZW50aWNhdGVkQXR0cmlidXRlczogW3sKICAgICAqICAgICB0eXBlOiBmb3JnZS5wa2kub2lkcy5jb250ZW50VHlwZSwKICAgICAqICAgICB2YWx1ZTogZm9yZ2UucGtpLm9pZHMuZGF0YQogICAgICogICB9LCB7CiAgICAgKiAgICAgdHlwZTogZm9yZ2UucGtpLm9pZHMubWVzc2FnZURpZ2VzdAogICAgICogICB9XQogICAgICogfSk7CiAgICAgKgogICAgICogVE9ETzogU3VwcG9ydCBbc3ViamVjdEtleUlkZW50aWZpZXJdIGFzIHNpZ25lcidzIElELgogICAgICoKICAgICAqIEBwYXJhbSBzaWduZXIgdGhlIHNpZ25lciBpbmZvcm1hdGlvbjoKICAgICAqICAgICAgICAgIGtleSB0aGUgc2lnbmVyJ3MgcHJpdmF0ZSBrZXkuCiAgICAgKiAgICAgICAgICBbY2VydGlmaWNhdGVdIGEgY2VydGlmaWNhdGUgY29udGFpbmluZyB0aGUgcHVibGljIGtleQogICAgICogICAgICAgICAgICBhc3NvY2lhdGVkIHdpdGggdGhlIHNpZ25lcidzIHByaXZhdGUga2V5OyB1c2UgdGhpcyBvcHRpb24gYXMKICAgICAqICAgICAgICAgICAgYW4gYWx0ZXJuYXRpdmUgdG8gc3BlY2lmeWluZyBzaWduZXIuaXNzdWVyIGFuZAogICAgICogICAgICAgICAgICBzaWduZXIuc2VyaWFsTnVtYmVyLgogICAgICogICAgICAgICAgW2lzc3Vlcl0gdGhlIGlzc3VlciBhdHRyaWJ1dGVzIChlZzogY2VydC5pc3N1ZXIuYXR0cmlidXRlcykuCiAgICAgKiAgICAgICAgICBbc2VyaWFsTnVtYmVyXSB0aGUgc2lnbmVyJ3MgY2VydGlmaWNhdGUncyBzZXJpYWwgbnVtYmVyIGluCiAgICAgKiAgICAgICAgICAgaGV4YWRlY2ltYWwgKGVnOiBjZXJ0LnNlcmlhbE51bWJlcikuCiAgICAgKiAgICAgICAgICBbZGlnZXN0QWxnb3JpdGhtXSB0aGUgbWVzc2FnZSBkaWdlc3QgT0lELCBhcyBhIHN0cmluZywgdG8gdXNlCiAgICAgKiAgICAgICAgICAgIChlZzogZm9yZ2UucGtpLm9pZHMuc2hhMSkuCiAgICAgKiAgICAgICAgICBbYXV0aGVudGljYXRlZEF0dHJpYnV0ZXNdIGFuIG9wdGlvbmFsIGFycmF5IG9mIGF0dHJpYnV0ZXMKICAgICAqICAgICAgICAgICAgdG8gYWxzbyBzaWduIGFsb25nIHdpdGggdGhlIGNvbnRlbnQuCiAgICAgKi8KICAgIGFkZFNpZ25lcjogZnVuY3Rpb24oc2lnbmVyKSB7CiAgICAgIHZhciBpc3N1ZXIgPSBzaWduZXIuaXNzdWVyOwogICAgICB2YXIgc2VyaWFsTnVtYmVyID0gc2lnbmVyLnNlcmlhbE51bWJlcjsKICAgICAgaWYoc2lnbmVyLmNlcnRpZmljYXRlKSB7CiAgICAgICAgdmFyIGNlcnQgPSBzaWduZXIuY2VydGlmaWNhdGU7CiAgICAgICAgaWYodHlwZW9mIGNlcnQgPT09ICdzdHJpbmcnKSB7CiAgICAgICAgICBjZXJ0ID0gZm9yZ2UucGtpLmNlcnRpZmljYXRlRnJvbVBlbShjZXJ0KTsKICAgICAgICB9CiAgICAgICAgaXNzdWVyID0gY2VydC5pc3N1ZXIuYXR0cmlidXRlczsKICAgICAgICBzZXJpYWxOdW1iZXIgPSBjZXJ0LnNlcmlhbE51bWJlcjsKICAgICAgfQogICAgICB2YXIga2V5ID0gc2lnbmVyLmtleTsKICAgICAgaWYoIWtleSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigKICAgICAgICAgICdDb3VsZCBub3QgYWRkIFBLQ1MjNyBzaWduZXI7IG5vIHByaXZhdGUga2V5IHNwZWNpZmllZC4nKTsKICAgICAgfQogICAgICBpZih0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykgewogICAgICAgIGtleSA9IGZvcmdlLnBraS5wcml2YXRlS2V5RnJvbVBlbShrZXkpOwogICAgICB9CgogICAgICAvLyBlbnN1cmUgT0lEIGtub3duIGZvciBkaWdlc3QgYWxnb3JpdGhtCiAgICAgIHZhciBkaWdlc3RBbGdvcml0aG0gPSBzaWduZXIuZGlnZXN0QWxnb3JpdGhtIHx8IGZvcmdlLnBraS5vaWRzLnNoYTE7CiAgICAgIHN3aXRjaChkaWdlc3RBbGdvcml0aG0pIHsKICAgICAgY2FzZSBmb3JnZS5wa2kub2lkcy5zaGExOgogICAgICBjYXNlIGZvcmdlLnBraS5vaWRzLnNoYTI1NjoKICAgICAgY2FzZSBmb3JnZS5wa2kub2lkcy5zaGEzODQ6CiAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHMuc2hhNTEyOgogICAgICBjYXNlIGZvcmdlLnBraS5vaWRzLm1kNToKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICAgICAnQ291bGQgbm90IGFkZCBQS0NTIzcgc2lnbmVyOyB1bmtub3duIG1lc3NhZ2UgZGlnZXN0IGFsZ29yaXRobTogJyArCiAgICAgICAgICBkaWdlc3RBbGdvcml0aG0pOwogICAgICB9CgogICAgICAvLyBpZiBhdXRoZW50aWNhdGVkQXR0cmlidXRlcyBpcyBwcmVzZW50LCB0aGVuIHRoZSBhdHRyaWJ1dGVzCiAgICAgIC8vIG11c3QgY29udGFpbiBhdCBsZWFzdCBQS0NTICM5IGNvbnRlbnQtdHlwZSBhbmQgbWVzc2FnZS1kaWdlc3QKICAgICAgdmFyIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzID0gc2lnbmVyLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIHx8IFtdOwogICAgICBpZihhdXRoZW50aWNhdGVkQXR0cmlidXRlcy5sZW5ndGggPiAwKSB7CiAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gZmFsc2U7CiAgICAgICAgdmFyIG1lc3NhZ2VEaWdlc3QgPSBmYWxzZTsKICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgIHZhciBhdHRyID0gYXV0aGVudGljYXRlZEF0dHJpYnV0ZXNbaV07CiAgICAgICAgICBpZighY29udGVudFR5cGUgJiYgYXR0ci50eXBlID09PSBmb3JnZS5wa2kub2lkcy5jb250ZW50VHlwZSkgewogICAgICAgICAgICBjb250ZW50VHlwZSA9IHRydWU7CiAgICAgICAgICAgIGlmKG1lc3NhZ2VEaWdlc3QpIHsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmKCFtZXNzYWdlRGlnZXN0ICYmIGF0dHIudHlwZSA9PT0gZm9yZ2UucGtpLm9pZHMubWVzc2FnZURpZ2VzdCkgewogICAgICAgICAgICBtZXNzYWdlRGlnZXN0ID0gdHJ1ZTsKICAgICAgICAgICAgaWYoY29udGVudFR5cGUpIHsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmKCFjb250ZW50VHlwZSB8fCAhbWVzc2FnZURpZ2VzdCkgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNpZ25lci5hdXRoZW50aWNhdGVkQXR0cmlidXRlcy4gSWYgJyArCiAgICAgICAgICAgICdzaWduZXIuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgaXMgc3BlY2lmaWVkLCB0aGVuIGl0IG11c3QgJyArCiAgICAgICAgICAgICdjb250YWluIGF0IGxlYXN0IHR3byBhdHRyaWJ1dGVzLCBQS0NTICM5IGNvbnRlbnQtdHlwZSBhbmQgJyArCiAgICAgICAgICAgICdQS0NTICM5IG1lc3NhZ2UtZGlnZXN0LicpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgbXNnLnNpZ25lcnMucHVzaCh7CiAgICAgICAga2V5OiBrZXksCiAgICAgICAgdmVyc2lvbjogMSwKICAgICAgICBpc3N1ZXI6IGlzc3VlciwKICAgICAgICBzZXJpYWxOdW1iZXI6IHNlcmlhbE51bWJlciwKICAgICAgICBkaWdlc3RBbGdvcml0aG06IGRpZ2VzdEFsZ29yaXRobSwKICAgICAgICBzaWduYXR1cmVBbGdvcml0aG06IGZvcmdlLnBraS5vaWRzLnJzYUVuY3J5cHRpb24sCiAgICAgICAgc2lnbmF0dXJlOiBudWxsLAogICAgICAgIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzOiBhdXRoZW50aWNhdGVkQXR0cmlidXRlcywKICAgICAgICB1bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzOiBbXQogICAgICB9KTsKICAgIH0sCgogICAgLyoqCiAgICAgKiBTaWducyB0aGUgY29udGVudC4KICAgICAqLwogICAgc2lnbjogZnVuY3Rpb24oKSB7CiAgICAgIC8vIGF1dG8tZ2VuZXJhdGUgY29udGVudCBpbmZvCiAgICAgIGlmKHR5cGVvZiBtc2cuY29udGVudCAhPT0gJ29iamVjdCcgfHwgbXNnLmNvbnRlbnRJbmZvID09PSBudWxsKSB7CiAgICAgICAgLy8gdXNlIERhdGEgQ29udGVudEluZm8KICAgICAgICBtc2cuY29udGVudEluZm8gPSBhc24xLmNyZWF0ZSgKICAgICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAgICAgLy8gQ29udGVudFR5cGUKICAgICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgICAgIGFzbjEub2lkVG9EZXIoZm9yZ2UucGtpLm9pZHMuZGF0YSkuZ2V0Qnl0ZXMoKSkKICAgICAgICAgIF0pOwoKICAgICAgICAvLyBhZGQgYWN0dWFsIGNvbnRlbnQsIGlmIHByZXNlbnQKICAgICAgICBpZignY29udGVudCcgaW4gbXNnKSB7CiAgICAgICAgICB2YXIgY29udGVudDsKICAgICAgICAgIGlmKG1zZy5jb250ZW50IGluc3RhbmNlb2YgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKSB7CiAgICAgICAgICAgIGNvbnRlbnQgPSBtc2cuY29udGVudC5ieXRlcygpOwogICAgICAgICAgfSBlbHNlIGlmKHR5cGVvZiBtc2cuY29udGVudCA9PT0gJ3N0cmluZycpIHsKICAgICAgICAgICAgY29udGVudCA9IGZvcmdlLnV0aWwuZW5jb2RlVXRmOChtc2cuY29udGVudCk7CiAgICAgICAgICB9CgogICAgICAgICAgbXNnLmNvbnRlbnRJbmZvLnZhbHVlLnB1c2goCiAgICAgICAgICAgIC8vIFswXSBFWFBMSUNJVCBjb250ZW50CiAgICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMCwgdHJ1ZSwgWwogICAgICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLAogICAgICAgICAgICAgICAgY29udGVudCkKICAgICAgICAgICAgXSkpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gbm8gc2lnbmVycywgcmV0dXJuIGVhcmx5IChkZWdlbmVyYXRlIGNhc2UgZm9yIGNlcnRpZmljYXRlIGNvbnRhaW5lcikKICAgICAgaWYobXNnLnNpZ25lcnMubGVuZ3RoID09PSAwKSB7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICAvLyBnZW5lcmF0ZSBkaWdlc3QgYWxnb3JpdGhtIGlkZW50aWZpZXJzCiAgICAgIHZhciBtZHMgPSBhZGREaWdlc3RBbGdvcml0aG1JZHMoKTsKCiAgICAgIC8vIGdlbmVyYXRlIHNpZ25lckluZm9zCiAgICAgIGFkZFNpZ25lckluZm9zKG1kcyk7CiAgICB9LAoKICAgIHZlcmlmeTogZnVuY3Rpb24oKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignUEtDUyM3IHNpZ25hdHVyZSB2ZXJpZmljYXRpb24gbm90IHlldCBpbXBsZW1lbnRlZC4nKTsKICAgIH0sCgogICAgLyoqCiAgICAgKiBBZGQgYSBjZXJ0aWZpY2F0ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gY2VydCB0aGUgY2VydGlmaWNhdGUgdG8gYWRkLgogICAgICovCiAgICBhZGRDZXJ0aWZpY2F0ZTogZnVuY3Rpb24oY2VydCkgewogICAgICAvLyBjb252ZXJ0IGZyb20gUEVNCiAgICAgIGlmKHR5cGVvZiBjZXJ0ID09PSAnc3RyaW5nJykgewogICAgICAgIGNlcnQgPSBmb3JnZS5wa2kuY2VydGlmaWNhdGVGcm9tUGVtKGNlcnQpOwogICAgICB9CiAgICAgIG1zZy5jZXJ0aWZpY2F0ZXMucHVzaChjZXJ0KTsKICAgIH0sCgogICAgLyoqCiAgICAgKiBBZGQgYSBjZXJ0aWZpY2F0ZSByZXZva2F0aW9uIGxpc3QuCiAgICAgKgogICAgICogQHBhcmFtIGNybCB0aGUgY2VydGlmaWNhdGUgcmV2b2thdGlvbiBsaXN0IHRvIGFkZC4KICAgICAqLwogICAgYWRkQ2VydGlmaWNhdGVSZXZva2F0aW9uTGlzdDogZnVuY3Rpb24oY3JsKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignUEtDUyM3IENSTCBzdXBwb3J0IG5vdCB5ZXQgaW1wbGVtZW50ZWQuJyk7CiAgICB9CiAgfTsKICByZXR1cm4gbXNnOwoKICBmdW5jdGlvbiBhZGREaWdlc3RBbGdvcml0aG1JZHMoKSB7CiAgICB2YXIgbWRzID0ge307CgogICAgZm9yKHZhciBpID0gMDsgaSA8IG1zZy5zaWduZXJzLmxlbmd0aDsgKytpKSB7CiAgICAgIHZhciBzaWduZXIgPSBtc2cuc2lnbmVyc1tpXTsKICAgICAgdmFyIG9pZCA9IHNpZ25lci5kaWdlc3RBbGdvcml0aG07CiAgICAgIGlmKCEob2lkIGluIG1kcykpIHsKICAgICAgICAvLyBjb250ZW50IGRpZ2VzdAogICAgICAgIG1kc1tvaWRdID0gZm9yZ2UubWRbZm9yZ2UucGtpLm9pZHNbb2lkXV0uY3JlYXRlKCk7CiAgICAgIH0KICAgICAgaWYoc2lnbmVyLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzLmxlbmd0aCA9PT0gMCkgewogICAgICAgIC8vIG5vIGN1c3RvbSBhdHRyaWJ1dGVzIHRvIGRpZ2VzdDsgdXNlIGNvbnRlbnQgbWVzc2FnZSBkaWdlc3QKICAgICAgICBzaWduZXIubWQgPSBtZHNbb2lkXTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBjdXN0b20gYXR0cmlidXRlcyB0byBiZSBkaWdlc3RlZDsgdXNlIG93biBtZXNzYWdlIGRpZ2VzdAogICAgICAgIC8vIFRPRE86IG9wdGltaXplIHRvIGp1c3QgY29weSBtZXNzYWdlIGRpZ2VzdCBzdGF0ZSBpZiB0aGF0CiAgICAgICAgLy8gZmVhdHVyZSBpcyBldmVyIHN1cHBvcnRlZCB3aXRoIG1lc3NhZ2UgZGlnZXN0cwogICAgICAgIHNpZ25lci5tZCA9IGZvcmdlLm1kW2ZvcmdlLnBraS5vaWRzW29pZF1dLmNyZWF0ZSgpOwogICAgICB9CiAgICB9CgogICAgLy8gYWRkIHVuaXF1ZSBkaWdlc3QgYWxnb3JpdGhtIGlkZW50aWZpZXJzCiAgICBtc2cuZGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllcnMgPSBbXTsKICAgIGZvcih2YXIgb2lkIGluIG1kcykgewogICAgICBtc2cuZGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllcnMucHVzaCgKICAgICAgICAvLyBBbGdvcml0aG1JZGVudGlmaWVyCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgICAgLy8gYWxnb3JpdGhtCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgICAgIGFzbjEub2lkVG9EZXIob2lkKS5nZXRCeXRlcygpKSwKICAgICAgICAgIC8vIHBhcmFtZXRlcnMgKG51bGwpCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgICAgICBdKSk7CiAgICB9CgogICAgcmV0dXJuIG1kczsKICB9CgogIGZ1bmN0aW9uIGFkZFNpZ25lckluZm9zKG1kcykgewogICAgLy8gTm90ZTogQ29udGVudEluZm8gaXMgYSBTRVFVRU5DRSB3aXRoIDIgdmFsdWVzLCBzZWNvbmQgdmFsdWUgaXMKICAgIC8vIHRoZSBjb250ZW50IGZpZWxkIGFuZCBpcyBvcHRpb25hbCBmb3IgYSBDb250ZW50SW5mbyBidXQgcmVxdWlyZWQgaGVyZQogICAgLy8gc2luY2Ugc2lnbmVycyBhcmUgcHJlc2VudAogICAgaWYobXNnLmNvbnRlbnRJbmZvLnZhbHVlLmxlbmd0aCA8IDIpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKAogICAgICAgICdDb3VsZCBub3Qgc2lnbiBQS0NTIzcgbWVzc2FnZTsgdGhlcmUgaXMgbm8gY29udGVudCB0byBzaWduLicpOwogICAgfQoKICAgIC8vIGdldCBDb250ZW50SW5mbyBjb250ZW50IHR5cGUKICAgIHZhciBjb250ZW50VHlwZSA9IGFzbjEuZGVyVG9PaWQobXNnLmNvbnRlbnRJbmZvLnZhbHVlWzBdLnZhbHVlKTsKCiAgICAvLyBnZXQgQ29udGVudEluZm8gY29udGVudAogICAgdmFyIGNvbnRlbnQgPSBtc2cuY29udGVudEluZm8udmFsdWVbMV07CiAgICAvLyBza2lwIFswXSBFWFBMSUNJVCBjb250ZW50IHdyYXBwZXIKICAgIGNvbnRlbnQgPSBjb250ZW50LnZhbHVlWzBdOwoKICAgIC8vIHNlcmlhbGl6ZSBjb250ZW50CiAgICB2YXIgYnl0ZXMgPSBhc24xLnRvRGVyKGNvbnRlbnQpOwoKICAgIC8vIHNraXAgaWRlbnRpZmllciBhbmQgbGVuZ3RoIHBlciBSRkMgMjMxNSA5LjMKICAgIC8vIHNraXAgaWRlbnRpZmllciAoMSBieXRlKQogICAgYnl0ZXMuZ2V0Qnl0ZSgpOwogICAgLy8gcmVhZCBhbmQgZGlzY2FyZCBsZW5ndGggYnl0ZXMKICAgIGFzbjEuZ2V0QmVyVmFsdWVMZW5ndGgoYnl0ZXMpOwogICAgYnl0ZXMgPSBieXRlcy5nZXRCeXRlcygpOwoKICAgIC8vIGRpZ2VzdCBjb250ZW50IERFUiB2YWx1ZSBieXRlcwogICAgZm9yKHZhciBvaWQgaW4gbWRzKSB7CiAgICAgIG1kc1tvaWRdLnN0YXJ0KCkudXBkYXRlKGJ5dGVzKTsKICAgIH0KCiAgICAvLyBzaWduIGNvbnRlbnQKICAgIHZhciBzaWduaW5nVGltZSA9IG5ldyBEYXRlKCk7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbXNnLnNpZ25lcnMubGVuZ3RoOyArK2kpIHsKICAgICAgdmFyIHNpZ25lciA9IG1zZy5zaWduZXJzW2ldOwoKICAgICAgaWYoc2lnbmVyLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzLmxlbmd0aCA9PT0gMCkgewogICAgICAgIC8vIGlmIENvbnRlbnRJbmZvIGNvbnRlbnQgdHlwZSBpcyBub3QgIkRhdGEiLCB0aGVuCiAgICAgICAgLy8gYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgbXVzdCBiZSBwcmVzZW50IHBlciBSRkMgMjMxNQogICAgICAgIGlmKGNvbnRlbnRUeXBlICE9PSBmb3JnZS5wa2kub2lkcy5kYXRhKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICAgICAgICdJbnZhbGlkIHNpZ25lcjsgYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgbXVzdCBiZSBwcmVzZW50ICcgKwogICAgICAgICAgICAnd2hlbiB0aGUgQ29udGVudEluZm8gY29udGVudCB0eXBlIGlzIG5vdCBQS0NTIzcgRGF0YS4nKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gcHJvY2VzcyBhdXRoZW50aWNhdGVkIGF0dHJpYnV0ZXMKICAgICAgICAvLyBbMF0gSU1QTElDSVQKICAgICAgICBzaWduZXIuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXNBc24xID0gYXNuMS5jcmVhdGUoCiAgICAgICAgICBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFtdKTsKCiAgICAgICAgLy8gcGVyIFJGQyAyMzE1LCBhdHRyaWJ1dGVzIGFyZSB0byBiZSBkaWdlc3RlZCB1c2luZyBhIFNFVCBjb250YWluZXIKICAgICAgICAvLyBub3QgdGhlIGFib3ZlIFswXSBJTVBMSUNJVCBjb250YWluZXIKICAgICAgICB2YXIgYXR0cnNBc24xID0gYXNuMS5jcmVhdGUoCiAgICAgICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFVCwgdHJ1ZSwgW10pOwoKICAgICAgICBmb3IodmFyIGFpID0gMDsgYWkgPCBzaWduZXIuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMubGVuZ3RoOyArK2FpKSB7CiAgICAgICAgICB2YXIgYXR0ciA9IHNpZ25lci5hdXRoZW50aWNhdGVkQXR0cmlidXRlc1thaV07CiAgICAgICAgICBpZihhdHRyLnR5cGUgPT09IGZvcmdlLnBraS5vaWRzLm1lc3NhZ2VEaWdlc3QpIHsKICAgICAgICAgICAgLy8gdXNlIGNvbnRlbnQgbWVzc2FnZSBkaWdlc3QgYXMgdmFsdWUKICAgICAgICAgICAgYXR0ci52YWx1ZSA9IG1kc1tzaWduZXIuZGlnZXN0QWxnb3JpdGhtXS5kaWdlc3QoKTsKICAgICAgICAgIH0gZWxzZSBpZihhdHRyLnR5cGUgPT09IGZvcmdlLnBraS5vaWRzLnNpZ25pbmdUaW1lKSB7CiAgICAgICAgICAgIC8vIGF1dG8tcG9wdWxhdGUgc2lnbmluZyB0aW1lIGlmIG5vdCBhbHJlYWR5IHNldAogICAgICAgICAgICBpZighYXR0ci52YWx1ZSkgewogICAgICAgICAgICAgIGF0dHIudmFsdWUgPSBzaWduaW5nVGltZTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIC8vIGNvbnZlcnQgdG8gQVNOLjEgYW5kIHB1c2ggb250byBBdHRyaWJ1dGVzIFNFVCAoZm9yIHNpZ25pbmcpIGFuZAogICAgICAgICAgLy8gb250byBhdXRoZW50aWNhdGVkQXR0cmlidXRlc0FzbjEgdG8gY29tcGxldGUgU2lnbmVkRGF0YSBBU04uMQogICAgICAgICAgLy8gVE9ETzogb3B0aW1pemUgYXdheSBkdXBsaWNhdGlvbgogICAgICAgICAgYXR0cnNBc24xLnZhbHVlLnB1c2goX2F0dHJpYnV0ZVRvQXNuMShhdHRyKSk7CiAgICAgICAgICBzaWduZXIuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXNBc24xLnZhbHVlLnB1c2goX2F0dHJpYnV0ZVRvQXNuMShhdHRyKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBERVItc2VyaWFsaXplIGFuZCBkaWdlc3QgU0VUIE9GIGF0dHJpYnV0ZXMgb25seQogICAgICAgIGJ5dGVzID0gYXNuMS50b0RlcihhdHRyc0FzbjEpLmdldEJ5dGVzKCk7CiAgICAgICAgc2lnbmVyLm1kLnN0YXJ0KCkudXBkYXRlKGJ5dGVzKTsKICAgICAgfQoKICAgICAgLy8gc2lnbiBkaWdlc3QKICAgICAgc2lnbmVyLnNpZ25hdHVyZSA9IHNpZ25lci5rZXkuc2lnbihzaWduZXIubWQsICdSU0FTU0EtUEtDUzEtVjFfNScpOwogICAgfQoKICAgIC8vIGFkZCBzaWduZXIgaW5mbwogICAgbXNnLnNpZ25lckluZm9zID0gX3NpZ25lcnNUb0FzbjEobXNnLnNpZ25lcnMpOwogIH0KfTsKCi8qKgogKiBDcmVhdGVzIGFuIGVtcHR5IFBLQ1MjNyBtZXNzYWdlIG9mIHR5cGUgRW5jcnlwdGVkRGF0YS4KICoKICogQHJldHVybiB0aGUgbWVzc2FnZS4KICovCnA3LmNyZWF0ZUVuY3J5cHRlZERhdGEgPSBmdW5jdGlvbigpIHsKICB2YXIgbXNnID0gbnVsbDsKICBtc2cgPSB7CiAgICB0eXBlOiBmb3JnZS5wa2kub2lkcy5lbmNyeXB0ZWREYXRhLAogICAgdmVyc2lvbjogMCwKICAgIGVuY3J5cHRlZENvbnRlbnQ6IHsKICAgICAgYWxnb3JpdGhtOiBmb3JnZS5wa2kub2lkc1snYWVzMjU2LUNCQyddCiAgICB9LAoKICAgIC8qKgogICAgICogUmVhZHMgYW4gRW5jcnlwdGVkRGF0YSBjb250ZW50IGJsb2NrIChpbiBBU04uMSBmb3JtYXQpCiAgICAgKgogICAgICogQHBhcmFtIG9iaiBUaGUgQVNOLjEgcmVwcmVzZW50YXRpb24gb2YgdGhlIEVuY3J5cHRlZERhdGEgY29udGVudCBibG9jawogICAgICovCiAgICBmcm9tQXNuMTogZnVuY3Rpb24ob2JqKSB7CiAgICAgIC8vIFZhbGlkYXRlIEVuY3J5cHRlZERhdGEgY29udGVudCBibG9jayBhbmQgY2FwdHVyZSBkYXRhLgogICAgICBfZnJvbUFzbjEobXNnLCBvYmosIHA3LmFzbjEuZW5jcnlwdGVkRGF0YVZhbGlkYXRvcik7CiAgICB9LAoKICAgIC8qKgogICAgICogRGVjcnlwdCBlbmNyeXB0ZWQgY29udGVudAogICAgICoKICAgICAqIEBwYXJhbSBrZXkgVGhlIChzeW1tZXRyaWMpIGtleSBhcyBhIGJ5dGUgYnVmZmVyCiAgICAgKi8KICAgIGRlY3J5cHQ6IGZ1bmN0aW9uKGtleSkgewogICAgICBpZihrZXkgIT09IHVuZGVmaW5lZCkgewogICAgICAgIG1zZy5lbmNyeXB0ZWRDb250ZW50LmtleSA9IGtleTsKICAgICAgfQogICAgICBfZGVjcnlwdENvbnRlbnQobXNnKTsKICAgIH0KICB9OwogIHJldHVybiBtc2c7Cn07CgovKioKICogQ3JlYXRlcyBhbiBlbXB0eSBQS0NTIzcgbWVzc2FnZSBvZiB0eXBlIEVudmVsb3BlZERhdGEuCiAqCiAqIEByZXR1cm4gdGhlIG1lc3NhZ2UuCiAqLwpwNy5jcmVhdGVFbnZlbG9wZWREYXRhID0gZnVuY3Rpb24oKSB7CiAgdmFyIG1zZyA9IG51bGw7CiAgbXNnID0gewogICAgdHlwZTogZm9yZ2UucGtpLm9pZHMuZW52ZWxvcGVkRGF0YSwKICAgIHZlcnNpb246IDAsCiAgICByZWNpcGllbnRzOiBbXSwKICAgIGVuY3J5cHRlZENvbnRlbnQ6IHsKICAgICAgYWxnb3JpdGhtOiBmb3JnZS5wa2kub2lkc1snYWVzMjU2LUNCQyddCiAgICB9LAoKICAgIC8qKgogICAgICogUmVhZHMgYW4gRW52ZWxvcGVkRGF0YSBjb250ZW50IGJsb2NrIChpbiBBU04uMSBmb3JtYXQpCiAgICAgKgogICAgICogQHBhcmFtIG9iaiB0aGUgQVNOLjEgcmVwcmVzZW50YXRpb24gb2YgdGhlIEVudmVsb3BlZERhdGEgY29udGVudCBibG9jay4KICAgICAqLwogICAgZnJvbUFzbjE6IGZ1bmN0aW9uKG9iaikgewogICAgICAvLyB2YWxpZGF0ZSBFbnZlbG9wZWREYXRhIGNvbnRlbnQgYmxvY2sgYW5kIGNhcHR1cmUgZGF0YQogICAgICB2YXIgY2FwdHVyZSA9IF9mcm9tQXNuMShtc2csIG9iaiwgcDcuYXNuMS5lbnZlbG9wZWREYXRhVmFsaWRhdG9yKTsKICAgICAgbXNnLnJlY2lwaWVudHMgPSBfcmVjaXBpZW50c0Zyb21Bc24xKGNhcHR1cmUucmVjaXBpZW50SW5mb3MudmFsdWUpOwogICAgfSwKCiAgICB0b0FzbjE6IGZ1bmN0aW9uKCkgewogICAgICAvLyBDb250ZW50SW5mbwogICAgICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgIC8vIENvbnRlbnRUeXBlCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgYXNuMS5vaWRUb0Rlcihtc2cudHlwZSkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgLy8gWzBdIEVudmVsb3BlZERhdGEKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFsKICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAgICAgLy8gVmVyc2lvbgogICAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICAgICAgICAgIGFzbjEuaW50ZWdlclRvRGVyKG1zZy52ZXJzaW9uKS5nZXRCeXRlcygpKSwKICAgICAgICAgICAgLy8gUmVjaXBpZW50SW5mb3MKICAgICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVQsIHRydWUsCiAgICAgICAgICAgICAgX3JlY2lwaWVudHNUb0FzbjEobXNnLnJlY2lwaWVudHMpKSwKICAgICAgICAgICAgLy8gRW5jcnlwdGVkQ29udGVudEluZm8KICAgICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwKICAgICAgICAgICAgICBfZW5jcnlwdGVkQ29udGVudFRvQXNuMShtc2cuZW5jcnlwdGVkQ29udGVudCkpCiAgICAgICAgICBdKQogICAgICAgIF0pCiAgICAgIF0pOwogICAgfSwKCiAgICAvKioKICAgICAqIEZpbmQgcmVjaXBpZW50IGJ5IFguNTA5IGNlcnRpZmljYXRlJ3MgaXNzdWVyLgogICAgICoKICAgICAqIEBwYXJhbSBjZXJ0IHRoZSBjZXJ0aWZpY2F0ZSB3aXRoIHRoZSBpc3N1ZXIgdG8gbG9vayBmb3IuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgcmVjaXBpZW50IG9iamVjdC4KICAgICAqLwogICAgZmluZFJlY2lwaWVudDogZnVuY3Rpb24oY2VydCkgewogICAgICB2YXIgc0F0dHIgPSBjZXJ0Lmlzc3Vlci5hdHRyaWJ1dGVzOwoKICAgICAgZm9yKHZhciBpID0gMDsgaSA8IG1zZy5yZWNpcGllbnRzLmxlbmd0aDsgKytpKSB7CiAgICAgICAgdmFyIHIgPSBtc2cucmVjaXBpZW50c1tpXTsKICAgICAgICB2YXIgckF0dHIgPSByLmlzc3VlcjsKCiAgICAgICAgaWYoci5zZXJpYWxOdW1iZXIgIT09IGNlcnQuc2VyaWFsTnVtYmVyKSB7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIGlmKHJBdHRyLmxlbmd0aCAhPT0gc0F0dHIubGVuZ3RoKSB7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIHZhciBtYXRjaCA9IHRydWU7CiAgICAgICAgZm9yKHZhciBqID0gMDsgaiA8IHNBdHRyLmxlbmd0aDsgKytqKSB7CiAgICAgICAgICBpZihyQXR0cltqXS50eXBlICE9PSBzQXR0cltqXS50eXBlIHx8CiAgICAgICAgICAgIHJBdHRyW2pdLnZhbHVlICE9PSBzQXR0cltqXS52YWx1ZSkgewogICAgICAgICAgICBtYXRjaCA9IGZhbHNlOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmKG1hdGNoKSB7CiAgICAgICAgICByZXR1cm4gcjsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHJldHVybiBudWxsOwogICAgfSwKCiAgICAvKioKICAgICAqIERlY3J5cHQgZW52ZWxvcGVkIGNvbnRlbnQKICAgICAqCiAgICAgKiBAcGFyYW0gcmVjaXBpZW50IFRoZSByZWNpcGllbnQgb2JqZWN0IHJlbGF0ZWQgdG8gdGhlIHByaXZhdGUga2V5CiAgICAgKiBAcGFyYW0gcHJpdktleSBUaGUgKFJTQSkgcHJpdmF0ZSBrZXkgb2JqZWN0CiAgICAgKi8KICAgIGRlY3J5cHQ6IGZ1bmN0aW9uKHJlY2lwaWVudCwgcHJpdktleSkgewogICAgICBpZihtc2cuZW5jcnlwdGVkQ29udGVudC5rZXkgPT09IHVuZGVmaW5lZCAmJiByZWNpcGllbnQgIT09IHVuZGVmaW5lZCAmJgogICAgICAgIHByaXZLZXkgIT09IHVuZGVmaW5lZCkgewogICAgICAgIHN3aXRjaChyZWNpcGllbnQuZW5jcnlwdGVkQ29udGVudC5hbGdvcml0aG0pIHsKICAgICAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHMucnNhRW5jcnlwdGlvbjoKICAgICAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHMuZGVzQ0JDOgogICAgICAgICAgICB2YXIga2V5ID0gcHJpdktleS5kZWNyeXB0KHJlY2lwaWVudC5lbmNyeXB0ZWRDb250ZW50LmNvbnRlbnQpOwogICAgICAgICAgICBtc2cuZW5jcnlwdGVkQ29udGVudC5rZXkgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihrZXkpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGFzeW1tZXRyaWMgY2lwaGVyLCAnICsKICAgICAgICAgICAgICAnT0lEICcgKyByZWNpcGllbnQuZW5jcnlwdGVkQ29udGVudC5hbGdvcml0aG0pOwogICAgICAgIH0KICAgICAgfQoKICAgICAgX2RlY3J5cHRDb250ZW50KG1zZyk7CiAgICB9LAoKICAgIC8qKgogICAgICogQWRkIChhbm90aGVyKSBlbnRpdHkgdG8gbGlzdCBvZiByZWNpcGllbnRzLgogICAgICoKICAgICAqIEBwYXJhbSBjZXJ0IFRoZSBjZXJ0aWZpY2F0ZSBvZiB0aGUgZW50aXR5IHRvIGFkZC4KICAgICAqLwogICAgYWRkUmVjaXBpZW50OiBmdW5jdGlvbihjZXJ0KSB7CiAgICAgIG1zZy5yZWNpcGllbnRzLnB1c2goewogICAgICAgIHZlcnNpb246IDAsCiAgICAgICAgaXNzdWVyOiBjZXJ0Lmlzc3Vlci5hdHRyaWJ1dGVzLAogICAgICAgIHNlcmlhbE51bWJlcjogY2VydC5zZXJpYWxOdW1iZXIsCiAgICAgICAgZW5jcnlwdGVkQ29udGVudDogewogICAgICAgICAgLy8gV2Ugc2ltcGx5IGFzc3VtZSByc2FFbmNyeXB0aW9uIGhlcmUsIHNpbmNlIGZvcmdlLnBraSBvbmx5CiAgICAgICAgICAvLyBzdXBwb3J0cyBSU0Egc28gZmFyLiAgSWYgdGhlIFBLSSBtb2R1bGUgc3VwcG9ydHMgb3RoZXIKICAgICAgICAgIC8vIGNpcGhlcnMgb25lIGRheSwgd2UgbmVlZCB0byBtb2RpZnkgdGhpcyBvbmUgYXMgd2VsbC4KICAgICAgICAgIGFsZ29yaXRobTogZm9yZ2UucGtpLm9pZHMucnNhRW5jcnlwdGlvbiwKICAgICAgICAgIGtleTogY2VydC5wdWJsaWNLZXkKICAgICAgICB9CiAgICAgIH0pOwogICAgfSwKCiAgICAvKioKICAgICAqIEVuY3J5cHQgZW52ZWxvcGVkIGNvbnRlbnQuCiAgICAgKgogICAgICogVGhpcyBmdW5jdGlvbiBzdXBwb3J0cyB0d28gb3B0aW9uYWwgYXJndW1lbnRzLCBjaXBoZXIgYW5kIGtleSwgd2hpY2gKICAgICAqIGNhbiBiZSB1c2VkIHRvIGluZmx1ZW5jZSBzeW1tZXRyaWMgZW5jcnlwdGlvbi4gIFVubGVzcyBjaXBoZXIgaXMKICAgICAqIHByb3ZpZGVkLCB0aGUgY2lwaGVyIHNwZWNpZmllZCBpbiBlbmNyeXB0ZWRDb250ZW50LmFsZ29yaXRobSBpcyB1c2VkCiAgICAgKiAoZGVmYXVsdHMgdG8gQUVTLTI1Ni1DQkMpLiAgSWYgbm8ga2V5IGlzIHByb3ZpZGVkLCBlbmNyeXB0ZWRDb250ZW50LmtleQogICAgICogaXMgKHJlLSl1c2VkLiAgSWYgdGhhdCBvbmUncyBub3Qgc2V0LCBhIHJhbmRvbSBrZXkgd2lsbCBiZSBnZW5lcmF0ZWQKICAgICAqIGF1dG9tYXRpY2FsbHkuCiAgICAgKgogICAgICogQHBhcmFtIFtrZXldIFRoZSBrZXkgdG8gYmUgdXNlZCBmb3Igc3ltbWV0cmljIGVuY3J5cHRpb24uCiAgICAgKiBAcGFyYW0gW2NpcGhlcl0gVGhlIE9JRCBvZiB0aGUgc3ltbWV0cmljIGNpcGhlciB0byB1c2UuCiAgICAgKi8KICAgIGVuY3J5cHQ6IGZ1bmN0aW9uKGtleSwgY2lwaGVyKSB7CiAgICAgIC8vIFBhcnQgMTogU3ltbWV0cmljIGVuY3J5cHRpb24KICAgICAgaWYobXNnLmVuY3J5cHRlZENvbnRlbnQuY29udGVudCA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgY2lwaGVyID0gY2lwaGVyIHx8IG1zZy5lbmNyeXB0ZWRDb250ZW50LmFsZ29yaXRobTsKICAgICAgICBrZXkgPSBrZXkgfHwgbXNnLmVuY3J5cHRlZENvbnRlbnQua2V5OwoKICAgICAgICB2YXIga2V5TGVuLCBpdkxlbiwgY2lwaEZuOwogICAgICAgIHN3aXRjaChjaXBoZXIpIHsKICAgICAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHNbJ2FlczEyOC1DQkMnXToKICAgICAgICAgICAga2V5TGVuID0gMTY7CiAgICAgICAgICAgIGl2TGVuID0gMTY7CiAgICAgICAgICAgIGNpcGhGbiA9IGZvcmdlLmFlcy5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICBjYXNlIGZvcmdlLnBraS5vaWRzWydhZXMxOTItQ0JDJ106CiAgICAgICAgICAgIGtleUxlbiA9IDI0OwogICAgICAgICAgICBpdkxlbiA9IDE2OwogICAgICAgICAgICBjaXBoRm4gPSBmb3JnZS5hZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgY2FzZSBmb3JnZS5wa2kub2lkc1snYWVzMjU2LUNCQyddOgogICAgICAgICAgICBrZXlMZW4gPSAzMjsKICAgICAgICAgICAgaXZMZW4gPSAxNjsKICAgICAgICAgICAgY2lwaEZuID0gZm9yZ2UuYWVzLmNyZWF0ZUVuY3J5cHRpb25DaXBoZXI7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHNbJ2Rlcy1FREUzLUNCQyddOgogICAgICAgICAgICBrZXlMZW4gPSAyNDsKICAgICAgICAgICAgaXZMZW4gPSA4OwogICAgICAgICAgICBjaXBoRm4gPSBmb3JnZS5kZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBzeW1tZXRyaWMgY2lwaGVyLCBPSUQgJyArIGNpcGhlcik7CiAgICAgICAgfQoKICAgICAgICBpZihrZXkgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAga2V5ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoZm9yZ2UucmFuZG9tLmdldEJ5dGVzKGtleUxlbikpOwogICAgICAgIH0gZWxzZSBpZihrZXkubGVuZ3RoKCkgIT0ga2V5TGVuKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N5bW1ldHJpYyBrZXkgaGFzIHdyb25nIGxlbmd0aDsgJyArCiAgICAgICAgICAgICdnb3QgJyArIGtleS5sZW5ndGgoKSArICcgYnl0ZXMsIGV4cGVjdGVkICcgKyBrZXlMZW4gKyAnLicpOwogICAgICAgIH0KCiAgICAgICAgLy8gS2VlcCBhIGNvcHkgb2YgdGhlIGtleSAmIElWIGluIHRoZSBvYmplY3QsIHNvIHRoZSBjYWxsZXIgY2FuCiAgICAgICAgLy8gdXNlIGl0IGZvciB3aGF0ZXZlciByZWFzb24uCiAgICAgICAgbXNnLmVuY3J5cHRlZENvbnRlbnQuYWxnb3JpdGhtID0gY2lwaGVyOwogICAgICAgIG1zZy5lbmNyeXB0ZWRDb250ZW50LmtleSA9IGtleTsKICAgICAgICBtc2cuZW5jcnlwdGVkQ29udGVudC5wYXJhbWV0ZXIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigKICAgICAgICAgIGZvcmdlLnJhbmRvbS5nZXRCeXRlcyhpdkxlbikpOwoKICAgICAgICB2YXIgY2lwaCA9IGNpcGhGbihrZXkpOwogICAgICAgIGNpcGguc3RhcnQobXNnLmVuY3J5cHRlZENvbnRlbnQucGFyYW1ldGVyLmNvcHkoKSk7CiAgICAgICAgY2lwaC51cGRhdGUobXNnLmNvbnRlbnQpOwoKICAgICAgICAvLyBUaGUgZmluaXNoIGZ1bmN0aW9uIGRvZXMgUEtDUyM3IHBhZGRpbmcgYnkgZGVmYXVsdCwgdGhlcmVmb3JlCiAgICAgICAgLy8gbm8gYWN0aW9uIHJlcXVpcmVkIGJ5IHVzLgogICAgICAgIGlmKCFjaXBoLmZpbmlzaCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N5bW1ldHJpYyBlbmNyeXB0aW9uIGZhaWxlZC4nKTsKICAgICAgICB9CgogICAgICAgIG1zZy5lbmNyeXB0ZWRDb250ZW50LmNvbnRlbnQgPSBjaXBoLm91dHB1dDsKICAgICAgfQoKICAgICAgLy8gUGFydCAyOiBhc3ltbWV0cmljIGVuY3J5cHRpb24gZm9yIGVhY2ggcmVjaXBpZW50CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtc2cucmVjaXBpZW50cy5sZW5ndGg7ICsraSkgewogICAgICAgIHZhciByZWNpcGllbnQgPSBtc2cucmVjaXBpZW50c1tpXTsKCiAgICAgICAgLy8gTm90aGluZyB0byBkbywgZW5jcnlwdGlvbiBhbHJlYWR5IGRvbmUuCiAgICAgICAgaWYocmVjaXBpZW50LmVuY3J5cHRlZENvbnRlbnQuY29udGVudCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIHN3aXRjaChyZWNpcGllbnQuZW5jcnlwdGVkQ29udGVudC5hbGdvcml0aG0pIHsKICAgICAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHMucnNhRW5jcnlwdGlvbjoKICAgICAgICAgICAgcmVjaXBpZW50LmVuY3J5cHRlZENvbnRlbnQuY29udGVudCA9CiAgICAgICAgICAgICAgcmVjaXBpZW50LmVuY3J5cHRlZENvbnRlbnQua2V5LmVuY3J5cHQoCiAgICAgICAgICAgICAgICBtc2cuZW5jcnlwdGVkQ29udGVudC5rZXkuZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgYXN5bW1ldHJpYyBjaXBoZXIsIE9JRCAnICsKICAgICAgICAgICAgICByZWNpcGllbnQuZW5jcnlwdGVkQ29udGVudC5hbGdvcml0aG0pOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH07CiAgcmV0dXJuIG1zZzsKfTsKCi8qKgogKiBDb252ZXJ0cyBhIHNpbmdsZSByZWNpcGllbnQgZnJvbSBhbiBBU04uMSBvYmplY3QuCiAqCiAqIEBwYXJhbSBvYmogdGhlIEFTTi4xIFJlY2lwaWVudEluZm8uCiAqCiAqIEByZXR1cm4gdGhlIHJlY2lwaWVudCBvYmplY3QuCiAqLwpmdW5jdGlvbiBfcmVjaXBpZW50RnJvbUFzbjEob2JqKSB7CiAgLy8gdmFsaWRhdGUgRW52ZWxvcGVkRGF0YSBjb250ZW50IGJsb2NrIGFuZCBjYXB0dXJlIGRhdGEKICB2YXIgY2FwdHVyZSA9IHt9OwogIHZhciBlcnJvcnMgPSBbXTsKICBpZighYXNuMS52YWxpZGF0ZShvYmosIHA3LmFzbjEucmVjaXBpZW50SW5mb1ZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzcgUmVjaXBpZW50SW5mby4gJyArCiAgICAgICdBU04uMSBvYmplY3QgaXMgbm90IGFuIFBLQ1MjNyBSZWNpcGllbnRJbmZvLicpOwogICAgZXJyb3IuZXJyb3JzID0gZXJyb3JzOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICByZXR1cm4gewogICAgdmVyc2lvbjogY2FwdHVyZS52ZXJzaW9uLmNoYXJDb2RlQXQoMCksCiAgICBpc3N1ZXI6IGZvcmdlLnBraS5SRE5BdHRyaWJ1dGVzQXNBcnJheShjYXB0dXJlLmlzc3VlciksCiAgICBzZXJpYWxOdW1iZXI6IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUuc2VyaWFsKS50b0hleCgpLAogICAgZW5jcnlwdGVkQ29udGVudDogewogICAgICBhbGdvcml0aG06IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5lbmNBbGdvcml0aG0pLAogICAgICBwYXJhbWV0ZXI6IGNhcHR1cmUuZW5jUGFyYW1ldGVyLnZhbHVlLAogICAgICBjb250ZW50OiBjYXB0dXJlLmVuY0tleQogICAgfQogIH07Cn0KCi8qKgogKiBDb252ZXJ0cyBhIHNpbmdsZSByZWNpcGllbnQgb2JqZWN0IHRvIGFuIEFTTi4xIG9iamVjdC4KICoKICogQHBhcmFtIG9iaiB0aGUgcmVjaXBpZW50IG9iamVjdC4KICoKICogQHJldHVybiB0aGUgQVNOLjEgUmVjaXBpZW50SW5mby4KICovCmZ1bmN0aW9uIF9yZWNpcGllbnRUb0FzbjEob2JqKSB7CiAgcmV0dXJuIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgIC8vIFZlcnNpb24KICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgIGFzbjEuaW50ZWdlclRvRGVyKG9iai52ZXJzaW9uKS5nZXRCeXRlcygpKSwKICAgIC8vIElzc3VlckFuZFNlcmlhbE51bWJlcgogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAvLyBOYW1lCiAgICAgIGZvcmdlLnBraS5kaXN0aW5ndWlzaGVkTmFtZVRvQXNuMSh7YXR0cmlidXRlczogb2JqLmlzc3Vlcn0pLAogICAgICAvLyBTZXJpYWwKICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgICBmb3JnZS51dGlsLmhleFRvQnl0ZXMob2JqLnNlcmlhbE51bWJlcikpCiAgICBdKSwKICAgIC8vIEtleUVuY3J5cHRpb25BbGdvcml0aG1JZGVudGlmaWVyCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIEFsZ29yaXRobQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgYXNuMS5vaWRUb0RlcihvYmouZW5jcnlwdGVkQ29udGVudC5hbGdvcml0aG0pLmdldEJ5dGVzKCkpLAogICAgICAvLyBQYXJhbWV0ZXIsIGZvcmNlIE5VTEwsIG9ubHkgUlNBIHN1cHBvcnRlZCBmb3Igbm93LgogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgIF0pLAogICAgLy8gRW5jcnlwdGVkS2V5CiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLCBmYWxzZSwKICAgICAgb2JqLmVuY3J5cHRlZENvbnRlbnQuY29udGVudCkKICBdKTsKfQoKLyoqCiAqIE1hcCBhIHNldCBvZiBSZWNpcGllbnRJbmZvIEFTTi4xIG9iamVjdHMgdG8gcmVjaXBpZW50IG9iamVjdHMuCiAqCiAqIEBwYXJhbSBpbmZvcyBhbiBhcnJheSBvZiBBU04uMSByZXByZXNlbnRhdGlvbnMgUmVjaXBpZW50SW5mbyAoaS5lLiBTRVQgT0YpLgogKgogKiBAcmV0dXJuIGFuIGFycmF5IG9mIHJlY2lwaWVudCBvYmplY3RzLgogKi8KZnVuY3Rpb24gX3JlY2lwaWVudHNGcm9tQXNuMShpbmZvcykgewogIHZhciByZXQgPSBbXTsKICBmb3IodmFyIGkgPSAwOyBpIDwgaW5mb3MubGVuZ3RoOyArK2kpIHsKICAgIHJldC5wdXNoKF9yZWNpcGllbnRGcm9tQXNuMShpbmZvc1tpXSkpOwogIH0KICByZXR1cm4gcmV0Owp9CgovKioKICogTWFwIGFuIGFycmF5IG9mIHJlY2lwaWVudCBvYmplY3RzIHRvIEFTTi4xIFJlY2lwaWVudEluZm8gb2JqZWN0cy4KICoKICogQHBhcmFtIHJlY2lwaWVudHMgYW4gYXJyYXkgb2YgcmVjaXBpZW50SW5mbyBvYmplY3RzLgogKgogKiBAcmV0dXJuIGFuIGFycmF5IG9mIEFTTi4xIFJlY2lwaWVudEluZm9zLgogKi8KZnVuY3Rpb24gX3JlY2lwaWVudHNUb0FzbjEocmVjaXBpZW50cykgewogIHZhciByZXQgPSBbXTsKICBmb3IodmFyIGkgPSAwOyBpIDwgcmVjaXBpZW50cy5sZW5ndGg7ICsraSkgewogICAgcmV0LnB1c2goX3JlY2lwaWVudFRvQXNuMShyZWNpcGllbnRzW2ldKSk7CiAgfQogIHJldHVybiByZXQ7Cn0KCi8qKgogKiBDb252ZXJ0cyBhIHNpbmdsZSBzaWduZXIgZnJvbSBhbiBBU04uMSBvYmplY3QuCiAqCiAqIEBwYXJhbSBvYmogdGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIGEgU2lnbmVySW5mby4KICoKICogQHJldHVybiB0aGUgc2lnbmVyIG9iamVjdC4KICovCmZ1bmN0aW9uIF9zaWduZXJGcm9tQXNuMShvYmopIHsKICAvLyB2YWxpZGF0ZSBFbnZlbG9wZWREYXRhIGNvbnRlbnQgYmxvY2sgYW5kIGNhcHR1cmUgZGF0YQogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgcDcuYXNuMS5zaWduZXJJbmZvVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIFBLQ1MjNyBTaWduZXJJbmZvLiAnICsKICAgICAgJ0FTTi4xIG9iamVjdCBpcyBub3QgYW4gUEtDUyM3IFNpZ25lckluZm8uJyk7CiAgICBlcnJvci5lcnJvcnMgPSBlcnJvcnM7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIHZhciBydmFsID0gewogICAgdmVyc2lvbjogY2FwdHVyZS52ZXJzaW9uLmNoYXJDb2RlQXQoMCksCiAgICBpc3N1ZXI6IGZvcmdlLnBraS5SRE5BdHRyaWJ1dGVzQXNBcnJheShjYXB0dXJlLmlzc3VlciksCiAgICBzZXJpYWxOdW1iZXI6IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUuc2VyaWFsKS50b0hleCgpLAogICAgZGlnZXN0QWxnb3JpdGhtOiBhc24xLmRlclRvT2lkKGNhcHR1cmUuZGlnZXN0QWxnb3JpdGhtKSwKICAgIHNpZ25hdHVyZUFsZ29yaXRobTogYXNuMS5kZXJUb09pZChjYXB0dXJlLnNpZ25hdHVyZUFsZ29yaXRobSksCiAgICBzaWduYXR1cmU6IGNhcHR1cmUuc2lnbmF0dXJlLAogICAgYXV0aGVudGljYXRlZEF0dHJpYnV0ZXM6IFtdLAogICAgdW5hdXRoZW50aWNhdGVkQXR0cmlidXRlczogW10KICB9OwoKICAvLyBUT0RPOiBjb252ZXJ0IGF0dHJpYnV0ZXMKICB2YXIgYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgPSBjYXB0dXJlLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIHx8IFtdOwogIHZhciB1bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzID0gY2FwdHVyZS51bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIHx8IFtdOwoKICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIENvbnZlcnRzIGEgc2luZ2xlIHNpZ25lckluZm8gb2JqZWN0IHRvIGFuIEFTTi4xIG9iamVjdC4KICoKICogQHBhcmFtIG9iaiB0aGUgc2lnbmVySW5mbyBvYmplY3QuCiAqCiAqIEByZXR1cm4gdGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIGEgU2lnbmVySW5mby4KICovCmZ1bmN0aW9uIF9zaWduZXJUb0FzbjEob2JqKSB7CiAgLy8gU2lnbmVySW5mbwogIHZhciBydmFsID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgLy8gdmVyc2lvbgogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIob2JqLnZlcnNpb24pLmdldEJ5dGVzKCkpLAogICAgLy8gaXNzdWVyQW5kU2VyaWFsTnVtYmVyCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIG5hbWUKICAgICAgZm9yZ2UucGtpLmRpc3Rpbmd1aXNoZWROYW1lVG9Bc24xKHthdHRyaWJ1dGVzOiBvYmouaXNzdWVyfSksCiAgICAgIC8vIHNlcmlhbAogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICAgIGZvcmdlLnV0aWwuaGV4VG9CeXRlcyhvYmouc2VyaWFsTnVtYmVyKSkKICAgIF0pLAogICAgLy8gZGlnZXN0QWxnb3JpdGhtCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIGFsZ29yaXRobQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgYXNuMS5vaWRUb0RlcihvYmouZGlnZXN0QWxnb3JpdGhtKS5nZXRCeXRlcygpKSwKICAgICAgLy8gcGFyYW1ldGVycyAobnVsbCkKICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5OVUxMLCBmYWxzZSwgJycpCiAgICBdKQogIF0pOwoKICAvLyBhdXRoZW50aWNhdGVkQXR0cmlidXRlcyAoT1BUSU9OQUwpCiAgaWYob2JqLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzQXNuMSkgewogICAgLy8gYWRkIEFTTi4xIHByZXZpb3VzbHkgZ2VuZXJhdGVkIGR1cmluZyBzaWduaW5nCiAgICBydmFsLnZhbHVlLnB1c2gob2JqLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzQXNuMSk7CiAgfQoKICAvLyBkaWdlc3RFbmNyeXB0aW9uQWxnb3JpdGhtCiAgcnZhbC52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgIC8vIGFsZ29yaXRobQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICBhc24xLm9pZFRvRGVyKG9iai5zaWduYXR1cmVBbGdvcml0aG0pLmdldEJ5dGVzKCkpLAogICAgLy8gcGFyYW1ldGVycyAobnVsbCkKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuTlVMTCwgZmFsc2UsICcnKQogIF0pKTsKCiAgLy8gZW5jcnlwdGVkRGlnZXN0CiAgcnZhbC52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsIG9iai5zaWduYXR1cmUpKTsKCiAgLy8gdW5hdXRoZW50aWNhdGVkQXR0cmlidXRlcyAoT1BUSU9OQUwpCiAgaWYob2JqLnVuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMubGVuZ3RoID4gMCkgewogICAgLy8gWzFdIElNUExJQ0lUCiAgICB2YXIgYXR0cnNBc24xID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAxLCB0cnVlLCBbXSk7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgb2JqLnVuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMubGVuZ3RoOyArK2kpIHsKICAgICAgdmFyIGF0dHIgPSBvYmoudW5hdXRoZW50aWNhdGVkQXR0cmlidXRlc1tpXTsKICAgICAgYXR0cnNBc24xLnZhbHVlcy5wdXNoKF9hdHRyaWJ1dGVUb0FzbjEoYXR0cikpOwogICAgfQogICAgcnZhbC52YWx1ZS5wdXNoKGF0dHJzQXNuMSk7CiAgfQoKICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIE1hcCBhIHNldCBvZiBTaWduZXJJbmZvIEFTTi4xIG9iamVjdHMgdG8gYW4gYXJyYXkgb2Ygc2lnbmVyIG9iamVjdHMuCiAqCiAqIEBwYXJhbSBzaWduZXJJbmZvQXNuMXMgYW4gYXJyYXkgb2YgQVNOLjEgU2lnbmVySW5mb3MgKGkuZS4gU0VUIE9GKS4KICoKICogQHJldHVybiBhbiBhcnJheSBvZiBzaWduZXJzIG9iamVjdHMuCiAqLwpmdW5jdGlvbiBfc2lnbmVyc0Zyb21Bc24xKHNpZ25lckluZm9Bc24xcykgewogIHZhciByZXQgPSBbXTsKICBmb3IodmFyIGkgPSAwOyBpIDwgc2lnbmVySW5mb0FzbjFzLmxlbmd0aDsgKytpKSB7CiAgICByZXQucHVzaChfc2lnbmVyRnJvbUFzbjEoc2lnbmVySW5mb0FzbjFzW2ldKSk7CiAgfQogIHJldHVybiByZXQ7Cn0KCi8qKgogKiBNYXAgYW4gYXJyYXkgb2Ygc2lnbmVyIG9iamVjdHMgdG8gQVNOLjEgb2JqZWN0cy4KICoKICogQHBhcmFtIHNpZ25lcnMgYW4gYXJyYXkgb2Ygc2lnbmVyIG9iamVjdHMuCiAqCiAqIEByZXR1cm4gYW4gYXJyYXkgb2YgQVNOLjEgU2lnbmVySW5mb3MuCiAqLwpmdW5jdGlvbiBfc2lnbmVyc1RvQXNuMShzaWduZXJzKSB7CiAgdmFyIHJldCA9IFtdOwogIGZvcih2YXIgaSA9IDA7IGkgPCBzaWduZXJzLmxlbmd0aDsgKytpKSB7CiAgICByZXQucHVzaChfc2lnbmVyVG9Bc24xKHNpZ25lcnNbaV0pKTsKICB9CiAgcmV0dXJuIHJldDsKfQoKLyoqCiAqIENvbnZlcnQgYW4gYXR0cmlidXRlIG9iamVjdCB0byBhbiBBU04uMSBBdHRyaWJ1dGUuCiAqCiAqIEBwYXJhbSBhdHRyIHRoZSBhdHRyaWJ1dGUgb2JqZWN0LgogKgogKiBAcmV0dXJuIHRoZSBBU04uMSBBdHRyaWJ1dGUuCiAqLwpmdW5jdGlvbiBfYXR0cmlidXRlVG9Bc24xKGF0dHIpIHsKICB2YXIgdmFsdWU7CgogIC8vIFRPRE86IGdlbmVyYWxpemUgdG8gc3VwcG9ydCBtb3JlIGF0dHJpYnV0ZXMKICBpZihhdHRyLnR5cGUgPT09IGZvcmdlLnBraS5vaWRzLmNvbnRlbnRUeXBlKSB7CiAgICB2YWx1ZSA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgYXNuMS5vaWRUb0RlcihhdHRyLnZhbHVlKS5nZXRCeXRlcygpKTsKICB9IGVsc2UgaWYoYXR0ci50eXBlID09PSBmb3JnZS5wa2kub2lkcy5tZXNzYWdlRGlnZXN0KSB7CiAgICB2YWx1ZSA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLAogICAgICBhdHRyLnZhbHVlLmJ5dGVzKCkpOwogIH0gZWxzZSBpZihhdHRyLnR5cGUgPT09IGZvcmdlLnBraS5vaWRzLnNpZ25pbmdUaW1lKSB7CiAgICAvKiBOb3RlIHBlciBSRkMgMjk4NTogRGF0ZXMgYmV0d2VlbiAxIEphbnVhcnkgMTk1MCBhbmQgMzEgRGVjZW1iZXIgMjA0OQogICAgICAoaW5jbHVzaXZlKSBNVVNUIGJlIGVuY29kZWQgYXMgVVRDVGltZS4gQW55IGRhdGVzIHdpdGggeWVhciB2YWx1ZXMKICAgICAgYmVmb3JlIDE5NTAgb3IgYWZ0ZXIgMjA0OSBNVVNUIGJlIGVuY29kZWQgYXMgR2VuZXJhbGl6ZWRUaW1lLiBbRnVydGhlcixdCiAgICAgIFVUQ1RpbWUgdmFsdWVzIE1VU1QgYmUgZXhwcmVzc2VkIGluIEdyZWVud2ljaCBNZWFuIFRpbWUgKFp1bHUpIGFuZCBNVVNUCiAgICAgIGluY2x1ZGUgc2Vjb25kcyAoaS5lLiwgdGltZXMgYXJlIFlZTU1EREhITU1TU1opLCBldmVuIHdoZXJlIHRoZQogICAgICBudW1iZXIgb2Ygc2Vjb25kcyBpcyB6ZXJvLiAgTWlkbmlnaHQgKEdNVCkgbXVzdCBiZSByZXByZXNlbnRlZCBhcwogICAgICAiWVlNTUREMDAwMDAwWiIuICovCiAgICAvLyBUT0RPOiBtYWtlIHRoZXNlIG1vZHVsZS1sZXZlbCBjb25zdGFudHMKICAgIHZhciBqYW5fMV8xOTUwID0gbmV3IERhdGUoJ0phbiAxLCAxOTUwIDAwOjAwOjAwWicpOwogICAgdmFyIGphbl8xXzIwNTAgPSBuZXcgRGF0ZSgnSmFuIDEsIDIwNTAgMDA6MDA6MDBaJyk7CiAgICB2YXIgZGF0ZSA9IGF0dHIudmFsdWU7CiAgICBpZih0eXBlb2YgZGF0ZSA9PT0gJ3N0cmluZycpIHsKICAgICAgLy8gdHJ5IHRvIHBhcnNlIGRhdGUKICAgICAgdmFyIHRpbWVzdGFtcCA9IERhdGUucGFyc2UoZGF0ZSk7CiAgICAgIGlmKCFpc05hTih0aW1lc3RhbXApKSB7CiAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKHRpbWVzdGFtcCk7CiAgICAgIH0gZWxzZSBpZihkYXRlLmxlbmd0aCA9PT0gMTMpIHsKICAgICAgICAvLyBZWU1NRERISE1NU1NaICgxMyBjaGFycyBmb3IgVVRDVGltZSkKICAgICAgICBkYXRlID0gYXNuMS51dGNUaW1lVG9EYXRlKGRhdGUpOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIGFzc3VtZSBnZW5lcmFsaXplZCB0aW1lCiAgICAgICAgZGF0ZSA9IGFzbjEuZ2VuZXJhbGl6ZWRUaW1lVG9EYXRlKGRhdGUpOwogICAgICB9CiAgICB9CgogICAgaWYoZGF0ZSA+PSBqYW5fMV8xOTUwICYmIGRhdGUgPCBqYW5fMV8yMDUwKSB7CiAgICAgIHZhbHVlID0gYXNuMS5jcmVhdGUoCiAgICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5VVENUSU1FLCBmYWxzZSwKICAgICAgICBhc24xLmRhdGVUb1V0Y1RpbWUoZGF0ZSkpOwogICAgfSBlbHNlIHsKICAgICAgdmFsdWUgPSBhc24xLmNyZWF0ZSgKICAgICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLkdFTkVSQUxJWkVEVElNRSwgZmFsc2UsCiAgICAgICAgYXNuMS5kYXRlVG9HZW5lcmFsaXplZFRpbWUoZGF0ZSkpOwogICAgfQogIH0KCiAgLy8gVE9ETzogZXhwb3NlIGFzIGNvbW1vbiBBUEkgY2FsbAogIC8vIGNyZWF0ZSBhIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUgc2V0CiAgLy8gZWFjaCB2YWx1ZSBpbiB0aGUgc2V0IGlzIGFuIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZSBmaXJzdAogIC8vIGNvbnRhaW5pbmcgdGhlIHR5cGUgKGFuIE9JRCkgYW5kIHNlY29uZCB0aGUgdmFsdWUKICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgLy8gQXR0cmlidXRlVHlwZQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICBhc24xLm9pZFRvRGVyKGF0dHIudHlwZSkuZ2V0Qnl0ZXMoKSksCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFVCwgdHJ1ZSwgWwogICAgICAvLyBBdHRyaWJ1dGVWYWx1ZQogICAgICB2YWx1ZQogICAgXSkKICBdKTsKfQoKLyoqCiAqIE1hcCBtZXNzYWdlcyBlbmNyeXB0ZWQgY29udGVudCB0byBBU04uMSBvYmplY3RzLgogKgogKiBAcGFyYW0gZWMgVGhlIGVuY3J5cHRlZENvbnRlbnQgb2JqZWN0IG9mIHRoZSBtZXNzYWdlLgogKgogKiBAcmV0dXJuIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlbmNyeXB0ZWRDb250ZW50IG9iamVjdCAoU0VRVUVOQ0UpLgogKi8KZnVuY3Rpb24gX2VuY3J5cHRlZENvbnRlbnRUb0FzbjEoZWMpIHsKICByZXR1cm4gWwogICAgLy8gQ29udGVudFR5cGUsIGFsd2F5cyBEYXRhIGZvciB0aGUgbW9tZW50CiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgIGFzbjEub2lkVG9EZXIoZm9yZ2UucGtpLm9pZHMuZGF0YSkuZ2V0Qnl0ZXMoKSksCiAgICAvLyBDb250ZW50RW5jcnlwdGlvbkFsZ29yaXRobUlkZW50aWZpZXIKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgLy8gQWxnb3JpdGhtCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICBhc24xLm9pZFRvRGVyKGVjLmFsZ29yaXRobSkuZ2V0Qnl0ZXMoKSksCiAgICAgIC8vIFBhcmFtZXRlcnMgKElWKQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLCBmYWxzZSwKICAgICAgICBlYy5wYXJhbWV0ZXIuZ2V0Qnl0ZXMoKSkKICAgIF0pLAogICAgLy8gWzBdIEVuY3J5cHRlZENvbnRlbnQKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMCwgdHJ1ZSwgWwogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLCBmYWxzZSwKICAgICAgICBlYy5jb250ZW50LmdldEJ5dGVzKCkpCiAgICBdKQogIF07Cn0KCi8qKgogKiBSZWFkcyB0aGUgImNvbW1vbiBwYXJ0IiBvZiBhbiBQS0NTIzcgY29udGVudCBibG9jayAoaW4gQVNOLjEgZm9ybWF0KQogKgogKiBUaGlzIGZ1bmN0aW9uIHJlYWRzIHRoZSAiY29tbW9uIHBhcnQiIG9mIHRoZSBQS0NTIzcgY29udGVudCBibG9ja3MKICogRW5jcnlwdGVkRGF0YSBhbmQgRW52ZWxvcGVkRGF0YSwgaS5lLiB2ZXJzaW9uIG51bWJlciBhbmQgc3ltbWV0cmljYWxseQogKiBlbmNyeXB0ZWQgY29udGVudCBibG9jay4KICoKICogVGhlIHJlc3VsdCBvZiB0aGUgQVNOLjEgdmFsaWRhdGUgYW5kIGNhcHR1cmUgcHJvY2VzcyBpcyByZXR1cm5lZAogKiB0byBhbGxvdyB0aGUgY2FsbGVyIHRvIGV4dHJhY3QgZnVydGhlciBkYXRhLCBlLmcuIHRoZSBsaXN0IG9mIHJlY2lwaWVudHMKICogaW4gY2FzZSBvZiBhIEVudmVsb3BlZERhdGEgb2JqZWN0LgogKgogKiBAcGFyYW0gbXNnIHRoZSBQS0NTIzcgb2JqZWN0IHRvIHJlYWQgdGhlIGRhdGEgdG8uCiAqIEBwYXJhbSBvYmogdGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjb250ZW50IGJsb2NrLgogKiBAcGFyYW0gdmFsaWRhdG9yIHRoZSBBU04uMSBzdHJ1Y3R1cmUgdmFsaWRhdG9yIG9iamVjdCB0byB1c2UuCiAqCiAqIEByZXR1cm4gdGhlIHZhbHVlIG1hcCBjYXB0dXJlZCBieSB2YWxpZGF0b3Igb2JqZWN0LgogKi8KZnVuY3Rpb24gX2Zyb21Bc24xKG1zZywgb2JqLCB2YWxpZGF0b3IpIHsKICB2YXIgY2FwdHVyZSA9IHt9OwogIHZhciBlcnJvcnMgPSBbXTsKICBpZighYXNuMS52YWxpZGF0ZShvYmosIHZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzcgbWVzc2FnZS4gJyArCiAgICAgICdBU04uMSBvYmplY3QgaXMgbm90IGEgc3VwcG9ydGVkIFBLQ1MjNyBtZXNzYWdlLicpOwogICAgZXJyb3IuZXJyb3JzID0gZXJyb3I7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIC8vIENoZWNrIGNvbnRlbnRUeXBlLCBzbyBmYXIgd2Ugb25seSBzdXBwb3J0IChyYXcpIERhdGEuCiAgdmFyIGNvbnRlbnRUeXBlID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLmNvbnRlbnRUeXBlKTsKICBpZihjb250ZW50VHlwZSAhPT0gZm9yZ2UucGtpLm9pZHMuZGF0YSkgewogICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBQS0NTIzcgbWVzc2FnZS4gJyArCiAgICAgICdPbmx5IHdyYXBwZWQgQ29udGVudFR5cGUgRGF0YSBzdXBwb3J0ZWQuJyk7CiAgfQoKICBpZihjYXB0dXJlLmVuY3J5cHRlZENvbnRlbnQpIHsKICAgIHZhciBjb250ZW50ID0gJyc7CiAgICBpZihmb3JnZS51dGlsLmlzQXJyYXkoY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50KSkgewogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgaWYoY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50W2ldLnR5cGUgIT09IGFzbjEuVHlwZS5PQ1RFVFNUUklORykgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNYWxmb3JtZWQgUEtDUyM3IG1lc3NhZ2UsIGV4cGVjdGluZyBlbmNyeXB0ZWQgJyArCiAgICAgICAgICAgICdjb250ZW50IGNvbnN0cnVjdGVkIG9mIG9ubHkgT0NURVQgU1RSSU5HIG9iamVjdHMuJyk7CiAgICAgICAgfQogICAgICAgIGNvbnRlbnQgKz0gY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50W2ldLnZhbHVlOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBjb250ZW50ID0gY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50OwogICAgfQogICAgbXNnLmVuY3J5cHRlZENvbnRlbnQgPSB7CiAgICAgIGFsZ29yaXRobTogYXNuMS5kZXJUb09pZChjYXB0dXJlLmVuY0FsZ29yaXRobSksCiAgICAgIHBhcmFtZXRlcjogZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5lbmNQYXJhbWV0ZXIudmFsdWUpLAogICAgICBjb250ZW50OiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjb250ZW50KQogICAgfTsKICB9CgogIGlmKGNhcHR1cmUuY29udGVudCkgewogICAgdmFyIGNvbnRlbnQgPSAnJzsKICAgIGlmKGZvcmdlLnV0aWwuaXNBcnJheShjYXB0dXJlLmNvbnRlbnQpKSB7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBjYXB0dXJlLmNvbnRlbnQubGVuZ3RoOyArK2kpIHsKICAgICAgICBpZihjYXB0dXJlLmNvbnRlbnRbaV0udHlwZSAhPT0gYXNuMS5UeXBlLk9DVEVUU1RSSU5HKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01hbGZvcm1lZCBQS0NTIzcgbWVzc2FnZSwgZXhwZWN0aW5nICcgKwogICAgICAgICAgICAnY29udGVudCBjb25zdHJ1Y3RlZCBvZiBvbmx5IE9DVEVUIFNUUklORyBvYmplY3RzLicpOwogICAgICAgIH0KICAgICAgICBjb250ZW50ICs9IGNhcHR1cmUuY29udGVudFtpXS52YWx1ZTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgY29udGVudCA9IGNhcHR1cmUuY29udGVudDsKICAgIH0KICAgIG1zZy5jb250ZW50ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY29udGVudCk7CiAgfQoKICBtc2cudmVyc2lvbiA9IGNhcHR1cmUudmVyc2lvbi5jaGFyQ29kZUF0KDApOwogIG1zZy5yYXdDYXB0dXJlID0gY2FwdHVyZTsKCiAgcmV0dXJuIGNhcHR1cmU7Cn0KCi8qKgogKiBEZWNyeXB0IHRoZSBzeW1tZXRyaWNhbGx5IGVuY3J5cHRlZCBjb250ZW50IGJsb2NrIG9mIHRoZSBQS0NTIzcgbWVzc2FnZS4KICoKICogRGVjcnlwdGlvbiBpcyBza2lwcGVkIGluIGNhc2UgdGhlIFBLQ1MjNyBtZXNzYWdlIG9iamVjdCBhbHJlYWR5IGhhcyBhCiAqIChkZWNyeXB0ZWQpIGNvbnRlbnQgYXR0cmlidXRlLiAgVGhlIGFsZ29yaXRobSwga2V5IGFuZCBjaXBoZXIgcGFyYW1ldGVycwogKiAocHJvYmFibHkgdGhlIGl2KSBhcmUgdGFrZW4gZnJvbSB0aGUgZW5jcnlwdGVkQ29udGVudCBhdHRyaWJ1dGUgb2YgdGhlCiAqIG1lc3NhZ2Ugb2JqZWN0LgogKgogKiBAcGFyYW0gVGhlIFBLQ1MjNyBtZXNzYWdlIG9iamVjdC4KICovCmZ1bmN0aW9uIF9kZWNyeXB0Q29udGVudChtc2cpIHsKICBpZihtc2cuZW5jcnlwdGVkQ29udGVudC5rZXkgPT09IHVuZGVmaW5lZCkgewogICAgdGhyb3cgbmV3IEVycm9yKCdTeW1tZXRyaWMga2V5IG5vdCBhdmFpbGFibGUuJyk7CiAgfQoKICBpZihtc2cuY29udGVudCA9PT0gdW5kZWZpbmVkKSB7CiAgICB2YXIgY2lwaDsKCiAgICBzd2l0Y2gobXNnLmVuY3J5cHRlZENvbnRlbnQuYWxnb3JpdGhtKSB7CiAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHNbJ2FlczEyOC1DQkMnXToKICAgICAgY2FzZSBmb3JnZS5wa2kub2lkc1snYWVzMTkyLUNCQyddOgogICAgICBjYXNlIGZvcmdlLnBraS5vaWRzWydhZXMyNTYtQ0JDJ106CiAgICAgICAgY2lwaCA9IGZvcmdlLmFlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyKG1zZy5lbmNyeXB0ZWRDb250ZW50LmtleSk7CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIGZvcmdlLnBraS5vaWRzWydkZXNDQkMnXToKICAgICAgY2FzZSBmb3JnZS5wa2kub2lkc1snZGVzLUVERTMtQ0JDJ106CiAgICAgICAgY2lwaCA9IGZvcmdlLmRlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyKG1zZy5lbmNyeXB0ZWRDb250ZW50LmtleSk7CiAgICAgICAgYnJlYWs7CgogICAgICBkZWZhdWx0OgogICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgc3ltbWV0cmljIGNpcGhlciwgT0lEICcgKwogICAgICAgICAgbXNnLmVuY3J5cHRlZENvbnRlbnQuYWxnb3JpdGhtKTsKICAgIH0KICAgIGNpcGguc3RhcnQobXNnLmVuY3J5cHRlZENvbnRlbnQucGFyYW1ldGVyKTsKICAgIGNpcGgudXBkYXRlKG1zZy5lbmNyeXB0ZWRDb250ZW50LmNvbnRlbnQpOwoKICAgIGlmKCFjaXBoLmZpbmlzaCgpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignU3ltbWV0cmljIGRlY3J5cHRpb24gZmFpbGVkLicpOwogICAgfQoKICAgIG1zZy5jb250ZW50ID0gY2lwaC5vdXRwdXQ7CiAgfQp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdwa2NzNyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9wa2NzNycsWwogICdyZXF1aXJlJywKICAnbW9kdWxlJywKICAnLi9hZXMnLAogICcuL2FzbjEnLAogICcuL2RlcycsCiAgJy4vb2lkcycsCiAgJy4vcGVtJywKICAnLi9wa2NzN2FzbjEnLAogICcuL3JhbmRvbScsCiAgJy4vdXRpbCcsCiAgJy4veDUwOScKXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogRnVuY3Rpb25zIHRvIG91dHB1dCBrZXlzIGluIFNTSC1mcmllbmRseSBmb3JtYXRzLgogKgogKiBUaGlzIGlzIHBhcnQgb2YgdGhlIEZvcmdlIHByb2plY3Qgd2hpY2ggbWF5IGJlIHVzZWQgdW5kZXIgdGhlIHRlcm1zIG9mCiAqIGVpdGhlciB0aGUgQlNEIExpY2Vuc2Ugb3IgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIChHUEwpIFZlcnNpb24gMi4KICoKICogU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZGlnaXRhbGJhemFhci9mb3JnZS9ibG9iL2NiZWJjYTM3ODA2NTg3MDNkOTI1YjYxYjJjYWZmYjFkMjYzYTZjMWQvTElDRU5TRQogKgogKiBAYXV0aG9yIGh0dHBzOi8vZ2l0aHViLmNvbS9zaGVsbGFjCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKdmFyIHNzaCA9IGZvcmdlLnNzaCA9IGZvcmdlLnNzaCB8fCB7fTsKCi8qKgogKiBFbmNvZGVzIChhbmQgb3B0aW9uYWxseSBlbmNyeXB0cykgYSBwcml2YXRlIFJTQSBrZXkgYXMgYSBQdXR0eSBQUEsgZmlsZS4KICoKICogQHBhcmFtIHByaXZhdGVLZXkgdGhlIGtleS4KICogQHBhcmFtIHBhc3NwaHJhc2UgYSBwYXNzcGhyYXNlIHRvIHByb3RlY3QgdGhlIGtleSAoZmFsc3kgZm9yIG5vIGVuY3J5cHRpb24pLgogKiBAcGFyYW0gY29tbWVudCBhIGNvbW1lbnQgdG8gaW5jbHVkZSBpbiB0aGUga2V5IGZpbGUuCiAqCiAqIEByZXR1cm4gdGhlIFBQSyBmaWxlIGFzIGEgc3RyaW5nLgogKi8Kc3NoLnByaXZhdGVLZXlUb1B1dHR5ID0gZnVuY3Rpb24ocHJpdmF0ZUtleSwgcGFzc3BocmFzZSwgY29tbWVudCkgewogIGNvbW1lbnQgPSBjb21tZW50IHx8ICcnOwogIHBhc3NwaHJhc2UgPSBwYXNzcGhyYXNlIHx8ICcnOwogIHZhciBhbGdvcml0aG0gPSAnc3NoLXJzYSc7CiAgdmFyIGVuY3J5cHRpb25BbGdvcml0aG0gPSAocGFzc3BocmFzZSA9PT0gJycpID8gJ25vbmUnIDogJ2FlczI1Ni1jYmMnOwoKICB2YXIgcHBrID0gJ1B1VFRZLVVzZXItS2V5LUZpbGUtMjogJyArIGFsZ29yaXRobSArICdcclxuJzsKICBwcGsgKz0gJ0VuY3J5cHRpb246ICcgKyBlbmNyeXB0aW9uQWxnb3JpdGhtICsgJ1xyXG4nOwogIHBwayArPSAnQ29tbWVudDogJyArIGNvbW1lbnQgKyAnXHJcbic7CgogIC8vIHB1YmxpYyBrZXkgaW50byBidWZmZXIgZm9yIHBwawogIHZhciBwdWJidWZmZXIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIF9hZGRTdHJpbmdUb0J1ZmZlcihwdWJidWZmZXIsIGFsZ29yaXRobSk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihwdWJidWZmZXIsIHByaXZhdGVLZXkuZSk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihwdWJidWZmZXIsIHByaXZhdGVLZXkubik7CgogIC8vIHdyaXRlIHB1YmxpYyBrZXkKICB2YXIgcHViID0gZm9yZ2UudXRpbC5lbmNvZGU2NChwdWJidWZmZXIuYnl0ZXMoKSwgNjQpOwogIHZhciBsZW5ndGggPSBNYXRoLmZsb29yKHB1Yi5sZW5ndGggLyA2NikgKyAxOyAvLyA2NiA9IDY0ICsgXHJcbgogIHBwayArPSAnUHVibGljLUxpbmVzOiAnICsgbGVuZ3RoICsgJ1xyXG4nOwogIHBwayArPSBwdWI7CgogIC8vIHByaXZhdGUga2V5IGludG8gYSBidWZmZXIKICB2YXIgcHJpdmJ1ZmZlciA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihwcml2YnVmZmVyLCBwcml2YXRlS2V5LmQpOwogIF9hZGRCaWdJbnRlZ2VyVG9CdWZmZXIocHJpdmJ1ZmZlciwgcHJpdmF0ZUtleS5wKTsKICBfYWRkQmlnSW50ZWdlclRvQnVmZmVyKHByaXZidWZmZXIsIHByaXZhdGVLZXkucSk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihwcml2YnVmZmVyLCBwcml2YXRlS2V5LnFJbnYpOwoKICAvLyBvcHRpb25hbGx5IGVuY3J5cHQgdGhlIHByaXZhdGUga2V5CiAgdmFyIHByaXY7CiAgaWYoIXBhc3NwaHJhc2UpIHsKICAgIC8vIHVzZSB0aGUgdW5lbmNyeXB0ZWQgYnVmZmVyCiAgICBwcml2ID0gZm9yZ2UudXRpbC5lbmNvZGU2NChwcml2YnVmZmVyLmJ5dGVzKCksIDY0KTsKICB9IGVsc2UgewogICAgLy8gZW5jcnlwdCBSU0Ega2V5IHVzaW5nIHBhc3NwaHJhc2UKICAgIHZhciBlbmNMZW4gPSBwcml2YnVmZmVyLmxlbmd0aCgpICsgMTYgLSAxOwogICAgZW5jTGVuIC09IGVuY0xlbiAlIDE2OwoKICAgIC8vIHBhZCBwcml2YXRlIGtleSB3aXRoIHNoYTEtZCBkYXRhIC0tIG5lZWRzIHRvIGJlIGEgbXVsdGlwbGUgb2YgMTYKICAgIHZhciBwYWRkaW5nID0gX3NoYTEocHJpdmJ1ZmZlci5ieXRlcygpKTsKCiAgICBwYWRkaW5nLnRydW5jYXRlKHBhZGRpbmcubGVuZ3RoKCkgLSBlbmNMZW4gKyBwcml2YnVmZmVyLmxlbmd0aCgpKTsKICAgIHByaXZidWZmZXIucHV0QnVmZmVyKHBhZGRpbmcpOwoKICAgIHZhciBhZXNrZXkgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgYWVza2V5LnB1dEJ1ZmZlcihfc2hhMSgnXHgwMFx4MDBceDAwXHgwMCcsIHBhc3NwaHJhc2UpKTsKICAgIGFlc2tleS5wdXRCdWZmZXIoX3NoYTEoJ1x4MDBceDAwXHgwMFx4MDEnLCBwYXNzcGhyYXNlKSk7CgogICAgLy8gZW5jcnlwdCBzb21lIGJ5dGVzIHVzaW5nIENCQyBtb2RlCiAgICAvLyBrZXkgaXMgNDAgYnl0ZXMsIHNvIHRydW5jYXRlICpieSogOCBieXRlcwogICAgdmFyIGNpcGhlciA9IGZvcmdlLmFlcy5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyKGFlc2tleS50cnVuY2F0ZSg4KSwgJ0NCQycpOwogICAgY2lwaGVyLnN0YXJ0KGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCkuZmlsbFdpdGhCeXRlKDAsIDE2KSk7CiAgICBjaXBoZXIudXBkYXRlKHByaXZidWZmZXIuY29weSgpKTsKICAgIGNpcGhlci5maW5pc2goKTsKICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIub3V0cHV0OwoKICAgIC8vIE5vdGU6IHRoaXMgYXBwZWFycyB0byBkaWZmZXIgZnJvbSBQdXR0eSAtLSBpcyBmb3JnZSB3cm9uZywgb3IgcHV0dHk/CiAgICAvLyBkdWUgdG8gcGFkZGluZyB3ZSBmaW5pc2ggYXMgYW4gZXhhY3QgbXVsdGlwbGUgb2YgMTYKICAgIGVuY3J5cHRlZC50cnVuY2F0ZSgxNik7IC8vIGFsbCBwYWRkaW5nCgogICAgcHJpdiA9IGZvcmdlLnV0aWwuZW5jb2RlNjQoZW5jcnlwdGVkLmJ5dGVzKCksIDY0KTsKICB9CgogIC8vIG91dHB1dCBwcml2YXRlIGtleQogIGxlbmd0aCA9IE1hdGguZmxvb3IocHJpdi5sZW5ndGggLyA2NikgKyAxOyAvLyA2NCArIFxyXG4KICBwcGsgKz0gJ1xyXG5Qcml2YXRlLUxpbmVzOiAnICsgbGVuZ3RoICsgJ1xyXG4nOwogIHBwayArPSBwcml2OwoKICAvLyBNQUMKICB2YXIgbWFja2V5ID0gX3NoYTEoJ3B1dHR5LXByaXZhdGUta2V5LWZpbGUtbWFjLWtleScsIHBhc3NwaHJhc2UpOwoKICB2YXIgbWFjYnVmZmVyID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBfYWRkU3RyaW5nVG9CdWZmZXIobWFjYnVmZmVyLCBhbGdvcml0aG0pOwogIF9hZGRTdHJpbmdUb0J1ZmZlcihtYWNidWZmZXIsIGVuY3J5cHRpb25BbGdvcml0aG0pOwogIF9hZGRTdHJpbmdUb0J1ZmZlcihtYWNidWZmZXIsIGNvbW1lbnQpOwogIG1hY2J1ZmZlci5wdXRJbnQzMihwdWJidWZmZXIubGVuZ3RoKCkpOwogIG1hY2J1ZmZlci5wdXRCdWZmZXIocHViYnVmZmVyKTsKICBtYWNidWZmZXIucHV0SW50MzIocHJpdmJ1ZmZlci5sZW5ndGgoKSk7CiAgbWFjYnVmZmVyLnB1dEJ1ZmZlcihwcml2YnVmZmVyKTsKCiAgdmFyIGhtYWMgPSBmb3JnZS5obWFjLmNyZWF0ZSgpOwogIGhtYWMuc3RhcnQoJ3NoYTEnLCBtYWNrZXkpOwogIGhtYWMudXBkYXRlKG1hY2J1ZmZlci5ieXRlcygpKTsKCiAgcHBrICs9ICdcclxuUHJpdmF0ZS1NQUM6ICcgKyBobWFjLmRpZ2VzdCgpLnRvSGV4KCkgKyAnXHJcbic7CgogIHJldHVybiBwcGs7Cn07CgovKioKICogRW5jb2RlcyBhIHB1YmxpYyBSU0Ega2V5IGFzIGFuIE9wZW5TU0ggZmlsZS4KICoKICogQHBhcmFtIGtleSB0aGUga2V5LgogKiBAcGFyYW0gY29tbWVudCBhIGNvbW1lbnQuCiAqCiAqIEByZXR1cm4gdGhlIHB1YmxpYyBrZXkgaW4gT3BlblNTSCBmb3JtYXQuCiAqLwpzc2gucHVibGljS2V5VG9PcGVuU1NIID0gZnVuY3Rpb24oa2V5LCBjb21tZW50KSB7CiAgdmFyIHR5cGUgPSAnc3NoLXJzYSc7CiAgY29tbWVudCA9IGNvbW1lbnQgfHwgJyc7CgogIHZhciBidWZmZXIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIF9hZGRTdHJpbmdUb0J1ZmZlcihidWZmZXIsIHR5cGUpOwogIF9hZGRCaWdJbnRlZ2VyVG9CdWZmZXIoYnVmZmVyLCBrZXkuZSk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihidWZmZXIsIGtleS5uKTsKCiAgcmV0dXJuIHR5cGUgKyAnICcgKyBmb3JnZS51dGlsLmVuY29kZTY0KGJ1ZmZlci5ieXRlcygpKSArICcgJyArIGNvbW1lbnQ7Cn07CgovKioKICogRW5jb2RlcyBhIHByaXZhdGUgUlNBIGtleSBhcyBhbiBPcGVuU1NIIGZpbGUuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIGtleS4KICogQHBhcmFtIHBhc3NwaHJhc2UgYSBwYXNzcGhyYXNlIHRvIHByb3RlY3QgdGhlIGtleSAoZmFsc3kgZm9yIG5vIGVuY3J5cHRpb24pLgogKgogKiBAcmV0dXJuIHRoZSBwdWJsaWMga2V5IGluIE9wZW5TU0ggZm9ybWF0LgogKi8Kc3NoLnByaXZhdGVLZXlUb09wZW5TU0ggPSBmdW5jdGlvbihwcml2YXRlS2V5LCBwYXNzcGhyYXNlKSB7CiAgaWYoIXBhc3NwaHJhc2UpIHsKICAgIHJldHVybiBmb3JnZS5wa2kucHJpdmF0ZUtleVRvUGVtKHByaXZhdGVLZXkpOwogIH0KICAvLyBPcGVuU1NIIHByaXZhdGUga2V5IGlzIGp1c3QgYSBsZWdhY3kgZm9ybWF0LCBpdCBzZWVtcwogIHJldHVybiBmb3JnZS5wa2kuZW5jcnlwdFJzYVByaXZhdGVLZXkocHJpdmF0ZUtleSwgcGFzc3BocmFzZSwKICAgIHtsZWdhY3k6IHRydWUsIGFsZ29yaXRobTogJ2FlczEyOCd9KTsKfTsKCi8qKgogKiBHZXRzIHRoZSBTU0ggZmluZ2VycHJpbnQgZm9yIHRoZSBnaXZlbiBwdWJsaWMga2V5LgogKgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2UuCiAqICAgICAgICAgIFttZF0gdGhlIG1lc3NhZ2UgZGlnZXN0IG9iamVjdCB0byB1c2UgKGRlZmF1bHRzIHRvIGZvcmdlLm1kLm1kNSkuCiAqICAgICAgICAgIFtlbmNvZGluZ10gYW4gYWx0ZXJuYXRpdmUgb3V0cHV0IGVuY29kaW5nLCBzdWNoIGFzICdoZXgnCiAqICAgICAgICAgICAgKGRlZmF1bHRzIHRvIG5vbmUsIG91dHB1dHMgYSBieXRlIGJ1ZmZlcikuCiAqICAgICAgICAgIFtkZWxpbWl0ZXJdIHRoZSBkZWxpbWl0ZXIgdG8gdXNlIGJldHdlZW4gYnl0ZXMgZm9yICdoZXgnIGVuY29kZWQKICogICAgICAgICAgICBvdXRwdXQsIGVnOiAnOicgKGRlZmF1bHRzIHRvIG5vbmUpLgogKgogKiBAcmV0dXJuIHRoZSBmaW5nZXJwcmludCBhcyBhIGJ5dGUgYnVmZmVyIG9yIG90aGVyIGVuY29kaW5nIGJhc2VkIG9uIG9wdGlvbnMuCiAqLwpzc2guZ2V0UHVibGljS2V5RmluZ2VycHJpbnQgPSBmdW5jdGlvbihrZXksIG9wdGlvbnMpIHsKICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICB2YXIgbWQgPSBvcHRpb25zLm1kIHx8IGZvcmdlLm1kLm1kNS5jcmVhdGUoKTsKCiAgdmFyIHR5cGUgPSAnc3NoLXJzYSc7CiAgdmFyIGJ1ZmZlciA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgX2FkZFN0cmluZ1RvQnVmZmVyKGJ1ZmZlciwgdHlwZSk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihidWZmZXIsIGtleS5lKTsKICBfYWRkQmlnSW50ZWdlclRvQnVmZmVyKGJ1ZmZlciwga2V5Lm4pOwoKICAvLyBoYXNoIHB1YmxpYyBrZXkgYnl0ZXMKICBtZC5zdGFydCgpOwogIG1kLnVwZGF0ZShidWZmZXIuZ2V0Qnl0ZXMoKSk7CiAgdmFyIGRpZ2VzdCA9IG1kLmRpZ2VzdCgpOwogIGlmKG9wdGlvbnMuZW5jb2RpbmcgPT09ICdoZXgnKSB7CiAgICB2YXIgaGV4ID0gZGlnZXN0LnRvSGV4KCk7CiAgICBpZihvcHRpb25zLmRlbGltaXRlcikgewogICAgICByZXR1cm4gaGV4Lm1hdGNoKC8uezJ9L2cpLmpvaW4ob3B0aW9ucy5kZWxpbWl0ZXIpOwogICAgfQogICAgcmV0dXJuIGhleDsKICB9IGVsc2UgaWYob3B0aW9ucy5lbmNvZGluZyA9PT0gJ2JpbmFyeScpIHsKICAgIHJldHVybiBkaWdlc3QuZ2V0Qnl0ZXMoKTsKICB9IGVsc2UgaWYob3B0aW9ucy5lbmNvZGluZykgewogICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nICInICsgb3B0aW9ucy5lbmNvZGluZyArICciLicpOwogIH0KICByZXR1cm4gZGlnZXN0Owp9OwoKLyoqCiAqIEFkZHMgbGVuKHZhbCkgdGhlbiB2YWwgdG8gYSBidWZmZXIuCiAqCiAqIEBwYXJhbSBidWZmZXIgdGhlIGJ1ZmZlciB0byBhZGQgdG8uCiAqIEBwYXJhbSB2YWwgYSBiaWcgaW50ZWdlci4KICovCmZ1bmN0aW9uIF9hZGRCaWdJbnRlZ2VyVG9CdWZmZXIoYnVmZmVyLCB2YWwpIHsKICB2YXIgaGV4VmFsID0gdmFsLnRvU3RyaW5nKDE2KTsKICAvLyBlbnN1cmUgMnMgY29tcGxlbWVudCArdmUKICBpZihoZXhWYWxbMF0gPj0gJzgnKSB7CiAgICBoZXhWYWwgPSAnMDAnICsgaGV4VmFsOwogIH0KICB2YXIgYnl0ZXMgPSBmb3JnZS51dGlsLmhleFRvQnl0ZXMoaGV4VmFsKTsKICBidWZmZXIucHV0SW50MzIoYnl0ZXMubGVuZ3RoKTsKICBidWZmZXIucHV0Qnl0ZXMoYnl0ZXMpOwp9CgovKioKICogQWRkcyBsZW4odmFsKSB0aGVuIHZhbCB0byBhIGJ1ZmZlci4KICoKICogQHBhcmFtIGJ1ZmZlciB0aGUgYnVmZmVyIHRvIGFkZCB0by4KICogQHBhcmFtIHZhbCBhIHN0cmluZy4KICovCmZ1bmN0aW9uIF9hZGRTdHJpbmdUb0J1ZmZlcihidWZmZXIsIHZhbCkgewogIGJ1ZmZlci5wdXRJbnQzMih2YWwubGVuZ3RoKTsKICBidWZmZXIucHV0U3RyaW5nKHZhbCk7Cn0KCi8qKgogKiBIYXNoZXMgdGhlIGFyZ3VtZW50cyBpbnRvIG9uZSB2YWx1ZSB1c2luZyBTSEEtMS4KICoKICogQHJldHVybiB0aGUgc2hhMSBoYXNoIG9mIHRoZSBwcm92aWRlZCBhcmd1bWVudHMuCiAqLwpmdW5jdGlvbiBfc2hhMSgpIHsKICB2YXIgc2hhID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICB2YXIgbnVtID0gYXJndW1lbnRzLmxlbmd0aDsKICBmb3IgKHZhciBpID0gMDsgaSA8IG51bTsgKytpKSB7CiAgICBzaGEudXBkYXRlKGFyZ3VtZW50c1tpXSk7CiAgfQogIHJldHVybiBzaGEuZGlnZXN0KCk7Cn0KCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3NzaCc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9zc2gnLFsKICAncmVxdWlyZScsCiAgJ21vZHVsZScsCiAgJy4vYWVzJywKICAnLi9obWFjJywKICAnLi9tZDUnLAogICcuL3NoYTEnLAogICcuL3V0aWwnCl0sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFN1cHBvcnQgZm9yIGNvbmN1cnJlbnQgdGFzayBtYW5hZ2VtZW50IGFuZCBzeW5jaHJvbml6YXRpb24gaW4gd2ViCiAqIGFwcGxpY2F0aW9ucy4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICogQGF1dGhvciBEYXZpZCBJLiBMZWhuIDxkbGVobkBkaWdpdGFsYmF6YWFyLmNvbT4KICoKICogQ29weXJpZ2h0IChjKSAyMDA5LTIwMTMgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovLyBsb2dnaW5nIGNhdGVnb3J5CnZhciBjYXQgPSAnZm9yZ2UudGFzayc7CgovLyB2ZXJib3NlIGxldmVsCi8vIDA6IG9mZiwgMTogYSBsaXR0bGUsIDI6IGEgd2hvbGUgbG90Ci8vIFZlcmJvc2UgZGVidWcgbG9nZ2luZyBpcyBzdXJyb3VuZGVkIGJ5IGEgbGV2ZWwgY2hlY2sgdG8gYXZvaWQgdGhlCi8vIHBlcmZvcm1hbmNlIGlzc3VlcyB3aXRoIGV2ZW4gY2FsbGluZyB0aGUgbG9nZ2luZyBjb2RlIHJlZ2FyZGxlc3MgaWYgaXQKLy8gaXMgYWN0dWFsbHkgbG9nZ2VkLiAgRm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMgdGhpcyBzaG91bGQgbm90IGJlIHNldCB0byAyCi8vIGZvciBwcm9kdWN0aW9uIHVzZS4KLy8gZXg6IGlmKHNWTCA+PSAyKSBmb3JnZS5sb2cudmVyYm9zZSguLi4uKQp2YXIgc1ZMID0gMDsKCi8vIHRyYWNrIHRhc2tzIGZvciBkZWJ1Z2dpbmcKdmFyIHNUYXNrcyA9IHt9Owp2YXIgc05leHRUYXNrSWQgPSAwOwovLyBkZWJ1ZyBhY2Nlc3MKZm9yZ2UuZGVidWcuc2V0KGNhdCwgJ3Rhc2tzJywgc1Rhc2tzKTsKCi8vIGEgbWFwIG9mIHRhc2sgdHlwZSB0byB0YXNrIHF1ZXVlCnZhciBzVGFza1F1ZXVlcyA9IHt9OwovLyBkZWJ1ZyBhY2Nlc3MKZm9yZ2UuZGVidWcuc2V0KGNhdCwgJ3F1ZXVlcycsIHNUYXNrUXVldWVzKTsKCi8vIG5hbWUgZm9yIHVubmFtZWQgdGFza3MKdmFyIHNOb1Rhc2tOYW1lID0gJz8nOwoKLy8gbWF4aW11bSBudW1iZXIgb2YgZG9OZXh0KCkgcmVjdXJzaW9ucyBiZWZvcmUgYSBjb250ZXh0IHN3YXAgb2NjdXJzCi8vIEZJWE1FOiBtaWdodCBuZWVkIHRvIHR3ZWFrIHRoaXMgYmFzZWQgb24gdGhlIGJyb3dzZXIKdmFyIHNNYXhSZWN1cnNpb25zID0gMzA7CgovLyB0aW1lIHNsaWNlIGZvciBkb2luZyB0YXNrcyBiZWZvcmUgYSBjb250ZXh0IHN3YXAgb2NjdXJzCi8vIEZJWE1FOiBtaWdodCBuZWVkIHRvIHR3ZWFrIHRoaXMgYmFzZWQgb24gdGhlIGJyb3dzZXIKdmFyIHNUaW1lU2xpY2UgPSAyMDsKCi8qKgogKiBUYXNrIHN0YXRlcy4KICoKICogUkVBRFk6IHJlYWR5IHRvIHN0YXJ0IHByb2Nlc3NpbmcKICogUlVOTklORzogdGFzayBvciBhIHN1YnRhc2sgaXMgcnVubmluZwogKiBCTE9DS0VEOiB0YXNrIGlzIHdhaXRpbmcgdG8gYWNxdWlyZSBOIHBlcm1pdHMgdG8gY29udGludWUKICogU0xFRVBJTkc6IHRhc2sgaXMgc2xlZXBpbmcgZm9yIGEgcGVyaW9kIG9mIHRpbWUKICogRE9ORTogdGFzayBpcyBkb25lCiAqIEVSUk9SOiB0YXNrIGhhcyBhbiBlcnJvcgogKi8KdmFyIFJFQURZID0gJ3JlYWR5JzsKdmFyIFJVTk5JTkcgPSAncnVubmluZyc7CnZhciBCTE9DS0VEID0gJ2Jsb2NrZWQnOwp2YXIgU0xFRVBJTkcgPSAnc2xlZXBpbmcnOwp2YXIgRE9ORSA9ICdkb25lJzsKdmFyIEVSUk9SID0gJ2Vycm9yJzsKCi8qKgogKiBUYXNrIGFjdGlvbnMuICBVc2VkIHRvIGNvbnRyb2wgc3RhdGUgdHJhbnNpdGlvbnMuCiAqCiAqIFNUT1A6IHN0b3AgcHJvY2Vzc2luZwogKiBTVEFSVDogc3RhcnQgcHJvY2Vzc2luZyB0YXNrcwogKiBCTE9DSzogYmxvY2sgdGFzayBmcm9tIGNvbnRpbnVpbmcgdW50aWwgMSBvciBtb3JlIHBlcm1pdHMgYXJlIHJlbGVhc2VkCiAqIFVOQkxPQ0s6IHJlbGVhc2Ugb25lIG9yIG1vcmUgcGVybWl0cwogKiBTTEVFUDogc2xlZXAgZm9yIGEgcGVyaW9kIG9mIHRpbWUKICogV0FLRVVQOiB3YWtldXAgZWFybHkgZnJvbSBTTEVFUElORyBzdGF0ZQogKiBDQU5DRUw6IGNhbmNlbCBmdXJ0aGVyIHRhc2tzCiAqIEZBSUw6IGEgZmFpbHVyZSBvY2N1cmVkCiAqLwp2YXIgU1RPUCA9ICdzdG9wJzsKdmFyIFNUQVJUID0gJ3N0YXJ0JzsKdmFyIEJMT0NLID0gJ2Jsb2NrJzsKdmFyIFVOQkxPQ0sgPSAndW5ibG9jayc7CnZhciBTTEVFUCA9ICdzbGVlcCc7CnZhciBXQUtFVVAgPSAnd2FrZXVwJzsKdmFyIENBTkNFTCA9ICdjYW5jZWwnOwp2YXIgRkFJTCA9ICdmYWlsJzsKCi8qKgogKiBTdGF0ZSB0cmFuc2l0aW9uIHRhYmxlLgogKgogKiBuZXh0U3RhdGUgPSBzU3RhdGVUYWJsZVtjdXJyZW50U3RhdGVdW2FjdGlvbl0KICovCnZhciBzU3RhdGVUYWJsZSA9IHt9OwoKc1N0YXRlVGFibGVbUkVBRFldID0ge307CnNTdGF0ZVRhYmxlW1JFQURZXVtTVE9QXSA9IFJFQURZOwpzU3RhdGVUYWJsZVtSRUFEWV1bU1RBUlRdID0gUlVOTklORzsKc1N0YXRlVGFibGVbUkVBRFldW0NBTkNFTF0gPSBET05FOwpzU3RhdGVUYWJsZVtSRUFEWV1bRkFJTF0gPSBFUlJPUjsKCnNTdGF0ZVRhYmxlW1JVTk5JTkddID0ge307CnNTdGF0ZVRhYmxlW1JVTk5JTkddW1NUT1BdID0gUkVBRFk7CnNTdGF0ZVRhYmxlW1JVTk5JTkddW1NUQVJUXSA9IFJVTk5JTkc7CnNTdGF0ZVRhYmxlW1JVTk5JTkddW0JMT0NLXSA9IEJMT0NLRUQ7CnNTdGF0ZVRhYmxlW1JVTk5JTkddW1VOQkxPQ0tdID0gUlVOTklORzsKc1N0YXRlVGFibGVbUlVOTklOR11bU0xFRVBdID0gU0xFRVBJTkc7CnNTdGF0ZVRhYmxlW1JVTk5JTkddW1dBS0VVUF0gPSBSVU5OSU5HOwpzU3RhdGVUYWJsZVtSVU5OSU5HXVtDQU5DRUxdID0gRE9ORTsKc1N0YXRlVGFibGVbUlVOTklOR11bRkFJTF0gPSBFUlJPUjsKCnNTdGF0ZVRhYmxlW0JMT0NLRURdID0ge307CnNTdGF0ZVRhYmxlW0JMT0NLRURdW1NUT1BdID0gQkxPQ0tFRDsKc1N0YXRlVGFibGVbQkxPQ0tFRF1bU1RBUlRdID0gQkxPQ0tFRDsKc1N0YXRlVGFibGVbQkxPQ0tFRF1bQkxPQ0tdID0gQkxPQ0tFRDsKc1N0YXRlVGFibGVbQkxPQ0tFRF1bVU5CTE9DS10gPSBCTE9DS0VEOwpzU3RhdGVUYWJsZVtCTE9DS0VEXVtTTEVFUF0gPSBCTE9DS0VEOwpzU3RhdGVUYWJsZVtCTE9DS0VEXVtXQUtFVVBdID0gQkxPQ0tFRDsKc1N0YXRlVGFibGVbQkxPQ0tFRF1bQ0FOQ0VMXSA9IERPTkU7CnNTdGF0ZVRhYmxlW0JMT0NLRURdW0ZBSUxdID0gRVJST1I7CgpzU3RhdGVUYWJsZVtTTEVFUElOR10gPSB7fTsKc1N0YXRlVGFibGVbU0xFRVBJTkddW1NUT1BdID0gU0xFRVBJTkc7CnNTdGF0ZVRhYmxlW1NMRUVQSU5HXVtTVEFSVF0gPSBTTEVFUElORzsKc1N0YXRlVGFibGVbU0xFRVBJTkddW0JMT0NLXSA9IFNMRUVQSU5HOwpzU3RhdGVUYWJsZVtTTEVFUElOR11bVU5CTE9DS10gPSBTTEVFUElORzsKc1N0YXRlVGFibGVbU0xFRVBJTkddW1NMRUVQXSA9IFNMRUVQSU5HOwpzU3RhdGVUYWJsZVtTTEVFUElOR11bV0FLRVVQXSA9IFNMRUVQSU5HOwpzU3RhdGVUYWJsZVtTTEVFUElOR11bQ0FOQ0VMXSA9IERPTkU7CnNTdGF0ZVRhYmxlW1NMRUVQSU5HXVtGQUlMXSA9IEVSUk9SOwoKc1N0YXRlVGFibGVbRE9ORV0gPSB7fTsKc1N0YXRlVGFibGVbRE9ORV1bU1RPUF0gPSBET05FOwpzU3RhdGVUYWJsZVtET05FXVtTVEFSVF0gPSBET05FOwpzU3RhdGVUYWJsZVtET05FXVtCTE9DS10gPSBET05FOwpzU3RhdGVUYWJsZVtET05FXVtVTkJMT0NLXSA9IERPTkU7CnNTdGF0ZVRhYmxlW0RPTkVdW1NMRUVQXSA9IERPTkU7CnNTdGF0ZVRhYmxlW0RPTkVdW1dBS0VVUF0gPSBET05FOwpzU3RhdGVUYWJsZVtET05FXVtDQU5DRUxdID0gRE9ORTsKc1N0YXRlVGFibGVbRE9ORV1bRkFJTF0gPSBFUlJPUjsKCnNTdGF0ZVRhYmxlW0VSUk9SXSA9IHt9OwpzU3RhdGVUYWJsZVtFUlJPUl1bU1RPUF0gPSBFUlJPUjsKc1N0YXRlVGFibGVbRVJST1JdW1NUQVJUXSA9IEVSUk9SOwpzU3RhdGVUYWJsZVtFUlJPUl1bQkxPQ0tdID0gRVJST1I7CnNTdGF0ZVRhYmxlW0VSUk9SXVtVTkJMT0NLXSA9IEVSUk9SOwpzU3RhdGVUYWJsZVtFUlJPUl1bU0xFRVBdID0gRVJST1I7CnNTdGF0ZVRhYmxlW0VSUk9SXVtXQUtFVVBdID0gRVJST1I7CnNTdGF0ZVRhYmxlW0VSUk9SXVtDQU5DRUxdID0gRVJST1I7CnNTdGF0ZVRhYmxlW0VSUk9SXVtGQUlMXSA9IEVSUk9SOwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgdGFzay4KICoKICogQHBhcmFtIG9wdGlvbnMgb3B0aW9ucyBmb3IgdGhpcyB0YXNrCiAqICAgcnVuOiB0aGUgcnVuIGZ1bmN0aW9uIGZvciB0aGUgdGFzayAocmVxdWlyZWQpCiAqICAgbmFtZTogdGhlIHJ1biBmdW5jdGlvbiBmb3IgdGhlIHRhc2sgKG9wdGlvbmFsKQogKiAgIHBhcmVudDogcGFyZW50IG9mIHRoaXMgdGFzayAob3B0aW9uYWwpCiAqCiAqIEByZXR1cm4gdGhlIGVtcHR5IHRhc2suCiAqLwp2YXIgVGFzayA9IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAvLyB0YXNrIGlkCiAgdGhpcy5pZCA9IC0xOwoKICAvLyB0YXNrIG5hbWUKICB0aGlzLm5hbWUgPSBvcHRpb25zLm5hbWUgfHwgc05vVGFza05hbWU7CgogIC8vIHRhc2sgaGFzIG5vIHBhcmVudAogIHRoaXMucGFyZW50ID0gb3B0aW9ucy5wYXJlbnQgfHwgbnVsbDsKCiAgLy8gc2F2ZSBydW4gZnVuY3Rpb24KICB0aGlzLnJ1biA9IG9wdGlvbnMucnVuOwoKICAvLyBjcmVhdGUgYSBxdWV1ZSBvZiBzdWJ0YXNrcyB0byBydW4KICB0aGlzLnN1YnRhc2tzID0gW107CgogIC8vIGVycm9yIGZsYWcKICB0aGlzLmVycm9yID0gZmFsc2U7CgogIC8vIHN0YXRlIG9mIHRoZSB0YXNrCiAgdGhpcy5zdGF0ZSA9IFJFQURZOwoKICAvLyBudW1iZXIgb2YgdGltZXMgdGhlIHRhc2sgaGFzIGJlZW4gYmxvY2tlZCAoYWxzbyB0aGUgbnVtYmVyCiAgLy8gb2YgcGVybWl0cyBuZWVkZWQgdG8gYmUgcmVsZWFzZWQgdG8gY29udGludWUgcnVubmluZykKICB0aGlzLmJsb2NrcyA9IDA7CgogIC8vIHRpbWVvdXQgaWQgd2hlbiBzbGVlcGluZwogIHRoaXMudGltZW91dElkID0gbnVsbDsKCiAgLy8gbm8gc3dhcCB0aW1lIHlldAogIHRoaXMuc3dhcFRpbWUgPSBudWxsOwoKICAvLyBubyB1c2VyIGRhdGEKICB0aGlzLnVzZXJEYXRhID0gbnVsbDsKCiAgLy8gaW5pdGlhbGl6ZSB0YXNrCiAgLy8gRklYTUU6IGRlYWwgd2l0aCBvdmVyZmxvdwogIHRoaXMuaWQgPSBzTmV4dFRhc2tJZCsrOwogIHNUYXNrc1t0aGlzLmlkXSA9IHRoaXM7CiAgaWYoc1ZMID49IDEpIHsKICAgIGZvcmdlLmxvZy52ZXJib3NlKGNhdCwgJ1slc11bJXNdIGluaXQnLCB0aGlzLmlkLCB0aGlzLm5hbWUsIHRoaXMpOwogIH0KfTsKCi8qKgogKiBMb2dzIGRlYnVnIGluZm9ybWF0aW9uIG9uIHRoaXMgdGFzayBhbmQgdGhlIHN5c3RlbSBzdGF0ZS4KICovClRhc2sucHJvdG90eXBlLmRlYnVnID0gZnVuY3Rpb24obXNnKSB7CiAgbXNnID0gbXNnIHx8ICcnOwogIGZvcmdlLmxvZy5kZWJ1ZyhjYXQsIG1zZywKICAgICdbJXNdWyVzXSB0YXNrOicsIHRoaXMuaWQsIHRoaXMubmFtZSwgdGhpcywKICAgICdzdWJ0YXNrczonLCB0aGlzLnN1YnRhc2tzLmxlbmd0aCwKICAgICdxdWV1ZTonLCBzVGFza1F1ZXVlcyk7Cn07CgovKioKICogQWRkcyBhIHN1YnRhc2sgdG8gcnVuIGFmdGVyIHRhc2suZG9OZXh0KCkgb3IgdGFzay5mYWlsKCkgaXMgY2FsbGVkLgogKgogKiBAcGFyYW0gbmFtZSBodW1hbiByZWFkYWJsZSBuYW1lIGZvciB0aGlzIHRhc2sgKG9wdGlvbmFsKS4KICogQHBhcmFtIHN1YnJ1biBhIGZ1bmN0aW9uIHRvIHJ1biB0aGF0IHRha2VzIHRoZSBjdXJyZW50IHRhc2sgYXMKICogICAgICAgICAgaXRzIGZpcnN0IHBhcmFtZXRlci4KICoKICogQHJldHVybiB0aGUgY3VycmVudCB0YXNrICh1c2VmdWwgZm9yIGNoYWluaW5nIG5leHQoKSBjYWxscykuCiAqLwpUYXNrLnByb3RvdHlwZS5uZXh0ID0gZnVuY3Rpb24obmFtZSwgc3VicnVuKSB7CiAgLy8ganVnZ2xlIHBhcmFtZXRlcnMgaWYgaXQgbG9va3MgbGlrZSBubyBuYW1lIGlzIGdpdmVuCiAgaWYodHlwZW9mKG5hbWUpID09PSAnZnVuY3Rpb24nKSB7CiAgICBzdWJydW4gPSBuYW1lOwoKICAgIC8vIGluaGVyaXQgcGFyZW50J3MgbmFtZQogICAgbmFtZSA9IHRoaXMubmFtZTsKICB9CiAgLy8gY3JlYXRlIHN1YnRhc2ssIHNldCBwYXJlbnQgdG8gdGhpcyB0YXNrLCBwcm9wYWdhdGUgY2FsbGJhY2tzCiAgdmFyIHN1YnRhc2sgPSBuZXcgVGFzayh7CiAgICBydW46IHN1YnJ1biwKICAgIG5hbWU6IG5hbWUsCiAgICBwYXJlbnQ6IHRoaXMKICB9KTsKICAvLyBzdGFydCBzdWJ0YXNrcyBydW5uaW5nCiAgc3VidGFzay5zdGF0ZSA9IFJVTk5JTkc7CiAgc3VidGFzay50eXBlID0gdGhpcy50eXBlOwogIHN1YnRhc2suc3VjY2Vzc0NhbGxiYWNrID0gdGhpcy5zdWNjZXNzQ2FsbGJhY2sgfHwgbnVsbDsKICBzdWJ0YXNrLmZhaWx1cmVDYWxsYmFjayA9IHRoaXMuZmFpbHVyZUNhbGxiYWNrIHx8IG51bGw7CgogIC8vIHF1ZXVlIGEgbmV3IHN1YnRhc2sKICB0aGlzLnN1YnRhc2tzLnB1c2goc3VidGFzayk7CgogIHJldHVybiB0aGlzOwp9OwoKLyoqCiAqIEFkZHMgc3VidGFza3MgdG8gcnVuIGluIHBhcmFsbGVsIGFmdGVyIHRhc2suZG9OZXh0KCkgb3IgdGFzay5mYWlsKCkKICogaXMgY2FsbGVkLgogKgogKiBAcGFyYW0gbmFtZSBodW1hbiByZWFkYWJsZSBuYW1lIGZvciB0aGlzIHRhc2sgKG9wdGlvbmFsKS4KICogQHBhcmFtIHN1YnJ1biBmdW5jdGlvbnMgdG8gcnVuIHRoYXQgdGFrZSB0aGUgY3VycmVudCB0YXNrIGFzCiAqICAgICAgICAgIHRoZWlyIGZpcnN0IHBhcmFtZXRlci4KICoKICogQHJldHVybiB0aGUgY3VycmVudCB0YXNrICh1c2VmdWwgZm9yIGNoYWluaW5nIG5leHQoKSBjYWxscykuCiAqLwpUYXNrLnByb3RvdHlwZS5wYXJhbGxlbCA9IGZ1bmN0aW9uKG5hbWUsIHN1YnJ1bikgewogIC8vIGp1Z2dsZSBwYXJhbWV0ZXJzIGlmIGl0IGxvb2tzIGxpa2Ugbm8gbmFtZSBpcyBnaXZlbgogIGlmKGZvcmdlLnV0aWwuaXNBcnJheShuYW1lKSkgewogICAgc3VicnVuID0gbmFtZTsKCiAgICAvLyBpbmhlcml0IHBhcmVudCdzIG5hbWUKICAgIG5hbWUgPSB0aGlzLm5hbWU7CiAgfQogIC8vIFdyYXAgcGFyYWxsZWwgdGFza3MgaW4gYSByZWd1bGFyIHRhc2sgc28gdGhleSBhcmUgc3RhcnRlZCBhdCB0aGUKICAvLyBwcm9wZXIgdGltZS4KICByZXR1cm4gdGhpcy5uZXh0KG5hbWUsIGZ1bmN0aW9uKHRhc2spIHsKICAgIC8vIGJsb2NrIHdhaXRpbmcgZm9yIHN1YnRhc2tzCiAgICB2YXIgcHRhc2sgPSB0YXNrOwogICAgcHRhc2suYmxvY2soc3VicnVuLmxlbmd0aCk7CgogICAgLy8gd2UgcGFzcyB0aGUgaXRlcmF0b3IgZnJvbSB0aGUgbG9vcCBiZWxvdyBhcyBhIHBhcmFtZXRlcgogICAgLy8gdG8gYSBmdW5jdGlvbiBiZWNhdXNlIGl0IGlzIG90aGVyd2lzZSBpbmNsdWRlZCBpbiB0aGUKICAgIC8vIGNsb3N1cmUgYW5kIGNoYW5nZXMgYXMgdGhlIGxvb3AgY2hhbmdlcyAtLSBjYXVzaW5nIGkKICAgIC8vIHRvIGFsd2F5cyBiZSBzZXQgdG8gaXRzIGhpZ2hlc3QgdmFsdWUKICAgIHZhciBzdGFydFBhcmFsbGVsVGFzayA9IGZ1bmN0aW9uKHBuYW1lLCBwaSkgewogICAgICBmb3JnZS50YXNrLnN0YXJ0KHsKICAgICAgICB0eXBlOiBwbmFtZSwKICAgICAgICBydW46IGZ1bmN0aW9uKHRhc2spIHsKICAgICAgICAgICBzdWJydW5bcGldKHRhc2spOwogICAgICAgIH0sCiAgICAgICAgc3VjY2VzczogZnVuY3Rpb24odGFzaykgewogICAgICAgICAgIHB0YXNrLnVuYmxvY2soKTsKICAgICAgICB9LAogICAgICAgIGZhaWx1cmU6IGZ1bmN0aW9uKHRhc2spIHsKICAgICAgICAgICBwdGFzay51bmJsb2NrKCk7CiAgICAgICAgfQogICAgICB9KTsKICAgIH07CgogICAgZm9yKHZhciBpID0gMDsgaSA8IHN1YnJ1bi5sZW5ndGg7IGkrKykgewogICAgICAvLyBUeXBlIG11c3QgYmUgdW5pcXVlIHNvIHRhc2sgc3RhcnRzIGluIHBhcmFsbGVsOgogICAgICAvLyAgICBuYW1lICsgcHJpdmF0ZSBzdHJpbmcgKyB0YXNrIGlkICsgc3ViLXRhc2sgaW5kZXgKICAgICAgLy8gc3RhcnQgdGFza3MgaW4gcGFyYWxsZWwgYW5kIHVuYmxvY2sgd2hlbiB0aGUgZmluaXNoCiAgICAgIHZhciBwbmFtZSA9IG5hbWUgKyAnX19wYXJhbGxlbC0nICsgdGFzay5pZCArICctJyArIGk7CiAgICAgIHZhciBwaSA9IGk7CiAgICAgIHN0YXJ0UGFyYWxsZWxUYXNrKHBuYW1lLCBwaSk7CiAgICB9CiAgfSk7Cn07CgovKioKICogU3RvcHMgYSBydW5uaW5nIHRhc2suCiAqLwpUYXNrLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24oKSB7CiAgdGhpcy5zdGF0ZSA9IHNTdGF0ZVRhYmxlW3RoaXMuc3RhdGVdW1NUT1BdOwp9OwoKLyoqCiAqIFN0YXJ0cyBydW5uaW5nIGEgdGFzay4KICovClRhc2sucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oKSB7CiAgdGhpcy5lcnJvciA9IGZhbHNlOwogIHRoaXMuc3RhdGUgPSBzU3RhdGVUYWJsZVt0aGlzLnN0YXRlXVtTVEFSVF07CgogIC8vIHRyeSB0byByZXN0YXJ0CiAgaWYodGhpcy5zdGF0ZSA9PT0gUlVOTklORykgewogICAgdGhpcy5zdGFydCA9IG5ldyBEYXRlKCk7CiAgICB0aGlzLnJ1bih0aGlzKTsKICAgIHJ1bk5leHQodGhpcywgMCk7CiAgfQp9OwoKLyoqCiAqIEJsb2NrcyBhIHRhc2sgdW50aWwgaXQgb25lIG9yIG1vcmUgcGVybWl0cyBoYXZlIGJlZW4gcmVsZWFzZWQuIFRoZQogKiB0YXNrIHdpbGwgbm90IHJlc3VtZSB1bnRpbCB0aGUgcmVxdWVzdGVkIG51bWJlciBvZiBwZXJtaXRzIGhhdmUKICogYmVlbiByZWxlYXNlZCB3aXRoIGNhbGwocykgdG8gdW5ibG9jaygpLgogKgogKiBAcGFyYW0gbiBudW1iZXIgb2YgcGVybWl0cyB0byB3YWl0IGZvcihkZWZhdWx0OiAxKS4KICovClRhc2sucHJvdG90eXBlLmJsb2NrID0gZnVuY3Rpb24obikgewogIG4gPSB0eXBlb2YobikgPT09ICd1bmRlZmluZWQnID8gMSA6IG47CiAgdGhpcy5ibG9ja3MgKz0gbjsKICBpZih0aGlzLmJsb2NrcyA+IDApIHsKICAgIHRoaXMuc3RhdGUgPSBzU3RhdGVUYWJsZVt0aGlzLnN0YXRlXVtCTE9DS107CiAgfQp9OwoKLyoqCiAqIFJlbGVhc2VzIGEgcGVybWl0IHRvIHVuYmxvY2sgYSB0YXNrLiBJZiBhIHRhc2sgd2FzIGJsb2NrZWQgYnkKICogcmVxdWVzdGluZyBOIHBlcm1pdHMgdmlhIGJsb2NrKCksIHRoZW4gaXQgd2lsbCBvbmx5IGNvbnRpbnVlCiAqIHJ1bm5pbmcgb25jZSBlbm91Z2ggcGVybWl0cyBoYXZlIGJlZW4gcmVsZWFzZWQgdmlhIHVuYmxvY2soKSBjYWxscy4KICoKICogSWYgbXVsdGlwbGUgcHJvY2Vzc2VzIG5lZWQgdG8gc3luY2hyb25pemUgd2l0aCBhIHNpbmdsZSB0YXNrIHRoZW4KICogdXNlIGEgY29uZGl0aW9uIHZhcmlhYmxlIChzZWUgZm9yZ2UudGFzay5jcmVhdGVDb25kaXRpb24pLiBJdCBpcwogKiBhbiBlcnJvciB0byB1bmJsb2NrIGEgdGFzayBtb3JlIHRpbWVzIHRoYW4gaXQgaGFzIGJlZW4gYmxvY2tlZC4KICoKICogQHBhcmFtIG4gbnVtYmVyIG9mIHBlcm1pdHMgdG8gcmVsZWFzZSAoZGVmYXVsdDogMSkuCiAqCiAqIEByZXR1cm4gdGhlIGN1cnJlbnQgYmxvY2sgY291bnQgKHRhc2sgaXMgdW5ibG9ja2VkIHdoZW4gY291bnQgaXMgMCkKICovClRhc2sucHJvdG90eXBlLnVuYmxvY2sgPSBmdW5jdGlvbihuKSB7CiAgbiA9IHR5cGVvZihuKSA9PT0gJ3VuZGVmaW5lZCcgPyAxIDogbjsKICB0aGlzLmJsb2NrcyAtPSBuOwogIGlmKHRoaXMuYmxvY2tzID09PSAwICYmIHRoaXMuc3RhdGUgIT09IERPTkUpIHsKICAgIHRoaXMuc3RhdGUgPSBSVU5OSU5HOwogICAgcnVuTmV4dCh0aGlzLCAwKTsKICB9CiAgcmV0dXJuIHRoaXMuYmxvY2tzOwp9OwoKLyoqCiAqIFNsZWVwIGZvciBhIHBlcmlvZCBvZiB0aW1lIGJlZm9yZSByZXN1bWluZyB0YXNrcy4KICoKICogQHBhcmFtIG4gbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBzbGVlcCAoZGVmYXVsdDogMCkuCiAqLwpUYXNrLnByb3RvdHlwZS5zbGVlcCA9IGZ1bmN0aW9uKG4pIHsKICBuID0gdHlwZW9mKG4pID09PSAndW5kZWZpbmVkJyA/IDAgOiBuOwogIHRoaXMuc3RhdGUgPSBzU3RhdGVUYWJsZVt0aGlzLnN0YXRlXVtTTEVFUF07CiAgdmFyIHNlbGYgPSB0aGlzOwogIHRoaXMudGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbigpIHsKICAgIHNlbGYudGltZW91dElkID0gbnVsbDsKICAgIHNlbGYuc3RhdGUgPSBSVU5OSU5HOwogICAgcnVuTmV4dChzZWxmLCAwKTsKICB9LCBuKTsKfTsKCi8qKgogKiBXYWl0cyBvbiBhIGNvbmRpdGlvbiB2YXJpYWJsZSB1bnRpbCBub3RpZmllZC4gVGhlIG5leHQgdGFzayB3aWxsCiAqIG5vdCBiZSBzY2hlZHVsZWQgdW50aWwgbm90aWZpY2F0aW9uLiBBIGNvbmRpdGlvbiB2YXJpYWJsZSBjYW4gYmUKICogY3JlYXRlZCB3aXRoIGZvcmdlLnRhc2suY3JlYXRlQ29uZGl0aW9uKCkuCiAqCiAqIE9uY2UgY29uZC5ub3RpZnkoKSBpcyBjYWxsZWQsIHRoZSB0YXNrIHdpbGwgY29udGludWUuCiAqCiAqIEBwYXJhbSBjb25kIHRoZSBjb25kaXRpb24gdmFyaWFibGUgdG8gd2FpdCBvbi4KICovClRhc2sucHJvdG90eXBlLndhaXQgPSBmdW5jdGlvbihjb25kKSB7CiAgY29uZC53YWl0KHRoaXMpOwp9OwoKLyoqCiAqIElmIHNsZWVwaW5nLCB3YWtldXAgYW5kIGNvbnRpbnVlIHJ1bm5pbmcgdGFza3MuCiAqLwpUYXNrLnByb3RvdHlwZS53YWtldXAgPSBmdW5jdGlvbigpIHsKICBpZih0aGlzLnN0YXRlID09PSBTTEVFUElORykgewogICAgY2FuY2VsVGltZW91dCh0aGlzLnRpbWVvdXRJZCk7CiAgICB0aGlzLnRpbWVvdXRJZCA9IG51bGw7CiAgICB0aGlzLnN0YXRlID0gUlVOTklORzsKICAgIHJ1bk5leHQodGhpcywgMCk7CiAgfQp9OwoKLyoqCiAqIENhbmNlbCBhbGwgcmVtYWluaW5nIHN1YnRhc2tzIG9mIHRoaXMgdGFzay4KICovClRhc2sucHJvdG90eXBlLmNhbmNlbCA9IGZ1bmN0aW9uKCkgewogIHRoaXMuc3RhdGUgPSBzU3RhdGVUYWJsZVt0aGlzLnN0YXRlXVtDQU5DRUxdOwogIC8vIHJlbW92ZSBwZXJtaXRzIG5lZWRlZAogIHRoaXMucGVybWl0c05lZWRlZCA9IDA7CiAgLy8gY2FuY2VsIHRpbWVvdXRzCiAgaWYodGhpcy50aW1lb3V0SWQgIT09IG51bGwpIHsKICAgIGNhbmNlbFRpbWVvdXQodGhpcy50aW1lb3V0SWQpOwogICAgdGhpcy50aW1lb3V0SWQgPSBudWxsOwogIH0KICAvLyByZW1vdmUgc3VidGFza3MKICB0aGlzLnN1YnRhc2tzID0gW107Cn07CgovKioKICogRmluaXNoZXMgdGhpcyB0YXNrIHdpdGggZmFpbHVyZSBhbmQgc2V0cyBlcnJvciBmbGFnLiBUaGUgZW50aXJlCiAqIHRhc2sgd2lsbCBiZSBhYm9ydGVkIHVubGVzcyB0aGUgbmV4dCB0YXNrIHRoYXQgc2hvdWxkIGV4ZWN1dGUKICogaXMgcGFzc2VkIGFzIGEgcGFyYW1ldGVyLiBUaGlzIGFsbG93cyBsZXZlbHMgb2Ygc3VidGFza3MgdG8gYmUKICogc2tpcHBlZC4gRm9yIGluc3RhbmNlLCB0byBhYm9ydCBvbmx5IHRoaXMgdGFza3MncyBzdWJ0YXNrcywgdGhlbgogKiBjYWxsIGZhaWwodGFzay5wYXJlbnQpLiBUbyBhYm9ydCB0aGlzIHRhc2sncyBzdWJ0YXNrcyBhbmQgaXRzCiAqIHBhcmVudCdzIHN1YnRhc2tzLCBjYWxsIGZhaWwodGFzay5wYXJlbnQucGFyZW50KS4gVG8gYWJvcnQKICogYWxsIHRhc2tzIGFuZCBzaW1wbHkgY2FsbCB0aGUgdGFzayBjYWxsYmFjaywgY2FsbCBmYWlsKCkgb3IKICogZmFpbChudWxsKS4KICoKICogVGhlIHRhc2sgY2FsbGJhY2sgKHN1Y2Nlc3Mgb3IgZmFpbHVyZSkgd2lsbCBhbHdheXMsIGV2ZW50dWFsbHksIGJlCiAqIGNhbGxlZC4KICoKICogQHBhcmFtIG5leHQgdGhlIHRhc2sgdG8gY29udGludWUgYXQsIG9yIG51bGwgdG8gYWJvcnQgZW50aXJlbHkuCiAqLwpUYXNrLnByb3RvdHlwZS5mYWlsID0gZnVuY3Rpb24obmV4dCkgewogIC8vIHNldCBlcnJvciBmbGFnCiAgdGhpcy5lcnJvciA9IHRydWU7CgogIC8vIGZpbmlzaCB0YXNrCiAgZmluaXNoKHRoaXMsIHRydWUpOwoKICBpZihuZXh0KSB7CiAgICAvLyBwcm9wYWdhdGUgdGFzayBpbmZvCiAgICBuZXh0LmVycm9yID0gdGhpcy5lcnJvcjsKICAgIG5leHQuc3dhcFRpbWUgPSB0aGlzLnN3YXBUaW1lOwogICAgbmV4dC51c2VyRGF0YSA9IHRoaXMudXNlckRhdGE7CgogICAgLy8gZG8gbmV4dCB0YXNrIGFzIHNwZWNpZmllZAogICAgcnVuTmV4dChuZXh0LCAwKTsKICB9IGVsc2UgewogICAgaWYodGhpcy5wYXJlbnQgIT09IG51bGwpIHsKICAgICAgLy8gZmluaXNoIHJvb3QgdGFzayAoZW5zdXJlcyBpdCBpcyByZW1vdmVkIGZyb20gdGFzayBxdWV1ZSkKICAgICAgdmFyIHBhcmVudCA9IHRoaXMucGFyZW50OwogICAgICB3aGlsZShwYXJlbnQucGFyZW50ICE9PSBudWxsKSB7CiAgICAgICAgLy8gcHJvcGFnYXRlIHRhc2sgaW5mbwogICAgICAgIHBhcmVudC5lcnJvciA9IHRoaXMuZXJyb3I7CiAgICAgICAgcGFyZW50LnN3YXBUaW1lID0gdGhpcy5zd2FwVGltZTsKICAgICAgICBwYXJlbnQudXNlckRhdGEgPSB0aGlzLnVzZXJEYXRhOwogICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnQ7CiAgICAgIH0KICAgICAgZmluaXNoKHBhcmVudCwgdHJ1ZSk7CiAgICB9CgogICAgLy8gY2FsbCBmYWlsdXJlIGNhbGxiYWNrIGlmIG9uZSBleGlzdHMKICAgIGlmKHRoaXMuZmFpbHVyZUNhbGxiYWNrKSB7CiAgICAgIHRoaXMuZmFpbHVyZUNhbGxiYWNrKHRoaXMpOwogICAgfQogIH0KfTsKCi8qKgogKiBBc3luY2hyb25vdXNseSBzdGFydCBhIHRhc2suCiAqCiAqIEBwYXJhbSB0YXNrIHRoZSB0YXNrIHRvIHN0YXJ0LgogKi8KdmFyIHN0YXJ0ID0gZnVuY3Rpb24odGFzaykgewogIHRhc2suZXJyb3IgPSBmYWxzZTsKICB0YXNrLnN0YXRlID0gc1N0YXRlVGFibGVbdGFzay5zdGF0ZV1bU1RBUlRdOwogIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7CiAgICBpZih0YXNrLnN0YXRlID09PSBSVU5OSU5HKSB7CiAgICAgIHRhc2suc3dhcFRpbWUgPSArbmV3IERhdGUoKTsKICAgICAgdGFzay5ydW4odGFzayk7CiAgICAgIHJ1bk5leHQodGFzaywgMCk7CiAgICB9CiAgfSwgMCk7Cn07CgovKioKICogUnVuIHRoZSBuZXh0IHN1YnRhc2sgb3IgZmluaXNoIHRoaXMgdGFzay4KICoKICogQHBhcmFtIHRhc2sgdGhlIHRhc2sgdG8gcHJvY2Vzcy4KICogQHBhcmFtIHJlY3Vyc2UgdGhlIHJlY3Vyc2lvbiBjb3VudC4KICovCnZhciBydW5OZXh0ID0gZnVuY3Rpb24odGFzaywgcmVjdXJzZSkgewogIC8vIGdldCB0aW1lIHNpbmNlIGxhc3QgY29udGV4dCBzd2FwIChtcyksIGlmIGVub3VnaCB0aW1lIGhhcyBwYXNzZWQgc2V0CiAgLy8gc3dhcCB0byB0cnVlIHRvIGluZGljYXRlIHRoYXQgZG9OZXh0IHdhcyBwZXJmb3JtZWQgYXN5bmNocm9ub3VzbHkKICAvLyBhbHNvLCBpZiByZWN1cnNlIGlzIHRvbyBoaWdoIGRvIGFzeW5jaHJvbm91c2x5CiAgdmFyIHN3YXAgPQogICAgKHJlY3Vyc2UgPiBzTWF4UmVjdXJzaW9ucykgfHwKICAgICgrbmV3IERhdGUoKSAtIHRhc2suc3dhcFRpbWUpID4gc1RpbWVTbGljZTsKCiAgdmFyIGRvTmV4dCA9IGZ1bmN0aW9uKHJlY3Vyc2UpIHsKICAgIHJlY3Vyc2UrKzsKICAgIGlmKHRhc2suc3RhdGUgPT09IFJVTk5JTkcpIHsKICAgICAgaWYoc3dhcCkgewogICAgICAgIC8vIHVwZGF0ZSBzd2FwIHRpbWUKICAgICAgICB0YXNrLnN3YXBUaW1lID0gK25ldyBEYXRlKCk7CiAgICAgIH0KCiAgICAgIGlmKHRhc2suc3VidGFza3MubGVuZ3RoID4gMCkgewogICAgICAgIC8vIHJ1biBuZXh0IHN1YnRhc2sKICAgICAgICB2YXIgc3VidGFzayA9IHRhc2suc3VidGFza3Muc2hpZnQoKTsKICAgICAgICBzdWJ0YXNrLmVycm9yID0gdGFzay5lcnJvcjsKICAgICAgICBzdWJ0YXNrLnN3YXBUaW1lID0gdGFzay5zd2FwVGltZTsKICAgICAgICBzdWJ0YXNrLnVzZXJEYXRhID0gdGFzay51c2VyRGF0YTsKICAgICAgICBzdWJ0YXNrLnJ1bihzdWJ0YXNrKTsKICAgICAgICBpZighc3VidGFzay5lcnJvcikgewogICAgICAgICAgIHJ1bk5leHQoc3VidGFzaywgcmVjdXJzZSk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGZpbmlzaCh0YXNrKTsKCiAgICAgICAgaWYoIXRhc2suZXJyb3IpIHsKICAgICAgICAgIC8vIGNoYWluIGJhY2sgdXAgYW5kIHJ1biBwYXJlbnQKICAgICAgICAgIGlmKHRhc2sucGFyZW50ICE9PSBudWxsKSB7CiAgICAgICAgICAgIC8vIHByb3BhZ2F0ZSB0YXNrIGluZm8KICAgICAgICAgICAgdGFzay5wYXJlbnQuZXJyb3IgPSB0YXNrLmVycm9yOwogICAgICAgICAgICB0YXNrLnBhcmVudC5zd2FwVGltZSA9IHRhc2suc3dhcFRpbWU7CiAgICAgICAgICAgIHRhc2sucGFyZW50LnVzZXJEYXRhID0gdGFzay51c2VyRGF0YTsKCiAgICAgICAgICAgIC8vIG5vIHN1YnRhc2tzIGxlZnQsIGNhbGwgcnVuIG5leHQgc3VidGFzayBvbiBwYXJlbnQKICAgICAgICAgICAgcnVuTmV4dCh0YXNrLnBhcmVudCwgcmVjdXJzZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfTsKCiAgaWYoc3dhcCkgewogICAgLy8gd2UncmUgc3dhcHBpbmcsIHNvIHJ1biBhc3luY2hyb25vdXNseQogICAgc2V0VGltZW91dChkb05leHQsIDApOwogIH0gZWxzZSB7CiAgICAvLyBub3Qgc3dhcHBpbmcsIHNvIHJ1biBzeW5jaHJvbm91c2x5CiAgICBkb05leHQocmVjdXJzZSk7CiAgfQp9OwoKLyoqCiAqIEZpbmlzaGVzIGEgdGFzayBhbmQgbG9va3MgZm9yIHRoZSBuZXh0IHRhc2sgaW4gdGhlIHF1ZXVlIHRvIHN0YXJ0LgogKgogKiBAcGFyYW0gdGFzayB0aGUgdGFzayB0byBmaW5pc2guCiAqIEBwYXJhbSBzdXBwcmVzc0NhbGxiYWNrcyB0cnVlIHRvIHN1cHByZXNzIGNhbGxiYWNrcy4KICovCnZhciBmaW5pc2ggPSBmdW5jdGlvbih0YXNrLCBzdXBwcmVzc0NhbGxiYWNrcykgewogIC8vIHN1YnRhc2sgaXMgbm93IGRvbmUKICB0YXNrLnN0YXRlID0gRE9ORTsKCiAgZGVsZXRlIHNUYXNrc1t0YXNrLmlkXTsKICBpZihzVkwgPj0gMSkgewogICAgZm9yZ2UubG9nLnZlcmJvc2UoY2F0LCAnWyVzXVslc10gZmluaXNoJywKICAgICAgdGFzay5pZCwgdGFzay5uYW1lLCB0YXNrKTsKICB9CgogIC8vIG9ubHkgZG8gcXVldWUgcHJvY2Vzc2luZyBmb3Igcm9vdCB0YXNrcwogIGlmKHRhc2sucGFyZW50ID09PSBudWxsKSB7CiAgICAvLyByZXBvcnQgZXJyb3IgaWYgcXVldWUgaXMgbWlzc2luZwogICAgaWYoISh0YXNrLnR5cGUgaW4gc1Rhc2tRdWV1ZXMpKSB7CiAgICAgIGZvcmdlLmxvZy5lcnJvcihjYXQsCiAgICAgICAgJ1slc11bJXNdIHRhc2sgcXVldWUgbWlzc2luZyBbJXNdJywKICAgICAgICB0YXNrLmlkLCB0YXNrLm5hbWUsIHRhc2sudHlwZSk7CiAgICB9IGVsc2UgaWYoc1Rhc2tRdWV1ZXNbdGFzay50eXBlXS5sZW5ndGggPT09IDApIHsKICAgICAgLy8gcmVwb3J0IGVycm9yIGlmIHF1ZXVlIGlzIGVtcHR5CiAgICAgIGZvcmdlLmxvZy5lcnJvcihjYXQsCiAgICAgICAgJ1slc11bJXNdIHRhc2sgcXVldWUgZW1wdHkgWyVzXScsCiAgICAgICAgdGFzay5pZCwgdGFzay5uYW1lLCB0YXNrLnR5cGUpOwogICAgfSBlbHNlIGlmKHNUYXNrUXVldWVzW3Rhc2sudHlwZV1bMF0gIT09IHRhc2spIHsKICAgICAgLy8gcmVwb3J0IGVycm9yIGlmIHRoaXMgdGFzayBpc24ndCB0aGUgZmlyc3QgaW4gdGhlIHF1ZXVlCiAgICAgIGZvcmdlLmxvZy5lcnJvcihjYXQsCiAgICAgICAgJ1slc11bJXNdIHRhc2sgbm90IGZpcnN0IGluIHF1ZXVlIFslc10nLAogICAgICAgIHRhc2suaWQsIHRhc2submFtZSwgdGFzay50eXBlKTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIHJlbW92ZSBvdXJzZWx2ZXMgZnJvbSB0aGUgcXVldWUKICAgICAgc1Rhc2tRdWV1ZXNbdGFzay50eXBlXS5zaGlmdCgpOwogICAgICAvLyBjbGVhbiB1cCBxdWV1ZSBpZiBpdCBpcyBlbXB0eQogICAgICBpZihzVGFza1F1ZXVlc1t0YXNrLnR5cGVdLmxlbmd0aCA9PT0gMCkgewogICAgICAgIGlmKHNWTCA+PSAxKSB7CiAgICAgICAgICBmb3JnZS5sb2cudmVyYm9zZShjYXQsICdbJXNdWyVzXSBkZWxldGUgcXVldWUgWyVzXScsCiAgICAgICAgICAgIHRhc2suaWQsIHRhc2submFtZSwgdGFzay50eXBlKTsKICAgICAgICB9CiAgICAgICAgLyogTm90ZTogT25seSBhIHRhc2sgY2FuIGRlbGV0ZSBhIHF1ZXVlIG9mIGl0cyBvd24gdHlwZS4gVGhpcwogICAgICAgICBpcyB1c2VkIGFzIGEgd2F5IHRvIHN5bmNocm9uaXplIHRhc2tzLiBJZiBhIHF1ZXVlIGZvciBhIGNlcnRhaW4KICAgICAgICAgdGFzayB0eXBlIGV4aXN0cywgdGhlbiBhIHRhc2sgb2YgdGhhdCB0eXBlIGlzIHJ1bm5pbmcuCiAgICAgICAgICovCiAgICAgICAgZGVsZXRlIHNUYXNrUXVldWVzW3Rhc2sudHlwZV07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gZGVxdWV1ZSB0aGUgbmV4dCB0YXNrIGFuZCBzdGFydCBpdAogICAgICAgIGlmKHNWTCA+PSAxKSB7CiAgICAgICAgICBmb3JnZS5sb2cudmVyYm9zZShjYXQsCiAgICAgICAgICAgICdbJXNdWyVzXSBxdWV1ZSBzdGFydCBuZXh0IFslc10gcmVtYWluOiVzJywKICAgICAgICAgICAgdGFzay5pZCwgdGFzay5uYW1lLCB0YXNrLnR5cGUsCiAgICAgICAgICAgIHNUYXNrUXVldWVzW3Rhc2sudHlwZV0ubGVuZ3RoKTsKICAgICAgICB9CiAgICAgICAgc1Rhc2tRdWV1ZXNbdGFzay50eXBlXVswXS5zdGFydCgpOwogICAgICB9CiAgICB9CgogICAgaWYoIXN1cHByZXNzQ2FsbGJhY2tzKSB7CiAgICAgIC8vIGNhbGwgZmluYWwgY2FsbGJhY2sgaWYgb25lIGV4aXN0cwogICAgICBpZih0YXNrLmVycm9yICYmIHRhc2suZmFpbHVyZUNhbGxiYWNrKSB7CiAgICAgICAgdGFzay5mYWlsdXJlQ2FsbGJhY2sodGFzayk7CiAgICAgIH0gZWxzZSBpZighdGFzay5lcnJvciAmJiB0YXNrLnN1Y2Nlc3NDYWxsYmFjaykgewogICAgICAgIHRhc2suc3VjY2Vzc0NhbGxiYWNrKHRhc2spOwogICAgICB9CiAgICB9CiAgfQp9OwoKLyogVGFza3MgQVBJICovCmZvcmdlLnRhc2sgPSBmb3JnZS50YXNrIHx8IHt9OwoKLyoqCiAqIFN0YXJ0cyBhIG5ldyB0YXNrIHRoYXQgd2lsbCBydW4gdGhlIHBhc3NlZCBmdW5jdGlvbiBhc3luY2hyb25vdXNseS4KICoKICogSW4gb3JkZXIgdG8gZmluaXNoIHRoZSB0YXNrLCBlaXRoZXIgdGFzay5kb05leHQoKSBvciB0YXNrLmZhaWwoKQogKiAqbXVzdCogYmUgY2FsbGVkLgogKgogKiBUaGUgdGFzayBtdXN0IGhhdmUgYSB0eXBlIChhIHN0cmluZyBpZGVudGlmaWVyKSB0aGF0IGNhbiBiZSB1c2VkIHRvCiAqIHN5bmNocm9uaXplIGl0IHdpdGggb3RoZXIgdGFza3Mgb2YgdGhlIHNhbWUgdHlwZS4gVGhhdCB0eXBlIGNhbiBhbHNvCiAqIGJlIHVzZWQgdG8gY2FuY2VsIHRhc2tzIHRoYXQgaGF2ZW4ndCBzdGFydGVkIHlldC4KICoKICogVG8gc3RhcnQgYSB0YXNrLCB0aGUgZm9sbG93aW5nIG9iamVjdCBtdXN0IGJlIHByb3ZpZGVkIGFzIGEgcGFyYW1ldGVyCiAqIChlYWNoIGZ1bmN0aW9uIHRha2VzIGEgdGFzayBvYmplY3QgYXMgaXRzIGZpcnN0IHBhcmFtZXRlcik6CiAqCiAqIHsKICogICB0eXBlOiB0aGUgdHlwZSBvZiB0YXNrLgogKiAgIHJ1bjogdGhlIGZ1bmN0aW9uIHRvIHJ1biB0byBleGVjdXRlIHRoZSB0YXNrLgogKiAgIHN1Y2Nlc3M6IGEgY2FsbGJhY2sgdG8gY2FsbCB3aGVuIHRoZSB0YXNrIHN1Y2NlZWRzIChvcHRpb25hbCkuCiAqICAgZmFpbHVyZTogYSBjYWxsYmFjayB0byBjYWxsIHdoZW4gdGhlIHRhc2sgZmFpbHMgKG9wdGlvbmFsKS4KICogfQogKgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb2JqZWN0IGFzIGRlc2NyaWJlZCBhYm92ZS4KICovCmZvcmdlLnRhc2suc3RhcnQgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgLy8gY3JlYXRlIGEgbmV3IHRhc2sKICB2YXIgdGFzayA9IG5ldyBUYXNrKHsKICAgIHJ1bjogb3B0aW9ucy5ydW4sCiAgICBuYW1lOiBvcHRpb25zLm5hbWUgfHwgc05vVGFza05hbWUKICB9KTsKICB0YXNrLnR5cGUgPSBvcHRpb25zLnR5cGU7CiAgdGFzay5zdWNjZXNzQ2FsbGJhY2sgPSBvcHRpb25zLnN1Y2Nlc3MgfHwgbnVsbDsKICB0YXNrLmZhaWx1cmVDYWxsYmFjayA9IG9wdGlvbnMuZmFpbHVyZSB8fCBudWxsOwoKICAvLyBhcHBlbmQgdGhlIHRhc2sgb250byB0aGUgYXBwcm9wcmlhdGUgcXVldWUKICBpZighKHRhc2sudHlwZSBpbiBzVGFza1F1ZXVlcykpIHsKICAgIGlmKHNWTCA+PSAxKSB7CiAgICAgIGZvcmdlLmxvZy52ZXJib3NlKGNhdCwgJ1slc11bJXNdIGNyZWF0ZSBxdWV1ZSBbJXNdJywKICAgICAgICB0YXNrLmlkLCB0YXNrLm5hbWUsIHRhc2sudHlwZSk7CiAgICB9CiAgICAvLyBjcmVhdGUgdGhlIHF1ZXVlIHdpdGggdGhlIG5ldyB0YXNrCiAgICBzVGFza1F1ZXVlc1t0YXNrLnR5cGVdID0gW3Rhc2tdOwogICAgc3RhcnQodGFzayk7CiAgfSBlbHNlIHsKICAgIC8vIHB1c2ggdGhlIHRhc2sgb250byB0aGUgcXVldWUsIGl0IHdpbGwgYmUgcnVuIGFmdGVyIGEgdGFzawogICAgLy8gd2l0aCB0aGUgc2FtZSB0eXBlIGNvbXBsZXRlcwogICAgc1Rhc2tRdWV1ZXNbb3B0aW9ucy50eXBlXS5wdXNoKHRhc2spOwogIH0KfTsKCi8qKgogKiBDYW5jZWxzIGFsbCB0YXNrcyBvZiB0aGUgZ2l2ZW4gdHlwZSB0aGF0IGhhdmVuJ3Qgc3RhcnRlZCB5ZXQuCiAqCiAqIEBwYXJhbSB0eXBlIHRoZSB0eXBlIG9mIHRhc2sgdG8gY2FuY2VsLgogKi8KZm9yZ2UudGFzay5jYW5jZWwgPSBmdW5jdGlvbih0eXBlKSB7CiAgLy8gZmluZCB0aGUgdGFzayBxdWV1ZQogIGlmKHR5cGUgaW4gc1Rhc2tRdWV1ZXMpIHsKICAgIC8vIGVtcHR5IGFsbCBidXQgdGhlIGN1cnJlbnQgdGFzayBmcm9tIHRoZSBxdWV1ZQogICAgc1Rhc2tRdWV1ZXNbdHlwZV0gPSBbc1Rhc2tRdWV1ZXNbdHlwZV1bMF1dOwogIH0KfTsKCi8qKgogKiBDcmVhdGVzIGEgY29uZGl0aW9uIHZhcmlhYmxlIHRvIHN5bmNocm9uaXplIHRhc2tzLiBUbyBtYWtlIGEgdGFzayB3YWl0CiAqIG9uIHRoZSBjb25kaXRpb24gdmFyaWFibGUsIGNhbGwgdGFzay53YWl0KGNvbmRpdGlvbikuIFRvIG5vdGlmeSBhbGwKICogdGFza3MgdGhhdCBhcmUgd2FpdGluZywgY2FsbCBjb25kaXRpb24ubm90aWZ5KCkuCiAqCiAqIEByZXR1cm4gdGhlIGNvbmRpdGlvbiB2YXJpYWJsZS4KICovCmZvcmdlLnRhc2suY3JlYXRlQ29uZGl0aW9uID0gZnVuY3Rpb24oKSB7CiAgdmFyIGNvbmQgPSB7CiAgICAvLyBhbGwgdGFza3MgdGhhdCBhcmUgYmxvY2tlZAogICAgdGFza3M6IHt9CiAgfTsKCiAgLyoqCiAgICogQ2F1c2VzIHRoZSBnaXZlbiB0YXNrIHRvIGJsb2NrIHVudGlsIG5vdGlmeSBpcyBjYWxsZWQuIElmIHRoZSB0YXNrCiAgICogaXMgYWxyZWFkeSB3YWl0aW5nIG9uIHRoaXMgY29uZGl0aW9uIHRoZW4gdGhpcyBpcyBhIG5vLW9wLgogICAqCiAgICogQHBhcmFtIHRhc2sgdGhlIHRhc2sgdG8gY2F1c2UgdG8gd2FpdC4KICAgKi8KICBjb25kLndhaXQgPSBmdW5jdGlvbih0YXNrKSB7CiAgICAvLyBvbmx5IGJsb2NrIG9uY2UKICAgIGlmKCEodGFzay5pZCBpbiBjb25kLnRhc2tzKSkgewogICAgICAgdGFzay5ibG9jaygpOwogICAgICAgY29uZC50YXNrc1t0YXNrLmlkXSA9IHRhc2s7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogTm90aWZpZXMgYWxsIHdhaXRpbmcgdGFza3MgdG8gd2FrZSB1cC4KICAgKi8KICBjb25kLm5vdGlmeSA9IGZ1bmN0aW9uKCkgewogICAgLy8gc2luY2UgdW5ibG9jaygpIHdpbGwgcnVuIHRoZSBuZXh0IHRhc2sgZnJvbSBoZXJlLCBtYWtlIHN1cmUgdG8KICAgIC8vIGNsZWFyIHRoZSBjb25kaXRpb24ncyBibG9ja2VkIHRhc2sgbGlzdCBiZWZvcmUgdW5ibG9ja2luZwogICAgdmFyIHRtcCA9IGNvbmQudGFza3M7CiAgICBjb25kLnRhc2tzID0ge307CiAgICBmb3IodmFyIGlkIGluIHRtcCkgewogICAgICB0bXBbaWRdLnVuYmxvY2soKTsKICAgIH0KICB9OwoKICByZXR1cm4gY29uZDsKfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3Rhc2snOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvdGFzaycsWydyZXF1aXJlJywgJ21vZHVsZScsICcuL2RlYnVnJywgJy4vbG9nJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBOb2RlLmpzIG1vZHVsZSBmb3IgRm9yZ2UuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAyMDExLTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKdmFyIG5hbWUgPSAnZm9yZ2UnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICAvLyBzZXQgdG8gdHJ1ZSB0byBkaXNhYmxlIG5hdGl2ZSBjb2RlIGlmIGV2ZW4gaXQncyBhdmFpbGFibGUKICAgICAgZm9yZ2UgPSB7ZGlzYWJsZU5hdGl2ZUNvZGU6IGZhbHNlfTsKICAgIH0KICAgIHJldHVybjsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZTsKICB9OwogIC8vIHNldCB0byB0cnVlIHRvIGRpc2FibGUgbmF0aXZlIGNvZGUgaWYgZXZlbiBpdCdzIGF2YWlsYWJsZQogIG1vZHVsZS5leHBvcnRzLmRpc2FibGVOYXRpdmVDb2RlID0gdHJ1ZTsKICBtb2R1bGUuZXhwb3J0cyhtb2R1bGUuZXhwb3J0cyk7Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9mb3JnZScsWwogICdyZXF1aXJlJywKICAnbW9kdWxlJywKICAnLi9hZXMnLAogICcuL2Flc0NpcGhlclN1aXRlcycsCiAgJy4vYXNuMScsCiAgJy4vY2lwaGVyJywKICAnLi9jaXBoZXJNb2RlcycsCiAgJy4vZGVidWcnLAogICcuL2RlcycsCiAgJy4vaG1hYycsCiAgJy4va2VtJywKICAnLi9sb2cnLAogICcuL21kJywKICAnLi9tZ2YxJywKICAnLi9wYmtkZjInLAogICcuL3BlbScsCiAgJy4vcGtjczcnLAogICcuL3BrY3MxJywKICAnLi9wa2NzMTInLAogICcuL3BraScsCiAgJy4vcHJpbWUnLAogICcuL3BybmcnLAogICcuL3BzcycsCiAgJy4vcmFuZG9tJywKICAnLi9yYzInLAogICcuL3NzaCcsCiAgJy4vdGFzaycsCiAgJy4vdGxzJywKICAnLi91dGlsJwpdLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCgpyZXR1cm4gcmVxdWlyZSgnanMvZm9yZ2UnKTsKCn0pOwovKioNCiogQGZpbGVvdmVydmlldyBJbnRlbChyKSBBTVQgQ2VydGlmaWNhdGUgZnVuY3Rpb25zDQoqIEBhdXRob3IgWWxpYW4gU2FpbnQtSGlsYWlyZQ0KKiBAdmVyc2lvbiB2MC4yLjBiDQoqLw0KDQovLyBDaGVjayB3aGljaCBrZXkgcGFpciBtYXRjaGVzIHRoZSBwdWJsaWMga2V5IGluIHRoZSBjZXJ0aWZpY2F0ZQ0KZnVuY3Rpb24gYW10Y2VydF9saW5rQ2VydFByaXZhdGVLZXkoY2VydHMsIGtleXMpIHsNCiAgICBmb3IgKHZhciBpIGluIGNlcnRzKSB7DQogICAgICAgIHZhciBjZXJ0ID0gY2VydHNbaV07DQogICAgICAgIHRyeSB7DQogICAgICAgICAgICBpZiAoeHhDZXJ0UHJpdmF0ZUtleXMubGVuZ3RoID09IDApIHJldHVybjsNCiAgICAgICAgICAgIHZhciBwdWJsaWNLZXlQRU0gPSBmb3JnZS5wa2kucHVibGljS2V5VG9QZW0oZm9yZ2UucGtpLmNlcnRpZmljYXRlRnJvbUFzbjEoZm9yZ2UuYXNuMS5mcm9tRGVyKGNlcnQuWDUwOUNlcnRpZmljYXRlKSkucHVibGljS2V5KS5zdWJzdHJpbmcoMjggKyAzMikucmVwbGFjZSgvKFxyXG58XG58XHIpL2dtLCAiIik7DQogICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGtleXMubGVuZ3RoOyBqKyspIHsNCiAgICAgICAgICAgICAgICBpZiAocHVibGljS2V5UEVNID09PSAoa2V5c1tqXVsnREVSS2V5J10gKyAnLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tJykpIHsNCiAgICAgICAgICAgICAgICAgICAga2V5c1tqXS5YQ2VydCA9IGNlcnQ7IC8vIExpbmsgdGhlIGtleSBwYWlyIHRvIHRoZSBjZXJ0aWZpY2F0ZQ0KICAgICAgICAgICAgICAgICAgICBjZXJ0LlhQcml2YXRlS2V5ID0ga2V5c1tqXTsgLy8gTGluayB0aGUgY2VydGlmaWNhdGUgdG8gdGhlIGtleSBwYWlyDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9IGNhdGNoIChlKSB7IGNvbnNvbGUubG9nKGUpOyB9DQogICAgfQ0KfQ0KDQovLyBMb2FkIGEgUDEyIGZpbGUsIGRlY29kZXMgaXQgdXNpbmcgdGhlIHBhc3N3b3JkIGFuZCByZXR1cm5zIHRoZSBwcml2YXRlIGtleSBoYW5kbGUNCmZ1bmN0aW9uIGFtdGNlcnRfbG9hZFAxMkZpbGUoZmlsZSwgcGFzc3dvcmQsIGZ1bmMpIHsNCiAgICB0cnkgew0KICAgICAgICAvLyBFbmNvZGUgaW4gQmFzZTY0IHNvIEZvcmdlIEFQSSBjYW4gcGFyc2UgaXQuDQogICAgICAgIHZhciBwMTJEZXIgPSB3aW5kb3cuZm9yZ2UudXRpbC5kZWNvZGU2NChidG9hKGZpbGUpKTsNCiAgICAgICAgdmFyIHAxMkFzbjEgPSB3aW5kb3cuZm9yZ2UuYXNuMS5mcm9tRGVyKHAxMkRlcik7DQogICAgICAgIHZhciBwMTIgPSB3aW5kb3cuZm9yZ2UucGtjczEyLnBrY3MxMkZyb21Bc24xKHAxMkFzbjEsIHBhc3N3b3JkKTsNCg0KICAgICAgICAvLyBQcml2YXRlIGtleSBpcyBzdG9yZWQgaW4gYSBzaHJvdWRlZCBrZXkgYmFnDQogICAgICAgIHZhciBiYWdzID0gcDEyLmdldEJhZ3MoeyBiYWdUeXBlOiB3aW5kb3cuZm9yZ2UucGtpLm9pZHMucGtjczhTaHJvdWRlZEtleUJhZyB9KTsNCiAgICAgICAgY29uc29sZS5hc3NlcnQoYmFnc1t3aW5kb3cuZm9yZ2UucGtpLm9pZHMucGtjczhTaHJvdWRlZEtleUJhZ10gJiYgYmFnc1t3aW5kb3cuZm9yZ2UucGtpLm9pZHMucGtjczhTaHJvdWRlZEtleUJhZ10ubGVuZ3RoID4gMCk7DQogICAgICAgIA0KICAgICAgICAvLyBJbXBvcnQgdGhlIEZvcmdlIHByaXZhdGUga2V5IHN0cnVjdHVyZSBpbnRvIFdlYiBDcnlwdG8NCiAgICAgICAgdmFyIHByaXZhdGVLZXkgPSBiYWdzW3dpbmRvdy5mb3JnZS5wa2kub2lkcy5wa2NzOFNocm91ZGVkS2V5QmFnXVswXS5rZXk7DQogICAgICAgIHZhciByc2FQcml2YXRlS2V5ID0gd2luZG93LmZvcmdlLnBraS5wcml2YXRlS2V5VG9Bc24xKHByaXZhdGVLZXkpOw0KICAgICAgICB2YXIgcHJpdmF0ZUtleUluZm8gPSB3aW5kb3cuZm9yZ2UucGtpLndyYXBSc2FQcml2YXRlS2V5KHJzYVByaXZhdGVLZXkpOw0KICAgICAgICB2YXIgcGtjczggPSB3aW5kb3cuZm9yZ2UuYXNuMS50b0Rlcihwcml2YXRlS2V5SW5mbykuZ2V0Qnl0ZXMoKTsNCiAgICAgICAgDQogICAgICAgIC8vIEdldCB0aGUgaXNzdWVyIGF0dHJpYnV0ZXMNCiAgICAgICAgdmFyIGNlcnRCYWdzID0gcDEyLmdldEJhZ3MoeyBiYWdUeXBlOiB3aW5kb3cuZm9yZ2UucGtpLm9pZHMuY2VydEJhZyB9KTsNCiAgICAgICAgdmFyIGlzc3VlckF0dHJpYnV0ZXMgPSBjZXJ0QmFnc1t3aW5kb3cuZm9yZ2UucGtpLm9pZHMuY2VydEJhZ11bMF0uY2VydC5zdWJqZWN0LmF0dHJpYnV0ZXM7DQoNCiAgICAgICAgdmFyIGJhZ3MxID0gcDEyLmdldEJhZ3MoeyBiYWdUeXBlOiBmb3JnZS5wa2kub2lkcy5jZXJ0QmFnIH0pOw0KICAgICAgICB2YXIgY2VydCA9IGJhZ3MxW2ZvcmdlLnBraS5vaWRzLmNlcnRCYWddWzBdLmNlcnQ7DQoNCiAgICAgICAgZnVuYyhwcml2YXRlS2V5LCBpc3N1ZXJBdHRyaWJ1dGVzLCBjZXJ0KTsNCiAgICAgICAgcmV0dXJuIHRydWU7DQogICAgfSBjYXRjaCAoZXgpIHsgfQ0KICAgIHJldHVybiBmYWxzZTsNCn0NCg0KZnVuY3Rpb24gYW10Y2VydF9zaWduV2l0aENhS2V5KERFUktleSwgY2FQcml2YXRlS2V5LCBjZXJ0QXR0cmlidXRlcywgaXNzdWVyQXR0cmlidXRlcywgZXh0S2V5VXNhZ2UpIHsNCiAgICBpZiAoIWNhUHJpdmF0ZUtleSB8fCBjYVByaXZhdGVLZXkgPT0gbnVsbCkgew0KICAgICAgICB2YXIgY2VydEFuZEtleSA9IGFtdGNlcnRfY3JlYXRlQ2VydGlmaWNhdGUoaXNzdWVyQXR0cmlidXRlcyk7DQogICAgICAgIGNhUHJpdmF0ZUtleSA9IGNlcnRBbmRLZXkua2V5Ow0KICAgIH0NCiAgICByZXR1cm4gYW10Y2VydF9jcmVhdGVDZXJ0aWZpY2F0ZShjZXJ0QXR0cmlidXRlcywgY2FQcml2YXRlS2V5LCBERVJLZXksIGlzc3VlckF0dHJpYnV0ZXMsIGV4dEtleVVzYWdlKTsNCn0NCg0KLy8gLS0tIEV4dGVuZGVkIEtleSBVc2FnZSBPSUQncyAtLS0NCi8vIDEuMy42LjEuNS41LjcuMy4xICAgICAgICAgICAgPSBUTFMgU2VydmVyIGNlcnRpZmljYXRlDQovLyAxLjMuNi4xLjUuNS43LjMuMiAgICAgICAgICAgID0gVExTIENsaWVudCBjZXJ0aWZpY2F0ZQ0KLy8gMi4xNi44NDAuMS4xMTM3NDEuMS4yLjEgICAgICA9IEludGVsIEFNVCBSZW1vdGUgQ29uc29sZQ0KLy8gMi4xNi44NDAuMS4xMTM3NDEuMS4yLjIgICAgICA9IEludGVsIEFNVCBMb2NhbCBDb25zb2xlDQovLyAyLjE2Ljg0MC4xLjExMzc0MS4xLjIuMyAgICAgID0gSW50ZWwgQU1UIENsaWVudCBTZXR1cCBDZXJ0aWZpY2F0ZSAoWmVyby1Ub3VjaCkNCg0KLy8gR2VuZXJhdGUgYSBjZXJ0aWZpY2F0ZSB3aXRoIGEgc2V0IG9mIGF0dHJpYnV0ZXMgc2lnbmVkIGJ5IGEgcm9vdENlcnQuIElmIHRoZSByb290Q2VydCBpcyBvYm1pdHRlZCwgdGhlIGdlbmVyYXRlZCBjZXJ0aWZpY2F0ZSBpcyBzZWxmLXNpZ25lZC4NCmZ1bmN0aW9uIGFtdGNlcnRfY3JlYXRlQ2VydGlmaWNhdGUoY2VydEF0dHJpYnV0ZXMsIGNhUHJpdmF0ZUtleSwgREVSS2V5LCBpc3N1ZXJBdHRyaWJ1dGVzLCBleHRLZXlVc2FnZSkgew0KICAgIC8vIEdlbmVyYXRlIGEga2V5cGFpciBhbmQgY3JlYXRlIGFuIFguNTA5djMgY2VydGlmaWNhdGUNCiAgICB2YXIga2V5cywgY2VydCA9IGZvcmdlLnBraS5jcmVhdGVDZXJ0aWZpY2F0ZSgpOw0KICAgIGlmICghREVSS2V5KSB7DQogICAgICAgIGtleXMgPSBmb3JnZS5wa2kucnNhLmdlbmVyYXRlS2V5UGFpcigyMDQ4KTsNCiAgICAgICAgY2VydC5wdWJsaWNLZXkgPSBrZXlzLnB1YmxpY0tleTsNCiAgICB9IGVsc2Ugew0KICAgICAgICBjZXJ0LnB1YmxpY0tleSA9IGZvcmdlLnBraS5wdWJsaWNLZXlGcm9tUGVtKCctLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLScgKyBERVJLZXkgKyAnLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tJyk7DQogICAgfQ0KICAgIGNlcnQuc2VyaWFsTnVtYmVyID0gJycgKyBNYXRoLmZsb29yKChNYXRoLnJhbmRvbSgpICogMTAwMDAwKSArIDEpOw0KICAgIGNlcnQudmFsaWRpdHkubm90QmVmb3JlID0gbmV3IERhdGUoKTsNCiAgICBjZXJ0LnZhbGlkaXR5Lm5vdEJlZm9yZS5zZXRGdWxsWWVhcihjZXJ0LnZhbGlkaXR5Lm5vdEJlZm9yZS5nZXRGdWxsWWVhcigpIC0gMSk7IC8vIENyZWF0ZSBhIGNlcnRpZmljYXRlIHRoYXQgaXMgdmFsaWQgb25lIHllYXIgYmVmb3JlLCB0byBtYWtlIHN1cmUgb3V0LW9mLXN5bmMgY2xvY2tzIGRvbid0IHJlamVjdCB0aGlzIGNlcnQuDQogICAgY2VydC52YWxpZGl0eS5ub3RBZnRlciA9IG5ldyBEYXRlKCk7DQogICAgY2VydC52YWxpZGl0eS5ub3RBZnRlci5zZXRGdWxsWWVhcihjZXJ0LnZhbGlkaXR5Lm5vdEFmdGVyLmdldEZ1bGxZZWFyKCkgKyAzMCk7DQogICAgdmFyIGF0dHJzID0gW107DQogICAgaWYgKGNlcnRBdHRyaWJ1dGVzWydDTiddKSBhdHRycy5wdXNoKHsgbmFtZTogJ2NvbW1vbk5hbWUnLCB2YWx1ZTogY2VydEF0dHJpYnV0ZXNbJ0NOJ10gfSk7DQogICAgaWYgKGNlcnRBdHRyaWJ1dGVzWydDJ10pIGF0dHJzLnB1c2goeyBuYW1lOiAnY291bnRyeU5hbWUnLCB2YWx1ZTogY2VydEF0dHJpYnV0ZXNbJ0MnXSB9KTsNCiAgICBpZiAoY2VydEF0dHJpYnV0ZXNbJ1NUJ10pIGF0dHJzLnB1c2goeyBzaG9ydE5hbWU6ICdTVCcsIHZhbHVlOiBjZXJ0QXR0cmlidXRlc1snU1QnXSB9KTsNCiAgICBpZiAoY2VydEF0dHJpYnV0ZXNbJ08nXSkgYXR0cnMucHVzaCh7IG5hbWU6ICdvcmdhbml6YXRpb25OYW1lJywgdmFsdWU6IGNlcnRBdHRyaWJ1dGVzWydPJ10gfSk7DQogICAgY2VydC5zZXRTdWJqZWN0KGF0dHJzKTsNCg0KICAgIGlmIChjYVByaXZhdGVLZXkpIHsNCiAgICAgICAgLy8gVXNlIHJvb3QgYXR0cmlidXRlcw0KICAgICAgICB2YXIgcm9vdGF0dHJzID0gW107DQogICAgICAgIGlmIChpc3N1ZXJBdHRyaWJ1dGVzWydDTiddKSByb290YXR0cnMucHVzaCh7IG5hbWU6ICdjb21tb25OYW1lJywgdmFsdWU6IGlzc3VlckF0dHJpYnV0ZXNbJ0NOJ10gfSk7DQogICAgICAgIGlmIChpc3N1ZXJBdHRyaWJ1dGVzWydDJ10pIHJvb3RhdHRycy5wdXNoKHsgbmFtZTogJ2NvdW50cnlOYW1lJywgdmFsdWU6IGlzc3VlckF0dHJpYnV0ZXNbJ0MnXSB9KTsNCiAgICAgICAgaWYgKGlzc3VlckF0dHJpYnV0ZXNbJ1NUJ10pIHJvb3RhdHRycy5wdXNoKHsgc2hvcnROYW1lOiAnU1QnLCB2YWx1ZTogaXNzdWVyQXR0cmlidXRlc1snU1QnXSB9KTsNCiAgICAgICAgaWYgKGlzc3VlckF0dHJpYnV0ZXNbJ08nXSkgcm9vdGF0dHJzLnB1c2goeyBuYW1lOiAnb3JnYW5pemF0aW9uTmFtZScsIHZhbHVlOiBpc3N1ZXJBdHRyaWJ1dGVzWydPJ10gfSk7DQogICAgICAgIGNlcnQuc2V0SXNzdWVyKHJvb3RhdHRycyk7DQogICAgfSBlbHNlIHsNCiAgICAgICAgLy8gVXNlIG91ciBvd24gYXR0cmlidXRlcw0KICAgICAgICBjZXJ0LnNldElzc3VlcihhdHRycyk7DQogICAgfQ0KDQogICAgaWYgKGNhUHJpdmF0ZUtleSA9PSB1bmRlZmluZWQpIHsNCiAgICAgICAgLy8gQ3JlYXRlIGEgcm9vdCBjZXJ0aWZpY2F0ZQ0KICAgICAgICBjZXJ0LnNldEV4dGVuc2lvbnMoW3sNCiAgICAgICAgICAgIG5hbWU6ICdiYXNpY0NvbnN0cmFpbnRzJywNCiAgICAgICAgICAgIGNBOiB0cnVlDQogICAgICAgIH0sIHsNCiAgICAgICAgICAgIG5hbWU6ICduc0NlcnRUeXBlJywNCiAgICAgICAgICAgIHNzbENBOiB0cnVlLA0KICAgICAgICAgICAgZW1haWxDQTogdHJ1ZSwNCiAgICAgICAgICAgIG9iakNBOiB0cnVlDQogICAgICAgIH0sIHsNCiAgICAgICAgICAgIG5hbWU6ICdzdWJqZWN0S2V5SWRlbnRpZmllcicNCiAgICAgICAgfV0pOw0KICAgIH0gZWxzZSB7DQogICAgICAgIGlmIChleHRLZXlVc2FnZSA9PSBudWxsKSB7IGV4dEtleVVzYWdlID0geyBuYW1lOiAnZXh0S2V5VXNhZ2UnLCBzZXJ2ZXJBdXRoOiB0cnVlLCB9IH0gZWxzZSB7IGV4dEtleVVzYWdlLm5hbWUgPSAnZXh0S2V5VXNhZ2UnOyB9DQoNCiAgICAgICAgLyoNCiAgICAgICAgew0KICAgICAgICAgICAgbmFtZTogJ2V4dEtleVVzYWdlJywNCiAgICAgICAgICAgIHNlcnZlckF1dGg6IHRydWUsDQogICAgICAgICAgICBjbGllbnRBdXRoOiB0cnVlLA0KICAgICAgICAgICAgY29kZVNpZ25pbmc6IHRydWUsDQogICAgICAgICAgICBlbWFpbFByb3RlY3Rpb246IHRydWUsDQogICAgICAgICAgICB0aW1lU3RhbXBpbmc6IHRydWUsDQogICAgICAgICAgICAnMi4xNi44NDAuMS4xMTM3NDEuMS4yLjEnOiB0cnVlDQogICAgICAgIH0NCiAgICAgICAgKi8NCg0KICAgICAgICAvLyBDcmVhdGUgYSBsZWFmIGNlcnRpZmljYXRlDQogICAgICAgIGNlcnQuc2V0RXh0ZW5zaW9ucyhbew0KICAgICAgICAgICAgbmFtZTogJ2Jhc2ljQ29uc3RyYWludHMnDQogICAgICAgIH0sIHsNCiAgICAgICAgICAgIG5hbWU6ICdrZXlVc2FnZScsDQogICAgICAgICAgICBrZXlDZXJ0U2lnbjogdHJ1ZSwNCiAgICAgICAgICAgIGRpZ2l0YWxTaWduYXR1cmU6IHRydWUsDQogICAgICAgICAgICBub25SZXB1ZGlhdGlvbjogdHJ1ZSwNCiAgICAgICAgICAgIGtleUVuY2lwaGVybWVudDogdHJ1ZSwNCiAgICAgICAgICAgIGRhdGFFbmNpcGhlcm1lbnQ6IHRydWUNCiAgICAgICAgfSwgZXh0S2V5VXNhZ2UsIHsNCiAgICAgICAgICAgIG5hbWU6ICduc0NlcnRUeXBlJywNCiAgICAgICAgICAgIGNsaWVudDogdHJ1ZSwNCiAgICAgICAgICAgIHNlcnZlcjogdHJ1ZSwNCiAgICAgICAgICAgIGVtYWlsOiB0cnVlLA0KICAgICAgICAgICAgb2Jqc2lnbjogdHJ1ZSwNCiAgICAgICAgfSwgew0KICAgICAgICAgICAgbmFtZTogJ3N1YmplY3RLZXlJZGVudGlmaWVyJw0KICAgICAgICB9XSk7DQogICAgfQ0KDQogICAgLy8gU2VsZi1zaWduIGNlcnRpZmljYXRlDQogICAgaWYgKGNhUHJpdmF0ZUtleSkgew0KICAgICAgICBjZXJ0LnNpZ24oY2FQcml2YXRlS2V5LCBmb3JnZS5tZC5zaGEyNTYuY3JlYXRlKCkpOw0KICAgIH0gZWxzZSB7DQogICAgICAgIGNlcnQuc2lnbihrZXlzLnByaXZhdGVLZXksIGZvcmdlLm1kLnNoYTI1Ni5jcmVhdGUoKSk7DQogICAgfQ0KDQogICAgaWYgKERFUktleSkgew0KICAgICAgICByZXR1cm4gY2VydDsNCiAgICB9IGVsc2Ugew0KICAgICAgICByZXR1cm4geyAnY2VydCc6IGNlcnQsICdrZXknOiBrZXlzLnByaXZhdGVLZXkgfTsNCiAgICB9DQp9DQoNCmZ1bmN0aW9uIF9zdHJpbmdUb0FycmF5QnVmZmVyKHN0cikgew0KICAgIHZhciBidWYgPSBuZXcgQXJyYXlCdWZmZXIoc3RyLmxlbmd0aCk7DQogICAgdmFyIGJ1ZlZpZXcgPSBuZXcgVWludDhBcnJheShidWYpOw0KICAgIGZvciAodmFyIGkgPSAwLCBzdHJMZW4gPSBzdHIubGVuZ3RoOyBpIDwgc3RyTGVuOyBpKyspIHsgYnVmVmlld1tpXSA9IHN0ci5jaGFyQ29kZUF0KGkpOyB9DQogICAgcmV0dXJuIGJ1ZjsNCn0NCg0KZnVuY3Rpb24gX2FycmF5QnVmZmVyVG9TdHJpbmcoYnVmZmVyKSB7DQogICAgdmFyIGJpbmFyeSA9ICcnOw0KICAgIHZhciBieXRlcyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7DQogICAgdmFyIGxlbiA9IGJ5dGVzLmJ5dGVMZW5ndGg7DQogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykgeyBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7IH0NCiAgICByZXR1cm4gYmluYXJ5Ow0KfQ0KLyoqDQoqIEBmaWxlb3ZlcnZpZXcgU2NyaXB0IENvbXBpbGVyIC8gRGVjb21waWxlciAvIFJ1bm5lcg0KKiBAYXV0aG9yIFlsaWFuIFNhaW50LUhpbGFpcmUNCiogQHZlcnNpb24gdjAuMS4wZQ0KKi8NCg0KLy8gQ29yZSBmdW5jdGlvbnMNCnNjcmlwdF9mdW5jdGlvblRhYmxlMSA9IFsnbm9wJywgJ2p1bXAnLCAnc2V0JywgJ3ByaW50JywgJ2RpYWxvZycsICdnZXRpdGVtJywgJ3N1YnN0cicsICdpbmRleG9mJywgJ3NwbGl0JywgJ2pvaW4nLCAnbGVuZ3RoJywgJ2pzb25wYXJzZScsICdqc29uc3RyJywgJ2FkZCcsICdzdWJzdHJhY3QnLCAncGFyc2VpbnQnLCAnd3NiYXRjaGVudW0nLCAnd3NwdXQnLCAnd3NjcmVhdGUnLCAnd3NkZWxldGUnLCAnd3NleGVjJywgJ3NjcmlwdHNwZWVkJywgJ3dzc3Vic2NyaWJlJywgJ3dzdW5zdWJzY3JpYmUnLCAncmVhZGNoYXInLCAnc2lnbndpdGhkdW1teWNhJ107DQoNCi8vIGZ1bmN0aW9ucyBvZiB0eXBlIEFSRzEgPSBmdW5jKEFSRzIsIEFSRzMsIEFSRzQsIEFSRzUsIEFSRzYpDQpzY3JpcHRfZnVuY3Rpb25UYWJsZTIgPSBbJ2VuY29kZXVyaScsICdkZWNvZGV1cmknLCAncGFzc3dvcmRjaGVjaycsICdhdG9iJywgJ2J0b2EnLCAnaGV4MnN0cicsICdzdHIyaGV4JywgJ3JhbmRvbScsICdtZDUnLCAnbWFrZXRvYXJyYXknLCAncmVhZHNob3J0JywgJ3JlYWRzaG9ydHgnLCAncmVhZGludCcsICdyZWFkc2ludCcsICdyZWFkaW50eCcsICdzaG9ydHRvc3RyJywgJ3Nob3J0dG9zdHJ4JywgJ2ludHRvc3RyJywgJ2ludHRvc3RyeCddOw0KDQovLyBmdW5jdGlvbnMgb2YgdHlwZSBBUkcxID0gZnVuYyhBUkcyLCBBUkczLCBBUkc0LCBBUkc1LCBBUkc2KQ0Kc2NyaXB0X2Z1bmN0aW9uVGFibGVYMiA9IFtlbmNvZGVVUkksIGRlY29kZVVSSSwgcGFzc3dvcmRjaGVjaywgd2luZG93LmF0b2IuYmluZCh3aW5kb3cpLCB3aW5kb3cuYnRvYS5iaW5kKHdpbmRvdyksIGhleDJyc3RyLCByc3RyMmhleCwgcmFuZG9tLCByc3RyX21kNSwgTWFrZVRvQXJyYXksIFJlYWRTaG9ydCwgUmVhZFNob3J0WCwgUmVhZEludCwgUmVhZFNJbnQsIFJlYWRJbnRYLCBTaG9ydFRvU3RyLCBTaG9ydFRvU3RyWCwgSW50VG9TdHIsIEludFRvU3RyWF07DQoNCi8vIE9wdGlvbmFsIGZ1bmN0aW9ucyBvZiB0eXBlIEFSRzEgPSBmdW5jKEFSRzIsIEFSRzMsIEFSRzQsIEFSRzUsIEFSRzYpDQpzY3JpcHRfZnVuY3Rpb25UYWJsZTMgPSBbJ3B1bGxzeXN0ZW1zdGF0dXMnLCAncHVsbGV2ZW50bG9nJywgJ3B1bGxhdWRpdGxvZycsICdwdWxsY2VydGlmaWNhdGVzJywgJ3B1bGx3YXRjaGRvZycsICdwdWxsc3lzdGVtZGVmZW5zZScsICdwdWxsaGFyZHdhcmUnLCAncHVsbHVzZXJpbmZvJywgJ3B1bGxyZW1vdGVhY2Nlc3MnLCAnaGlnaGxpZ2h0YmxvY2snLCAnZGlzY29ubmVjdCcsICdnZXRzaWRzdHJpbmcnLCAnZ2V0c2lkYnl0ZWFycmF5JywgJ3B1bGxldmVudHN1YnNjcmlwdGlvbnMnXTsNCg0KLy8gT3B0aW9uYWwgZnVuY3Rpb25zIG9mIHR5cGUgQVJHMSA9IGZ1bmMoQVJHMiwgQVJHMywgQVJHNCwgQVJHNSwgQVJHNikNCnNjcmlwdF9mdW5jdGlvblRhYmxlWDMgPSBbDQogICAgUHVsbFN5c3RlbVN0YXR1cw0KICAgICwNCiAgICANCiAgICBQdWxsRXZlbnRMb2cNCiAgICAgICAgLA0KICAgIA0KICAgIFB1bGxBdWRpdExvZw0KICAgICAgICAsDQogICAgDQogICAgUHVsbENlcnRpZmljYXRlcw0KICAgICAgICAsDQogICAgDQogICAgUHVsbFdhdGNoZG9nDQogICAgICAgICwNCiAgICANCiAgICBQdWxsU3lzdGVtRGVmZW5zZQ0KICAgICAgICAsDQogICAgDQogICAgUHVsbEhhcmR3YXJlDQogICAgICAgICwNCiAgICBQdWxsVXNlckluZm8NCiAgICAsDQogICAgDQogICAgUHVsbFJlbW90ZUFjY2Vzcw0KICAgICAgICAsDQogICAgDQogICAgc2NyaXB0X0hpZ2hsaWdodEJsb2NrDQogICAgICAgICwNCiAgICAgICAgLA0KICAgIGZ1bmN0aW9uIChydW5uZXIsIHgpIHsgcmV0dXJuIEdldFNpZFN0cmluZyh4KTsgfQ0KICAgICwNCiAgICBmdW5jdGlvbiAocnVubmVyLCB4KSB7IHJldHVybiBHZXRTaWRCeXRlQXJyYXkoeCk7IH0NCiAgICAsDQogICAgXTsNCg0KLy8gU2V0dXAgdGhlIHNjcmlwdCBzdGF0ZQ0KZnVuY3Rpb24gc2NyaXB0X3NldHVwKGJpbmFyeSwgc3RhcnR2YXJzKSB7DQogICAgdmFyIG9iaiA9IHsgc3RhcnR2YXJzOnN0YXJ0dmFycyB9Ow0KICAgIGlmIChiaW5hcnkubGVuZ3RoIDwgNikgeyBjb25zb2xlLmVycm9yKCdJbnZhbGlkIHNjcmlwdCBsZW5ndGgnKTsgcmV0dXJuIG51bGw7IH0gLy8gU2NyaXB0IG11c3QgaGF2ZSBhdCBsZWFzdCA2IGJ5dGUgaGVhZGVyDQogICAgaWYgKFJlYWRJbnQoYmluYXJ5LCAwKSAhPSAweDI0N0QyOTQ1KSB7IGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgYmluYXJ5IHNjcmlwdCcpOyByZXR1cm4gbnVsbDsgfSAvLyBDaGVjayB0aGUgc2NyaXB0IG1hZ2ljIGhlYWRlcg0KICAgIGlmIChSZWFkU2hvcnQoYmluYXJ5LCA0KSA+IDEpIHsgY29uc29sZS5lcnJvcignVW5zdXBwb3J0ZWQgc2NyaXB0IHZlcnNpb24nKTsgcmV0dXJuIG51bGw7IH0gLy8gQ2hlY2sgdGhlIHNjcmlwdCB2ZXJzaW9uDQogICAgb2JqLnNjcmlwdCA9IGJpbmFyeS5zdWJzdHJpbmcoNik7DQogICAgLy8gb2JqLm9uU3RlcDsNCiAgICAvLyBvYmoub25Db25zb2xlOw0KDQogICAgLy8gUmVzZXQgdGhlIHNjcmlwdCB0byB0aGUgc3RhcnQNCiAgICBvYmoucmVzZXQgPSBmdW5jdGlvbiAoc3RlcHNwZWVkKSB7DQogICAgICAgIG9iai5zdG9wKCk7DQogICAgICAgIG9iai5pcCA9IDA7DQogICAgICAgIG9iai52YXJpYWJsZXMgPSBzdGFydHZhcnM7DQogICAgICAgIG9iai5zdGF0ZSA9IDE7DQogICAgfQ0KDQogICAgLy8gU3RhcnQgdGhlIHNjcmlwdA0KICAgIG9iai5zdGFydCA9IGZ1bmN0aW9uIChzdGVwc3BlZWQpIHsNCiAgICAgICAgb2JqLnN0b3AoKTsNCiAgICAgICAgb2JqLnN0ZXBzcGVlZCA9IHN0ZXBzcGVlZDsNCiAgICAgICAgaWYgKHN0ZXBzcGVlZCA+IDApIHsgb2JqLnRpbWVyID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkgeyBvYmouc3RlcCgpIH0sIHN0ZXBzcGVlZCk7IH0NCiAgICB9DQoNCiAgICAvLyBTdG9wIHRoZSBzY3JpcHQNCiAgICBvYmouc3RvcCA9IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgaWYgKG9iai50aW1lciAhPSBudWxsKSB7IGNsZWFySW50ZXJ2YWwob2JqLnRpbWVyKTsgfQ0KICAgICAgICBvYmoudGltZXIgPSBudWxsOw0KICAgICAgICBvYmouc3RlcHNwZWVkID0gMDsNCiAgICB9DQoNCiAgICAvLyBmdW5jdGlvbiB1c2VkIHRvIGxvYWQgYW5kIHN0b3JlIHZhcmlhYmxlIHZhbHVlcw0KICAgIG9iai5nZXRWYXIgPSBmdW5jdGlvbiAobmFtZSkgeyBpZiAobmFtZSA9PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWQ7IHJldHVybiBvYmouZ2V0VmFyRXgobmFtZS5zcGxpdCgnLicpLCBvYmoudmFyaWFibGVzKTsgfQ0KICAgIG9iai5nZXRWYXJFeCA9IGZ1bmN0aW9uIChuYW1lLCB2YWwpIHsgdHJ5IHsgaWYgKG5hbWUgPT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkOyBpZiAobmFtZS5sZW5ndGggPT0gMCkgcmV0dXJuIHZhbDsgcmV0dXJuIG9iai5nZXRWYXJFeChuYW1lLnNsaWNlKDEpLCB2YWxbbmFtZVswXV0pOyB9IGNhdGNoIChlKSB7IHJldHVybiBudWxsOyB9IH0NCiAgICBvYmouc2V0VmFyID0gZnVuY3Rpb24gKG5hbWUsIHZhbCkgeyBvYmouc2V0VmFyRXgobmFtZS5zcGxpdCgnLicpLCBvYmoudmFyaWFibGVzLCB2YWwpOyB9DQogICAgb2JqLnNldFZhckV4ID0gZnVuY3Rpb24gKG5hbWUsIHZhcnMsIHZhbCkgeyBpZiAobmFtZS5sZW5ndGggPT0gMSkgeyB2YXJzW25hbWVbMF1dID0gdmFsOyB9IGVsc2UgeyBvYmouc2V0VmFyRXgobmFtZS5zbGljZSgxKSwgdmFyc1tuYW1lWzBdXSwgdmFsKTsgfSB9DQoNCiAgICAvLyBSdW4gdGhlIHNjcmlwdCBvbmUgc3RlcCBmb3J3YXJkDQogICAgb2JqLnN0ZXAgPSBmdW5jdGlvbiAoKSB7DQogICAgICAgIGlmIChvYmouc3RhdGUgIT0gMSkgcmV0dXJuOw0KICAgICAgICBpZiAob2JqLmlwIDwgb2JqLnNjcmlwdC5sZW5ndGgpIHsNCiAgICAgICAgICAgIHZhciBjbWRpZCA9IFJlYWRTaG9ydChvYmouc2NyaXB0LCBvYmouaXApOw0KICAgICAgICAgICAgdmFyIGNtZGxlbiA9IFJlYWRTaG9ydChvYmouc2NyaXB0LCBvYmouaXAgKyAyKTsNCiAgICAgICAgICAgIHZhciBhcmdjb3VudCA9IFJlYWRTaG9ydChvYmouc2NyaXB0LCBvYmouaXAgKyA0KTsNCiAgICAgICAgICAgIHZhciBhcmdwdHIgPSBvYmouaXAgKyA2Ow0KICAgICAgICAgICAgdmFyIGFyZ3MgPSBbXTsNCg0KICAgICAgICAgICAgLy8gQ2xlYXIgYWxsIHRlbXAgdmFyaWFibGVzIChUaGlzIGlzIG9wdGlvbmFsKQ0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBvYmoudmFyaWFibGVzKSB7IGlmIChpLnN0YXJ0c1dpdGgoJ19fJykpIHsgZGVsZXRlIG9iai52YXJpYWJsZXNbaV07IH0gfQ0KDQogICAgICAgICAgICAvLyBMb29wIG9uIGVhY2ggYXJndW1lbnQsIG1vdmluZyBmb3J3YXJkIGJ5IHRoZSBhcmd1bWVudCBsZW5ndGggZWFjaCB0aW1lDQogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ2NvdW50OyBpKyspIHsNCiAgICAgICAgICAgICAgICB2YXIgYXJnbGVuID0gUmVhZFNob3J0KG9iai5zY3JpcHQsIGFyZ3B0cik7DQogICAgICAgICAgICAgICAgdmFyIGFyZ3ZhbCA9IG9iai5zY3JpcHQuc3Vic3RyaW5nKGFyZ3B0ciArIDIsIGFyZ3B0ciArIDIgKyBhcmdsZW4pOw0KICAgICAgICAgICAgICAgIHZhciBhcmd0eXAgPSBhcmd2YWwuY2hhckNvZGVBdCgwKTsNCiAgICAgICAgICAgICAgICBhcmd2YWwgPSBhcmd2YWwuc3Vic3RyaW5nKDEpOw0KICAgICAgICAgICAgICAgIGlmIChhcmd0eXAgPCAyKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgdmFsdWUgYW5kIHJlcGxhY2UgYWxsIHt2YXJ9IHdpdGggdmFyaWFibGUgdmFsdWVzDQogICAgICAgICAgICAgICAgICAgIHdoaWxlIChhcmd2YWwuc3BsaXQoInsiKS5sZW5ndGggPiAxKSB7IHZhciB0ID0gYXJndmFsLnNwbGl0KCJ7IikucG9wKCkuc3BsaXQoIn0iKS5zaGlmdCgpOyBhcmd2YWwgPSBhcmd2YWwucmVwbGFjZSgneycgKyB0ICsgJ30nLCBvYmouZ2V0VmFyKHQpKTsgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAoYXJndHlwID09IDEpIHsgb2JqLnZhcmlhYmxlc1snX18nICsgaV0gPSBkZWNvZGVVUkkoYXJndmFsKTsgYXJndmFsID0gJ19fJyArIGk7IH0gLy8gSWYgYXJndHlwIGlzIDEsIHRoaXMgaXMgYSBsaXRlcmFsLiBTdG9yZSBpbiB0ZW1wIHZhcmlhYmxlLg0KICAgICAgICAgICAgICAgICAgICBhcmdzLnB1c2goYXJndmFsKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYgKGFyZ3R5cCA9PSAyIHx8IGFyZ3R5cCA9PSAzKSB7DQogICAgICAgICAgICAgICAgICAgIG9iai52YXJpYWJsZXNbJ19fJyArIGldID0gUmVhZFNJbnQoYXJndmFsLCAwKTsNCiAgICAgICAgICAgICAgICAgICAgYXJncy5wdXNoKCdfXycgKyBpKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgYXJncHRyICs9ICgyICsgYXJnbGVuKTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gTW92ZSBpbnN0cnVjdGlvbiBwb2ludGVyIGZvcndhcmQgYnkgY29tbWFuZCBzaXplDQogICAgICAgICAgICBvYmouaXAgKz0gY21kbGVuOw0KDQogICAgICAgICAgICAvLyBHZXQgYWxsIHZhcmlhYmxlIHZhbHVlcw0KICAgICAgICAgICAgdmFyIGFyZ3N2YWwgPSBbXTsNCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTA7IGkrKykgeyBhcmdzdmFsLnB1c2gob2JqLmdldFZhcihhcmdzW2ldKSk7IH0NCiAgICAgICAgICAgIHZhciBzdG9yZUluQXJnMDsNCg0KICAgICAgICAgICAgdHJ5IHsNCiAgICAgICAgICAgICAgICBpZiAoY21kaWQgPCAxMDAwMCkgew0KICAgICAgICAgICAgICAgICAgICAvLyBMZXRzIHJ1biB0aGUgYWN0dWFsIGNvbW1hbmQNCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjbWRpZCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAwOiAvLyBub3ANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTogLy8ganVtcChsYWJlbCkgb3IganVtcChsYWJlbCwgYSwgY29tcGFyZSwgYikNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJnc3ZhbFsyXSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXJnc3ZhbFsyXSA9PSAnPCcgJiYgYXJnc3ZhbFsxXSA8IGFyZ3N2YWxbM10pIHx8DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXJnc3ZhbFsyXSA9PSAnPD0nICYmIGFyZ3N2YWxbMV0gPD0gYXJnc3ZhbFszXSkgfHwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcmdzdmFsWzJdID09ICchPScgJiYgYXJnc3ZhbFsxXSAhPSBhcmdzdmFsWzNdKSB8fA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFyZ3N2YWxbMl0gPT0gJz0nICYmIGFyZ3N2YWxbMV0gPT0gYXJnc3ZhbFszXSkgfHwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcmdzdmFsWzJdID09ICc+PScgJiYgYXJnc3ZhbFsxXSA+PSBhcmdzdmFsWzNdKSB8fA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFyZ3N2YWxbMl0gPT0gJz4nICYmIGFyZ3N2YWxbMV0gPiBhcmdzdmFsWzNdKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHsgb2JqLmlwID0gYXJnc3ZhbFswXTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5pcCA9IGFyZ3N2YWxbMF07IC8vIFNldCB0aGUgaW5zdHJ1Y3Rpb24gcG9pbnRlciB0byB0aGUgbmV3IGxvY2F0aW9uIGluIHRoZSBzY3JpcHQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IC8vIHNldCh2YXJpYWJsZSwgdmFsdWUpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3NbMV0gPT0gdW5kZWZpbmVkKSBkZWxldGUgb2JqLnZhcmlhYmxlc1thcmdzWzBdXTsgZWxzZSBvYmouc2V0VmFyKGFyZ3NbMF0sIGFyZ3N2YWxbMV0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOiAvLyBwcmludChtZXNzYWdlKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvYmoub25Db25zb2xlKSB7IG9iai5vbkNvbnNvbGUob2JqLnRvU3RyaW5nKGFyZ3N2YWxbMF0pLCBvYmopOyB9IGVsc2UgeyBjb25zb2xlLmxvZyhvYmoudG9TdHJpbmcoYXJnc3ZhbFswXSkpOyB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIFEob2JqLmNvbnNvbGVpZCkudmFsdWUgKz0gKCkgKyAnXG4nKTsgUShvYmouY29uc29sZSkuc2Nyb2xsVG9wID0gUShvYmouY29uc29sZSkuc2Nyb2xsSGVpZ2h0Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiAvLyBkaWFsb2codGl0bGUsIGNvbnRlbnQsIGJ1dHRvbnMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouZGlhbG9nID0gdHJ1ZTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCBhcmdzdmFsWzBdLCBhcmdzdmFsWzJdLCBvYmoueHhTdGVwRGlhbG9nT2ssIGFyZ3N2YWxbMV0sIG9iaik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDU6IC8vIGdldGl0ZW0oYSwgYiwgYykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIGFyZ3N2YWxbMV0pIHsgaWYgKGFyZ3N2YWxbMV1baV1bYXJnc3ZhbFsyXV0gPT0gYXJnc3ZhbFszXSkgeyBzdG9yZUluQXJnMCA9IGk7IH0gfTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNjogLy8gc3Vic3RyKHZhcmlhYmxlX2Rlc3QsIHZhcmlhYmxlX3NyYywgaW5kZXgsIGxlbikNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUluQXJnMCA9IGFyZ3N2YWxbMV0uc3Vic3RyKGFyZ3N2YWxbMl0sIGFyZ3N2YWxbM10pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA3OiAvLyBpbmRleE9mKHZhcmlhYmxlX2Rlc3QsIHZhcmlhYmxlX3NyYywgaW5kZXgsIGxlbikNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUluQXJnMCA9IGFyZ3N2YWxbMV0uaW5kZXhPZihhcmdzdmFsWzJdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgODogLy8gc3BsaXQodmFyaWFibGVfZGVzdCwgdmFyaWFibGVfc3JjLCBzZXBhcmF0b3IpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmVJbkFyZzAgPSBhcmdzdmFsWzFdLnNwbGl0KGFyZ3N2YWxbMl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA5OiAvLyBqb2luKHZhcmlhYmxlX2Rlc3QsIHZhcmlhYmxlX3NyYywgc2VwYXJhdG9yKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlSW5BcmcwID0gYXJnc3ZhbFsxXS5qb2luKGFyZ3N2YWxbMl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMDogLy8gbGVuZ3RoKHZhcmlhYmxlX2Rlc3QsIHZhcmlhYmxlX3NyYykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUluQXJnMCA9IGFyZ3N2YWxbMV0ubGVuZ3RoOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMTogLy8ganNvbnBhcnNlKHZhcmlhYmxlX2Rlc3QsIGpzb24pDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmVJbkFyZzAgPSBKU09OLnBhcnNlKGFyZ3N2YWxbMV0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMjogLy8ganNvbnN0cih2YXJpYWJsZV9kZXN0LCB2YXJpYWJsZV9zcmMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmVJbkFyZzAgPSBKU09OLnN0cmluZ2lmeShhcmdzdmFsWzFdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTM6IC8vIGFkZCh2YXJpYWJsZV9kZXN0LCB2YXJpYWJsZV9zcmMsIHZhbHVlKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlSW5BcmcwID0gKGFyZ3N2YWxbMV0gKyBhcmdzdmFsWzJdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTQ6IC8vIHN1YnN0cmFjdCh2YXJpYWJsZV9kZXN0LCB2YXJpYWJsZV9zcmMsIHZhbHVlKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlSW5BcmcwID0gKGFyZ3N2YWxbMV0gLSBhcmdzdmFsWzJdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTU6IC8vIHBhcnNlSW50KHZhcmlhYmxlX2Rlc3QsIHZhcmlhYmxlX3NyYykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUluQXJnMCA9IHBhcnNlSW50KGFyZ3N2YWxbMV0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNjogLy8gd3NiYXRjaGVudW0obmFtZSwgb2JqZWN0TGlzdCkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouc3RhdGUgPSAyOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5hbXRzdGFjay5CYXRjaEVudW0oYXJnc3ZhbFswXSwgYXJnc3ZhbFsxXSwgb2JqLnh4V3NtYW5SZXR1cm4sIG9iaik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE3OiAvLyB3c3B1dChuYW1lLCBhcmdzKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5zdGF0ZSA9IDI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmFtdHN0YWNrLlB1dChhcmdzdmFsWzBdLCBhcmdzdmFsWzFdLCBvYmoueHhXc21hblJldHVybiwgb2JqKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTg6IC8vIHdzY3JlYXRlKG5hbWUsIGFyZ3MpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouYW10c3RhY2suQ3JlYXRlKGFyZ3N2YWxbMF0sIGFyZ3N2YWxbMV0sIG9iai54eFdzbWFuUmV0dXJuLCBvYmopOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOTogLy8gd3NkZWxldGUobmFtZSwgYXJncykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouc3RhdGUgPSAyOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5hbXRzdGFjay5EZWxldGUoYXJnc3ZhbFswXSwgYXJnc3ZhbFsxXSwgb2JqLnh4V3NtYW5SZXR1cm4sIG9iaik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIwOiAvLyB3c2V4ZWMobmFtZSwgbWV0aG9kLCBhcmdzLCBzZWxlY3RvcnMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouYW10c3RhY2suRXhlYyhhcmdzdmFsWzBdLCBhcmdzdmFsWzFdLCBhcmdzdmFsWzJdLCBvYmoueHhXc21hblJldHVybiwgb2JqLCAwLCBhcmdzdmFsWzNdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjE6IC8vIFNjcmlwdCBTcGVlZA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5zdGVwc3BlZWQgPSBhcmdzdmFsWzBdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvYmoudGltZXIgIT0gbnVsbCkgeyBjbGVhckludGVydmFsKG9iai50aW1lcik7IG9iai50aW1lciA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHsgb2JqLnN0ZXAoKSB9LCBvYmouc3RlcHNwZWVkKTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMjogLy8gd3NzdWJzY3JpYmUobmFtZSwgZGVsaXZlcnksIHVybCwgc2VsZWN0b3JzLCBvcGFxdWUsIHVzZXIsIHBhc3MpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouYW10c3RhY2suU3Vic2NyaWJlKGFyZ3N2YWxbMF0sIGFyZ3N2YWxbMV0sIGFyZ3N2YWxbMl0sIG9iai54eFdzbWFuUmV0dXJuLCBvYmosIDAsIGFyZ3N2YWxbM10sIGFyZ3N2YWxbNF0sIGFyZ3N2YWxbNV0sIGFyZ3N2YWxbNl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMzogLy8gd3N1bnN1YnNjcmliZShuYW1lLCBzZWxlY3RvcnMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouYW10c3RhY2suVW5TdWJzY3JpYmUoYXJnc3ZhbFswXSwgb2JqLnh4V3NtYW5SZXR1cm4sIG9iaiwgMCwgYXJnc3ZhbFsxXSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI0OiAvLyByZWFkY2hhcihzdHIsIHBvcykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhhcmdzdmFsWzFdLCBhcmdzdmFsWzJdLCBhcmdzdmFsWzFdLmNoYXJDb2RlQXQoYXJnc3ZhbFsyXSkpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlSW5BcmcwID0gYXJnc3ZhbFsxXS5jaGFyQ29kZUF0KGFyZ3N2YWxbMl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyNTogLy8gc2lnbldpdGhEdW1teUNhDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBERVJLZXksIHh4Q2FQcml2YXRlS2V5LCBjZXJ0YXR0cmlidXRlcywgaXNzdWVyYXR0cmlidXRlcw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFtdGNlcnRfc2lnbldpdGhDYUtleShhcmdzdmFsWzBdLCBudWxsLCBhcmdzdmFsWzFdLCB7ICdDTic6ICdVbnRydXN0ZWQgUm9vdCBDZXJ0aWZpY2F0ZScgfSwgb2JqLnh4U2lnbldpdGhEdW1teUNhUmV0dXJuKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gOTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCJTY3JpcHQgRXJyb3IsIHVua25vd24gY29tbWFuZDogIiArIGNtZGlkKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChjbWRpZCA8IDIwMDAwKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAvLyBmdW5jdGlvbnMgb2YgdHlwZSBBUkcxID0gZnVuYyhBUkcyLCBBUkczLCBBUkc0LCBBUkc1LCBBUkc2KQ0KICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmVJbkFyZzAgPSBzY3JpcHRfZnVuY3Rpb25UYWJsZVgyW2NtZGlkIC0gMTAwMDBdKGFyZ3N2YWxbMV0sIGFyZ3N2YWxbMl0sIGFyZ3N2YWxbM10sIGFyZ3N2YWxbNF0sIGFyZ3N2YWxbNV0sIGFyZ3N2YWxbNl0pOw0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3B0aW9uYWwgZnVuY3Rpb25zIG9mIHR5cGUgQVJHMSA9IGZ1bmMoQVJHMiwgQVJHMywgQVJHNCwgQVJHNSwgQVJHNikNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzY3JpcHRfZnVuY3Rpb25UYWJsZVgzICYmIHNjcmlwdF9mdW5jdGlvblRhYmxlWDNbY21kaWQgLSAyMDAwMF0pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUluQXJnMCA9IHNjcmlwdF9mdW5jdGlvblRhYmxlWDNbY21kaWQgLSAyMDAwMF0ob2JqLCBhcmdzdmFsWzFdLCBhcmdzdmFsWzJdLCBhcmdzdmFsWzNdLCBhcmdzdmFsWzRdLCBhcmdzdmFsWzVdLCBhcmdzdmFsWzZdKTsgLy8gTm90ZSB0aGF0IG9wdGlvbmFsIGNhbGxzIHN0YXJ0IHdpdGggIm9iaiIgYXMgZmlyc3QgYXJndW1lbnQuDQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICBpZiAoc3RvcmVJbkFyZzAgIT0gdW5kZWZpbmVkKSBvYmouc2V0VmFyKGFyZ3NbMF0sIHN0b3JlSW5BcmcwKTsNCiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsNCiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGUgPT0gJ29iamVjdCcpIHsgZSA9IGUubWVzc2FnZTsgfQ0KICAgICAgICAgICAgICAgIG9iai5zZXRWYXIoJ19leGNlcHRpb24nLCBlKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGlmIChvYmouc3RhdGUgPT0gMSAmJiBvYmouaXAgPj0gb2JqLnNjcmlwdC5sZW5ndGgpIHsgb2JqLnN0YXRlID0gMDsgb2JqLnN0b3AoKTsgfQ0KICAgICAgICBpZiAob2JqLm9uU3RlcCkgb2JqLm9uU3RlcChvYmopOw0KICAgICAgICByZXR1cm4gb2JqOw0KICAgIH0NCg0KICAgIG9iai54eFN0ZXBEaWFsb2dPayA9IGZ1bmN0aW9uIChidXR0b24pIHsNCiAgICAgICAgb2JqLnZhcmlhYmxlc1snRGlhbG9nU2VsZWN0J10gPSBidXR0b247DQogICAgICAgIG9iai5zdGF0ZSA9IDE7DQogICAgICAgIG9iai5kaWFsb2cgPSBmYWxzZTsNCiAgICAgICAgaWYgKG9iai5vblN0ZXApIG9iai5vblN0ZXAob2JqKTsNCiAgICB9DQoNCiAgICANCiAgICBvYmoueHhXc21hblJldHVybiA9IGZ1bmN0aW9uIChzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgICAgICBvYmouc2V0VmFyKG5hbWUsIHJlc3BvbnNlcyk7DQogICAgICAgIG9iai5zZXRWYXIoJ3dzbWFuX3Jlc3VsdCcsIHN0YXR1cyk7DQogICAgICAgIG9iai5zZXRWYXIoJ3dzbWFuX3Jlc3VsdF9zdHInLCAoKGh0dHBFcnJvclRhYmxlW3N0YXR1c10pID8gKGh0dHBFcnJvclRhYmxlW3N0YXR1c10pIDogKCdFcnJvciAjJyArIHN0YXR1cykpKTsNCiAgICAgICAgb2JqLnN0YXRlID0gMTsNCiAgICAgICAgaWYgKG9iai5vblN0ZXApIG9iai5vblN0ZXAob2JqKTsNCiAgICB9DQoNCiAgICANCiAgICBvYmoueHhTaWduV2l0aER1bW15Q2FSZXR1cm4gPSBmdW5jdGlvbiAoY2VydCkgew0KICAgICAgICBvYmouc2V0VmFyKCdzaWduZWRfY2VydCcsIGJ0b2EoX2FycmF5QnVmZmVyVG9TdHJpbmcoY2VydCkpKTsNCiAgICAgICAgb2JqLnN0YXRlID0gMTsNCiAgICAgICAgaWYgKG9iai5vblN0ZXApIG9iai5vblN0ZXAob2JqKTsNCiAgICB9DQogICAgDQogICAgb2JqLnRvU3RyaW5nID0gZnVuY3Rpb24gKHgpIHsgaWYgKHR5cGVvZiB4ID09ICdvYmplY3QnKSByZXR1cm4gSlNPTi5zdHJpbmdpZnkoeCk7IHJldHVybiB4OyB9DQoNCiAgICBvYmoucmVzZXQoKTsNCiAgICByZXR1cm4gb2JqOw0KfQ0KDQovLyBBcmd1bWVudCB0eXBlczogMCA9IFZhcmlhYmxlLCAxID0gU3RyaW5nLCAyID0gSW50ZWdlciwgMyA9IExhYmVsDQpmdW5jdGlvbiBzY3JpcHRfY29tcGlsZShzY3JpcHQsIG9ubXNnKSB7DQogICAgdmFyIHIgPSAnJywgc2NyaXB0bGluZXMgPSBzY3JpcHQuc3BsaXQoJ1xuJyksIGxhYmVscyA9IHt9LCBsYWJlbHN3YXAgPSBbXSwgc3dhcHMgPSBbXTsNCiAgICAvLyBHbyB0aHJ1IGVhY2ggc2NyaXB0IGxpbmUgYW5kIGVuY29kZSBpdA0KICAgIGZvciAodmFyIGkgaW4gc2NyaXB0bGluZXMpIHsNCiAgICAgICAgdmFyIHNjcmlwdGxpbmUgPSBzY3JpcHRsaW5lc1tpXTsNCiAgICAgICAgaWYgKHNjcmlwdGxpbmUuc3RhcnRzV2l0aCgnIyNTV0FQICcpKSB7IHZhciB4ID0gc2NyaXB0bGluZS5zcGxpdCgnICcpOyBpZiAoeC5sZW5ndGggPT0gMykgeyBzd2Fwc1t4WzFdXSA9IHhbMl07IH0gfSAvLyBBZGQgYSBzd2FwIGluc3RhbmNlDQogICAgICAgIGlmIChzY3JpcHRsaW5lWzBdID09ICcjJyB8fCBzY3JpcHRsaW5lLmxlbmd0aCA9PSAwKSBjb250aW51ZTsgLy8gU2tpcCBjb21tZW50cyAmIGJsYW5rIGxpbmVzDQogICAgICAgIGZvciAodmFyIHggaW4gc3dhcHMpIHsgc2NyaXB0bGluZSA9IHNjcmlwdGxpbmUuc3BsaXQoeCkuam9pbihzd2Fwc1t4XSk7IH0gLy8gQXBwbHkgYWxsIHN3YXBzDQogICAgICAgIHZhciBrZXl3b3JkcyA9IHNjcmlwdGxpbmUubWF0Y2goLyJbXiJdKiJ8W15ccyJdKy9nKTsNCiAgICAgICAgaWYgKGtleXdvcmRzLmxlbmd0aCA9PSAwKSBjb250aW51ZTsgLy8gU2tpcCBibGFuayBsaW5lcw0KICAgICAgICBpZiAoc2NyaXB0bGluZVswXSA9PSAnOicpIHsgbGFiZWxzW2tleXdvcmRzWzBdLnRvVXBwZXJDYXNlKCldID0gci5sZW5ndGg7IGNvbnRpbnVlOyB9IC8vIE1hcmsgYSBsYWJlbCBwb3NpdGlvbg0KICAgICAgICB2YXIgZnVuY0luZGV4ID0gc2NyaXB0X2Z1bmN0aW9uVGFibGUxLmluZGV4T2Yoa2V5d29yZHNbMF0udG9Mb3dlckNhc2UoKSk7DQogICAgICAgIGlmIChmdW5jSW5kZXggPT0gLTEpIHsgZnVuY0luZGV4ID0gc2NyaXB0X2Z1bmN0aW9uVGFibGUyLmluZGV4T2Yoa2V5d29yZHNbMF0udG9Mb3dlckNhc2UoKSk7IGlmIChmdW5jSW5kZXggPj0gMCkgZnVuY0luZGV4ICs9IDEwMDAwOyB9DQogICAgICAgIGlmIChmdW5jSW5kZXggPT0gLTEpIHsgZnVuY0luZGV4ID0gc2NyaXB0X2Z1bmN0aW9uVGFibGUzLmluZGV4T2Yoa2V5d29yZHNbMF0udG9Mb3dlckNhc2UoKSk7IGlmIChmdW5jSW5kZXggPj0gMCkgZnVuY0luZGV4ICs9IDIwMDAwOyB9IC8vIE9wdGlvbmFsIG1ldGhvZHMNCiAgICAgICAgaWYgKGZ1bmNJbmRleCA9PSAtMSkgeyBpZiAob25tc2cpIHsgb25tc2coIlVuYWJsZWQgdG8gY29tcGlsZSwgdW5rbm93biBjb21tYW5kOiAiICsga2V5d29yZHNbMF0pOyB9IHJldHVybiAnJzsgfQ0KICAgICAgICAvLyBFbmNvZGUgQ29tbWFuZElkLCBDbWRTaXplLCBBcmdDb3VudCwgQXJnMUxlbiwgQXJnMSwgQXJnMkxlbiwgQXJnMi4uLg0KICAgICAgICB2YXIgY21kID0gU2hvcnRUb1N0cihrZXl3b3Jkcy5sZW5ndGggLSAxKTsNCiAgICAgICAgZm9yICh2YXIgaiBpbiBrZXl3b3Jkcykgew0KICAgICAgICAgICAgaWYgKGogPT0gMCkgY29udGludWU7DQogICAgICAgICAgICBpZiAoa2V5d29yZHNbal1bMF0gPT0gJzonKSB7DQogICAgICAgICAgICAgICAgbGFiZWxzd2FwLnB1c2goW2tleXdvcmRzW2pdLCByLmxlbmd0aCArIGNtZC5sZW5ndGggKyA3XSk7IC8vIEFkZCBhIGxhYmVsIHN3YXANCiAgICAgICAgICAgICAgICBjbWQgKz0gU2hvcnRUb1N0cig1KSArIFN0cmluZy5mcm9tQ2hhckNvZGUoMykgKyBJbnRUb1N0cigweEZGRkZGRkZGKTsgLy8gUHV0IGFuIGVtcHR5IGxhYmVsDQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHZhciBhcmdpbnQgPSBwYXJzZUludChrZXl3b3Jkc1tqXSk7DQogICAgICAgICAgICAgICAgaWYgKGFyZ2ludCA9PSBrZXl3b3Jkc1tqXSkgew0KICAgICAgICAgICAgICAgICAgICBjbWQgKz0gU2hvcnRUb1N0cig1KSArIFN0cmluZy5mcm9tQ2hhckNvZGUoMikgKyBJbnRUb1N0cihhcmdpbnQpOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChrZXl3b3Jkc1tqXVswXSA9PSAnIicgJiYga2V5d29yZHNbal1ba2V5d29yZHNbal0ubGVuZ3RoIC0gMV0gPT0gJyInKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBjbWQgKz0gU2hvcnRUb1N0cihrZXl3b3Jkc1tqXS5sZW5ndGggLSAxKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoMSkgKyBrZXl3b3Jkc1tqXS5zdWJzdHJpbmcoMSwga2V5d29yZHNbal0ubGVuZ3RoIC0gMSk7DQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICBjbWQgKz0gU2hvcnRUb1N0cihrZXl3b3Jkc1tqXS5sZW5ndGggKyAxKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoMCkgKyBrZXl3b3Jkc1tqXTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBjbWQgPSBTaG9ydFRvU3RyKGZ1bmNJbmRleCkgKyBTaG9ydFRvU3RyKGNtZC5sZW5ndGggKyA0KSArIGNtZDsNCiAgICAgICAgciArPSBjbWQ7DQogICAgfQ0KICAgIC8vIFBlcmZvcm0gYWxsIHRoZSBuZWVkZWQgbGFiZWwgc3dhcHMNCiAgICBmb3IgKGkgaW4gbGFiZWxzd2FwKSB7DQogICAgICAgIHZhciBsYWJlbCA9IGxhYmVsc3dhcFtpXVswXS50b1VwcGVyQ2FzZSgpLCBwb3NpdGlvbiA9IGxhYmVsc3dhcFtpXVsxXSwgdGFyZ2V0ID0gbGFiZWxzW2xhYmVsXTsNCiAgICAgICAgaWYgKHRhcmdldCA9PSB1bmRlZmluZWQpIHsgaWYgKG9ubXNnKSB7IG9ubXNnKCJVbmFibGVkIHRvIGNvbXBpbGUsIHVua25vd24gbGFiZWw6ICIgKyBsYWJlbCk7IH0gcmV0dXJuICcnOyB9DQogICAgICAgIHIgPSByLnN1YnN0cigwLCBwb3NpdGlvbikgKyBJbnRUb1N0cih0YXJnZXQpICsgci5zdWJzdHIocG9zaXRpb24gKyA0KTsNCiAgICB9DQogICAgcmV0dXJuIEludFRvU3RyKDB4MjQ3RDI5NDUpICsgU2hvcnRUb1N0cigxKSArIHI7DQp9DQoNCi8vIERlY29tcGlsZSB0aGUgc2NyaXB0LCBpbnRlbmRlZCBmb3IgZGVidWdnaW5nIG9ubHkNCmZ1bmN0aW9uIHNjcmlwdF9kZWNvbXBpbGUoYmluYXJ5LCBvbmVjbWQpIHsNCiAgICB2YXIgciA9ICcnLCBwdHIgPSA2LCBsYWJlbGNvdW50ID0gMCwgbGFiZWxzID0ge307DQogICAgaWYgKG9uZWNtZCA+PSAwKSB7DQogICAgICAgIHB0ciA9IG9uZWNtZDsgLy8gSWYgd2UgYXJlIGRlY29tcGlsaW5nIGp1c3Qgb25lIGNvbW1hbmQsIHNldCB0aGUgcHRyIHRvIHRoYXQgY29tbWFuZC4NCiAgICB9IGVsc2Ugew0KICAgICAgICBpZiAoYmluYXJ5Lmxlbmd0aCA8IDYpIHsgcmV0dXJuICcjIEludmFsaWQgc2NyaXB0IGxlbmd0aCc7IH0NCiAgICAgICAgdmFyIG1hZ2ljID0gUmVhZEludChiaW5hcnksIDApOw0KICAgICAgICB2YXIgdmVyc2lvbiA9IFJlYWRTaG9ydChiaW5hcnksIDQpOw0KICAgICAgICBpZiAobWFnaWMgIT0gMHgyNDdEMjk0NSkgeyByZXR1cm4gJyMgSW52YWxpZCBiaW5hcnkgc2NyaXB0OiAnICsgbWFnaWM7IH0NCiAgICAgICAgaWYgKHZlcnNpb24gIT0gMSkgeyByZXR1cm4gJyMgSW52YWxpZCBzY3JpcHQgdmVyc2lvbic7IH0NCiAgICB9DQogICAgLy8gTG9vcCBvbiBlYWNoIGNvbW1hbmQsIG1vdmluZyBmb3J3YXJkIGJ5IHRoZSBjb21tYW5kIGxlbmd0aCBlYWNoIHRpbWUuDQogICAgd2hpbGUgKHB0ciA8IGJpbmFyeS5sZW5ndGgpIHsNCiAgICAgICAgdmFyIGNtZGlkID0gUmVhZFNob3J0KGJpbmFyeSwgcHRyKTsNCiAgICAgICAgdmFyIGNtZGxlbiA9IFJlYWRTaG9ydChiaW5hcnksIHB0ciArIDIpOw0KICAgICAgICB2YXIgYXJnY291bnQgPSBSZWFkU2hvcnQoYmluYXJ5LCBwdHIgKyA0KTsNCiAgICAgICAgdmFyIGFyZ3B0ciA9IHB0ciArIDY7DQogICAgICAgIHZhciBhcmdzdHIgPSAnJzsNCiAgICAgICAgaWYgKCEob25lY21kID49IDApKSByICs9ICI6bGFiZWwiICsgKHB0ciAtIDYpICsgIlxuIjsNCiAgICAgICAgLy8gTG9vcCBvbiBlYWNoIGFyZ3VtZW50LCBtb3ZpbmcgZm9yd2FyZCBieSB0aGUgYXJndW1lbnQgbGVuZ3RoIGVhY2ggdGltZQ0KICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ2NvdW50OyBpKyspIHsNCiAgICAgICAgICAgIHZhciBhcmdsZW4gPSBSZWFkU2hvcnQoYmluYXJ5LCBhcmdwdHIpOw0KICAgICAgICAgICAgdmFyIGFyZ3ZhbCA9IGJpbmFyeS5zdWJzdHJpbmcoYXJncHRyICsgMiwgYXJncHRyICsgMiArIGFyZ2xlbik7DQogICAgICAgICAgICB2YXIgYXJndHlwID0gYXJndmFsLmNoYXJDb2RlQXQoMCk7DQogICAgICAgICAgICBpZiAoYXJndHlwID09IDApIHsgYXJnc3RyICs9ICcgJyArIGFyZ3ZhbC5zdWJzdHJpbmcoMSk7IH0gLy8gVmFyaWFibGUNCiAgICAgICAgICAgIGVsc2UgaWYgKGFyZ3R5cCA9PSAxKSB7IGFyZ3N0ciArPSAnIFwiJyArIGFyZ3ZhbC5zdWJzdHJpbmcoMSkgKyAnXCInOyB9IC8vIFN0cmluZw0KICAgICAgICAgICAgZWxzZSBpZiAoYXJndHlwID09IDIpIHsgYXJnc3RyICs9ICcgJyArIFJlYWRJbnQoYXJndmFsLCAxKTsgfSAvLyBJbnRlZ2VyDQogICAgICAgICAgICBlbHNlIGlmIChhcmd0eXAgPT0gMykgeyAvLyBMYWJlbA0KICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSBSZWFkSW50KGFyZ3ZhbCwgMSk7DQogICAgICAgICAgICAgICAgdmFyIGxhYmVsID0gbGFiZWxzW3RhcmdldF07DQogICAgICAgICAgICAgICAgaWYgKCFsYWJlbCkgeyBsYWJlbCA9ICI6bGFiZWwiICsgdGFyZ2V0OyBsYWJlbHNbbGFiZWxdID0gdGFyZ2V0OyB9DQogICAgICAgICAgICAgICAgYXJnc3RyICs9ICcgJyArIGxhYmVsOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgYXJncHRyICs9ICgyICsgYXJnbGVuKTsNCiAgICAgICAgfQ0KICAgICAgICAvLyBHbyBpbiB0aGUgc2NyaXB0IGZ1bmN0aW9uIHRhYmxlIHRvIGRlY29kZSB0aGUgZnVuY3Rpb24NCiAgICAgICAgaWYgKGNtZGlkIDwgMTAwMDApIHsNCiAgICAgICAgICAgIHIgKz0gc2NyaXB0X2Z1bmN0aW9uVGFibGUxW2NtZGlkXSArIGFyZ3N0ciArICJcbiI7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBpZiAoY21kaWQgPj0gMjAwMDApIHsNCiAgICAgICAgICAgICAgICByICs9IHNjcmlwdF9mdW5jdGlvblRhYmxlM1tjbWRpZCAtIDIwMDAwXSArIGFyZ3N0ciArICJcbiI7IC8vIE9wdGlvbmFsIG1ldGhvZHMNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgciArPSBzY3JpcHRfZnVuY3Rpb25UYWJsZTJbY21kaWQgLSAxMDAwMF0gKyBhcmdzdHIgKyAiXG4iOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIHB0ciArPSBjbWRsZW47DQogICAgICAgIGlmIChvbmVjbWQgPj0gMCkgcmV0dXJuIHI7IC8vIElmIHdlIGFyZSBkZWNvbXBpbGluZyBqdXN0IG9uZSBjb21tYW5kLCBleGl0IG5vdw0KICAgIH0NCiAgICAvLyBSZW1vdmUgYWxsIHVudXNlZCBsYWJlbHMNCiAgICB2YXIgc2NyaXB0bGluZXMgPSByLnNwbGl0KCdcbicpOw0KICAgIHIgPSAnJzsNCiAgICBmb3IgKHZhciBpIGluIHNjcmlwdGxpbmVzKSB7DQogICAgICAgIHZhciBsaW5lID0gc2NyaXB0bGluZXNbaV07DQogICAgICAgIGlmIChsaW5lWzBdICE9ICc6JykgeyByICs9IGxpbmUgKyAnXG4nOyB9IGVsc2UgeyBpZiAobGFiZWxzW2xpbmVdKSB7IHIgKz0gbGluZSArICdcbic7IH0gfQ0KICAgIH0NCiAgICByZXR1cm4gcjsNCn0NCi8qKiANCiogQGRlc2NyaXB0aW9uIEludGVsKFIpIEFNVCBTZXR1cC5iaW4gUGFyc2VyDQoqIEBhdXRob3IgWWxpYW4gU2FpbnQtSGlsYWlyZQ0KKiBAdmVyc2lvbiB2MC4xLjANCiovDQoNCi8vIEludGVsKFIpIEFNVCBTZXR1cC5iaW4gR1VJRCdzDQp2YXIgQW10U2V0dXBCaW5TZXR1cEd1aWRzID0gWw0KICAgICJceGI1XHgxNlx4ZmJceDcxXHg4N1x4Y2JceGY5XHg0YVx4YjRceDQxXHhjYVx4N2JceDM4XHgzNVx4NzhceGY5IiwgLy8gVmVyc2lvbiAxDQogICAgIlx4OTZceGIyXHg4MVx4NThceGNmXHg2Ylx4NzJceDRjXHg4Ylx4OTFceGExXHg1ZVx4NTFceDJlXHg5OVx4YzQiLCAvLyBWZXJzaW9uIDINCiAgICAiXHhhN1x4ZjdceGY2XHhjNlx4ODlceGM0XHhmNlx4NDdceDkzXHhlZFx4ZTJceGU1XHgwMlx4MGRceGE1XHgxZCIsIC8vIFZlcnNpb24gMw0KICAgICJceGFhXHhhOVx4MzRceDUyXHhlMVx4MjlceGE5XHg0NFx4OGRceDRkXHgwOFx4MWNceDA3XHhiOVx4NjNceDUzIiAgLy8gVmVyc2lvbiA0DQpdOw0KDQovLyBOb3RlcyBhYm91dCB2ZXJzaW9uIDIgb2Ygc2V0dXAuYmluOg0KLy8gICAtIERlZmF1bHQgImFkbWluIiBtdXN0IGJlIGZvbGxvd2VkIGJ5IGEgbmV3IE1FQnggcGFzc3dvcmQNCi8vICAgLSBNRV9WQVJJQUJMRV9JREVOVElGSUVSX01BTkFHRUFCSUxJVFlfRkVBVFVSRV9TRUxFQ1RJT04gbWF5IG5vdCBhcHBlYXIgYWZ0ZXIgYW55IENNIHNldHRpbmdzDQovLyAgIC0gQ01fVkFSSUFCTEVfSURFTlRJRklFUl9VU0VSX0RFRklORURfQ0VSVF9BREQgbXVzdCBiZSBwcmVjZWRlZCBieSBzZXR0aW5nIENNX1ZBUklBQkxFX0lERU5USUZJRVJfVVNFUl9ERUZJTkVEX0NFUlRTX0NPTkZJRyB0byAoVE9ETyEpDQoNCi8vIEdlbmVyYWwgbm90ZXM6DQovLyAgIC0gU2V0dXAuYmluIHNob3VsZCBhbHdheXMgc3RhcnQgd2l0aCAiQ3VycmVudE1FQnggUHdkIiwgIm5ld01lYnggUHdkIiwgIm1hbmFnZWFiaWxpdHkgc2VsZWN0aW9uIiAoaWYgcHJlc2VudCkuDQoNCi8vIEludGVsKFIpIEFNVCB2YXJpYWJsZSBpZGVudGlmaWVycw0KLy8gVHlwZTogMCA9IEJpbmFyIFN0cmluZ3ksIDEgPSBDaGFyLCAyID0gU2hvcnQsIDMgPSBJbnQNCnZhciBBbXRTZXR1cEJpblZhcklkcyA9DQp7DQogICAgMTogew0KICAgICAgICAxOiAgWzAsICJDdXJyZW50IE1FQnggUGFzc3dvcmQiXSwNCiAgICAgICAgMjogIFswLCAiTmV3IE1FQnggUGFzc3dvcmQiXSwNCiAgICAgICAgMzogIFsxLCAiTWFuYWdlYWJpbGl0eSBGZWF0dXJlIFNlbGVjdGlvbiJdLA0KICAgICAgICA0OiAgWzEsICJGaXJtd2FyZSBMb2NhbCBVcGRhdGUiLCAgICAgICAgICAgICAgICAgICAvLyAwID0gRGlzYWJsZWQsIDEgPSBFbmFibGVkLCAyID0gUGFzc3dvcmQgUHJvdGVjdGVkDQogICAgICAgICAgICB7IDA6ICJEaXNhYmxlZCIsIDE6ICJFbmFibGVkIiwgMjogIlBhc3N3b3JkIFByb3RlY3RlZCIgfV0sDQogICAgICAgIDU6ICBbMSwgIkZpcm13YXJlIFVwZGF0ZSBRdWFsaWZpZXIiLCAgICAgICAgICAgICAgIC8vIDAgPSBBbHdheXMsIDEgPSBOZXZlciwgMiA9IFJlc3RyaWN0ZWQNCiAgICAgICAgICAgIHsgMDogIkFsd2F5cyIsIDE6ICJOZXZlciIsIDI6ICJSZXN0cmljdGVkIiB9XSwNCiAgICAgICAgNjogIFs0LCAiUG93ZXIgUGFja2FnZSJdICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR1VJRCBMZW5ndGggKDE2IGJ5dGVzKSwgSW50ZWwgQU1UIHZlcnNpb24gMi4xLCAzIGFuZCA0DQogICAgfSwNCiAgICAyOiB7DQogICAgICAgIDE6ICBbMCwgIlByb3Zpc2lvbmluZyBQcmVzaGFyZWQgS2V5IElEIChQSUQpIl0sDQogICAgICAgIDI6ICBbMCwgIlByb3Zpc2lvbmluZyBQcmVzaGFyZWQgS2V5IChQUFMpIl0sDQogICAgICAgIDM6ICBbMCwgIlBLSSBETlMgU3VmZml4Il0sICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDI1NSBieXRlcyBtYXggbGVuZ3RoDQogICAgICAgIDQ6ICBbMCwgIkNvbmZpZ3VyYXRpb24gU2VydmVyIEZRRE4iXSwgICAgICAgICAgICAgIC8vIDI1NSBieXRlcyBtYXggbGVuZ3RoDQogICAgICAgIDU6ICBbMSwgIlJlbW90ZSBDb25maWd1cmF0aW9uIEVuYWJsZWQgKFJDRkcpIiwgICAgIC8vIDAgPSBPZmYsIDEgPSBPbg0KICAgICAgICAgICAgeyAwOiAiT2ZmIiwgMTogIk9uIiB9XSwNCiAgICAgICAgNjogIFsxLCAiUHJlLUluc3RhbGxlZCBDZXJ0aWZpY2F0ZXMgRW5hYmxlZCIsICAgICAgLy8gMCA9IE9mZiwgMSA9IE9uDQogICAgICAgICAgICB7IDA6ICJPZmYiLCAxOiAiT24iIH1dLA0KICAgICAgICA3OiAgWzEsICJVc2VyIERlZmluZWQgQ2VydGlmaWNhdGUgQ29uZmlndXJhdGlvbiIsICAvLyAwID0gRGlzYWJsZWQsIDEgPSBFbmFibGVkLCAyID0gRGVsZXRlDQogICAgICAgICAgICB7IDA6ICJEaXNhYmxlZCIsIDE6ICJFbmFibGVkIiwgMjogIkRlbGV0ZSIgfV0sDQogICAgICAgIDg6ICBbMCwgIlVzZXIgRGVmaW5lZCBDZXJ0aWZpY2F0ZSBBZGRpdGlvbiJdLCAgICAgIC8vIDEgYnl0ZSBoYXNoIGFsZ28sIDIwIHRvIDQ4IGJ5dGVzIGhhc2gsIDEgYnl0ZSBuYW1lIGxlbmd0aCwgdXAgdG8gMzIgYnl0ZXMgZnJpZW5kbHkgbmFtZSwgMSA9IFNIQTEgKDIwIGJ5dGVzKSwgMiA9IFNIQTI1NiAoMzIgYnl0ZXMpLCAzID0gU0hBMzg0ICg0OCBieXRlcykuIEFsZ28gMiAmIDMgYXJlIGZvciB2ZXJzaW9uIDMgYW5kIHVwLg0KICAgICAgICAxMDogWzEsICJTT0wvSURFUiBSZWRpcmVjdGlvbiBDb25maWd1cmF0aW9uIl0sDQogICAgICAgIDExOiBbMCwgIkhvc3RuYW1lIl0sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDYzIGJ5dGVzIG1heCBsZW5ndGgNCiAgICAgICAgMTI6IFswLCAiRG9tYWluIE5hbWUiXSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gMjU1IGJ5dGVzIG1heCBsZW5ndGgNCiAgICAgICAgMTM6IFsxLCAiREhDUCIsIHsgMTogIkRpc2FibGVkIiwgMjogIkVuYWJsZWQiIH1dLA0KICAgICAgICAxNDogWzEsICJTZWN1cmUgRmlybXdhcmUgVXBkYXRlIChTRldVKSIsICAgICAgICAgICAvLyAwID0gRGlzYWJsZWQsIDEgPSBFbmFibGVkDQogICAgICAgICAgICB7IDA6ICJEaXNhYmxlZCIsIDE6ICJFbmFibGVkIiB9XSwNCiAgICAgICAgMTU6IFswLCAiSVRPIl0sDQogICAgICAgIDE2OiBbMSwgIlByb3Zpc2lvbmluZyBNb2RlIChQTSkiLCAgICAgICAgICAgICAgICAgIC8vIDEgPSBFbnRlcnByaXNlLCAyID0gU21hbGwgQnVpc25lc3MgKFNNQikNCiAgICAgICAgICAgIHsgMDogIkVudGVycHJpc2UiLCAxOiAiU21hbGwgQnVpc25lc3MifV0sDQogICAgICAgIDE3OiBbMCwgIlByb3Zpc2lvbmluZyBTZXJ2ZXIgQWRkcmVzcyJdLA0KICAgICAgICAxODogWzIsICJQcm92aXNpb24gU2VydmVyIFBvcnQgTnVtYmVyIChQU1BPKSJdLA0KICAgICAgICAxOTogWzAsICJTdGF0aWMgUFY0IFBhcmFtZXRlcnMiXSwNCiAgICAgICAgMjA6IFswLCAiVkxBTiJdLA0KICAgICAgICAyMTogWzAsICJQQVNTIFBvbGljeSBGbGFnIl0sDQogICAgICAgIDIyOiBbMCwgIklQdjYiXSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIExlbmd0aCBpcyAyMDQgYnl0ZXMgb2xkIGZvcm1hdCwgODQgYnl0ZXMgbmV3IGZvcm1hdCwgVmVyc2lvbiAzKyBvbmx5DQogICAgICAgIDIzOiBbMSwgIlNoYXJlZC9EZWRpY2F0ZWQgRlFETiIsICAgICAgICAgICAgICAgICAgIC8vIDAgPSBEZWRpY2F0ZWQsIDEgPSBTaGFyZWQuIFRoaXMgb3B0aW9uIGlzIHZhbGlkIG9ubHkgaWYgY29uZmlndXJpbmcgdGhlIGhvc3RuYW1lIGFzIHdlbGwNCiAgICAgICAgICAgIHsgMDogIkRlZGljYXRlZCIsIDE6ICJTaGFyZWQiIH1dLA0KICAgICAgICAyNDogWzEsICJEeW5hbWljIEROUyBVcGRhdGUiLCAgICAgICAgICAgICAgICAgICAgICAvLyAwID0gRGlzYWJsZWQsIDEgPSBFbmFibGVkDQogICAgICAgICAgICB7IDA6ICJEaXNhYmxlZCIsIDE6ICJFbmFibGVkIiB9XSwNCiAgICAgICAgMjU6IFsxLCAiUmVtb3RlIERlc2t0b3AgKEtWTSkgU3RhdGUiLCAgICAgICAgICAgICAgLy8gMCA9IERpc2FibGVkLCAxID0gRW5hYmxlZA0KICAgICAgICAgICAgeyAwOiAiRGlzYWJsZWQiLCAxOiAiRW5hYmxlZCIgfV0sDQogICAgICAgIDI2OiBbMSwgIk9wdC1pbiBVc2VyIENvbnNlbnQgT3B0aW9uIiwgICAgICAgICAgICAgIC8vIDAgPSBEaXNhYmxlZCwgMSA9IEtWTSwgMHhGRiA9IEFMTA0KICAgICAgICAgICAgeyAwIDogIkRpc2FibGVkIiwgMSA6ICJLVk0iLCAyNTUgOiAiQWxsIiB9XSwNCiAgICAgICAgMjc6IFsxLCAiT3B0LWluIFJlbW90ZSBJVCBDb25zZW50IFBvbGljeSIsICAgICAgICAgLy8gMCA9IERpc2FibGVkLCAxID0gRW5hYmxlZC4gQWxsb3dzIHVzZXIgY29uc2VudCB0byBiZSBjb25maWd1cmVkIHJlbW90ZWx5Lg0KICAgICAgICAgICAgeyAwIDogIkRpc2FibGVkIiwgMSA6ICJFbmFibGVkIn0gXSwNCiAgICAgICAgMjg6IFsxLCAiTUUgUHJvdmlzaW9uIEhhbHQgQWN0aXZlIiwgICAgICAgICAgICAgICAgLy8gMCA9IFN0b3AsIDEgPSBTdGFydC4gVGhlICJNRSBwcm92aXNpb25pbmcgSGFsdC9BY3RpdmF0ZSIgY29tbWFuZCBtdXN0IGFwcGVhciBpbiB0aGUgZmlsZSBvbmx5IGFmdGVyICJQS0lETlNTdWZmaXgiLCAiQ29uZmlnU2VydmVyRlFETiIgYW5kICJQcm92aXNpb25pbmcgU2VydmVyIEFkZHJlc3MiDQogICAgICAgICAgICB7IDAgOiAiU3RvcCIsIDEgOiAiU3RhcnQifV0sDQogICAgICAgIDI5OiBbMSwgIk1hbnVhbCBTZXR1cCBhbmQgQ29uZmlndXJhdGlvbiIsICAgICAgICAgIC8vIDAgPSBBdXRvbWF0ZWQsIDEgPSBNYW51YWwNCiAgICAgICAgICAgIHsgMCA6ICJBdXRvbWF0ZWQiLCAxIDogIk1hbnVhbCJ9XSwNCiAgICAgICAgMzA6IFszLCAiU3VwcG9ydCBDaGFubmVsIElkZW50aWZpZXIiXSwgICAgICAgICAgICAgLy8gNCBieXRlcyBsZW5ndGguIFN1cHBvcnQgY2hhbm5lbCBpZGVudGlmaWVyICh2YWxpZCB2YWx1ZXM6IDEtNjU1MzUpDQogICAgICAgIDMxOiBbMCwgIlN1cHBvcnQgQ2hhbm5lbCBEZXNjcmlwdGlvbiJdLCAgICAgICAgICAgIC8vIDYwIGJ5dGVzIG1heC4gRnJpZW5kbHkgbmFtZSB1c2VkIHRvIGRlc2NyaWJlIHRoZSBwYXJ0eSByZXByZXNlbnRlZGJ5IHRoZSBzdXBwb3J0IGNoYW5uZWwgaWRlbnRpZmllci4NCiAgICAgICAgMzI6IFswLCAiU2VydmljZSBBY2NvdW50IE51bWJlciJdLCAgICAgICAgICAgICAgICAgLy8gMzIgYnl0ZXMgbWF4LiBVbmlxdWUgc3RyaW5nIGlkZW50aWZpZXIgZ2l2ZW4gdG8gdGhlIGVuZCB1c2VyIGJ5IHRoZSBzZXJ2aWNlIHByb3ZpZGVyLg0KICAgICAgICAzMzogWzAsICJFbnJvbGxlbWVudCBQYXNzY29kZSJdLCAgICAgICAgICAgICAgICAgICAvLyAzMiBieXRlcyBtYXgNCiAgICAgICAgMzQ6IFszLCAiU2VydmljZSBUeXBlIl0sICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gNCBieXRlcyBsZW5ndGguIDEgPSBSZWFjdGl2ZSwgMiA9IFByb2FjdGl2ZSwgNCA9IE9uZSBUaW1lIFNlc3Npb24NCiAgICAgICAgMzU6IFswLCAiU2VydmljZSBQcm92aWRlciBJZGVudGlmaWVyIl0gICAgICAgICAgICAgLy8gR1VJRCBMZW5ndGggKDE2IGJ5dGVzKQ0KICAgIH0NCn0NCg0KDQovLyBQYXJzZSB0aGUgU2V0dXAuYmluIGZpbGUNCnZhciBBbXRTZXR1cEJpbkNyZWF0ZSA9IGZ1bmN0aW9uICh2ZXJzaW9uLCBmbGFncykgew0KICAgIHZhciBvYmogPSB7fTsNCiAgICBvYmouZmlsZVR5cGUgPSB2ZXJzaW9uOw0KICAgIG9iai5yZWNvcmRDaHVua0NvdW50ID0gMDsNCiAgICBvYmoucmVjb3JkSGVhZGVyQnl0ZUNvdW50ID0gMDsNCiAgICBvYmoucmVjb3JkTnVtYmVyID0gMDsNCiAgICBvYmoubWFqb3JWZXJzaW9uID0gdmVyc2lvbjsNCiAgICBvYmoubWlub3JWZXJzaW9uID0gMDsNCiAgICBvYmouZmxhZ3MgPSBmbGFnczsNCiAgICBvYmouZGF0YVJlY29yZHNDb25zdW1lZCA9IDA7DQogICAgb2JqLmRhdGFSZWNvcmRDaHVua0NvdW50ID0gMDsNCiAgICBvYmoucmVjb3JkcyA9IFtdOw0KICAgIHJldHVybiBvYmo7DQp9DQoNCg0KLy8gUGFyc2UgdGhlIFNldHVwLmJpbiBmaWxlDQp2YXIgQW10U2V0dXBCaW5EZWNvZGUgPSBmdW5jdGlvbiAoZmlsZSkgew0KDQogICAgLy8gRm9ybWF0IG9mIHRoZSBzZXR1cCBmaWxlIGhlYWRlcjoNCiAgICAvLyBGaWxlVHlwZVVVSUQoMTYpICAgICAgICAgLSB1bmlxdWVseSBpZGVudGlmaWVzIHRoZSBmaWxlIHR5cGUuIFRoaXMgaWRlbnRpZmllciB3aWxsIHJlbWFpbiB2YWxpZCBhbmQgY29uc3RhbnQgYWNyb3NzIGFsbCB2ZXJzaW9ucyBvZiB0aGUgZmlsZSB0eXBlLg0KICAgIC8vIFJlY29yZENodW5rQ291bnQoMikgICAgICAtIGluZGljYXRlcyB0aGUgbnVtYmVyIG9mIDUxMi1ieXRlIGNodW5rcyBvY2N1cGllZCBieSB0aGlzIHJlY29yZCwgaW5jbHVkaW5nIGFsbCBoZWFkZXIsIGJvZHksIGFuZCByZXNlcnZlZCBmaWVsZHMuDQogICAgLy8gUmVjb3JkSGVhZGVyQnl0ZXMoMikgICAgIC0gaW5kaWNhdGVzIHRoZSBsZW5ndGggb2YgdGhlIHJlY29yZCBoZWFkZXIgaW4gYnl0ZXMuDQogICAgLy8gUmVjb3JkTnVtYmVyKDQpICAgICAgICAgIC0gdW5pcXVlbHkgaWRlbnRpZmllcyB0aGUgcmVjb3JkIGFtb25nIGFsbCByZWNvcmRzIGluIHRoZSBmaWxlLiBUaGUgZmllbGQgY29udGFpbnMgYSBub24tbmVnYXRpdmUgb3JkaW5hbCB2YWx1ZS4gVGhlIHZhbHVlIG9mIHRoaXMgZmllbGQgaXMgYWx3YXlzIHplcm8gaW4gdGhlIExvY2FsIFByb3Zpc2lvbmluZyBGaWxlIEhlYWRlciBSZWNvcmQuDQogICAgLy8gTWFqb3JWZXJzaW9uKDEpICAgICAgICAgIC0gaWRlbnRpZmllcyB0aGUgbWFqb3IgdmVyc2lvbiBvZiB0aGUgZmlsZSBmb3JtYXQgc3BlY2lmaWNhdGlvbi4gVGhpcyBpcyBhIHBvc2l0aXZlIGludGVnZXIgdGhhdCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMS4gVGhlIE1ham9yIFZlcnNpb24gbnVtYmVyIGlzIGluY3JlbWVudGVkIHRvIGluZGljYXRlIHRoYXQgY2hhbmdlcyBoYXZlIGJlZW4gaW50cm9kdWNlZCB0aGF0IHdpbGwgY2F1c2UgY29kZSB3cml0dGVuIGFnYWluc3QgYSBsb3dlciBNYWpvciBWZXJzaW9uIG51bWJlciB0byBmYWlsLg0KICAgIC8vIE1pbm9yVmVyc2lvbigxKSAgICAgICAgICAtIGlkZW50aWZpZXMgdGhlIG1pbm9yIHZlcnNpb24gb2YgdGhlIGZpbGUgZm9ybWF0IHNwZWNpZmljYXRpb24uIFRoaXMgaXMgYW4gaW50ZWdlciB0aGF0IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAwLiBUaGUgTWlub3IgVmVyc2lvbiBudW1iZXIgaXMgaW5jcmVtZW50ZWQgdG8gaW5kaWNhdGUgdGhhdCBjaGFuZ2VzIGhhdmUgYmVlbiBpbnRyb2R1Y2VkIHRoYXQgd2lsbCBub3QgY2F1c2UgY29kZSB3cml0dGVuIGFnYWluc3QgdGhlIHNhbWUgTWFqb3IgVmVyc2lvbiBhbmQgYSBsb3dlciBNaW5vciBWZXJzaW9uIG51bWJlciB0byBmYWlsLiBUaGUgcHVycG9zZSBvZiB0aGlzIGJlaGF2aW9yIGlzIHRvIGFsbG93IGEgc2luZ2xlIGxvY2FsIHByb3Zpc2lvbmluZyBmaWxlIHRvIGJlIHVzZWQgZm9yIG11bHRpcGxlIGdlbmVyYXRpb25zIG9mIEludGVs77+9IEFNVCBwbGF0Zm9ybS4NCiAgICAvLyBEYXRhUmVjb3JkQ291bnQoNCkgICAgICAgLSBpbmRpY2F0ZXMgdGhlIHRvdGFsIG51bWJlciBvZiBkYXRhIHJlY29yZHMgd3JpdHRlbiBpbiB0aGUgZmlsZSB3aGVuIGl0IHdhcyBjcmVhdGVkLg0KICAgIC8vIERhdGFSZWNvcmRzQ29uc3VtZWQoNCkgICAtIGlzIGEgY291bnRlciB2YWx1ZSB0aGF0IGJlZ2lucyBhdCAwIGFuZCBpcyBpbmNyZW1lbnRlZCBieSAxIGJ5IGVhY2ggcGxhdGZvcm0gQklPUyB3aGVuIGl0IGNvbnN1bWVzIGEgZGF0YSByZWNvcmQgZnJvbSB0aGUgZmlsZS4gVGhpcyB2YWx1ZSBpcyB1c2VkIHRvIGRldGVybWluZSB0aGUgb2Zmc2V0IG9mIHRoZSBuZXh0IGRhdGEgcmVjb3JkIGluIHRoZSBmaWxlLg0KICAgIC8vIERhdGFSZWNvcmRDaHVua0NvdW50KDIpICAtIGNvbnRhaW5zIHRoZSBudW1iZXIgb2YgNTEyLWJ5dGUgY2h1bmtzIGluIGVhY2ggZGF0YSByZWNvcmQuIEFsbCBkYXRhIHJlY29yZHMgYXJlIHRoZSBzYW1lIGxlbmd0aC4NCiAgICAvLyBNb2R1bGVMaXN0ICAgICAgICAgICAgICAgLSBjb250YWlucyBhIGxpc3Qgb2YgbW9kdWxlIGlkZW50aWZpZXJzLiBBIG1vZHVsZe+/vXMgaWRlbnRpZmllciBhcHBlYXJzIGluIHRoZSBsaXN0IGlmIGFuZCBvbmx5IGlmIHRoZSBkYXRhIHJlY29yZHMgY29udGFpbiBlbnRyaWVzIGZvciB0aGF0IG1vZHVsZS4gRWFjaCBtb2R1bGUgaWRlbnRpZmllciBpcyB0d28gYnl0ZXMgaW4gbGVuZ3RoLiBUaGUgbGlzdCBpcyB0ZXJtaW5hdGVkIGJ5IGFuIGlkZW50aWZpZXIgdmFsdWUgb2YgMC4gDQoNCiAgICB2YXIgb2JqID0ge30sIFVVSUQgPSBmaWxlLnN1YnN0cmluZygwLCAxNik7DQogICAgb2JqLmZpbGVUeXBlID0gMDsNCiAgICBmb3IgKHZhciBpIGluIEFtdFNldHVwQmluU2V0dXBHdWlkcykgeyBpZiAoVVVJRCA9PSBBbXRTZXR1cEJpblNldHVwR3VpZHNbaV0pIG9iai5maWxlVHlwZSA9ICgraSArIDEpOyB9DQogICAgaWYgKG9iai5maWxlVHlwZSA9PSAwKSByZXR1cm47IC8vIEJhZCBoZWFkZXINCiAgICBvYmoucmVjb3JkQ2h1bmtDb3VudCA9IFJlYWRTaG9ydFgoZmlsZSwgMTYpOw0KICAgIG9iai5yZWNvcmRIZWFkZXJCeXRlQ291bnQgPSBSZWFkU2hvcnRYKGZpbGUsIDE4KTsNCiAgICBvYmoucmVjb3JkTnVtYmVyID0gUmVhZEludFgoZmlsZSwgMjApOw0KICAgIG9iai5tYWpvclZlcnNpb24gPSBmaWxlLmNoYXJDb2RlQXQoMjQpOw0KICAgIG9iai5taW5vclZlcnNpb24gPSBmaWxlLmNoYXJDb2RlQXQoMjUpOw0KICAgIG9iai5mbGFncyA9IFJlYWRTaG9ydFgoZmlsZSwgMjYpOyAgICAgICAgICAgICAgICAgICAvLyBGbGFnczogMSA9IERvIG5vdCBjb25zdW1lIHJlY29yZHMNCiAgICB2YXIgZGF0YVJlY29yZENvdW50ID0gUmVhZEludFgoZmlsZSwgMjgpOw0KICAgIG9iai5kYXRhUmVjb3Jkc0NvbnN1bWVkID0gUmVhZEludFgoZmlsZSwgMzIpOw0KICAgIG9iai5kYXRhUmVjb3JkQ2h1bmtDb3VudCA9IFJlYWRTaG9ydFgoZmlsZSwgMzYpOw0KICAgIG9iai5yZWNvcmRzID0gW107DQoNCiAgICB2YXIgcHRyID0gNTEyOw0KICAgIHdoaWxlIChwdHIgKyA1MTIgPD0gZmlsZS5sZW5ndGgpIHsNCg0KICAgICAgICAvLyBGb3JtYXQgb2YgYSBkYXRhIHJlY29yZCBoZWFkZXI6DQogICAgICAgIC8vIFJlY29yZFR5cGVJZGVudGlmaWVyKDQpICAgICAgICAgICAtIGlkZW50aWZpZXMgdGhlIHR5cGUgb2YgcmVjb3JkIChpbiB0aGlzIGNhc2UgYSBkYXRhIHJlY29yZCkuIFJlY29yZCBJZGVudGlmaWVyczogSW52YWxpZCAtIDAsIERhdGEgUmVjb3JkIC0gMQ0KICAgICAgICAvLyBSZWNvcmRGbGFncyg0KSAgICAgICAgICAgICAgICAgICAgLSBjb250YWlucyBhIHNldCBvZiBiaXQgZmxhZ3MgdGhhdCBjaGFyYWN0ZXJpemUgdGhlIHJlY29yZC4NCiAgICAgICAgLy8gUmVjb3JkQ2h1bmtDb3VudCgyKSAgICAgICAgICAgICAgIC0gY29udGFpbnMgdGhlIG51bWJlciBvZiA1MTItYnl0ZSBjaHVua3Mgb2NjdXBpZWQgYnkgdGhlIHJlY29yZCBpbmNsdWRpbmcgYWxsIGhlYWRlciwgYm9keSwgYW5kIHJlc2VydmVkIGZpZWxkcy4NCiAgICAgICAgLy8gUmVjb3JkSGVhZGVyQnl0ZUNvdW50KDIpICAgICAgICAgIC0gaW5kaWNhdGVzIHRoZSBsZW5ndGggb2YgdGhlIHJlY29yZCBoZWFkZXIgaW4gYnl0ZXMuDQogICAgICAgIC8vIFJlY29yZE51bWJlcig0KSAgICAgICAgICAgICAgICAgICAtIHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhlIHJlY29yZCBhbW9uZyBhbGwgcmVjb3JkcyBpbiB0aGUgZmlsZSwgaW5jbHVkaW5nIGludmFsaWQgYXMgd2VsbCBhcyB2YWxpZCByZWNvcmRzLiBUaGUgaWRlbnRpZmllciBpcyBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyLg0KDQogICAgICAgIHZhciByID0ge307DQogICAgICAgIHIudHlwZUlkZW50aWZpZXIgPSBSZWFkSW50WChmaWxlLCBwdHIpOw0KICAgICAgICByLmZsYWdzID0gUmVhZEludFgoZmlsZSwgcHRyICsgNCk7ICAgICAgICAgICAgICAvLyBGbGFnczogMSA9IFZhbGlkLCAyID0gU2NyYW1ibGVkDQogICAgICAgIHIuY2h1bmtDb3VudCA9IFJlYWRTaG9ydFgoZmlsZSwgcHRyICsgOCk7DQogICAgICAgIHIuaGVhZGVyQnl0ZUNvdW50ID0gUmVhZFNob3J0WChmaWxlLCBwdHIgKyAxMCk7DQogICAgICAgIHIubnVtYmVyID0gUmVhZEludFgoZmlsZSwgcHRyICsgMTIpOw0KICAgICAgICByLnZhcmlhYmxlcyA9IFtdOw0KDQogICAgICAgIHZhciBwdHIyID0gMCwgcmVjYmluID0gZmlsZS5zdWJzdHJpbmcocHRyICsgMjQsIHB0ciArIDUxMik7DQogICAgICAgIGlmICgoci5mbGFncyAmIDIpICE9IDApIHsgcmVjYmluID0gQW10U2V0dXBCaW5EZXNjcmFtYmxlUmVjb3JkRGF0YShyZWNiaW4pOyB9IC8vIERlLVNjcmFtYmxlIHRoZSByZWNvcmQNCiAgICAgICAgd2hpbGUgKDEpIHsNCg0KICAgICAgICAgICAgLy8gRm9ybWF0IG9mIGEgZGF0YSByZWNvcmQgZW50cnk6DQogICAgICAgICAgICAvLyBNb2R1bGVJZGVudGlmaWVyKDIpICAgICAgICAgICAtIGlkZW50aWZpZXMgdGhlIHRhcmdldCBNRSBtb2R1bGUgZm9yIHRoZSBlbnRyeS4NCiAgICAgICAgICAgIC8vIFZhcmlhYmxlSWRlbnRpZmllcigyKSAgICAgICAgIC0gYW4gZW51bWVyYXRpb24gdmFsdWUgdGhhdCBpZGVudGlmaWVzIHRoZSB2YXJpYWJsZS4gVmFyaWFibGUgaWRlbnRpZmllcnMgYXJlIHVuaXF1ZSB0byBlYWNoIE1vZHVsZUlkZW50aWZpZXIuDQogICAgICAgICAgICAvLyBWYXJpYWJsZUxlbmd0aCgyKSAgICAgICAgICAgICAtIGlzIHRoZSBsZW5ndGggb2YgdGhlIHZhcmlhYmxlIHZhbHVlIGluIGJ5dGVzLg0KICAgICAgICAgICAgLy8gVmFyaWFibGVWYWx1ZSAgICAgICAgICAgICAgICAgLSBpcyB0aGUgdmFsdWUgdG8gYmUgYXNzaWduZWQgdG8gdGhlIHZhcmlhYmxlLg0KDQogICAgICAgICAgICB2YXIgdiA9IHt9Ow0KICAgICAgICAgICAgdi5tb2R1bGVpZCA9IFJlYWRTaG9ydFgocmVjYmluLCBwdHIyKTsNCiAgICAgICAgICAgIHYudmFyaWQgPSBSZWFkU2hvcnRYKHJlY2JpbiwgcHRyMiArIDIpOw0KICAgICAgICAgICAgaWYgKHYubW9kdWxlaWQgPT0gMCB8fCB2LnZhcmlkID09IDApIGJyZWFrOw0KICAgICAgICAgICAgaWYgKEFtdFNldHVwQmluVmFySWRzW3YubW9kdWxlaWRdW3YudmFyaWRdKSB7DQogICAgICAgICAgICAgICAgdi5sZW5ndGggPSBSZWFkU2hvcnRYKHJlY2JpbiwgcHRyMiArIDQpOw0KICAgICAgICAgICAgICAgIHYudHlwZSA9IEFtdFNldHVwQmluVmFySWRzW3YubW9kdWxlaWRdW3YudmFyaWRdWzBdOw0KICAgICAgICAgICAgICAgIHYuZGVzYyA9IEFtdFNldHVwQmluVmFySWRzW3YubW9kdWxlaWRdW3YudmFyaWRdWzFdOw0KICAgICAgICAgICAgICAgIHYudmFsdWUgPSByZWNiaW4uc3Vic3RyaW5nKHB0cjIgKyA4LCBwdHIyICsgOCArIHYubGVuZ3RoKTsNCiAgICAgICAgICAgICAgICBpZiAodi50eXBlID09IDEgJiYgdi5sZW5ndGggPT0gMSkgdi52YWx1ZSA9IHYudmFsdWUuY2hhckNvZGVBdCgwKTsgLy8gMSBieXRlIG51bWJlcg0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHYudHlwZSA9PSAyICYmIHYubGVuZ3RoID09IDIpIHYudmFsdWUgPSBSZWFkU2hvcnRYKHYudmFsdWUsIDApOyAvLyAyIGJ5dGUgbnVtYmVyDQogICAgICAgICAgICAgICAgZWxzZSBpZiAodi50eXBlID09IDMgJiYgdi5sZW5ndGggPT0gNCkgdi52YWx1ZSA9IFJlYWRJbnRYKHYudmFsdWUsIDApOyAvLyA0IGJ5dGUgbnVtYmVyDQogICAgICAgICAgICAgICAgZWxzZSBpZiAodi50eXBlID09IDQpIHYudmFsdWUgPSBndWlkVG9TdHIocnN0cjJoZXgodi52YWx1ZSkpOyAvLyBHVUlEDQogICAgICAgICAgICAgICAgci52YXJpYWJsZXMucHVzaCh2KTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHB0cjIgKz0gKDggKyAoTWF0aC5mbG9vcigodi5sZW5ndGggKyAzKSAvIDQpICogNCkpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gU29ydCB0aGUgdmFyaWFibGVzDQogICAgICAgIHIudmFyaWFibGVzLnNvcnQoQW10U2V0dXBCaW5WYXJpYWJsZUNvbXBhcmUpOw0KDQogICAgICAgIG9iai5yZWNvcmRzLnB1c2gocik7DQogICAgICAgIHB0ciArPSA1MTI7DQogICAgfQ0KDQogICAgaWYgKGRhdGFSZWNvcmRDb3VudCAhPSBvYmoucmVjb3Jkcy5sZW5ndGgpIHJldHVybjsgLy8gTWlzbWF0Y2ggcmVjb3JkIGNvdW50DQogICAgcmV0dXJuIG9iajsNCn0NCg0KLy8gQ29uc3RydWN0IGEgU2V0dXAuYmluIGZpbGUNCnZhciBBbXRTZXR1cEJpbkVuY29kZSA9IGZ1bmN0aW9uIChvYmopIHsNCiAgICBpZiAob2JqLmZpbGVUeXBlIDwgMSAmJiBvYmouZmlsZVR5cGUgPiBBbXRTZXR1cEJpblNldHVwR3VpZHMubGVuZ3RoKSByZXR1cm4gbnVsbDsNCiAgICB2YXIgb3V0ID0gW10sIHIgPSBBbXRTZXR1cEJpblNldHVwR3VpZHNbb2JqLmZpbGVUeXBlIC0gMV0sIHJlY2NvdW50ID0gMDsNCiAgICByICs9IFNob3J0VG9TdHJYKG9iai5yZWNvcmRDaHVua0NvdW50KTsNCiAgICByICs9IFNob3J0VG9TdHJYKG9iai5yZWNvcmRIZWFkZXJCeXRlQ291bnQpOw0KICAgIHIgKz0gSW50VG9TdHJYKG9iai5yZWNvcmROdW1iZXIpOw0KICAgIHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShvYmoubWFqb3JWZXJzaW9uLCBvYmoubWlub3JWZXJzaW9uKTsNCiAgICByICs9IFNob3J0VG9TdHJYKG9iai5mbGFncyk7IC8vIEZsYWdzOiAxID0gRG8gbm90IGNvbnN1bWUgcmVjb3Jkcw0KICAgIHIgKz0gSW50VG9TdHJYKG9iai5yZWNvcmRzLmxlbmd0aCk7DQogICAgciArPSBJbnRUb1N0clgob2JqLmRhdGFSZWNvcmRzQ29uc3VtZWQpOw0KICAgIHIgKz0gU2hvcnRUb1N0clgob2JqLmRhdGFSZWNvcmRDaHVua0NvdW50KTsNCiAgICB3aGlsZSAoci5sZW5ndGggPCA1MTIpIHsgciArPSAiXDAiOyB9IC8vIFBhZCB0aGUgaGVhZGVyDQogICAgb3V0LnB1c2gocik7DQoNCiAgICAvLyBXcml0ZSBlYWNoIHJlY29yZA0KICAgIGZvciAodmFyIGkgaW4gb2JqLnJlY29yZHMpIHsNCiAgICAgICAgdmFyIHIyID0gIiIsIHJlYyA9IG9iai5yZWNvcmRzW2ldOw0KICAgICAgICByMiArPSBJbnRUb1N0clgocmVjLnR5cGVJZGVudGlmaWVyKTsNCiAgICAgICAgcjIgKz0gSW50VG9TdHJYKHJlYy5mbGFncyk7DQogICAgICAgIHIyICs9IEludFRvU3RyWCgwKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVzZXJ2ZWQNCiAgICAgICAgcjIgKz0gSW50VG9TdHJYKDApOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXNlcnZlZA0KICAgICAgICByMiArPSBTaG9ydFRvU3RyWCgxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlYy5jaHVua0NvdW50DQogICAgICAgIHIyICs9IFNob3J0VG9TdHJYKDI0KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVjLmhlYWRlckJ5dGVDb3VudA0KICAgICAgICByMiArPSBJbnRUb1N0clgoKytyZWNjb3VudCk7DQoNCiAgICAgICAgLy8gU29ydCB0aGUgdmFyaWFibGVzDQogICAgICAgIHJlYy52YXJpYWJsZXMuc29ydChBbXRTZXR1cEJpblZhcmlhYmxlQ29tcGFyZSk7DQoNCiAgICAgICAgLyoNCiAgICAgICAgLy8gQ2hhbmdlIHZhcmlhYmxlIHByaW9yaXR5DQogICAgICAgIEFtdFNldHVwQmluTW92ZVRvVG9wKHIudmFyaWFibGVzLCAxLCAzKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFuYWdlYWJpbGl0eSBGZWF0dXJlIFNlbGVjdGlvbg0KICAgICAgICBBbXRTZXR1cEJpbk1vdmVUb1RvcChyLnZhcmlhYmxlcywgMSwgMik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5ldyBNRUJ4IHBhc3N3b3JkDQogICAgICAgIEFtdFNldHVwQmluTW92ZVRvVG9wKHIudmFyaWFibGVzLCAxLCAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ3VycmVudCBNRUJ4IHBhc3N3b3JkDQogICAgICAgICovDQoNCiAgICAgICAgLy8gV3JpdGUgZWFjaCB2YXJpYWJsZQ0KICAgICAgICBmb3IgKHZhciBqIGluIHJlYy52YXJpYWJsZXMpIHsNCiAgICAgICAgICAgIHZhciByMyA9ICIiLCB2ID0gcmVjLnZhcmlhYmxlc1tqXSwgZGF0YSA9IHYudmFsdWU7DQogICAgICAgICAgICB2LnR5cGUgPSBBbXRTZXR1cEJpblZhcklkc1t2Lm1vZHVsZWlkXVt2LnZhcmlkXVswXTsgICAgICAgICAgICAgLy8gU2V0IHRoZSBjb3JyZWN0IHR5cGUgaWYgbm90IGFscmVheSBjb25uZWN0DQogICAgICAgICAgICBpZiAoKHYudHlwZSA+IDApICYmICh2LnR5cGUgPCA0KSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhIG51bWVyaWMgdmFsdWUsIGVuY29kZSBpdCBjb3JyZWN0bHkNCiAgICAgICAgICAgICAgICBkYXRhID0gcGFyc2VJbnQoZGF0YSk7DQogICAgICAgICAgICAgICAgaWYgKHYudHlwZSA9PSAxKSBkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZShkYXRhKTsNCiAgICAgICAgICAgICAgICBpZiAodi50eXBlID09IDIpIGRhdGEgPSBTaG9ydFRvU3RyWChkYXRhKTsNCiAgICAgICAgICAgICAgICBpZiAodi50eXBlID09IDMpIGRhdGEgPSBJbnRUb1N0clgoZGF0YSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAodi50eXBlID09IDQpIHsgZGF0YSA9IGhleDJyc3RyKGd1aWRUb1N0cihkYXRhLnNwbGl0KCctJykuam9pbignJykpLnNwbGl0KCctJykuam9pbignJykpOyB9DQogICAgICAgICAgICByMyArPSBTaG9ydFRvU3RyWCh2Lm1vZHVsZWlkKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9kdWxlIElkZW50aWZpZXINCiAgICAgICAgICAgIHIzICs9IFNob3J0VG9TdHJYKHYudmFyaWQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBWYXJpYWJsZSBJZGVudGlmaWVyDQogICAgICAgICAgICByMyArPSBTaG9ydFRvU3RyWChkYXRhLmxlbmd0aCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVmFyaWFibGUgTGVuZ3RoDQogICAgICAgICAgICByMyArPSBTaG9ydFRvU3RyWCgwKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVzZXJ2ZWQNCiAgICAgICAgICAgIHIzICs9IGRhdGE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBWYXJpYWJsZSBEYXRhDQogICAgICAgICAgICB3aGlsZSAocjMubGVuZ3RoICUgNCAhPSAwKSB7IHIzICs9ICJcMCI7IH0gICAgICAgICAgICAgICAgICAgICAgLy8gUGFkIHRoZSB2YXJpYWJsZQ0KICAgICAgICAgICAgcjIgKz0gcjM7DQogICAgICAgIH0NCg0KICAgICAgICB3aGlsZSAocjIubGVuZ3RoIDwgNTEyKSB7IHIyICs9ICJcMCI7IH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBhZCB0aGUgcmVjb3JkDQogICAgICAgIGlmICgocmVjLmZsYWdzICYgMikgIT0gMCkgeyByMiA9IHIyLnN1YnN0cmluZygwLCAyNCkgKyBBbXRTZXR1cEJpblNjcmFtYmxlUmVjb3JkRGF0YShyMi5zdWJzdHJpbmcoMjQpKTsgfSAvLyBTY3JhbWJsZSB0aGUgcmVjb3JkIHN0YXJ0aW5nIGF0IGJ5dGUgMjQsIGFmdGVyIHRoZSBoZWFkZXINCiAgICAgICAgb3V0LnB1c2gocjIpOw0KICAgIH0NCiAgICByZXR1cm4gb3V0LmpvaW4oJycpOw0KfQ0KDQovLyBVc2VkIHRvIHNvcnQgdmFyaWFibGVzDQpmdW5jdGlvbiBBbXRTZXR1cEJpblZhcmlhYmxlQ29tcGFyZShhLCBiKSB7DQogICAgaWYgKGEubW9kdWxlaWQgPiBiLm1vZHVsZWlkKSByZXR1cm4gMTsNCiAgICBpZiAoYS5tb2R1bGVpZCA8IGIubW9kdWxlaWQpIHJldHVybiAtMTsNCiAgICBpZiAoYS52YXJpZCA+IGIudmFyaWQpIHJldHVybiAxOw0KICAgIGlmIChhLnZhcmlkIDwgYi52YXJpZCkgcmV0dXJuIC0xOw0KICAgIHJldHVybiAwOw0KfQ0KDQovLyBTY3JhbWJsZSBhbmQgdW4tc2NyYW1ibGUgcmVjb3Jkcw0KZnVuY3Rpb24gQW10U2V0dXBCaW5TY3JhbWJsZVJlY29yZERhdGEoZGF0YSkgeyB2YXIgb3V0ID0gIiI7IGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykgeyBvdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoZGF0YS5jaGFyQ29kZUF0KGkpICsgMTcpICYgMHhGRik7IH0gcmV0dXJuIG91dDsgfQ0KZnVuY3Rpb24gQW10U2V0dXBCaW5EZXNjcmFtYmxlUmVjb3JkRGF0YShkYXRhKSB7IHZhciBvdXQgPSAiIjsgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7IG91dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChkYXRhLmNoYXJDb2RlQXQoaSkgKyAweEVGKSAmIDB4RkYpOyB9IHJldHVybiBvdXQ7IH0NCg0KLy8gRmluZCBhIG1vZHVsZWlkL3ZhcmlkIGluIHRoZSB2YXJpYWJsZSBsaXN0LCBpZiBmb3VuZCwgbW92ZSBpdCB0byB0aGUgdG9wDQovL2Z1bmN0aW9uIEFtdFNldHVwQmluTW92ZVRvVG9wKHZhcmlhYmxlcywgbW9kdWxlaWQsIHZhcmlkKSB7IHZhciBpID0gLTE7IGZvciAodmFyIGogaW4gdmFyaWFibGVzKSB7IGlmICgodmFyaWFibGVzW2pdLm1vZHVsZWlkID09IG1vZHVsZWlkKSAmJiAodmFyaWFibGVzW2pdLnZhcmlkID09IHZhcmlkKSkgeyBpID0gajsgfSB9IGlmIChpID4gMSkgeyBBcnJheUVsZW1lbnRNb3ZlKHZhcmlhYmxlcywgaSwgMCk7IH0gfQ0KLyogRmlsZVNhdmVyLmpzDQogKiBBIHNhdmVBcygpIEZpbGVTYXZlciBpbXBsZW1lbnRhdGlvbi4NCiAqIDEuMS4yMDE1MTAwMw0KICoNCiAqIEJ5IEVsaSBHcmV5LCBodHRwOi8vZWxpZ3JleS5jb20NCiAqIExpY2Vuc2U6IE1JVA0KICogICBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2VsaWdyZXkvRmlsZVNhdmVyLmpzL2Jsb2IvbWFzdGVyL0xJQ0VOU0UubWQNCiAqLw0KDQovKmdsb2JhbCBzZWxmICovDQovKmpzbGludCBiaXR3aXNlOiB0cnVlLCBpbmRlbnQ6IDQsIGxheGJyZWFrOiB0cnVlLCBsYXhjb21tYTogdHJ1ZSwgc21hcnR0YWJzOiB0cnVlLCBwbHVzcGx1czogdHJ1ZSAqLw0KDQovKiEgQHNvdXJjZSBodHRwOi8vcHVybC5lbGlncmV5LmNvbS9naXRodWIvRmlsZVNhdmVyLmpzL2Jsb2IvbWFzdGVyL0ZpbGVTYXZlci5qcyAqLw0KDQp2YXIgc2F2ZUFzID0gc2F2ZUFzIHx8IChmdW5jdGlvbiAodmlldykgew0KICAgICJ1c2Ugc3RyaWN0IjsNCiAgICAvLyBJRSA8MTAgaXMgZXhwbGljaXRseSB1bnN1cHBvcnRlZA0KICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9PSAidW5kZWZpbmVkIiAmJiAvTVNJRSBbMS05XVwuLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSB7DQogICAgICAgIHJldHVybjsNCiAgICB9DQogICAgdmFyDQoJCSAgZG9jID0gdmlldy5kb2N1bWVudA0KCQkgIC8vIG9ubHkgZ2V0IFVSTCB3aGVuIG5lY2Vzc2FyeSBpbiBjYXNlIEJsb2IuanMgaGFzbid0IG92ZXJyaWRkZW4gaXQgeWV0DQoJCSwgZ2V0X1VSTCA9IGZ1bmN0aW9uICgpIHsNCgkJICAgIHJldHVybiB2aWV3LlVSTCB8fCB2aWV3LndlYmtpdFVSTCB8fCB2aWV3Ow0KCQl9DQoJCSwgc2F2ZV9saW5rID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIsICJhIikNCgkJLCBjYW5fdXNlX3NhdmVfbGluayA9ICJkb3dubG9hZCIgaW4gc2F2ZV9saW5rDQoJCSwgY2xpY2sgPSBmdW5jdGlvbiAobm9kZSkgew0KCQkgICAgdmFyIGV2ZW50ID0gbmV3IE1vdXNlRXZlbnQoImNsaWNrIik7DQoJCSAgICBub2RlLmRpc3BhdGNoRXZlbnQoZXZlbnQpOw0KCQl9DQoJCSwgaXNfc2FmYXJpID0gL1ZlcnNpb25cL1tcZFwuXSsuKlNhZmFyaS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KQ0KCQksIHdlYmtpdF9yZXFfZnMgPSB2aWV3LndlYmtpdFJlcXVlc3RGaWxlU3lzdGVtDQoJCSwgcmVxX2ZzID0gdmlldy5yZXF1ZXN0RmlsZVN5c3RlbSB8fCB3ZWJraXRfcmVxX2ZzIHx8IHZpZXcubW96UmVxdWVzdEZpbGVTeXN0ZW0NCgkJLCB0aHJvd19vdXRzaWRlID0gZnVuY3Rpb24gKGV4KSB7DQoJCSAgICAodmlldy5zZXRJbW1lZGlhdGUgfHwgdmlldy5zZXRUaW1lb3V0KShmdW5jdGlvbiAoKSB7DQoJCSAgICAgICAgdGhyb3cgZXg7DQoJCSAgICB9LCAwKTsNCgkJfQ0KCQksIGZvcmNlX3NhdmVhYmxlX3R5cGUgPSAiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIg0KCQksIGZzX21pbl9zaXplID0gMA0KCQkvLyBTZWUgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTM3NTI5NyNjNyBhbmQNCgkJLy8gaHR0cHM6Ly9naXRodWIuY29tL2VsaWdyZXkvRmlsZVNhdmVyLmpzL2NvbW1pdC80ODU5MzBhI2NvbW1pdGNvbW1lbnQtODc2ODA0Nw0KCQkvLyBmb3IgdGhlIHJlYXNvbmluZyBiZWhpbmQgdGhlIHRpbWVvdXQgYW5kIHJldm9jYXRpb24gZmxvdw0KCQksIGFyYml0cmFyeV9yZXZva2VfdGltZW91dCA9IDUwMCAvLyBpbiBtcw0KCQksIHJldm9rZSA9IGZ1bmN0aW9uIChmaWxlKSB7DQoJCSAgICB2YXIgcmV2b2tlciA9IGZ1bmN0aW9uICgpIHsNCgkJICAgICAgICBpZiAodHlwZW9mIGZpbGUgPT09ICJzdHJpbmciKSB7IC8vIGZpbGUgaXMgYW4gb2JqZWN0IFVSTA0KCQkgICAgICAgICAgICBnZXRfVVJMKCkucmV2b2tlT2JqZWN0VVJMKGZpbGUpOw0KCQkgICAgICAgIH0gZWxzZSB7IC8vIGZpbGUgaXMgYSBGaWxlDQoJCSAgICAgICAgICAgIGZpbGUucmVtb3ZlKCk7DQoJCSAgICAgICAgfQ0KCQkgICAgfTsNCgkJICAgIGlmICh2aWV3LmNocm9tZSkgew0KCQkgICAgICAgIHJldm9rZXIoKTsNCgkJICAgIH0gZWxzZSB7DQoJCSAgICAgICAgc2V0VGltZW91dChyZXZva2VyLCBhcmJpdHJhcnlfcmV2b2tlX3RpbWVvdXQpOw0KCQkgICAgfQ0KCQl9DQoJCSwgZGlzcGF0Y2ggPSBmdW5jdGlvbiAoZmlsZXNhdmVyLCBldmVudF90eXBlcywgZXZlbnQpIHsNCgkJICAgIGV2ZW50X3R5cGVzID0gW10uY29uY2F0KGV2ZW50X3R5cGVzKTsNCgkJICAgIHZhciBpID0gZXZlbnRfdHlwZXMubGVuZ3RoOw0KCQkgICAgd2hpbGUgKGktLSkgew0KCQkgICAgICAgIHZhciBsaXN0ZW5lciA9IGZpbGVzYXZlclsib24iICsgZXZlbnRfdHlwZXNbaV1dOw0KCQkgICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgPT09ICJmdW5jdGlvbiIpIHsNCgkJICAgICAgICAgICAgdHJ5IHsNCgkJICAgICAgICAgICAgICAgIGxpc3RlbmVyLmNhbGwoZmlsZXNhdmVyLCBldmVudCB8fCBmaWxlc2F2ZXIpOw0KCQkgICAgICAgICAgICB9IGNhdGNoIChleCkgew0KCQkgICAgICAgICAgICAgICAgdGhyb3dfb3V0c2lkZShleCk7DQoJCSAgICAgICAgICAgIH0NCgkJICAgICAgICB9DQoJCSAgICB9DQoJCX0NCgkJLCBhdXRvX2JvbSA9IGZ1bmN0aW9uIChibG9iKSB7DQoJCSAgICAvLyBwcmVwZW5kIEJPTSBmb3IgVVRGLTggWE1MIGFuZCB0ZXh0IHR5cGVzIChpbmNsdWRpbmcgSFRNTCkNCgkJICAgIGlmICgvXlxzKig/OnRleHRcL1xTKnxhcHBsaWNhdGlvblwveG1sfFxTKlwvXFMqXCt4bWwpXHMqOy4qY2hhcnNldFxzKj1ccyp1dGYtOC9pLnRlc3QoYmxvYi50eXBlKSkgew0KCQkgICAgICAgIHJldHVybiBuZXcgQmxvYihbIlx1ZmVmZiIsIGJsb2JdLCB7IHR5cGU6IGJsb2IudHlwZSB9KTsNCgkJICAgIH0NCgkJICAgIHJldHVybiBibG9iOw0KCQl9DQoJCSwgRmlsZVNhdmVyID0gZnVuY3Rpb24gKGJsb2IsIG5hbWUsIG5vX2F1dG9fYm9tKSB7DQoJCSAgICBpZiAoIW5vX2F1dG9fYm9tKSB7DQoJCSAgICAgICAgYmxvYiA9IGF1dG9fYm9tKGJsb2IpOw0KCQkgICAgfQ0KCQkgICAgLy8gRmlyc3QgdHJ5IGEuZG93bmxvYWQsIHRoZW4gd2ViIGZpbGVzeXN0ZW0sIHRoZW4gb2JqZWN0IFVSTHMNCgkJICAgIHZhcg0KCQkJCSAgZmlsZXNhdmVyID0gdGhpcw0KCQkJCSwgdHlwZSA9IGJsb2IudHlwZQ0KCQkJCSwgYmxvYl9jaGFuZ2VkID0gZmFsc2UNCgkJCQksIG9iamVjdF91cmwNCgkJCQksIHRhcmdldF92aWV3DQoJCQkJLCBkaXNwYXRjaF9hbGwgPSBmdW5jdGlvbiAoKSB7DQoJCQkJICAgIGRpc3BhdGNoKGZpbGVzYXZlciwgIndyaXRlc3RhcnQgcHJvZ3Jlc3Mgd3JpdGUgd3JpdGVlbmQiLnNwbGl0KCIgIikpOw0KCQkJCX0NCgkJCQkvLyBvbiBhbnkgZmlsZXN5cyBlcnJvcnMgcmV2ZXJ0IHRvIHNhdmluZyB3aXRoIG9iamVjdCBVUkxzDQoJCQkJLCBmc19lcnJvciA9IGZ1bmN0aW9uICgpIHsNCgkJCQkgICAgaWYgKHRhcmdldF92aWV3ICYmIGlzX3NhZmFyaSAmJiB0eXBlb2YgRmlsZVJlYWRlciAhPT0gInVuZGVmaW5lZCIpIHsNCgkJCQkgICAgICAgIC8vIFNhZmFyaSBkb2Vzbid0IGFsbG93IGRvd25sb2FkaW5nIG9mIGJsb2IgdXJscw0KCQkJCSAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7DQoJCQkJICAgICAgICByZWFkZXIub25sb2FkZW5kID0gZnVuY3Rpb24gKCkgew0KCQkJCSAgICAgICAgICAgIHZhciBiYXNlNjREYXRhID0gcmVhZGVyLnJlc3VsdDsNCgkJCQkgICAgICAgICAgICB0YXJnZXRfdmlldy5sb2NhdGlvbi5ocmVmID0gImRhdGE6YXR0YWNobWVudC9maWxlIiArIGJhc2U2NERhdGEuc2xpY2UoYmFzZTY0RGF0YS5zZWFyY2goL1ssO10vKSk7DQoJCQkJICAgICAgICAgICAgZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuRE9ORTsNCgkJCQkgICAgICAgICAgICBkaXNwYXRjaF9hbGwoKTsNCgkJCQkgICAgICAgIH07DQoJCQkJICAgICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChibG9iKTsNCgkJCQkgICAgICAgIGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLklOSVQ7DQoJCQkJICAgICAgICByZXR1cm47DQoJCQkJICAgIH0NCgkJCQkgICAgLy8gZG9uJ3QgY3JlYXRlIG1vcmUgb2JqZWN0IFVSTHMgdGhhbiBuZWVkZWQNCgkJCQkgICAgaWYgKGJsb2JfY2hhbmdlZCB8fCAhb2JqZWN0X3VybCkgew0KCQkJCSAgICAgICAgb2JqZWN0X3VybCA9IGdldF9VUkwoKS5jcmVhdGVPYmplY3RVUkwoYmxvYik7DQoJCQkJICAgIH0NCgkJCQkgICAgaWYgKHRhcmdldF92aWV3KSB7DQoJCQkJICAgICAgICB0YXJnZXRfdmlldy5sb2NhdGlvbi5ocmVmID0gb2JqZWN0X3VybDsNCgkJCQkgICAgfSBlbHNlIHsNCgkJCQkgICAgICAgIHZhciBuZXdfdGFiID0gdmlldy5vcGVuKG9iamVjdF91cmwsICJfYmxhbmsiKTsNCgkJCQkgICAgICAgIGlmIChuZXdfdGFiID09IHVuZGVmaW5lZCAmJiBpc19zYWZhcmkpIHsNCgkJCQkgICAgICAgICAgICAvL0FwcGxlIGRvIG5vdCBhbGxvdyB3aW5kb3cub3Blbiwgc2VlIGh0dHA6Ly9iaXQubHkvMWtaZmZSSQ0KCQkJCSAgICAgICAgICAgIHZpZXcubG9jYXRpb24uaHJlZiA9IG9iamVjdF91cmwNCgkJCQkgICAgICAgIH0NCgkJCQkgICAgfQ0KCQkJCSAgICBmaWxlc2F2ZXIucmVhZHlTdGF0ZSA9IGZpbGVzYXZlci5ET05FOw0KCQkJCSAgICBkaXNwYXRjaF9hbGwoKTsNCgkJCQkgICAgcmV2b2tlKG9iamVjdF91cmwpOw0KCQkJCX0NCgkJCQksIGFib3J0YWJsZSA9IGZ1bmN0aW9uIChmdW5jKSB7DQoJCQkJICAgIHJldHVybiBmdW5jdGlvbiAoKSB7DQoJCQkJICAgICAgICBpZiAoZmlsZXNhdmVyLnJlYWR5U3RhdGUgIT09IGZpbGVzYXZlci5ET05FKSB7DQoJCQkJICAgICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsNCgkJCQkgICAgICAgIH0NCgkJCQkgICAgfTsNCgkJCQl9DQoJCQkJLCBjcmVhdGVfaWZfbm90X2ZvdW5kID0geyBjcmVhdGU6IHRydWUsIGV4Y2x1c2l2ZTogZmFsc2UgfQ0KCQkJCSwgc2xpY2UNCgkJICAgIDsNCgkJICAgIGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLklOSVQ7DQoJCSAgICBpZiAoIW5hbWUpIHsNCgkJICAgICAgICBuYW1lID0gImRvd25sb2FkIjsNCgkJICAgIH0NCgkJICAgIGlmIChjYW5fdXNlX3NhdmVfbGluaykgew0KCQkgICAgICAgIG9iamVjdF91cmwgPSBnZXRfVVJMKCkuY3JlYXRlT2JqZWN0VVJMKGJsb2IpOw0KCQkgICAgICAgIHNhdmVfbGluay5ocmVmID0gb2JqZWN0X3VybDsNCgkJICAgICAgICBzYXZlX2xpbmsuZG93bmxvYWQgPSBuYW1lOw0KCQkgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgew0KCQkgICAgICAgICAgICBjbGljayhzYXZlX2xpbmspOw0KCQkgICAgICAgICAgICBkaXNwYXRjaF9hbGwoKTsNCgkJICAgICAgICAgICAgcmV2b2tlKG9iamVjdF91cmwpOw0KCQkgICAgICAgICAgICBmaWxlc2F2ZXIucmVhZHlTdGF0ZSA9IGZpbGVzYXZlci5ET05FOw0KCQkgICAgICAgIH0pOw0KCQkgICAgICAgIHJldHVybjsNCgkJICAgIH0NCgkJICAgIC8vIE9iamVjdCBhbmQgd2ViIGZpbGVzeXN0ZW0gVVJMcyBoYXZlIGEgcHJvYmxlbSBzYXZpbmcgaW4gR29vZ2xlIENocm9tZSB3aGVuDQoJCSAgICAvLyB2aWV3ZWQgaW4gYSB0YWIsIHNvIEkgZm9yY2Ugc2F2ZSB3aXRoIGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbQ0KCQkgICAgLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9OTExNTgNCgkJICAgIC8vIFVwZGF0ZTogR29vZ2xlIGVycmFudGx5IGNsb3NlZCA5MTE1OCwgSSBzdWJtaXR0ZWQgaXQgYWdhaW46DQoJCSAgICAvLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9Mzg5NjQyDQoJCSAgICBpZiAodmlldy5jaHJvbWUgJiYgdHlwZSAmJiB0eXBlICE9PSBmb3JjZV9zYXZlYWJsZV90eXBlKSB7DQoJCSAgICAgICAgc2xpY2UgPSBibG9iLnNsaWNlIHx8IGJsb2Iud2Via2l0U2xpY2U7DQoJCSAgICAgICAgYmxvYiA9IHNsaWNlLmNhbGwoYmxvYiwgMCwgYmxvYi5zaXplLCBmb3JjZV9zYXZlYWJsZV90eXBlKTsNCgkJICAgICAgICBibG9iX2NoYW5nZWQgPSB0cnVlOw0KCQkgICAgfQ0KCQkgICAgLy8gU2luY2UgSSBjYW4ndCBiZSBzdXJlIHRoYXQgdGhlIGd1ZXNzZWQgbWVkaWEgdHlwZSB3aWxsIHRyaWdnZXIgYSBkb3dubG9hZA0KCQkgICAgLy8gaW4gV2ViS2l0LCBJIGFwcGVuZCAuZG93bmxvYWQgdG8gdGhlIGZpbGVuYW1lLg0KCQkgICAgLy8gaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTY1NDQwDQoJCSAgICBpZiAod2Via2l0X3JlcV9mcyAmJiBuYW1lICE9PSAiZG93bmxvYWQiKSB7DQoJCSAgICAgICAgbmFtZSArPSAiLmRvd25sb2FkIjsNCgkJICAgIH0NCgkJICAgIGlmICh0eXBlID09PSBmb3JjZV9zYXZlYWJsZV90eXBlIHx8IHdlYmtpdF9yZXFfZnMpIHsNCgkJICAgICAgICB0YXJnZXRfdmlldyA9IHZpZXc7DQoJCSAgICB9DQoJCSAgICBpZiAoIXJlcV9mcykgew0KCQkgICAgICAgIGZzX2Vycm9yKCk7DQoJCSAgICAgICAgcmV0dXJuOw0KCQkgICAgfQ0KCQkgICAgZnNfbWluX3NpemUgKz0gYmxvYi5zaXplOw0KCQkgICAgcmVxX2ZzKHZpZXcuVEVNUE9SQVJZLCBmc19taW5fc2l6ZSwgYWJvcnRhYmxlKGZ1bmN0aW9uIChmcykgew0KCQkgICAgICAgIGZzLnJvb3QuZ2V0RGlyZWN0b3J5KCJzYXZlZCIsIGNyZWF0ZV9pZl9ub3RfZm91bmQsIGFib3J0YWJsZShmdW5jdGlvbiAoZGlyKSB7DQoJCSAgICAgICAgICAgIHZhciBzYXZlID0gZnVuY3Rpb24gKCkgew0KCQkgICAgICAgICAgICAgICAgZGlyLmdldEZpbGUobmFtZSwgY3JlYXRlX2lmX25vdF9mb3VuZCwgYWJvcnRhYmxlKGZ1bmN0aW9uIChmaWxlKSB7DQoJCSAgICAgICAgICAgICAgICAgICAgZmlsZS5jcmVhdGVXcml0ZXIoYWJvcnRhYmxlKGZ1bmN0aW9uICh3cml0ZXIpIHsNCgkJICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLm9ud3JpdGVlbmQgPSBmdW5jdGlvbiAoZXZlbnQpIHsNCgkJICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldF92aWV3LmxvY2F0aW9uLmhyZWYgPSBmaWxlLnRvVVJMKCk7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc2F2ZXIucmVhZHlTdGF0ZSA9IGZpbGVzYXZlci5ET05FOw0KCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2goZmlsZXNhdmVyLCAid3JpdGVlbmQiLCBldmVudCk7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXZva2UoZmlsZSk7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgIH07DQoJCSAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci5vbmVycm9yID0gZnVuY3Rpb24gKCkgew0KCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gd3JpdGVyLmVycm9yOw0KCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgIT09IGVycm9yLkFCT1JUX0VSUikgew0KCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZzX2Vycm9yKCk7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQoJCSAgICAgICAgICAgICAgICAgICAgICAgIH07DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICJ3cml0ZXN0YXJ0IHByb2dyZXNzIHdyaXRlIGFib3J0Ii5zcGxpdCgiICIpLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXJbIm9uIiArIGV2ZW50XSA9IGZpbGVzYXZlclsib24iICsgZXZlbnRdOw0KCQkgICAgICAgICAgICAgICAgICAgICAgICB9KTsNCgkJICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKGJsb2IpOw0KCQkgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc2F2ZXIuYWJvcnQgPSBmdW5jdGlvbiAoKSB7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIuYWJvcnQoKTsNCgkJICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLkRPTkU7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgIH07DQoJCSAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLldSSVRJTkc7DQoJCSAgICAgICAgICAgICAgICAgICAgfSksIGZzX2Vycm9yKTsNCgkJICAgICAgICAgICAgICAgIH0pLCBmc19lcnJvcik7DQoJCSAgICAgICAgICAgIH07DQoJCSAgICAgICAgICAgIGRpci5nZXRGaWxlKG5hbWUsIHsgY3JlYXRlOiBmYWxzZSB9LCBhYm9ydGFibGUoZnVuY3Rpb24gKGZpbGUpIHsNCgkJICAgICAgICAgICAgICAgIC8vIGRlbGV0ZSBmaWxlIGlmIGl0IGFscmVhZHkgZXhpc3RzDQoJCSAgICAgICAgICAgICAgICBmaWxlLnJlbW92ZSgpOw0KCQkgICAgICAgICAgICAgICAgc2F2ZSgpOw0KCQkgICAgICAgICAgICB9KSwgYWJvcnRhYmxlKGZ1bmN0aW9uIChleCkgew0KCQkgICAgICAgICAgICAgICAgaWYgKGV4LmNvZGUgPT09IGV4Lk5PVF9GT1VORF9FUlIpIHsNCgkJICAgICAgICAgICAgICAgICAgICBzYXZlKCk7DQoJCSAgICAgICAgICAgICAgICB9IGVsc2Ugew0KCQkgICAgICAgICAgICAgICAgICAgIGZzX2Vycm9yKCk7DQoJCSAgICAgICAgICAgICAgICB9DQoJCSAgICAgICAgICAgIH0pKTsNCgkJICAgICAgICB9KSwgZnNfZXJyb3IpOw0KCQkgICAgfSksIGZzX2Vycm9yKTsNCgkJfQ0KCQksIEZTX3Byb3RvID0gRmlsZVNhdmVyLnByb3RvdHlwZQ0KCQksIHNhdmVBcyA9IGZ1bmN0aW9uIChibG9iLCBuYW1lLCBub19hdXRvX2JvbSkgew0KCQkgICAgcmV0dXJuIG5ldyBGaWxlU2F2ZXIoYmxvYiwgbmFtZSwgbm9fYXV0b19ib20pOw0KCQl9DQogICAgOw0KICAgIC8vIElFIDEwKyAobmF0aXZlIHNhdmVBcykNCiAgICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gInVuZGVmaW5lZCIgJiYgbmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IpIHsNCiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChibG9iLCBuYW1lLCBub19hdXRvX2JvbSkgew0KICAgICAgICAgICAgaWYgKCFub19hdXRvX2JvbSkgew0KICAgICAgICAgICAgICAgIGJsb2IgPSBhdXRvX2JvbShibG9iKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHJldHVybiBuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYihibG9iLCBuYW1lIHx8ICJkb3dubG9hZCIpOw0KICAgICAgICB9Ow0KICAgIH0NCg0KICAgIEZTX3Byb3RvLmFib3J0ID0gZnVuY3Rpb24gKCkgew0KICAgICAgICB2YXIgZmlsZXNhdmVyID0gdGhpczsNCiAgICAgICAgZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuRE9ORTsNCiAgICAgICAgZGlzcGF0Y2goZmlsZXNhdmVyLCAiYWJvcnQiKTsNCiAgICB9Ow0KICAgIEZTX3Byb3RvLnJlYWR5U3RhdGUgPSBGU19wcm90by5JTklUID0gMDsNCiAgICBGU19wcm90by5XUklUSU5HID0gMTsNCiAgICBGU19wcm90by5ET05FID0gMjsNCg0KICAgIEZTX3Byb3RvLmVycm9yID0NCglGU19wcm90by5vbndyaXRlc3RhcnQgPQ0KCUZTX3Byb3RvLm9ucHJvZ3Jlc3MgPQ0KCUZTX3Byb3RvLm9ud3JpdGUgPQ0KCUZTX3Byb3RvLm9uYWJvcnQgPQ0KCUZTX3Byb3RvLm9uZXJyb3IgPQ0KCUZTX3Byb3RvLm9ud3JpdGVlbmQgPQ0KCQludWxsOw0KDQogICAgcmV0dXJuIHNhdmVBczsNCn0oDQoJICAgdHlwZW9mIHNlbGYgIT09ICJ1bmRlZmluZWQiICYmIHNlbGYNCgl8fCB0eXBlb2Ygd2luZG93ICE9PSAidW5kZWZpbmVkIiAmJiB3aW5kb3cNCgl8fCB0aGlzLmNvbnRlbnQNCikpOw0KLy8gYHNlbGZgIGlzIHVuZGVmaW5lZCBpbiBGaXJlZm94IGZvciBBbmRyb2lkIGNvbnRlbnQgc2NyaXB0IGNvbnRleHQNCi8vIHdoaWxlIGB0aGlzYCBpcyBuc0lDb250ZW50RnJhbWVNZXNzYWdlTWFuYWdlcg0KLy8gd2l0aCBhbiBhdHRyaWJ1dGUgYGNvbnRlbnRgIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIHdpbmRvdw0KDQppZiAodHlwZW9mIG1vZHVsZSAhPT0gInVuZGVmaW5lZCIgJiYgbW9kdWxlLmV4cG9ydHMpIHsNCiAgICBtb2R1bGUuZXhwb3J0cy5zYXZlQXMgPSBzYXZlQXM7DQp9IGVsc2UgaWYgKCh0eXBlb2YgZGVmaW5lICE9PSAidW5kZWZpbmVkIiAmJiBkZWZpbmUgIT09IG51bGwpICYmIChkZWZpbmUuYW1kICE9IG51bGwpKSB7DQogICAgZGVmaW5lKFtdLCBmdW5jdGlvbiAoKSB7DQogICAgICAgIHJldHVybiBzYXZlQXM7DQogICAgfSk7DQp9DQoNCiAgICAgICAgdmFyIHZlcnNpb24gPSAnMC43LjUnOw0KICAgICAgICB2YXIgdXJsdmFycyA9IHt9Ow0KICAgICAgICB2YXIgYW10c3RhY2s7DQogICAgICAgIHZhciB3c3N0YWNrID0gbnVsbDsNCiAgICAgICAgdmFyIEFsbFdzbWFuID0gIkFNVF84MDIxeENyZWRlbnRpYWxDb250ZXh0LEFNVF84MDIxWFByb2ZpbGUsQU1UX0FjdGl2ZUZpbHRlclN0YXRpc3RpY3MsQU1UX0FnZW50UHJlc2VuY2VDYXBhYmlsaXRpZXMsQU1UX0FnZW50UHJlc2VuY2VJbnRlcmZhY2VQb2xpY3ksQU1UX0FnZW50UHJlc2VuY2VTZXJ2aWNlLEFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2csQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ0FjdGlvbixBTVRfQWxhcm1DbG9ja1NlcnZpY2UsSVBTX0FsYXJtQ2xvY2tPY2N1cnJlbmNlLEFNVF9Bc3NldFRhYmxlLEFNVF9Bc3NldFRhYmxlU2VydmljZSxBTVRfQXVkaXRMb2csQU1UX0F1ZGl0UG9saWN5UnVsZSxBTVRfQXV0aG9yaXphdGlvblNlcnZpY2UsQU1UX0Jvb3RDYXBhYmlsaXRpZXMsQU1UX0Jvb3RTZXR0aW5nRGF0YSxBTVRfQ29tcGxleEZpbHRlckVudHJ5QmFzZSxBTVRfQ1JMLEFNVF9DcnlwdG9ncmFwaGljQ2FwYWJpbGl0aWVzLEFNVF9FQUNDcmVkZW50aWFsQ29udGV4dCxBTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZSxBTVRfRW52aXJvbm1lbnREZXRlY3Rpb25JbnRlcmZhY2VQb2xpY3ksQU1UX0Vudmlyb25tZW50RGV0ZWN0aW9uU2V0dGluZ0RhdGEsQU1UX0V0aGVybmV0UG9ydFNldHRpbmdzLEFNVF9FdmVudExvZ0VudHJ5LEFNVF9FdmVudE1hbmFnZXJTZXJ2aWNlLEFNVF9FdmVudFN1YnNjcmliZXIsQU1UX0ZpbHRlckVudHJ5QmFzZSxBTVRfRmlsdGVySW5TeXN0ZW1EZWZlbnNlUG9saWN5LEFNVF9HZW5lcmFsU2V0dGluZ3MsQU1UX0dlbmVyYWxTeXN0ZW1EZWZlbnNlQ2FwYWJpbGl0aWVzLEFNVF9IZHI4MDIxRmlsdGVyLEFNVF9IZXVyaXN0aWNQYWNrZXRGaWx0ZXJJbnRlcmZhY2VQb2xpY3ksQU1UX0hldXJpc3RpY1BhY2tldEZpbHRlclNldHRpbmdzLEFNVF9IZXVyaXN0aWNQYWNrZXRGaWx0ZXJTdGF0aXN0aWNzLEFNVF9JbnRlcmZhY2VQb2xpY3ksQU1UX0lQSGVhZGVyc0ZpbHRlcixBTVRfS2VyYmVyb3NTZXR0aW5nRGF0YSxBTVRfTWFuYWdlbWVudFByZXNlbmNlUmVtb3RlU0FQLEFNVF9NZXNzYWdlTG9nLEFNVF9NUFNVc2VybmFtZVBhc3N3b3JkLEFNVF9OZXR3b3JrRmlsdGVyLEFNVF9OZXR3b3JrUG9ydERlZmF1bHRTeXN0ZW1EZWZlbnNlUG9saWN5LEFNVF9OZXR3b3JrUG9ydFN5c3RlbURlZmVuc2VDYXBhYmlsaXRpZXMsQU1UX05ldHdvcmtQb3J0U3lzdGVtRGVmZW5zZVBvbGljeSxBTVRfUENJRGV2aWNlLEFNVF9QRVRDYXBhYmlsaXRpZXMsQU1UX1BFVEZpbHRlckZvclRhcmdldCxBTVRfUEVURmlsdGVyU2V0dGluZyxBTVRfUHJvdmlzaW9uaW5nQ2VydGlmaWNhdGVIYXNoLEFNVF9QdWJsaWNLZXlDZXJ0aWZpY2F0ZSxBTVRfUHVibGljS2V5TWFuYWdlbWVudENhcGFiaWxpdGllcyxBTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2UsQU1UX1B1YmxpY1ByaXZhdGVLZXlQYWlyLEFNVF9SZWRpcmVjdGlvblNlcnZpY2UsQU1UX1JlbW90ZUFjY2Vzc0NhcGFiaWxpdGllcyxBTVRfUmVtb3RlQWNjZXNzQ3JlZGVudGlhbENvbnRleHQsQU1UX1JlbW90ZUFjY2Vzc1BvbGljeUFwcGxpZXNUb01QUyxBTVRfUmVtb3RlQWNjZXNzUG9saWN5UnVsZSxBTVRfUmVtb3RlQWNjZXNzU2VydmljZSxBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSxBTVRfU05NUEV2ZW50U3Vic2NyaWJlcixBTVRfU3RhdGVUcmFuc2l0aW9uQ29uZGl0aW9uLEFNVF9TeXN0ZW1EZWZlbnNlUG9saWN5LEFNVF9TeXN0ZW1EZWZlbnNlUG9saWN5SW5TZXJ2aWNlLEFNVF9TeXN0ZW1EZWZlbnNlU2VydmljZSxBTVRfU3lzdGVtUG93ZXJTY2hlbWUsQU1UX1RoaXJkUGFydHlEYXRhU3RvcmFnZUFkbWluaXN0cmF0aW9uU2VydmljZSxBTVRfVGhpcmRQYXJ0eURhdGFTdG9yYWdlU2VydmljZSxBTVRfVGltZVN5bmNocm9uaXphdGlvblNlcnZpY2UsQU1UX1RMU0NyZWRlbnRpYWxDb250ZXh0LEFNVF9UTFNQcm90b2NvbEVuZHBvaW50LEFNVF9UTFNQcm90b2NvbEVuZHBvaW50Q29sbGVjdGlvbixBTVRfVExTU2V0dGluZ0RhdGEsQU1UX1RyYXBUYXJnZXRGb3JTZXJ2aWNlLEFNVF9Vc2VySW5pdGlhdGVkQ29ubmVjdGlvblNlcnZpY2UsQU1UX1dlYlVJU2VydmljZSxBTVRfV2lGaVBvcnRDb25maWd1cmF0aW9uU2VydmljZSxDSU1fQWJzdHJhY3RJbmRpY2F0aW9uU3Vic2NyaXB0aW9uLENJTV9BY2NvdW50LENJTV9BY2NvdW50TWFuYWdlbWVudENhcGFiaWxpdGllcyxDSU1fQWNjb3VudE1hbmFnZW1lbnRTZXJ2aWNlLENJTV9BY2NvdW50T25TeXN0ZW0sQ0lNX0FkbWluRG9tYWluLENJTV9BbGVydEluZGljYXRpb24sQ0lNX0Fzc2lnbmVkSWRlbnRpdHksQ0lNX0Fzc29jaWF0ZWRQb3dlck1hbmFnZW1lbnRTZXJ2aWNlLENJTV9BdXRoZW50aWNhdGlvblNlcnZpY2UsQ0lNX0F1dGhvcml6YXRpb25TZXJ2aWNlLENJTV9CSU9TRWxlbWVudCxDSU1fQklPU0ZlYXR1cmUsQ0lNX0JJT1NGZWF0dXJlQklPU0VsZW1lbnRzLENJTV9Cb290Q29uZmlnU2V0dGluZyxDSU1fQm9vdFNlcnZpY2UsQ0lNX0Jvb3RTZXR0aW5nRGF0YSxDSU1fQm9vdFNvdXJjZVNldHRpbmcsQ0lNX0NhcGFiaWxpdGllcyxDSU1fQ2FyZCxDSU1fQ2hhc3NpcyxDSU1fQ2hpcCxDSU1fQ29sbGVjdGlvbixDSU1fQ29tcG9uZW50LENJTV9Db21wdXRlclN5c3RlbSxDSU1fQ29tcHV0ZXJTeXN0ZW1QYWNrYWdlLENJTV9Db25jcmV0ZUNvbXBvbmVudCxDSU1fQ29uY3JldGVEZXBlbmRlbmN5LENJTV9Db250cm9sbGVyLENJTV9Db29saW5nRGV2aWNlLENJTV9DcmVkZW50aWFsLENJTV9DcmVkZW50aWFsQ29udGV4dCxDSU1fQ3JlZGVudGlhbE1hbmFnZW1lbnRTZXJ2aWNlLENJTV9EZXBlbmRlbmN5LENJTV9EZXZpY2VTQVBJbXBsZW1lbnRhdGlvbixDSU1fRWxlbWVudENhcGFiaWxpdGllcyxDSU1fRWxlbWVudENvbmZvcm1zVG9Qcm9maWxlLENJTV9FbGVtZW50TG9jYXRpb24sQ0lNX0VsZW1lbnRTZXR0aW5nRGF0YSxDSU1fRWxlbWVudFNvZnR3YXJlSWRlbnRpdHksQ0lNX0VsZW1lbnRTdGF0aXN0aWNhbERhdGEsQ0lNX0VuYWJsZWRMb2dpY2FsRWxlbWVudCxDSU1fRW5hYmxlZExvZ2ljYWxFbGVtZW50Q2FwYWJpbGl0aWVzLENJTV9FdGhlcm5ldFBvcnQsQ0lNX0ZhbixDSU1fRmlsdGVyQ29sbGVjdGlvbixDSU1fRmlsdGVyQ29sbGVjdGlvblN1YnNjcmlwdGlvbixDSU1fSG9zdGVkQWNjZXNzUG9pbnQsQ0lNX0hvc3RlZERlcGVuZGVuY3ksQ0lNX0hvc3RlZFNlcnZpY2UsQ0lNX0lkZW50aXR5LENJTV9JRUVFODAyMXhDYXBhYmlsaXRpZXMsQ0lNX0lFRUU4MDIxeFNldHRpbmdzLENJTV9JbmRpY2F0aW9uLENJTV9JbmRpY2F0aW9uU2VydmljZSxDSU1fSW5zdGFsbGVkU29mdHdhcmVJZGVudGl0eSxDSU1fS1ZNUmVkaXJlY3Rpb25TQVAsQ0lNX0xBTkVuZHBvaW50LENJTV9MaXN0ZW5lckRlc3RpbmF0aW9uLENJTV9MaXN0ZW5lckRlc3RpbmF0aW9uV1NNYW5hZ2VtZW50LENJTV9Mb2NhdGlvbixDSU1fTG9nLENJTV9Mb2dFbnRyeSxDSU1fTG9naWNhbERldmljZSxDSU1fTG9naWNhbEVsZW1lbnQsQ0lNX0xvZ2ljYWxQb3J0LENJTV9Mb2dpY2FsUG9ydENhcGFiaWxpdGllcyxDSU1fTG9nTWFuYWdlc1JlY29yZCxDSU1fTWFuYWdlZENyZWRlbnRpYWwsQ0lNX01hbmFnZWRFbGVtZW50LENJTV9NYW5hZ2VkU3lzdGVtRWxlbWVudCxDSU1fTWVkaWFBY2Nlc3NEZXZpY2UsQ0lNX01lbWJlck9mQ29sbGVjdGlvbixDSU1fTWVtb3J5LENJTV9NZXNzYWdlTG9nLENJTV9OZXR3b3JrUG9ydCxDSU1fTmV0d29ya1BvcnRDYXBhYmlsaXRpZXMsQ0lNX05ldHdvcmtQb3J0Q29uZmlndXJhdGlvblNlcnZpY2UsQ0lNX09yZGVyZWRDb21wb25lbnQsQ0lNX093bmluZ0NvbGxlY3Rpb25FbGVtZW50LENJTV9Pd25pbmdKb2JFbGVtZW50LENJTV9QQ0lDb250cm9sbGVyLENJTV9QaHlzaWNhbENvbXBvbmVudCxDSU1fUGh5c2ljYWxFbGVtZW50LENJTV9QaHlzaWNhbEVsZW1lbnRMb2NhdGlvbixDSU1fUGh5c2ljYWxGcmFtZSxDSU1fUGh5c2ljYWxNZW1vcnksQ0lNX1BoeXNpY2FsUGFja2FnZSxDSU1fUG9saWN5LENJTV9Qb2xpY3lBY3Rpb24sQ0lNX1BvbGljeUNvbmRpdGlvbixDSU1fUG9saWN5SW5TeXN0ZW0sQ0lNX1BvbGljeVJ1bGUsQ0lNX1BvbGljeVJ1bGVJblN5c3RlbSxDSU1fUG9saWN5U2V0LENJTV9Qb2xpY3lTZXRBcHBsaWVzVG9FbGVtZW50LENJTV9Qb2xpY3lTZXRJblN5c3RlbSxDSU1fUG93ZXJNYW5hZ2VtZW50Q2FwYWJpbGl0aWVzLENJTV9Qb3dlck1hbmFnZW1lbnRTZXJ2aWNlLENJTV9Qb3dlclN1cHBseSxDSU1fUHJpdmlsZWdlLENJTV9Qcml2aWxlZ2VNYW5hZ2VtZW50Q2FwYWJpbGl0aWVzLENJTV9Qcml2aWxlZ2VNYW5hZ2VtZW50U2VydmljZSxDSU1fUHJvY2Vzc0luZGljYXRpb24sQ0lNX1Byb2Nlc3NvcixDSU1fUHJvdG9jb2xFbmRwb2ludCxDSU1fUHJvdmlkZXNTZXJ2aWNlVG9FbGVtZW50LENJTV9SZWFsaXplcyxDSU1fUmVjb3JkRm9yTG9nLENJTV9SZWNvcmRMb2csQ0lNX1JlZGlyZWN0aW9uU2VydmljZSxDSU1fUmVmZXJlbmNlZFByb2ZpbGUsQ0lNX1JlZ2lzdGVyZWRQcm9maWxlLENJTV9SZW1vdGVBY2Nlc3NBdmFpbGFibGVUb0VsZW1lbnQsQ0lNX1JlbW90ZUlkZW50aXR5LENJTV9SZW1vdGVQb3J0LENJTV9SZW1vdGVTZXJ2aWNlQWNjZXNzUG9pbnQsQ0lNX1JvbGUsQ0lNX1JvbGVCYXNlZEF1dGhvcml6YXRpb25TZXJ2aWNlLENJTV9Sb2xlQmFzZWRNYW5hZ2VtZW50Q2FwYWJpbGl0aWVzLENJTV9Sb2xlTGltaXRlZFRvVGFyZ2V0LENJTV9TQVBBdmFpbGFibGVGb3JFbGVtZW50LENJTV9TZWN1cml0eVNlcnZpY2UsQ0lNX1NlbnNvcixDSU1fU2VydmljZSxDSU1fU2VydmljZUFjY2Vzc0J5U0FQLENJTV9TZXJ2aWNlQWNjZXNzUG9pbnQsQ0lNX1NlcnZpY2VBZmZlY3RzRWxlbWVudCxDSU1fU2VydmljZUF2YWlsYWJsZVRvRWxlbWVudCxDSU1fU2VydmljZVNBUERlcGVuZGVuY3ksQ0lNX1NlcnZpY2VTZXJ2aWNlRGVwZW5kZW5jeSxDSU1fU2V0dGluZ0RhdGEsQ0lNX1NoYXJlZENyZWRlbnRpYWwsQ0lNX1NvZnR3YXJlRWxlbWVudCxDSU1fU29mdHdhcmVGZWF0dXJlLENJTV9Tb2Z0d2FyZUZlYXR1cmVTb2Z0d2FyZUVsZW1lbnRzLENJTV9Tb2Z0d2FyZUlkZW50aXR5LENJTV9TdGF0aXN0aWNhbERhdGEsQ0lNX1N0b3JhZ2VFeHRlbnQsQ0lNX1N5c3RlbSxDSU1fU3lzdGVtQklPUyxDSU1fU3lzdGVtQ29tcG9uZW50LENJTV9TeXN0ZW1EZXZpY2UsQ0lNX1N5c3RlbVBhY2thZ2luZyxDSU1fVXNlT2ZMb2csQ0lNX1dhdGNoZG9nLENJTV9XaUZpRW5kcG9pbnQsQ0lNX1dpRmlFbmRwb2ludENhcGFiaWxpdGllcyxDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MsQ0lNX1dpRmlQb3J0LENJTV9XaUZpUG9ydENhcGFiaWxpdGllcyxJUFNfQWRtaW5Qcm92aXNpb25pbmdSZWNvcmQsSVBTX0NsaWVudFByb3Zpc2lvbmluZ1JlY29yZCxJUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlLElQU19Ib3N0SVBTZXR0aW5ncyxJUFNfSFRUUFByb3h5U2VydmljZSxJUFNfSFRUUFByb3h5QWNjZXNzUG9pbnQsSVBTX0lkZXJTZXNzaW9uVXNpbmdQb3J0LElQU19JUHY2UG9ydFNldHRpbmdzLElQU19LVk1SZWRpcmVjdGlvblNldHRpbmdEYXRhLElQU19Ldm1TZXNzaW9uVXNpbmdQb3J0LElQU19NYW51YWxQcm92aXNpb25pbmdSZWNvcmQsSVBTX09wdEluU2VydmljZSxJUFNfUHJvdmlzaW9uaW5nQXVkaXRSZWNvcmQsSVBTX1Byb3Zpc2lvbmluZ1JlY29yZExvZyxJUFNfUmFzU2Vzc2lvblVzaW5nUG9ydCxJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UsSVBTX1NjcmVlblNldHRpbmdEYXRhLElQU19TZWNJT1NlcnZpY2UsSVBTX1Nlc3Npb25Vc2luZ1BvcnQsSVBTX1NvbFNlc3Npb25Vc2luZ1BvcnQsSVBTX1RMU1Byb3Zpc2lvbmluZ1JlY29yZCxJUFNfV2F0Y2hEb2dBY3Rpb24iLnNwbGl0KCcsJyk7DQogICAgICAgIHZhciBkaXNjb25uZWN0dXJsID0gbnVsbDsNCiAgICAgICAgdmFyIGN1cnJlbnRWaWV3ID0gMDsNCiAgICAgICAgdmFyIExvYWRpbmdIdG1sID0gIjxkaXYgc3R5bGU9dGV4dC1hbGlnbjpjZW50ZXI7cGFkZGluZy10b3A6MjBweD5Mb2FkaW5nLi4uPGRpdj4iOw0KICAgICAgICB2YXIgYW10dmVyc2lvbiA9IDA7DQogICAgICAgIHZhciBhbXR2ZXJzaW9ubWluID0gMDsNCiAgICAgICAgdmFyIGFtdEZpcnN0UHVsbCA9IDA7IC8vIEJpdG1hc2ssIFNldCB0aGlzIHdoZW4gdGhlIGZpcnN0IHB1bGwgcmVxdWVzdCBpcyBtYWRlIG9uIGEgZGV2aWNlOiAxID0gSGFyZHdhcmVJbmZvLCAyID0gV2lyZWxlc3NJbmZvLCA0ID0gU3lzdGVtRGVmZW5zZSwgOCA9IFN0b3JhZ2UsIDE2ID0gRXZlbnRMb2csIDMyID0gQXVkaXRMb2cNCg0KICAgICAgICB2YXIgYW10d2lyZWxlc3NpZiA9IC0xOyAvLyBTZXQgdG8gdGhlIGludGVyZmFjZSBpbmRleCBmb3IgdGhlIHdpcmVsZXNzIGludGVyZmFjZSwgLTEgaWYgbm8gd2lyZWxlc3MuDQogICAgICAgIHZhciB3ZWJjb21waWxlcmZlYXR1cmVzID0gWydBZ2VudFByZXNlbmNlJywnQWxhcm1zJywnQXVkaXRMb2cnLCdDZXJ0aWZpY2F0ZXMnLCdDb21wdXRlclNlbGVjdG9yVG9vbGJhcicsJ0Rlc2t0b3AtU2V0dGluZ3MnLCdFdmVudExvZycsJ0ZpbGVTYXZlcicsJ0hhcmR3YXJlSW5mbycsJ0xvb2stQ29tbWFuZGVyJywnTW9kZS1MTVMnLCdOZXR3b3JrU2V0dGluZ3MnLCdSZW1vdGVBY2Nlc3MnLCdTY3JpcHRpbmcnLCdTY3JpcHRpbmctRWRpdG9yJywnU3RvcmFnZScsJ1N5c3RlbURlZmVuc2UnLCdVU0JTZXR1cCcsJ1dpcmVsZXNzJ107DQogICAgICAgIHZhciBTdGF0dXNTdHJzID0gWydEaXNjb25uZWN0ZWQnLCAnQ29ubmVjdGluZy4uLicsICdTZXR1cC4uLicsICdDb25uZWN0ZWQnXTsNCg0KICAgICAgICB2YXIgc2NyaXB0c3RhdGU7DQoNCiAgICAgICAgdmFyIHNldHVwYmluOw0KICAgICAgICB2YXIgc2VsZWN0ZWRSZWNvcmQgPSAwOw0KICAgICAgICB2YXIgc2VsZWN0ZWRWYXJpYWJsZSA9IDA7DQoNCiAgICAgICAgdmFyIGFtdFBvd2VyUG9sbFRpbWVyID0gbnVsbDsNCg0KICAgICAgICB2YXIgbG1zID0gbnVsbDsNCiAgICAgICAgdmFyIHQsIHQyLCByc2VwYXNzID0gbnVsbDsgLy8gR2xvYmFsIHRlbXBvcmFyeSB2YXJpYWJsZQ0KDQogICAgICAgIGZ1bmN0aW9uIHN0YXJ0dXAoKSB7DQogICAgICAgICAgICAvLyBUaGlzIGlzIGEgYml0IGZyZWVreSwgYnV0IGFsbCBIVE1MIGlucHV0IGVsZW1lbnRzIGFyZSBqdXN0IGdvaW5nIHRvIGJlIGFjY2Vzc2libGUgZGlyZWN0bHkuDQogICAgICAgICAgICB2YXIgYWxsZWxlbWVudHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaW5wdXQnKTsNCiAgICAgICAgICAgIGZvciAodCA9IDA7IHQgPCBhbGxlbGVtZW50cy5sZW5ndGg7IHQrKykgeyBpZiAoYWxsZWxlbWVudHNbdF0uaWQpIHsgd2luZG93W2FsbGVsZW1lbnRzW3RdLmlkXSA9IGFsbGVsZW1lbnRzW3RdOyB9IH0NCg0KDQogICAgICAgICAgICB1cmx2YXJzID0gZ2V0VXJsVmFycygpOw0KDQoNCg0KICAgICAgICAgICAgLy8gU2V0dXAgTE1TDQogICAgICAgICAgICBsbXMgPSBDcmVhdGVMbXNDb250cm9sKCk7DQogICAgICAgICAgICBsbXMub25TdGF0ZUNoYW5nZWQgPSBsbXNDaGFuZ2VkU3RhdGU7DQogICAgICAgICAgICBsbXMub25EYXRhID0gbG1zT25EYXRhOw0KICAgICAgICAgICAgbG1zLlN0YXJ0KCk7DQogICAgICAgICAgICBRSCgnaWRfbG1zRGF0YScsIExvYWRpbmdIdG1sKTsNCiAgICAgICAgICAgIFFIKCdpZF9sbXNEYXRhJywgJycpOw0KICAgICAgICAgICAgUUgoJ2lkX2NvbXB1dGVybmFtZScsICdDb25maWd1cmF0aW9uIENvbnNvbGUgdicgKyB2ZXJzaW9uKTsNCiAgICAgICAgICAgIGdvKDEwMSk7DQogICAgICAgICAgICBsbXNSZWZyZXNoKCk7DQoNCg0KDQoNCiAgICAgICAgICAgIC8vIE1hc3RlciBkcmFnICYgZHJvcA0KICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ292ZXInLCBoYWx0RXZlbnQsIGZhbHNlKTsNCiAgICAgICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdsZWF2ZScsIGhhbHRFdmVudCwgZmFsc2UpOw0KICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignZHJvcCcsIGRvY3VtZW50RmlsZVNlbGVjdEhhbmRsZXIsIGZhbHNlKTsNCg0KDQogICAgICAgICAgICAvLyBTZXR1cCBUZXJtaW5hbCBkcmFnICYgZHJvcA0KICAgICAgICAgICAgUSgncDE2JykuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ292ZXInLCBoYWx0RXZlbnQsIGZhbHNlKTsNCiAgICAgICAgICAgIFEoJ3AxNicpLmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdsZWF2ZScsIGhhbHRFdmVudCwgZmFsc2UpOw0KICAgICAgICAgICAgUSgncDE2JykuYWRkRXZlbnRMaXN0ZW5lcignZHJvcCcsIGNlcnRfRmlsZVNlbGVjdEhhbmRsZXIsIGZhbHNlKTsNCg0KDQoNCg0KDQoNCg0KDQogICAgICAgICAgICB1c2JfZGlzcGxheVNldHVwQmluKCk7DQoNCiAgICAgICAgICAgIC8vIEFkZCBhbGwgcG9zc2libGUgdmFyaWFibGUgdHlwZXMgdG8gZGlhbG9nIDE2DQogICAgICAgICAgICB2YXIgb3B0aW9ucyA9ICcnOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBBbXRTZXR1cEJpblZhcklkcykgeyBmb3IgKHZhciBqIGluIEFtdFNldHVwQmluVmFySWRzW2ldKSB7IG9wdGlvbnMgKz0gJzxvcHRpb24gdmFsdWU9IicgKyBpICsgIi0iICsgaiArICciPicgKyBBbXRTZXR1cEJpblZhcklkc1tpXVtqXVsxXSB9IH0NCiAgICAgICAgICAgIFFIKCdkMTZ0eXBlJywgb3B0aW9ucyk7DQoNCiAgICAgICAgICAgIGRvY3VtZW50Lm9ua2V5dXAgPSBoYW5kbGVLZXlVcDsNCiAgICAgICAgICAgIGRvY3VtZW50Lm9ua2V5ZG93biA9IGhhbmRsZUtleURvd247DQogICAgICAgICAgICBkb2N1bWVudC5vbmtleXByZXNzID0gaGFuZGxlS2V5UHJlc3M7DQogICAgICAgICAgICB3aW5kb3cub25yZXNpemUgPSBjZW50ZXI7DQogICAgICAgICAgICBjZW50ZXIoKTsNCg0KDQoNCg0KICAgICAgICAgICAgc2NyaXB0TG9hZFN0YXJ0aW5nQmxvY2tzKCk7DQoNCg0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZG9jdW1lbnRGaWxlU2VsZWN0SGFuZGxlcihlKSB7DQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQogICAgICAgICAgICBpZiAoZS5kYXRhVHJhbnNmZXIgPT0gbnVsbCB8fCBlLmRhdGFUcmFuc2Zlci5maWxlcy5sZW5ndGggIT0gMSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIGYgPSBudWxsLCBmaWxlbmFtZSA9IGUuZGF0YVRyYW5zZmVyLmZpbGVzWzBdLm5hbWUudG9Mb3dlckNhc2UoKTsNCg0KICAgICAgICAgICAgaWYgKGN1cnJlbnRWaWV3ID09IDIxKSB7IFVwbG9hZFRvU3RvcmFnZShlLmRhdGFUcmFuc2Zlci5maWxlc1swXSwgZmlsZW5hbWUpOyByZXR1cm47IH0NCg0KICAgICAgICAgICAgaWYgKGN1cnJlbnRWaWV3ID09IDEwMiAmJiBmaWxlbmFtZS5lbmRzV2l0aCgnLmJpbicpKSB7IGYgPSB1c2Jfb25TZXR1cEJpblJlYWQ7IH0NCg0KICAgICAgICAgICAgaWYgKHdzc3RhY2sgIT0gbnVsbCAmJiAoZmlsZW5hbWUuZW5kc1dpdGgoJy5tZXNjcmlwdCcpIHx8IGZpbGVuYW1lLmVuZHNXaXRoKCcubWVibG9ja3MnKSkpIHsgZiA9IHNjcmlwdF9vblNjcmlwdFJlYWQ7IH0NCiAgICAgICAgICAgIGlmIChmICE9IG51bGwpIHsgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7IHJlYWRlci5vbmxvYWQgPSBmOyByZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKGUuZGF0YVRyYW5zZmVyLmZpbGVzWzBdKTsgfQ0KICAgICAgICB9DQoNCg0KDQoNCiAgICAgICAgLy8gQ2FsbGVkIHdoZW4gdGhlIExNUyBjb250cm9sIGNoYW5uZWwgY2hhbmdlcyBzdGF0ZQ0KICAgICAgICBmdW5jdGlvbiBsbXNDaGFuZ2VkU3RhdGUoc2VuZGVyLCBzdGF0ZSkNCiAgICAgICAgew0KICAgICAgICAgICAgLy9jb25zb2xlLmxvZygiTE1TIENvbnRyb2wgQ2hhbm5lbCBTdGF0ZTogIiArIHN0YXRlKTsNCiAgICAgICAgICAgIGlmIChzdGF0ZSA9PSAwKSB7IA0KICAgICAgICAgICAgICAgIHNldERpYWxvZ01vZGUoKTsNCiAgICAgICAgICAgICAgICBRVignaWRfbG1zVG9vbEJhckNvbnRlbnQnLCBmYWxzZSk7DQogICAgICAgICAgICAgICAgUUgoJ2lkX2xtc0RhdGEnLCAnPGRpdiBzdHlsZT10ZXh0LWFsaWduOmNlbnRlcjtwYWRkaW5nLXRvcDoyMHB4Pk1pY3JvTE1TIGRpc2Nvbm5lY3RlZC48ZGl2PicpOw0KICAgICAgICAgICAgICAgIFFIKCdpZF9sbXNEYXRhMicsICcnKTsNCiAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT0gMikgeyBRVignaWRfbG1zVG9vbEJhckNvbnRlbnQnLCB0cnVlKTsgbG1zUmVmcmVzaCgpOyB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBsbXNMb2dpbigpIHsgd2luZG93LmxvY2F0aW9uLmhyZWYgPSAnL2F1dGhpbmRleC5odG1sJzsgfQ0KDQogICAgICAgIHZhciBsbXNQcm92aXNpb25pbmdTdGF0ZXMgPSBbJ1ByZS1Qcm92aXNpb25pbmcnLCAnSW4tUHJvdmlzaW9uaW5nJywgJ1Bvc3QtUHJvdmlzaW9uaW5nJ107DQogICAgICAgIHZhciBsbXNQcm92aXNpb25pbmdNb2RlcyA9IFsnTm9uZScsICdFbnRlcnByaXNlIE1vZGUnLCAnU21hbGwgQnVpc25lc3MgTW9kZScsICdSZW1vdGUgQXNzaXN0YW5jZSBNb2RlJ107DQogICAgICAgIHZhciBsbXNNZUluZm8gPSBudWxsOw0KICAgICAgICB2YXIgbG1zVGVtcCA9IG51bGw7DQogICAgICAgIHZhciBsbXNOb3RpZmljYXRpb25zID0gbnVsbDsNCg0KICAgICAgICAvLyBDYWxsZWQgd2hlbiBkYXRhIGlzIHJlY2VpdmVkIG9uIHRoZSBMTVMgY29udHJvbCBjaGFubmVsDQogICAgICAgIGZ1bmN0aW9uIGxtc09uRGF0YShzZW5kZXIsIGRhdGEpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBjbWRpZCA9IFJlYWRTaG9ydFgoZGF0YSwgMCk7DQogICAgICAgICAgICAvL2NvbnNvbGUubG9nKCJMTVMgQ29udHJvbCBDaGFubmVsIERhdGE6ICIgKyBkYXRhICsgIiwgY21kaWQ6IiArIGNtZGlkKTsNCg0KICAgICAgICAgICAgc3dpdGNoICgrY21kaWQpIHsNCiAgICAgICAgICAgICAgICBjYXNlIDE6IHsgLy8gTUUgSW5mb3JtYXRpb24NCiAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhkYXRhLnN1YnN0cmluZygyKSk7DQogICAgICAgICAgICAgICAgICAgIHZhciBtZWluZm8gPSBKU09OLnBhcnNlKGRhdGEuc3Vic3RyaW5nKDIpKTsNCiAgICAgICAgICAgICAgICAgICAgUVYoJ2lkX2xtc0xvZ2luQnV0dG9uJywgbWVpbmZvWydMb2dpbk1vZGUnXSA9PSAxKTsNCg0KICAgICAgICAgICAgICAgICAgICAvLyBJZiBJbnRlbCBBTVQgaXMgaW4tYmV0d2VlbiBzdGF0ZXMsIHJlbG9hZCBkYXRhIGluIGEgZmV3IHNlY29uZHMuDQogICAgICAgICAgICAgICAgICAgIGlmICgobWVpbmZvWydUcnVzdGVkSGFzaGVzJ10gIT0gbnVsbCkgJiYgKG1laW5mb1snUHJvdmlzaW9uaW5nTW9kZSddID09IC04NTg5OTM0NjApKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBRVignaWRfbG1zQ29uZmlndXJlQnV0dG9uJywgZmFsc2UpOw0KICAgICAgICAgICAgICAgICAgICAgICAgUVYoJ2lkX2xtc0FjdGl2YXRlQnV0dG9uJywgZmFsc2UpOw0KICAgICAgICAgICAgICAgICAgICAgICAgUVYoJ2lkX2xtc0RlYWN0aXZhdGVCdXR0b24nLCBmYWxzZSk7DQogICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGxtc1JlZnJlc2gsIDEwMDApOw0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOw0KICAgICAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAgICAgbG1zTWVJbmZvID0gbWVpbmZvOw0KICAgICAgICAgICAgICAgICAgICBpZiAobWVpbmZvWydQcm92aXNpb25pbmdTdGF0ZSddID09IG51bGwpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIFFIKCdpZF9sbXNEYXRhJywgJzxkaXYgc3R5bGU9dGV4dC1hbGlnbjpjZW50ZXI7cGFkZGluZy10b3A6MjBweD5JbnRlbCZyZWc7IEFNVCBub3QgZm91bmQ8ZGl2PicpOw0KICAgICAgICAgICAgICAgICAgICAgICAgUUgoJ2lkX2xtc0RhdGEyJywgJycpOw0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgbWVpbmZvWydGbGFncyddID0gK21laW5mb1snRmxhZ3MnXTsNCg0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHggPSAnPGgyPkN1cnJlbnQgU3RhdHVzPC9oMj4nOw0KICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZVN0YXJ0KCk7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAobWVpbmZvWydQcm92aXNpb25pbmdTdGF0ZSddICE9IDIpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkFjdGl2YXRpb24gc3RhdGUiLCBsbXNQcm92aXNpb25pbmdTdGF0ZXNbbWVpbmZvWydQcm92aXNpb25pbmdTdGF0ZSddXSk7DQogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtZWluZm9bJ0ZsYWdzJ10gJiAyKSB7IHggKz0gVGFibGVFbnRyeSgnQWN0aXZhdGlvbiBzdGF0ZScsICdBY3RpdmF0ZWQgaW4gQ2xpZW50IENvbnRyb2wgTW9kZScpOyB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobWVpbmZvWydGbGFncyddICYgNCkgeyB4ICs9IFRhYmxlRW50cnkoJ0FjdGl2YXRpb24gc3RhdGUnLCAnQWN0aXZhdGVkIGluIEFkbWluIENvbnRyb2wgTW9kZScpOyB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7IHggKz0gVGFibGVFbnRyeSgnQWN0aXZhdGlvbiBzdGF0ZScsICdBY3RpdmF0ZWQsICcgKyBsbXNQcm92aXNpb25pbmdNb2Rlc1ttZWluZm9bJ1Byb3Zpc2lvbmluZ01vZGUnXV0pOyB9DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoJ0ludGVsJnJlZzsgQU1UIHZlcnNpb24nLCBhZGRMaW5rKG1laW5mb1snVmVyc2lvbnMnXVsnQU1UJ10sICdsbXNTaG93VmVyc2lvbnNEbGcoKScpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtZWluZm9bJ01laVZlcnNpb24nXSAhPSBudWxsKSB7IHggKz0gVGFibGVFbnRyeSgnSW50ZWwmcmVnOyBNRUkgZHJpdmVyIHZlcnNpb24nLCBtZWluZm9bJ01laVZlcnNpb24nXSk7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbmQoKTsNCg0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1laW5mb1snUHJvdmlzaW9uaW5nU3RhdGUnXSAhPSAyKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSAnPGgyPkFjdGl2YXRpb24gSW5mb3JtYXRpb248L2gyPic7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZVN0YXJ0KCk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1laW5mb1snRG5zU3VmZml4J10pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCdUcnVzdGVkIEROUyBzdWZmaXgnLCBtZWluZm9bJ0Ruc1N1ZmZpeCddKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoJ1RydXN0ZWQgRE5TIHN1ZmZpeCcsICc8aT5Ob3QgU2V0PC9pPicpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWVpbmZvWydUcnVzdGVkSGFzaGVzJ10gIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWVpbmZvWydUcnVzdGVkSGFzaGVzJ10ubGVuZ3RoID09IDEpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgnVHJ1c3RlZCBoYXNoZXMnLCBhZGRMaW5rKG1laW5mb1snVHJ1c3RlZEhhc2hlcyddLmxlbmd0aCArICcgaGFzaCcsICdsbXNTaG93VHJ1c3RlZEhhc2hlc0RsZygpJykpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCdUcnVzdGVkIGhhc2hlcycsIGFkZExpbmsobWVpbmZvWydUcnVzdGVkSGFzaGVzJ10ubGVuZ3RoICsgJyBoYXNoZXMnLCAnbG1zU2hvd1RydXN0ZWRIYXNoZXNEbGcoKScpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW5kKCk7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAgICAgICAgIFFIKCdpZF9sbXNEYXRhJywgeCk7DQogICAgICAgICAgICAgICAgICAgICAgICBRVignaWRfbG1zRGF0YTInLCB0cnVlKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGxtc05vdGlmaWNhdGlvbnMgPSBtZWluZm9bJ05vdGlmaWNhdGlvbnMnXS5yZXZlcnNlKCk7DQogICAgICAgICAgICAgICAgICAgICAgICBsbXNSZWZyZXNoTm90aWZpY2F0aW9ucygpOw0KICAgICAgICAgICAgICAgICAgICAgICAgUVYoJ2lkX2xtc0NvbmZpZ3VyZUJ1dHRvbicsIChtZWluZm9bJ1Byb3Zpc2lvbmluZ1N0YXRlJ10gPT0gMikpOyAvLyBPbmx5IGRpc3BsYXkgdGhlICJMb2dpbi4uLiIgYnV0dG9uIGlmIEludGVsIEFNVCBpcyBpbiBwb3N0LXByb3Zpc2lvbmluZyBzdGF0ZS4NCiAgICAgICAgICAgICAgICAgICAgICAgIFFWKCdpZF9sbXNBY3RpdmF0ZUJ1dHRvbicsIChtZWluZm9bJ1Byb3Zpc2lvbmluZ1N0YXRlJ10gPT0gMCkgJiYgKG1laW5mb1snTG9naW5Nb2RlJ10gPj0gMikpOyAvLyBPbmx5IGRpc3BsYXkgdGhlICJBY3RpdmF0ZS4uLiIgYnV0dG9uIGlmIEludGVsIEFNVCBpcyBpbiBwcmUtcHJvdmlzaW9uaW5nIHN0YXRlIGFuZCB3ZSBhcmUgYWRybWluaXN0cmF0b3IuDQogICAgICAgICAgICAgICAgICAgICAgICBRVignaWRfbG1zRGVhY3RpdmF0ZUJ1dHRvbicsIChtZWluZm9bJ1Byb3Zpc2lvbmluZ1N0YXRlJ10gPT0gMikgJiYgKG1laW5mb1snRmxhZ3MnXSAmIDIpICYmIChtZWluZm9bJ0xvZ2luTW9kZSddID49IDIpKTsgLy8gT25seSBkaXNwbGF5IHRoZSAiRGVhY3RpdmF0ZS4uLiIgYnV0dG9uIGlmIEludGVsIEFNVCBpcyBpbiBwb3J0LXByb3Zpc2lvbmluZyBzdGF0ZSAmIGluIGNsaWVudCBjb250cm9sIG1vZGUgJiB3ZSBhcmUgYWRybWluaXN0cmF0b3IuDQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGNhc2UgMjogeyAvLyBJbnRlbCBNRSBVbi1Qcm92aXNpb25pbmcNCiAgICAgICAgICAgICAgICAgICAgbG1zRGVhY3RpdmF0ZVgyKFJlYWRJbnRYKGRhdGEsIDIpKTsNCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGNhc2UgMzogeyAvLyBJbnRlbCBNRSBTeXN0ZW0gQWNjb3VudCBJbmZvcm1hdGlvbg0KICAgICAgICAgICAgICAgICAgICB2YXIgc3RhdHVzID0gUmVhZEludFgoZGF0YSwgMik7DQogICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnSW50ZWwmcmVnOyBBTVQgQWN0aXZhdGlvbicsICdGYWlsZWQgdG8gZ2V0IGFjY291bnQgaW5mb3JtYXRpb24sIHN0YXR1cyAnICsgc3RhdHVzKTsNCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtZXVzZXIgPSBkYXRhLnN1YnN0cmluZyg2LCBkYXRhLmluZGV4T2YoJ1wwJywgNikpOw0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1lcGFzcyA9IGRhdGEuc3Vic3RyaW5nKDM5LCBkYXRhLmluZGV4T2YoJ1wwJywgMzkpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIFFIKCdpZF9kaWFsb2dNZXNzYWdlJywgJ0ZldGNoaW5nIGFjdGl2YXRpb24gc3RhdHVzLi4uJyk7DQogICAgICAgICAgICAgICAgICAgICAgICB3c3N0YWNrID0gV3NtYW5TdGFja0NyZWF0ZVNlcnZpY2UoImxvY2FsaG9zdCIsIDE2OTkyLCBtZXVzZXIsIG1lcGFzcywgZmFsc2UpOw0KICAgICAgICAgICAgICAgICAgICAgICAgYW10c3RhY2sgPSBBbXRTdGFja0NyZWF0ZVNlcnZpY2Uod3NzdGFjayk7DQogICAgICAgICAgICAgICAgICAgICAgICBhbXRzdGFjay5vblByb2Nlc3NDaGFuZ2VkID0gb25Qcm9jZXNzQ2hhbmdlZDsNCiAgICAgICAgICAgICAgICAgICAgICAgIGFtdHN0YWNrLkJhdGNoRW51bShudWxsLCBbJypBTVRfR2VuZXJhbFNldHRpbmdzJywgJypJUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlJ10sIGxtc0FjdGl2YXRpb25YMSk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGNhc2UgOTogeyAvLyBOZXcgbm90aWZpY2F0aW9uDQogICAgICAgICAgICAgICAgICAgIHZhciBub3RpZmljYXRpb24gPSBKU09OLnBhcnNlKGRhdGEuc3Vic3RyaW5nKDIpKTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGxtc05vdGlmaWNhdGlvbnMgPT0gbnVsbCkgeyBsbXNOb3RpZmljYXRpb25zID0gW107IH0NCiAgICAgICAgICAgICAgICAgICAgbG1zTm90aWZpY2F0aW9ucy51bnNoaWZ0KG5vdGlmaWNhdGlvbik7DQogICAgICAgICAgICAgICAgICAgIGxtc1JlZnJlc2hOb3RpZmljYXRpb25zKCk7DQogICAgICAgICAgICAgICAgICAgIGlmICgobm90aWZpY2F0aW9uLmNvZGUgPT0gJ2lBTVQwMDU1LTAnKSB8fCAobm90aWZpY2F0aW9uLmNvZGUgPT0gJ2lBTVQwMDU1LTEnKSB8fCAobm90aWZpY2F0aW9uLmNvZGUgPT0gJ2lBTVQwMDU1LTInKSkgeyBzZXREaWFsb2dNb2RlKCk7IGxtc1JlZnJlc2goKTsgfQ0KICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBsbXNSZWZyZXNoTm90aWZpY2F0aW9ucygpIHsNCiAgICAgICAgICAgIHZhciB4ID0gJzxoMj5Ob3RpZmljYXRpb25zPC9oMj4nICsgVGFibGVTdGFydCgpOw0KICAgICAgICAgICAgaWYgKGxtc05vdGlmaWNhdGlvbnMgJiYgbG1zTm90aWZpY2F0aW9ucy5sZW5ndGggPiAwKSB7DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBsbXNOb3RpZmljYXRpb25zKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBuID0gbG1zTm90aWZpY2F0aW9uc1tpXSwgdiA9IG4uc3RyOw0KICAgICAgICAgICAgICAgICAgICBpZiAobi5jb2RlICE9ICdpQU1UMDA1MC0zMicpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2LmluZGV4T2YoJ1VzZXIgTm90aWZpY2F0aW9uIEFsZXJ0IC0gJykgPT0gMCkgeyB2ID0gdi5zdWJzdHJpbmcoMjYpOyB9DQogICAgICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkobmV3IERhdGUobi5kYXRlKS50b0xvY2FsZVN0cmluZygpLCB2KTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgeCArPSAiPHRyPjx0ZCBzdHlsZT1wYWRkaW5nOjhweD48aT5ObyBub3RpZmljYXRpb25zIGZvdW5kLjwvaT48dGQ+IjsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbmQoKTsNCiAgICAgICAgICAgIFFIKCdpZF9sbXNEYXRhMicsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gbG1zQWN0aXZhdGlvblgxKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsNCiAgICAgICAgICAgICAgICBtZXNzYWdlYm94KCdJbnRlbCZyZWc7IEFNVCBBY3RpdmF0aW9uJywgJ0ZhaWxlZCB0byBmZXRjaCBhY3RpdmF0aW9uIHN0YXR1cywgc3RhdHVzICcgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZXNbJ0lQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2UnXS5yZXNwb25zZVsnQWxsb3dlZENvbnRyb2xNb2RlcyddLmxlbmd0aCAhPSAyKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnSW50ZWwmcmVnOyBBTVQgQWN0aXZhdGlvbicsICdDbGllbnQgY29udHJvbCBtb2RlIGFjdGl2YXRpb24gbm90IGFsbG93ZWQnKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgbG1zVGVtcCA9IHJlc3BvbnNlc1snQU1UX0dlbmVyYWxTZXR0aW5ncyddLnJlc3BvbnNlOw0KICAgICAgICAgICAgICAgIGFtdHN0YWNrLklQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2VfU2V0dXAoMiwgcnN0cjJoZXgocnN0cl9tZDUoJ2FkbWluOicgKyByZXNwb25zZXNbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZVsnRGlnZXN0UmVhbG0nXSArICc6JyArIGQ0cGFzc3dvcmQudmFsdWUpKSwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbG1zQWN0aXZhdGlvblgyKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGxtc0FjdGl2YXRpb25YMihzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDAgfHwgcmVzcG9uc2UuQm9keVsnUmV0dXJuVmFsdWUnXSAhPSAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnSW50ZWwmcmVnOyBBTVQgQWN0aXZhdGlvbicsICdGYWlsZWQgYWN0aXZhdGlvbiwgc3RhdHVzICcgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBzZXREaWFsb2dNb2RlKCk7DQogICAgICAgICAgICAgICAgbG1zUmVmcmVzaCgpOw0KICAgICAgICAgICAgICAgIGxtc1RlbXBbJ0hvc3ROYW1lJ10gPSBsbXNNZUluZm9bJ09zSG9zdG5hbWUnXTsgLy8gU2V0IHRoZSBPUyBob3N0bmFtZQ0KICAgICAgICAgICAgICAgIC8vIFRPRE86IEFsc28gc2V0IHRoZSBsb2NhbCBGUUROIGlmIHdlIGNhbiBnZXQgaXQgZnJvbSBMTVMNCiAgICAgICAgICAgICAgICB3c3N0YWNrID0gV3NtYW5TdGFja0NyZWF0ZVNlcnZpY2UoJ2xvY2FsaG9zdCcsIDE2OTkyLCAnYWRtaW4nLCBkNHBhc3N3b3JkLnZhbHVlLCBmYWxzZSk7DQogICAgICAgICAgICAgICAgYW10c3RhY2sgPSBBbXRTdGFja0NyZWF0ZVNlcnZpY2Uod3NzdGFjayk7DQogICAgICAgICAgICAgICAgYW10c3RhY2sub25Qcm9jZXNzQ2hhbmdlZCA9IG9uUHJvY2Vzc0NoYW5nZWQ7DQogICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfR2VuZXJhbFNldHRpbmdzJywgbG1zVGVtcCwgZnVuY3Rpb24oKSB7IH0sIDAsIDEpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gbG1zRGVhY3RpdmF0ZSgpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgfHwgbG1zLlN0YXRlICE9IDIpIHJldHVybjsNCiAgICAgICAgICAgIFFIKCdpZF9kaWFsb2dNZXNzYWdlJywgJ0NvbmZpcm0gSW50ZWwmcmVnOyBBTVQgZGVhY3RpdmF0aW9uPycpOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxLCAiSW50ZWwmcmVnOyBBTVQgRGVhY3RpdmF0aW9uIiwgMywgbG1zRGVhY3RpdmF0ZVgxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGxtc0RlYWN0aXZhdGVYMSgpIHsNCiAgICAgICAgICAgIHN0YXR1c2JveCgnSW50ZWwmcmVnOyBBTVQgRGVhY3RpdmF0aW9uJywgJ0RlYWN0aXZhdGluZyBJbnRlbCZyZWc7IEFNVC4uLicpDQogICAgICAgICAgICBsbXMuU2VuZENtZCgyLCBJbnRUb1N0clgoMSkpOyAvLyBTZW5kIHJlcXVlc3QgZm9yIGRlYWN0aXZhdGlvbg0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gbG1zRGVhY3RpdmF0ZVgyKHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnSW50ZWwmcmVnOyBBTVQgRGVhY3RpdmF0aW9uJywgJ0ZhaWxlZCBkZWFjdGl2YXRpb24sIHN0YXR1cyAnICsgc3RhdHVzKQ0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBRSCgnaWRfbG1zRGF0YScsICdQbGVhc2Ugd2FpdCBmb3IgZGVhY3RpdmF0aW9uLi4uJyk7DQogICAgICAgICAgICAgICAgUVYoJ2lkX2xtc0RhdGEyJywgZmFsc2UpOw0KICAgICAgICAgICAgICAgIHNldERpYWxvZ01vZGUoKTsNCiAgICAgICAgICAgICAgICBsbXNSZWZyZXNoKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICAvLyBSZWZyZXNoIGJ1dHRvbiBvbiB0aGUgVUkNCiAgICAgICAgZnVuY3Rpb24gbG1zUmVmcmVzaCgpIHsNCiAgICAgICAgICAgIGlmIChsbXMuU3RhdGUgIT0gMikgcmV0dXJuOw0KICAgICAgICAgICAgbG1zLlNlbmRDbWQoMSwgIiIpOyAvLyBTZW5kIHRoZSByZXF1ZXN0IGJhc2ljIGluZm9ybWF0aW9uIGNvbW1hbmQNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENvbmZpZ3VyZSBidXR0b24gb24gdGhlIFVJDQogICAgICAgIGZ1bmN0aW9uIGxtc0NvbmZpZ3VyZSgpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoNCwgJ0ludGVsJnJlZzsgQU1UIExvZ2luJywgMywgZnVuY3Rpb24gKCkgeyBsbXNDb25maWd1cmVMb2dpbigpOyB9KTsNCiAgICAgICAgICAgIC8vZDR1c2VybmFtZS5yZWFkT25seSA9IGZhbHNlOw0KICAgICAgICAgICAgZDR1c2VybmFtZS5kaXNhYmxlZCA9IGZhbHNlOw0KICAgICAgICAgICAgaWYgKGQ0dXNlcm5hbWUudmFsdWUgPT0gJ2FkbWluJykgZDR1c2VybmFtZS52YWx1ZSA9ICcnOw0KICAgICAgICAgICAgaW5wdXRCb3hGb2N1cygnZDR1c2VybmFtZScpOw0KICAgICAgICAgICAgbG1zVXBkYXRlTG9naW5EaWFsb2coKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENhbGxlZCB3aGVuIHRoZSB1c2VyIGhpdHMgT0sgb24gdGhlIGxvZ2luIGRpYWxvZw0KICAgICAgICBmdW5jdGlvbiBsbXNDb25maWd1cmVMb2dpbigpIHsNCiAgICAgICAgICAgIHZhciB1c2VyID0gZDR1c2VybmFtZS52YWx1ZTsNCiAgICAgICAgICAgIGlmICh1c2VyID09ICcnKSB1c2VyID0gJ2FkbWluJzsNCiAgICAgICAgICAgIGNvbm5lY3QoJ2xvY2FsaG9zdCcsIDE2OTkyLCB1c2VyLCBkNHBhc3N3b3JkLnZhbHVlLCAwKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIEFjdGl2YXRlIGJ1dHRvbiBvbiB0aGUgVUkNCiAgICAgICAgZnVuY3Rpb24gbG1zQWN0aXZhdGUoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlfHwgbG1zLlN0YXRlICE9IDIpIHJldHVybjsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoNCwgJ0ludGVsJnJlZzsgQU1UIEFjdGl2YXRpb24nLCAzLCBmdW5jdGlvbiAoKSB7IGxtc0FjdGl2YXRlRXgoKTsgfSk7DQogICAgICAgICAgICAvL2Q0dXNlcm5hbWUucmVhZE9ubHkgPSB0cnVlOw0KICAgICAgICAgICAgZDR1c2VybmFtZS5kaXNhYmxlZCA9IHRydWU7DQogICAgICAgICAgICBkNHVzZXJuYW1lLnZhbHVlID0gJ2FkbWluJzsNCiAgICAgICAgICAgIGlucHV0Qm94Rm9jdXMoJ2Q0cGFzc3dvcmQnKTsNCiAgICAgICAgICAgIGxtc1VwZGF0ZUxvZ2luRGlhbG9nKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBHbyBoZWFkIHdpdGggSW50ZWwgQU1UIGNsaWVudCBjb250cm9sIG1vZGUgYWN0aXZhdGlvbg0KICAgICAgICBmdW5jdGlvbiBsbXNBY3RpdmF0ZUV4KCkNCiAgICAgICAgew0KICAgICAgICAgICAgbG1zLlNlbmRDbWQoMyk7IC8vIFNlbmQgcmVxdWVzdCBmb3IgYWNjb3VudCBpbmZvcm1hdGlvbg0KICAgICAgICAgICAgc3RhdHVzYm94KCdJbnRlbCZyZWc7IEFNVCBBY3RpdmF0aW9uJywgJ0ZldGNoaW5nIEFjY291bnQgSW5mb3JtYXRpb24uLi4nKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENhbGxlZCBlYWNoIHRpbWUgc29tZXRoaW5nIGNoYW5nZXMgaW4gdGhlIGxvZ2luIGRpYWxvZw0KICAgICAgICBmdW5jdGlvbiBsbXNVcGRhdGVMb2dpbkRpYWxvZyhlLCBkKSB7DQogICAgICAgICAgICB2YXIgb2sgPSBwYXNzd29yZGNoZWNrKGQ0cGFzc3dvcmQudmFsdWUpOw0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgICAgIGlmIChlICE9IG51bGwgJiYgZS5rZXlDb2RlID09IDEzICYmIGQgPT0gMSkgaW5wdXRCb3hGb2N1cygnZDRwYXNzd29yZCcpOw0KICAgICAgICAgICAgaWYgKG9rID09IHRydWUgJiYgZSAhPSBudWxsICYmIGUua2V5Q29kZSA9PSAxMyAmJiBkID09IDIpIGRpYWxvZ2Nsb3NlKDEpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIGxtc0hhc2hBcmdTdHJpbmdzID0gWyJNRDUiLCAiU0hBMSIsICJTSEEyNTYiLCAiU0hBNTEyIl07DQogICAgICAgIGZ1bmN0aW9uIGxtc1Nob3dUcnVzdGVkSGFzaGVzRGxnKCkgew0KICAgICAgICAgICAgLy8ge1wiQUNcIjolZCxcIkRGXCI6JWQsXCJBTFwiOiVkLFwiTkFcIjpcIiVzXCIsXCJIQVwiOlwiJXNcIn0iDQoNCiAgICAgICAgICAgIHZhciB4ID0gIjxkaXYgc3R5bGU9bWF4LWhlaWdodDoyNDBweDtvdmVyZmxvdy15OnNjcm9sbD4iICsgVGFibGVTdGFydCgpOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBsbXNNZUluZm9bJ1RydXN0ZWRIYXNoZXMnXSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAvL3ggKz0gIjxiPiIgKyBsbXNNZUluZm9bJ1RydXN0ZWRIYXNoZXMnXVtpXVsnTmFtZSddICsgIjwvYj48YnI+PHNwYW4gc3R5bGU9Zm9udC1zaXplOjEwcHg+IiArIGxtc0hhc2hBcmdTdHJpbmdzW2xtc01lSW5mb1snVHJ1c3RlZEhhc2hlcyddW2ldWydIYXNoQWxnb3JpdGhtJ11dICsgKGxtc01lSW5mb1snVHJ1c3RlZEhhc2hlcyddW2ldWydBY3RpdmUnXSA9PSAxPyIsIEFjdGl2ZSI6IiIpICsgKGxtc01lSW5mb1snVHJ1c3RlZEhhc2hlcyddW2ldWydEZWZhdWx0J10gPT0gMT8iLCBEZWZhdWx0IjoiIikgKyAiPC9zcGFuPjxicj48c3BhbiBzdHlsZT1mb250LXNpemU6MTBweD4iICsgbG1zTWVJbmZvWydUcnVzdGVkSGFzaGVzJ11baV1bJ0hhc2gnXSArICI8L3NwYW4+PGJyPjxicj4iOw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiPGI+IiArIGxtc01lSW5mb1snVHJ1c3RlZEhhc2hlcyddW2ldWydOYW1lJ10gKyAiPC9iPjxicj48c3BhbiBzdHlsZT1mb250LXNpemU6MTBweD4iICsgbG1zSGFzaEFyZ1N0cmluZ3NbbG1zTWVJbmZvWydUcnVzdGVkSGFzaGVzJ11baV1bJ0hhc2hBbGdvcml0aG0nXV0gKyAobG1zTWVJbmZvWydUcnVzdGVkSGFzaGVzJ11baV1bJ0FjdGl2ZSddID09IDE/IiwgQWN0aXZlIjoiIikgKyAobG1zTWVJbmZvWydUcnVzdGVkSGFzaGVzJ11baV1bJ0RlZmF1bHQnXSA9PSAxPyIsIERlZmF1bHQiOiIiKSArICI8L3NwYW4+PGJyPjxzcGFuIHN0eWxlPWZvbnQtc2l6ZTo4cHg+IiArIGxtc01lSW5mb1snVHJ1c3RlZEhhc2hlcyddW2ldWydIYXNoJ10gKyAiPC9zcGFuPiIsICIiKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbmQoKSArICI8L2Rpdj4iOw0KICAgICAgICAgICAgbWVzc2FnZWJveCgiSW50ZWwmcmVnOyBBTVQgVHJ1c3RlZCBIYXNoZXMiLCB4KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGxtc1Nob3dWZXJzaW9uc0RsZygpIHsNCiAgICAgICAgICAgIHZhciB4ID0gVGFibGVTdGFydCgpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJJbnRlbCZyZWc7IEFNVCIsIGxtc01lSW5mb1snVmVyc2lvbnMnXVsnQU1UJ10pOw0KICAgICAgICAgICAgaWYgKGxtc01lSW5mb1snTWVpVmVyc2lvbiddICE9IG51bGwpIHsgeCArPSBUYWJsZUVudHJ5KCJJbnRlbCZyZWc7IE1FSSBkcml2ZXIiLCBsbXNNZUluZm9bJ01laVZlcnNpb24nXSk7IH0NCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gbG1zTWVJbmZvWydWZXJzaW9ucyddKSB7IGlmIChpICE9ICdBTVQnKSB4ICs9IFRhYmxlRW50cnkoaSwgbG1zTWVJbmZvWydWZXJzaW9ucyddW2ldKTsgfQ0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KICAgICAgICAgICAgbWVzc2FnZWJveCgiSW50ZWwmcmVnOyBBTVQgVmVyc2lvbnMiLCB4KTsNCiAgICAgICAgfQ0KDQoNCg0KICAgICAgICBmdW5jdGlvbiBjbGVhbnVwKCkgew0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gaGFuZGxlS2V5VXAoZSkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gaGFuZGxlS2V5RG93bihlKSB7DQogICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdoYW5kbGVLZXlEb3duJywgZSk7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBoYW5kbGVLZXlQcmVzcyhlKSB7DQogICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdoYW5kbGVLZXlQcmVzcycsIGUpOw0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIGNvbm5lY3RGdW5jID0gbnVsbDsNCiAgICAgICAgdmFyIGNvbm5lY3RGdW5jVGFnID0gbnVsbDsNCiAgICAgICAgZnVuY3Rpb24gY29ubmVjdChob3N0LCBwb3J0LCB1c2VyLCBwYXNzLCB0bHMsIGZ1bmMsIGZ1bmN0YWcpIHsNCiAgICAgICAgICAgIGdvKDApOw0KICAgICAgICAgICAgZnVsbHNjcmVlbm9ubHkgPSBmYWxzZTsNCiAgICAgICAgICAgIGNvbm5lY3RGdW5jID0gZnVuYzsNCiAgICAgICAgICAgIGNvbm5lY3RGdW5jVGFnID0gZnVuY3RhZzsNCg0KDQoNCiAgICAgICAgICAgIHdzc3RhY2sgPSBXc21hblN0YWNrQ3JlYXRlU2VydmljZShob3N0LCBwb3J0LCB1c2VyLCBwYXNzLCB0bHMpOw0KICAgICAgICAgICAgYW10c3RhY2sgPSBBbXRTdGFja0NyZWF0ZVNlcnZpY2Uod3NzdGFjayk7DQogICAgICAgICAgICBhbXRzdGFjay5vblByb2Nlc3NDaGFuZ2VkID0gb25Qcm9jZXNzQ2hhbmdlZDsNCg0KICAgICAgICAgICAgLy8gU2V0dXAgVExTIGNoZWNraW5nDQoNCiAgICAgICAgICAgIC8vIEhpZGUgVExTIGluZGljYXRvcg0KDQogICAgICAgICAgICAvLyBIaWRlIG1vc3Qgb2YgdGhlIGxlZnQgbWVudSBvcHRpb25zLCB3ZSB3aWxsIHNlZSB0aGVtIGFzIHdlIGxvYWQgZGF0YQ0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDI7IGkgPCAyNTsgaSsrKSB7IFFWKCdnbycgKyBpLCBmYWxzZSk7IH0NCiAgICAgICAgICAgIFFWKCdnbzgnLCB0cnVlKTsgLy8gTmV0d29yayBTZXR0aW5ncw0KICAgICAgICAgICAgLy9RVignZ28xNScsIGZhbHNlKTsgLy8gQXVkaXQgTG9nDQoNCiAgICAgICAgICAgIC8vUVYoJ2dvMTYnLCBmYWxzZSk7IC8vIFNlY3VyaXR5IFNldHRpbmdzDQoNCiAgICAgICAgICAgIC8vUVYoJ2dvMTcnLCBmYWxzZSk7IC8vIFJlbW90ZSBBY2Nlc3MNCg0KICAgICAgICAgICAgUVYoJ2dvMjAnLCB0cnVlKTsgLy8gU2NyaXB0aW5nIEVkaXRvcg0KDQoNCg0KICAgICAgICAgICAgLy8gQ2xlYXIgdGhlIGRpc3BsYXllZCBwb3dlciBzdGF0ZQ0KDQogICAgICAgICAgICAvLyBDbGVhciBldmVyeXRoaW5nLCBtYWtlIHN1cmUgYWxsIGNvbm5lY3Rpb24gc3RhdGUgaXMgcmVzZXQuDQogICAgICAgICAgICBhbXR2ZXJzaW9uID0gYW10dmVyc2lvbm1pbiA9IGFtdEZpcnN0UHVsbCA9IDA7DQogICAgICAgICAgICBhbXRzeXNzdGF0ZSA9IGFtdGRlbHRhdGltZSA9IGFtdGxvZ2ljYWxlbGVtZW50cyA9IEhhcmR3YXJlSW52ZW50b3J5ID0gdW5kZWZpbmVkOw0KICAgICAgICAgICAgYW10UG93ZXJCb290Q2FwYWJpbGl0aWVzID0gbnVsbDsNCiAgICAgICAgICAgIHh4QWNjb3VudEZldGNoID0gOTk5Ow0KDQogICAgICAgICAgICAvLyBTaG93IGxvYWRpbmcgb24gYWxsIHBhbmVscw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlU3lzU3RhdHVzJywgTG9hZGluZ0h0bWwpOw0KDQogICAgICAgICAgICBRSCgnaWRfVGFibGVOZXR3b3JrU2V0dGluZ3NTcGFuJywgTG9hZGluZ0h0bWwpOw0KICAgICAgICAgICAgYW10d2lyZWxlc3NpZiA9IC0xOw0KDQogICAgICAgICAgICB4eFdpcmVsZXNzID0gdW5kZWZpbmVkOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlV2lmaTInLCAnJyk7DQoNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZVN5c0luZm8nLCBMb2FkaW5nSHRtbCk7DQoNCiAgICAgICAgICAgIHh4QWNjb3VudEFkbWluTmFtZSA9IG51bGw7DQogICAgICAgICAgICB4eEFjY291bnRSZWFsbUluZm8gPSB7fTsNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZVVzZXJBY2NvdW50cycsIExvYWRpbmdIdG1sKTsNCg0KICAgICAgICAgICAgZXZlbnRtZXNzYWdlcyA9IG51bGw7DQogICAgICAgICAgICBRSCgnaWRfVGFibGVFdmVudExvZycsJycpOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlRXZlbnRMb2cyJyxMb2FkaW5nSHRtbCk7DQoNCiAgICAgICAgICAgIGF1ZGl0TG9nID0gbnVsbDsNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZUF1ZGl0TG9nMScsICcnKTsNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZUF1ZGl0TG9nMicsIExvYWRpbmdIdG1sKTsNCg0KICAgICAgICAgICAgeHhDZXJ0aWZpY2F0ZXMgPSBudWxsOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlQ2VydHMnLCBMb2FkaW5nSHRtbCk7DQoNCiAgICAgICAgICAgIHh4UmVtb3RlQWNjZXNzID0gbnVsbDsNCiAgICAgICAgICAgIHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uID0gbnVsbDsNCiAgICAgICAgICAgIHh4Q2lyYVNlcnZlcnMgPSBudWxsOw0KICAgICAgICAgICAgeHhVc2VySW5pdGlhdGVkQ2lyYSA9IG51bGw7DQogICAgICAgICAgICB4eFJlbW90ZUFjY2Vzc0NyZWRlbnRpYUxpbmtzID0gbnVsbDsNCiAgICAgICAgICAgIHh4TVBTVXNlclBhc3MgPSBudWxsOw0KICAgICAgICAgICAgeHhQb2xpY2llcyA9IG51bGw7DQogICAgICAgICAgICBRSCgnaWRfVGFibGVSZW1vdGVBY2Nlc3MnLCBMb2FkaW5nSHRtbCk7DQoNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZVN5c3RlbUFnZW50UHJlc2VuY2UnLCBMb2FkaW5nSHRtbCk7DQoNCiAgICAgICAgICAgIHh4U3lzdGVtRGVmZW5zZSA9IG51bGw7DQogICAgICAgICAgICB4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3kgPSB7fTsNCiAgICAgICAgICAgIHh4VXBkYXRpbmdEZWZlbnNlU3RhdHMgPSBmYWxzZTsNCiAgICAgICAgICAgIHh4RmlsdGVyU3RhdGlzdGljcyA9IFt7fSwge31dOyAvLyBXaXJlZCBhbmQgd2lyZWxlc3MgaW50ZXJmYWNlIHN0YXRzDQogICAgICAgICAgICB4eEZpbHRlclN0YXRpc3RpY3NUaW1lciA9IG51bGw7DQogICAgICAgICAgICB4eEZpbHRlclN0YXRpc3RpY3NUaW1lckFjdGl2ZSA9IGZhbHNlOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlU3lzdGVtRGVmZW5zZScsIExvYWRpbmdIdG1sKTsNCg0KDQogICAgICAgICAgICAvLyBTdGFydCBwdWxsaW5nIEludGVsIEFNVCBpbmZvcm1hdGlvbg0KICAgICAgICAgICAgYW10c3RhY2suQmF0Y2hFbnVtKCIiLCBbIkNJTV9Tb2Z0d2FyZUlkZW50aXR5IiwgIipBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSJdLCBwcm9jZXNzU3lzdGVtVmVyc2lvbik7IC8vIEdldCBJbnRlbCBBTVQgdmVyc2lvbiBpbmZvcm1hdGlvbiBhbmQgcGxlbnR5IG1vcmUNCiAgICAgICAgICAgIC8vYW10c3RhY2suRW51bSgiQ0lNX0xvZ2ljYWxFbGVtZW50IiwgcHJvY2Vzc1N5c3RlbVZlcnNpb24pOyAvLyBHZXQgSW50ZWwgQU1UIHZlcnNpb24gaW5mb3JtYXRpb24gYW5kIHBsZW50eSBtb3JlDQoNCg0KDQogICAgICAgICAgICBmdXBkYXRlc2NyaXB0KCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBkaXNjb25uZWN0KCkgew0KDQoNCg0KDQoNCg0KICAgICAgICAgICAgU3RvcERlZmVuc2VTdGF0c1RpbWVyKCk7DQoNCg0KICAgICAgICAgICAgc2NyaXB0X1N0b3AoKTsNCg0KICAgICAgICAgICAgYnJlYWtTY3JpcHRCdXR0b24oKTsNCg0KICAgICAgICAgICAgZGlhbG9nY2xvc2UoMCk7DQoNCiAgICAgICAgICAgIFFIKCdpZF9jb21wdXRlcm5hbWUnLCAnJyk7DQogICAgICAgICAgICBpZiAoYW10c3RhY2spIHsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5vblByb2Nlc3NDaGFuZ2VkID0gbnVsbDsgLy8gVW4taG9vayBwcm9ncmVzcyBpbmRpY2F0b3INCiAgICAgICAgICAgICAgICBhbXRzdGFjay5DYW5jZWxBbGxRdWVyaWVzKDk5OSk7IC8vIEZhaWwgYWxsIHBlbmRpbmcgV1NNQU4gY2FsbHMuIFNldCB0byA5OTkgdG8gaW5kaWNhdGUgbm90IHRvIGNhbGwgYmFjayBhbnkgb2YgdGhlIHBlbmRpbmcgY2FsbHMgd2l0aCBlcnJvcnMuDQogICAgICAgICAgICAgICAgYW10c3RhY2sgPSBudWxsOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY2xlYW51cCgpOw0KICAgICAgICAgICAgd3NzdGFjayA9IG51bGw7DQogICAgICAgICAgICBkZWxldGUgYW10c3RhY2s7DQogICAgICAgICAgICBvblByb2Nlc3NDaGFuZ2VkKDAsIDEpOw0KICAgICAgICAgICAgZ28oMTAxKTsNCg0KDQoNCiAgICAgICAgICAgIFFIKCdpZF9jb21wdXRlcm5hbWUnLCAnUmVtb3RlIE1hbmFnZW1lbnQgQ29uc29sZSB2JyArIHZlcnNpb24pOw0KICAgICAgICAgICAgDQoNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIG9uUHJvY2Vzc0NoYW5nZWQoYSwgYikgew0KICAgICAgICAgICAgUVMoJ2lkX3Byb2dyZXNzYmFyJykud2lkdGggPSAoKGEgKiAxMDApIC8gYikgKyAiJSI7DQogICAgICAgICAgICBpZiAoYSA9PSAwKSByZWZyZXNoQnV0dG9ucyh0cnVlKTsgLy8gSWYgbm90aGluZyBpcyBiZWluZyBkb25lLCByZS1lbmFibGUgcmVmcmVzaCBidXR0b25zDQoNCg0KICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm90aGluZyBiZWluZyBkb25lIG5vdywgc2VlIGlmIHdlIGNhbiBwdWxsIG1vcmUgaW5mb3JtYXRpb24NCiAgICAgICAgICAgIGlmIChhICE9IDAgfHwgIWFtdHN0YWNrKSByZXR1cm47DQogICAgICAgICAgICBpZiAoKGFtdHZlcnNpb24gPiAwKSAmJiAoKGFtdEZpcnN0UHVsbCAmIDY0KSA9PSAwKSkgew0KICAgICAgICAgICAgICAgIGFtdEZpcnN0UHVsbCB8PSA2NDsNCiAgICAgICAgICAgICAgICBQdWxsUG93ZXJQb2xpY3koKTsNCg0KICAgICAgICAgICAgICAgIFB1bGxXYXRjaGRvZygpOw0KDQoNCiAgICAgICAgICAgICAgICBzY3JpcHRWaWV3QnV0dG9uKHNjcmlwdF9CdWlsZGluZ0Jsb2Nrcz8xOjApOw0KDQogICAgICAgICAgICAgICAgaWYgKGFtdHZlcnNpb24gPiA1KSB7DQoNCiAgICAgICAgICAgICAgICAgICAgUHVsbENlcnRpZmljYXRlcygpOw0KDQogICAgICAgICAgICAgICAgICAgIFB1bGxSZW1vdGVBY2Nlc3MoKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgcmV0dXJuOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBpZiAoKGFtdEZpcnN0UHVsbCAmIDEpID09IDApIHsgUHVsbEhhcmR3YXJlKCk7IHJldHVybjsgfQ0KDQogICAgICAgICAgICBpZiAoKGFtdEZpcnN0UHVsbCAmIDE2KSA9PSAwKSB7IFB1bGxFdmVudExvZygpOyByZXR1cm47IH0NCg0KICAgICAgICAgICAgaWYgKChhbXRGaXJzdFB1bGwgJiAzMikgPT0gMCkgeyBQdWxsQXVkaXRMb2coKTsgcmV0dXJuOyB9DQogICAgICAgIH0NCg0KDQogICAgICAgIGZ1bmN0aW9uIHRvb2xtZW51Y2xpY2soeCkgew0KICAgICAgICAgICAgUVYoJ2lkX21lbnVpdGVtMScsIGN1cnJlbnRWaWV3ID09IDEwMSk7DQoNCiAgICAgICAgICAgIFFWKCdpZF9tZW51aXRlbTInLCBjdXJyZW50VmlldyA9PSAxMDIpOw0KDQogICAgICAgICAgICB2YXIgZCA9IChRUygnaWRfY29tcHV0ZXJTZWxlY3Rvck1lbnUnKS5kaXNwbGF5ID09ICdub25lJyk7DQogICAgICAgICAgICBpZiAoZCA9PSB0cnVlICYmIHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgeHhkaWFsb2dNb2RlID0gKGQgPT0gdHJ1ZSk/OTk5OnVuZGVmaW5lZDsNCiAgICAgICAgICAgIFFWKCdpZF9jb21wdXRlclNlbGVjdG9yTWVudScsIGQpOw0KICAgICAgICAgICAgaWYgKHggPT0gMCkgcmV0dXJuOw0KICAgICAgICAgICAgZ28oeCk7DQogICAgICAgIH0NCg0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gQk9UVE9NIElORk9STUFUSU9OIFNUUklORw0KICAgICAgICAvLw0KDQoNCiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1N5c3RlbVZlcnNpb24oc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCB8fCBzdGF0dXMgPT0gNDAwKSB7DQogICAgICAgICAgICAgICAgdmFyIHY7DQogICAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsNCiAgICAgICAgICAgICAgICAgICAgLy9hbXRsb2dpY2FsZWxlbWVudHMgPSByZXNwb25zZXM7DQogICAgICAgICAgICAgICAgICAgIGFtdGxvZ2ljYWxlbGVtZW50cyA9IFtdOw0KICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2VzICE9IG51bGwpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZXNbIkNJTV9Tb2Z0d2FyZUlkZW50aXR5Il0gIT0gbnVsbCAmJiByZXNwb25zZXNbIkNJTV9Tb2Z0d2FyZUlkZW50aXR5Il0ucmVzcG9uc2VzICE9IG51bGwpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbXRsb2dpY2FsZWxlbWVudHMgPSByZXNwb25zZXNbIkNJTV9Tb2Z0d2FyZUlkZW50aXR5Il0ucmVzcG9uc2VzOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZXNbIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIl0gIT0gbnVsbCAmJiByZXNwb25zZXNbIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIl0ucmVzcG9uc2UgIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbXRsb2dpY2FsZWxlbWVudHMucHVzaChyZXNwb25zZXNbIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIl0ucmVzcG9uc2UpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAoYW10bG9naWNhbGVsZW1lbnRzLmxlbmd0aCA9PSAwKSB7IGNvbnNvbGUuZXJyb3IoJ0VSUk9SOiBDb3VsZCBub3QgZ2V0IEludGVsIEFNVCB2ZXJzaW9uLicpOyBkaXNjb25uZWN0KCk7IHJldHVybjsgfSAvLyBDb3VsZCBub3QgZ2V0IEludGVsIEFNVCB2ZXJzaW9uLCBkaXNjb25uZWN0KCk7DQogICAgICAgICAgICAgICAgICAgIHYgPSBnZXRJbnN0YW5jZShhbXRsb2dpY2FsZWxlbWVudHMsICJBTVQiKVsiVmVyc2lvblN0cmluZyJdOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIHYgPSBzdGFjay53c21hbi5jb21tLmFtdFZlcnNpb247DQogICAgICAgICAgICAgICAgICAgIGlmICghdikgeyBlcnJjaGVjayg0MDAsIHN0YWNrKTsgcmV0dXJuOyB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGFtdHZlcnNpb24gPSBwYXJzZUludCh2LnNwbGl0KCcuJylbMF0pOw0KICAgICAgICAgICAgICAgIGFtdHZlcnNpb25taW4gPSBwYXJzZUludCh2LnNwbGl0KCcuJylbMV0pOw0KDQoNCiAgICAgICAgICAgICAgICAvL2lmIChhbXR2ZXJzaW9uID4gMTApIHsgd3NzdGFjay5jb21tLk1heEFjdGl2ZUFqYXhDb3VudCA9IDQ7IGFtdHN0YWNrLk1heEFjdGl2ZUVudW1zQ291bnQgPSAxOyBjb25zb2xlLmxvZygnSFRUUCBQaXBlbGluaW5nIGFjdGl2YXRlZCcpOyB9IC8vIFdpdGggSW50ZWwgQU1UIDExIGFuZCBoaWdoZXIsIHVzZSBIVFRQIHBpcGVsaW5pbmcuDQoNCiAgICAgICAgICAgICAgICBQdWxsU3lzdGVtU3RhdHVzKCk7DQogICAgICAgICAgICAgICAgdXBkYXRlU3lzdGVtU3RhdHVzKCk7DQoNCiAgICAgICAgICAgICAgICAvLyBQZXJmb3JtIGxvYWRzIG1vcmUgV1NNQU4gb25seSBpZiBuZWVkZWQNCiAgICAgICAgICAgICAgICBpZiAoKHVybHZhcnNbJ2t2bW9ubHknXSAhPSAxKSAmJiAoZnVsbHNjcmVlbm9ubHkgPT0gZmFsc2UpKSB7DQogICAgICAgICAgICAgICAgICAgIFB1bGxVc2VySW5mbygpOw0KDQoNCiAgICAgICAgICAgICAgICAgICAgaWYgKGFtdHZlcnNpb24gPj0gOCkgUHVsbEFsYXJtcygpOw0KICAgICAgICAgICAgICAgIH0NCg0KDQogICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBjYWxsYmFjaw0KICAgICAgICAgICAgICAgIGlmIChjb25uZWN0RnVuYykgeyBjb25uZWN0RnVuYyhjb25uZWN0RnVuY1RhZyk7IGNvbm5lY3RGdW5jID0gbnVsbDsgY29ubmVjdEZ1bmNUYWcgPSBudWxsOyB9DQoNCg0KDQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIGVycmNoZWNrKHN0YXR1cywgc3RhY2spOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQ29udHJvbCB0aGUgc3RhdGUgb2YgYWxsIHJlZnJlc2ggYnV0dG9ucw0KICAgICAgICB2YXIgcmVmcmVzaEJ1dHRvbnNTdGF0ZSA9IHRydWU7DQogICAgICAgIGZ1bmN0aW9uIHJlZnJlc2hCdXR0b25zKHgpIHsNCiAgICAgICAgICAgIGlmIChyZWZyZXNoQnV0dG9uc1N0YXRlID09IHgpIHJldHVybjsNCiAgICAgICAgICAgIHJlZnJlc2hCdXR0b25zU3RhdGUgPSB4Ow0KICAgICAgICAgICAgdmFyIGkgPSAwLCBlID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lucHV0Jyk7DQogICAgICAgICAgICBmb3IgKDsgaSA8IGUubGVuZ3RoOyBpKyspIHsgaWYgKGVbaV0ubmFtZSA9PSAncmVmcmVzaGJ0bicpIHsgZVtpXS5kaXNhYmxlZCA9ICF4OyB9IH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIERpc3BsYXkgVExTIGNlcnRpZmljYXRlDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gU1lTVEVNIFNUQVRVUyBQQU5FTA0KICAgICAgICAvLw0KDQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbFN5c3RlbVN0YXR1cyh4KSB7DQogICAgICAgICAgICByZWZyZXNoQnV0dG9ucyhmYWxzZSk7DQogICAgICAgICAgICBhbXRzdGFjay5BTVRfVGltZVN5bmNocm9uaXphdGlvblNlcnZpY2VfR2V0TG93QWNjdXJhY3lUaW1lU3luY2gocHJvY2Vzc1N5c3RlbVRpbWUpOw0KDQogICAgICAgICAgICB2YXIgcXVlcnkgPSBbIkNJTV9TZXJ2aWNlQXZhaWxhYmxlVG9FbGVtZW50IiwgIipBTVRfR2VuZXJhbFNldHRpbmdzIiwgIkFNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyIsICIqQU1UX1JlZGlyZWN0aW9uU2VydmljZSIsICJDSU1fRWxlbWVudFNldHRpbmdEYXRhIl07DQogICAgICAgICAgICBpZiAoYW10dmVyc2lvbiA+IDUpIHF1ZXJ5LnB1c2goIklQU19JUHY2UG9ydFNldHRpbmdzIiwgIipDSU1fS1ZNUmVkaXJlY3Rpb25TQVAiLCAiKklQU19PcHRJblNlcnZpY2UiLCIqSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEiKTsNCiAgICAgICAgICAgIGlmIChhbXR2ZXJzaW9uID4gOSkgcXVlcnkucHVzaCgiKklQU19TY3JlZW5Db25maWd1cmF0aW9uU2VydmljZSIpOw0KICAgICAgICAgICAgYW10c3RhY2suQmF0Y2hFbnVtKCIiLCBxdWVyeSwgcHJvY2Vzc1N5c3RlbVN0YXR1cywgdHJ1ZSk7DQoNCiAgICAgICAgICAgIGlmICh4ID09IDEpIFB1bGxXaXJlbGVzcygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1N5c3RlbVRpbWUoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoZXJyY2hlY2soc3RhdHVzLCBzdGFjaykpIHJldHVybjsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gMjAwKSB7DQogICAgICAgICAgICAgICAgLy8gQ29udmVydCBtcyB0byB0aW1lIGFuZCBhZGp1c3QgZm9yIHRoZSB0aW1lem9uZQ0KICAgICAgICAgICAgICAgIHZhciB0ID0gbmV3IERhdGUoKSwgdDIgPSBuZXcgRGF0ZSgpOw0KICAgICAgICAgICAgICAgIHQuc2V0VGltZShyZXNwb25zZXMuQm9keVsiVGEwIl0gKiAxMDAwICsgKHQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwICogMTAwMCkpOw0KICAgICAgICAgICAgICAgIGFtdGRlbHRhdGltZSA9IHQgLSB0MjsNCiAgICAgICAgICAgICAgICB1cGRhdGVTeXN0ZW1TdGF0dXMoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIHZhciBhbXRkZWx0YXRpbWU7DQogICAgICAgIHZhciBhbXRzeXNzdGF0ZTsNCiAgICAgICAgdmFyIGFtdGxvZ2ljYWxlbGVtZW50czsgLy8gcHJvY2Vzc1N5c3RlbVZlcnNpb24NCiAgICAgICAgdmFyIGFtdGZlYXR1cmVzID0ge307DQogICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NTeXN0ZW1TdGF0dXMoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICAvLyBJZiB0aGlzIGNvbXB1dGVyIGhhcyBubyBLVk0sIGlnbm9yZSBhbmQgY29udGludWUgKFN0YW5kYXJkIE1hbmFnZWFiaWxpdHkpDQogICAgICAgICAgICBpZiAoKHJlc3BvbnNlc1snSVBTX1NjcmVlbkNvbmZpZ3VyYXRpb25TZXJ2aWNlJ10gPT0gdW5kZWZpbmVkKSB8fCAocmVzcG9uc2VzWydJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnXS5zdGF0dXMgPT0gNDAwKSkgeyByZXNwb25zZXNbJ0lQU19TY3JlZW5Db25maWd1cmF0aW9uU2VydmljZSddID0gbnVsbDsgfQ0KICAgICAgICAgICAgaWYgKChyZXNwb25zZXNbJ0lQU19LVk1SZWRpcmVjdGlvblNldHRpbmdEYXRhJ10gPT0gdW5kZWZpbmVkKSB8fCAocmVzcG9uc2VzWydJUFNfS1ZNUmVkaXJlY3Rpb25TZXR0aW5nRGF0YSddLnN0YXR1cyA9PSA0MDApKSB7IHJlc3BvbnNlc1snSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEnXSA9IG51bGw7IH0NCiAgICAgICAgICAgIGlmICgocmVzcG9uc2VzWydDSU1fS1ZNUmVkaXJlY3Rpb25TQVAnXSA9PSB1bmRlZmluZWQpIHx8IChyZXNwb25zZXNbJ0NJTV9LVk1SZWRpcmVjdGlvblNBUCddLnN0YXR1cyA9PSA0MDApKSB7IHJlc3BvbnNlc1snQ0lNX0tWTVJlZGlyZWN0aW9uU0FQJ10gPSBudWxsOyB9DQogICAgICAgICAgICBpZiAoKHJlc3BvbnNlc1snSVBTX09wdEluU2VydmljZSddID09IHVuZGVmaW5lZCkgfHwgKHJlc3BvbnNlc1snSVBTX09wdEluU2VydmljZSddLnN0YXR1cyA9PSA0MDApKSB7IHJlc3BvbnNlc1snSVBTX09wdEluU2VydmljZSddID0gbnVsbDsgfQ0KICAgICAgICAgICAgaWYgKChyZXNwb25zZXNbJ0FNVF9SZWRpcmVjdGlvblNlcnZpY2UnXSAhPSB1bmRlZmluZWQpICYmIChyZXNwb25zZXNbJ0FNVF9SZWRpcmVjdGlvblNlcnZpY2UnXS5zdGF0dXMgPT0gMjAwKSkgeyBRVignZ28xMycsIHRydWUpOyB9IC8vIFNob3cgdGhlIHRlcm1pbmFsDQoNCiAgICAgICAgICAgIC8vIFJlc2V0IHRoZSBzdGF0dXMgYWZ0ZXIgcG9zc2libGUgS1ZNIHJlbW92YWwNCiAgICAgICAgICAgIHN0YXR1cyA9IDA7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHJlc3BvbnNlcykgeyBpZiAoKHJlc3BvbnNlc1tpXSAhPSBudWxsKSAmJiAocmVzcG9uc2VzW2ldLnN0YXR1cyA+IHN0YXR1cykpIHsgc3RhdHVzID0gcmVzcG9uc2VzW2ldLnN0YXR1czsgfSB9DQoNCiAgICAgICAgICAgIGlmICgoc3RhdHVzICE9IDQwMCkgJiYgZXJyY2hlY2soc3RhdHVzLCBzdGFjaykpIHJldHVybjsNCiAgICAgICAgICAgIGFtdHN5c3N0YXRlID0gcmVzcG9uc2VzOw0KICAgICAgICAgICAgdXBkYXRlU3lzdGVtU3RhdHVzKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1cGRhdGVTeXN0ZW1TdGF0dXMoKSB7DQogICAgICAgICAgICBpZiAoKCFhbXRzeXNzdGF0ZSkgfHwgKGN1cnJlbnRWaWV3ID4gOTkpKSByZXR1cm47DQogICAgICAgICAgIA0KICAgICAgICAgICAgLy8gU3lzdGVtIFN0YXR1cyBUYWJsZQ0KICAgICAgICAgICAgdmFyIHN5c3RlbWRlZmVuc2UgPSAwLCBob3N0LCB5LCB4ID0gVGFibGVTdGFydCgpLCBmZWF0dXJlcyA9ICcnLCBncyA9IGFtdHN5c3N0YXRlWydBTVRfR2VuZXJhbFNldHRpbmdzJ10ucmVzcG9uc2U7DQoNCiAgICAgICAgICAgIGhvc3QgPSBnc1siSG9zdE5hbWUiXTsNCiAgICAgICAgICAgIHkgPSBnc1siRG9tYWluTmFtZSJdOw0KICAgICAgICAgICAgaWYgKHkgIT0gbnVsbCAmJiB5Lmxlbmd0aCA+IDApIGhvc3QgKz0gIi4iICsgeTsNCiAgICAgICAgICAgIGlmIChob3N0Lmxlbmd0aCA9PSAwKSB7IGhvc3QgPSAiPGk+Tm9uZTwvaT4iOyB9IGVsc2UgeyBob3N0ID0gRXNjYXBlSHRtbChob3N0KTsgfQ0KICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJOYW1lICYgRG9tYWluIiwgYWRkTGlua0NvbmRpdGlvbmFsKGhvc3QsICdzaG93RWRpdE5hbWVEbGcoKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgaWYgKEhhcmR3YXJlSW52ZW50b3J5KSB4ICs9IFRhYmxlRW50cnkoIlN5c3RlbSBJRCIsIGd1aWRUb1N0cihIYXJkd2FyZUludmVudG9yeVsnQ0lNX0NvbXB1dGVyU3lzdGVtUGFja2FnZSddLnJlc3BvbnNlWyJQbGF0Zm9ybUdVSUQiXS50b0xvd2VyQ2FzZSgpKSk7DQogICAgICAgICAgICBpZiAoYW10bG9naWNhbGVsZW1lbnRzKSB7DQogICAgICAgICAgICAgICAgdmFyIG1vZGUgPSAnJywgc2NzID0gZ2V0SXRlbShhbXRsb2dpY2FsZWxlbWVudHMsICJDcmVhdGlvbkNsYXNzTmFtZSIsICJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIpOw0KDQogICAgICAgICAgICAgICAgaWYgKChzY3NbIlByb3Zpc2lvbmluZ1N0YXRlIl0gPT0gMikgJiYgKGFtdHZlcnNpb24gPiA1KSkgew0KICAgICAgICAgICAgICAgICAgICBtb2RlID0gJyBhY3RpdmF0ZWQgaW4gQWRtaW4gQ29udHJvbCBNb2RlIChBQ00pJzsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHNjc1siUHJvdmlzaW9uaW5nTW9kZSJdID09IDQpIHsgbW9kZSA9ICcgYWN0aXZhdGVkIGluIENsaWVudCBDb250cm9sIE1vZGUgKENDTSknOyBzeXN0ZW1kZWZlbnNlID0gOTsgfQ0KICAgICAgICAgICAgICAgIH0NCg0KDQogICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJJbnRlbCZyZWc7IE1FIiwgInYiICsgZ2V0SXRlbShhbXRsb2dpY2FsZWxlbWVudHMsICJJbnN0YW5jZUlEIiwgIkFNVCIpWyJWZXJzaW9uU3RyaW5nIl0gKyBtb2RlKTsNCg0KICAgICAgICAgICAgfQ0KDQoNCg0KDQogICAgICAgICAgICBRSCgnaWRfY29tcHV0ZXJuYW1lJywgJ0NvbXB1dGVyOiAnICsgKChnc1siSG9zdE5hbWUiXSA9PSAnJykgPyAiPGk+Tm9uZTwvaT4iIDogZ3NbIkhvc3ROYW1lIl0pKTsNCg0KDQoNCg0KICAgICAgICAgICAgLy8gSW50ZWwgQU1UIEZlYXR1cmVzDQogICAgICAgICAgICBpZiAoYW10c3lzc3RhdGVbJ0FNVF9SZWRpcmVjdGlvblNlcnZpY2UnXS5zdGF0dXMgPT0gMjAwKSB7DQogICAgICAgICAgICAgICAgdmFyIHJlZGlyID0gYW10ZmVhdHVyZXNbMF0gPSAoYW10c3lzc3RhdGVbJ0FNVF9SZWRpcmVjdGlvblNlcnZpY2UnXS5yZXNwb25zZVsiTGlzdGVuZXJFbmFibGVkIl0gPT0gdHJ1ZSk7DQogICAgICAgICAgICAgICAgdmFyIHNvbCA9IGFtdGZlYXR1cmVzWzFdID0gKChhbXRzeXNzdGF0ZVsnQU1UX1JlZGlyZWN0aW9uU2VydmljZSddLnJlc3BvbnNlWyJFbmFibGVkU3RhdGUiXSAmIDIpICE9IDApOw0KICAgICAgICAgICAgICAgIHZhciBpZGVyID0gYW10ZmVhdHVyZXNbMl0gPSAoKGFtdHN5c3N0YXRlWydBTVRfUmVkaXJlY3Rpb25TZXJ2aWNlJ10ucmVzcG9uc2VbIkVuYWJsZWRTdGF0ZSJdICYgMSkgIT0gMCk7DQogICAgICAgICAgICAgICAgdmFyIGt2bSA9IGFtdGZlYXR1cmVzWzNdID0gdW5kZWZpbmVkOw0KICAgICAgICAgICAgICAgIGlmICgoYW10dmVyc2lvbiA+IDUpICYmIChhbXRzeXNzdGF0ZVsnQ0lNX0tWTVJlZGlyZWN0aW9uU0FQJ10gIT0gbnVsbCkpIHsNCiAgICAgICAgICAgICAgICAgICAga3ZtID0gYW10ZmVhdHVyZXNbM10gPSAoKGFtdHN5c3N0YXRlWydDSU1fS1ZNUmVkaXJlY3Rpb25TQVAnXS5yZXNwb25zZVsiRW5hYmxlZFN0YXRlIl0gPT0gNiAmJiBhbXRzeXNzdGF0ZVsnQ0lNX0tWTVJlZGlyZWN0aW9uU0FQJ10ucmVzcG9uc2VbIlJlcXVlc3RlZFN0YXRlIl0gPT0gMikgfHwgYW10c3lzc3RhdGVbJ0NJTV9LVk1SZWRpcmVjdGlvblNBUCddLnJlc3BvbnNlWyJFbmFibGVkU3RhdGUiXSA9PSAyIHx8IGFtdHN5c3N0YXRlWydDSU1fS1ZNUmVkaXJlY3Rpb25TQVAnXS5yZXNwb25zZVsiRW5hYmxlZFN0YXRlIl0gPT0gNik7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmIChyZWRpcikgZmVhdHVyZXMgKz0gIiwgUmVkaXJlY3Rpb24gUG9ydCI7DQogICAgICAgICAgICAgICAgaWYgKHNvbCkgZmVhdHVyZXMgKz0gIiwgU2VyaWFsLW92ZXItTEFOIjsNCiAgICAgICAgICAgICAgICBpZiAoaWRlcikgZmVhdHVyZXMgKz0gIiwgSURFLVJlZGlyZWN0IjsNCiAgICAgICAgICAgICAgICBpZiAoa3ZtKSBmZWF0dXJlcyArPSAiLCBLVk0iOw0KICAgICAgICAgICAgICAgIGlmIChmZWF0dXJlcyA9PSAnJykgZmVhdHVyZXMgPSAiICBOb25lIjsNCiAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkFjdGl2ZSBGZWF0dXJlcyIsIGFkZExpbmtDb25kaXRpb25hbChmZWF0dXJlcy5zdWJzdHJpbmcoMiksICdzaG93RmVhdHVyZXNEbGcoKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBpZiAoKGFtdHN5c3N0YXRlWydJUFNfS1ZNUmVkaXJlY3Rpb25TZXR0aW5nRGF0YSddICE9IG51bGwpICYmIChhbXRzeXNzdGF0ZVsnSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEnXS5yZXNwb25zZSkpIHsNCiAgICAgICAgICAgICAgICB2YXIgZGVza3RvcFNldHRpbmdzID0gYW10c3lzc3RhdGVbJ0lQU19LVk1SZWRpcmVjdGlvblNldHRpbmdEYXRhJ10ucmVzcG9uc2U7DQogICAgICAgICAgICAgICAgdmFyIHNjcmVlbm5hbWUgPSAnUHJpbWFyeSBkaXNwbGF5JzsNCiAgICAgICAgICAgICAgICBpZiAoKGFtdHZlcnNpb24gPiA3KSAmJiAoZGVza3RvcFNldHRpbmdzWydEZWZhdWx0U2NyZWVuJ10gIT09IHVuZGVmaW5lZCkgJiYgKGRlc2t0b3BTZXR0aW5nc1snRGVmYXVsdFNjcmVlbiddIDwgMjU1KSkgeyBzY3JlZW5uYW1lID0gWydQcmltYXJ5IGRpc3BsYXknLCAnU2Vjb25kYXJ5IGRpc3BsYXknLCAnM3JkIGRpc3BsYXknXVtkZXNrdG9wU2V0dGluZ3NbJ0RlZmF1bHRTY3JlZW4nXV07IH0NCiAgICAgICAgICAgICAgICBmZWF0dXJlcyA9ICc8c3BhbiB0aXRsZT0iVGhlIGRlZmF1bHQgcmVtb3RlIGRpc3BsYXkgaXMgdGhlICcgKyBzY3JlZW5uYW1lLnRvTG93ZXJDYXNlKCkgKyAnIj4nICsgc2NyZWVubmFtZSArICI8L3NwYW4+IjsNCiAgICAgICAgICAgICAgICBpZiAoZGVza3RvcFNldHRpbmdzWydJczU5MDBQb3J0RW5hYmxlZCddID09IHRydWUpIHsgZmVhdHVyZXMgKz0gIiwgUG9ydCA1OTAwIGVuYWJsZWQiOyB9DQogICAgICAgICAgICAgICAgaWYgKGRlc2t0b3BTZXR0aW5nc1snT3B0SW5Qb2xpY3knXSA9PSB0cnVlKSB7IGZlYXR1cmVzICs9ICIsICIgKyBkZXNrdG9wU2V0dGluZ3NbJ09wdEluUG9saWN5VGltZW91dCddICsgIiBzZWNvbmQiICsgKChkZXNrdG9wU2V0dGluZ3NbJ09wdEluUG9saWN5VGltZW91dCddID4gMCk/J3MnOicnKSArICIgb3B0LWluIjsgfQ0KICAgICAgICAgICAgICAgIGZlYXR1cmVzICs9ICIsICIgKyBkZXNrdG9wU2V0dGluZ3NbJ1Nlc3Npb25UaW1lb3V0J10gKyAiIG1pbnV0ZSIgKyAoKGRlc2t0b3BTZXR0aW5nc1snU2Vzc2lvblRpbWVvdXQnXSA+IDApID8gJ3MnIDogJycpICsgIiBzZXNzaW9uIHRpbWVvdXQiOw0KDQogICAgICAgICAgICAgICAgLy8gU2NyZWVuIGJsYW5raW5nIG9uIEFNVCAxMCBhbmQgaGlnaGVyDQogICAgICAgICAgICAgICAgaWYgKChhbXR2ZXJzaW9uID4gOSkgJiYgKGFtdHN5c3N0YXRlWydJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnXSAhPSBudWxsKSkgew0KICAgICAgICAgICAgICAgICAgICB2YXIgc2NyZWVuQmxhbmtpbmcgPSAoKGFtdHN5c3N0YXRlWydJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnXS5yZXNwb25zZVsiRW5hYmxlZFN0YXRlIl0gJiAxKSAhPSAwKTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHNjcmVlbkJsYW5raW5nKSBmZWF0dXJlcyArPSAiLCBCbGFua2luZyBBbGxvd2VkIjsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIH0NCg0KDQogICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJSZW1vdGUgRGVza3RvcCIsIGFkZExpbmtDb25kaXRpb25hbChmZWF0dXJlcywgJ3Nob3dEZXNrdG9wU2V0dGluZ3NEbGcoKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBJbnRlbCBBTVQgdXNlciBDb25zZW50DQogICAgICAgICAgICBpZiAoKGFtdHZlcnNpb24gPiA1KSAmJiAoYW10c3lzc3RhdGVbJ0lQU19PcHRJblNlcnZpY2UnXSAhPSBudWxsKSAmJiAoYW10c3lzc3RhdGVbJ0lQU19PcHRJblNlcnZpY2UnXS5yZXNwb25zZSAhPSB1bmRlZmluZWQpKSB7DQogICAgICAgICAgICAgICAgZmVhdHVyZXMgPSAiVW5rbm93biBzdGF0ZSI7DQogICAgICAgICAgICAgICAgdmFyIG9wdGlucmVxdWlyZWQgPSBhbXRzeXNzdGF0ZVsnSVBTX09wdEluU2VydmljZSddLnJlc3BvbnNlWyJPcHRJblJlcXVpcmVkIl07DQogICAgICAgICAgICAgICAgaWYgKG9wdGlucmVxdWlyZWQgPT0gMCkgeyBmZWF0dXJlcyA9ICJOb3QgUmVxdWlyZWQiOyB9DQogICAgICAgICAgICAgICAgaWYgKG9wdGlucmVxdWlyZWQgPT0gMSkgeyBmZWF0dXJlcyA9ICJSZXF1aXJlZCBmb3IgS1ZNIG9ubHkiOyB9DQogICAgICAgICAgICAgICAgaWYgKG9wdGlucmVxdWlyZWQgPT0gMHhGRkZGRkZGRikgeyBmZWF0dXJlcyA9ICJBbHdheXMgUmVxdWlyZWQiOyB9DQogICAgICAgICAgICAgICAgaWYgKGFtdHN5c3N0YXRlWydJUFNfT3B0SW5TZXJ2aWNlJ10ucmVzcG9uc2VbIkNhbk1vZGlmeU9wdEluUG9saWN5Il0gPT0gdHJ1ZSkgZmVhdHVyZXMgPSBhZGRMaW5rQ29uZGl0aW9uYWwoZmVhdHVyZXMsICdzaG93Q29uc2VudERsZygpJywgeHhBY2NvdW50QWRtaW5OYW1lKTsgLy8gSWYgd2UgY2FuIG1vZGlmeSB1c2VyIGNvbnNlbnQgc2V0dGluZ3MsIGFkZCB0aGUgbGluayB0byBkbyBpdC4NCiAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIlVzZXIgQ29uc2VudCIsIGZlYXR1cmVzKTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gSW50ZWwgQU1UIFBvd2VyIHBvbGljeQ0KICAgICAgICAgICAgaWYgKEFtdFN5c3RlbVBvd2VyU2NoZW1lcyAhPSBudWxsKSB7DQogICAgICAgICAgICAgICAgdmFyIGVsZW1lbnRTZXR0aW5ncyA9IGFtdHN5c3N0YXRlWydDSU1fRWxlbWVudFNldHRpbmdEYXRhJ10ucmVzcG9uc2VzOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWxlbWVudFNldHRpbmdzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50U2V0dGluZ3NbaV1bJ1NldHRpbmdEYXRhJ10gJiYgZWxlbWVudFNldHRpbmdzW2ldWydJc0N1cnJlbnQnXSA9PSAxICYmIGVsZW1lbnRTZXR0aW5nc1tpXVsnU2V0dGluZ0RhdGEnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydSZXNvdXJjZVVSSSddID09ICdodHRwOi8vaW50ZWwuY29tL3diZW0vd3NjaW0vMS9hbXQtc2NoZW1hLzEvQU1UX1N5c3RlbVBvd2VyU2NoZW1lJykgew0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm91bmQgdGhlIGFjdGl2ZSBJbnRlbCBBTVQgcG93ZXIgc2NoZW1lDQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcG93ZXJndWlkID0gZWxlbWVudFNldHRpbmdzW2ldWydTZXR0aW5nRGF0YSddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ11bMV1bJ1ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3cgZmluZCB0aGUgbmFtZSBvZiB0aGUgcG93ZXIgc2NoZW1hIGluIHRoZSBBTVRfU3lzdGVtUG93ZXJTY2hlbWUgdGFibGUNCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgQW10U3lzdGVtUG93ZXJTY2hlbWVzLmxlbmd0aDsgaisrKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEFtdFN5c3RlbVBvd2VyU2NoZW1lc1tqXVsnU2NoZW1lR1VJRCddID09IHBvd2VyZ3VpZCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3VuZCB0aGUgcG93ZXIgc2NoZW1lIG5hbWUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJQb3dlciBQb2xpY3kiLCBhZGRMaW5rQ29uZGl0aW9uYWwoQW10U3lzdGVtUG93ZXJTY2hlbWVzW2pdWydEZXNjcmlwdGlvbiddLnNwbGl0KCc6JyApWzFdLCAic2hvd1Bvd2VyUG9saWN5RGxnKFwiIiArIHBvd2VyZ3VpZCArICJcIikiLCB4eEFjY291bnRBZG1pbk5hbWUpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIGlmIChhbXRkZWx0YXRpbWUpIHsgeCArPSBUYWJsZUVudHJ5KCJEYXRlICYgVGltZSIsIG5ldyBEYXRlKG5ldyBEYXRlKCkuZ2V0VGltZSgpICsgYW10ZGVsdGF0aW1lKS50b0xvY2FsZVN0cmluZygpKTsgfQ0KICAgICAgICAgICAgdmFyIGJ1dHRvbnMgPSBBZGRSZWZyZXNoQnV0dG9uKCJQdWxsU3lzdGVtU3RhdHVzKCkiKSArICIgIjsNCg0KICAgICAgICAgICAgYnV0dG9ucyArPSBBZGRCdXR0b24oIlNhdmUgU3RhdGUuLi4iLCAic2F2ZUVudGlyZUFtdFN0YXRlKCkiKSArICIgIjsNCg0KICAgICAgICAgICAgYnV0dG9ucyArPSBBZGRCdXR0b24oIlJ1biBTY3JpcHQuLi4iLCAic2NyaXB0X3J1blNjcmlwdERsZygpIikgKyAiICI7DQogICAgICAgICAgICB4ICs9IFRhYmxlRW5kKGJ1dHRvbnMpOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlU3lzU3RhdHVzJywgeCk7DQoNCg0KICAgICAgICAgICAgdmFyIHggPSAiPHRhYmxlIGNsYXNzPWxvZzEgY2VsbHBhZGRpbmc9MCBjZWxsc3BhY2luZz0wIHN0eWxlPXdpZHRoOjEwMCU7Ym9yZGVyLXJhZGl1czo4cHg+IjsNCiAgICAgICAgICAgIHggKz0gVGFibGVFbmQoIjxkaXY+Jm5ic3A7IiArIEFkZFJlZnJlc2hCdXR0b24oIlB1bGxTeXN0ZW1TdGF0dXMoMSkiKQ0KDQogICAgICAgICAgICAgICAgKyAnIENoYW5naW5nIG5ldHdvcmsgc2V0dGluZ3MgbWF5IGNhdXNlIHRoaXMgcGFnZSB0byBiZSB1bmF2YWlsYWJsZSBmb3IgYSBmZXcgc2Vjb25kcy4nDQogICAgICAgICAgICApOw0KDQogICAgICAgICAgICAvLyBHZW5lcmFsIHNldHRpbmdzDQogICAgICAgICAgICB4ICs9ICI8YnI+PGgyPkdlbmVyYWwgU2V0dGluZ3M8L2gyPiI7DQogICAgICAgICAgICB4ICs9IFRhYmxlU3RhcnQoKTsNCg0KICAgICAgICAgICAgLy8gTmV0d29yayBzdGF0ZQ0KICAgICAgICAgICAgLy8gaWYgKGdzWyJBTVROZXR3b3JrRW5hYmxlZCJdKSB7IHggKz0gVGFibGVFbnRyeSgiTmV0d29yayBzdGF0ZSIsIChnc1siQU1UTmV0d29ya0VuYWJsZWQiXT09MSk/IkVuYWJsZWQiOiJEaXNhYmxlZCIpOyB9DQoNCiAgICAgICAgICAgIC8vIFNoYXJlZCBGUURODQogICAgICAgICAgICB2YXIgZnFkbnNoYXJlID0gJyc7DQogICAgICAgICAgICBpZiAoaG9zdCAhPSAiPGk+Tm9uZTwvaT4iKSB7DQogICAgICAgICAgICAgICAgaWYgKGdzWyJTaGFyZWRGUUROIl0gPT0gdHJ1ZSkgZnFkbnNoYXJlID0gJywgc2hhcmVkIHdpdGggT1MnOw0KICAgICAgICAgICAgICAgIGlmIChnc1siU2hhcmVkRlFETiJdID09IGZhbHNlKSBmcWRuc2hhcmUgPSAnLCBkaWZmZXJlbnQgZnJvbSBPUyc7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIk5hbWUgJiBEb21haW4iLCBhZGRMaW5rQ29uZGl0aW9uYWwoaG9zdCArIGZxZG5zaGFyZSwgJ3Nob3dFZGl0TmFtZURsZygxKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KDQogICAgICAgICAgICAvLyBEeW5hbWljIEROUw0KICAgICAgICAgICAgdmFyIGRkbnMgPSAnRGlzYWJsZWQnOw0KICAgICAgICAgICAgaWYgKGdzWyJERE5TVXBkYXRlRW5hYmxlZCJdID09IHRydWUpIHsNCiAgICAgICAgICAgICAgICBkZG5zID0gIkVuYWJsZWQgZWFjaCAiICsgZ3NbIkRETlNQZXJpb2RpY1VwZGF0ZUludGVydmFsIl0gKyAiIG1pbnV0ZXMsIFRUTCBpcyAiICsgZ3NbIkRETlNUVEwiXSArICIgbWludXRlcyI7DQogICAgICAgICAgICB9IGVsc2UgaWYgKGdzWyJERE5TVXBkYXRlQnlESENQU2VydmVyRW5hYmxlZCJdID09IHRydWUpIHsNCiAgICAgICAgICAgICAgICBkZG5zID0gIlVwZGF0ZSBieSBESENQIHNlcnZlciI7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkR5bmFtaWMgRE5TIiwgYWRkTGlua0NvbmRpdGlvbmFsKGRkbnMsICdzaG93RWRpdERuc0RsZygpJywgeHhBY2NvdW50QWRtaW5OYW1lKSk7DQogICAgICAgICAgICB4ICs9IFRhYmxlRW5kKCk7DQoNCiAgICAgICAgICAgIGZvciAodmFyIHkgaW4gYW10c3lzc3RhdGVbJ0FNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyddLnJlc3BvbnNlcykgew0KICAgICAgICAgICAgICAgIHZhciB6ID0gYW10c3lzc3RhdGVbJ0FNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyddLnJlc3BvbnNlc1t5XTsNCiAgICAgICAgICAgICAgICBpZiAoelsnV0xBTkxpbmtQcm90ZWN0aW9uTGV2ZWwnXSB8fCAoeSA9PSAxKSkgeyBhbXR3aXJlbGVzc2lmID0geTsgfSAvLyBTZXQgdGhlIHdpcmVsZXNzIGludGVyZmFjZSwgdGhpcyBzZWVtcyB0byBjb3ZlciBuZXcgd2lyZWxlc3Mgb25seSBjb21wdXRlcnMgYW5kIG9sZGVyIGNvbXB1dGVycyB3aXRoIGR1YWwgaW50ZXJmYWNlcy4NCiAgICAgICAgICAgICAgICBpZiAoKHkgPT0gMCkgJiYgKGFtdHdpcmVsZXNzaWYgIT0geSkgJiYgKHpbIk1BQ0FkZHJlc3MiXSA9PSAiMDAtMDAtMDAtMDAtMDAtMDAiKSkgeyBjb250aW51ZTsgfSAvLyBPbiBjb21wdXRlcnMgd2l0aCBvbmx5IHdpcmVsZXNzLCB0aGUgd2lyZWQgaW50ZXJmYWNlIHdpbGwgaGF2ZSBhIG51bGwgTUFDLCBza2lwIGl0Lg0KICAgICAgICAgICAgICAgIGlmICh5ID09IDApIHN5c3RlbWRlZmVuc2UrKzsNCiAgICAgICAgICAgICAgICB4ICs9ICI8YnI+PGgyPiIgKyAoKGFtdHdpcmVsZXNzaWYgPT0geSk/J1dpcmVsZXNzJzonV2lyZWQnKSArICIgSW50ZXJmYWNlPC9oMj4iOw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVTdGFydCgpOw0KDQogICAgICAgICAgICAgICAgLyoNCiAgICAgICAgICAgICAgICB2YXIgbHAgPSBbXSwgbGlua3BvbGljeSA9IE1ha2VUb0FycmF5KHpbIkxpbmtQb2xpY3kiXSk7DQogICAgICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBsaW5rcG9saWN5KSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBhcCA9IGxpbmtwb2xpY3lbcF07DQogICAgICAgICAgICAgICAgICAgIGlmIChhcCA9PSAxKSBscC5wdXNoKCJTMC9BQyIpOw0KICAgICAgICAgICAgICAgICAgICBpZiAoYXAgPT0gMTQpIGxwLnB1c2goIlN4L0FDIik7DQogICAgICAgICAgICAgICAgICAgIGlmIChhcCA9PSAxNikgbHAucHVzaCgiUzAvREMiKTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGFwID09IDIyNCkgbHAucHVzaCgiU3gvREMiKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJMaW5rIHN0YXRlIiwgKHpbIkxpbmtJc1VwIl0gPT0gdHJ1ZT8nTGluayBpcyB1cCc6J0xpbmsgaXMgZG93bicpICsgIiwgYXZhaWxhYmxlIGluICIgKyBscC5qb2luKCcsICcpKTsNCiAgICAgICAgICAgICAgICAqLw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiTGluayBzdGF0ZSIsICh6WyJMaW5rSXNVcCJdID09IHRydWU/J0xpbmsgaXMgdXAnOidMaW5rIGlzIGRvd24nKSk7DQogICAgICAgICAgICAgICAgaWYgKHpbIk1BQ0FkZHJlc3MiXSAhPSAiMDAtMDAtMDAtMDAtMDAtMDAiKSB7IHggKz0gVGFibGVFbnRyeSgiTUFDIGFkZHJlc3MiLCB6WyJNQUNBZGRyZXNzIl0pOyB9DQoNCg0KICAgICAgICAgICAgICAgIGlmICgoYW10d2lyZWxlc3NpZiA9PSB5KSAmJiB4eFdpcmVsZXNzICYmIHh4V2lyZWxlc3NbJ0NJTV9XaUZpUG9ydENhcGFiaWxpdGllcyddLnJlc3BvbnNlKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIFN0YXJ0IGFuZCBzdGF0ZQ0KICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIlN0YXRlIiwgYWRkTGlua0NvbmRpdGlvbmFsKHh4V2lmaVN0YXRlW3h4V2lyZWxlc3NbJ0NJTV9XaUZpUG9ydCddLnJlc3BvbnNlWyJFbmFibGVkU3RhdGUiXV0sICdzaG93V2lmaVN0YXRlRGxnKCknLCB4eEFjY291bnRBZG1pbk5hbWUpKTsNCiAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIC8qIFRoaXMgaXMgbm90IHRoYXQgdXNlZnVsDQogICAgICAgICAgICAgICAgICAgIC8vIENhcGFiaWxpdGllcw0KICAgICAgICAgICAgICAgICAgICB2YXIgcyA9ICcnLCBzYyA9IHh4V2lyZWxlc3NbJ0NJTV9XaUZpUG9ydENhcGFiaWxpdGllcyddLnJlc3BvbnNlLCBzdXBwb3J0ZWRUeXBlcyA9IHNjWyJTdXBwb3J0ZWRQb3J0VHlwZXMiXTsNCiAgICAgICAgICAgICAgICAgICAgZm9yIChpIGluIHN1cHBvcnRlZFR5cGVzKSB7IHMgKz0gIiwgODAyLjExIiArICJhYmduIltzdXBwb3J0ZWRUeXBlc1tpXSAtIDcwXTsgfQ0KICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkNhcGFiaWxpdGVzIiwgcy5zdWJzdHJpbmcoMikpOw0KICAgICAgICAgICAgICAgICAgICAqLw0KDQogICAgICAgICAgICAgICAgICAgIC8vIEN1cnJlbnQgcmFkaW8gc3RhdGUNCiAgICAgICAgICAgICAgICAgICAgcyA9IHh4V2lyZWxlc3NbJ0NJTV9XaUZpRW5kcG9pbnQnXS5yZXNwb25zZVsnTEFOSUQnXTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJSYWRpbyBTdGF0ZSIsIHh4UmFkaW9TdGF0ZVt4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50J10ucmVzcG9uc2VbJ0VuYWJsZWRTdGF0ZSddXSArICIsIFNTSUQ6ICIgKyAocz9zOiI8aT5Ob25lPC9pPiIpKTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICBpZiAoYW10d2lyZWxlc3NpZiAhPSB5KSB7DQogICAgICAgICAgICAgICAgICAgIC8vIFRoaW5ncyB0aGF0IGFyZSBzcGVjaWZpYyB0byB0aGUgd2lyZWQgaW50ZXJmYWNlDQogICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiUmVzcG9uZCB0byBwaW5nIiwgYWRkTGlua0NvbmRpdGlvbmFsKFsiRGlzYWJsZWQiLCJJQ01QIHJlc3BvbnNlIiwiUk1DUCByZXNwb25zZSIsIklDTVAgJiBSTUNQIHJlc3BvbnNlIl1bZ3NbIlBpbmdSZXNwb25zZUVuYWJsZWQiXSArIChnc1siUm1jcFBpbmdSZXNwb25zZUVuYWJsZWQiXSA8PCAxKV0sICJzaG93UGluZ0FjdGlvbkRsZygpIiwgeHhBY2NvdW50QWRtaW5OYW1lKSk7DQogICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiSVB2NCBzdGF0ZSIsIGFkZExpbmtDb25kaXRpb25hbCh6WyJESENQRW5hYmxlZCJdID09IHRydWU/IkF1dG9tYXRpYyB1c2luZyBESENQIHNlcnZlciI6IlN0YXRpYyBJUCBhZGRyZXNzIiwgInNob3dJUFNldHVwRGxnKCkiLCB4eEFjY291bnRBZG1pbk5hbWUpKTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAvLyBEaXNwbGF5IElQdjQgY3VycmVudCBzZXR0aW5ncw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiSVB2NCBhZGRyZXNzIiwgaXNJcEFkZHJlc3MoelsiSVBBZGRyZXNzIl0sIk5vbmUiKSk7DQogICAgICAgICAgICAgICAgaWYgKGlzSXBBZGRyZXNzKHpbIkRlZmF1bHRHYXRld2F5Il0pKSB7IHggKz0gVGFibGVFbnRyeSgiSVB2NCBnYXRld2F5IC8gTWFzayIsIHpbIkRlZmF1bHRHYXRld2F5Il0gKyAiIC8gIiArIGlzSXBBZGRyZXNzKHpbIlN1Ym5ldE1hc2siXSwiTm9uZSIpKTsgfQ0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIHZhciBkbnMgPSB6WyJQcmltYXJ5RE5TIl07DQogICAgICAgICAgICAgICAgaWYgKGlzSXBBZGRyZXNzKGRucykpIHsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHpbIlNlY29uZGFyeUROUyJdKSBkbnMgKz0gIiAvICIgKyB6WyJTZWNvbmRhcnlETlMiXTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJJUHY0IGRvbWFpbiBuYW1lIHNlcnZlciIsIGRucyk7DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgaWYgKChhbXRzeXNzdGF0ZVsnSVBTX0lQdjZQb3J0U2V0dGluZ3MnXS5zdGF0dXMgPT0gMjAwKSAmJiAoYW10dmVyc2lvbiA+IDUpKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIElQdjYgaXMgZW5hYmxlZCBmb3IgdGhpcyBpbnRlcmZhY2UNCiAgICAgICAgICAgICAgICAgICAgdmFyIHp6ID0gYW10c3lzc3RhdGVbJ0lQU19JUHY2UG9ydFNldHRpbmdzJ10ucmVzcG9uc2VzW3ldOw0KICAgICAgICAgICAgICAgICAgICB2YXIgaXB2NnN0YXRlID0gJ0Rpc2FibGVkJywgaXB2NiwgaXB2Nm1hbnVhbCwgZWxlbWVudFNldHRpbmdzID0gYW10c3lzc3RhdGVbJ0NJTV9FbGVtZW50U2V0dGluZ0RhdGEnXS5yZXNwb25zZXM7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWxlbWVudFNldHRpbmdzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudFNldHRpbmdzW2ldWydTZXR0aW5nRGF0YSddICYmIGVsZW1lbnRTZXR0aW5nc1tpXVsnU2V0dGluZ0RhdGEnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddWydWYWx1ZSddID09ICdJbnRlbChyKSBJUFMgSVB2NiBTZXR0aW5ncyAnICsgeSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlwdjYgPSAoZWxlbWVudFNldHRpbmdzW2ldWydJc0N1cnJlbnQnXSA9PSAxKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIG1hbnVhbCBhZGRyZXNzZXMgaGF2ZSBiZWVuIGFkZGVkDQogICAgICAgICAgICAgICAgICAgIGlmIChpcHY2ID09IHRydWUpIHsgDQogICAgICAgICAgICAgICAgICAgICAgICBpcHY2bWFudWFsID0gaXNJcEFkZHJlc3MoenpbIklQdjZBZGRyZXNzIl0pIHx8IGlzSXBBZGRyZXNzKHp6WyJEZWZhdWx0Um91dGVyIl0pIHx8IGlzSXBBZGRyZXNzKHp6WyJQcmltYXJ5RE5TIl0pIHx8IGlzSXBBZGRyZXNzKHp6WyJTZWNvbmRhcnlETlMiXSk7DQogICAgICAgICAgICAgICAgICAgICAgICBpcHY2c3RhdGUgPSAnRW5hYmxlZCwgQXV0b21hdGljICcgKyAoaXB2Nm1hbnVhbD8iJiBtYW51YWwiOiIiKSArICIgYWRkcmVzc2VzIjsNCiAgICAgICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgICAgIC8vIERpc3BsYXkgSVB2NiBjdXJyZW50IHNldHRpbmdzDQogICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiSVB2NiBzdGF0ZSIsIGFkZExpbmtDb25kaXRpb25hbChpcHY2c3RhdGUsICJzaG93SVB2NlN0YXRlRGxnKCIgKyB5ICsgIiwiICsgaXB2NiArICIpIiwgeHhBY2NvdW50QWRtaW5OYW1lKSk7DQogICAgICAgICAgICAgICAgICAgIGlmIChpcHY2ID09IHRydWUpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh6elsiQ3VycmVudEFkZHJlc3NJbmZvIl0gJiYgenpbIkN1cnJlbnRBZGRyZXNzSW5mbyJdLmxlbmd0aCA+IDApIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB6elsiQ3VycmVudEFkZHJlc3NJbmZvIl0gPSBNYWtlVG9BcnJheSh6elsiQ3VycmVudEFkZHJlc3NJbmZvIl0pOyAvLyBCZWNhdXNlIG91ciBXU01BTiBzdGFjayBkb2VzIG5vdCBrbm93IGlmIHRoaXMgaXMgYSBhcnJheSwgd2UgbmVlZCB0byBtYWtlIGl0IGFuIGFycmF5IGlmIGl0IGNvbnRhaW5zIDEgZWxlbWVudC4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcHY2YWRkciA9ICcnOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgenpbIkN1cnJlbnRBZGRyZXNzSW5mbyJdLmxlbmd0aDsgaSsrKSB7IGlmIChpcHY2YWRkci5sZW5ndGggPiAwKSBpcHY2YWRkciArPSAiLCAiOyBpcHY2YWRkciArPSB6elsiQ3VycmVudEFkZHJlc3NJbmZvIl1baV0uc3BsaXQoJywnKVswXTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiSVB2NiBhZGRyZXNzIiwgYWRkTGluayhpcHY2YWRkciwgInNob3dJUHY2QWRkckRsZygiICsgeSArICIsXCIiICsgenpbIkN1cnJlbnRBZGRyZXNzSW5mbyJdICsgIlwiKSIpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJJUHY2IGFkZHJlc3MiLCAnTm9uZScpOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzSXBBZGRyZXNzKHp6WyJDdXJyZW50RGVmYXVsdFJvdXRlciJdKSkgeyB4ICs9IFRhYmxlRW50cnkoIklQdjYgZGVmYXVsdCByb3V0ZXIiLCB6elsiQ3VycmVudERlZmF1bHRSb3V0ZXIiXSk7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0lwQWRkcmVzcyh6elsiQ3VycmVudFByaW1hcnlETlMiXSkpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZG5zID0genpbIkN1cnJlbnRQcmltYXJ5RE5TIl07DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzSXBBZGRyZXNzKHp6WyJDdXJyZW50U2Vjb25kYXJ5RE5TIl0pKSBkbnMgKz0gIiAvICIgKyB6elsiQ3VycmVudFNlY29uZGFyeUROUyJdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiSVB2NiBkb21haW4gbmFtZSBzZXJ2ZXIiLCBkbnMpOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBPbmx5IGRvIG1vcmUgV1NNQU4gaWYgd2UgbmVlZCBpdA0KICAgICAgICAgICAgaWYgKCh1cmx2YXJzWydrdm1vbmx5J10gIT0gMSkgJiYgKGZ1bGxzY3JlZW5vbmx5ID09IGZhbHNlKSkgew0KDQogICAgICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgYSB3aXJlbGVzcyBpbnRlcmZhY2UsIGdldCB0aGUgZGF0YSBmb3IgaXQuIElmIG5vdCwgc2hvdyB0aGF0IHRoZXJlIGlzIG5vdC4NCiAgICAgICAgICAgICAgICBpZiAoYW10d2lyZWxlc3NpZiAhPSAtMSkgeyBpZiAoKGFtdEZpcnN0UHVsbCAmIDIpID09IDApIFB1bGxXaXJlbGVzcygpOyB9DQogICAgICAgICAgICAgICAgUUgoJ2lkX1RhYmxlTmV0d29ya1NldHRpbmdzU3BhbicsIHgpOw0KDQoNCiAgICAgICAgICAgICAgICAvLyBJZiBpbiBBQ00gbW9kZSBhbmQgd2UgaGF2ZSBhIHdpcmVkIGludGVyZmFjZSwgcHVsbCBTeXN0ZW0gRGVmZW5zZSBpbmZvcm1hdGlvbg0KICAgICAgICAgICAgICAgIGlmICgoc3lzdGVtZGVmZW5zZSA9PSAxKSAmJiAoKGFtdEZpcnN0UHVsbCAmIDQpID09IDApKSBQdWxsU3lzdGVtRGVmZW5zZSgpOw0KDQoNCiAgICAgICAgICAgICAgICBpZiAoKChhbXRGaXJzdFB1bGwgJiA4KSA9PSAwKSAmJiAoYW10dmVyc2lvbiA+IDExIHx8IChhbXR2ZXJzaW9uID09IDExICYmIGFtdHZlcnNpb25taW4gPiA1KSkpIHsgUHVsbFN0b3JhZ2UoKTsgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBpZiAoY3VycmVudFZpZXcgPT0gMCkgZ28oMSwgMSk7IC8vIElmIHdlIGFyZSBhdCB0aGUgbG9hZGluZyBzY3JlZW4sIG1vc3QgdG8gU3lzdGVtIFN0YXR1cyBzY3JlZW4NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGlzSXBBZGRyZXNzKHQsIHgpIHsgcmV0dXJuICh0ICYmIHQgIT0gbnVsbCAmJiB0Lmxlbmd0aCA+IDAgJiYgdCAhPSAnOjonICYmIHQgIT0gJzo6MCcpP3Q6eDsgfQ0KDQoNCiAgICAgICAgdmFyIEludGVsQW10RW50aXJlU3RhdGU7DQogICAgICAgIHZhciBJbnRlbEFtdEVudGlyZVN0YXRlQ2FsbHM7DQogICAgICAgIGZ1bmN0aW9uIHNhdmVFbnRpcmVBbXRTdGF0ZSgpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBuID0gJycsIGQgPSBuZXcgRGF0ZSgpOw0KICAgICAgICAgICAgaWYgKGFtdHN5c3N0YXRlKSB7IG4gPSAiLSIgKyBhbXRzeXNzdGF0ZVsnQU1UX0dlbmVyYWxTZXR0aW5ncyddLnJlc3BvbnNlWydIb3N0TmFtZSddOyB9DQogICAgICAgICAgICBuICs9ICctJyArIGQuZ2V0RnVsbFllYXIoKSArICItIiArICgiMCIrKGQuZ2V0TW9udGgoKSsxKSkuc2xpY2UoLTIpICsgIi0iICsgKCIwIiArIGQuZ2V0RGF0ZSgpKS5zbGljZSgtMikgKyAiLSIgKyAoIjAiICsgZC5nZXRIb3VycygpKS5zbGljZSgtMikgKyAiLSIgKyAoIjAiICsgZC5nZXRNaW51dGVzKCkpLnNsaWNlKC0yKTs7DQogICAgICAgICAgICBpZHhfZDE5c2F2ZXN0YXRlZmlsZW5hbWUudmFsdWUgPSAnYW10c3RhdGUnICsgbiArICcuanNvbic7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDE5LCAiU2F2ZSBFbnRpcmUgSW50ZWwmcmVnOyBBTVQgU3RhdGUiLCAzLCBzYXZlRW50aXJlQW10U3RhdGVPayk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzYXZlRW50aXJlQW10U3RhdGVPaygpIHsNCiAgICAgICAgICAgIEludGVsQW10RW50aXJlU3RhdGUgPSB7ICd3ZWJhcHB2ZXJzaW9uJzp2ZXJzaW9uLCdsb2NhbHRpbWUnOkRhdGUoKSwndXRjdGltZSc6bmV3IERhdGUoKS50b1VUQ1N0cmluZygpLCdpc290aW1lJzpuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkgfTsNCiAgICAgICAgICAgIFFIKCdpZF9kaWFsb2dNZXNzYWdlJywgJ0ZldGNoaW5nIGVudGlyZSBzdGF0ZSwgcGxlYXNlIHdhaXQuLi4nKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMSwgIlNhdmUgRW50aXJlIEludGVsJnJlZzsgQU1UIFN0YXRlIiwgMCwgbnVsbCk7DQoNCiAgICAgICAgICAgIC8vIEZldGNoIGV2ZXJ5dGhpbmchDQogICAgICAgICAgICBJbnRlbEFtdEVudGlyZVN0YXRlQ2FsbHMgPSAzOw0KICAgICAgICAgICAgYW10c3RhY2suQmF0Y2hFbnVtKG51bGwsIEFsbFdzbWFuLCBzYXZlRW50aXJlQW10U3RhdGVPazIsIG51bGwsIHRydWUpOw0KICAgICAgICAgICAgYW10c3RhY2suR2V0QXVkaXRMb2coc2F2ZUVudGlyZUFtdFN0YXRlT2szKTsNCiAgICAgICAgICAgIGFtdHN0YWNrLkdldE1lc3NhZ2VMb2coc2F2ZUVudGlyZUFtdFN0YXRlT2s0KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNhdmVFbnRpcmVBbXRTdGF0ZU9rMihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsgSW50ZWxBbXRFbnRpcmVTdGF0ZVsnd3NtYW5lbnVtcyddID0gcmVzcG9uc2VzOyBzYXZlRW50aXJlQW10U3RhdGVEb25lKCk7IH0NCiAgICAgICAgZnVuY3Rpb24gc2F2ZUVudGlyZUFtdFN0YXRlT2szKHN0YWNrLCBtZXNzYWdlcykgeyBJbnRlbEFtdEVudGlyZVN0YXRlWydhdWRpdGxvZyddID0gbWVzc2FnZXM7IHNhdmVFbnRpcmVBbXRTdGF0ZURvbmUoKTsgfQ0KICAgICAgICBmdW5jdGlvbiBzYXZlRW50aXJlQW10U3RhdGVPazQoc3RhY2ssIG1lc3NhZ2VzKSB7IEludGVsQW10RW50aXJlU3RhdGVbJ2V2ZW50bG9nJ10gPSBtZXNzYWdlczsgc2F2ZUVudGlyZUFtdFN0YXRlRG9uZSgpOyB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2F2ZUVudGlyZUFtdFN0YXRlRG9uZSgpIHsNCiAgICAgICAgICAgIGlmICgtLUludGVsQW10RW50aXJlU3RhdGVDYWxscyAhPSAwKSByZXR1cm47DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKCk7DQoNCiAgICAgICAgICAgIHNhdmVBcyhkYXRhMmJsb2IoSlNPTi5zdHJpbmdpZnkoSW50ZWxBbXRFbnRpcmVTdGF0ZSwgbnVsbCwgJyAgJykucmVwbGFjZSgvXG4vZywgJ1xyXG4nKSksIGlkeF9kMTlzYXZlc3RhdGVmaWxlbmFtZS52YWx1ZSk7DQogICAgICAgIH0NCg0KDQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0Rlc2t0b3BTZXR0aW5nc0RsZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBkZXNrdG9wU2V0dGluZ3MgPSBhbXRzeXNzdGF0ZVsnSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEnXS5yZXNwb25zZTsNCiAgICAgICAgICAgIHZhciB4ID0gJzxkaXYgc3R5bGU9dGV4dC1hbGlnbjpsZWZ0Pic7DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxzZWxlY3QgaWQ9c3ViZGRpc3BsYXkgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHg+PG9wdGlvbiB2YWx1ZT0wPlByaW1hcnkgZGlzcGxheTwvb3B0aW9uPjxvcHRpb24gdmFsdWU9MT5TZWNvbmRhcnkgZGlzcGxheTwvb3B0aW9uPiI7DQogICAgICAgICAgICBpZiAoYW10dmVyc2lvbiA+IDkpIHsgeCArPSAiPG9wdGlvbiB2YWx1ZT0yPjNyZCBkaXNwbGF5PC9vcHRpb24+IjsgfQ0KICAgICAgICAgICAgeCArPSAiPC9zZWxlY3Q+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+RGVmYXVsdCBkaXNwbGF5PC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IGlkPXN1YnNlc3Npb250aW1lb3V0IHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IG1heGxlbmd0aD01IG9ua2V5cHJlc3M9J3JldHVybiBudW1iZXJzT25seShldmVudCknPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PlNlc3Npb24gdGltZW91dCAoTWludXRlcyk8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgaWYgKGRlc2t0b3BTZXR0aW5nc1snT3B0SW5Qb2xpY3knXSA9PSB0cnVlKSB7IHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IGlkPXN1Ym9wdGludGltZW91dCBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBtYXhsZW5ndGg9NSBvbmtleXByZXNzPSdyZXR1cm4gbnVtYmVyc09ubHkoZXZlbnQpJz48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5PcHQtaW4gdGltZW91dCAoU2Vjb25kcyk8L2Rpdj48L2Rpdj4iOyB9DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxzZWxlY3QgaWQ9c3ViZGxlZ2FjeSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBvbmNoYW5nZT1zaG93RGVza3RvcFNldHRpbmdzRGxnVXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT0wPkRpc2FibGVkLCBSZWNvbW1lbmRlZDwvb3B0aW9uPjxvcHRpb24gdmFsdWU9MT5FbmFibGVkLCBMZWdhY3kgS1ZNIHZpZXdlcnM8L29wdGlvbj48L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5Qb3J0IDU5MDA8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweCBpZD1zdWJzcGFzc3g+PGlucHV0IGlkPXN1YnNwYXNzIHR5cGU9cGFzc3dvcmQgYXV0b2NvbXBsZXRlPW9mZiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBtYXhsZW5ndGg9OCBvbmtleXVwPXNob3dEZXNrdG9wU2V0dGluZ3NEbGdVcGRhdGUoKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD41OTAwIHBhc3N3b3JkICg4IGNoYXJzKTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICBpZiAoKGFtdHZlcnNpb24gPiA5KSAmJiAoYW10c3lzc3RhdGVbJ0lQU19TY3JlZW5Db25maWd1cmF0aW9uU2VydmljZSddICE9IG51bGwpKSB7IHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PHNlbGVjdCBpZD1zdWJzYiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBvbmNoYW5nZT1zaG93RGVza3RvcFNldHRpbmdzRGxnVXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT0wPkRpc2FibGVkPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT0xPkVuYWJsZWQ8L29wdGlvbj48L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweCB0aXRsZT0nVGhpcyBmZWF0dXJlIGlzIG5vdCBvZnRlbiBzdXBwb3J0ZWQnPlNjcmVlbiBCbGFua2luZzwvZGl2PjwvZGl2PiI7IH0NCiAgICAgICAgICAgIHggKz0gIjwvZGl2PiI7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiUmVtb3RlIERlc2t0b3AgU2V0dGluZ3MiLCAzLCBzaG93RGVza3RvcFNldHRpbmdzRGxnT2ssIHgpOw0KICAgICAgICAgICAgUSgnc3ViZGRpc3BsYXknKS52YWx1ZSA9IGRlc2t0b3BTZXR0aW5nc1snRGVmYXVsdFNjcmVlbiddOw0KICAgICAgICAgICAgUSgnc3Vic2Vzc2lvbnRpbWVvdXQnKS52YWx1ZSA9IGRlc2t0b3BTZXR0aW5nc1snU2Vzc2lvblRpbWVvdXQnXTsNCiAgICAgICAgICAgIGlmIChkZXNrdG9wU2V0dGluZ3NbJ09wdEluUG9saWN5J10gPT0gdHJ1ZSkgeyBRKCdzdWJvcHRpbnRpbWVvdXQnKS52YWx1ZSA9IGRlc2t0b3BTZXR0aW5nc1snT3B0SW5Qb2xpY3lUaW1lb3V0J107IH0NCiAgICAgICAgICAgIFEoJ3N1YmRsZWdhY3knKS52YWx1ZSA9ICgoZGVza3RvcFNldHRpbmdzWydJczU5MDBQb3J0RW5hYmxlZCddID09IHRydWUpID8gMSA6IDApOw0KICAgICAgICAgICAgaWYgKChhbXR2ZXJzaW9uID4gOSkgJiYgKGFtdHN5c3N0YXRlWydJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnXSAhPSBudWxsKSkgeyBRKCdzdWJzYicpLnZhbHVlID0gYW10c3lzc3RhdGVbJ0lQU19TY3JlZW5Db25maWd1cmF0aW9uU2VydmljZSddLnJlc3BvbnNlWyJFbmFibGVkU3RhdGUiXTsgfQ0KICAgICAgICAgICAgc2hvd0Rlc2t0b3BTZXR0aW5nc0RsZ1VwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0Rlc2t0b3BTZXR0aW5nc0RsZ1VwZGF0ZSgpIHsNCiAgICAgICAgICAgIFFWKCdzdWJzcGFzc3gnLCAoUSgnc3ViZGxlZ2FjeScpLnZhbHVlID09IDEpKTsNCiAgICAgICAgICAgIHZhciBvayA9ICgoUSgnc3ViZGxlZ2FjeScpLnZhbHVlID09IDApIHx8IChRKCdzdWJzcGFzcycpLnZhbHVlLmxlbmd0aCA9PSA4KSB8fCAoUSgnc3Vic3Bhc3MnKS52YWx1ZS5sZW5ndGggPT0gMCkpICYmIChRKCdzdWJzZXNzaW9udGltZW91dCcpLnZhbHVlLmxlbmd0aCA+IDApOw0KICAgICAgICAgICAgaWYgKChhbXRzeXNzdGF0ZVsnSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEnXS5yZXNwb25zZVsnT3B0SW5Qb2xpY3knXSA9PSB0cnVlKSAmJiAoUSgnc3Vib3B0aW50aW1lb3V0JykudmFsdWUubGVuZ3RoID09IDApKSB7IG9rID0gZmFsc2U7IH0NCiAgICAgICAgICAgIFFFKCdpZHhfZGxnT2tCdXR0b24nLCBvayk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93RGVza3RvcFNldHRpbmdzRGxnT2soKSB7DQogICAgICAgICAgICB2YXIgeCA9IENsb25lKGFtdHN5c3N0YXRlWydJUFNfS1ZNUmVkaXJlY3Rpb25TZXR0aW5nRGF0YSddLnJlc3BvbnNlKTsNCiAgICAgICAgICAgIHhbJ0RlZmF1bHRTY3JlZW4nXSA9IFEoJ3N1YmRkaXNwbGF5JykudmFsdWUNCiAgICAgICAgICAgIHhbJ1Nlc3Npb25UaW1lb3V0J10gPSBRKCdzdWJzZXNzaW9udGltZW91dCcpLnZhbHVlOw0KICAgICAgICAgICAgeFsnSXM1OTAwUG9ydEVuYWJsZWQnXSA9IChRKCdzdWJkbGVnYWN5JykudmFsdWUgPT0gMSk7DQogICAgICAgICAgICBpZiAoeFsnT3B0SW5Qb2xpY3knXSA9PSB0cnVlKSB7IHhbJ09wdEluUG9saWN5VGltZW91dCddID0gUSgnc3Vib3B0aW50aW1lb3V0JykudmFsdWU7IH0NCiAgICAgICAgICAgIGlmICh4WydJczU5MDBQb3J0RW5hYmxlZCddID09IHRydWUpIHsgeFsnUkZCUGFzc3dvcmQnXSA9IFEoJ3N1YnNwYXNzJykudmFsdWU7IH0NCiAgICAgICAgICAgIGFtdHN0YWNrLlB1dCgnSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEnLCB4LCBzaG93RGVza3RvcFNldHRpbmdzRGxnT2syKTsNCg0KICAgICAgICAgICAgLy8gU2NyZWVuIGJsYW5raW5nDQogICAgICAgICAgICB2YXIgeSA9IENsb25lKGFtdHN5c3N0YXRlWydJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnXS5yZXNwb25zZSk7DQogICAgICAgICAgICB5WydFbmFibGVkU3RhdGUnXSA9IHBhcnNlSW50KFEoJ3N1YnNiJykudmFsdWUpOw0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCdJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnLCB5LCBzaG93RGVza3RvcFNldHRpbmdzRGxnT2szKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dEZXNrdG9wU2V0dGluZ3NEbGdPazIoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCkgUHVsbFN5c3RlbVN0YXR1cygpOyBlbHNlIG1lc3NhZ2Vib3goIlJlbW90ZSBEZXNrdG9wIFNldHRpbmdzIiwgIkVycm9yICIgKyBzdGF0dXMgKyAiLCB1bmFibGUgdG8gc2V0IHZhbHVlcy4iKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dEZXNrdG9wU2V0dGluZ3NEbGdPazMoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goIkVycm9yIiwgIlNjcmVlbiBCbGFua2luZyBjb3VsZCBub3QgYmUgc2V0LCBibGFua2luZyBtYXkgbm90IGJlIHN1cHBvcnRlZCBvbiB0aGlzIHN5c3RlbSAoIiArIHN0YXR1cyArICIpLiIpOyByZXR1cm47IH0NCiAgICAgICAgICAgIGFtdHN0YWNrLkdldCgiSVBTX1NjcmVlbkNvbmZpZ3VyYXRpb25TZXJ2aWNlIiwgZnVuY3Rpb24gKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgYW10c3lzc3RhdGVbJ0lQU19TY3JlZW5Db25maWd1cmF0aW9uU2VydmljZSddLnJlc3BvbnNlID0gcmVzcG9uc2UuQm9keTsgdXBkYXRlU3lzdGVtU3RhdHVzKCk7IH0NCiAgICAgICAgICAgIH0sIDAsIDEpOw0KICAgICAgICB9DQoNCg0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gRVZFTlQgTE9HIFBBTkVMDQogICAgICAgIC8vDQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbEV2ZW50TG9nKGJ1dHRvbikgew0KICAgICAgICAgICAgaWYgKGJ1dHRvbiA9PSAxICYmIHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgYW10Rmlyc3RQdWxsIHw9IDE2Ow0KICAgICAgICAgICAgYW10c3RhY2suRW51bSgiQU1UX01lc3NhZ2VMb2ciLCBwcm9jZXNzTWVzc2FnZUxvZzApOw0KICAgICAgICAgICAgYW10c3RhY2suR2V0TWVzc2FnZUxvZyhwcm9jZXNzTWVzc2FnZUxvZzEpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIHByb2Nlc3NNZXNzYWdlTG9nMHJlc3BvbnNlcyA9IG51bGw7DQogICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NNZXNzYWdlTG9nMChzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSByZXR1cm47DQogICAgICAgICAgICBpZiAoc3RhdHVzKSBRVignZ282JywgdHJ1ZSk7IC8vIFNob3cgZXZlbnQgbG9nIGxlZnQgcGFuZWwgb3B0aW9uDQogICAgICAgICAgICBpZiAocmVzcG9uc2VzKSBwcm9jZXNzTWVzc2FnZUxvZzByZXNwb25zZXMgPSByZXNwb25zZXM7DQogICAgICAgICAgICB2YXIgZnIgPSAnJywgeCA9ICI8dGFibGUgY2xhc3M9bG9nMSBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgc3R5bGU9d2lkdGg6MTAwJTtib3JkZXItcmFkaXVzOjhweD4iOw0KICAgICAgICAgICAgaWYgKHByb2Nlc3NNZXNzYWdlTG9nMHJlc3BvbnNlcyAhPSBudWxsKSB7IGZyID0gKChwcm9jZXNzTWVzc2FnZUxvZzByZXNwb25zZXNbMF1bIklzRnJvemVuIl0gPT0gdHJ1ZSkgPyBBZGRCdXR0b24oIlVuLWZyZWV6ZSBMb2ciLCAiRnJlZXplTG9nKDApIikgOiBBZGRCdXR0b24oIkZyZWV6ZSBMb2ciLCAiRnJlZXplTG9nKDEpIikpOyB9DQoNCg0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgiPGRpdiBzdHlsZT1mbG9hdDpyaWdodD48aW5wdXQgaWQ9ZXZlbnRGaWx0ZXIgcGxhY2Vob2xkZXI9RmlsdGVyIHN0eWxlPW1hcmdpbjo0cHggb25rZXl1cD1ldmVudEZpbHRlcigpPiZuYnNwOzwvZGl2PjxkaXY+Jm5ic3A7IiArIEFkZFJlZnJlc2hCdXR0b24oIlB1bGxFdmVudExvZygxKSIpICsgQWRkQnV0dG9uKCJDbGVhciBMb2ciLCAiQ2xlYXJMb2coKSIpICsgQWRkQnV0dG9uKCJTYXZlLi4uIiwgIlNhdmVFdmVudExvZygpIikgKyBmcik7DQogICAgICAgICAgICBRSCgnaWRfVGFibGVFdmVudExvZycsIHggKyAnPGJyPicpOw0KICAgICAgICB9DQoNCg0KICAgICAgICBmdW5jdGlvbiBTYXZlRXZlbnRMb2coKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlIHx8IGV2ZW50bWVzc2FnZXMgPT0gbnVsbCkgcmV0dXJuOw0KICAgICAgICAgICAgU2F2ZUpzb25GaWxlKCdJbnRlbEFtdEV2ZW50bG9nJywgJ2V2ZW50cycsICdJbnRlbCBBTVQgRXZlbnQgTG9nJywgZXZlbnRtZXNzYWdlcyk7DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgZXZlbnRtZXNzYWdlcyA9IG51bGw7DQogICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NNZXNzYWdlTG9nMShzdGFjaywgbWVzc2FnZXMpIHsNCiAgICAgICAgICAgIGV2ZW50bWVzc2FnZXMgPSBtZXNzYWdlczsNCiAgICAgICAgICAgIHZhciBpLCB5ID0gMCwgeCA9ICI8dGFibGUgY2xhc3M9bG9nMSBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgc3R5bGU9d2lkdGg6MTAwJTtib3JkZXItcmFkaXVzOjhweD48dHI+PHRkIHdpZHRoPTgwcHg+PHA+PHRkPjx0ZD48dGQ+IjsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9d2lkdGg6OTBweD48Yj4mbmJzcDsmbmJzcDtFdmVudDwvYj48dGQgY2xhc3M9cjEgc3R5bGU9d2lkdGg6MTEwcHg+PGI+VGltZTwvYj48dGQgY2xhc3M9cjEgc3R5bGU9d2lkdGg6MTYwcHg+PGI+U291cmNlPC9iPjx0ZCBjbGFzcz1yMT48Yj5EZXNjcmlwdGlvbjwvYj4iOw0KICAgICAgICAgICAgZm9yIChpIGluIG1lc3NhZ2VzKSB7DQogICAgICAgICAgICAgICAgeSsrOw0KICAgICAgICAgICAgICAgIHZhciBpY29uID0gMSwgbSA9IG1lc3NhZ2VzW2ldOw0KICAgICAgICAgICAgICAgIGlmIChtWydFdmVudFNldmVyaXR5J10gPj0gOCkgeyBpY29uID0gMjsgfSBpZiAobVsnRXZlbnRTZXZlcml0eSddID49IDE2KSB7IGljb24gPSAzOyB9DQogICAgICAgICAgICAgICAgeCArPSAiPHRyIGlkPXhhbXRldmVudCIgKyBpICsgIiBjbGFzcz1yMyBvbmNsaWNrPXNob3dFdmVudERldGFpbHMoIiArIGkgKyAiKT48dGQgY2xhc3M9cjE+PHA+PGRpdiBjbGFzcz1pY29uIiArIGljb24gKyAiIHN0eWxlPWRpc3BsYXk6YmxvY2s7ZmxvYXQ6bGVmdDttYXJnaW4tbGVmdDo1cHg7bWFyZ2luLXJpZ2h0OjVweD48L2Rpdj4iICsgKHBhcnNlSW50KGkpICsgMSkgKyAiPHRkIGNsYXNzPXIxIHRpdGxlPSciICsgbVsnVGltZSddLnRvTG9jYWxlU3RyaW5nKCkgKyAiJz4iICsgbVsnVGltZSddLnRvTG9jYWxlRGF0ZVN0cmluZygnZW4nLCB7IHllYXI6ICJudW1lcmljIiwgbW9udGg6ICIyLWRpZ2l0IiwgZGF5OiAibnVtZXJpYyIgfSkgKyAiPGJyPiIgKyBtWydUaW1lJ10udG9Mb2NhbGVUaW1lU3RyaW5nKCdlbicsIHsgaG91cjoiMi1kaWdpdCIsIG1pbnV0ZToiMi1kaWdpdCIsIHNlY29uZDoiMi1kaWdpdCIgfSkgKyAiPHRkIGNsYXNzPXIxPiIgKyBtWydFbnRpdHlTdHInXS5yZXBsYWNlKCIocikiLCAiJnJlZzsiKSArICI8dGQgY2xhc3M9cjE+IiArIG1bJ0Rlc2MnXTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbmQoeSA9PSAwID8gIiZuYnNwOyIgOiAiIik7DQogICAgICAgICAgICBRSCgnaWRfVGFibGVFdmVudExvZzInLCB4ICsgJzxicj4nKTsNCiAgICAgICAgICAgIHByb2Nlc3NNZXNzYWdlTG9nMCgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gRnJlZXplTG9nKHgpIHsgaWYgKCF4eGRpYWxvZ01vZGUpIHsgYW10c3RhY2suQU1UX01lc3NhZ2VMb2dfRnJlZXplTG9nKHgsIGZ1bmN0aW9uICgpIHsgYW10c3RhY2suRW51bSgiQU1UX01lc3NhZ2VMb2ciLCBwcm9jZXNzTWVzc2FnZUxvZzApOyB9KSB9IH0NCiAgICAgICAgZnVuY3Rpb24gQ2xlYXJMb2coeCkgeyBpZiAoIXh4ZGlhbG9nTW9kZSkgeyBRSCgnaWRfZGlhbG9nTWVzc2FnZScsICdDbGVhciBldmVudCBsb2c/Jyk7IHNldERpYWxvZ01vZGUoMSwgIkV2ZW50IExvZyIsIDMsIENsZWFyTG9nRXgpOyB9IH0NCiAgICAgICAgZnVuY3Rpb24gQ2xlYXJMb2dFeCgpIHsgYW10c3RhY2suQU1UX01lc3NhZ2VMb2dfQ2xlYXJMb2coZnVuY3Rpb24gKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgeyBpZiAoc3RhdHVzICE9IDIwMCkgbWVzc2FnZWJveCgiRXZlbnQgTG9nIiwgIlVuYWJsZSB0byBjbGVhciwgRXJyb3I6ICIgKyBzdGF0dXMpOyBlbHNlIFB1bGxFdmVudExvZygpOyB9KSB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0V2ZW50RGV0YWlscyhoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgbSA9IGV2ZW50bWVzc2FnZXNbaF07DQogICAgICAgICAgICB2YXIgeCA9ICc8ZGl2IHN0eWxlPXRleHQtYWxpZ246bGVmdD4nOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlRpbWUiLCBtWydUaW1lJ10udG9Mb2NhbGVTdHJpbmcoKSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiU291cmNlIiwgbVsnRW50aXR5U3RyJ10ucmVwbGFjZSgiKHIpIiwgIiZyZWc7IikpOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkRlc2NyaXB0aW9uIiwgbVsnRGVzYyddKTsNCiAgICAgICAgICAgIHggKz0gTW9yZVN0YXJ0KCk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiRGV2aWNlIEFkZHJlc3MiLCBtWydEZXZpY2VBZGRyZXNzJ10pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkVudGl0eSIsIG1bJ0VudGl0eSddKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJFbnRpdHkgSW5zdGFuY2UiLCBtWydFbnRpdHlJbnN0YW5jZSddKTsNCiAgICAgICAgICAgIHZhciBlID0gJyc7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIG1bJ0V2ZW50RGF0YSddKSB7IGlmIChlLmxlbmd0aCA+IDApIGUgKz0nLCc7IGUgKz0gbVsnRXZlbnREYXRhJ11baV07IH0NCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJEYXRhIiwgZSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiT2Zmc2V0IiwgbVsnRXZlbnRPZmZzZXQnXSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiU2Vuc29yIFR5cGUiLCBtWydFdmVudFNlbnNvclR5cGUnXSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiU2V2ZXJpdHkiLCBtWydFdmVudFNldmVyaXR5J10pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlNvdXJjZSBUeXBlIiwgbVsnRXZlbnRTb3VyY2VUeXBlJ10pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlR5cGUiLCBtWydFdmVudFR5cGUnXSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiU2Vuc29yIE51bWJlciIsIG1bJ1NlbnNvck51bWJlciddKTsNCiAgICAgICAgICAgIHggKz0gTW9yZUVuZCgpOw0KICAgICAgICAgICAgeCArPSAiPC9kaXY+IjsNCiAgICAgICAgICAgIG1lc3NhZ2Vib3goIkV2ZW50ICMiICsgKGggKyAxKSArICIgRGV0YWlscyIsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZXZlbnRGaWx0ZXIoKSB7DQogICAgICAgICAgICB2YXIgZmlsdGVyID0gUSgnZXZlbnRGaWx0ZXInKS52YWx1ZS50b0xvd2VyQ2FzZSgpOw0KICAgICAgICAgICAgZm9yICh2YXIgdyBpbiBldmVudG1lc3NhZ2VzKSB7IFFWKCd4YW10ZXZlbnQnICsgdywgZmlsdGVyID09ICcnIHx8IGV2ZW50bWVzc2FnZXNbd11bJ0Rlc2MnXS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoZmlsdGVyKSA+PSAwIHx8IGV2ZW50bWVzc2FnZXNbd11bJ0VudGl0eVN0ciddLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihmaWx0ZXIpID49IDApOyB9DQogICAgICAgIH0NCg0KDQoNCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIEFVRElUIExPRyBQQU5FTA0KICAgICAgICAvLw0KDQogICAgICAgIGZ1bmN0aW9uIFB1bGxBdWRpdExvZyhidXR0b24pIHsNCiAgICAgICAgICAgIGlmIChidXR0b24gPT0gMSAmJiB4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIGFtdEZpcnN0UHVsbCB8PSAzMjsNCiAgICAgICAgICAgIGFtdHN0YWNrLkVudW0oIkFNVF9BdWRpdExvZyIsIHByb2Nlc3NBdWRpdExvZzApOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIGF1ZGl0TG9nID0gbnVsbDsNCiAgICAgICAgdmFyIGF1ZGl0TG9nRW5hYmxlZFN0YXRlcyA9IFsiVW5rbm93biIsICJPdGhlciIsICJFbmFibGVkIiwgIkRpc2FibGVkIiwgIlNodXR0aW5nIERvd24iLCAiTm90IEFwcGxpY2FibGUiLCAiRW5hYmxlZCBidXQgT2ZmbGluZSIsICJJbiBUZXN0IiwgIkRlZmVycmVkIiwgIlF1aWVzY2UiLCAiU3RhcnRpbmciXTsNCg0KICAgICAgICBmdW5jdGlvbiBwcm9jZXNzQXVkaXRMb2cwKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsNCiAgICAgICAgICAgICAgICBRVignZ28xNScsIHRydWUpOyAvLyBTaG93IGF1ZGl0IGxvZyBsZWZ0IHBhbmVsIG9wdGlvbg0KDQogICAgICAgICAgICAgICAgdmFyIHIgPSByZXNwb25zZXNbMF1bIkF1ZGl0U3RhdGUiXTsNCiAgICAgICAgICAgICAgICB2YXIgYXVkaXRzdGF0ZSA9IChyICYgMHgwMSkgPyAnRGlzYWJsZWQnIDogJ0VuYWJsZWQnOw0KICAgICAgICAgICAgICAgIGlmIChyICYgMHgwMikgYXVkaXRzdGF0ZSArPSAiLCBMb2NrZWQiOw0KICAgICAgICAgICAgICAgIGlmIChyICYgMHgwNCkgYXVkaXRzdGF0ZSArPSAiLCBBbG1vc3QgRnVsbCI7DQogICAgICAgICAgICAgICAgaWYgKHIgJiAweDA4KSBhdWRpdHN0YXRlICs9ICIsIEZ1bGwiOw0KICAgICAgICAgICAgICAgIGlmIChyICYgMHgxMCkgYXVkaXRzdGF0ZSArPSAiLCBOb0tleSI7DQoNCiAgICAgICAgICAgICAgICB2YXIgeCA9ICI8aDE+QXVkaXQgTG9nIFNldHRpbmdzPC9oMT4iICsgVGFibGVTdGFydCgpOw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiU3RhdGUiLCBhdWRpdHN0YXRlKTsNCiAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIlN0b3JhZ2UiLCByZXNwb25zZXNbMF1bIkN1cnJlbnROdW1iZXJPZlJlY29yZHMiXSArICIgcmVjb3JkKHMpLCAiICsgcmVzcG9uc2VzWzBdWyJQZXJjZW50YWdlRnJlZSJdICsgIiUgZnJlZSIpOw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiT3ZlcndyaXRlIHBvbGljeSIsICgocmVzcG9uc2VzWzBdWyJPdmVyd3JpdGVQb2xpY3kiXSA9PSAyKSA/ICJXcmFwcyB3aGVuIGZ1bGwiIDogIk5ldmVyIG92ZXJ3cml0ZXMiKSk7DQogICAgICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KICAgICAgICAgICAgICAgIFFIKCdpZF9UYWJsZUF1ZGl0TG9nMScsIHgpOw0KDQogICAgICAgICAgICAgICAgYW10c3RhY2suR2V0QXVkaXRMb2cocHJvY2Vzc0F1ZGl0TG9nMSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBwcm9jZXNzQXVkaXRMb2cxKHN0YWNrLCBtZXNzYWdlcykgew0KICAgICAgICAgICAgYXVkaXRMb2cgPSBtZXNzYWdlczsNCiAgICAgICAgICAgIHZhciBpLCB4ID0gIjx0YWJsZSBjbGFzcz1sb2cxIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCBzdHlsZT13aWR0aDoxMDAlO2JvcmRlci1yYWRpdXM6OHB4PiI7DQoNCiAgICAgICAgICAgIHggKz0gVGFibGVFbmQoIjxkaXYgc3R5bGU9ZmxvYXQ6cmlnaHQ+PGlucHV0IGlkPWF1ZGl0RmlsdGVyIHBsYWNlaG9sZGVyPUZpbHRlciBzdHlsZT1tYXJnaW46NHB4IG9ua2V5dXA9YXVkaXRGaWx0ZXIoKT4mbmJzcDs8L2Rpdj48ZGl2PiAiICsgQWRkUmVmcmVzaEJ1dHRvbigiUHVsbEF1ZGl0TG9nKDEpIikgKyBBZGRCdXR0b24oIlNhdmUuLi4iLCAiU2F2ZUF1ZGl0TG9nKCkiKSArIEFkZEJ1dHRvbigiQ2xlYXIgTG9nIiwgIkNsZWFyQXVkaXRMb2coKSIpIC8qICsgQWRkQnV0dG9uKCJTZXR0aW5ncy4uLiIsICJTaG93QXVkaXRMb2dTZXR0aW5ncygpIikqLykgKyAiPGJyPiI7DQogICAgICAgICAgICBpZiAobWVzc2FnZXMubGVuZ3RoID09IDApIHsNCiAgICAgICAgICAgICAgICB4ID0gIk5vIGF1ZGl0IGxvZyBldmVudHMgZm91bmQuIjsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgdmFyIHkgPSAwOw0KICAgICAgICAgICAgICAgIHggKz0gIjx0YWJsZSBjbGFzcz1sb2cxIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCBzdHlsZT13aWR0aDoxMDAlO2JvcmRlci1yYWRpdXM6OHB4Pjx0cj48dGQgd2lkdGg9ODBweD48cD48dGQ+PHRkPjx0ZD4iOw0KICAgICAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9d2lkdGg6MTEwcHg+Jm5ic3A7Jm5ic3A7PGI+VGltZTwvYj48dGQgY2xhc3M9cjEgc3R5bGU9d2lkdGg6MjYwcHg+PGI+SW5pdGlhdG9yPC9iPjx0ZCBjbGFzcz1yMT48Yj5BY3Rpb248L2I+IjsNCiAgICAgICAgICAgICAgICBmb3IgKGkgaW4gbWVzc2FnZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIG0gPSBtZXNzYWdlc1tpXSwgZGVzY3JpcHRpb24gPSBtWydBdWRpdEFwcCddLCBpbml0aWF0b3IgPSBtWydJbml0aWF0b3InXTsNCiAgICAgICAgICAgICAgICAgICAgeSsrOw0KICAgICAgICAgICAgICAgICAgICB2YXIgYWRkciA9ICcnOw0KICAgICAgICAgICAgICAgICAgICBpZiAobVsnTmV0QWRkcmVzcyddLmxlbmd0aCA+IDApIGFkZHIgPSBtWydOZXRBZGRyZXNzJ10ucmVwbGFjZSgnMDAwMDowMDAwOjAwMDA6MDAwMDowMDAwOjAwMDA6MDAwMDowMDAxJywnOjoxJyk7DQogICAgICAgICAgICAgICAgICAgIGlmIChtWydFdmVudCddKSBkZXNjcmlwdGlvbiArPSAiLCAiICsgbVsnRXZlbnQnXTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKG1bJ0V4U3RyJ10gIT0gbnVsbCkgZGVzY3JpcHRpb24gKz0gIiwgIiArIG1bJ0V4U3RyJ107DQogICAgICAgICAgICAgICAgICAgIGlmIChpbml0aWF0b3IgIT0gJycgJiYgYWRkciAhPSAnJykgaW5pdGlhdG9yICs9ICIsICI7DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjx0ciBpZD14YW10YXVkaXQiICsgaSArICIgY2xhc3M9cjMgb25jbGljaz1zaG93QXVkaXREZXRhaWxzKCIgKyBpICsgIik+PHRkIGNsYXNzPXIxIHRpdGxlPSciICsgbVsnVGltZSddLnRvTG9jYWxlU3RyaW5nKCkgKyAiJz4mbmJzcDsmbmJzcDsiICsgbVsnVGltZSddLnRvTG9jYWxlRGF0ZVN0cmluZygnZW4nLCB7IHllYXI6ICJudW1lcmljIiwgbW9udGg6ICIyLWRpZ2l0IiwgZGF5OiAibnVtZXJpYyIgfSkgKyAiPGJyPiZuYnNwOyZuYnNwOyIgKyBtWydUaW1lJ10udG9Mb2NhbGVUaW1lU3RyaW5nKCdlbicsIHsgaG91cjoiMi1kaWdpdCIsIG1pbnV0ZToiMi1kaWdpdCIsIHNlY29uZDoiMi1kaWdpdCIgfSkgKyAiPHRkIGNsYXNzPXIxPiIgKyBpbml0aWF0b3IgKyBhZGRyICsgIjx0ZCBjbGFzcz1yMT4iICsgZGVzY3JpcHRpb247DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbmQoeSA9PSAwID8gIiZuYnNwOyIgOiAiIikgKyAiPGJyPiI7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBRSCgnaWRfVGFibGVBdWRpdExvZzInLCB4KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGF1ZGl0RmlsdGVyKCkgew0KICAgICAgICAgICAgdmFyIGZpbHRlciA9IFEoJ2F1ZGl0RmlsdGVyJykudmFsdWUudG9Mb3dlckNhc2UoKTsNCiAgICAgICAgICAgIGZvciAodmFyIHcgaW4gYXVkaXRMb2cpIHsgUVYoJ3hhbXRhdWRpdCcgKyB3LCBmaWx0ZXIgPT0gJycgfHwgSlNPTi5zdHJpbmdpZnkoYXVkaXRMb2dbd10pLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihmaWx0ZXIpID49IDApOyB9DQogICAgICAgIH0NCg0KDQogICAgICAgIGZ1bmN0aW9uIFNhdmVBdWRpdExvZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgfHwgYXVkaXRMb2cgPT0gbnVsbCkgcmV0dXJuOw0KICAgICAgICAgICAgU2F2ZUpzb25GaWxlKCdJbnRlbEFtdEF1ZGl0bG9nJywgJ2F1ZGl0ZXZlbnRzJywgJ0ludGVsIEFNVCBBdWRpdCBMb2cnLCBhdWRpdExvZyk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBDbGVhckF1ZGl0TG9nKHgpIHsgUUgoJ2lkX2RpYWxvZ01lc3NhZ2UnLCAnQ2xlYXIgYXVkaXQgbG9nPycpOyBzZXREaWFsb2dNb2RlKDEsICJBdWRpdCBMb2ciLCAzLCBDbGVhckF1ZGl0TG9nRXgpOyB9DQogICAgICAgIGZ1bmN0aW9uIENsZWFyQXVkaXRMb2dFeCgpIHsNCiAgICAgICAgICAgIC8vYW10c3RhY2suQU1UX0F1ZGl0TG9nX0NsZWFyTG9nKGZ1bmN0aW9uICgpIHsgUHVsbEF1ZGl0TG9nKCk7IH0pDQogICAgICAgICAgICB2YXIgaGFuZGxlID0gYW10c3RhY2suQU1UX0F1ZGl0TG9nX1NldEF1ZGl0TG9jaygxLDAsIGhhbmRsZSwgZnVuY3Rpb24oKSB7IGFtdHN0YWNrLkFNVF9BdWRpdExvZ19DbGVhckxvZyhmdW5jdGlvbiAoKSB7IGFtdHN0YWNrLkFNVF9BdWRpdExvZ19TZXRBdWRpdExvY2soMCwgMiwgaGFuZGxlLCBmdW5jdGlvbiAoKSB7IHNldFRpbWVvdXQoUHVsbEF1ZGl0TG9nLDEwMDApO30pOyB9KTsgfSk7ICAgICAgICAgDQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBTaG93QXVkaXRMb2dTZXR0aW5ncygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9BdWRpdExvZ19SZXF1ZXN0U3RhdGVDaGFuZ2UoMiwgMCwgQXVkaXRMb2dTZXR0aW5nc0NvbXBsZXRlZCk7IC8vIEVuYWJsZQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQXVkaXRMb2dTZXR0aW5nc0NvbXBsZXRlZChzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gMjAwKSBQdWxsQXVkaXRMb2coKTsgZWxzZSBtZXNzYWdlYm94KCJBdWRpdCBMb2ciLCAiRXJyb3I6ICIgKyBzdGF0dXMpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0F1ZGl0RGV0YWlscyhoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgaSwgbSA9IGF1ZGl0TG9nW2hdLCB4ID0gJzxkaXYgc3R5bGU9dGV4dC1hbGlnbjpsZWZ0Pic7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiVGltZSIsIG1bJ1RpbWUnXS50b0xvY2FsZVN0cmluZygpKTsNCiAgICAgICAgICAgIGlmIChtWydJbml0aWF0b3InXSAhPSAnJykgeCArPSBhZGRIdG1sVmFsdWUoIkluaXRpYXRvciIsIG1bJ0luaXRpYXRvciddKTsNCiAgICAgICAgICAgIGlmIChtWydOZXRBZGRyZXNzJ10gIT0gJycpIHggKz0gYWRkSHRtbFZhbHVlKCJBZGRyZXNzIiwgbVsnTmV0QWRkcmVzcyddKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJBcHBsaWNhdGlvbiIsIG1bJ0F1ZGl0QXBwJ10pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkV2ZW50IiwgbVsnRXZlbnQnXSk7DQogICAgICAgICAgICBpZiAobVsnRXhTdHInXSAhPSBudWxsKSB7DQogICAgICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkV4dGVuZGVkIERhdGEiLCBtWydFeFN0ciddKTsNCiAgICAgICAgICAgIH0gZWxzZSBpZiAobVsnRXgnXS5sZW5ndGggPiAwKSB7DQogICAgICAgICAgICAgICAgdmFyIGUgPSAnJzsNCiAgICAgICAgICAgICAgICBmb3IgKGkgaW4gbVsnRXgnXSkgeyBpZiAoZS5sZW5ndGggPiAwKSBlICs9ICcsJzsgZSArPSBtWydFeCddLmNoYXJDb2RlQXQoaSk7IH0NCiAgICAgICAgICAgICAgICBpZiAoZSAhPSAnJykgeCArPSBhZGRIdG1sVmFsdWUoIkRhdGEgVmFsdWVzIiwgZSk7DQogICAgICAgICAgICAgICAgaWYgKG1bJ0V4J10ubGVuZ3RoID4gMiAmJiBSZWFkU2hvcnQobVsnRXgnXSwgMCkgPT0gKG1bJ0V4J10ubGVuZ3RoIC0gMikpIHggKz0gYWRkSHRtbFZhbHVlKCJEYXRhIFN0cmluZyIsIG1bJ0V4J10uc3Vic3RyaW5nKDIpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gIjwvZGl2PiI7DQogICAgICAgICAgICBtZXNzYWdlYm94KCJBdWRpdCBFdmVudCAjIiArIChoICsgMSkgKyAiIERldGFpbHMiLCB4KTsNCiAgICAgICAgfQ0KDQoNCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIENlcnRpZmljYXRlcw0KICAgICAgICAvLw0KDQogICAgICAgIHZhciB4eENlcnRpZmljYXRlcyA9IG51bGw7DQogICAgICAgIHZhciB4eENlcnRQcml2YXRlS2V5cyA9IG51bGw7DQogICAgICAgIHZhciB4eFRsc1NldHRpbmdzID0gbnVsbDsNCiAgICAgICAgdmFyIHh4VGxzQ3VycmVudENlcnQgPSBudWxsOw0KICAgICAgICB2YXIgeHhUTFNDcmVkZW50aWFsQ29udGV4dCA9IG51bGw7DQogICAgICAgIHZhciB4eENhUHJpdmF0ZUtleSA9IG51bGw7DQogICAgICAgIHZhciB4eENhU3ViamVjdEF0dHJpYnV0ZXMgPSBudWxsOw0KDQogICAgICAgIGZ1bmN0aW9uIFB1bGxDZXJ0aWZpY2F0ZXMoKSB7DQogICAgICAgICAgICAvLyBXZSBvbmx5IGRlYWwgd2l0aCBjZXJ0aWZpY2F0ZXMgc3RhcnRpbmcgd2l0aCBJbnRlbCBBTVQgNiBhbmQgYmV5b25kDQogICAgICAgICAgICBhbXRzdGFjay5CYXRjaEVudW0obnVsbCwgWyJBTVRfUHVibGljS2V5Q2VydGlmaWNhdGUiLCAiQU1UX1B1YmxpY1ByaXZhdGVLZXlQYWlyIiwgIkFNVF9UTFNTZXR0aW5nRGF0YSIsICJBTVRfVExTQ3JlZGVudGlhbENvbnRleHQiXSwgcHJvY2Vzc0NlcnRzMSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBwcm9jZXNzQ2VydHMxKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKChzdGF0dXMgPT0gNDAwKSB8fCBlcnJjaGVjayhzdGF0dXMsIHN0YWNrKSkgcmV0dXJuOw0KICAgICAgICAgICAgUVYoJ2dvMTYnLCB0cnVlKTsgLy8gU2VjdXJpdHkgU2V0dGluZ3MNCiAgICAgICAgICAgIHh4Q2VydGlmaWNhdGVzID0gcmVzcG9uc2VzWyJBTVRfUHVibGljS2V5Q2VydGlmaWNhdGUiXS5yZXNwb25zZXM7DQogICAgICAgICAgICB4eENlcnRQcml2YXRlS2V5cyA9IHJlc3BvbnNlc1siQU1UX1B1YmxpY1ByaXZhdGVLZXlQYWlyIl0ucmVzcG9uc2VzOw0KICAgICAgICAgICAgeHhUbHNTZXR0aW5ncyA9IHJlc3BvbnNlc1siQU1UX1RMU1NldHRpbmdEYXRhIl0ucmVzcG9uc2VzOw0KICAgICAgICAgICAgeHhUTFNDcmVkZW50aWFsQ29udGV4dCA9IHJlc3BvbnNlc1siQU1UX1RMU0NyZWRlbnRpYWxDb250ZXh0Il0ucmVzcG9uc2VzOw0KDQogICAgICAgICAgICAvLyBTZWxlY3QgdGhlIGN1cnJlbnQgVExTIGNlcnRpZmljYXRlIGluIHRoZSBkcm9wIGRvd24gYm94DQogICAgICAgICAgICB4eFRsc0N1cnJlbnRDZXJ0ID0gbnVsbDsNCiAgICAgICAgICAgIGlmICh4eFRMU0NyZWRlbnRpYWxDb250ZXh0Lmxlbmd0aCA+IDApIHsNCiAgICAgICAgICAgICAgICB2YXIgY2VydEluc3RhbmNlSWQgPSB4eFRMU0NyZWRlbnRpYWxDb250ZXh0WzBdWydFbGVtZW50SW5Db250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXVsnVmFsdWUnXTsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4Q2VydGlmaWNhdGVzKSB7IGlmICh4eENlcnRpZmljYXRlc1tpXVsnSW5zdGFuY2VJRCddID09IGNlcnRJbnN0YW5jZUlkKSB7IHh4VGxzQ3VycmVudENlcnQgPSBpOyB9IH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gU2V0dXAgdGhlIGNlcnRpZmljYXRlcw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eENlcnRpZmljYXRlcykgew0KICAgICAgICAgICAgICAgIHh4Q2VydGlmaWNhdGVzW2ldLlRydXN0ZWRSb290Q2VydGZpY2F0ZSA9ICh4eENlcnRpZmljYXRlc1tpXVsiVHJ1c3RlZFJvb3RDZXJ0ZmljYXRlIl0gPT0gdHJ1ZSk7DQogICAgICAgICAgICAgICAgeHhDZXJ0aWZpY2F0ZXNbaV0uWDUwOUNlcnRpZmljYXRlID0gd2luZG93LmF0b2IoeHhDZXJ0aWZpY2F0ZXNbaV1bIlg1MDlDZXJ0aWZpY2F0ZSJdKTsNCiAgICAgICAgICAgICAgICB4eENlcnRpZmljYXRlc1tpXS5YSXNzdWVyID0gcGFyc2VDZXJ0TmFtZSh4eENlcnRpZmljYXRlc1tpXVsiSXNzdWVyIl0pOw0KICAgICAgICAgICAgICAgIHh4Q2VydGlmaWNhdGVzW2ldLlhTdWJqZWN0ID0gcGFyc2VDZXJ0TmFtZSh4eENlcnRpZmljYXRlc1tpXVsiU3ViamVjdCJdKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGFtdGNlcnRfbGlua0NlcnRQcml2YXRlS2V5KHh4Q2VydGlmaWNhdGVzLCB4eENlcnRQcml2YXRlS2V5cyk7IC8vIFRoaXMgbGlua3MgYWxsIGNlcnRpZmljYXRlcyBhbmQgcHJpdmF0ZSBrZXlzDQoNCiAgICAgICAgICAgIHVwZGF0ZUNlcnRpZmljYXRlcygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gcGFyc2VDZXJ0TmFtZSh4KSB7DQogICAgICAgICAgICB2YXIgaiwgciA9IHt9LCB4eCA9IHguc3BsaXQoJywnKTsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHgpIHsgaiA9IHh4W2ldLmluZGV4T2YoJz0nKTsgclt4eFtpXS5zdWJzdHJpbmcoMCwgaildID0geHhbaV0uc3Vic3RyaW5nKGogKyAxKTsgfQ0KICAgICAgICAgICAgcmV0dXJuIHI7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBnZXRUbHNTZWN1cml0eVN0YXRlKHgpIHsNCiAgICAgICAgICAgIGlmICh4eFRsc1NldHRpbmdzW3hdWydFbmFibGVkJ10gPT0gZmFsc2UpIHJldHVybiAiRGlzYWJsZWQiOw0KICAgICAgICAgICAgdmFyIHIgPSAoKHh4VGxzU2V0dGluZ3NbeF1bJ011dHVhbEF1dGhlbnRpY2F0aW9uJ10gPT0gdHJ1ZSkgPyAnTXV0dWFsLWF1dGggVExTJyA6ICdTZXJ2ZXItYXV0aCBUTFMnKSArICgoeHhUbHNTZXR0aW5nc1t4XVsnQWNjZXB0Tm9uU2VjdXJlQ29ubmVjdGlvbnMnXSA9PSB0cnVlKSA/ICIgYW5kIG5vbi1UTFMiIDogIiIpOw0KICAgICAgICAgICAgaWYgKCh4eFRsc1NldHRpbmdzW3hdWydNdXR1YWxBdXRoZW50aWNhdGlvbiddID09IHRydWUpICYmICh4eFRsc1NldHRpbmdzW3hdWydUcnVzdGVkQ04nXSkpIHsNCiAgICAgICAgICAgICAgICB2YXIgdHJ1c3RlZENuID0gTWFrZVRvQXJyYXkoeHhUbHNTZXR0aW5nc1t4XVsnVHJ1c3RlZENOJ10pOw0KICAgICAgICAgICAgICAgIGlmICh0cnVzdGVkQ24ubGVuZ3RoID4gMCkgeyByICs9ICIsIFRydXN0ZWQgbmFtZSIgKyAoKHRydXN0ZWRDbi5sZW5ndGggPiAxKT8ncyc6JycpICsgIjogIiArIHRydXN0ZWRDbi5qb2luKCcsICcpICsgIi4iOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gcjsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVwZGF0ZUNlcnRpZmljYXRlcygpIHsNCiAgICAgICAgICAgIGlmICh4eENlcnRpZmljYXRlcyA9PSBudWxsKSByZXR1cm47DQoNCiAgICAgICAgICAgIC8vIEZpZ3VyZSBvdXQgd2hhdCBpbmRleCBpcyBsb2NhbCAmIHJlbW90ZQ0KICAgICAgICAgICAgdmFyIGxvY2FsTmR4ID0gKCh4eFRsc1NldHRpbmdzWzBdWydJbnN0YW5jZUlEJ10gPT0gJ0ludGVsKHIpIEFNVCBMTVMgVExTIFNldHRpbmdzJykpID8gMCA6IDEsIHJlbW90ZU5keCA9ICgxIC0gbG9jYWxOZHgpOw0KDQogICAgICAgICAgICAvLyBHZW5lcmFsIHNldHRpbmdzDQogICAgICAgICAgICB2YXIgeCA9IFRhYmxlU3RhcnQoKTsNCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiUmVtb3RlIFRMUyBzZWN1cml0eSIsIGFkZExpbmtDb25kaXRpb25hbChnZXRUbHNTZWN1cml0eVN0YXRlKHJlbW90ZU5keCksICdzaG93U2V0VGxzU2VjdXJpdHlEbGcoKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJMb2NhbCBUTFMgc2VjdXJpdHkiLCBhZGRMaW5rQ29uZGl0aW9uYWwoZ2V0VGxzU2VjdXJpdHlTdGF0ZShsb2NhbE5keCksICdzaG93U2V0VGxzU2VjdXJpdHlEbGcoKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KICAgICAgICAgICAgeCArPSAiPGJyPiIgKyBUYWJsZVN0YXJ0MigpICsgIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPk1hbmFnZSBJbnRlbCZyZWc7IEFNVCBjZXJ0aWZpY2F0ZXMgZm9yIHRoaXMgY29tcHV0ZXIuPGJyPjxicj4iOw0KICAgICAgICAgICAgaWYgKHh4Q2VydGlmaWNhdGVzLmxlbmd0aCA9PSAwICYmIHh4Q2VydFByaXZhdGVLZXlzLmxlbmd0aCA9PSAwKSB7DQogICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweD48YnI+PGk+Tm8gY2VydGlmaWNhdGVzIGZvdW5kLjwvaT48L2Rpdj48YnI+IjsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eENlcnRpZmljYXRlcykgew0KICAgICAgICAgICAgICAgICAgICB2YXIgZGVzYyA9ICcnOw0KICAgICAgICAgICAgICAgICAgICBpZiAoeHhDZXJ0aWZpY2F0ZXNbaV0uVHJ1c3RlZFJvb3RDZXJ0ZmljYXRlKSBkZXNjID0gJywgVHJ1c3RlZCBSb290JzsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHh4Q2VydGlmaWNhdGVzW2ldLlhQcml2YXRlS2V5KSBkZXNjID0gJywgUHJpdmF0ZSBLZXknOw0KICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSB4eFRsc0N1cnJlbnRDZXJ0KSBkZXNjICs9ICcsIFRMUyBjZXJ0JzsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBjbGFzcz1pdGVtQmFyIG9uY2xpY2s9c2hvd0NlcnREZXRhaWxzKCIgKyBpICsgIik+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDozcHg+PGI+IiArIEVzY2FwZUh0bWwoeHhDZXJ0aWZpY2F0ZXNbaV0uWFN1YmplY3RbIkNOIl0pICsgIjwvYj48aT4iICsgZGVzYyArICI8L2k+PC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eENlcnRQcml2YXRlS2V5cykgew0KICAgICAgICAgICAgICAgICAgICBpZiAoIXh4Q2VydFByaXZhdGVLZXlzW2ldLlhDZXJ0KSB7DQogICAgICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93S2V5UGFpckRldGFpbHMoIiArIGkgKyAiKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjNweD48aT5VbmFzc2lnbmVkIFByaXZhdGUgS2V5IFBhaXIgIyIgKyBpICsgIjwvaT48L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgdmFyIGJ1dHRvbnMgPSBBZGRSZWZyZXNoQnV0dG9uKCJQdWxsQ2VydGlmaWNhdGVzKCkiKTsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHsgYnV0dG9ucyArPSAoQWRkQnV0dG9uKCJBZGQgQ2VydGlmaWNhdGUuLi4iLCAiYWRkQ2VydEJ1dHRvbigpIikgKyBBZGRCdXR0b24oIklzc3VlIENlcnRpZmljYXRlLi4uIiwgImlzc3VlQ2VydEJ1dHRvbigpIikpOyB9DQogICAgICAgICAgICB4ICs9ICI8YnI+PHRkIGNsYXNzPXIxPiIgKyBUYWJsZUVuZChidXR0b25zKTsNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZUNlcnRzJywgeCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93S2V5UGFpckRldGFpbHMoaCkgew0KICAgICAgICAgICAgdmFyIHggPSAiVGhpcyBpcyBhIHB1YmxpYy9wcml2YXRlIGNlcnRpZmljYXRlIGtleSBwYWlyIHRoYXQgZG9lcyBub3QgYmVsb25nIHRvIGFueSBjZXJ0aWZpY2F0ZXMuIFRoaXMgZW50cnkgc2hvdWxkIGJlIHRlbXBvcmFyeS4iOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIktleSBQYWlyICMiICsgaCwgNSwgZnVuY3Rpb24gKGIpIHsgaWYgKGIgPT0gMikgeyBhbXRzdGFjay5EZWxldGUoJ0FNVF9QdWJsaWNQcml2YXRlS2V5UGFpcicsIHsgJ0luc3RhbmNlSUQnOiB4eENlcnRQcml2YXRlS2V5c1toXVsnSW5zdGFuY2VJRCddIH0sIFB1bGxDZXJ0aWZpY2F0ZXMsIDAsIDEpOyB9IH0sIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIHh4Q2VydFN1YmplY3ROYW1lcyA9IHsgJ0NOJzogJ0NvbW1vbiBOYW1lJywgJ08nOiAnT3JnYW5pemF0aW9uJywgJ09VJzogJ09yZyBVbml0JywgJ1MnOiAnU3RhdGUvUHJvdmluY2UnLCAnU1QnOiAnU3RhdGUvUHJvdmluY2UnLCAnTCc6ICdMb2NhbGl0eScsICdDJzogJ0NvdW50cnknLCAnU04nOiAnU3VybmFtZScsICdHTic6ICdHaXZlbiBuYW1lJyB9Ow0KICAgICAgICBmdW5jdGlvbiBzaG93Q2VydERldGFpbHMoaCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIGMgPSB4eENlcnRpZmljYXRlc1toXSwgeCA9ICc8YnI+JzsNCg0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkNlcnRpZmljYXRlIiwgYy5YNTA5Q2VydGlmaWNhdGUubGVuZ3RoICsgIiBieXRlcywgPGEgc3R5bGU9Y3Vyc29yOnBvaW50ZXI7Y29sb3I6Ymx1ZSBvbmNsaWNrPWRvd25sb2FkQ2VydCgiICsgaCArICIpPkRvd25sb2FkPC9hPiIpOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlRydXN0ZWQgcm9vdCIsIGMuVHJ1c3RlZFJvb3RDZXJ0ZmljYXRlID8gIlllcyIgOiAiTm8iKTsNCiAgICAgICAgICAgIGlmIChjLlRydXN0ZWRSb290Q2VydGZpY2F0ZSA9PSBmYWxzZSAmJiBjLlhQcml2YXRlS2V5KSB7IHggKz0gYWRkSHRtbFZhbHVlKCdQcml2YXRlIGtleScsICdQcmVzZW50Jyk7IH0NCg0KICAgICAgICAgICAgLy8gU2hvdyBjZXJ0aWZpY2F0ZSB1c2FnZXMNCiAgICAgICAgICAgIC8qDQogICAgICAgICAgICB5ID0gW107DQogICAgICAgICAgICBpZiAoZXh0S2V5VXNhZ2UgIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgIGlmIChleHRLZXlVc2FnZS5jbGllbnRBdXRoID09IHRydWUpIHsgeS5wdXNoKCJUTFMmbmJzcDtDbGllbnQiKTsgfQ0KICAgICAgICAgICAgICAgIGlmIChleHRLZXlVc2FnZS5jb2RlU2lnbmluZyA9PSB0cnVlKSB7IHkucHVzaCgiQ29kZSZuYnNwO1NpZ25pbmciKTsgfQ0KICAgICAgICAgICAgICAgIGlmIChleHRLZXlVc2FnZS5lbWFpbFByb3RlY3Rpb24gPT0gdHJ1ZSkgeyB5LnB1c2goIkVNYWlsIik7IH0NCiAgICAgICAgICAgICAgICBpZiAoZXh0S2V5VXNhZ2Uuc2VydmVyQXV0aCA9PSB0cnVlKSB7IHkucHVzaCgiVExTJm5ic3A7U2VydmVyIik7IH0NCiAgICAgICAgICAgICAgICBpZiAoZXh0S2V5VXNhZ2VbIjIuMTYuODQwLjEuMTEzNzQxLjEuMi4xIl0gPT0gdHJ1ZSkgeyB5LnB1c2goIkludGVsJnJlZzsmbmJzcDtBTVQgQ29uc29sZSIpOyB9DQogICAgICAgICAgICAgICAgaWYgKGV4dEtleVVzYWdlWyIyLjE2Ljg0MC4xLjExMzc0MS4xLjIuMiJdID09IHRydWUpIHsgeS5wdXNoKCJJbnRlbCZyZWc7Jm5ic3A7QU1UIEFnZW50Iik7IH0NCiAgICAgICAgICAgICAgICBpZiAoZXh0S2V5VXNhZ2VbIjIuMTYuODQwLjEuMTEzNzQxLjEuMi4zIl0gPT0gdHJ1ZSkgeyB5LnB1c2goIkludGVsJnJlZzsmbmJzcDtBTVQgQWN0aXZhdGlvbiIpOyB9DQogICAgICAgICAgICAgICAgaWYgKGV4dEtleVVzYWdlLnRpbWVTdGFtcGluZyA9PSB0cnVlKSB7IHkucHVzaCgiVGltZSZuYnNwO1N0YW1waW5nIik7IH0NCiAgICAgICAgICAgICAgICBpZiAoeS5sZW5ndGggPiAwKSB7IHggKz0gYWRkSHRtbFZhbHVlTm9UaXRsZSgiQ2VydGlmaWNhdGUgVXNhZ2UiLCB5LmpvaW4oJywgJykgKyAnLicpICsgJzxiciBjbGVhcj1hbGwgLz4nOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICAqLw0KDQogICAgICAgICAgICB4ICs9ICc8YnI+PGRpdiBzdHlsZT0iYm9yZGVyLWJvdHRvbToxcHggc29saWQgZ3JheSI+PGk+Q2VydGlmaWNhdGUgU3ViamVjdDwvaT48L2Rpdj48YnI+JzsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYy5YU3ViamVjdCkgeyBpZiAoYy5YU3ViamVjdFtpXSkgeyB4ICs9IGFkZEh0bWxWYWx1ZSh4eENlcnRTdWJqZWN0TmFtZXNbaV0gPyB4eENlcnRTdWJqZWN0TmFtZXNbaV0gOiBpLCBFc2NhcGVIdG1sKGMuWFN1YmplY3RbaV0pKTsgfSB9DQogICAgICAgICAgICAvLyB4ICs9IGFkZEh0bWxWYWx1ZU5vVGl0bGUoJ0ZpbmdlcnByaW50JywgYy5maW5nZXJwcmludC5zdWJzdHJpbmcoMCwyOSkgKyAnPGJyIC8+JyArIGMuZmluZ2VycHJpbnQuc3Vic3RyaW5nKDMwKSk7IC8vIFRPRE86IFBhcnNlIHRoZSBjZXJ0aWZpY2F0ZSB1c2luZyBGb3JnZSBhbmQgZ2V0IHRoZSBmaW5nZXJwcmludA0KICAgICAgICAgICAgeCArPSAnPGJyPjxkaXYgc3R5bGU9ImJvcmRlci1ib3R0b206MXB4IHNvbGlkIGdyYXkiPjxpPklzc3VlciBDZXJ0aWZpY2F0ZTwvaT48L2Rpdj48YnI+JzsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYy5YSXNzdWVyKSB7IGlmIChjLlhJc3N1ZXJbaV0pIHsgeCArPSBhZGRIdG1sVmFsdWUoeHhDZXJ0U3ViamVjdE5hbWVzW2ldID8geHhDZXJ0U3ViamVjdE5hbWVzW2ldIDogaSwgRXNjYXBlSHRtbChjLlhJc3N1ZXJbaV0pKTsgfSB9DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiQ2VydGlmaWNhdGUgLSAiICsgRXNjYXBlSHRtbChjLlhTdWJqZWN0WyJDTiJdKSwgNSwgZnVuY3Rpb24gKGIpIHsNCiAgICAgICAgICAgICAgICBpZiAoYiA9PSAyKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZXJlIGlzIGEgcHJpdmF0ZSBrZXksIGRlbGV0ZSBpdC4NCiAgICAgICAgICAgICAgICAgICAgaWYgKHh4Q2VydGlmaWNhdGVzW2hdLlhQcml2YXRlS2V5KSBhbXRzdGFjay5EZWxldGUoJ0FNVF9QdWJsaWNQcml2YXRlS2V5UGFpcicsIHsgJ0luc3RhbmNlSUQnOiB4eENlcnRpZmljYXRlc1toXS5YUHJpdmF0ZUtleVsnSW5zdGFuY2VJRCddIH0sIGZ1bmN0aW9uICgpIHsgfSwgMCwgMSk7DQogICAgICAgICAgICAgICAgICAgIC8vIERlbGV0ZSB0aGUgY2VydGlmaWNhdGUNCiAgICAgICAgICAgICAgICAgICAgYW10c3RhY2suRGVsZXRlKCdBTVRfUHVibGljS2V5Q2VydGlmaWNhdGUnLCB4eENlcnRpZmljYXRlc1toXSwgY2VydGlmaWNhdGVSZW1vdmVkLCAwLCAxKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LCB4KTsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgZnVuY3Rpb24gZG93bmxvYWRDZXJ0KGgpIHsgDQoNCiAgICAgICAgICAgIHNhdmVBcyhkYXRhMmJsb2IoeHhDZXJ0aWZpY2F0ZXNbaF0uWDUwOUNlcnRpZmljYXRlKSwgeHhDZXJ0aWZpY2F0ZXNbaF0uWFN1YmplY3RbJ0NOJ10gKyAiLmNlciIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gY2VydF9GaWxlU2VsZWN0SGFuZGxlcihlKSB7DQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQogICAgICAgICAgICBpZiAoZS5kYXRhVHJhbnNmZXIuZmlsZXMubGVuZ3RoID09IDEpIHsNCiAgICAgICAgICAgICAgICBpZiAoZS5kYXRhVHJhbnNmZXIuZmlsZXNbMF0ubmFtZS50b0xvd2VyQ2FzZSgpLmVuZHNXaXRoKCcucDEyJykpIHsNCiAgICAgICAgICAgICAgICAgICAgaXNzdWVDZXJ0QnV0dG9uKGUuZGF0YVRyYW5zZmVyLmZpbGVzKTsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBhZGRDZXJ0QnV0dG9uKGUuZGF0YVRyYW5zZmVyLmZpbGVzKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgeHhEcmFnRHJvcENlcnRGaWxlcyA9IG51bGw7DQogICAgICAgIGZ1bmN0aW9uIGFkZENlcnRCdXR0b24oZmlsZXMpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgfHwgIXh4QWNjb3VudEFkbWluTmFtZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHggPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MTBweD48L2Rpdj4nOw0KICAgICAgICAgICAgeHhEcmFnRHJvcENlcnRGaWxlcyA9IGZpbGVzOw0KDQogICAgICAgICAgICB2YXIgaW5wdXQgPSAiPGlucHV0IGlkPWNlcnRvcGVuIG9uY2hhbmdlPWFkZENlcnRCdXR0b25VcGRhdGUoKSB0eXBlPWZpbGUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHggYWNjZXB0PScuY2VyLC5wZW0nPiI7DQogICAgICAgICAgICBpZiAoeHhEcmFnRHJvcENlcnRGaWxlcykgeyBpbnB1dCA9ICc8aW5wdXQgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHggcmVhZG9ubHkgZGlzYWJsZWQgdmFsdWU9IicgKyB4eERyYWdEcm9wQ2VydEZpbGVzWzBdLm5hbWUgKyAnIj4nOyB9DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PiIgKyBpbnB1dCArICI8ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5DZXJ0aWZpY2F0ZSBmaWxlPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PHNlbGVjdCBpZD1jZXJ0dHlwZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjBweD48b3B0aW9uIHZhbHVlPTA+Q2hhaW4gQ2VydGlmaWNhdGU8L29wdGlvbj48b3B0aW9uIHZhbHVlPTE+VHJ1c3RlZCBSb290IENlcnRpZmljYXRlPC9vcHRpb24+PC9zZWxlY3Q+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+Q2VydGlmaWNhdGUgdHlwZTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiQWRkIENlcnRpZmljYXRlIiwgMywgYWRkQ2VydEJ1dHRvbk9rLCB4KTsNCiAgICAgICAgICAgIGFkZENlcnRCdXR0b25VcGRhdGUoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZENlcnRCdXR0b25VcGRhdGUoKSB7DQogICAgICAgICAgICB2YXIgY2VydG9wZW4gPSBnZXRJbnB1dEVsZW1lbnQoJ2NlcnRvcGVuJyk7DQogICAgICAgICAgICBRRSgnaWR4X2RsZ09rQnV0dG9uJywgIWNlcnRvcGVuIHx8IGNlcnRvcGVuLmZpbGVzLmxlbmd0aCA9PSAxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZENlcnRCdXR0b25PaygpIHsNCg0KICAgICAgICAgICAgdmFyIGNlcnRvcGVuID0gZ2V0SW5wdXRFbGVtZW50KCdjZXJ0b3BlbicpOw0KICAgICAgICAgICAgdmFyIGZpbGVzID0geHhEcmFnRHJvcENlcnRGaWxlczsNCiAgICAgICAgICAgIGlmIChjZXJ0b3BlbikgZmlsZXMgPSBjZXJ0b3Blbi5maWxlczsNCiAgICAgICAgICAgIGlmIChmaWxlcyAmJiBmaWxlcy5sZW5ndGggPT0gMSkgew0KICAgICAgICAgICAgICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpOw0KICAgICAgICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSBhZGRDZXJ0QnV0dG9uT2syOw0KICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkQXNCaW5hcnlTdHJpbmcoZmlsZXNbMF0pOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIA0KICAgICAgICBmdW5jdGlvbiBhZGRDZXJ0QnV0dG9uT2syKGZpbGUpIHsNCiAgICAgICAgICAgIHZhciBkYXRhID0gZmlsZS50YXJnZXQucmVzdWx0Ow0KICAgICAgICAgICAgdmFyIGkgPSBkYXRhLmluZGV4T2YoJy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLScpOw0KICAgICAgICAgICAgaWYgKGkgPiAwKSB7DQogICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBhIC5QRU0gZmlsZSwga2VlcCBldmVyeXRoaW5nIGJldHdlZW4gQkVHSU4vRU5ELCBjbGVhbiBpdCB1cCBhbmQgdXNlIGFzLWlzLiBJdCdzIGFscmVhZHkgQmFzZTY0Lg0KICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLnN1YnN0cmluZyhpICsgMjcpOw0KICAgICAgICAgICAgICAgIGkgPSBkYXRhLmluZGV4T2YoJy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0nKTsNCiAgICAgICAgICAgICAgICBpZiAoaSA+IDApIGRhdGEgPSBkYXRhLnN1YnN0cmluZygwLCBpKQ0KICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLnJlcGxhY2UoL1xyXG4vZywgJycpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGEgLkNFUiBmaWxlLCBqdXN0IGJhc2U2NCBlbmNvZGUgaXQgYW5kIHdlIHNob3VsZCBiZSBvay4NCiAgICAgICAgICAgICAgICBkYXRhID0gYnRvYShkYXRhKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChnZXRTZWxlY3RFbGVtZW50KCdjZXJ0dHlwZScpLnZhbHVlID09IDEpIHsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfQWRkVHJ1c3RlZFJvb3RDZXJ0aWZpY2F0ZShkYXRhLCBjZXJ0aWZpY2F0ZUFkZGVkKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgYW10c3RhY2suQU1UX1B1YmxpY0tleU1hbmFnZW1lbnRTZXJ2aWNlX0FkZENlcnRpZmljYXRlKGRhdGEsIGNlcnRpZmljYXRlQWRkZWQpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gaXNzdWVDZXJ0QnV0dG9uKGZpbGVzKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlIHx8ICF4eEFjY291bnRBZG1pbk5hbWUpIHJldHVybjsNCiAgICAgICAgICAgIHh4RHJhZ0Ryb3BDZXJ0RmlsZXMgPSBmaWxlczsNCg0KDQoNCiAgICAgICAgICAgIHZhciB4ID0gJycsIGlucHV0ID0gIjxpbnB1dCBpZD1jZXJ0b3BlbiB0eXBlPWZpbGUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjMwcHggb25jaGFuZ2U9aXNzdWVDZXJ0QnV0dG9uVXBkYXRlKCkgYWNjZXB0PScucDEyJz4iOw0KICAgICAgICAgICAgaWYgKHh4RHJhZ0Ryb3BDZXJ0RmlsZXMpIHsgaW5wdXQgPSAnPGlucHV0IHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIzMHB4IHJlYWRvbmx5IGRpc2FibGVkIHZhbHVlPSInICsgeHhEcmFnRHJvcENlcnRGaWxlc1swXS5uYW1lICsgJyI+JzsgfQ0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZWhlaWdodDoyNnB4O21hcmdpbi10b3A6MTRweD4iICsgaW5wdXQgKyAiPGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+Q2VydGlmaWNhdGUgZmlsZTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxpbnB1dCBvbmtleXVwPWlzc3VlQ2VydEJ1dHRvblVwZGF0ZSgpIGlkPWNlcnRvcGVucGFzcyB0eXBlPXBhc3N3b3JkIGF1dG9jb21wbGV0ZT1vZmYgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjMwcHg+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+Q2VydGlmaWNhdGUgcGFzc3dvcmQ8L2Rpdj48L2Rpdj4iOw0KDQogICAgICAgICAgICB4ICs9ICc8YnI+PGRpdiBzdHlsZT0iYm9yZGVyLWJvdHRvbToxcHggc29saWQgZ3JheSI+PGk+SW50ZWwmcmVnOyBBTVQgQ2VydGlmaWNhdGU8L2k+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IG9ua2V5dXA9aXNzdWVDZXJ0QnV0dG9uVXBkYXRlKCkgaWQ9Y2VydGNuIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIzMHB4PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PkNvbW1vbiBOYW1lPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IG9ua2V5dXA9aXNzdWVDZXJ0QnV0dG9uVXBkYXRlKCkgaWQ9Y2VydG8gc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjMwcHg+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+T3JnYW5pemF0aW9uPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IG9ua2V5dXA9aXNzdWVDZXJ0QnV0dG9uVXBkYXRlKCkgaWQ9Y2VydHN0IHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIzMHB4PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PlN0YXRlL1Byb3ZpbmNlPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IG9ua2V5dXA9aXNzdWVDZXJ0QnV0dG9uVXBkYXRlKCkgaWQ9Y2VydGMgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjMwcHg+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+Q291bnRyeTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICB4ICs9ICc8ZGl2PkNlcnRpZmljYXRlIFVzYWdlczwvZGl2Pjx1bCBzdHlsZT0ibGlzdC1zdHlsZS10eXBlOm5vbmU7aGVpZ2h0OjEwMHB4O292ZXJmbG93OmF1dG87d2lkdGg6MTAwJTtib3JkZXI6IDFweCBzb2xpZCAjMDAwO2JhY2tncm91bmQtY29sb3I6d2hpdGU7b3ZlcmZsb3cteDpoaWRkZW47bWFyZ2luOjA7cGFkZGluZzowIj4nOw0KICAgICAgICAgICAgLy94ICs9ICc8bGk+PGxhYmVsPjxpbnB1dCB0eXBlPWNoZWNrYm94IGlkPWQxMV9jdTE+SW50ZWwmcmVnOyBBTVQgQ29uc29sZTwvbGFiZWw+PC9saT4nOw0KICAgICAgICAgICAgLy94ICs9ICc8bGk+PGxhYmVsPjxpbnB1dCB0eXBlPWNoZWNrYm94IGlkPWQxMV9jdTI+SW50ZWwmcmVnOyBBTVQgQWdlbnQ8L2xhYmVsPjwvbGk+JzsNCiAgICAgICAgICAgIC8veCArPSAnPGxpPjxsYWJlbD48aW5wdXQgdHlwZT1jaGVja2JveCBpZD1kMTFfY3UzPkludGVsJnJlZzsgQU1UIEFjdGl2YXRpb248L2xhYmVsPjwvbGk+JzsNCiAgICAgICAgICAgIHggKz0gJzxsaT48bGFiZWw+PGlucHV0IHR5cGU9Y2hlY2tib3ggaWQ9ZDExX2N1NCBjaGVja2VkPlRMUyBTZXJ2ZXIgKEhUVFBTKTwvbGFiZWw+PC9saT4nOw0KICAgICAgICAgICAgeCArPSAnPGxpPjxsYWJlbD48aW5wdXQgdHlwZT1jaGVja2JveCBpZD1kMTFfY3U1PlRMUyBDbGllbnQgKEhUVFBTKTwvbGFiZWw+PC9saT4nOw0KICAgICAgICAgICAgeCArPSAnPGxpPjxsYWJlbD48aW5wdXQgdHlwZT1jaGVja2JveCBpZD1kMTFfY3U2PkVtYWlsIFByb3RlY3Rpb248L2xhYmVsPjwvbGk+JzsNCiAgICAgICAgICAgIHggKz0gJzxsaT48bGFiZWw+PGlucHV0IHR5cGU9Y2hlY2tib3ggaWQ9ZDExX2N1Nz5Db2RlIFNpZ25pbmc8L2xhYmVsPjwvbGk+JzsNCiAgICAgICAgICAgIHggKz0gJzxsaT48bGFiZWw+PGlucHV0IHR5cGU9Y2hlY2tib3ggaWQ9ZDExX2N1OD5UaW1lIFN0YW1wPC9sYWJlbD48L2xpPic7DQogICAgICAgICAgICB4ICs9ICc8L3VsPic7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiSXNzdWUgQ2VydGlmaWNhdGUiLCAzLCBpc3N1ZUNlcnRCdXR0b25PaywgeCk7DQogICAgICAgICAgICBpc3N1ZUNlcnRCdXR0b25VcGRhdGUoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGlzc3VlQ2VydEJ1dHRvblVwZGF0ZSgpIHsNCiAgICAgICAgICAgIHZhciBjZXJ0b3BlbiA9IGdldElucHV0RWxlbWVudCgnY2VydG9wZW4nKTsNCiAgICAgICAgICAgIFFFKCdjZXJ0b3BlbnBhc3MnLCAhY2VydG9wZW4gfHwgKGNlcnRvcGVuICYmIGNlcnRvcGVuLmZpbGVzLmxlbmd0aCA9PSAxKSk7DQogICAgICAgICAgICB2YXIgeCA9ICghY2VydG9wZW4gfHwgY2VydG9wZW4uZmlsZXMubGVuZ3RoIDwgMik7DQogICAgICAgICAgICBpZiAoKCFjZXJ0b3BlbiB8fCAoY2VydG9wZW4gJiYgY2VydG9wZW4uZmlsZXMubGVuZ3RoKSkgPT0gMSAmJiBRKCdjZXJ0b3BlbnBhc3MnKS52YWx1ZSA9PSAnJykgeCA9IGZhbHNlOw0KICAgICAgICAgICAgaWYgKGdldElucHV0RWxlbWVudCgnY2VydGNuJykudmFsdWUgPT0gJycgfHwgZ2V0SW5wdXRFbGVtZW50KCdjZXJ0bycpLnZhbHVlID09ICcnIHx8IGdldElucHV0RWxlbWVudCgnY2VydHN0JykudmFsdWUgPT0gJycgfHwgZ2V0SW5wdXRFbGVtZW50KCdjZXJ0YycpLnZhbHVlID09ICcnKSB7IHggPSBmYWxzZTsgfQ0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gaXNzdWVDZXJ0QnV0dG9uT2soKSB7DQoNCiAgICAgICAgICAgIHZhciBjZXJ0b3BlbiA9IGdldElucHV0RWxlbWVudCgnY2VydG9wZW4nKTsNCiAgICAgICAgICAgIHZhciBmaWxlcyA9IHh4RHJhZ0Ryb3BDZXJ0RmlsZXM7DQogICAgICAgICAgICBpZiAoY2VydG9wZW4pIGZpbGVzID0gY2VydG9wZW4uZmlsZXM7DQogICAgICAgICAgICBpZiAoZmlsZXMgJiYgZmlsZXMubGVuZ3RoID09IDEpIHsNCiAgICAgICAgICAgICAgICAvLyBJc3N1ZSBhIGNlcnRpZmljYXRlIHVzaW5nIHRoaXMgZmlsZQ0KICAgICAgICAgICAgICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpOw0KICAgICAgICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSBpc3N1ZUNlcnRCdXR0b25PazI7DQogICAgICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyhmaWxlc1swXSk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIC8vIElzc3VlIGEgY2VydGlmaWNhdGUgdXNpbmcgYSBkdW1teSBDQQ0KICAgICAgICAgICAgICAgIGlzc3VlQ2VydEJ1dHRvbk9rMyhudWxsKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGlzc3VlQ2VydEJ1dHRvbk9rMihmaWxlKSB7DQogICAgICAgICAgICAvLyBMb2FkIHRoZSBDQSBjZXJ0aWZpY2F0ZSBhbmQgcHJpdmF0ZSBrZXkNCiAgICAgICAgICAgIHZhciByID0gYW10Y2VydF9sb2FkUDEyRmlsZShmaWxlLnRhcmdldC5yZXN1bHQsIFEoJ2NlcnRvcGVucGFzcycpLnZhbHVlLCBpc3N1ZUNlcnRCdXR0b25PazMpOw0KICAgICAgICAgICAgaWYgKHIgPT0gZmFsc2UpIHsgbWVzc2FnZWJveCgiSXNzdWUgQ2VydGlmaWNhdGUiLCAiVW5hYmxlIHRvIGRlY3J5cHQvZGVjb2RlIGNlcnRpZmljYXRlLiIpOyByZXR1cm47IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGlzc3VlQ2VydEJ1dHRvbk9rMyhwcml2YXRlS2V5LCBzdWJqZWN0QXR0cmlidXRlcywgY2VydCkgew0KICAgICAgICAgICAgLy8gQXNrIEludGVsIEFNVCB0byBnZW5lcmF0ZSBhIGtleSBwYWlyDQogICAgICAgICAgICB4eENhUHJpdmF0ZUtleSA9IHByaXZhdGVLZXk7DQogICAgICAgICAgICB4eENhU3ViamVjdEF0dHJpYnV0ZXMgPSBzdWJqZWN0QXR0cmlidXRlczsNCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZV9HZW5lcmF0ZUtleVBhaXIoMCwgMjA0OCwgR2VuZXJhdGVLZXlQYWlyUmVzcG9uc2UpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gR2VuZXJhdGVLZXlQYWlyUmVzcG9uc2Uoc3RhY2ssIHNlcnZpY2VOYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBtZXNzYWdlYm94KCdJc3N1ZSBDZXJ0aWZpY2F0ZScsICdGYWlsZWQgdG8gZ2VuZXJhdGUga2V5IHBhaXIuIFN0YXR1czogJyArIHN0YXR1cyk7IHJldHVybjsgfQ0KICAgICAgICAgICAgaWYgKHJlc3BvbnNlLkJvZHlbJ1JldHVyblZhbHVlJ10gIT0gMCkgeyBtZXNzYWdlYm94KCdJc3N1ZSBDZXJ0aWZpY2F0ZScsICdGYWlsZWQgdG8gZ2VuZXJhdGUga2V5IHBhaXIsICcgKyByZXNwb25zZS5Cb2R5WydSZXR1cm5WYWx1ZVN0ciddKTsgcmV0dXJuOyB9DQoNCiAgICAgICAgICAgIC8vIEdldCB0aGUgbmV3IGtleSBwYWlyDQogICAgICAgICAgICBhbXRzdGFjay5FbnVtKCJBTVRfUHVibGljUHJpdmF0ZUtleVBhaXIiLCBHZW5lcmF0ZUtleVBhaXJSZXNwb25zZTIsIHJlc3BvbnNlLkJvZHlbJ0tleVBhaXInXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddWydWYWx1ZSddKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEdlbmVyYXRlS2V5UGFpclJlc3BvbnNlMihzdGFjaywgc2VydmljZU5hbWUsIHJlc3BvbnNlLCBzdGF0dXMsIHRhZykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsgbWVzc2FnZWJveCgnSXNzdWUgQ2VydGlmaWNhdGUnLCAnRmFpbGVkIHRvIGdlbmVyYXRlIGtleSBwYWlyLiBTdGF0dXM6ICcgKyBzdGF0dXMpOyByZXR1cm47IH0NCiAgICAgICAgICAgIHZhciBERVJLZXkgPSBudWxsOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiByZXNwb25zZSkgeyBpZiAocmVzcG9uc2VbaV1bJ0luc3RhbmNlSUQnXSA9PSB0YWcpIERFUktleSA9IHJlc3BvbnNlW2ldWydERVJLZXknXTsgfQ0KDQogICAgICAgICAgICAvLyBHZXQgY2VydGlmaWNhdGUgdmFsdWVzDQogICAgICAgICAgICB2YXIgY2VydGF0dHJpYnV0ZXMgPSB7ICdDTic6IGdldElucHV0RWxlbWVudCgnY2VydGNuJykudmFsdWUsICdPJzogZ2V0SW5wdXRFbGVtZW50KCdjZXJ0bycpLnZhbHVlLCAnU1QnOiBnZXRJbnB1dEVsZW1lbnQoJ2NlcnRzdCcpLnZhbHVlLCAnQyc6IGdldElucHV0RWxlbWVudCgnY2VydGMnKS52YWx1ZSB9Ow0KICAgICAgICAgICAgdmFyIGlzc3VlcmF0dHJpYnV0ZXMgPSB7ICdDTic6ICdVbnRydXN0ZWQgUm9vdCBDZXJ0aWZpY2F0ZScgfTsNCiAgICAgICAgICAgIGlmICh4eENhUHJpdmF0ZUtleSAhPSBudWxsICYmIHh4Q2FTdWJqZWN0QXR0cmlidXRlcykgew0KICAgICAgICAgICAgICAgIGlzc3VlcmF0dHJpYnV0ZXMgPSB7fTsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4Q2FTdWJqZWN0QXR0cmlidXRlcykgew0KICAgICAgICAgICAgICAgICAgICBpc3N1ZXJhdHRyaWJ1dGVzW3h4Q2FTdWJqZWN0QXR0cmlidXRlc1tpXS5zaG9ydE5hbWVdID0geHhDYVN1YmplY3RBdHRyaWJ1dGVzW2ldLnZhbHVlOyAvLyBUaGUgaXNzdWluZyBDQSdzIHN1YmplY3QgYXR0cmlidXRlcyANCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9IA0KDQogICAgICAgICAgICAvLyBGaWd1cmUgb3V0IHRoZSBleHRlbmRlZCBrZXkgdXNhZ2VzDQogICAgICAgICAgICB2YXIgZXh0S2V5VXNhZ2UgPSB7IG5hbWU6ICdleHRLZXlVc2FnZScgfQ0KICAgICAgICAgICAgLy9pZiAoUSgnZDExX2N1MScpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2VbJzIuMTYuODQwLjEuMTEzNzQxLjEuMi4xJ10gPSB0cnVlOyBleHRLZXlVc2FnZS5jbGllbnRBdXRoID0gdHJ1ZTsgfQ0KICAgICAgICAgICAgLy9pZiAoUSgnZDExX2N1MicpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2VbJzIuMTYuODQwLjEuMTEzNzQxLjEuMi4yJ10gPSB0cnVlOyBleHRLZXlVc2FnZS5jbGllbnRBdXRoID0gdHJ1ZTsgfQ0KICAgICAgICAgICAgLy9pZiAoUSgnZDExX2N1MycpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2VbJzIuMTYuODQwLjEuMTEzNzQxLjEuMi4zJ10gPSB0cnVlOyBleHRLZXlVc2FnZS5jbGllbnRBdXRoID0gdHJ1ZTsgfQ0KICAgICAgICAgICAgaWYgKFEoJ2QxMV9jdTQnKS5jaGVja2VkKSB7IGV4dEtleVVzYWdlLnNlcnZlckF1dGggPSB0cnVlOyB9DQogICAgICAgICAgICBpZiAoUSgnZDExX2N1NScpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2UuY2xpZW50QXV0aCA9IHRydWU7IH0NCiAgICAgICAgICAgIGlmIChRKCdkMTFfY3U2JykuY2hlY2tlZCkgeyBleHRLZXlVc2FnZS5lbWFpbFByb3RlY3Rpb24gPSB0cnVlOyB9DQogICAgICAgICAgICBpZiAoUSgnZDExX2N1NycpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2UuY29kZVNpZ25pbmcgPSB0cnVlOyB9DQogICAgICAgICAgICBpZiAoUSgnZDExX2N1OCcpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2UudGltZVN0YW1waW5nID0gdHJ1ZTsgfQ0KDQogICAgICAgICAgICAvLyBTaWduIHRoZSBrZXkgcGFpciB1c2luZyB0aGUgQ0EgY2VydGlmaWF0ZQ0KICAgICAgICAgICAgdmFyIGNlcnQgPSBhbXRjZXJ0X3NpZ25XaXRoQ2FLZXkoREVSS2V5LCB4eENhUHJpdmF0ZUtleSwgY2VydGF0dHJpYnV0ZXMsIGlzc3VlcmF0dHJpYnV0ZXMsIGV4dEtleVVzYWdlKTsNCiAgICAgICAgICAgIGlmIChjZXJ0ID09IG51bGwpIHsgbWVzc2FnZWJveCgnSXNzdWUgQ2VydGlmaWNhdGUnLCAnVW5hYmxlIHRvIHNpZ24gY2VydGlmaWNhdGUuJyk7IHJldHVybjsgfQ0KDQogICAgICAgICAgICAvLyBQbGFjZSB0aGUgcmVzdWx0aW5nIHNpZ25lZCBjZXJ0aWZpY2F0ZSBiYWNrIGludG8gQU1UDQogICAgICAgICAgICB2YXIgcGVtID0gZm9yZ2UucGtpLmNlcnRpZmljYXRlVG9QZW0oY2VydCkucmVwbGFjZSgvKFxyXG58XG58XHIpL2dtLCAiIik7DQogICAgICAgICAgICBhbXRzdGFjay5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfQWRkQ2VydGlmaWNhdGUocGVtLnN1YnN0cmluZygyNywgcGVtLmxlbmd0aCAtIDI1KSwgR2VuZXJhdGVLZXlQYWlyUmVzcG9uc2U0KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEdlbmVyYXRlS2V5UGFpclJlc3BvbnNlNChzdGFjaywgc2VydmljZU5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goJ0lzc3VlIENlcnRpZmljYXRlJywgJ0ZhaWxlZCB0byBnZW5lcmF0ZSBrZXkgcGFpci4gU3RhdHVzOiAnICsgc3RhdHVzKTsgcmV0dXJuOyB9DQogICAgICAgICAgICBQdWxsQ2VydGlmaWNhdGVzKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBjZXJ0aWZpY2F0ZUFkZGVkKHN0YWNrLCBzZXJ2aWNlTmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgeyBpZiAoc3RhdHVzICE9IDIwMCB8fCByZXNwb25zZS5Cb2R5WydSZXR1cm5WYWx1ZSddICE9IDApIHsgbWVzc2FnZWJveCgnQWRkIENlcnRpZmljYXRlJywgJ1VuYWJsZSB0byBhZGQgY2VydGlmaWNhdGUsIGVycm9yICcgKyAoc3RhdHVzICE9IDIwMCA/IHN0YXR1cyA6IHJlc3BvbnNlLkJvZHlbJ1JldHVyblZhbHVlU3RyJ10pKTsgfSBlbHNlIFB1bGxDZXJ0aWZpY2F0ZXMoKTsgfQ0KICAgICAgICBmdW5jdGlvbiBjZXJ0aWZpY2F0ZVJlbW92ZWQoc3RhY2ssIHNlcnZpY2VOYW1lLCBoZWFkZXIsIHN0YXR1cykgeyBpZiAoc3RhdHVzICE9IDIwMCkgeyBtZXNzYWdlYm94KCdSZW1vdmUgQ2VydGlmaWNhdGUnLCAnVW5hYmxlIHRvIHJlbW92ZSBjZXJ0aWZpY2F0ZSwgZXJyb3IgJyArIHN0YXR1cyk7IH0gZWxzZSBQdWxsQ2VydGlmaWNhdGVzKCk7IH0NCg0KICAgICAgICBmdW5jdGlvbiBnZXRJbnB1dEVsZW1lbnQoaWQpIHsgdmFyIGFsbGVsZW1lbnRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lucHV0Jyk7IGZvciAodCA9IDA7IHQgPCBhbGxlbGVtZW50cy5sZW5ndGg7IHQrKykgeyBpZiAoYWxsZWxlbWVudHNbdF0uaWQgPT0gaWQpIHJldHVybiBhbGxlbGVtZW50c1t0XTsgfSB9DQogICAgICAgIGZ1bmN0aW9uIGdldFNlbGVjdEVsZW1lbnQoaWQpIHsgdmFyIGFsbGVsZW1lbnRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3NlbGVjdCcpOyBmb3IgKHQgPSAwOyB0IDwgYWxsZWxlbWVudHMubGVuZ3RoOyB0KyspIHsgaWYgKGFsbGVsZW1lbnRzW3RdLmlkID09IGlkKSByZXR1cm4gYWxsZWxlbWVudHNbdF07IH0gfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dTZXRUbHNTZWN1cml0eURsZyh4KSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9ICcnOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48c2VsZWN0IG9uY2hhbmdlPXNob3dTZXRUbHNTZWN1cml0eURsZ1VwZGF0ZSgpIGlkPXRsc2NlcnQgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHg+PG9wdGlvbiB2YWx1ZT0tMT5ObyBDZXJ0aWZpY2F0ZSwgVExTIERpc2FibGVkPC9vcHRpb24+IjsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhDZXJ0aWZpY2F0ZXMpIHsgaWYgKHh4Q2VydGlmaWNhdGVzW2ldLlRydXN0ZWRSb290Q2VydGZpY2F0ZSA9PSBmYWxzZSAmJiB4eENlcnRpZmljYXRlc1tpXS5YUHJpdmF0ZUtleSAmJiAoeHhUbHNDdXJyZW50Q2VydCA9PSBudWxsIHx8IHh4VGxzQ3VycmVudENlcnQgPT0gaSkpIHsgeCArPSAiPG9wdGlvbiB2YWx1ZT0iICsgaSArICI+IiArIHh4Q2VydGlmaWNhdGVzW2ldLlhTdWJqZWN0WyJDTiJdICsgIjwvb3B0aW9uPiI7IH0gfQ0KICAgICAgICAgICAgeCArPSAiPC9zZWxlY3Q+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+Q2VydGlmaWNhdGU8L2Rpdj48L2Rpdj4iOw0KDQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxzZWxlY3QgaWQ9dGxzcmVtb3RlIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG9uY2hhbmdlPXNob3dTZXRUbHNTZWN1cml0eURsZ1VwZGF0ZSgpPjxvcHRpb24gdmFsdWU9MD5TZXJ2ZXItYXV0aCBUTFMgb25seTwvb3B0aW9uPjxvcHRpb24gdmFsdWU9MT5TZXJ2ZXItYXV0aCwgbm9uLVRMUyBhbGxvd2VkPC9vcHRpb24+IjsNCiAgICAgICAgICAgIGlmIChhbXR2ZXJzaW9uIDwgOCkgeyB4ICs9ICI8b3B0aW9uIHZhbHVlPTI+TXV0dWFsLWF1dGggVExTIG9ubHk8L29wdGlvbj48b3B0aW9uIHZhbHVlPTM+TXV0dWFsLWF1dGgsIG5vbi1UTFMgYWxsb3dlZDwvb3B0aW9uPiI7IH0gLy8gU3VwcG9ydCBmb3IgbXV0dWFsLWF1dGggVExTIHNlZW1zIHRvIGhhdmUgYmVlbiByZW1vdmVkIG9uIEFNVDggYW5kIGFmdGVyDQogICAgICAgICAgICB4ICs9ICI8L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5TZWN1cml0eTwvZGl2PjwvZGl2PjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHggaWQ9ZDExcmNuIHRpdGxlPSdDb21tYSBzZXBlcmF0ZWQgbGlzdCBvZiBjZXJ0aWZpY2F0ZSBjb21tb24gbmFtZXMgdGhhdCB3aWxsIGJlIGFsbG93ZWQgdG8gY29ubmVjdCByZW1vdGVseS4nPjxpbnB1dCBpZD1kMTFfcmNuIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG9ua2V5dXA9c2hvd1NldFRsc1NlY3VyaXR5RGxnVXBkYXRlKCkgcGxhY2Vob2xkZXI9J25hbWUxLCBuYW1lMic+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+UmVtb3RlIENOJ3M8L2Rpdj48L2Rpdj4iOw0KDQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiVExTIFNldHRpbmdzIiwgMywgc2hvd1NldFRsc1NlY3VyaXR5RGxnT2ssIHgpOw0KDQogICAgICAgICAgICAvLyBTZWxlY3QgdGhlIGN1cnJlbnQgVExTIGNlcnRpZmljYXRlIGluIHRoZSBkcm9wIGRvd24gYm94DQogICAgICAgICAgICBpZiAoKHh4VExTQ3JlZGVudGlhbENvbnRleHQubGVuZ3RoID09IDApIHx8ICh4eFRsc1NldHRpbmdzWzBdWydFbmFibGVkJ10gPT0gZmFsc2UpIHx8ICh4eFRsc1NldHRpbmdzWzFdWydFbmFibGVkJ10gPT0gZmFsc2UpKSB7DQogICAgICAgICAgICAgICAgZ2V0U2VsZWN0RWxlbWVudCgndGxzY2VydCcpLnZhbHVlID0gLTE7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHZhciBjZXJ0SW5zdGFuY2VJZCA9IHh4VExTQ3JlZGVudGlhbENvbnRleHRbMF1bJ0VsZW1lbnRJbkNvbnRleHQnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddWydWYWx1ZSddOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhDZXJ0aWZpY2F0ZXMpIHsgaWYgKHh4Q2VydGlmaWNhdGVzW2ldWydJbnN0YW5jZUlEJ10gPT0gY2VydEluc3RhbmNlSWQpIHsgZ2V0U2VsZWN0RWxlbWVudCgndGxzY2VydCcpLnZhbHVlID0gaTsgfSB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIEZpZ3VyZSBvdXQgd2hhdCBpbmRleCBpcyBsb2NhbCAmIHJlbW90ZQ0KICAgICAgICAgICAgdmFyIGxvY2FsTmR4ID0gKCh4eFRsc1NldHRpbmdzWzBdWydJbnN0YW5jZUlEJ10gPT0gJ0ludGVsKHIpIEFNVCBMTVMgVExTIFNldHRpbmdzJykpID8gMCA6IDEsIHJlbW90ZU5keCA9ICgxIC0gbG9jYWxOZHgpOw0KDQogICAgICAgICAgICAvLyBTZWxlY3QgY29ycmVjdCBUTFMgb3B0aW9ucyBpbiB0aGUgZHJvcCBkb3duIGJveGVzDQogICAgICAgICAgICBnZXRTZWxlY3RFbGVtZW50KCd0bHNyZW1vdGUnKS52YWx1ZSA9ICgoeHhUbHNTZXR0aW5nc1tyZW1vdGVOZHhdWydNdXR1YWxBdXRoZW50aWNhdGlvbiddID09IHRydWUpID8gMiA6IDApICsgKCh4eFRsc1NldHRpbmdzW3JlbW90ZU5keF1bJ0FjY2VwdE5vblNlY3VyZUNvbm5lY3Rpb25zJ10gPT0gdHJ1ZSkgPyAxIDogMCk7DQogICAgICAgICAgICBpZiAoeHhUbHNTZXR0aW5nc1tyZW1vdGVOZHhdWydUcnVzdGVkQ04nXSkgeyBRKCdkMTFfcmNuJykudmFsdWUgPSBNYWtlVG9BcnJheSh4eFRsc1NldHRpbmdzW3JlbW90ZU5keF1bJ1RydXN0ZWRDTiddKS5qb2luKCcsICcpOyB9DQoNCiAgICAgICAgICAgIHNob3dTZXRUbHNTZWN1cml0eURsZ1VwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1NldFRsc1NlY3VyaXR5RGxnVXBkYXRlKCkgew0KICAgICAgICAgICAgdmFyIGggPSBnZXRTZWxlY3RFbGVtZW50KCd0bHNjZXJ0JykudmFsdWU7DQogICAgICAgICAgICBRRSgndGxzcmVtb3RlJywgaCAhPSAtMSk7DQogICAgICAgICAgICBRVignZDExcmNuJywgKGggIT0gLTEpICYmIChnZXRTZWxlY3RFbGVtZW50KCd0bHNyZW1vdGUnKS52YWx1ZSA+IDEpKTsNCiAgICAgICAgICAgIHZhciBvayA9IHRydWU7DQogICAgICAgICAgICBpZiAoKGdldFNlbGVjdEVsZW1lbnQoJ3Rsc3JlbW90ZScpLnZhbHVlID4gMSkgJiYgKCFzcGxpdERvbWFpbnMoUSgnZDExX3JjbicpLnZhbHVlKSkpIHsgb2sgPSBmYWxzZTsgfQ0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgfQ0KDQogICAgICAgIHZhciBzZXRUbHNTZWN1cml0eVBlbmRpbmdDYWxsczsNCiAgICAgICAgdmFyIHNldFRsc1NlY3VyaXR5RGVsZXRlQ3JlZGVudGlhbENvbnRleHQ7DQogICAgICAgIGZ1bmN0aW9uIHNob3dTZXRUbHNTZWN1cml0eURsZ09rKCkgew0KICAgICAgICAgICAgdmFyIGggPSBnZXRTZWxlY3RFbGVtZW50KCd0bHNjZXJ0JykudmFsdWU7DQogICAgICAgICAgICB2YXIgciA9IGdldFNlbGVjdEVsZW1lbnQoJ3Rsc3JlbW90ZScpLnZhbHVlOw0KICAgICAgICAgICAgdmFyIHh4VGxzU2V0dGluZ3MyID0gQ2xvbmUoeHhUbHNTZXR0aW5ncyk7DQogICAgICAgICAgICBzZXRUbHNTZWN1cml0eVBlbmRpbmdDYWxscyA9IDA7DQogICAgICAgICAgICBzZXRUbHNTZWN1cml0eURlbGV0ZUNyZWRlbnRpYWxDb250ZXh0ID0gbnVsbDsNCg0KICAgICAgICAgICAgaWYgKGggIT0gLTEpIHsNCiAgICAgICAgICAgICAgICAvLyBTZXQgdGhlIFRMUyBjZXJ0aWZpY2F0ZQ0KICAgICAgICAgICAgICAgIGlmICh4eFRMU0NyZWRlbnRpYWxDb250ZXh0Lmxlbmd0aCA+IDApIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gTW9kaWZ5IHRoZSBjdXJyZW50IGNvbnRleHQNCiAgICAgICAgICAgICAgICAgICAgdmFyIG5ld1RMU0NyZWRlbnRpYWxDb250ZXh0ID0gQ2xvbmUoeHhUTFNDcmVkZW50aWFsQ29udGV4dFswXSk7DQogICAgICAgICAgICAgICAgICAgIG5ld1RMU0NyZWRlbnRpYWxDb250ZXh0WydFbGVtZW50SW5Db250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXVsnVmFsdWUnXSA9IHh4Q2VydGlmaWNhdGVzW2hdWydJbnN0YW5jZUlEJ107DQogICAgICAgICAgICAgICAgICAgIGFtdHN0YWNrLlB1dCgnQU1UX1RMU0NyZWRlbnRpYWxDb250ZXh0JywgbmV3VExTQ3JlZGVudGlhbENvbnRleHQsIHNldFRsc1NlY3VyaXR5UmVzcG9uc2UsIDAsIDEpOw0KICAgICAgICAgICAgICAgICAgICBzZXRUbHNTZWN1cml0eVBlbmRpbmdDYWxscysrOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIC8vIEFkZCBhIG5ldyBzZWN1cml0eSBjb250ZXh0DQogICAgICAgICAgICAgICAgICAgIGFtdHN0YWNrLkNyZWF0ZSgnQU1UX1RMU0NyZWRlbnRpYWxDb250ZXh0Jywgew0KICAgICAgICAgICAgICAgICAgICAgICAgJ0VsZW1lbnRJbkNvbnRleHQnOic8YTpBZGRyZXNzPi93c21hbjwvYTpBZGRyZXNzPjxhOlJlZmVyZW5jZVBhcmFtZXRlcnM+PHc6UmVzb3VyY2VVUkk+JyArIGFtdHN0YWNrLkNvbXBsZXRlTmFtZSgnQU1UX1B1YmxpY0tleUNlcnRpZmljYXRlJykgKyAnPC93OlJlc291cmNlVVJJPjx3OlNlbGVjdG9yU2V0Pjx3OlNlbGVjdG9yIE5hbWU9Ikluc3RhbmNlSUQiPicgKyB4eENlcnRpZmljYXRlc1toXVsnSW5zdGFuY2VJRCddICsgJzwvdzpTZWxlY3Rvcj48L3c6U2VsZWN0b3JTZXQ+PC9hOlJlZmVyZW5jZVBhcmFtZXRlcnM+JywNCiAgICAgICAgICAgICAgICAgICAgICAgICdFbGVtZW50UHJvdmlkaW5nQ29udGV4dCc6JzxhOkFkZHJlc3M+L3dzbWFuPC9hOkFkZHJlc3M+PGE6UmVmZXJlbmNlUGFyYW1ldGVycz48dzpSZXNvdXJjZVVSST4nICsgYW10c3RhY2suQ29tcGxldGVOYW1lKCdBTVRfVExTUHJvdG9jb2xFbmRwb2ludENvbGxlY3Rpb24nKSArICc8L3c6UmVzb3VyY2VVUkk+PHc6U2VsZWN0b3JTZXQ+PHc6U2VsZWN0b3IgTmFtZT0iRWxlbWVudE5hbWUiPlRMU1Byb3RvY29sRW5kcG9pbnRJbnN0YW5jZXMgQ29sbGVjdGlvbjwvdzpTZWxlY3Rvcj48L3c6U2VsZWN0b3JTZXQ+PC9hOlJlZmVyZW5jZVBhcmFtZXRlcnM+JyB9LCBzZXRUbHNTZWN1cml0eVJlc3BvbnNlKTsNCiAgICAgICAgICAgICAgICAgICAgc2V0VGxzU2VjdXJpdHlQZW5kaW5nQ2FsbHMrKzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIC8vIENsZWFyIHRoZSBUTFMgY2VydGlmaWNhdGUgYXNzb2NpYXRpb24gKE1PVkUgVEhJUykNCiAgICAgICAgICAgICAgICBpZiAoeHhUTFNDcmVkZW50aWFsQ29udGV4dC5sZW5ndGggPiAwKSB7IHNldFRsc1NlY3VyaXR5RGVsZXRlQ3JlZGVudGlhbENvbnRleHQgPSBDbG9uZSh4eFRMU0NyZWRlbnRpYWxDb250ZXh0WzBdKTsgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBGaWd1cmUgb3V0IHdoYXQgaW5kZXggaXMgbG9jYWwgJiByZW1vdGUNCiAgICAgICAgICAgIHZhciBsb2NhbE5keCA9ICgoeHhUbHNTZXR0aW5nc1swXVsnSW5zdGFuY2VJRCddID09ICdJbnRlbChyKSBBTVQgTE1TIFRMUyBTZXR0aW5ncycpKSA/IDAgOiAxLCByZW1vdGVOZHggPSAoMSAtIGxvY2FsTmR4KTsNCg0KICAgICAgICAgICAgLy8gUmVtb3RlIFRMUyBzZXR0aW5ncw0KICAgICAgICAgICAgeHhUbHNTZXR0aW5nczJbcmVtb3RlTmR4XVsnRW5hYmxlZCddID0gKGggIT0gLTEpOw0KICAgICAgICAgICAgeHhUbHNTZXR0aW5nczJbcmVtb3RlTmR4XVsnTXV0dWFsQXV0aGVudGljYXRpb24nXSA9IChyID49IDIpOw0KICAgICAgICAgICAgeHhUbHNTZXR0aW5nczJbcmVtb3RlTmR4XVsnQWNjZXB0Tm9uU2VjdXJlQ29ubmVjdGlvbnMnXSA9ICgociAlIDIpID09IDEpOw0KICAgICAgICAgICAgeHhUbHNTZXR0aW5nczJbcmVtb3RlTmR4XVsnVHJ1c3RlZENOJ10gPSBzcGxpdERvbWFpbnMoUSgnZDExX3JjbicpLnZhbHVlKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgLy8gTG9jYWwgVExTIHNldHRpbmdzDQogICAgICAgICAgICB4eFRsc1NldHRpbmdzMltsb2NhbE5keF1bJ0VuYWJsZWQnXSA9IChoICE9IC0xKTsNCg0KICAgICAgICAgICAgLy8gVXBkYXRlIFRMUyBzZXR0aW5ncw0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfVExTU2V0dGluZ0RhdGEnLCB4eFRsc1NldHRpbmdzMlswXSwgc2V0VGxzU2VjdXJpdHlSZXNwb25zZSwgMCwgMSwgeHhUbHNTZXR0aW5nczJbMF0pOw0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfVExTU2V0dGluZ0RhdGEnLCB4eFRsc1NldHRpbmdzMlsxXSwgc2V0VGxzU2VjdXJpdHlSZXNwb25zZSwgMCwgMSwgeHhUbHNTZXR0aW5nczJbMV0pOw0KICAgICAgICAgICAgc2V0VGxzU2VjdXJpdHlQZW5kaW5nQ2FsbHMgKz0gMjsNCg0KICAgICAgICAgICAgc3RhdHVzYm94KCJUTFMgU2V0dGluZ3MiLCAiQXBwbHlpbmcgbmV3IHNlY3VyaXR5IHNldHRpbmdzLi4uIik7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBTcGxpdCBhIHN0cmluZyBpbnRvIGEgYXJyYXkgb2YgZG9tYWlucy4gUmV0dXJuIG51bGwgaWYgbm90IGEgdmFsaWQgbGlzdC4NCiAgICAgICAgZnVuY3Rpb24gc3BsaXREb21haW5zKHN0cikgew0KICAgICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCcsJyk7DQogICAgICAgICAgICBpZiAoc3RyLmxlbmd0aCA9PSAwKSByZXR1cm47DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHN0cikgeyBzdHJbaV0gPSBzdHJbaV0udHJpbSgpOyBpZiAoKHN0cltpXS5pbmRleE9mKCcgJykgPj0gMCkgfHwgKHN0cltpXS5sZW5ndGggPT0gMCkpIHJldHVybjsgfQ0KICAgICAgICAgICAgaWYgKHN0ci5sZW5ndGggPiA0KSByZXR1cm47DQogICAgICAgICAgICByZXR1cm4gc3RyOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2V0VGxzU2VjdXJpdHlSZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBtZXNzYWdlYm94KCIiLCAiRmFpbGVkIHRvIHNldCBUTFMgc2VjdXJpdHksIHN0YXR1cyA9ICIgKyBzdGF0dXMpOyByZXR1cm47IH0NCiAgICAgICAgICAgIGlmIChyZXNwb25zZS5Cb2R5WydSZXR1cm5WYWx1ZVN0ciddICYmICFtZXRob2RjaGVjayhyZXNwb25zZSkpIHJldHVybjsNCg0KICAgICAgICAgICAgLy8gQ2hlY2sgaWYgYWxsIHRoZSBjYWxscyBhcmUgZG9uZQ0KICAgICAgICAgICAgaWYgKCgtLXNldFRsc1NlY3VyaXR5UGVuZGluZ0NhbGxzKSA9PSAwKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIC8vIFBlcmZvcm0gYSBjb21taXQNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9Db21taXRDaGFuZ2VzKG51bGwsIHNldFRsc1NlY3VyaXR5UmVzcG9uc2UyKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNldFRsc1NlY3VyaXR5UmVzcG9uc2UyKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBtZXNzYWdlYm94KCIiLCAiRmFpbGVkIHRvIHNldCBUTFMgc2VjdXJpdHksIHN0YXR1cyA9ICIgKyBzdGF0dXMpOyByZXR1cm47IH0NCiAgICAgICAgICAgIC8vIGlmIChyZXNwb25zZS5Cb2R5WydSZXR1cm5WYWx1ZVN0ciddICYmICFtZXRob2RjaGVjayhyZXNwb25zZSkpIHJldHVybjsNCiAgICAgICAgICAgIHNldFRpbWVvdXQoc2V0VGxzU2VjdXJpdHlSZXNwb25zZTMsIDIwMDApOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2V0VGxzU2VjdXJpdHlSZXNwb25zZTMoKSB7DQogICAgICAgICAgICBpZiAoc2V0VGxzU2VjdXJpdHlEZWxldGVDcmVkZW50aWFsQ29udGV4dCAhPSBudWxsKSB7IGFtdHN0YWNrLkRlbGV0ZSgnQU1UX1RMU0NyZWRlbnRpYWxDb250ZXh0Jywgc2V0VGxzU2VjdXJpdHlEZWxldGVDcmVkZW50aWFsQ29udGV4dCwgZnVuY3Rpb24gKCkgeyB9KTsgfQ0KICAgICAgICAgICAgUHVsbENlcnRpZmljYXRlcygpOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgpOw0KICAgICAgICB9DQoNCg0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gQUdFTlQgUFJFU0VOQ0UNCiAgICAgICAgLy8NCg0KICAgICAgICB2YXIgeHhXYXRjaGRvZyA9IG51bGw7DQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbFdhdGNoZG9nKCkgew0KICAgICAgICAgICAgYW10c3RhY2suQmF0Y2hFbnVtKG51bGwsIFsiKkFNVF9BZ2VudFByZXNlbmNlQ2FwYWJpbGl0aWVzIiwgIkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2ciLCAiQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ0FjdGlvbiIsICJBTVRfU3RhdGVUcmFuc2l0aW9uQ29uZGl0aW9uIiwgIkNJTV9Db25jcmV0ZURlcGVuZGVuY3kiXSwgUHVsbFdhdGNoZG9nUmVzcG9uc2UpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbFdhdGNoZG9nUmVzcG9uc2Uoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoKHN0YXR1cyA9PSAyMDApICYmIChyZXNwb25zZXNbJ0FNVF9BZ2VudFByZXNlbmNlQ2FwYWJpbGl0aWVzJ10uc3RhdHVzID09IDIwMCkpIHsNCiAgICAgICAgICAgICAgICB4eFdhdGNoZG9nID0gcmVzcG9uc2VzOw0KICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8gUGxhY2UgdGhlIGFjdGlvbnMgaW50byB0aGUgd2F0Y2hkb2dzIGZvciBlYXN5IG5hdmlnYXRpb24uDQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eFdhdGNoZG9nWydDSU1fQ29uY3JldGVEZXBlbmRlbmN5J10ucmVzcG9uc2VzKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBsaW5rID0geHhXYXRjaGRvZ1snQ0lNX0NvbmNyZXRlRGVwZW5kZW5jeSddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHgxID0gZ2V0SXRlbShsaW5rWydBbnRlY2VkZW50J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXSwgJ0BOYW1lJywgJ0NyZWF0aW9uQ2xhc3NOYW1lJyk7DQogICAgICAgICAgICAgICAgICAgIGlmICh4MSAmJiB4MVsnVmFsdWUnXSA9PSAnQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZycpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZXZpY2VpZCA9IGdldEl0ZW0obGlua1snQW50ZWNlZGVudCddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ10sICdATmFtZScsICdEZXZpY2VJRCcpWydWYWx1ZSddOw0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBvbGljeUNvbmRpdGlvbk5hbWUgPSBnZXRJdGVtKGxpbmtbJ0RlcGVuZGVudCddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ10sICdATmFtZScsICdQb2xpY3lDb25kaXRpb25OYW1lJylbJ1ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2F0Y2hkb2cgPSBnZXRJdGVtKHh4V2F0Y2hkb2dbJ0FNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2cnXS5yZXNwb25zZXMsICdEZXZpY2VJRCcsIGRldmljZWlkKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0cmFuc2l0aW9uUG9saWN5ID0gZ2V0SXRlbSh4eFdhdGNoZG9nWydBTVRfU3RhdGVUcmFuc2l0aW9uQ29uZGl0aW9uJ10ucmVzcG9uc2VzLCAnUG9saWN5Q29uZGl0aW9uTmFtZScsIHBvbGljeUNvbmRpdGlvbk5hbWUpOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF3YXRjaGRvZy50cmFuc2l0aW9ucykgd2F0Y2hkb2cudHJhbnNpdGlvbnMgPSBbXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHdhdGNoZG9nLnRyYW5zaXRpb25zLnB1c2godHJhbnNpdGlvblBvbGljeSk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKHgxICYmIHgxWydWYWx1ZSddID09ICdBTVRfU3RhdGVUcmFuc2l0aW9uQ29uZGl0aW9uJykgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBvbGljeUNvbmRpdGlvbk5hbWUgPSBnZXRJdGVtKGxpbmtbJ0FudGVjZWRlbnQnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddLCAnQE5hbWUnLCAnUG9saWN5Q29uZGl0aW9uTmFtZScpWydWYWx1ZSddOw0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBvbGljeUFjdGlvbk5hbWUgPSBnZXRJdGVtKGxpbmtbJ0RlcGVuZGVudCddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ10sICdATmFtZScsICdQb2xpY3lBY3Rpb25OYW1lJylbJ1ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJhbnNpdGlvblBvbGljeSA9IGdldEl0ZW0oeHhXYXRjaGRvZ1snQU1UX1N0YXRlVHJhbnNpdGlvbkNvbmRpdGlvbiddLnJlc3BvbnNlcywgJ1BvbGljeUNvbmRpdGlvbk5hbWUnLCBwb2xpY3lDb25kaXRpb25OYW1lKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3YXRjaGRvZ0FjdGlvbiA9IGdldEl0ZW0oeHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ0FjdGlvbiddLnJlc3BvbnNlcywgJ1BvbGljeUFjdGlvbk5hbWUnLCBwb2xpY3lBY3Rpb25OYW1lKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdHJhbnNpdGlvblBvbGljeS5hY3Rpb25zKSB0cmFuc2l0aW9uUG9saWN5LmFjdGlvbnMgPSBbXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zaXRpb25Qb2xpY3kuYWN0aW9ucy5wdXNoKHdhdGNoZG9nQWN0aW9uKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIHVwZGF0ZVdhdGNoZG9nKCk7DQogICAgICAgICAgICAgICAgUVYoJ2dvMTknLCB0cnVlKTsgLy8gU2hvdyBBZ2VudCBQcmVzZW5jZSBwYW5lbA0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIHdhdGNoZG9nRW5hYmxlZFN0YXRlcyA9IFsgJ1Vua25vd24nLCAnT3RoZXInLCAnRW5hYmxlZCcsICdEaXNhYmxlZCcsICdTaHV0dGluZyBEb3duJywgJ05vdCBBcHBsaWNhYmxlJywgJ0VuYWJsZWQgYnV0IE9mZmxpbmUnLCAnSW4gVGVzdCcsICdEZWZlcnJlZCcsICdRdWllc2NlJywgJ1N0YXJ0aW5nJyBdOw0KICAgICAgICB2YXIgd2F0Y2hkb2dNb25pdG9yZWRFbnRpdHkgPSBbICdVbmtub3duJywgJ090aGVyJywgJ09wZXJhdGluZyBTeXN0ZW0nLCAnT3BlcmF0aW5nIFN5c3RlbSBCb290IFByb2Nlc3MnLCAnT3BlcmF0aW5nIFN5c3RlbSBTaHV0ZG93biBQcm9jZXNzJywgJ0Zpcm13YXJlIEJvb3QgUHJvY2VzcycsICdCSU9TIEJvb3QgUHJvY2VzcycsICdBcHBsaWNhdGlvbicsICdTZXJ2aWNlIFByb2Nlc3NvcicgXTsNCiAgICAgICAgZnVuY3Rpb24gdXBkYXRlV2F0Y2hkb2coKSB7DQogICAgICAgICAgICBpZiAoeHhXYXRjaGRvZyA9PSBudWxsKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9ICcnOw0KDQogICAgICAgICAgICAvLyBHbG9iYWwgQWdlbnQgUHJlc2Vuc2UgVmFsdWVzDQogICAgICAgICAgICB4ICs9IFRhYmxlU3RhcnQoKTsNCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiTWF4aW11bSBXYXRjaGRvZ3MiLCB4eFdhdGNoZG9nWydBTVRfQWdlbnRQcmVzZW5jZUNhcGFiaWxpdGllcyddLnJlc3BvbnNlWydNYXhUb3RhbEFnZW50cyddICsgIiB3YXRjaGRvZ3MiKTsNCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiTWF4aW11bSBUb3RhbCBBY3Rpb25zIiwgeHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VDYXBhYmlsaXRpZXMnXS5yZXNwb25zZVsnTWF4VG90YWxBY3Rpb25zJ10gKyAiIGFjdGlvbnMiKTsNCiAgICAgICAgICAgIC8vIHggKz0gVGFibGVFbnRyeSgiTWF4aW11bSBFQUMgV2F0Y2hkb2dzIiwgeHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VDYXBhYmlsaXRpZXMnXS5yZXNwb25zZVsnTWF4RWFjQWdlbnRzJ10gKyAiIHdhdGNoZG9ncyIpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpICsgIjxicj4iOw0KDQogICAgICAgICAgICAvLyBXYXRjaGRvZ3MNCiAgICAgICAgICAgIHggKz0gVGFibGVTdGFydDIoKTsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPk1hbmFnZSBJbnRlbCZyZWc7IEFNVCBhZ2VudCBwcmVzZW5jZSB3YXRjaGRvZ3MuPGJyPjxicj4iOw0KICAgICAgICAgICAgaWYgKCh4eFdhdGNoZG9nWydBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nJ10ucmVzcG9uc2VzID09IG51bGwpIHx8ICh4eFdhdGNoZG9nWydBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nJ10ucmVzcG9uc2VzLmxlbmd0aCA9PSAwKSkgew0KICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGk+Tm8gYWdlbnQgcHJlc2VuY2Ugd2F0Y2hkb2cgZm91bmQuPC9pPjwvZGl2Pjxicj4iOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4V2F0Y2hkb2dbJ0FNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2cnXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHcgPSB4eFdhdGNoZG9nWydBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nJ10ucmVzcG9uc2VzW2ldOw0KICAgICAgICAgICAgICAgICAgICB2YXIgbiA9IGd1aWRUb1N0cihyc3RyMmhleChhdG9iKHdbJ0RldmljZUlEJ10pKSk7DQogICAgICAgICAgICAgICAgICAgIGlmICh3WydNb25pdG9yZWRFbnRpdHlEZXNjcmlwdGlvbiddICYmIHdbJ01vbml0b3JlZEVudGl0eURlc2NyaXB0aW9uJ10gIT0gJycpIG4gPSBFc2NhcGVIdG1sKHdbJ01vbml0b3JlZEVudGl0eURlc2NyaXB0aW9uJ10pOw0KICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93V2F0Y2hkb2dEZXRhaWxzKCIgKyBpICsgIik+PGlucHV0IHR5cGU9YnV0dG9uIHN0eWxlPWZsb2F0OnJpZ2h0IHZhbHVlPSdBZGQgQWN0aW9uLi4uJyBvbmNsaWNrPWFkZFdhdGNoZG9nQWN0aW9uKGV2ZW50LCIgKyBpICsgIik+IjsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHcudHJhbnNpdGlvbnMpIHsgeCArPSAiPGlucHV0IHR5cGU9YnV0dG9uIHN0eWxlPWZsb2F0OnJpZ2h0IHZhbHVlPSdEZWxldGUgQWN0aW9ucy4uLicgb25jbGljaz1kZWxldGVXYXRjaGRvZ0FjdGlvbnMoZXZlbnQsIiArIGkgKyAiKT4iOyB9DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PjxiPiIgKyBuICsgIjwvYj4sICIgKyBhbXRzdGFjay5XYXRjaGRvZ0N1cnJlbnRTdGF0ZXNbd1snQ3VycmVudFN0YXRlJ11dICsgIjwvZGl2PiI7DQogICAgICAgICAgICAgICAgICAgIHZhciB4eCA9ICcnOw0KICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqIGluIHcudHJhbnNpdGlvbnMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0ID0gdy50cmFuc2l0aW9uc1tqXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4eCAhPSAnJykgeHggKz0gIjxicj4iOw0KICAgICAgICAgICAgICAgICAgICAgICAgeHggKz0gZ2V0V2F0Y2hkb2dUcmFuc2l0aW9uU3RyKHRbJ09sZFN0YXRlJ10pICsgIiAmcmFycjsgIiArIGdldFdhdGNoZG9nVHJhbnNpdGlvblN0cih0WydOZXdTdGF0ZSddKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0LmFjdGlvbnMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWN0aW9uID0gdC5hY3Rpb25zWzBdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhY3Rpb25bJ0V2ZW50T25UcmFuc2l0aW9uJ10gPT0gdHJ1ZSkgeyB4eCArPSAiIDogRXZlbnQgdG8gbG9nIjsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGlmICh4eCAhPSAnJykgeyB4ICs9ICI8ZGl2IHN0eWxlPXBhZGRpbmc6MTJweD4iICsgeHggKyAiPC9kaXY+IjsgfQ0KICAgICAgICAgICAgICAgICAgICB4ICs9ICI8L2Rpdj4iOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gIjxicj4iOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZChBZGRSZWZyZXNoQnV0dG9uKCJQdWxsV2F0Y2hkb2coKSIpICsgQWRkQnV0dG9uKCJBZGQgV2F0Y2hkb2cuLi4iLCAiQWRkV2F0Y2hkb2coKSIpKTsNCiAgICAgICAgICAgIHggKz0gIjxicj4iOw0KDQogICAgICAgICAgICBRSCgnaWRfVGFibGVTeXN0ZW1BZ2VudFByZXNlbmNlJywgeCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBnZXRXYXRjaGRvZ1RyYW5zaXRpb25TdHIocykgew0KICAgICAgICAgICAgaWYgKHMgPT0gMzEpIHJldHVybiAiQW55IFN0YXRlIjsNCiAgICAgICAgICAgIHZhciB4ID0gJyc7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIGFtdHN0YWNrLldhdGNoZG9nQ3VycmVudFN0YXRlcykgeyBpZiAoKHMgJiBpKSAhPSAwKSB7IHggKz0gJywgJyArIGFtdHN0YWNrLldhdGNoZG9nQ3VycmVudFN0YXRlc1tpXTsgfSB9DQogICAgICAgICAgICByZXR1cm4geC5zdWJzdHJpbmcoMik7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93V2F0Y2hkb2dEZXRhaWxzKGkpIHsNCiAgICAgICAgICAgIHZhciB3ID0geHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZyddLnJlc3BvbnNlc1tpXTsNCg0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIC8veCArPSBhZGRIdG1sVmFsdWUoJ0RldmljZUlEJywgZ3VpZFRvU3RyKHJzdHIyaGV4KGF0b2Iod1snRGV2aWNlSUQnXSkpKSk7DQogICAgICAgICAgICBpZiAod1snTW9uaXRvcmVkRW50aXR5RGVzY3JpcHRpb24nXSAmJiB3WydNb25pdG9yZWRFbnRpdHlEZXNjcmlwdGlvbiddICE9ICcnKSB4ICs9IGFkZEh0bWxWYWx1ZSgnRGVzY3JpcHRpb24nLCBFc2NhcGVIdG1sKHdbJ01vbml0b3JlZEVudGl0eURlc2NyaXB0aW9uJ10pKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCdNb25pdG9yZWQgRW50aXR5Jywgd2F0Y2hkb2dNb25pdG9yZWRFbnRpdHlbd1snTW9uaXRvcmVkRW50aXR5J11dKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCdDdXJyZW50IFN0YXRlJywgYW10c3RhY2suV2F0Y2hkb2dDdXJyZW50U3RhdGVzW3dbJ0N1cnJlbnRTdGF0ZSddXSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnRW5hYmxlZCBTdGF0ZScsIHdhdGNoZG9nRW5hYmxlZFN0YXRlc1t3WydFbmFibGVkU3RhdGUnXV0pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ1N0YXJ0dXAgSW50ZXJ2YWwnLCB3WydTdGFydHVwSW50ZXJ2YWwnXSArICcgc2Vjb25kKHMpJyk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnVGltZW91dCBJbnRlcnZhbCcsIHdbJ1RpbWVvdXRJbnRlcnZhbCddICsgJyBzZWNvbmQocyknKTsNCg0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgJ1dhdGNoZG9nICcgKyBndWlkVG9TdHIocnN0cjJoZXgoYXRvYih3WydEZXZpY2VJRCddKSkpLCA1LCBzaG93V2F0Y2hkb2dEZXRhaWxzT2ssIHgsIHcpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1dhdGNoZG9nRGV0YWlsc09rKHgsIHcpIHsNCiAgICAgICAgICAgIGlmICh4ID09IDIpIHsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5EZWxldGUoJ0FNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2cnLCB7ICdEZXZpY2VJRCc6IHdbJ0RldmljZUlEJ10gfSwgUHVsbFdhdGNoZG9nKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEFkZFdhdGNoZG9nKCkgew0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IGlkPXdnbmFtZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNDBweCBtYXhsZW5ndGg9MTYgb25rZXl1cD1BZGRXYXRjaGRvZ1VwZGF0ZSgpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4Pk5hbWU8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48aW5wdXQgaWQ9d2dndWlkIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI0MHB4IG1heGxlbmd0aD0zNiBvbmtleXVwPUFkZFdhdGNoZG9nVXBkYXRlKCk+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHggdGl0bGU9J0dlbmVyYXRlIHJhbmRvbSBEZXZpY2VJRCc+IiArIGFkZExpbmsoIkRldmljZUlEIiwgIkdlbmVyYXRlV2F0Y2hkb2dHdWlkKCkiKSArICI8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48aW5wdXQgaWQ9d2dzdGFydCBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNDBweCBtYXhsZW5ndGg9OCBwbGFjZWhvbGRlcj0zNjAwIG9ua2V5dXA9QWRkV2F0Y2hkb2dVcGRhdGUoKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5TdGFydHVwIChzZWNvbmRzKTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxpbnB1dCBpZD13Z3RpbWVvdXQgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjQwcHggbWF4bGVuZ3RoPTggcGxhY2Vob2xkZXI9NjAgb25rZXl1cD1BZGRXYXRjaGRvZ1VwZGF0ZSgpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PlRpbWVvdXQgKHNlY29uZHMpPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdBZGQgV2F0Y2hkb2cnLCAzLCBBZGRXYXRjaGRvZ09rLCB4KTsNCiAgICAgICAgICAgIEFkZFdhdGNoZG9nVXBkYXRlKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBHZW5lcmF0ZVdhdGNoZG9nR3VpZCgpIHsNCiAgICAgICAgICAgIHZhciBpLCBndWlkID0gJyc7DQogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgeyBndWlkICs9IFN0cmluZy5mcm9tQ2hhckNvZGUocmFuZG9tKDI1NSkpOyB9DQogICAgICAgICAgICBRKCd3Z2d1aWQnKS52YWx1ZSA9IGd1aWRUb1N0cihyc3RyMmhleChndWlkKSk7DQogICAgICAgICAgICBBZGRXYXRjaGRvZ1VwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkV2F0Y2hkb2dVcGRhdGUoKSB7DQogICAgICAgICAgICB2YXIgb2sgPSAoUSgnd2dzdGFydCcpLnZhbHVlID09ICcnIHx8IHBhcnNlSW50KFEoJ3dnc3RhcnQnKS52YWx1ZSkgPiAwKSAmJiAoUSgnd2d0aW1lb3V0JykudmFsdWUgPT0gJycgfHwgcGFyc2VJbnQoUSgnd2d0aW1lb3V0JykudmFsdWUpID4gMCk7DQogICAgICAgICAgICB2YXIgZ2MgPSAwLCBnID0gUSgnd2dndWlkJykudmFsdWUudG9Mb3dlckNhc2UoKTsNCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZy5sZW5ndGg7IGkrKykgew0KICAgICAgICAgICAgICAgIHZhciBjID0gZy5jaGFyQ29kZUF0KGkpOw0KICAgICAgICAgICAgICAgIGlmIChjID09IDQ1KSBjb250aW51ZTsNCiAgICAgICAgICAgICAgICBpZiAoKGMgPj0gNDggJiYgYyA8PSA1NykgfHwgKGMgPj0gOTcgJiYgYyA8PSAxMDIpKSB7IGdjKys7IH0gZWxzZSB7IG9rID0gZmFsc2U7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChnYyAhPSAzMikgb2sgPSBmYWxzZTsNCiAgICAgICAgICAgIFFFKCdkbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEFkZFdhdGNoZG9nT2soKSB7DQogICAgICAgICAgICB2YXIgdGltZW91dCA9IFEoJ3dndGltZW91dCcpLnZhbHVlLCBzdGFydHVwID0gUSgnd2dzdGFydCcpLnZhbHVlOw0KICAgICAgICAgICAgaWYgKHRpbWVvdXQgPT0gJycpIHRpbWVvdXQgPSA2MDsNCiAgICAgICAgICAgIGlmIChzdGFydHVwID09ICcnKSBzdGFydHVwID0gMzYwMDsNCiAgICAgICAgICAgIHZhciBndWlkID0gYnRvYShoZXgycnN0cihndWlkVG9TdHIoUSgnd2dndWlkJykudmFsdWUucmVwbGFjZSgvLS9nLCAnJykpLnJlcGxhY2UoLy0vZywgJycpKSk7DQogICAgICAgICAgICB2YXIgd2RvZyA9IHsgJ0NyZWF0aW9uQ2xhc3NOYW1lJzogMCwgJ0RldmljZUlEJzogZ3VpZCwgJ1N0YXJ0dXBJbnRlcnZhbCc6IHN0YXJ0dXAsICdTeXN0ZW1DcmVhdGlvbkNsYXNzTmFtZSc6IDAsICdTeXN0ZW1OYW1lJzogMCwgJ1RpbWVvdXRJbnRlcnZhbCc6IHRpbWVvdXQsICdNb25pdG9yZWRFbnRpdHlEZXNjcmlwdGlvbic6IFEoJ3dnbmFtZScpLnZhbHVlIH07DQogICAgICAgICAgICBhbXRzdGFjay5DcmVhdGUoJ0FNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2cnLCB3ZG9nLCBBZGRXYXRjaGRvZ09rMik7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRXYXRjaGRvZ09rMihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnV2F0Y2hkb2cnLCAiVW5hYmxlIHRvIGFkZCB3YXRjaGRvZywgZXJyb3IgIyIgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBQdWxsV2F0Y2hkb2coKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZFdhdGNoZG9nQWN0aW9uKGUsIGkpIHsNCiAgICAgICAgICAgIHZhciB3ID0geHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZyddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgIHZhciB4ID0gJzx0YWJsZT4nOw0KICAgICAgICAgICAgeCArPSAnPHRkIHN0eWxlPXdpZHRoOjE4MHB4PkZyb208YnI+Jw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBhbXRzdGFjay5XYXRjaGRvZ0N1cnJlbnRTdGF0ZXMpIHsNCiAgICAgICAgICAgICAgICB4ICs9ICc8aW5wdXQgaWQ9d2dzYScgKyBpICsgJyB0eXBlPWNoZWNrYm94IG9uY2xpY2s9YWRkV2F0Y2hkb2dBY3Rpb25VcGRhdGUoKT4gJyArIGFtdHN0YWNrLldhdGNoZG9nQ3VycmVudFN0YXRlc1tpXSArICc8YnIgLz4nOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSAnPHRkPlRvPGJyPicNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYW10c3RhY2suV2F0Y2hkb2dDdXJyZW50U3RhdGVzKSB7DQogICAgICAgICAgICAgICAgeCArPSAnPGlucHV0IGlkPXdnc2InICsgaSArICcgdHlwZT1jaGVja2JveCBvbmNsaWNrPWFkZFdhdGNoZG9nQWN0aW9uVXBkYXRlKCk+ICcgKyBhbXRzdGFjay5XYXRjaGRvZ0N1cnJlbnRTdGF0ZXNbaV0gKyAnPGJyIC8+JzsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gJzwvdGFibGU+PGJyPlBlcmZvcm0gQWN0aW9uPGJyPjxpbnB1dCBpZD13Z3NldmVudCB0eXBlPWNoZWNrYm94IGNoZWNrZWQgb25jbGljaz1hZGRXYXRjaGRvZ0FjdGlvblVwZGF0ZSgpPldyaXRlIHRvIGV2ZW50IGxvZzxiciAvPic7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAnQWRkIFdhdGNoZG9nIEFjdGlvbicsIDMsIGFkZFdhdGNoZG9nQWN0aW9uT2ssIHgsIHcpOw0KICAgICAgICAgICAgYWRkV2F0Y2hkb2dBY3Rpb25VcGRhdGUoKTsNCiAgICAgICAgICAgIGhhbHRFdmVudChlKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZFdhdGNoZG9nQWN0aW9uVXBkYXRlKCkgew0KICAgICAgICAgICAgdmFyIHRmcm9tID0gMCwgdHRvID0gMDsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYW10c3RhY2suV2F0Y2hkb2dDdXJyZW50U3RhdGVzKSB7DQogICAgICAgICAgICAgICAgaWYgKFEoJ3dnc2EnICsgaSkuY2hlY2tlZCA9PSB0cnVlKSB0ZnJvbSArPSBwYXJzZUludChpKTsNCiAgICAgICAgICAgICAgICBpZiAoUSgnd2dzYicgKyBpKS5jaGVja2VkID09IHRydWUpIHR0byArPSBwYXJzZUludChpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIFFFKCdkbGdPa0J1dHRvbicsIHRmcm9tID4gMCAmJiB0dG8gPiAwICYmIFEoJ3dnc2V2ZW50JykuY2hlY2tlZCA9PSB0cnVlKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZFdhdGNoZG9nQWN0aW9uT2soYiwgdykgew0KICAgICAgICAgICAgdmFyIHRmcm9tID0gMCwgdHRvID0gMDsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYW10c3RhY2suV2F0Y2hkb2dDdXJyZW50U3RhdGVzKSB7DQogICAgICAgICAgICAgICAgaWYgKFEoJ3dnc2EnICsgaSkuY2hlY2tlZCA9PSB0cnVlKSB0ZnJvbSArPSBwYXJzZUludChpKTsNCiAgICAgICAgICAgICAgICBpZiAoUSgnd2dzYicgKyBpKS5jaGVja2VkID09IHRydWUpIHR0byArPSBwYXJzZUludChpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2dfQWRkQWN0aW9uKHRmcm9tLCB0dG8sIFEoJ3dnc2V2ZW50JykuY2hlY2tlZCwgbnVsbCwgbnVsbCwgQWRkV2F0Y2hkb2dBY3Rpb25SZXNwb25zZSwgbnVsbCwgMCwgeyAnRGV2aWNlSUQnOiB3WydEZXZpY2VJRCddIH0pOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkV2F0Y2hkb2dBY3Rpb25SZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnV2F0Y2hkb2cgQWN0aW9uJywgIlVuYWJsZSB0byBhZGQgd2F0Y2hkb2cgYWN0aW9uLCBlcnJvciAjIiArIHN0YXR1cyk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFB1bGxXYXRjaGRvZygpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZGVsZXRlV2F0Y2hkb2dBY3Rpb25zKGUsIGkpIHsNCiAgICAgICAgICAgIHZhciB3ID0geHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZyddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdEZWxldGUgV2F0Y2hkb2cgQWN0aW9ucycsIDMsIGRlbGV0ZVdhdGNoZG9nQWN0aW9uc09rLCAiRGVsZXRlIGFsbCBhY3Rpb25zIGZvciB0aGlzIHdhdGNoZG9nPyIsIHcpOw0KICAgICAgICAgICAgaGFsdEV2ZW50KGUpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZGVsZXRlV2F0Y2hkb2dBY3Rpb25zT2soYiwgdykgew0KICAgICAgICAgICAgYW10c3RhY2suQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ19EZWxldGVBbGxBY3Rpb25zKGRlbGV0ZVdhdGNoZG9nQWN0aW9uUmVzcG9uc2UsIG51bGwsIDAsIHsgJ0RldmljZUlEJzogd1snRGV2aWNlSUQnXSB9KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGRlbGV0ZVdhdGNoZG9nQWN0aW9uUmVzcG9uc2Uoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgew0KICAgICAgICAgICAgICAgIG1lc3NhZ2Vib3goJ1dhdGNoZG9nIEFjdGlvbicsICJVbmFibGUgdG8gcmVtb3ZlIHdhdGNoZG9nIGFjdGlvbnMsIGVycm9yICMiICsgc3RhdHVzKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgUHVsbFdhdGNoZG9nKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICANCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIFNZU1RFTSBERUZFTlNFIFBBTkVMDQogICAgICAgIC8vDQoNCiAgICAgICAgdmFyIHh4U3lzdGVtRGVmZW5zZSA9IG51bGw7DQogICAgICAgIHZhciB4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3kgPSB7fTsNCiAgICAgICAgdmFyIHh4VXBkYXRpbmdEZWZlbnNlU3RhdHMgPSBmYWxzZTsNCiAgICAgICAgdmFyIHh4RmlsdGVyU3RhdGlzdGljcyA9IFt7fSwge31dOyAvLyBXaXJlZCBhbmQgd2lyZWxlc3MgaW50ZXJmYWNlIHN0YXRzDQogICAgICAgIHZhciB4eEZpbHRlclN0YXRpc3RpY3NUaW1lciA9IG51bGw7DQogICAgICAgIHZhciB4eEZpbHRlclN0YXRpc3RpY3NUaW1lckFjdGl2ZSA9IGZhbHNlOw0KDQogICAgICAgIHZhciB4eFN5c3RlbURlZmVuY2VGaWx0ZXJFdGhlcm5ldFR5cGVzID0geyAyMDQ4OiAnQWxsIElQIFBhY2tldHMnLCAyMDU0OiAnQWxsIEFSUCBQYWNrZXRzJyB9Ow0KICAgICAgICB2YXIgeHhTeXN0ZW1EZWZlbmNlRmlsdGVySVBUeXBlcyA9IHsgNDogJ0lQdjQnLCA2OiAnSVB2NicgfTsNCiAgICAgICAgdmFyIHh4U3lzdGVtRGVmZW5jZUZpbHRlckRlc2MgPSB7IDA6ICdBbGxvdywgQ291bnQnLCAxOiAnRHJvcCwgQ291bnQnLCAyOiAnUmF0ZSBsaW1pdCcsIDM6ICdBbGxvdycsIDQ6ICdEcm9wJyB9Ow0KICAgICAgICB2YXIgeHhTeXN0ZW1EZWZlbmNlRmlsdGVycyA9IHsgJ0hkclByb3RvY29sSUQnOiAxLCAnSGRyRGVzdEFkZHJlc3MnOiAyLCAnSGRyRGVzdE1hc2snOiAyLCAnSGRyU3JjQWRkcmVzcyc6IDIsICdIZHJTcmNNYXNrJzogMiwgJ0hkclNyY1BvcnRTdGFydCc6IDEsICdIZHJTcmNQb3J0RW5kJzogMSwgJ0hkckRlc3RQb3J0U3RhcnQnOiAxLCAnSGRyRGVzdFBvcnRFbmQnOiAxLCAnSGRyU3JjQWRkcmVzc0VuZE9mUmFuZ2UnOiAyLCAnSGRyRGVzdEFkZHJlc3NFbmRPZlJhbmdlICc6IDIsICdUQ1BGbGFnc09uJzogMywgJ1RDUEZsYWdzT2ZmJzogMyB9Ow0KDQogICAgICAgIGZ1bmN0aW9uIFB1bGxTeXN0ZW1EZWZlbnNlKCkgew0KICAgICAgICAgICAgYW10Rmlyc3RQdWxsIHw9IDQ7DQogICAgICAgICAgICBhbXRzdGFjay5CYXRjaEVudW0obnVsbCwgWyJBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSIsICJBTVRfTmV0d29ya1BvcnRTeXN0ZW1EZWZlbnNlUG9saWN5IiwgIkFNVF9IZHI4MDIxRmlsdGVyIiwgIkFNVF9JUEhlYWRlcnNGaWx0ZXIiLCAiQU1UX05ldHdvcmtGaWx0ZXIiXSwgUHVsbFN5c3RlbURlZmVuc2VSZXNwb25zZSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBQdWxsU3lzdGVtRGVmZW5zZVJlc3BvbnNlKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsNCiAgICAgICAgICAgICAgICB4eFN5c3RlbURlZmVuc2UgPSByZXNwb25zZXM7DQogICAgICAgICAgICAgICAgdXBkYXRlU3lzdGVtRGVmZW5zZSgpOw0KICAgICAgICAgICAgICAgIFFWKCdnbzE4JywgdHJ1ZSk7IC8vIFNob3cgU3lzdGVtIERlZmVuc2UgUGFuZWwNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVwZGF0ZVN5c3RlbURlZmVuc2UoKSB7DQogICAgICAgICAgICBpZiAoeHhTeXN0ZW1EZWZlbnNlID09IG51bGwpIHJldHVybjsNCiAgICAgICAgICAgIHZhciB4ID0gJyc7DQoNCiAgICAgICAgICAgIC8vIEdldCBhY3RpdmUgcG9saWNpZXMNCiAgICAgICAgICAgIHh4U3lzdGVtRGVmZW5jZUxpbmtlZFBvbGljeSA9IHt9Ow0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eFN5c3RlbURlZmVuc2VbJ0FNVF9OZXR3b3JrUG9ydFN5c3RlbURlZmVuc2VQb2xpY3knXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICB2YXIgbGluayA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX05ldHdvcmtQb3J0U3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgICAgICB2YXIgYSA9ICtnZXRJdGVtKGxpbmtbJ0FudGVjZWRlbnQnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddLCAnQE5hbWUnLCAnRGV2aWNlSUQnKVsnVmFsdWUnXS5zdWJzdHJpbmcoMjcpOw0KICAgICAgICAgICAgICAgIHZhciBiID0gbGlua1snRGVwZW5kZW50J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXVsnVmFsdWUnXTsNCiAgICAgICAgICAgICAgICB2YXIgcCA9IGdldEl0ZW0oeHhTeXN0ZW1EZWZlbnNlWydBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlcywgJ0luc3RhbmNlSUQnLCBiKTsNCiAgICAgICAgICAgICAgICB4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3lbYV0gPSBwOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBHbG9iYWwgU3lzdGVtIERlZmVuc2Ugc2V0dGluZ3MNCiAgICAgICAgICAgIHggKz0gVGFibGVTdGFydCgpOw0KICAgICAgICAgICAgdmFyIHBvbGljeW5hbWUgPSAnPGk+Tm9uZTwvaT4nOw0KICAgICAgICAgICAgaWYgKHh4U3lzdGVtRGVmZW5jZUxpbmtlZFBvbGljeVswXSkgeyBwb2xpY3luYW1lID0geHhTeXN0ZW1EZWZlbmNlTGlua2VkUG9saWN5WzBdWydQb2xpY3lOYW1lJ107IH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiRGVmYXVsdCBXaXJlZCBQb2xpY3kiLCBhZGRMaW5rKHBvbGljeW5hbWUsICdjaGFuZ2VEZWZhdWx0UG9saWN5KDApJykpOw0KICAgICAgICAgICAgLyoNCiAgICAgICAgICAgIHBvbGljeW5hbWUgPSAnPGk+Tm9uZTwvaT4nOw0KICAgICAgICAgICAgaWYgKHh4U3lzdGVtRGVmZW5jZUxpbmtlZFBvbGljeVsxXSkgeyBwb2xpY3luYW1lID0geHhTeXN0ZW1EZWZlbmNlTGlua2VkUG9saWN5WzFdWydQb2xpY3lOYW1lJ107IH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiRGVmYXVsdCBXaXJlbGVzcyBQb2xpY3kiLCBhZGRMaW5rKHBvbGljeW5hbWUsICdjaGFuZ2VEZWZhdWx0UG9saWN5KDEpJykpOw0KICAgICAgICAgICAgKi8NCg0KICAgICAgICAgICAgLy8gRmlsdGVyIFN0YXRpc3RpY3MNCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjsgaSsrKSB7DQogICAgICAgICAgICAgICAgdmFyIGYgPSB4eEZpbHRlclN0YXRpc3RpY3NbaV07DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaiBpbiBmKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBjID0gZltqXTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT0gMSkgYyArPSAnIHBhY2tldCc7IGVsc2UgYyArPSAnIHBhY2tldHMnOw0KICAgICAgICAgICAgICAgICAgICB2YXIgam4gPSAoKGk9PTApPydXaXJlZCAnOidXaXJlbGVzcyAnKSArIGo7DQogICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeShqbiwgYyk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KICAgICAgICAgICAgeCArPSAiPGJyPiI7DQoNCiAgICAgICAgICAgIHggKz0gVGFibGVTdGFydDIoKTsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg7Ym9yZGVyOjA+PGJyPk1hbmFnZSBJbnRlbCZyZWc7IEFNVCBzeXN0ZW0gZGVmZW5zZSBwb2xpY2llcy48YnI+PGJyPiI7DQogICAgICAgICAgICBpZiAoeHhTeXN0ZW1EZWZlbnNlWydBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlcy5sZW5ndGggPT0gMCkgew0KICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGk+Tm8gc3lzdGVtIGRlZmVuc2UgcG9saWNpZXMgZm91bmQuPC9pPjwvZGl2Pjxicj4iOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4U3lzdGVtRGVmZW5zZVsnQU1UX1N5c3RlbURlZmVuc2VQb2xpY3knXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHBvbGljeSA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX1N5c3RlbURlZmVuc2VQb2xpY3knXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgICAgIHZhciBkZXNjID0gJyc7DQogICAgICAgICAgICAgICAgICAgIGlmIChwb2xpY3lbJ0ZpbHRlckNyZWF0aW9uSGFuZGxlcyddKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBwb2xpY3lbJ0ZpbHRlckNyZWF0aW9uSGFuZGxlcyddID0gTWFrZVRvQXJyYXkocG9saWN5WydGaWx0ZXJDcmVhdGlvbkhhbmRsZXMnXSk7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgYyA9IHBvbGljeVsnRmlsdGVyQ3JlYXRpb25IYW5kbGVzJ10ubGVuZ3RoOw0KICAgICAgICAgICAgICAgICAgICAgICAgZGVzYyA9ICcsICcgKyBjICsgJyBmaWx0ZXInICsgKGMgPiAxPydzJzonJyk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBjbGFzcz1pdGVtQmFyIG9uY2xpY2s9c2hvd1BvbGljeURldGFpbHMoIiArIGkgKyAiKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjNweD48Yj4iICsgRXNjYXBlSHRtbChwb2xpY3lbJ1BvbGljeU5hbWUnXSkgKyAiPC9iPiIgKyBkZXNjICsgIjwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICB4ICs9ICI8dHI+PHRkIGNsYXNzPXIxIHN0eWxlPXBhZGRpbmctbGVmdDoxNXB4Pjxicj5NYW5hZ2UgSW50ZWwmcmVnOyBBTVQgc3lzdGVtIGRlZmVuc2UgZmlsdGVycy48YnI+PGJyPiI7DQogICAgICAgICAgICBpZiAoeHhTeXN0ZW1EZWZlbnNlWydBTVRfSGRyODAyMUZpbHRlciddLnJlc3BvbnNlcy5sZW5ndGggPT0gMCAmJiB4eFN5c3RlbURlZmVuc2VbJ0FNVF9JUEhlYWRlcnNGaWx0ZXInXS5yZXNwb25zZXMubGVuZ3RoID09IDApIHsNCiAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPXBhZGRpbmctbGVmdDoxNXB4PjxpPk5vIHN5c3RlbSBkZWZlbnNlIGZpbHRlcnMgZm91bmQuPC9pPjwvZGl2Pjxicj4iOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4U3lzdGVtRGVmZW5zZVsnQU1UX0hkcjgwMjFGaWx0ZXInXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGZpbHRlciA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX0hkcjgwMjFGaWx0ZXInXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgICAgIHZhciBkZXNjID0geHhTeXN0ZW1EZWZlbmNlRmlsdGVyRXRoZXJuZXRUeXBlc1tmaWx0ZXJbJ0hkclByb3RvY29sSUQ4MDIxJ11dOw0KICAgICAgICAgICAgICAgICAgICBpZiAoIWRlc2MpIGRlc2MgPSAnQWxsIEV0aGVybmV0IFByb3RvY29sICcgKyBmaWx0ZXJbJ0hkclByb3RvY29sSUQ4MDIxJ107DQogICAgICAgICAgICAgICAgICAgIGRlc2MgKz0gJywgJyArIHh4U3lzdGVtRGVmZW5jZUZpbHRlckRlc2NbZmlsdGVyWydGaWx0ZXJQcm9maWxlJ11dOw0KICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyWydGaWx0ZXJQcm9maWxlJ10gPT0gMikgeyBkZXNjICs9ICIgYXQgIiArIGZpbHRlclsnRmlsdGVyUHJvZmlsZURhdGEnXSArICIgcGFja2V0IC8gc2VjIjsgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyWydBY3Rpb25FdmVudE9uTWF0Y2gnXSA9PSB0cnVlKSBkZXNjICs9ICcsIEV2ZW50IG9uIG1hdGNoJzsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBjbGFzcz1pdGVtQmFyIG9uY2xpY2s9c2hvd0ZpbHRlckRldGFpbHMoMCwiICsgaSArICIpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PjxiPiIgKyAoZmlsdGVyWydGaWx0ZXJEaXJlY3Rpb24nXSA9PSAwID8gJyYjODU5MjsgJyA6ICcmIzg1OTQ7ICcpICsgRXNjYXBlSHRtbChmaWx0ZXJbIk5hbWUiXSkgKyAiPC9iPiwgIiArIGRlc2MgKyAiPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eFN5c3RlbURlZmVuc2VbJ0FNVF9JUEhlYWRlcnNGaWx0ZXInXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGZpbHRlciA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX0lQSGVhZGVyc0ZpbHRlciddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGRlc2MgPSB4eFN5c3RlbURlZmVuY2VGaWx0ZXJJUFR5cGVzW2ZpbHRlclsnSGRySVBWZXJzaW9uJ11dOw0KICAgICAgICAgICAgICAgICAgICBpZiAoIWRlc2MpIGRlc2MgPSAnQWxsIEV0aGVybmV0IFByb3RvY29sICcgKyBmaWx0ZXJbJ0hkcklQVmVyc2lvbiddOw0KICAgICAgICAgICAgICAgICAgICBkZXNjICs9ICcsICcgKyB4eFN5c3RlbURlZmVuY2VGaWx0ZXJEZXNjW2ZpbHRlclsnRmlsdGVyUHJvZmlsZSddXTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlclsnRmlsdGVyUHJvZmlsZSddID09IDIpIHsgZGVzYyArPSAiIGF0ICIgKyBmaWx0ZXJbJ0ZpbHRlclByb2ZpbGVEYXRhJ10gKyAiIHBhY2tldCAvIHNlYyI7IH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlclsnQWN0aW9uRXZlbnRPbk1hdGNoJ10gPT0gdHJ1ZSkgZGVzYyArPSAnLCBFdmVudCBvbiBtYXRjaCc7DQogICAgICAgICAgICAgICAgICAgIHZhciBmaWx0ZXJjb3VudCA9IDA7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4geHhTeXN0ZW1EZWZlbmNlRmlsdGVycykgeyBpZiAoZmlsdGVyW2pdKSBmaWx0ZXJjb3VudCsrOyB9DQogICAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXJjb3VudCA+IDApIGRlc2MgKz0gJywgJyArIGZpbHRlcmNvdW50ICsgJyBmaWx0ZXInICsgKGZpbHRlcmNvdW50PjE/J3MnOicnKTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBjbGFzcz1pdGVtQmFyIG9uY2xpY2s9c2hvd0ZpbHRlckRldGFpbHMoMSwiICsgaSArICIpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PjxiPiIgKyAoZmlsdGVyWydGaWx0ZXJEaXJlY3Rpb24nXSA9PSAwID8gJyYjODU5MjsgJyA6ICcmIzg1OTQ7ICcpICsgRXNjYXBlSHRtbChmaWx0ZXJbIk5hbWUiXSkgKyAiPC9iPiwgIiArIGRlc2MgKyAiPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICB4ICs9ICI8YnI+PHRkIGNsYXNzPXIxPiIgKyBUYWJsZUVuZChBZGRSZWZyZXNoQnV0dG9uKCJQdWxsU3lzdGVtRGVmZW5zZSgpIikgKyAvKkFkZEJ1dHRvbigiVXBkYXRlIFN0YXRzIiwgIlVwZGF0ZURlZmVuc2VTdGF0cygpIikgKyovIEFkZEJ1dHRvbigiQWRkIEZpbHRlci4uLiIsICJBZGREZWZlbnNlRmlsdGVyKCkiKSArIEFkZEJ1dHRvbigiQWRkIFBvbGljeS4uLiIsICJBZGREZWZlbnNlUG9saWN5KCkiKSk7DQoNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZVN5c3RlbURlZmVuc2UnLCB4KTsNCg0KICAgICAgICAgICAgaWYgKHh4RmlsdGVyU3RhdGlzdGljc1RpbWVyID09IG51bGwpIHsNCiAgICAgICAgICAgICAgICBVcGRhdGVEZWZlbnNlU3RhdHMoKTsNCiAgICAgICAgICAgICAgICB4eEZpbHRlclN0YXRpc3RpY3NUaW1lckFjdGl2ZSA9IGZhbHNlOw0KICAgICAgICAgICAgICAgIGlmICghdXJsdmFyc1snbm9yZWZyZXNoJ10pIHsgeHhGaWx0ZXJTdGF0aXN0aWNzVGltZXIgPSBzZXRJbnRlcnZhbChVcGRhdGVEZWZlbnNlU3RhdHMsIDUwMDApOyB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBTdG9wRGVmZW5zZVN0YXRzVGltZXIoKSB7DQogICAgICAgICAgICBpZiAoeHhGaWx0ZXJTdGF0aXN0aWNzVGltZXIgIT0gbnVsbCkgeyBjbGVhckludGVydmFsKHh4RmlsdGVyU3RhdGlzdGljc1RpbWVyKTsgeHhGaWx0ZXJTdGF0aXN0aWNzVGltZXIgPSBudWxsOyB9DQogICAgICAgICAgICB4eEZpbHRlclN0YXRpc3RpY3NUaW1lckFjdGl2ZSA9IGZhbHNlOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gVXBkYXRlRGVmZW5zZVN0YXRzKG4pIHsNCiAgICAgICAgICAgIGlmICghbiAmJiB4eEZpbHRlclN0YXRpc3RpY3NUaW1lckFjdGl2ZSA9PSB0cnVlKSB7IHJldHVybjsgfQ0KICAgICAgICAgICAgeHhGaWx0ZXJTdGF0aXN0aWNzVGltZXJBY3RpdmUgPSB0cnVlOw0KICAgICAgICAgICAgdmFyIG5ldHdvcmsgPSBuP246MDsNCiAgICAgICAgICAgIGlmICh4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3lbbmV0d29ya10pIHsNCiAgICAgICAgICAgICAgICB2YXIgZXJlZiA9ICc8YTpBZGRyZXNzPjwvYTpBZGRyZXNzPjxhOlJlZmVyZW5jZVBhcmFtZXRlcnM+PHc6UmVzb3VyY2VVUkk+aHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NpbS1zY2hlbWEvMi9DSU1fRXRoZXJuZXRQb3J0PC93OlJlc291cmNlVVJJPjx3OlNlbGVjdG9yU2V0Pjx3OlNlbGVjdG9yIE5hbWU9IkRldmljZUlEIj5JbnRlbChyKSBBTVQgRXRoZXJuZXQgUG9ydCAnICsgbmV0d29yayArICc8L3c6U2VsZWN0b3I+PC93OlNlbGVjdG9yU2V0PjwvYTpSZWZlcmVuY2VQYXJhbWV0ZXJzPic7DQogICAgICAgICAgICAgICAgYW10c3RhY2suQU1UX1N5c3RlbURlZmVuc2VQb2xpY3lfVXBkYXRlU3RhdGlzdGljcyhlcmVmLCBmYWxzZSwgVXBkYXRlRGVmZW5zZVN0YXRzMiwgbmV0d29yaywgMCwgeyAnSW5zdGFuY2VJRCc6IHh4U3lzdGVtRGVmZW5jZUxpbmtlZFBvbGljeVtuZXR3b3JrXVsnSW5zdGFuY2VJRCddIH0pOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAvLyBObyBhY3RpdmUgcG9saWN5LCBzdG9wIHRoZSB0aW1lcg0KICAgICAgICAgICAgICAgIHh4RmlsdGVyU3RhdGlzdGljc1tuZXR3b3JrXSA9IHt9Ow0KICAgICAgICAgICAgICAgIHVwZGF0ZVN5c3RlbURlZmVuc2UoKTsNCiAgICAgICAgICAgICAgICBTdG9wRGVmZW5zZVN0YXRzVGltZXIoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIFVwZGF0ZURlZmVuc2VTdGF0czIoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzLCBuZXR3b3JrKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCkgew0KICAgICAgICAgICAgICAgIGFtdHN0YWNrLkVudW0oJ0FNVF9BY3RpdmVGaWx0ZXJTdGF0aXN0aWNzJywgVXBkYXRlRGVmZW5zZVN0YXRzMywgbmV0d29yayk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFN0b3BEZWZlbnNlU3RhdHNUaW1lcigpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gVXBkYXRlRGVmZW5zZVN0YXRzMyhzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMsIG5ldHdvcmspIHsNCiAgICAgICAgICAgIHZhciBjb3VudCA9IDA7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCkgew0KICAgICAgICAgICAgICAgIHh4RmlsdGVyU3RhdGlzdGljc1tuZXR3b3JrXSA9IHt9Ow0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gcmVzcG9uc2VzKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciByZWFkY291bnQgPSByZXNwb25zZXNbaV1bJ1JlYWRDb3VudCddOw0KICAgICAgICAgICAgICAgICAgICAvLyB2YXIgbWF0Y2hlZCA9IHJlc3BvbnNlc1tpXVsnRmlsdGVyTWF0Y2hlZCddOw0KICAgICAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IGdldEl0ZW0ocmVzcG9uc2VzW2ldWydEZXBlbmRlbnQnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddWzFdWydWYWx1ZSddWydFbmRwb2ludFJlZmVyZW5jZSddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ10sICdATmFtZScsICdOYW1lJylbJ1ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgIHh4RmlsdGVyU3RhdGlzdGljc1tuZXR3b3JrXVtuYW1lXSA9IHJlYWRjb3VudDsNCiAgICAgICAgICAgICAgICAgICAgY291bnQrKzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgdXBkYXRlU3lzdGVtRGVmZW5zZSgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeHhGaWx0ZXJTdGF0aXN0aWNzVGltZXJBY3RpdmUgPSBmYWxzZTsNCiAgICAgICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIHN0YXRpc3RpY3MsIHN0b3AgdGhlIHRpbWVyDQogICAgICAgICAgICBpZiAoY291bnQgPT0gMCkgeyBTdG9wRGVmZW5zZVN0YXRzVGltZXIoKTsgfSAvLyBUT0RPOiBDaGFuZ2UgdGhpcyB0byBhbGxvdyBmb3Igd2lyZWxlc3MNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGNoYW5nZURlZmF1bHRQb2xpY3kobmV0d29yaykgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PHNlbGVjdCBpZD1wb2xpY3lTZWxlY3Rpb24gc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjY2cHg+PG9wdGlvbiB2YWx1ZT0tMT5Ob25lIjsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhTeXN0ZW1EZWZlbnNlWydBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlcykgeyB4ICs9ICI8b3B0aW9uIHZhbHVlPSIgKyBpICsgKCh4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3lbbmV0d29ya10gJiYgeHhTeXN0ZW1EZWZlbnNlWydBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlc1tpXVsnSW5zdGFuY2VJRCddID09IHh4U3lzdGVtRGVmZW5jZUxpbmtlZFBvbGljeVtuZXR3b3JrXVsnSW5zdGFuY2VJRCddKSA/ICcgc2VsZWN0ZWQnIDogJycpICsgIj4iICsgeHhTeXN0ZW1EZWZlbnNlWydBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlc1tpXVsnUG9saWN5TmFtZSddOyB9DQogICAgICAgICAgICB4ICs9ICI8L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5EZWZhdWx0IFBvbGljeTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAnRGVmYXVsdCBTeXN0ZW0gRGVmZW5zZSBQb2xpY3knLCAzLCBjaGFuZ2VEZWZhdWx0UG9saWN5T2ssIHgsIG5ldHdvcmspOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gY2hhbmdlRGVmYXVsdFBvbGljeU9rKGJ1dHRvbiwgbmV0d29yaykgew0KICAgICAgICAgICAgdmFyIGkgPSBRKCdwb2xpY3lTZWxlY3Rpb24nKS52YWx1ZTsNCiAgICAgICAgICAgIHZhciBvbGRwb2xpY3kgPSB4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3lbbmV0d29ya107DQogICAgICAgICAgICBpZiAob2xkcG9saWN5KSB7IGFtdHN0YWNrLkRlbGV0ZSgnQU1UX05ldHdvcmtQb3J0U3lzdGVtRGVmZW5zZVBvbGljeScsICc8dzpTZWxlY3RvclNldD48dzpTZWxlY3RvciBOYW1lPSJBbnRlY2VkZW50Ij48YTpFbmRwb2ludFJlZmVyZW5jZSB4bWxuczpiPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmciIHhtbG5zOmM9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2QiPjxhOkFkZHJlc3M+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nL3JvbGUvYW5vbnltb3VzPC9hOkFkZHJlc3M+PGE6UmVmZXJlbmNlUGFyYW1ldGVycz48dzpSZXNvdXJjZVVSST5odHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yL0NJTV9FdGhlcm5ldFBvcnQ8L3c6UmVzb3VyY2VVUkk+PHc6U2VsZWN0b3JTZXQ+PHc6U2VsZWN0b3IgTmFtZT0iQ3JlYXRpb25DbGFzc05hbWUiPkNJTV9FdGhlcm5ldFBvcnQ8L3c6U2VsZWN0b3I+PHc6U2VsZWN0b3IgTmFtZT0iRGV2aWNlSUQiPkludGVsKHIpIEFNVCBFdGhlcm5ldCBQb3J0ICcgKyBuZXR3b3JrICsgJzwvdzpTZWxlY3Rvcj48L3c6U2VsZWN0b3JTZXQ+PC9hOlJlZmVyZW5jZVBhcmFtZXRlcnM+PC9hOkVuZHBvaW50UmVmZXJlbmNlPjwvdzpTZWxlY3Rvcj48dzpTZWxlY3RvciBOYW1lPSJEZXBlbmRlbnQiPjxhOkVuZHBvaW50UmVmZXJlbmNlIHhtbG5zOmI9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZyIgeG1sbnM6Yz0iaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZCI+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48YTpSZWZlcmVuY2VQYXJhbWV0ZXJzPjx3OlJlc291cmNlVVJJPmh0dHA6Ly9pbnRlbC5jb20vd2JlbS93c2NpbS8xL2FtdC1zY2hlbWEvMS9BTVRfU3lzdGVtRGVmZW5zZVBvbGljeTwvdzpSZXNvdXJjZVVSST48dzpTZWxlY3RvclNldD48dzpTZWxlY3RvciBOYW1lPSJJbnN0YW5jZUlEIj4nICsgb2xkcG9saWN5WydJbnN0YW5jZUlEJ10gKyAnPC93OlNlbGVjdG9yPjwvdzpTZWxlY3RvclNldD48L2E6UmVmZXJlbmNlUGFyYW1ldGVycz48L2E6RW5kcG9pbnRSZWZlcmVuY2U+PC93OlNlbGVjdG9yPjwvdzpTZWxlY3RvclNldD4nLCAoKGkgPT0gLTEpID8gUHVsbFN5c3RlbURlZmVuc2UgOiBmdW5jdGlvbiAoKSB7IH0pKTsgfQ0KDQogICAgICAgICAgICBpZiAoaSA+PSAwKSB7DQogICAgICAgICAgICAgICAgdmFyIHBvbGljeSA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX1N5c3RlbURlZmVuc2VQb2xpY3knXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgdmFyIGVyZWYgPSAnPEFkZHJlc3MgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZyI+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nPC9BZGRyZXNzPjxSZWZlcmVuY2VQYXJhbWV0ZXJzIHhtbG5zPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmciPjxSZXNvdXJjZVVSSSB4bWxucz0iaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZCI+aHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NpbS1zY2hlbWEvMi9DSU1fRXRoZXJuZXRQb3J0PC9SZXNvdXJjZVVSST48U2VsZWN0b3JTZXQgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2QiPjxTZWxlY3RvciBOYW1lPSJEZXZpY2VJRCI+SW50ZWwocikgQU1UIEV0aGVybmV0IFBvcnQgJyArIG5ldHdvcmsgKyAnPC9TZWxlY3Rvcj48L1NlbGVjdG9yU2V0PjwvUmVmZXJlbmNlUGFyYW1ldGVycz4nOw0KICAgICAgICAgICAgICAgIHZhciBwcmVmID0gJzxBZGRyZXNzIHhtbG5zPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmciPmh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZzwvQWRkcmVzcz48UmVmZXJlbmNlUGFyYW1ldGVycyB4bWxucz0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nIj48UmVzb3VyY2VVUkkgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2QiPmh0dHA6Ly9pbnRlbC5jb20vd2JlbS93c2NpbS8xL2FtdC1zY2hlbWEvMS9BTVRfU3lzdGVtRGVmZW5zZVBvbGljeTwvUmVzb3VyY2VVUkk+PFNlbGVjdG9yU2V0IHhtbG5zPSJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkIj48U2VsZWN0b3IgTmFtZT0iSW5zdGFuY2VJRCI+JyArIHBvbGljeVsnSW5zdGFuY2VJRCddICsgJzwvU2VsZWN0b3I+PC9TZWxlY3RvclNldD48L1JlZmVyZW5jZVBhcmFtZXRlcnM+JzsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5DcmVhdGUoJ0FNVF9OZXR3b3JrUG9ydFN5c3RlbURlZmVuc2VQb2xpY3knLCB7ICdBbnRlY2VkZW50JzogZXJlZiwgJ0RlcGVuZGVudCc6IHByZWYgfSwgY2hhbmdlRGVmYXVsdFBvbGljeU9rMik7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBjaGFuZ2VEZWZhdWx0UG9saWN5T2syKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsNCiAgICAgICAgICAgICAgICBtZXNzYWdlYm94KCdEZWZhdWx0IFN5c3RlbSBEZWZlbnNlIFBvbGljeScsICJVbmFibGUgdG8gc2V0IHBvbGljeSwgZXJyb3IgIiArIHN0YXR1cyk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFB1bGxTeXN0ZW1EZWZlbnNlKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGREZWZlbnNlRmlsdGVyKCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IGlkPWZpbHRlcm5hbWUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHggbWF4bGVuZ3RoPTE2IG9ua2V5dXA9QWRkRGVmZW5zZUZpbHRlclVwZGF0ZSgpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4Pk5hbWU8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48c2VsZWN0IGlkPWZpbHRlcnR5cGUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjY2cHggb25jaGFuZ2U9QWRkRGVmZW5zZUZpbHRlclVwZGF0ZSgpPjxvcHRpb24gdmFsdWU9MD5FdGhlcm5ldCBJUCBQYWNrZXQgRmlsdGVyPG9wdGlvbiB2YWx1ZT0xPkV0aGVybmV0IEFSUCBQYWNrZXQgRmlsdGVyPG9wdGlvbiB2YWx1ZT0yPklQdjQgUGFja2V0IEZpbHRlcjxvcHRpb24gdmFsdWU9Mz5JUHY2IFBhY2tldCBGaWx0ZXI8L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5UeXBlPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHggaWQ9aXBmaWx0ZXJkaXY+PGlucHV0IGlkPWlwZmlsdGVyIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IHBsYWNlaG9sZGVyPVwiT3B0aW9uYWwgUnVsZXNcIiBvbmtleXVwPUFkZERlZmVuc2VGaWx0ZXJVcGRhdGUoKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5NYXRjaGluZyBSdWxlczwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxzZWxlY3QgaWQ9ZmlsdGVyZGlyIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2NnB4IG9uY2hhbmdlPUFkZERlZmVuc2VGaWx0ZXJVcGRhdGUoKT48b3B0aW9uIHZhbHVlPTA+T3V0Ym91bmQgLyBUcmFuc21pdDxvcHRpb24gdmFsdWU9MT5JbmJvdW5kIC8gUmVjZWl2ZTwvc2VsZWN0PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PkRpcmVjdGlvbjwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxzZWxlY3QgaWQ9ZmlsdGVycHJvZmlsZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjZweCBvbmNoYW5nZT1BZGREZWZlbnNlRmlsdGVyVXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT0wPkFsbG93LCBDb3VudDxvcHRpb24gdmFsdWU9MT5Ecm9wLCBDb3VudDxvcHRpb24gdmFsdWU9Mj5SYXRlIExpbWl0PG9wdGlvbiB2YWx1ZT0zPkFsbG93PG9wdGlvbiB2YWx1ZT00PkRyb3A8L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5BY3Rpb248L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweCBpZD1maWx0ZXJkYXRhZGl2PjxpbnB1dCBpZD1maWx0ZXJkYXRhIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG1heGxlbmd0aD04IG9ua2V5dXA9QWRkRGVmZW5zZUZpbHRlclVwZGF0ZSgpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PlBhY2tldHMgLyBzZWNvbmQ8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48c2VsZWN0IGlkPWZpbHRlcmFjdGlvbiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjZweCBvbmNoYW5nZT1BZGREZWZlbnNlRmlsdGVyVXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT1mYWxzZT5EbyBOb3RoaW5nPG9wdGlvbiB2YWx1ZT0xPkV2ZW50IG9uIG1hdGNoPC9zZWxlY3Q+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+RXZlbnQgTG9nPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdBZGQgU3lzdGVtIERlZmVuc2UgRmlsdGVyJywgMywgQWRkRGVmZW5zZUZpbHRlck9rLCB4KTsNCiAgICAgICAgICAgIEFkZERlZmVuc2VGaWx0ZXJVcGRhdGUoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEFkZERlZmVuc2VGaWx0ZXJPaygpIHsNCiAgICAgICAgICAgIGlmIChRKCdmaWx0ZXJ0eXBlJykudmFsdWUgPD0gMSkgew0KICAgICAgICAgICAgICAgIC8vIEFkZCBFdGhlcm5ldCBJUCBvciBBUlAgZmlsdGVyDQogICAgICAgICAgICAgICAgdmFyIHByb3RvY29sID0gKFEoJ2ZpbHRlcnR5cGUnKS52YWx1ZSA9PSAwKSA/IDIwNDggOiAyMDU0OyAvLyBJUCA6IEFSUA0KICAgICAgICAgICAgICAgIHZhciBmaWx0ZXIgPSB7ICdJbnN0YW5jZUlEICc6IDAsICdOYW1lJzogUSgnZmlsdGVybmFtZScpLnZhbHVlLCAnQ3JlYXRpb25DbGFzc05hbWUnOiAwLCAnU3lzdGVtTmFtZSc6IDAsICdTeXN0ZW1DcmVhdGlvbkNsYXNzTmFtZSc6IDAsICdIZHJQcm90b2NvbElEODAyMSc6IHByb3RvY29sLCAnRmlsdGVyUHJvZmlsZSc6IFEoJ2ZpbHRlcnByb2ZpbGUnKS52YWx1ZSwgJ0ZpbHRlckRpcmVjdGlvbic6IFEoJ2ZpbHRlcmRpcicpLnZhbHVlLCAnQWN0aW9uRXZlbnRPbk1hdGNoJzogUSgnZmlsdGVyYWN0aW9uJykudmFsdWUgfTsNCiAgICAgICAgICAgICAgICBpZiAoUSgnZmlsdGVycHJvZmlsZScpLnZhbHVlID09IDIpIGZpbHRlclsnRmlsdGVyUHJvZmlsZURhdGEnXSA9IFEoJ2ZpbHRlcmRhdGEnKS52YWx1ZTsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5DcmVhdGUoJ0FNVF9IZHI4MDIxRmlsdGVyJywgZmlsdGVyLCBBZGREZWZlbnNlRmlsdGVyT2syKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gQWRkIElQdjQgb3IgSVB2NiBGaWx0ZXINCiAgICAgICAgICAgICAgICB2YXIgcHJvdG9jb2wgPSAoUSgnZmlsdGVydHlwZScpLnZhbHVlID09IDIpID8gNCA6IDY7IC8vIElQdjQgOiBJUHY2DQogICAgICAgICAgICAgICAgdmFyIGZpbHRlciA9IHsgJ0luc3RhbmNlSUQgJzogMCwgJ05hbWUnOiBRKCdmaWx0ZXJuYW1lJykudmFsdWUsICdDcmVhdGlvbkNsYXNzTmFtZSc6IDAsICdTeXN0ZW1OYW1lJzogMCwgJ1N5c3RlbUNyZWF0aW9uQ2xhc3NOYW1lJzogMCwgJ0hkcklQVmVyc2lvbic6IHByb3RvY29sLCAnRmlsdGVyUHJvZmlsZSc6IFEoJ2ZpbHRlcnByb2ZpbGUnKS52YWx1ZSwgJ0ZpbHRlckRpcmVjdGlvbic6IFEoJ2ZpbHRlcmRpcicpLnZhbHVlLCAnQWN0aW9uRXZlbnRPbk1hdGNoJzogUSgnZmlsdGVyYWN0aW9uJykudmFsdWUgfTsNCg0KICAgICAgICAgICAgICAgIC8vIFBhcnNlIHRoZSBmaWx0ZXIgc3RyaW5nDQogICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9zb2Z0d2FyZS5pbnRlbC5jb20vc2l0ZXMvbWFuYWdlYWJpbGl0eS9BTVRfSW1wbGVtZW50YXRpb25fYW5kX1JlZmVyZW5jZV9HdWlkZS9kZWZhdWx0Lmh0bT90dXJsPUhUTUxEb2N1bWVudHMlMkZXUy1NYW5hZ2VtZW50X0NsYXNzX1JlZmVyZW5jZSUyRkFNVF9IZHI4MDIxRmlsdGVyLmh0bQ0KICAgICAgICAgICAgICAgIHZhciBmaWx0ZXJzdHJzID0gUSgnaXBmaWx0ZXInKS52YWx1ZS5zcGxpdCgnLCcpOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gZmlsdGVyc3Rycykgew0KICAgICAgICAgICAgICAgICAgICB2YXIgeHggPSBmaWx0ZXJzdHJzW2ldLmluZGV4T2YoJz0nKTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIG4gPSBmaWx0ZXJzdHJzW2ldLnN1YnN0cmluZygwLCB4eCk7DQogICAgICAgICAgICAgICAgICAgIHZhciB2ID0gZmlsdGVyc3Ryc1tpXS5zdWJzdHJpbmcoeHggKyAxKTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHQgPSB4eFN5c3RlbURlZmVuY2VGaWx0ZXJzW25dOw0KICAgICAgICAgICAgICAgICAgICBpZiAoIXQpIHsgbiA9ICJIZHIiICsgbjsgdCA9IHh4U3lzdGVtRGVmZW5jZUZpbHRlcnNbbl07IH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKHQpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IFBhcnNlIHYgKHRoZSB2YWx1ZSkgYmFzZWQgb24gdGhlIHR5cGUgdC4NCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ID09IDIgJiYgcHJvdG9jb2wgPT0gNCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElQdjQgYWRkcmVzcw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpcHNwbGl0ID0gdi5zcGxpdCgnLicpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpcHNwbGl0Lmxlbmd0aCA9PSA0KSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZmlsdGVyW25dID0gYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KGlwc3BsaXRbMF0pLCBwYXJzZUludChpcHNwbGl0WzFdKSwgcGFyc2VJbnQoaXBzcGxpdFsyXSksIHBhcnNlSW50KGlwc3BsaXRbM10pKSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZmlsdGVyW25dID0gWyBwYXJzZUludChpcHNwbGl0WzBdKSwgcGFyc2VJbnQoaXBzcGxpdFsxXSksIHBhcnNlSW50KGlwc3BsaXRbMl0pLCBwYXJzZUludChpcHNwbGl0WzNdKSBdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJbbl0gPSByc3RyMmhleChTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KGlwc3BsaXRbMF0pLCBwYXJzZUludChpcHNwbGl0WzFdKSwgcGFyc2VJbnQoaXBzcGxpdFsyXSksIHBhcnNlSW50KGlwc3BsaXRbM10pKSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlciB2YWx1ZXMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJbbl0gPSB2Ow0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgaWYgKFEoJ2ZpbHRlcnByb2ZpbGUnKS52YWx1ZSA9PSAyKSBmaWx0ZXJbJ0ZpbHRlclByb2ZpbGVEYXRhJ10gPSBRKCdmaWx0ZXJkYXRhJykudmFsdWU7DQogICAgICAgICAgICAgICAgYW10c3RhY2suQ3JlYXRlKCdBTVRfSVBIZWFkZXJzRmlsdGVyJywgZmlsdGVyLCBBZGREZWZlbnNlRmlsdGVyT2syKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEFkZERlZmVuc2VGaWx0ZXJVcGRhdGUoKSB7DQogICAgICAgICAgICB2YXIgb2sgPSBRKCdmaWx0ZXJuYW1lJykudmFsdWUubGVuZ3RoID4gMDsNCiAgICAgICAgICAgIGlmIChvayAmJiBRKCdmaWx0ZXJwcm9maWxlJykudmFsdWUgPT0gMikgeyB2YXIgaSA9IHBhcnNlSW50KFEoJ2ZpbHRlcmRhdGEnKS52YWx1ZSk7IG9rID0gKGkgPiAwICYmIGkgPCAweEZGRkZGRkZGKTsgfQ0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgICAgIFFWKCdmaWx0ZXJkYXRhZGl2JywgUSgnZmlsdGVycHJvZmlsZScpLnZhbHVlID09IDIpOw0KICAgICAgICAgICAgUVYoJ2lwZmlsdGVyZGl2JywgUSgnZmlsdGVydHlwZScpLnZhbHVlID49IDIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkRGVmZW5zZUZpbHRlck9rMihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnQWRkIFN5c3RlbSBEZWZlbnNlIEZpbHRlcicsICJVbmFibGUgdG8gYWRkIGZpbHRlciwgZXJyb3IgIyIgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBQdWxsU3lzdGVtRGVmZW5zZSgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0ZpbHRlckRldGFpbHModCwgaSkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIGRlc2MsIGZpbHRlciwgdHlwZSwgdG47DQogICAgICAgICAgICBpZiAodCA9PSAwKSB7DQogICAgICAgICAgICAgICAgdG4gPSAnQU1UX0hkcjgwMjFGaWx0ZXInOw0KICAgICAgICAgICAgICAgIHR5cGUgPSAnRXRoZXJuZXQgVHJhZmZpYyc7DQogICAgICAgICAgICAgICAgZmlsdGVyID0geHhTeXN0ZW1EZWZlbnNlW3RuXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgZGVzYyA9IHh4U3lzdGVtRGVmZW5jZUZpbHRlckV0aGVybmV0VHlwZXNbZmlsdGVyWydIZHJQcm90b2NvbElEODAyMSddXTsNCiAgICAgICAgICAgICAgICBpZiAoIWRlc2MpIGRlc2MgPSAnQWxsIEV0aGVybmV0IFByb3RvY29sICcgKyBmaWx0ZXJbJ0hkclByb3RvY29sSUQ4MDIxJ107DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHRuID0gJ0FNVF9JUEhlYWRlcnNGaWx0ZXInOw0KICAgICAgICAgICAgICAgIHR5cGUgPSAnSVAgVHJhZmZpYyc7DQogICAgICAgICAgICAgICAgZmlsdGVyID0geHhTeXN0ZW1EZWZlbnNlW3RuXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgZGVzYyA9IHh4U3lzdGVtRGVmZW5jZUZpbHRlcklQVHlwZXNbZmlsdGVyWydIZHJJUFZlcnNpb24nXV07DQogICAgICAgICAgICAgICAgaWYgKCFkZXNjKSBkZXNjID0gJ0FsbCBJUCBQcm90b2NvbCAnICsgZmlsdGVyWydIZHJJUFZlcnNpb24nXTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHZhciB4ID0gJyc7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnTmFtZScsIEVzY2FwZUh0bWwoZmlsdGVyWyJOYW1lIl0pKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCdUeXBlJywgdHlwZSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnTWF0Y2hpbmcgVHJhZmZpYycsIGRlc2MpOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ0RpcmVjdGlvbicsIGZpbHRlclsnRmlsdGVyRGlyZWN0aW9uJ10gPT0gMCA/ICdPdXRib3VuZCAvIFRyYW5zbWl0JyA6ICdJbmJvdW5kIC8gUmVjZWl2ZScpOw0KICAgICAgICAgICAgaWYgKHQgPT0gMSkgew0KICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4geHhTeXN0ZW1EZWZlbmNlRmlsdGVycykgew0KICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyW2pdKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbiA9IGosIHYgPSBmaWx0ZXJbal0sIHQgPSB4eFN5c3RlbURlZmVuY2VGaWx0ZXJzW2pdOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHQgPT0gMiAmJiB2Lmxlbmd0aCA9PSA0KSB7IHYgPSBoZXgycnN0cih2KTsgdiA9IHYuY2hhckNvZGVBdCgwKSArICcuJyArIHYuY2hhckNvZGVBdCgxKSArICcuJyArIHYuY2hhckNvZGVBdCgyKSArICcuJyArIHYuY2hhckNvZGVBdCgzKTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG4uc3RhcnRzV2l0aCgnSGRyJykpIG4gPSBuLnN1YnN0cmluZygzKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCdGaWx0ZXIgJyArIG4sIHYpOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ0V2ZW50IG9uIG1hdGNoJywgKGZpbHRlclsnQWN0aW9uRXZlbnRPbk1hdGNoJ10gPT0gdHJ1ZSkgPyAnWWVzJyA6ICdObycpOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgJ0V0aGVybmV0IEZpbHRlciAjJyArIGZpbHRlclsnSW5zdGFuY2VJRCddLCA1LCBzaG93RmlsdGVyRGV0YWlsc09rLCB4LCBbdG4sIGZpbHRlcl0pOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0ZpbHRlckRldGFpbHNPayhiLCB0YWcpIHsNCiAgICAgICAgICAgIGlmIChiID09IDIpIHsgYW10c3RhY2suRGVsZXRlKHRhZ1swXSwgdGFnWzFdLCBkZWxldGVEZWZlbnNlRmlsdGVyKTsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZGVsZXRlRGVmZW5zZUZpbHRlcihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnUmVtb3ZlIEZpbHRlcicsICJVbmFibGUgdG8gcmVtb3ZlIGZpbHRlciwgbWFrZSBzdXJlIGl0J3Mgbm90IGluIHVzZS4iKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgUHVsbFN5c3RlbURlZmVuc2UoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIHZhciB4eEFkZERlZmVuc2VQb2xpY3lGaWx0ZXJzOw0KICAgICAgICBmdW5jdGlvbiBBZGREZWZlbnNlUG9saWN5KCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgeHhBZGREZWZlbnNlUG9saWN5RmlsdGVycyA9IFtdOw0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IGlkPXBvbGljeW5hbWUgdGl0bGU9Jzxwb2xpY3kgbmFtZT46PHBvbGljeSBwcmVjZWRlbmNlIG51bWJlcj4nIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG1heGxlbmd0aD0xNiBvbmtleXVwPUFkZERlZmVuc2VQb2xpY3lVcGRhdGUoKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5OYW1lPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PHNlbGVjdCBpZD1wb2xpY3l0eCB0aXRsZT0nRGVmYXVsdCBhY3Rpb24gdG8gdGFrZSBmb3Igb3V0Ym91bmQgdHJhZmZpYycgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MTMzcHg+PG9wdGlvbiB2YWx1ZT0wPkFsbG93PG9wdGlvbiB2YWx1ZT0xPkRyb3A8b3B0aW9uIHZhbHVlPTI+QWxsb3csQ291bnQ8b3B0aW9uIHZhbHVlPTM+RHJvcCxDb3VudDxvcHRpb24gdmFsdWU9ND5BbGxvdyxDb3VudCxFdmVudDxvcHRpb24gdmFsdWU9NT5Ecm9wLENvdW50LEV2ZW50PC9zZWxlY3Q+PHNlbGVjdCBpZD1wb2xpY3lyeCBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoxMzNweCB0aXRsZT0nRGVmYXVsdCBhY3Rpb24gdG8gdGFrZSBmb3IgaW5ib3VuZCB0cmFmZmljJz48b3B0aW9uIHZhbHVlPTA+QWxsb3c8b3B0aW9uIHZhbHVlPTE+RHJvcDxvcHRpb24gdmFsdWU9Mj5BbGxvdyxDb3VudDxvcHRpb24gdmFsdWU9Mz5Ecm9wLENvdW50PG9wdGlvbiB2YWx1ZT00PkFsbG93LENvdW50LEV2ZW50PG9wdGlvbiB2YWx1ZT01PkRyb3AsQ291bnQsRXZlbnQ8L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5EZWZhdWx0IFRYIC8gUlg8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBpZD1wb2xpY3lGaWx0ZXJzPjwvZGl2PiI7DQogICAgICAgICAgICBpZiAoeHhTeXN0ZW1EZWZlbnNlWydBTVRfSGRyODAyMUZpbHRlciddLnJlc3BvbnNlcy5sZW5ndGggPiAwIHx8IHh4U3lzdGVtRGVmZW5zZVsnQU1UX0lQSGVhZGVyc0ZpbHRlciddLnJlc3BvbnNlcy5sZW5ndGggPiAwKSB7DQogICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48ZGl2IHN0eWxlPWZsb2F0OnJpZ2h0PjxzZWxlY3QgaWQ9eGZpbHRlciBzdHlsZT13aWR0aDoxODZweD4iOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhTeXN0ZW1EZWZlbnNlWydBTVRfSGRyODAyMUZpbHRlciddLnJlc3BvbnNlcykgew0KICAgICAgICAgICAgICAgICAgICB2YXIgZmlsdGVyID0geHhTeXN0ZW1EZWZlbnNlWydBTVRfSGRyODAyMUZpbHRlciddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPG9wdGlvbiB2YWx1ZT0iICsgZmlsdGVyWyJJbnN0YW5jZUlEIl0gKyAiPiIgKyBmaWx0ZXJbIk5hbWUiXTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eFN5c3RlbURlZmVuc2VbJ0FNVF9JUEhlYWRlcnNGaWx0ZXInXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGZpbHRlciA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX0lQSGVhZGVyc0ZpbHRlciddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPG9wdGlvbiB2YWx1ZT0iICsgZmlsdGVyWyJJbnN0YW5jZUlEIl0gKyAiPiIgKyBmaWx0ZXJbIk5hbWUiXTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgeCArPSAiPC9zZWxlY3Q+PGlucHV0IGlkPWFkZEZpbHRlckJ1dHRvbiB0eXBlPWJ1dHRvbiB2YWx1ZT1BZGQgc3R5bGU9d2lkdGg6ODBweCBvbmNsaWNrPWFkZEZpbHRlckJ1dHRvbigpPjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PkFkZCBGaWx0ZXI8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgJ0FkZCBTeXN0ZW0gRGVmZW5zZSBQb2xpY3knLCAzLCBBZGREZWZlbnNlUG9saWN5T2ssIHgpOw0KICAgICAgICAgICAgQWRkRGVmZW5zZVBvbGljeVVwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gYWRkRmlsdGVyQnV0dG9uKCkgew0KICAgICAgICAgICAgaWYgKHh4QWRkRGVmZW5zZVBvbGljeUZpbHRlcnMuaW5kZXhPZihRKCd4ZmlsdGVyJykudmFsdWUpID49IDApIHJldHVybjsNCiAgICAgICAgICAgIHh4QWRkRGVmZW5zZVBvbGljeUZpbHRlcnMucHVzaChRKCd4ZmlsdGVyJykudmFsdWUpOw0KICAgICAgICAgICAgQWRkRGVmZW5zZVBvbGljeVVwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gcmVtb3ZlRmlsdGVyQnV0dG9uKGgpIHsNCiAgICAgICAgICAgIHh4QWRkRGVmZW5zZVBvbGljeUZpbHRlcnMuc3BsaWNlKGgsIDEpOw0KICAgICAgICAgICAgQWRkRGVmZW5zZVBvbGljeVVwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkRGVmZW5zZVBvbGljeVVwZGF0ZSgpIHsNCiAgICAgICAgICAgIHZhciBvayA9IFEoJ3BvbGljeW5hbWUnKS52YWx1ZS5zcGxpdCgnOicpWzBdLmxlbmd0aCA+IDA7DQogICAgICAgICAgICBRRSgnaWR4X2RsZ09rQnV0dG9uJywgb2spOw0KICAgICAgICAgICAgaWYgKHh4QWRkRGVmZW5zZVBvbGljeUZpbHRlcnMubGVuZ3RoID09IDApIHsNCiAgICAgICAgICAgICAgICBRSCgncG9saWN5RmlsdGVycycsICc8YnI+PGk+VGhpcyBwb2xpY3kgY29udGFpbnMgbm8gZmlsdGVycy48L2k+PGJyPjxicj4nKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4QWRkRGVmZW5zZVBvbGljeUZpbHRlcnMpIHsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBjbGFzcz1pdGVtQmFyIHN0eWxlPW1hcmdpbi1yaWdodDowPjxkaXYgc3R5bGU9ZmxvYXQ6cmlnaHQ+IiArIEFkZEJ1dHRvbjIoIlJlbW92ZSIsICJyZW1vdmVGaWx0ZXJCdXR0b24oIiArIGkgKyAiKSIpICsgIjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4O21heC13aWR0aDoyNjBweDtvdmVyZmxvdzpoaWRkZW4+PGI+IiArIEdldEZpbHRlckJ5SWQoeHhBZGREZWZlbnNlUG9saWN5RmlsdGVyc1tpXSlbJ05hbWUnXSArICI8L2I+PC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgUUgoJ3BvbGljeUZpbHRlcnMnLCB4KTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIFRPRE86IE9uY2UgbG9hZGVkLCB3ZSBjb3VsZCBtYWtlIGEgdGFibGUgb2YgImhhbmRsZSAtPiBmaWx0ZXIiIHdoZXJlIGJvdGggZmlsdGVyIHR5cGVzIGFyZSBtaXhlZC1pbi4gQ291bGQgbWFrZSB0aGluZ3Mgc2ltcGxlci9zbWFsbGVyPw0KICAgICAgICAvLyBXZSB3b3VsZCBvbmx5IGhhdmUgb25lIHRhYmxlIHRvIGxvb3AgaW5zdGVhZCBvZiB0d28gYXQgYSBmZXcgcGxhY2VzLiBUaGlzIGZ1bmN0aW9uIHdvdWxkIGJlIHJlbW92ZWQgY29tcGxldGVseS4NCiAgICAgICAgZnVuY3Rpb24gR2V0RmlsdGVyQnlJZChoKSB7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4U3lzdGVtRGVmZW5zZVsnQU1UX0hkcjgwMjFGaWx0ZXInXS5yZXNwb25zZXMpIHsgdmFyIGZpbHRlciA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX0hkcjgwMjFGaWx0ZXInXS5yZXNwb25zZXNbaV07IGlmIChmaWx0ZXJbIkluc3RhbmNlSUQiXSA9PSBoKSByZXR1cm4gZmlsdGVyOyB9DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4U3lzdGVtRGVmZW5zZVsnQU1UX0lQSGVhZGVyc0ZpbHRlciddLnJlc3BvbnNlcykgeyB2YXIgZmlsdGVyID0geHhTeXN0ZW1EZWZlbnNlWydBTVRfSVBIZWFkZXJzRmlsdGVyJ10ucmVzcG9uc2VzW2ldOyBpZiAoZmlsdGVyWyJJbnN0YW5jZUlEIl0gPT0gaCkgcmV0dXJuIGZpbHRlcjsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkRGVmZW5zZVBvbGljeU9rKCkgew0KICAgICAgICAgICAgdmFyIHR4ID0gUSgncG9saWN5dHgnKS52YWx1ZTsNCiAgICAgICAgICAgIHZhciByeCA9IFEoJ3BvbGljeXJ4JykudmFsdWU7DQogICAgICAgICAgICB2YXIgcHJpID0gMDsNCiAgICAgICAgICAgIHZhciBuID0gUSgncG9saWN5bmFtZScpLnZhbHVlLnNwbGl0KCc6Jyk7DQogICAgICAgICAgICBpZiAobi5sZW5ndGggPT0gMikgcHJpID0gcGFyc2VJbnQoblsxXSk7DQogICAgICAgICAgICB2YXIgZmlsdGVyID0geyAnSW5zdGFuY2VJRCAnOiAwLCAnUG9saWN5TmFtZSc6IG5bMF0sICdQb2xpY3lQcmVjZWRlbmNlJzogcHJpLCAnVHhEZWZhdWx0Q291bnQnOiAodHggPiAxKSwgJ1R4RGVmYXVsdERyb3AnOiAodHggJSAyID09IDEpLCAnVHhEZWZhdWx0TWF0Y2hFdmVudCc6ICh0eCA+IDMpLCAnUnhEZWZhdWx0Q291bnQnOiAocnggPiAxKSwgJ1J4RGVmYXVsdERyb3AnOiAocnggJSAyID09IDEpLCAnUnhEZWZhdWx0TWF0Y2hFdmVudCc6IChyeCA+IDMpIH07DQogICAgICAgICAgICBpZiAoeHhBZGREZWZlbnNlUG9saWN5RmlsdGVycy5sZW5ndGggPiAwKSBmaWx0ZXJbJ0ZpbHRlckNyZWF0aW9uSGFuZGxlcyddID0geHhBZGREZWZlbnNlUG9saWN5RmlsdGVyczsNCiAgICAgICAgICAgIGFtdHN0YWNrLkNyZWF0ZSgnQU1UX1N5c3RlbURlZmVuc2VQb2xpY3knLCBmaWx0ZXIsIEFkZERlZmVuc2VQb2xpY3lPazIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkRGVmZW5zZVBvbGljeU9rMihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnQWRkIFN5c3RlbSBEZWZlbnNlIFBvbGljeScsICJVbmFibGUgdG8gYWRkIHBvbGljeSwgZXJyb3IgIyIgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBQdWxsU3lzdGVtRGVmZW5zZSgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1BvbGljeURldGFpbHMoaSkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHBvbGljeSA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX1N5c3RlbURlZmVuc2VQb2xpY3knXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICB2YXIgeCA9ICcnOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ05hbWUnLCBFc2NhcGVIdG1sKHBvbGljeVsiUG9saWN5TmFtZSJdKSk7DQogICAgICAgICAgICBpZiAocG9saWN5WyJQb2xpY3lQcmVjZWRlbmNlIl0gIT0gMCkgeCArPSBhZGRIdG1sVmFsdWUoJ1ByZWNlZGVuY2UnLCBwb2xpY3lbIlBvbGljeVByZWNlZGVuY2UiXSk7DQoNCiAgICAgICAgICAgIHZhciBhY3Rpb24gPSAocG9saWN5WyJUeERlZmF1bHREcm9wIl0gPT0gdHJ1ZSkgPyAnRHJvcCcgOiAnQWxsb3cnOw0KICAgICAgICAgICAgaWYgKHBvbGljeVsiVHhEZWZhdWx0Q291bnQiXSA9PSB0cnVlKSBhY3Rpb24gKz0gJywgQ291bnQnOw0KICAgICAgICAgICAgaWYgKHBvbGljeVsiVHhEZWZhdWx0TWF0Y2hFdmVudCJdID09IHRydWUpIGFjdGlvbiArPSAnLCBFdmVudCc7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnRGVmYXVsdCBUWCBBY3Rpb24nLCBhY3Rpb24pOw0KDQogICAgICAgICAgICBhY3Rpb24gPSAocG9saWN5WyJSeERlZmF1bHREcm9wIl0gPT0gdHJ1ZSkgPyAnRHJvcCcgOiAnQWxsb3cnOw0KICAgICAgICAgICAgaWYgKHBvbGljeVsiUnhEZWZhdWx0Q291bnQiXSA9PSB0cnVlKSBhY3Rpb24gKz0gJywgQ291bnQnOw0KICAgICAgICAgICAgaWYgKHBvbGljeVsiUnhEZWZhdWx0TWF0Y2hFdmVudCJdID09IHRydWUpIGFjdGlvbiArPSAnLCBFdmVudCc7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnRGVmYXVsdCBSWCBBY3Rpb24nLCBhY3Rpb24pOw0KDQogICAgICAgICAgICBpZiAocG9saWN5WydGaWx0ZXJDcmVhdGlvbkhhbmRsZXMnXSkgeyBmb3IgKHZhciBpIGluIHBvbGljeVsnRmlsdGVyQ3JlYXRpb25IYW5kbGVzJ10pIHsgeCArPSBhZGRIdG1sVmFsdWUoJ0ZpbHRlciAjJyArICgraSArIDEpLCBHZXRGaWx0ZXJCeUlkKHBvbGljeVsnRmlsdGVyQ3JlYXRpb25IYW5kbGVzJ11baV0pWydOYW1lJ10pOyB9IH0NCg0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgJ1BvbGljeSAjJyArIHBvbGljeVsnSW5zdGFuY2VJRCddLnN1YnN0cmluZygyMCksIDUsIHNob3dQb2xpY3lEZXRhaWxzT2ssIHgsIHBvbGljeSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93UG9saWN5RGV0YWlsc09rKGIsIHRhZykgew0KICAgICAgICAgICAgaWYgKGIgPT0gMikgeyBhbXRzdGFjay5EZWxldGUoJ0FNVF9TeXN0ZW1EZWZlbnNlUG9saWN5JywgdGFnLCBkZWxldGVEZWZlbnNlUG9saWN5KTsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZGVsZXRlRGVmZW5zZVBvbGljeShzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnUmVtb3ZlIFBvbGljeScsICJVbmFibGUgdG8gcmVtb3ZlIHBvbGljeSwgbWFrZSBzdXJlIGl0J3Mgbm90IGluIHVzZS4iKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgUHVsbFN5c3RlbURlZmVuc2UoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQoNCg0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gV0lSRUxFU1MgU0VUVElOR1MgUEFORUwNCiAgICAgICAgLy8NCg0KICAgICAgICB2YXIgeHhXaXJlbGVzczsNCiAgICAgICAgZnVuY3Rpb24gUHVsbFdpcmVsZXNzKCkgew0KICAgICAgICAgICAgYW10Rmlyc3RQdWxsIHw9IDI7DQogICAgICAgICAgICB0cnkgeyBpZiAoYW10d2lyZWxlc3NpZiA9PSAtMSkgcmV0dXJuOyB9IGNhdGNoIChlKSB7fSAvLyBJZiB0aGUgd2lyZWxlc3MgYWRhcHRlciBoYXMgbm8gTUFDLCBkb24ndCBzaG93IHRoaXMuDQogICAgICAgICAgICBhbXRzdGFjay5CYXRjaEVudW0oIiIsIFsiKkNJTV9XaUZpUG9ydENhcGFiaWxpdGllcyIsICIqQ0lNX1dpRmlQb3J0IiwgIipDSU1fV2lGaUVuZHBvaW50IiwgIkNJTV9XaUZpRW5kcG9pbnRTZXR0aW5ncyJdLCBwcm9jZXNzV2lyZWxlc3MpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gd2lmaVJlZnJlc2goKSB7IGlmICgheHhkaWFsb2dNb2RlKSBQdWxsV2lyZWxlc3MoKTsgfQ0KDQogICAgICAgIHZhciB4eFdpZmlTdGF0ZSA9IHsgMzogJ0Rpc2FibGVkJywgMzI3Njg6ICdFbmFibGVkIGluIFMwJywgMzI3Njk6ICdFbmFibGVkIGluIFMwLCBTeC9BQycgfTsNCiAgICAgICAgdmFyIHh4UmFkaW9TdGF0ZSA9IAl7IDI6ICdPbiwgQ29ubmVjdGVkJywgMzogJ09mZicsIDY6ICdPbiwgRGlzY29ubmVjdGVkJyB9Ow0KICAgICAgICB2YXIgeHhXaWZpQXV0aGVudGljYXRpb25NZXRob2Q9IHsgMTogJ090aGVyJywgMjogJ09wZW4nLCAzOiAnU2hhcmVkIEtleScsIDQ6ICdXUEEgUFNLJywgNTogJ1dQQSBJRUVFIDgwMi4xeCcsIDY6ICdXUEEyIFBTSycsIDc6ICdXUEEyIElFRUUgODAyLjF4JyB9Ow0KICAgICAgICB2YXIgeHhXaWZpRW5jcnlwdGlvbk1ldGhvZCA9IHsgMTogJ090aGVyJywgMjogJ1dFUCcsIDM6ICdUS0lQLVJDNCcsIDQ6ICdDQ01QLUFFUycsIDU6ICdOb25lJyB9OyAvLyBGb3IgMiAmIDUsIEF1dGhlbnRpY2F0aW9uTWV0aG9kIG11c3QgYmUgMiBvciAzLiBGb3IgMyAmIDQgQXV0aGVudGljYXRpb25NZXRob2QgbXVzdCBiZSA0LDUsNiBvciA3DQoNCiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1dpcmVsZXNzKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgeHhXaXJlbGVzcyA9IHJlc3BvbnNlczsgfSBlbHNlIHsgeHhXaXJlbGVzcyA9IHVuZGVmaW5lZDsgfQ0KICAgICAgICAgICAgdXBkYXRlU3lzdGVtU3RhdHVzKCk7DQogICAgICAgICAgICBzaG93V2lyZWxlc3NJbmZvKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93V2lyZWxlc3NJbmZvKCkgew0KICAgICAgICAgICAgaWYgKCF4eFdpcmVsZXNzKSByZXR1cm47DQogICAgICAgICAgICB2YXIgaSwgaiwgcyA9ICIiLCBzYywgeCA9ICI8YnI+PGgyPldpcmVsZXNzIFByb2ZpbGVzPC9oMj4iOw0KICAgICAgICAgICAgaWYgKCEoeHhXaXJlbGVzc1snQ0lNX1dpRmlQb3J0Q2FwYWJpbGl0aWVzJ10ucmVzcG9uc2UpKSByZXR1cm47DQoNCiAgICAgICAgICAgIC8vIFNob3cgV0lGSSBwcm9maWxlcyBzb3J0ZWQgYnkgcHJpb3JpdHkNCiAgICAgICAgICAgIHggKz0gVGFibGVTdGFydDIoKTsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjIgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPldpcmVsZXNzIHByb2ZpbGVzIHRoYXQgSW50ZWwmcmVnOyBBTVQgd2lsbCB1c2UgZm9yIG5ldHdvcmsgY29ubmVjdGl2aXR5Ljxicj48YnI+IjsNCiAgICAgICAgICAgIHMgPSAwOw0KICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgMjU2OyBpKyspIHsNCiAgICAgICAgICAgICAgICBmb3IgKGogaW4geHhXaXJlbGVzc1snQ0lNX1dpRmlFbmRwb2ludFNldHRpbmdzJ10ucmVzcG9uc2VzKSB7DQogICAgICAgICAgICAgICAgICAgIHNjID0geHhXaXJlbGVzc1snQ0lNX1dpRmlFbmRwb2ludFNldHRpbmdzJ10ucmVzcG9uc2VzW2pdOw0KICAgICAgICAgICAgICAgICAgICBpZiAoc2NbJ0F1dGhlbnRpY2F0aW9uTWV0aG9kJ10gPT0gMSkgY29udGludWU7IC8vIFNraXAgIkVuZHBvaW50IFVzZXIgU2V0dGluZ3MiDQogICAgICAgICAgICAgICAgICAgIGlmIChzY1snUHJpb3JpdHknXSA9PSBpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93V2lmaURldGFpbHMoIiArIGogKyAiKT48ZGl2IHN0eWxlPWZsb2F0OnJpZ2h0PiIgKyBFc2NhcGVIdG1sKHNjWydTU0lEJ10pICsgIiwgIiArIHh4V2lmaUF1dGhlbnRpY2F0aW9uTWV0aG9kW3NjWydBdXRoZW50aWNhdGlvbk1ldGhvZCddXSArICIsICIgKyB4eFdpZmlFbmNyeXB0aW9uTWV0aG9kW3NjWydFbmNyeXB0aW9uTWV0aG9kJ11dICsgIiAmbmJzcDsgIjsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHggKz0gQWRkQnV0dG9uMigiUmVtb3ZlIiwgIndpZmlSZW1vdmVCdXR0b24oXCIiICsgaiArICJcIikiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gIjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PjxiPiIgKyBFc2NhcGVIdG1sKHNjWydFbGVtZW50TmFtZSddKSArICI8L2I+PC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICAgICAgICAgIHMrKzsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChzID09IDApIHggKz0gJzxpPk5vIFdpcmVsZXNzIFByb2ZpbGVzIFByZXNlbnQ8L2k+PGJyPic7DQoNCiAgICAgICAgICAgIC8vIEVuZCBvZiB0YWJsZQ0KICAgICAgICAgICAgeCArPSAiPGJyPjx0ZCBjbGFzcz1yMj4iOw0KICAgICAgICAgICAgaWYgKHh4QWNjb3VudEFkbWluTmFtZSkgeCArPSBUYWJsZUVuZChBZGRCdXR0b24oIk5ldyBQcm9maWxlIiwgInNob3dXaWZpTmV3UHJvZmlsZSgpIikpOyBlbHNlIHggKz0gVGFibGVFbmQoJycpOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlV2lmaTInLCB4ICsgIjxicj4iKTsNCiAgICAgICAgfQ0KICAgICAgICANCiAgICAgICAgZnVuY3Rpb24gc2hvd1dpZmlTdGF0ZURsZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBzID0gIiI7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4V2lmaVN0YXRlKSB7IHMgKz0gJzxpbnB1dCB0eXBlPXJhZGlvIG5hbWU9ZDExIGlkPXdsJyArIGkgKyAnIHZhbHVlPScgKyBpICsgJyAnICsgKCh4eFdpcmVsZXNzWydDSU1fV2lGaVBvcnQnXS5yZXNwb25zZVsiRW5hYmxlZFN0YXRlIl0gPT0gaSk/ImNoZWNrZWQiOiIiKSArICc+JyArIHh4V2lmaVN0YXRlW2ldICsgJzxicj4nOyB9DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAnV2lyZWxlc3MgU3RhdGUnLCAzLCB3aWZpU3RhdGVEbGcsIHMpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gd2lmaVN0YXRlRGxnKCkgeyBhbXRzdGFjay5DSU1fV2lGaVBvcnRfUmVxdWVzdFN0YXRlQ2hhbmdlKCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPWQxMV06Y2hlY2tlZCcpLnZhbHVlLCBudWxsLCBmdW5jdGlvbigpIHsgYW10c3RhY2suR2V0KCJDSU1fV2lGaVBvcnQiLCBmdW5jdGlvbihzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgeyBpZiAoc3RhdHVzID09IDIwMCkgeyB4eFdpcmVsZXNzWydDSU1fV2lGaVBvcnQnXS5yZXNwb25zZSA9IHJlc3BvbnNlLkJvZHk7IHNob3dXaXJlbGVzc0luZm8oKTsgfSB9ICk7IH0gKTsgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dXaWZpRGV0YWlscyhoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgaSwgc2MgPSB4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnXS5yZXNwb25zZXNbaF0sIHggPSAnPGRpdiBzdHlsZT10ZXh0LWFsaWduOmxlZnQ+JzsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJQcm9maWxlIE5hbWUiLCBFc2NhcGVIdG1sKHNjWydFbGVtZW50TmFtZSddKSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiU1NJRCIsIHNjWydTU0lEJ10pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkF1dGhlbnRpY2F0aW9uIiwgeHhXaWZpQXV0aGVudGljYXRpb25NZXRob2Rbc2NbJ0F1dGhlbnRpY2F0aW9uTWV0aG9kJ11dKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJFbmNyeXB0aW9uIiwgeHhXaWZpRW5jcnlwdGlvbk1ldGhvZFtzY1snRW5jcnlwdGlvbk1ldGhvZCddXSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiUHJpb3JpdHkiLCBzY1snUHJpb3JpdHknXSk7DQogICAgICAgICAgICB4ICs9ICI8L2Rpdj4iOw0KICAgICAgICAgICAgbWVzc2FnZWJveCgiV2lyZWxlc3MgUHJvZmlsZSIsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gd2lmaVJlbW92ZUJ1dHRvbihoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgc2MgPSB4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnXS5yZXNwb25zZXNbaF07DQogICAgICAgICAgICBRSCgnaWRfZGlhbG9nTWVzc2FnZScsICdSZW1vdmUgd2lyZWxlc3MgcHJvZmlsZSBcIicgKyBzY1siRWxlbWVudE5hbWUiXSArICdcIj8nKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMSwgIldpcmVsZXNzIFByb2ZpbGUiLCAzLCBmdW5jdGlvbiAoKSB7IHJlbW92ZVdpZmlCdXR0b25FeChoKSB9KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHJlbW92ZVdpZmlCdXR0b25FeChoKSB7DQogICAgICAgICAgICB2YXIgc2MgPSB4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnXS5yZXNwb25zZXNbaF07DQogICAgICAgICAgICBhbXRzdGFjay5EZWxldGUoJ0NJTV9XaUZpRW5kcG9pbnRTZXR0aW5ncycsIHsgSW5zdGFuY2VJRDogc2NbJ0luc3RhbmNlSUQnXSB9LCByZW1vdmVXaWZpRW50cnlSZXNwb25zZSwgMCwgMSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiByZW1vdmVXaWZpRW50cnlSZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICBpZiAobWV0aG9kY2hlY2socmVzcG9uc2UpKSByZXR1cm47DQogICAgICAgICAgICBhbXRzdGFjay5FbnVtKCJDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MiLCBmdW5jdGlvbihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsgaWYgKHN0YXR1cyA9PSAyMDApIHsgeHhXaXJlbGVzc1snQ0lNX1dpRmlFbmRwb2ludFNldHRpbmdzJ10ucmVzcG9uc2VzID0gcmVzcG9uc2VzOyBzaG93V2lyZWxlc3NJbmZvKCk7IH0gfSApOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1dpZmlOZXdQcm9maWxlKCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIGZvciAoaSA9IDE7IGkgPCAyNTY7IGkrKykgew0KICAgICAgICAgICAgICAgIHZhciB0ID0gMTsNCiAgICAgICAgICAgICAgICBmb3IgKGogaW4geHhXaXJlbGVzc1snQ0lNX1dpRmlFbmRwb2ludFNldHRpbmdzJ10ucmVzcG9uc2VzKSB7IGlmICh4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnXS5yZXNwb25zZXNbal1bJ1ByaW9yaXR5J10gPT0gaSkgdCA9IDA7IH0NCiAgICAgICAgICAgICAgICBpZiAodCkgeyB4ICs9ICc8b3B0aW9uIHZhbHVlPScrIGkgKyc+JysgaTsgfSAvLyBPcHRpb24gaXMgYSB0YWcgdGhhdCBpcyBzZWxmIGNsb3NpbmcuDQogICAgICAgICAgICB9DQogICAgICAgICAgICBRSCgnaWR4X2QxMnByaScsIHgpOw0KDQogICAgICAgICAgICBpZHhfZDEyYXV0aC52YWx1ZSA9IDY7DQogICAgICAgICAgICBpZHhfZDEyZW5jLnZhbHVlID0gNDsNCg0KICAgICAgICAgICAgaWR4X2QxMm5hbWUudmFsdWUgPSBpZHhfZDEyc3NpZC52YWx1ZSA9IGlkeF9kMTJwYXNzd29yZDEudmFsdWUgPSBpZHhfZDEycGFzc3dvcmQyLnZhbHVlID0gJyc7DQoNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTIsICJBZGQgV2lyZWxlc3MgUHJvZmlsZSIsIDMsIGZ1bmN0aW9uICgpIHsgYWRkV2lmaVByb2ZpbGUoKSB9KTsNCiAgICAgICAgICAgIHVwZGF0ZVdpZmlEaWFsb2coKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZFdpZmlQcm9maWxlKCkgew0KICAgICAgICAgICAgYW10c3RhY2suQU1UX1dpRmlQb3J0Q29uZmlndXJhdGlvblNlcnZpY2VfQWRkV2lGaVNldHRpbmdzKA0KCQkJCXsNCgkJCQkgICAgJ19fcGFyYW1ldGVyVHlwZSc6ICdyZWZlcmVuY2UnLA0KCQkJCSAgICAnX19yZXNvdXJjZVVyaSc6IGFtdHN0YWNrLkNvbXBsZXRlTmFtZSgnQ0lNX1dpRmlFbmRwb2ludCcpLA0KCQkJCSAgICAnTmFtZSc6ICdXaUZpIEVuZHBvaW50IDAnDQoJCQkJfSwgew0KCQkJCSAgICAnX19wYXJhbWV0ZXJUeXBlJzogJ2luc3RhbmNlJywNCgkJCQkgICAgJ19fbmFtZXNwYWNlJzogYW10c3RhY2suQ29tcGxldGVOYW1lKCdDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnKSwNCgkJCQkgICAgJ0VsZW1lbnROYW1lJzogaWR4X2QxMm5hbWUudmFsdWUsDQoJCQkJICAgICdJbnN0YW5jZUlEJzogJ0ludGVsKHIpIEFNVDpXaUZpIEVuZHBvaW50IFNldHRpbmdzICcgKyBpZHhfZDEybmFtZS52YWx1ZSwNCgkJCQkgICAgJ0F1dGhlbnRpY2F0aW9uTWV0aG9kJzogaWR4X2QxMmF1dGgudmFsdWUsDQoJCQkJICAgICdFbmNyeXB0aW9uTWV0aG9kJzogaWR4X2QxMmVuYy52YWx1ZSwNCgkJCQkgICAgJ1NTSUQnOiBpZHhfZDEyc3NpZC52YWx1ZSwNCgkJCQkgICAgJ1ByaW9yaXR5JzogaWR4X2QxMnByaS52YWx1ZSwNCgkJCQkgICAgJ1BTS1Bhc3NQaHJhc2UnOiBpZHhfZDEycGFzc3dvcmQxLnZhbHVlDQoJCQkJfSwNCgkJCQludWxsLCBudWxsLCBudWxsLCByZW1vdmVXaWZpRW50cnlSZXNwb25zZQ0KCQkJKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVwZGF0ZVdpZmlEaWFsb2coKSB7DQogICAgICAgICAgICB2YXIgciA9IHRydWU7DQogICAgICAgICAgICB2YXIgYSA9IGlkeF9kMTJhdXRoLnZhbHVlOw0KICAgICAgICAgICAgdmFyIGUgPSBpZHhfZDEyZW5jLnZhbHVlOw0KICAgICAgICAgICAgUVYoJ2lkX2QxMmUyJywgYSA8IDQpOw0KICAgICAgICAgICAgUVYoJ2lkX2QxMmUzJywgYSA+IDMpOw0KICAgICAgICAgICAgUVYoJ2lkX2QxMmU0JywgYSA+IDMpOw0KICAgICAgICAgICAgUVYoJ2lkX2QxMmU1JywgYSA8IDQpOw0KICAgICAgICAgICAgaWYgKGEgPCA0ICYmIChlID09IDMgfHwgZSA9PSA0KSkgeyBpZHhfZDEyZW5jLnZhbHVlID0gMjsgfQ0KICAgICAgICAgICAgaWYgKGEgPiAzICYmIChlID09IDIgfHwgZSA9PSA1KSkgeyBpZHhfZDEyZW5jLnZhbHVlID0gMzsgfQ0KDQogICAgICAgICAgICAvLyBDaGVjayBpZiB0aGVyZSBpcyBhbHJlYWR5IGEgcHJvZmlsZSB3aXRoIHRoaXMgbmFtZQ0KICAgICAgICAgICAgZm9yICh2YXIgaiBpbiB4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnXS5yZXNwb25zZXMpIHsgaWYgKHh4V2lyZWxlc3NbJ0NJTV9XaUZpRW5kcG9pbnRTZXR0aW5ncyddLnJlc3BvbnNlc1tqXVsnRWxlbWVudE5hbWUnXSA9PSBpZHhfZDEybmFtZS52YWx1ZSkgeyByID0gZmFsc2U7IH0gfQ0KDQogICAgICAgICAgICBRRSgnaWR4X2RsZ09rQnV0dG9uJywgciA9PSB0cnVlICYmIChpZHhfZDEybmFtZS52YWx1ZS5sZW5ndGggPiAwKSAmJiAoaWR4X2QxMnNzaWQudmFsdWUubGVuZ3RoID4gMCkgJiYgKGlkeF9kMTJwYXNzd29yZDEudmFsdWUubGVuZ3RoID4gNykgJiYgKGlkeF9kMTJwYXNzd29yZDEudmFsdWUgPT0gaWR4X2QxMnBhc3N3b3JkMi52YWx1ZSkpOw0KICAgICAgICB9DQoNCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIEhBUkRXQVJFIElORk9STUFUSU9OIFBBTkVMDQogICAgICAgIC8vDQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbEhhcmR3YXJlKCkgew0KICAgICAgICAgICAgYW10c3RhY2suQmF0Y2hFbnVtKCIiLCBbIipDSU1fQ29tcHV0ZXJTeXN0ZW1QYWNrYWdlIiwgIkNJTV9TeXN0ZW1QYWNrYWdpbmciLCAiKkNJTV9DaGFzc2lzIiwgIkNJTV9DaGlwIiwgIipDSU1fQ2FyZCIsICIqQ0lNX0JJT1NFbGVtZW50IiwgIkNJTV9Qcm9jZXNzb3IiLCAiQ0lNX1BoeXNpY2FsTWVtb3J5IiwgIkNJTV9NZWRpYUFjY2Vzc0RldmljZSIsICJDSU1fUGh5c2ljYWxQYWNrYWdlIl0sIHByb2Nlc3NIYXJkd2FyZSk7DQogICAgICAgICAgICBhbXRGaXJzdFB1bGwgfD0gMTsgLy8gU2V0IHRoZSBoYXJkd2FyZSBpbmZvIGJpdCBvbiwgaW5kaWNhdGVzIHdlIGFyZSBwdWxsaW5nIHRoaXMgaW5mb3JtYXRpb24uDQogICAgICAgIH0NCg0KICAgICAgICAvLyBodHRwOi8vd3d3LmRtdGYub3JnL3NpdGVzL2RlZmF1bHQvZmlsZXMvc3RhbmRhcmRzL2RvY3VtZW50cy9EU1AwMTM0XzIuNy4xLnBkZg0KICAgICAgICB2YXIgRE1URkNQVVN0YXR1cyA9IFsiVW5rbm93biIsICJFbmFibGVkIiwgIkRpc2FibGVkIGJ5IFVzZXIiLCAiRGlzYWJsZWQgQnkgQklPUyAoUE9TVCBFcnJvcikiLCAiSWRsZSIsICJPdGhlciJdOw0KICAgICAgICB2YXIgRE1URk1lbVR5cGUgPSBbIlVua25vd24iLCAiT3RoZXIiLCAiRFJBTSIsICJTeW5jaHJvbm91cyBEUkFNIiwgIkNhY2hlIERSQU0iLCAiRURPIiwgIkVEUkFNIiwgIlZSQU0iLCAiU1JBTSIsICJSQU0iLCAiUk9NIiwgIkZsYXNoIiwgIkVFUFJPTSIsICJGRVBST00iLCAiRVBST00iLCAiQ0RSQU0iLCAiM0RSQU0iLCAiU0RSQU0iLCAiU0dSQU0iLCAiUkRSQU0iLCAiRERSIiwgIkREUi0yIiwgIkJSQU0iLCAiRkItRElNTSIsICJERFIzIiwgIkZCRDIiLCAiRERSNCIsICJMUEREUiIsICJMUEREUjIiLCAiTFBERFIzIiwgIkxQRERSNCJdOw0KICAgICAgICB2YXIgRE1URk1lbUZvcm1GYWN0b3IgPSBbJycsICdPdGhlcicsJ1Vua25vd24nLCdTSU1NJywnU0lQJywnQ2hpcCcsJ0RJUCcsJ1pJUCcsJ1Byb3ByaWV0YXJ5IENhcmQnLCdESU1NJywnVFNPUCcsJ1JvdyBvZiBjaGlwcycsJ1JJTU0nLCdTT0RJTU0nLCdTUklNTScsJ0ZCLURJTSddOw0KICAgICAgICB2YXIgRE1URlByb2NGYW1pbGx5ID0geyAvLyBQYWdlIDQ2IG9mIERNVEYgZG9jdW1lbnQNCiAgICAgICAgICAgIDE5MTogJ0ludGVsJnJlZzsgQ29yZSZ0cmFkZTsgMiBEdW8gUHJvY2Vzc29yJywNCiAgICAgICAgICAgIDE5MjogJ0ludGVsJnJlZzsgQ29yZSZ0cmFkZTsgMiBTb2xvIHByb2Nlc3NvcicsDQogICAgICAgICAgICAxOTM6ICdJbnRlbCZyZWc7IENvcmUmdHJhZGU7IDIgRXh0cmVtZSBwcm9jZXNzb3InLA0KICAgICAgICAgICAgMTk0OiAnSW50ZWwmcmVnOyBDb3JlJnRyYWRlOyAyIFF1YWQgcHJvY2Vzc29yJywNCiAgICAgICAgICAgIDE5NTogJ0ludGVsJnJlZzsgQ29yZSZ0cmFkZTsgMiBFeHRyZW1lIG1vYmlsZSBwcm9jZXNzb3InLA0KICAgICAgICAgICAgMTk2OiAnSW50ZWwmcmVnOyBDb3JlJnRyYWRlOyAyIER1byBtb2JpbGUgcHJvY2Vzc29yJywNCiAgICAgICAgICAgIDE5NzogJ0ludGVsJnJlZzsgQ29yZSZ0cmFkZTsgMiBTb2xvIG1vYmlsZSBwcm9jZXNzb3InLA0KICAgICAgICAgICAgMTk4OiAnSW50ZWwmcmVnOyBDb3JlJnRyYWRlOyBpNyBwcm9jZXNzb3InLA0KICAgICAgICAgICAgMTk5OiAnRHVhbC1Db3JlIEludGVsJnJlZzsgQ2VsZXJvbiZyZWc7IHByb2Nlc3NvcicgfTsNCg0KICAgICAgICB2YXIgSGFyZHdhcmVJbnZlbnRvcnk7DQogICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NIYXJkd2FyZShzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSByZXR1cm47DQoNCiAgICAgICAgICAgIHZhciBpLCB4ID0gIjx0YWJsZSBjbGFzcz1sb2cxIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCBzdHlsZT13aWR0aDoxMDAlO2JvcmRlci1yYWRpdXM6OHB4PiI7DQogICAgICAgICAgICBIYXJkd2FyZUludmVudG9yeSA9IHJlc3BvbnNlczsNCiAgICAgICAgICAgIFFWKCdnbzInLCB0cnVlKTsgLy8gU2hvdyAiSGFyZHdhcmUgSW5mb3JtYXRpb24iIG9uIGxlZnQgcGFuZWwNCg0KDQogICAgICAgICAgICB4ICs9IFRhYmxlRW5kKCI8ZGl2PiZuYnNwOyIgKyBBZGRSZWZyZXNoQnV0dG9uKCJQdWxsSGFyZHdhcmUoMSkiKSArIEFkZEJ1dHRvbigiU2F2ZS4uLiIsICJTYXZlSGFyZHdhcmVMb2coKSIpICsgJyBIYXJkd2FyZSBpbmZvcm1hdGlvbiBpcyBnYXRoZXJlZCBhdCBzeXN0ZW0gYm9vdCB0aW1lLicpOw0KDQogICAgICAgICAgICB2YXIgYmEgPSByZXNwb25zZXNbJ0NJTV9DaGFzc2lzJ10ucmVzcG9uc2U7DQogICAgICAgICAgICB2YXIgYmIgPSByZXNwb25zZXNbJ0NJTV9DYXJkJ10ucmVzcG9uc2U7DQogICAgICAgICAgICB2YXIgdiA9IHJlc3BvbnNlc1snQ0lNX0JJT1NFbGVtZW50J10ucmVzcG9uc2VbIlNvZnR3YXJlRWxlbWVudElEIl07DQogICAgICAgICAgICANCiAgICAgICAgICAgIHggKz0gIjxicj48aDI+UGxhdGZvcm08L2gyPiI7DQogICAgICAgICAgICB4ICs9IEZ1bGxUYWJsZSh7IkNvbXB1dGVyIG1vZGVsIjpiYVsiTW9kZWwiXSwgIk1hbnVmYWN0dXJlciI6YmFbIk1hbnVmYWN0dXJlciJdLCAiVmVyc2lvbiI6YmFbIlZlcnNpb24iXSwgIlNlcmlhbCBudW1iZXIiOmJhWyJTZXJpYWxOdW1iZXIiXSwgIlN5c3RlbSBJRCI6Z3VpZFRvU3RyKHJlc3BvbnNlc1snQ0lNX1N5c3RlbVBhY2thZ2luZyddLnJlc3BvbnNlc1swXVsiUGxhdGZvcm1HVUlEIl0pLnRvTG93ZXJDYXNlKCl9LCAnJyk7DQoNCiAgICAgICAgICAgIHggKz0gIjxicj48aDI+QmFzZWJvYXJkPC9oMj4iOw0KICAgICAgICAgICAgeCArPSBGdWxsVGFibGUoeyAiTWFudWZhY3R1cmVyIjpiYlsiTWFudWZhY3R1cmVyIl0sICJQcm9kdWN0IG5hbWUiOmJiWyJNb2RlbCJdLCAiVmVyc2lvbiI6YmJbIlZlcnNpb24iXSwgIlNlcmlhbCBudW1iZXIiOmJiWyJTZXJpYWxOdW1iZXIiXSwgIkFzc2V0IHRhZyI6YmJbIlRhZyJdLCAiUmVwbGFjZWFibGU/IjooYmJbIkNhbkJlRlJVZWQiXT09dHJ1ZSk/J1llcyc6J05vJyB9LCcnKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgeCArPSAiPGJyPjxoMj5CSU9TPC9oMj4iOw0KICAgICAgICAgICAgeCArPSBGdWxsVGFibGUoeyJWZW5kb3IiOnJlc3BvbnNlc1snQ0lNX0JJT1NFbGVtZW50J10ucmVzcG9uc2VbIk1hbnVmYWN0dXJlciJdLCAiVmVyc2lvbiI6diwgIlJlbGVhc2UgZGF0ZSI6bmV3IERhdGUocmVzcG9uc2VzWydDSU1fQklPU0VsZW1lbnQnXS5yZXNwb25zZVsiUmVsZWFzZURhdGUiXVsnRGF0ZXRpbWUnXSkudG9Mb2NhbGVEYXRlU3RyaW5nKCdlbicsIHt0aW1lWm9uZTonVVRDJ30pfSwnJyk7DQogICAgICAgICAgICANCiAgICAgICAgICAgIHggKz0gIjxicj4iOw0KICAgICAgICAgICAgZm9yIChpIGluIHJlc3BvbnNlc1snQ0lNX1Byb2Nlc3NvciddLnJlc3BvbnNlcykgew0KICAgICAgICAgICAgICAgIHZhciBwID0gcmVzcG9uc2VzWydDSU1fUHJvY2Vzc29yJ10ucmVzcG9uc2VzW2ldOw0KICAgICAgICAgICAgICAgIHZhciBxID0gcmVzcG9uc2VzWydDSU1fQ2hpcCddLnJlc3BvbnNlc1tpXTsgLy8gVGhpcyBpcyBhIHNob3J0Y3V0LCB3ZSBhc3N1bWUgdGhhdCB0aGUgZmlyc3QgZW50cmllcyBpbiBDSU1fQ2hpcCBhcmUgdGhlIHByb2Nlc3NvcnMsIGluIHRoZSBzYW1lIG9yZGVyLg0KICAgICAgICAgICAgICAgIHggKz0gIjxoMj5Qcm9jZXNzb3IgIiArIChwYXJzZUludChpKSArIDEpICsgIjwvaDI+IjsNCiAgICAgICAgICAgICAgICB4ICs9IEZ1bGxUYWJsZSh7Ik1hbnVmYWN0dXJlciI6dHJhZGVtYXJrcyhxWyJNYW51ZmFjdHVyZXIiXSksICJGYW1pbHkiOkRNVEZQcm9jRmFtaWxseVtwWyJGYW1pbHkiXV0sICJWZXJzaW9uIjp0cmFkZW1hcmtzKHFbIlZlcnNpb24iXSksICJNYXhpbXVtIHNvY2tldCBzcGVlZCI6cFsiTWF4Q2xvY2tTcGVlZCJdICsgIiBNSHoiLCAiU3RhdHVzIjpETVRGQ1BVU3RhdHVzW3BbIkNQVVN0YXR1cyJdXX0sJycpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSAiPGJyPiI7DQoNCiAgICAgICAgICAgIGZvciAoaSBpbiByZXNwb25zZXNbJ0NJTV9QaHlzaWNhbE1lbW9yeSddLnJlc3BvbnNlcykgew0KICAgICAgICAgICAgICAgIHZhciBtID0gcmVzcG9uc2VzWydDSU1fUGh5c2ljYWxNZW1vcnknXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgeCArPSAiPGgyPk1lbW9yeSBNb2R1bGUgIiArICgraSArIDEpICsgIjwvaDI+IjsNCiAgICAgICAgICAgICAgICB4ICs9IEZ1bGxUYWJsZSh7IkJhbmsgTGFiZWwiOm1bIkJhbmtMYWJlbCJdLCAiTWFudWZhY3R1cmVyIjptWyJNYW51ZmFjdHVyZXIiXSwgIlNlcmlhbCBOdW1iZXIiOm1bIlNlcmlhbE51bWJlciJdLCAiU2l6ZSI6cGFyc2VJbnQobVsiQ2FwYWNpdHkiXSAvIDB4MTAwMDAwKSArICIgTUIiLCAiRm9ybSBmYWN0b3IiOkRNVEZNZW1Gb3JtRmFjdG9yW21bIkZvcm1GYWN0b3IiXV0sICJUeXBlIjpETVRGTWVtVHlwZVttWyJNZW1vcnlUeXBlIl1dLCAiQXNzZXQgdGFnIjptWyJUYWciXSwgIlBhcnQgbnVtYmVyIjptWyJQYXJ0TnVtYmVyIl19LCcnKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gIjxicj4iOw0KDQogICAgICAgICAgICBmb3IgKGkgaW4gcmVzcG9uc2VzWydDSU1fTWVkaWFBY2Nlc3NEZXZpY2UnXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICB2YXIgbSA9IHJlc3BvbnNlc1snQ0lNX01lZGlhQWNjZXNzRGV2aWNlJ10ucmVzcG9uc2VzW2ldOw0KICAgICAgICAgICAgICAgIHZhciBuID0gcmVzcG9uc2VzWydDSU1fUGh5c2ljYWxQYWNrYWdlJ10ucmVzcG9uc2VzWytpICsgMV07IC8vIFRoaXMgaXMgYSBzaG9ydGN1dCwgd2UgYXNzdW1lIENJTV9QaHlzaWNhbFBhY2thZ2UgaXMgdGhlIHNhbWUgYXMgQ0lNX01lZGlhQWNjZXNzRGV2aWNlIGV4Y2VwdCBmb3IgdGhlIGZpcnN0IGVudHJ5Lg0KICAgICAgICAgICAgICAgIHggKz0gIjxoMj5TdG9yYWdlIE1lZGlhICIgKyAocGFyc2VJbnQoaSkgKyAxKSArICI8L2gyPiI7DQogICAgICAgICAgICAgICAgeCArPSBGdWxsVGFibGUoeyJNb2RlbCI6blsnTW9kZWwnXSwiU2VyaWFsIG51bWJlciI6KG5bJ1NlcmlhbE51bWJlciddPT0nJz8nVW5rbm93bic6blsnU2VyaWFsTnVtYmVyJ10pLCAiU2l6ZSI6cGFyc2VJbnQoTWF0aC5yb3VuZChtWyJNYXhNZWRpYVNpemUiXSAqIDEwMDAgLyAweDEwMDAwMCkpICsgIiBNQiJ9LCcnKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gIjxicj4iOw0KDQogICAgICAgICAgICBRSCgnaWRfVGFibGVTeXNJbmZvJywgeCk7DQogICAgICAgICAgICB1cGRhdGVTeXN0ZW1TdGF0dXMoKTsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgZnVuY3Rpb24gU2F2ZUhhcmR3YXJlTG9nKCkgew0KICAgICAgICAgICAgaWYgKCF4eGRpYWxvZ01vZGUgJiYgSGFyZHdhcmVJbnZlbnRvcnkpIFNhdmVKc29uRmlsZSgnSW50ZWxBbXRIYXJkd2FyZScsICdoYXJkd2FyZScsICdJbnRlbCBBTVQgSGFyZHdhcmUgSW5mb3JtYXRpb24nLCBIYXJkd2FyZUludmVudG9yeSk7DQogICAgICAgIH0NCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIFBPV0VSIFBPTElDWQ0KICAgICAgICAvLw0KDQogICAgICAgIHZhciBBbXRTeXN0ZW1Qb3dlclNjaGVtZXMgPSBudWxsOw0KICAgICAgICBmdW5jdGlvbiBQdWxsUG93ZXJQb2xpY3koKSB7IGFtdHN0YWNrLkVudW0oIkFNVF9TeXN0ZW1Qb3dlclNjaGVtZSIsIHBvd2VyUG9saWN5UmVzcG9uc2UpOyB9DQogICAgICAgIGZ1bmN0aW9uIHBvd2VyUG9saWN5UmVzcG9uc2Uoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsgQW10U3lzdGVtUG93ZXJTY2hlbWVzID0gcmVzcG9uc2U7IHVwZGF0ZVN5c3RlbVN0YXR1cygpOyB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1Bvd2VyUG9saWN5RGxnKGN1cnJlbnRndWlkKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgcyA9ICIiOw0KDQogICAgICAgICAgICAvLyBOb3cgZmluZCB0aGUgbmFtZSBvZiB0aGUgcG93ZXIgc2NoZW1hIGluIHRoZSBBTVRfU3lzdGVtUG93ZXJTY2hlbWUgdGFibGUNCiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgQW10U3lzdGVtUG93ZXJTY2hlbWVzLmxlbmd0aDsgaisrKSB7DQogICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkID0gKChBbXRTeXN0ZW1Qb3dlclNjaGVtZXNbal1bJ1NjaGVtZUdVSUQnXSA9PSBjdXJyZW50Z3VpZCk/JyBjaGVja2VkJzonJyk7DQogICAgICAgICAgICAgICAgcyArPSAnPGlucHV0IHR5cGU9cmFkaW8gbmFtZT1wb3dlcnBvbGljeSB2YWx1ZT1cIicgKyBBbXRTeXN0ZW1Qb3dlclNjaGVtZXNbal1bJ0luc3RhbmNlSUQnXSArICJcIiAiICsgc2VsZWN0ZWQgKyAnPicgKyBBbXRTeXN0ZW1Qb3dlclNjaGVtZXNbal1bJ0Rlc2NyaXB0aW9uJ10gKyAnPGJyPic7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdJbnRlbCZyZWc7IEFNVCBQb3dlciBQb2xpY3knLCAzLCBzaG93UG93ZXJQb2xpY3lEbGdPaywgcyk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93UG93ZXJQb2xpY3lEbGdPaygpIHsNCiAgICAgICAgICAgIHZhciBpZCA9IG51bGwsIGkgPSAwLCBlID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lucHV0Jyk7DQogICAgICAgICAgICBmb3IgKDsgaSA8IGUubGVuZ3RoOyBpKyspIHsgaWYgKGVbaV0ubmFtZSA9PSAncG93ZXJwb2xpY3knICYmIGVbaV0uY2hlY2tlZCkgeyBpZCA9IGVbaV0udmFsdWU7IH0gfQ0KICAgICAgICAgICAgYW10c3RhY2suQU1UX1N5c3RlbVBvd2VyU2NoZW1lX1NldFBvd2VyU2NoZW1lKHNob3dQb3dlclBvbGljeURsZ09rRG9uZSwgaWQpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1Bvd2VyUG9saWN5RGxnT2tEb25lKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7IGlmIChzdGF0dXMgPT0gMjAwKSBQdWxsU3lzdGVtU3RhdHVzKCk7IH0NCg0KICAgICAgICAvLw0KICAgICAgICAvLyBVU0VSIElORk9STUFUSU9OIFBBTkVMDQogICAgICAgIC8vDQoNCiAgICAgICAgdmFyIHh4QWNjb3VudEFkbWluTmFtZSwgeHhBY2NvdW50UmVhbG1JbmZvLCB4eEFjY291bnRFbmFibGVkSW5mbyA9IHt9LCB4eEFjY291bnRGZXRjaCwgc2hvd0hpZGRlbkFjY291bnRzID0gZmFsc2U7DQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbFVzZXJJbmZvKCkgew0KICAgICAgICAgICAgeHhBY2NvdW50RmV0Y2ggPSAxOw0KICAgICAgICAgICAgZGVsZXRlIHh4QWNjb3VudEFkbWluTmFtZTsNCiAgICAgICAgICAgIHh4QWNjb3VudFJlYWxtSW5mbyA9IHt9Ow0KICAgICAgICAgICAgYW10c3RhY2suQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX0dldEFkbWluQWNsRW50cnkoZ2V0QWRtaW5BY2xFbnRyeVJlc3BvbnNlKTsNCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9FbnVtZXJhdGVVc2VyQWNsRW50cmllcygxLCBlbnVtZXJhdGVVc2VyQWNsRW50cmllc1Jlc3BvbnNlKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGdldEFkbWluQWNsRW50cnlSZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHJldHVybjsNCiAgICAgICAgICAgIHh4QWNjb3VudFJlYWxtSW5mb1stMV0gPSB7ICdBY2Nlc3NQZXJtaXNzaW9uJzogOTk5LCAnRGlnZXN0VXNlcm5hbWUnOiByZXNwb25zZS5Cb2R5WyJVc2VybmFtZSJdLCAnUmVhbG1zJzpudWxsIH07DQogICAgICAgICAgICB4eEFjY291bnRBZG1pbk5hbWUgPSByZXNwb25zZS5Cb2R5WyJVc2VybmFtZSJdOw0KICAgICAgICAgICAgdXBkYXRlQWNjb3VudHMoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGVudW1lcmF0ZVVzZXJBY2xFbnRyaWVzUmVzcG9uc2Uoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSByZXR1cm47DQogICAgICAgICAgICAvL2lmIChlcnJjaGVjayhzdGF0dXMsIHN0YWNrKSkgcmV0dXJuOw0KICAgICAgICAgICAgbWV0aG9kY2hlY2socmVzcG9uc2UpOw0KICAgICAgICAgICAgUVYoJ2dvMTEnLCB0cnVlKTsgLy8gU2hvdyAiVXNlciBBY2NvdW50cyIgb24gbGVmdCBwYW5lbA0KICAgICAgICAgICAgeHhBY2NvdW50RmV0Y2ggPSByZXNwb25zZS5Cb2R5WyJIYW5kbGVzIl0ubGVuZ3RoOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiByZXNwb25zZS5Cb2R5WyJIYW5kbGVzIl0pIHsNCiAgICAgICAgICAgICAgICB2YXIgaCA9IHJlc3BvbnNlLkJvZHlbIkhhbmRsZXMiXVtpXTsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfR2V0QWNsRW5hYmxlZFN0YXRlKGgsIGdldEFjbEVuYWJsZWRTdGF0ZVJlc3BvbnNlLCBoKTsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfR2V0VXNlckFjbEVudHJ5RXgoaCwgZ2V0VXNlckFjbEVudHJ5RXhSZXNwb25zZSwgaCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB1cGRhdGVBY2NvdW50cygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZ2V0VXNlckFjbEVudHJ5RXhSZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICB4eEFjY291bnRGZXRjaC0tOw0KICAgICAgICAgICAgLy9pZiAoZXJyY2hlY2soc3RhdHVzLCBzdGFjaykpIHJldHVybjsNCiAgICAgICAgICAgIC8vbWV0aG9kY2hlY2socmVzcG9uc2UpOw0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgLy8gU29tZXRpbWVzIEludGVsIEFNVCB3aWxsIGp1c3QgZnJlYWsgb3V0IG9uIHRoaXMgY2FsbCwgaWYgaXQncyB0aGUgY2FzZSwganVzdCBjYXJyeSBvbi4NCiAgICAgICAgICAgICAgICByZXNwb25zZS5Cb2R5WyJIYW5kbGUiXSA9IHRhZzsNCiAgICAgICAgICAgICAgICBpZiAoIXJlc3BvbnNlLkJvZHlbIlJlYWxtcyJdKSByZXNwb25zZS5Cb2R5WyJSZWFsbXMiXSA9IFtdOw0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFBcnJheS5pc0FycmF5KHJlc3BvbnNlLkJvZHlbIlJlYWxtcyJdKSkgcmVzcG9uc2UuQm9keVsiUmVhbG1zIl0gPSBbcmVzcG9uc2UuQm9keVsiUmVhbG1zIl1dOyAvLyBJZiAiUmVhbG1zIiBpcyBub3QgYW4gYXJyYXksIGl0J3MgYmVjYXVzZSBpdCdzIGp1c3Qgb25lIHJlYWxtLiBGaXggaXMgc28gaXQncyBhbiBhcnJheSBvZiBvbmUuDQogICAgICAgICAgICAgICAgeHhBY2NvdW50UmVhbG1JbmZvW3RhZ10gPSByZXNwb25zZS5Cb2R5Ow0KICAgICAgICAgICAgICAgIHVwZGF0ZUFjY291bnRzKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBnZXRBY2xFbmFibGVkU3RhdGVSZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICAvL2lmIChlcnJjaGVjayhzdGF0dXMsIHN0YWNrKSkgcmV0dXJuOw0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgLy8gU29tZXRpbWVzIEludGVsIEFNVCB3aWxsIGp1c3QgZnJlYWsgb3V0IG9uIHRoaXMgY2FsbCwgaWYgaXQncyB0aGUgY2FzZSwganVzdCBjYXJyeSBvbi4NCiAgICAgICAgICAgICAgICB4eEFjY291bnRFbmFibGVkSW5mb1t0YWddID0gcmVzcG9uc2UuQm9keTsNCiAgICAgICAgICAgICAgICB1cGRhdGVBY2NvdW50cygpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2V0QWNsRW5hYmxlZFN0YXRlUmVzcG9uc2Uoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMsIHRhZykgew0KICAgICAgICAgICAgaWYgKGVycmNoZWNrKHN0YXR1cywgc3RhY2spKSByZXR1cm47DQogICAgICAgICAgICBtZXRob2RjaGVjayhyZXNwb25zZSk7DQogICAgICAgICAgICBhbXRzdGFjay5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfR2V0QWNsRW5hYmxlZFN0YXRlKHRhZywgZ2V0QWNsRW5hYmxlZFN0YXRlUmVzcG9uc2UsIHRhZyk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1cGRhdGVBY2NvdW50cygpIHsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRGZXRjaCA+IDApIHJldHVybjsNCiAgICAgICAgICAgIHZhciB4ID0gVGFibGVTdGFydDIoKTsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPk1hbmFnZSB0aGUgSW50ZWwmcmVnOyBBTVQgdXNlciBhY2NvdW50cyBmb3IgdGhpcyBjb21wdXRlci48YnI+PGJyPiI7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4QWNjb3VudFJlYWxtSW5mbykgew0KICAgICAgICAgICAgICAgIHZhciByID0geHhBY2NvdW50UmVhbG1JbmZvW2ldLCBuYW1lLCBoaWRkZW4gPSBmYWxzZSwgc3RhdGUgPSAwOw0KICAgICAgICAgICAgICAgIGlmIChyWyJEaWdlc3RVc2VybmFtZSJdKSB7IG5hbWUgPSByWyJEaWdlc3RVc2VybmFtZSJdOyBoaWRkZW4gPSAobmFtZVswXSA9PSAnJCcgJiYgbmFtZVsxXSA9PSAnJCcpOyB9IGVsc2UgeyBuYW1lID0gR2V0U2lkU3RyaW5nKGF0b2IoclsiS2VyYmVyb3NVc2VyU2lkIl0pKTsgfQ0KICAgICAgICAgICAgICAgIGlmICh4eEFjY291bnRFbmFibGVkSW5mb1tpXSAmJiBuYW1lICE9ICckJE9zQWRtaW4nKSB7IHN0YXRlID0gKHh4QWNjb3VudEVuYWJsZWRJbmZvW2ldWydFbmFibGVkJ10gPT0gdHJ1ZSk/MToyOyB9DQogICAgICAgICAgICAgICAgaWYgKHNob3dIaWRkZW5BY2NvdW50cyB8fCAhaGlkZGVuKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciByYiA9ICIiOw0KICAgICAgICAgICAgICAgICAgICBpZiAoclsiQWNjZXNzUGVybWlzc2lvbiJdICE9IDk5OSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXRlID09IDIpIHsgcmIgKz0gIkRpc2FibGVkLCAiOyB9DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmMgPSAwOw0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpIGluIHJbIlJlYWxtcyJdKSB7IGlmIChhbXRzdGFjay5SZWFsbU5hbWVzW3JbIlJlYWxtcyJdW2ldXSAhPSAnJykgeyByYysrOyB9IH0gLy8gQ291bnQgb25seSByZWFsbXMgdGhhdCBoYXZlIGEgbmFtZSwgcmVtb3ZpbmcgcmVzZXJ2ZWQgcmVhbG1zLg0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJbIlJlYWxtcyJdLmluZGV4T2YoMjApID49IDApIHJiICs9ICJBdWRpdG9yLCAiOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJbIlJlYWxtcyJdLmluZGV4T2YoMykgPj0gMCkgeyByYiArPSAiQWRtaW5pc3RyYXRvciI7IH0gZWxzZSB7IGlmIChyYyA9PSAxKSB7IHJiICs9ICIxIHJlYWxtIjsgfSBlbHNlIHsgcmIgKz0gcmMgKyAiIHJlYWxtcyI7IH0gfQ0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgcmIgKz0gIkFkbWluaXN0cmF0b3IiOw0KICAgICAgICAgICAgICAgICAgICAgICAgclsiSGFuZGxlIl0gPSAtMTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93VXNlckRldGFpbHMoIiArIHJbIkhhbmRsZSJdICsgIik+PGRpdiBzdHlsZT1mbG9hdDpyaWdodD4iOw0KICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGUgPiAwICYmIHh4QWNjb3VudEFkbWluTmFtZSkgeCArPSAiICIgKyBBZGRCdXR0b24yKChzdGF0ZSA9PSAxPydEaXNhYmxlJzonRW5hYmxlJyksICJjaGFuZ2VBY2NvdW50U3RhdGVCdXR0b24oZXZlbnQsIiArIHJbIkhhbmRsZSJdICsgIiwiICsgc3RhdGUgKyAiKSIpOw0KICAgICAgICAgICAgICAgICAgICBpZiAoIWhpZGRlbiAmJiB4eEFjY291bnRBZG1pbk5hbWUpIHggKz0gIiAiICsgQWRkQnV0dG9uMigiRWRpdC4uLiIsICJjaGFuZ2VBY2NvdW50QnV0dG9uKGV2ZW50LCIgKyByWyJIYW5kbGUiXSArICIpIik7DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4O3dpZHRoOjMzMHB4O2Zsb2F0OmxlZnQ7b3ZlcmZsb3cteDpoaWRkZW4gdGl0bGU9JyIgKyBuYW1lICsgIic+PGI+IiArIG5hbWUgKyAiPC9iPjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PiIgKyByYiArICI8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHZhciB5ID0gIjxkaXYgc3R5bGU9ZmxvYXQ6cmlnaHQ7bWFyZ2luLXJpZ2h0OjhweD48YSB0aXRsZT0nVG9nZ2xlIGhpZGRlbiBhY2NvdW50cycgc3R5bGU9Y29sb3I6Z3JheTtjdXJzb3I6cG9pbnRlciBvbmNsaWNrPXRvZ2dsZUFjY291bnRCdXR0b24oKT4iICsgKHNob3dIaWRkZW5BY2NvdW50cz8nJiN4MjVCMjsnOicmI3gyNUJDOycpICsgIjwvYT48L2Rpdj48ZGl2PiZuYnNwOyIgKyBBZGRSZWZyZXNoQnV0dG9uKCJ4eEFjY291bnRGZXRjaD05OTk7UHVsbFVzZXJJbmZvKCkiKTsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHkgKz0gQWRkQnV0dG9uKCJOZXcgQWNjb3VudCIsICJuZXdBY2NvdW50QnV0dG9uKCkiKTsNCiAgICAgICAgICAgIHggKz0gIjxicj48dGQgY2xhc3M9cjE+IiArIFRhYmxlRW5kKHkgKyAiPC9kaXY+Iik7DQogICAgICAgICAgICBRSCgnaWRfVGFibGVVc2VyQWNjb3VudHMnLCB4KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHRvZ2dsZUFjY291bnRCdXR0b24oKSB7DQogICAgICAgICAgICBzaG93SGlkZGVuQWNjb3VudHMgPSAhc2hvd0hpZGRlbkFjY291bnRzOw0KICAgICAgICAgICAgdXBkYXRlQWNjb3VudHMoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHJlbW92ZVVzZXJBY2xFbnRyeVJlc3BvbnNlKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzLCB0YWcpIHsNCiAgICAgICAgICAgIGlmIChtZXRob2RjaGVjayhyZXNwb25zZSkpIHJldHVybjsNCiAgICAgICAgICAgIFB1bGxVc2VySW5mbygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gY2hhbmdlQWNjb3VudFN0YXRlQnV0dG9uKGUsIGgsIHMpIHsNCiAgICAgICAgICAgIGhhbHRFdmVudChlKTsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9TZXRBY2xFbmFibGVkU3RhdGUoaCwgKHM9PTE/ZmFsc2U6dHJ1ZSksIHNldEFjbEVuYWJsZWRTdGF0ZVJlc3BvbnNlLCBoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGNoYW5nZUFjY291bnRCdXR0b24oZSwgaCkgew0KICAgICAgICAgICAgaGFsdEV2ZW50KGUpOw0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdXBkYXRlUmVhbG1zKHh4QWNjb3VudFJlYWxtSW5mb1toXVsiUmVhbG1zIl0pOw0KICAgICAgICAgICAgZDJ1c2VybmFtZS52YWx1ZSA9IHh4QWNjb3VudFJlYWxtSW5mb1toXVsiRGlnZXN0VXNlcm5hbWUiXSA/IHh4QWNjb3VudFJlYWxtSW5mb1toXVsiRGlnZXN0VXNlcm5hbWUiXSA6IEdldFNpZFN0cmluZyhhdG9iKHh4QWNjb3VudFJlYWxtSW5mb1toXVsiS2VyYmVyb3NVc2VyU2lkIl0pKTsNCiAgICAgICAgICAgIGQycGFzc3dvcmQxLnZhbHVlID0gZDJwYXNzd29yZDIudmFsdWUgPSAnJzsNCiAgICAgICAgICAgIGQycGVybWlzc2lvbi52YWx1ZSA9IHh4QWNjb3VudFJlYWxtSW5mb1toXVsiQWNjZXNzUGVybWlzc2lvbiJdOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgyLCAiRWRpdCBBY2NvdW50IiwgKChoPT0tMSk/Mzo3KSwgZnVuY3Rpb24gKGJ1dHRvbikgeyBjaGFuZ2VBY2NvdW50QnV0dG9uRXgoaCwgYnV0dG9uKTsgfSk7IC8vIElmIGhhbmRsZSBpcyAtMSwgb25seSBkaXNwbGF5IE9LL0NhbmNlbCBidXR0b25zLCBpZiBub3QsIGFsc28gZGlzcGxheSBkZWxldGUgYnV0dG9uLg0KICAgICAgICAgICAgdXBkYXRlQWNjb3VudERpYWxvZygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gbmV3QWNjb3VudEJ1dHRvbigpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHVwZGF0ZVJlYWxtcyhbXSk7DQogICAgICAgICAgICBkMnVzZXJuYW1lLnZhbHVlID0gZDJwYXNzd29yZDEudmFsdWUgPSBkMnBhc3N3b3JkMi52YWx1ZSA9ICcnOw0KICAgICAgICAgICAgZDJwZXJtaXNzaW9uLnZhbHVlID0gMjsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMiwgIk5ldyBBY2NvdW50IiwgMywgZnVuY3Rpb24gKCkgeyBjaGFuZ2VBY2NvdW50QnV0dG9uRXgobnVsbCwgMSk7IH0pOw0KICAgICAgICAgICAgdXBkYXRlQWNjb3VudERpYWxvZygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gY2hhbmdlQWNjb3VudEJ1dHRvbkV4KGgsIGJ1dHRvbikgew0KICAgICAgICAgICAgaWYgKGJ1dHRvbiA9PSAxKSB7IC8vIE9LIEJ1dHRvbg0KICAgICAgICAgICAgICAgIHZhciByZWFsbXMgPSBbXSwgdXNlcm5hbWUgPSBkMnVzZXJuYW1lLnZhbHVlLCBwZXJtaXNzaW9uID0gZDJwZXJtaXNzaW9uLnZhbHVlLCBwYXNzd29yZCA9IGQycGFzc3dvcmQxLnZhbHVlLCBzaWQgPSBHZXRTaWRCeXRlQXJyYXkoUSgnZDJ1c2VybmFtZScpLnZhbHVlKSwgZCA9IG51bGw7DQogICAgICAgICAgICAgICAgaWYgKHVzZXJuYW1lLmxlbmd0aCA9PSAwIHx8IHBhc3N3b3JkICE9IGQycGFzc3dvcmQyLnZhbHVlKSB7IG1lc3NhZ2Vib3goIkFjY291bnQgRXJyb3IiLCAiSW52YWxpZCBQYXJhbWV0ZXJzIik7IHJldHVybjsgfQ0KICAgICAgICAgICAgICAgIGlmIChzaWQgPT0gbnVsbCkgeyBkID0gd2luZG93LmJ0b2EocnN0cl9tZDUodXNlcm5hbWUgKyAiOiIgKyBhbXRzeXNzdGF0ZVsnQU1UX0dlbmVyYWxTZXR0aW5ncyddLnJlc3BvbnNlWyJEaWdlc3RSZWFsbSJdICsgIjoiICsgcGFzc3dvcmQpKTsgfSBlbHNlIHsgdXNlcm5hbWUgPSBudWxsOyBzaWQgPSBidG9hKHNpZCk7IH0NCiAgICAgICAgICAgICAgICBpZiAoaCAhPSAtMSkgeyBmb3IgKHZhciB5IGluIGFtdHN0YWNrLlJlYWxtTmFtZXMpIHsgaWYgKCgoYW10c3RhY2suUmVhbG1OYW1lc1t5XSkgfHwgKHkgPT0gMykpICYmIFEoJ3J4JyArIHkpLmNoZWNrZWQpIHsgcmVhbG1zLnB1c2goeSk7IH0gfSB9DQogICAgICAgICAgICAgICAgaWYgKGggPT0gbnVsbCkgeyBhbXRzdGFjay5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfQWRkVXNlckFjbEVudHJ5RXgodXNlcm5hbWUsIGQsIHNpZCwgcGVybWlzc2lvbiwgcmVhbG1zLCB1c2VyQWNsRW50cnlFeFJlc3BvbnNlKTsgfQ0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGggPT0gLTEpIHsgYW10c3RhY2suQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX1NldEFkbWluQWNsRW50cnlFeCh1c2VybmFtZSwgZCwgdXNlckFjbEVudHJ5RXhSZXNwb25zZSk7IH0NCiAgICAgICAgICAgICAgICBlbHNlIHsgYW10c3RhY2suQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX1VwZGF0ZVVzZXJBY2xFbnRyeUV4KGgsIHVzZXJuYW1lLCBkLCBzaWQsIHBlcm1pc3Npb24sIHJlYWxtcywgdXNlckFjbEVudHJ5RXhSZXNwb25zZSk7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChidXR0b24gPT0gMikgeyAvLyBEZWxldGUgQnV0dG9uDQogICAgICAgICAgICAgICAgYW10c3RhY2suQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX1JlbW92ZVVzZXJBY2xFbnRyeShoLCByZW1vdmVVc2VyQWNsRW50cnlSZXNwb25zZSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2VyQWNsRW50cnlFeFJlc3BvbnNlKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzLCB0YWcpIHsgaWYgKG1ldGhvZGNoZWNrKHJlc3BvbnNlKSkgcmV0dXJuOyBQdWxsVXNlckluZm8oKTsgfQ0KICAgICAgICBmdW5jdGlvbiB1cGRhdGVSZWFsbXMocikgew0KICAgICAgICAgICAgUVYoJ2lkX2QycGVybWlzc2lvbnMnLCByICE9IG51bGwpOw0KICAgICAgICAgICAgaWYgKHIgIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgIHZhciB4ID0gJzxsaT48bGFiZWw+PGlucHV0IHR5cGU9Y2hlY2tib3ggb25jaGFuZ2U9dXBkYXRlQWNjb3VudERpYWxvZygpIGlkPXJ4MycgKyAoKHIuaW5kZXhPZigzKSA+PSAwKT8nIGNoZWNrZWQnOicnKSArICc+QWRtaW5pc3RyYXRvcjwvbGFiZWw+PC9saT48aHIgLz4nOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIHkgaW4gYW10c3RhY2suUmVhbG1OYW1lcykgeyB2YXIgYyA9ICcnOyBpZiAoci5pbmRleE9mKHBhcnNlSW50KHkpKSA+PSAwKSBjID0gJyBjaGVja2VkJzsgaWYgKGFtdHN0YWNrLlJlYWxtTmFtZXNbeV0pIHggKz0gJzxsaT48bGFiZWw+PGlucHV0IHR5cGU9Y2hlY2tib3ggb25jaGFuZ2U9dXBkYXRlQWNjb3VudERpYWxvZygpIGlkPXJ4JyArIHkgKyBjICsgJz4nICsgYW10c3RhY2suUmVhbG1OYW1lc1t5XSArICc8L2xhYmVsPjwvbGk+JzsgfQ0KICAgICAgICAgICAgICAgIFFIKCdpZF9kMnJlYWxtcycsIHgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXBkYXRlQWNjb3VudERpYWxvZygpIHsNCiAgICAgICAgICAgIHZhciBvayA9IGZhbHNlOw0KICAgICAgICAgICAgZm9yICh2YXIgeSBpbiBhbXRzdGFjay5SZWFsbU5hbWVzKSB7IGlmICgoKGFtdHN0YWNrLlJlYWxtTmFtZXNbeV0pIHx8ICh5ID09IDMpKSAmJiBRKCdyeCcgKyB5KS5jaGVja2VkKSB7IG9rID0gdHJ1ZTsgfSB9DQogICAgICAgICAgICBvayAmPSAoZDJ1c2VybmFtZS52YWx1ZS5sZW5ndGggPiAwICYmIHBhc3N3b3JkY2hlY2soZDJwYXNzd29yZDEudmFsdWUpICYmIGQycGFzc3dvcmQxLnZhbHVlID09IGQycGFzc3dvcmQyLnZhbHVlKTsNCiAgICAgICAgICAgIFFFKCdpZHhfZGxnT2tCdXR0b24nLCBvayk7DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgeHhVc2VyUGVybWlzc2lvbnMgPSBbJ0xvY2FsIG9ubHknICwgJ05ldHdvcmsgb25seScsICdBbGwgKExvY2FsICYgTmV0d29yayknXTsNCiAgICAgICAgZnVuY3Rpb24gc2hvd1VzZXJEZXRhaWxzKGgpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBhID0geHhBY2NvdW50UmVhbG1JbmZvW2hdLCB4ID0gJzxkaXYgc3R5bGU9dGV4dC1hbGlnbjpsZWZ0Pic7DQogICAgICAgICAgICB2YXIgaSwgbiA9IGFbIkRpZ2VzdFVzZXJuYW1lIl07DQogICAgICAgICAgICBpZiAoIW4pIG4gPSBHZXRTaWRTdHJpbmcoYXRvYihhWyJLZXJiZXJvc1VzZXJTaWQiXSkpOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIk5hbWUiLCBuKTsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRFbmFibGVkSW5mb1toXSkgeyB4ICs9IGFkZEh0bWxWYWx1ZSgiU3RhdGUiLCAoKHh4QWNjb3VudEVuYWJsZWRJbmZvW2hdWydFbmFibGVkJ10gPT0gdHJ1ZSk/J0VuYWJsZWQnOidEaXNhYmxlZCcpKTsgfQ0KICAgICAgICAgICAgaWYgKG4gPT0geHhBY2NvdW50QWRtaW5OYW1lKSB7DQogICAgICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlBlcm1pc3Npb24iLCAiQWRtaW5pc3RyYXRvciIpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiUGVybWlzc2lvbiIsIHh4VXNlclBlcm1pc3Npb25zW2FbIkFjY2Vzc1Blcm1pc3Npb24iXV0pOw0KICAgICAgICAgICAgICAgIHZhciB5ID0gJyc7DQogICAgICAgICAgICAgICAgaWYgKGFbIlJlYWxtcyJdLmluZGV4T2YoMykgPj0gMCkgew0KICAgICAgICAgICAgICAgICAgICB5ID0gJ0FkbWluaXN0cmF0b3InOw0KICAgICAgICAgICAgICAgICAgICBpZiAoYVsiUmVhbG1zIl0uaW5kZXhPZigyMCkgPj0gMCkgeSArPSAiLCBBdWRpdG9yIjsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBmb3IgKGkgaW4geHhBY2NvdW50UmVhbG1JbmZvW2hdWyJSZWFsbXMiXSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFtdHN0YWNrLlJlYWxtTmFtZXNbYVsiUmVhbG1zIl1baV1dICE9ICcnKSB7IC8vIFJlbW92ZSBibGFuayByZXNlcnZlZCByZWFsbXMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoeS5sZW5ndGggPiAwKSB5ICs9ICIsICI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeSArPSBhbXRzdGFjay5SZWFsbU5hbWVzW2FbIlJlYWxtcyJdW2ldXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAoeS5sZW5ndGggPT0gMCkgeSA9ICdOb25lJzsNCiAgICAgICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiUmVhbG1zIiwgIiIpICsgIjxiPiIgKyB5ICsgIjwvYj4iOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSAiPC9kaXY+IjsNCiAgICAgICAgICAgIG1lc3NhZ2Vib3goIkFjY291bnQgIiArIG4sIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gV1NNQU4gQlJPV1NFUiBQQU5FTA0KICAgICAgICAvLw0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gUmVtb3RlIFRlcm1pbmFsDQogICAgICAgIC8vDQoNCg0KICAgICAgICAvLw0KICAgICAgICAvLyBSZW1vdGUgRGVza3RvcA0KICAgICAgICAvLw0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gUmVtb3RlIElERVINCiAgICAgICAgLy8NCg0KDQoNCg0KICAgICAgICAvLw0KICAgICAgICAvLyBSZW1vdGUgQWNjZXNzDQogICAgICAgIC8vDQoNCiAgICAgICAgdmFyIHh4UmVtb3RlQWNjZXNzID0gbnVsbDsNCiAgICAgICAgdmFyIHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uID0gbnVsbDsNCiAgICAgICAgdmFyIHh4Q2lyYVNlcnZlcnMgPSBudWxsOw0KICAgICAgICB2YXIgeHhVc2VySW5pdGlhdGVkQ2lyYSA9IG51bGw7DQogICAgICAgIHZhciB4eFVzZXJJbml0aWF0ZWRFbmFibGVkU3RhdGUgPSB7IDMyNzY4OiAnRGlzYWJsZWQnLCAzMjc2OTogJ0JJT1MgZW5hYmxlZCcsIDMyNzcwOiAnT1MgZW5hYmxlJywgMzI3NzE6ICdCSU9TICYgT1MgZW5hYmxlZCcgfTsNCiAgICAgICAgdmFyIHh4UmVtb3RlQWNjZXNzQ3JlZGVudGlhTGlua3MgPSBudWxsOw0KICAgICAgICB2YXIgeHhNUFNVc2VyUGFzcyA9IG51bGw7DQogICAgICAgIHZhciB4eFBvbGljaWVzID0gbnVsbDsNCg0KICAgICAgICBmdW5jdGlvbiBQdWxsUmVtb3RlQWNjZXNzKCkgew0KICAgICAgICAgICAgLy8gV2Ugb25seSBkZWFsIHdpdGggcmVtb3RlIGFjY2VzcyBzdGFydGluZyB3aXRoIEludGVsIEFNVCA2IGFuZCBiZXlvbmQNCg0KICAgICAgICAgICAgdmFyIHJlcXVlc3RzID0gWyIqQU1UX0Vudmlyb25tZW50RGV0ZWN0aW9uU2V0dGluZ0RhdGEiLCAiQU1UX01hbmFnZW1lbnRQcmVzZW5jZVJlbW90ZVNBUCIsICJBTVRfUmVtb3RlQWNjZXNzQ3JlZGVudGlhbENvbnRleHQiLCAiQU1UX1JlbW90ZUFjY2Vzc1BvbGljeUFwcGxpZXNUb01QUyIsICJBTVRfUmVtb3RlQWNjZXNzUG9saWN5UnVsZSIsICIqQU1UX1VzZXJJbml0aWF0ZWRDb25uZWN0aW9uU2VydmljZSIsICJBTVRfTVBTVXNlcm5hbWVQYXNzd29yZCJdOw0KICAgICAgICAgICAgaWYgKGFtdHZlcnNpb24gPiAxMSkgeyByZXF1ZXN0cy5wdXNoKCIqSVBTX0hUVFBQcm94eVNlcnZpY2UiLCAiSVBTX0hUVFBQcm94eUFjY2Vzc1BvaW50Iik7IH0NCiAgICAgICAgICAgIGFtdHN0YWNrLkJhdGNoRW51bShudWxsLCByZXF1ZXN0cywgcHJvY2Vzc1JlbW90ZTEpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1JlbW90ZTEoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDQwMCkgcmV0dXJuOw0KICAgICAgICAgICAgaWYgKChlcnJjaGVjayhzdGF0dXMsIHN0YWNrKSkgfHwgKHJlc3BvbnNlc1siQU1UX1VzZXJJbml0aWF0ZWRDb25uZWN0aW9uU2VydmljZSJdID09IHVuZGVmaW5lZCB8fCByZXNwb25zZXNbIkFNVF9Vc2VySW5pdGlhdGVkQ29ubmVjdGlvblNlcnZpY2UiXS5yZXNwb25zZSA9PSB1bmRlZmluZWQpKSByZXR1cm47DQogICAgICAgICAgICBRVignZ28xNycsIHRydWUpOyAvLyBSZW1vdGUgQWNjZXNzDQogICAgICAgICAgICB4eFJlbW90ZUFjY2VzcyA9IHJlc3BvbnNlczsNCiAgICAgICAgICAgIHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uID0gcmVzcG9uc2VzWyJBTVRfRW52aXJvbm1lbnREZXRlY3Rpb25TZXR0aW5nRGF0YSJdLnJlc3BvbnNlOw0KICAgICAgICAgICAgeHhFbnZpcm9uZW1lbnREZXRlY3Rpb25bJ0RldGVjdGlvblN0cmluZ3MnXSA9IE1ha2VUb0FycmF5KHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uWydEZXRlY3Rpb25TdHJpbmdzJ10pOw0KICAgICAgICAgICAgeHhDaXJhU2VydmVycyA9IHJlc3BvbnNlc1siQU1UX01hbmFnZW1lbnRQcmVzZW5jZVJlbW90ZVNBUCJdLnJlc3BvbnNlczsNCiAgICAgICAgICAgIHh4VXNlckluaXRpYXRlZENpcmEgPSByZXNwb25zZXNbIkFNVF9Vc2VySW5pdGlhdGVkQ29ubmVjdGlvblNlcnZpY2UiXS5yZXNwb25zZTsNCiAgICAgICAgICAgIHh4UmVtb3RlQWNjZXNzQ3JlZGVudGlhTGlua3MgPSByZXNwb25zZXNbIkFNVF9SZW1vdGVBY2Nlc3NDcmVkZW50aWFsQ29udGV4dCJdLnJlc3BvbnNlczsNCiAgICAgICAgICAgIHh4TVBTVXNlclBhc3MgPSByZXNwb25zZXNbIkFNVF9NUFNVc2VybmFtZVBhc3N3b3JkIl0ucmVzcG9uc2VzOw0KDQogICAgICAgICAgICAvLyBGaWd1cmUgb3V0IHBvbGljaWVzIGF0dGFjaGVkIHRvIHNlcnZlcnMuIENyZWF0ZSBhIHBvbGljeSB0eXBlIHRvIHNlcnZlciB0YWJsZS4NCiAgICAgICAgICAgIHh4UG9saWNpZXMgPSB7ICdVc2VyJzogW10sICdBbGVydCc6IFtdLCAnUGVyaW9kaWMnOiBbXSB9Ow0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiByZXNwb25zZXNbIkFNVF9SZW1vdGVBY2Nlc3NQb2xpY3lBcHBsaWVzVG9NUFMiXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICB2YXIgcG9saWN5ID0gcmVzcG9uc2VzWyJBTVRfUmVtb3RlQWNjZXNzUG9saWN5QXBwbGllc1RvTVBTIl0ucmVzcG9uc2VzW2ldOw0KICAgICAgICAgICAgICAgIHZhciBzZXJ2ZXIgPSBDbG9uZShnZXRJdGVtKHh4Q2lyYVNlcnZlcnMsICJOYW1lIiwgZ2V0SXRlbShwb2xpY3lbJ01hbmFnZWRFbGVtZW50J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXSwgIkBOYW1lIiwgIk5hbWUiKVsnVmFsdWUnXSkpOw0KICAgICAgICAgICAgICAgIHNlcnZlci5NcHNUeXBlID0gcG9saWN5WydNcHNUeXBlJ107IC8vIE1wc1R5cGUgd2FzIGFkZGVkIGluIEludGVsIEFNVCAxMS42DQogICAgICAgICAgICAgICAgdmFyIHB0eXBlID0gKGdldEl0ZW0ocG9saWN5WydQb2xpY3lTZXQnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddLCAiQE5hbWUiLCAiUG9saWN5UnVsZU5hbWUiKVsnVmFsdWUnXSkuc3BsaXQoJyAnKVswXTsNCiAgICAgICAgICAgICAgICB4eFBvbGljaWVzW3B0eXBlXS5wdXNoKHNlcnZlcik7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHVwZGF0ZVJlbW90ZUFjY2VzcygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXBkYXRlUmVtb3RlQWNjZXNzKCkgew0KICAgICAgICAgICAgaWYgKHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uID09IG51bGwpIHJldHVybjsNCiAgICAgICAgICAgIHZhciB4ID0gJycsIGUgPSAnRGlzYWJsZWQnLCBjaXJhUHJveHlTdXBwb3J0ID0gKHh4UmVtb3RlQWNjZXNzWyJJUFNfSFRUUFByb3h5U2VydmljZSJdICYmIHh4UmVtb3RlQWNjZXNzWyJJUFNfSFRUUFByb3h5QWNjZXNzUG9pbnQiXSk7DQogICAgICAgICAgICBpZiAoeHhFbnZpcm9uZW1lbnREZXRlY3Rpb25bJ0RldGVjdGlvblN0cmluZ3MnXSAmJiB4eEVudmlyb25lbWVudERldGVjdGlvblsnRGV0ZWN0aW9uU3RyaW5ncyddLmxlbmd0aCA+IDApIHsgZSA9ICdFbmFibGVkLCAnICsgeHhFbnZpcm9uZW1lbnREZXRlY3Rpb25bJ0RldGVjdGlvblN0cmluZ3MnXS5sZW5ndGggKyAnIGRvbWFpbicgKyAoeHhFbnZpcm9uZW1lbnREZXRlY3Rpb25bJ0RldGVjdGlvblN0cmluZ3MnXS5sZW5ndGggPiAxPydzJzonJyk7IH0NCg0KICAgICAgICAgICAgLy8gR2VuZXJhbCBzZXR0aW5ncw0KICAgICAgICAgICAgeCArPSBUYWJsZVN0YXJ0KCk7DQogICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkVudmlyb25tZW50IGRldGVjdGlvbiIsIGFkZExpbmsoZSwgJ2VkaXRFbnZpcm9ubWVudERldGVjdGlvbigpJykpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJVc2VyIGluaXRpYXRpb24gb3B0aW9ucyIsIGFkZExpbmtDb25kaXRpb25hbCh4eFVzZXJJbml0aWF0ZWRFbmFibGVkU3RhdGVbeHhVc2VySW5pdGlhdGVkQ2lyYVsnRW5hYmxlZFN0YXRlJ11dLCAnZWRpdFVzZXJJbml0aWF0ZWRDaXJhKCknLCB4eEFjY291bnRBZG1pbk5hbWUpKTsNCiAgICAgICAgICAgIHZhciB5ID0gJzxpPk5vbmU8L2k+JzsNCiAgICAgICAgICAgIGlmICh4eFBvbGljaWVzWydVc2VyJ10ubGVuZ3RoID4gMCkgeyB5ID0gJyc7IGZvciAodmFyIGkgaW4geHhQb2xpY2llc1snVXNlciddKSB7IGlmICh5Lmxlbmd0aCA+IDApIHkgKz0gJywgJzsgeSArPSB4eFBvbGljaWVzWydVc2VyJ11baV1bJ0FjY2Vzc0luZm8nXTsgaWYgKHh4UG9saWNpZXNbJ1VzZXInXVtpXS5NcHNUeXBlID09IDEpIHsgeSArPSAnIChDSUxBKSc7IH0gfSB9DQogICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIlVzZXIgaW5pdGlhdGVkIGNvbm5lY3Rpb24iLCBhZGRMaW5rQ29uZGl0aW9uYWwoeSwgJ2VkaXRNcHNQb2xpY3koIlVzZXIiKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgdmFyIHkgPSAnPGk+Tm9uZTwvaT4nOw0KICAgICAgICAgICAgaWYgKHh4UG9saWNpZXNbJ0FsZXJ0J10ubGVuZ3RoID4gMCkgeyB5ID0gJyc7IGZvciAodmFyIGkgaW4geHhQb2xpY2llc1snQWxlcnQnXSkgeyBpZiAoeS5sZW5ndGggPiAwKSB5ICs9ICcsICc7IHkgKz0geHhQb2xpY2llc1snQWxlcnQnXVtpXVsnQWNjZXNzSW5mbyddOyBpZiAoeHhQb2xpY2llc1snQWxlcnQnXVtpXS5NcHNUeXBlID09IDEpIHsgeSArPSAnIChDSUxBKSc7IH0gfSB9DQogICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkFsZXJ0IGluaXRpYXRlZCBjb25uZWN0aW9uIiwgYWRkTGlua0NvbmRpdGlvbmFsKHksICdlZGl0TXBzUG9saWN5KCJBbGVydCIpJywgeHhBY2NvdW50QWRtaW5OYW1lKSk7DQogICAgICAgICAgICB2YXIgeSA9ICc8aT5Ob25lPC9pPic7DQogICAgICAgICAgICBpZiAoeHhQb2xpY2llc1snUGVyaW9kaWMnXS5sZW5ndGggPiAwKSB7IHkgPSAnJzsgZm9yICh2YXIgaSBpbiB4eFBvbGljaWVzWydQZXJpb2RpYyddKSB7IGlmICh5Lmxlbmd0aCA+IDApIHkgKz0gJywgJzsgeSArPSB4eFBvbGljaWVzWydQZXJpb2RpYyddW2ldWydBY2Nlc3NJbmZvJ107IGlmICh4eFBvbGljaWVzWydQZXJpb2RpYyddW2ldLk1wc1R5cGUgPT0gMSkgeyB5ICs9ICcgKENJTEEpJzsgfSB9IH0NCiAgICAgICAgICAgIHZhciBwZXJpb2RpY1BvbGljeSA9IGdldEl0ZW0oeHhSZW1vdGVBY2Nlc3NbIkFNVF9SZW1vdGVBY2Nlc3NQb2xpY3lSdWxlIl0ucmVzcG9uc2VzLCAiUG9saWN5UnVsZU5hbWUiLCAiUGVyaW9kaWMiKTsNCiAgICAgICAgICAgIGlmIChwZXJpb2RpY1BvbGljeSkgew0KICAgICAgICAgICAgICAgIHZhciBleGRhdGEgPSBhdG9iKHBlcmlvZGljUG9saWN5WydFeHRlbmRlZERhdGEnXSk7DQogICAgICAgICAgICAgICAgaWYgKFJlYWRJbnQoZXhkYXRhLCAwKSA9PSAwKSB7IHkgKz0gJywgZWFjaCAnICsgUmVhZEludChleGRhdGEsIDQpICsgJyBzZWNvbmRzJzsgfQ0KICAgICAgICAgICAgICAgIGlmIChSZWFkSW50KGV4ZGF0YSwgMCkgPT0gMSkgeyB2YXIgaG91cnMgPSBSZWFkSW50KGV4ZGF0YSwgNCk7IHZhciBtaW51dGVzID0gUmVhZEludChleGRhdGEsIDgpOyBpZiAobWludXRlcyA8IDEwKSBtaW51dGVzID0gJzAnICsgbWludXRlczsgeSArPSAnLCBhdCAnICsgaG91cnMgKyAiOiIgKyBtaW51dGVzICsgJyBkYWlseSc7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiUGVyaW9kaWMgY29ubmVjdGlvbiIsIGFkZExpbmtDb25kaXRpb25hbCh5LCAnZWRpdE1wc1BvbGljeSgiUGVyaW9kaWMiKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KDQogICAgICAgICAgICAvLyBTaG93IE1QUyBzZXJ2ZXJzDQogICAgICAgICAgICB4ICs9ICI8YnI+IjsNCiAgICAgICAgICAgIHggKz0gVGFibGVTdGFydDIoKTsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPk1hbmFnZSBJbnRlbCZyZWc7IEFNVCByZW1vdGUgbWFuYWdlbWVudCBzZXJ2ZXJzLjxicj48YnI+IjsNCiAgICAgICAgICAgIGlmICh4eENpcmFTZXJ2ZXJzLmxlbmd0aCA9PSAwKSB7DQogICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweD48YnI+PGk+Tm8gcmVtb3RlIHNlcnZlcnMgZm91bmQuPC9pPjwvZGl2Pjxicj4iOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4Q2lyYVNlcnZlcnMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGRlc2MgPSAnOicgKyB4eENpcmFTZXJ2ZXJzW2ldWydQb3J0J107DQogICAgICAgICAgICAgICAgICAgIGlmICh4eENpcmFTZXJ2ZXJzW2ldWydDTiddKSBkZXNjICs9ICcsICcgKyB4eENpcmFTZXJ2ZXJzW2ldWydDTiddOw0KICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93U2VydmVyRGV0YWlscygiICsgaSArICIpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PjxiPiIgKyB4eENpcmFTZXJ2ZXJzW2ldWyJBY2Nlc3NJbmZvIl0gKyAiPC9iPiIgKyBFc2NhcGVIdG1sKGRlc2MpICsgIjwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBTaG93IE1QUyBwcm94aWVzIGlmIHN1cHBvcnRlZA0KICAgICAgICAgICAgaWYgKGNpcmFQcm94eVN1cHBvcnQpIHsNCiAgICAgICAgICAgICAgICB4ICs9ICI8YnI+TWFuYWdlIEhUVFAgcHJveGllcyB1c2VkIGZvciBtYW5hZ2VtZW50IGNvbm5lY3Rpb25zLjxicj48YnI+IjsNCiAgICAgICAgICAgICAgICB2YXIgcHJveHlTZXJ2aWNlID0geHhSZW1vdGVBY2Nlc3NbIklQU19IVFRQUHJveHlTZXJ2aWNlIl0ucmVzcG9uc2U7DQogICAgICAgICAgICAgICAgdmFyIHByb3hpZXMgPSB4eFJlbW90ZUFjY2Vzc1siSVBTX0hUVFBQcm94eUFjY2Vzc1BvaW50Il0ucmVzcG9uc2VzOw0KICAgICAgICAgICAgICAgIGlmIChwcm94aWVzLmxlbmd0aCA9PSAwKSB7DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPjxpPk5vIHByb3hpZXMgY29uZmlndXJlZC48L2k+PC9kaXY+PGJyPiI7DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBwcm94aWVzKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAvL3ggKz0gIjxkaXYgY2xhc3M9aXRlbUJhciBvbmNsaWNrPXNob3dQcm94eURldGFpbHMoIiArIGkgKyAiKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjNweD48Yj4iICsgRXNjYXBlSHRtbChwcm94aWVzW2ldWydBY2Nlc3NJbmZvJ10pICsgIjoiICsgcHJveGllc1tpXVsnUHJveHlQb3J0J10gKyAiPC9iPiAvICIgKyBFc2NhcGVIdG1sKHByb3hpZXNbaV1bJ05ldHdvcmtEbnNTdWZmaXgnXSkgKyAiPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgY2xhc3M9aXRlbUJhciBvbmNsaWNrPXNob3dQcm94eURldGFpbHMoIiArIGkgKyAiKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjNweD48Yj4iICsgRXNjYXBlSHRtbChwcm94aWVzW2ldWydBY2Nlc3NJbmZvJ10pICsgIjoiICsgcHJveGllc1tpXVsnUG9ydCddICsgIjwvYj4gLyAiICsgRXNjYXBlSHRtbChwcm94aWVzW2ldWydOZXR3b3JrRG5zU3VmZml4J10pICsgIjwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHZhciBhZGRzZXJ2ZXJidXR0b24gPSAnJzsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHsNCiAgICAgICAgICAgICAgICBhZGRzZXJ2ZXJidXR0b24gPSBBZGRCdXR0b24oIkFkZCBTZXJ2ZXIuLi4iLCAiQWRkUmVtb3RlQWNjZXNzU2VydmVyKCkiKTsNCiAgICAgICAgICAgICAgICBpZiAoY2lyYVByb3h5U3VwcG9ydCkgeyBhZGRzZXJ2ZXJidXR0b24gKz0gQWRkQnV0dG9uKCJBZGQgUHJveHkuLi4iLCAiQWRkUmVtb3RlQWNjZXNzUHJveHkoKSIpOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICB4ICs9ICI8YnI+PHRkIGNsYXNzPXIxPiIgKyBUYWJsZUVuZChBZGRSZWZyZXNoQnV0dG9uKCJQdWxsUmVtb3RlQWNjZXNzKCkiKSArIGFkZHNlcnZlcmJ1dHRvbik7DQoNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZVJlbW90ZUFjY2VzcycsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIHh4RWRpdE1wc1BvbGljeVR5cGU7DQogICAgICAgIGZ1bmN0aW9uIGVkaXRNcHNQb2xpY3kodHlwZSkgew0KICAgICAgICAgICAgdmFyIHggPSAnJywgY2lsYVN1cHBvcnQgPSAoKGFtdHZlcnNpb24gPiAxMSkgfHwgKChhbXR2ZXJzaW9uID09IDExKSAmJiAoYW10dmVyc2lvbiA+PSA2KSkpOw0KICAgICAgICAgICAgeHhFZGl0TXBzUG9saWN5VHlwZSA9IHR5cGU7DQogICAgICAgICAgICB2YXIgbmFtZSA9IHh4RWRpdE1wc1BvbGljeVR5cGU7DQogICAgICAgICAgICBpZiAobmFtZSA9PSAnVXNlcicpIG5hbWUgPSAnVXNlciBJbml0aWF0ZWQnOw0KICAgICAgICAgICAgdmFyIHBvbGljeSA9IGdldEl0ZW0oeHhSZW1vdGVBY2Nlc3NbIkFNVF9SZW1vdGVBY2Nlc3NQb2xpY3lSdWxlIl0ucmVzcG9uc2VzLCAiUG9saWN5UnVsZU5hbWUiLCBuYW1lKTsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PHNlbGVjdCBpZD1kMnNlcnZlcjEgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjA2cHggb25jaGFuZ2U9ZWRpdE1wc1BvbGljeVVwZGF0ZSgpPic7DQogICAgICAgICAgICB4ICs9ICc8b3B0aW9uIHZhbHVlPS0xPihOb25lKScNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhDaXJhU2VydmVycykgeyB4ICs9ICc8b3B0aW9uIHZhbHVlPScgKyBpICsgJycgKyAoKHh4UG9saWNpZXNbdHlwZV1bMF0gJiYgeHhQb2xpY2llc1t0eXBlXVswXVsnTmFtZSddID09IHh4Q2lyYVNlcnZlcnNbaV1bJ05hbWUnXSkgPyAnIHNlbGVjdGVkJyA6ICcnKSArICc+JyArIHh4Q2lyYVNlcnZlcnNbaV1bJ0FjY2Vzc0luZm8nXSB9DQogICAgICAgICAgICB4ICs9ICc8L3NlbGVjdD48ZGl2PlByaW1hcnkgc2VydmVyPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIGlmIChjaWxhU3VwcG9ydCkgeyB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxzZWxlY3QgaWQ9ZDJzZXJ2ZXIxY2lyYSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDZweCBvbmNoYW5nZT1lZGl0TXBzUG9saWN5VXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT0wPkNJUkEgLSBFeHRlcm5hbDxvcHRpb24gdmFsdWU9MScgKyAoKCh4eFBvbGljaWVzW3R5cGVdWzBdKSAmJiAoeHhQb2xpY2llc1t0eXBlXVswXS5NcHNUeXBlID09IDEpKT8nIHNlbGVjdGVkJzonJykgKyAnPkNJTEEgLSBJbnRlcm5hbDwvc2VsZWN0PjxkaXY+UHJpbWFyeSBNUFMgVHlwZTwvZGl2PjwvZGl2Pic7IH0NCiAgICAgICAgICAgIGlmICh4eENpcmFTZXJ2ZXJzLmxlbmd0aCA+IDEpIHsNCiAgICAgICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxzZWxlY3QgaWQ9ZDJzZXJ2ZXIyIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwNnB4IG9uY2hhbmdlPWVkaXRNcHNQb2xpY3lVcGRhdGUoKT4nOw0KICAgICAgICAgICAgICAgIHggKz0gJzxvcHRpb24gdmFsdWU9LTE+KE5vbmUpJw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhDaXJhU2VydmVycykgeyB4ICs9ICc8b3B0aW9uIHZhbHVlPScgKyBpICsgJycgKyAoKHh4UG9saWNpZXNbdHlwZV1bMV0gJiYgeHhQb2xpY2llc1t0eXBlXVsxXVsnTmFtZSddID09IHh4Q2lyYVNlcnZlcnNbaV1bJ05hbWUnXSkgPyAnIHNlbGVjdGVkJyA6ICcnKSArICc+JyArIHh4Q2lyYVNlcnZlcnNbaV1bJ0FjY2Vzc0luZm8nXSB9DQogICAgICAgICAgICAgICAgeCArPSAnPC9zZWxlY3Q+PGRpdj5TZWNvbmRhcnkgc2VydmVyPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgICAgICBpZiAoY2lsYVN1cHBvcnQpIHsgeCArPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48c2VsZWN0IGlkPWQyc2VydmVyMmNpcmEgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjA2cHggb25jaGFuZ2U9ZWRpdE1wc1BvbGljeVVwZGF0ZSgpPjxvcHRpb24gdmFsdWU9MD5DSVJBIC0gRXh0ZXJuYWw8b3B0aW9uIHZhbHVlPTEnICsgKCgoeHhQb2xpY2llc1t0eXBlXVsxXSkgJiYgKHh4UG9saWNpZXNbdHlwZV1bMV0uTXBzVHlwZSA9PSAxKSkgPyAnIHNlbGVjdGVkJyA6ICcnKSArICc+Q0lMQSAtIEludGVybmFsPC9zZWxlY3Q+PGRpdj5TZWNvbmRhcnkgTVBTIFR5cGU8L2Rpdj48L2Rpdj4nOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICB2YXIgdCwgdiA9IDA7DQogICAgICAgICAgICBpZiAocG9saWN5KSB7IHYgPSBwb2xpY3lbJ1R1bm5lbExpZmVUaW1lJ107IH0NCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PGlucHV0IGlkPWQybGlmZXRpbWUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHggb25jaGFuZ2U9ZWRpdE1wc1BvbGljeVVwZGF0ZSgpIHZhbHVlPScgKyB2ICsgJz4nOw0KICAgICAgICAgICAgeCArPSAnPGRpdj5UdW5uZWwgbGlmZXRpbWUgKFNlY29uZHMpPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIGlmICh0eXBlID09ICdQZXJpb2RpYycpIHsNCiAgICAgICAgICAgICAgICB0ID0gMDsNCiAgICAgICAgICAgICAgICB2ID0gMzYwMDsNCiAgICAgICAgICAgICAgICBpZiAocG9saWN5KSB7DQogICAgICAgICAgICAgICAgICAgIHZhciB4eCA9IGF0b2IocG9saWN5WydFeHRlbmRlZERhdGEnXSk7DQogICAgICAgICAgICAgICAgICAgIHQgPSBSZWFkSW50KHh4LCAwKTsNCiAgICAgICAgICAgICAgICAgICAgdiA9IFJlYWRJbnQoeHgsIDQpOw0KICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSAxKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbW0gPSBSZWFkSW50KHh4LCA4KTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtbSA8IDEwKSBtbSA9ICcwJyArIG1tOw0KICAgICAgICAgICAgICAgICAgICAgICAgdiArPSAnOicgKyBtbTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxzZWxlY3QgaWQ9ZDJ0dHlwZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDZweCBvbmNoYW5nZT1lZGl0TXBzUG9saWN5VXBkYXRlKCk+JzsNCiAgICAgICAgICAgICAgICB4ICs9ICc8b3B0aW9uIHZhbHVlPTAnICsgKHQgPT0gMCA/ICcgc2VsZWN0ZWQnIDogJycpICsgJz5QZXJpb2RpYywgdGltZSBpbnRlcnZhbDxvcHRpb24gdmFsdWU9MScgKyAodCA9PSAxID8gJyBzZWxlY3RlZCcgOiAnJykgKyAnPlRpbWUgb2YgZGF5LCBvbmNlIGEgZGF5Jw0KICAgICAgICAgICAgICAgIHggKz0gJzwvc2VsZWN0PjxkaXY+VHJpZ2dlciB0eXBlPC9kaXY+PC9kaXY+PGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48aW5wdXQgaWQ9ZDJ0aW1lciBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBvbmtleXVwPWVkaXRNcHNQb2xpY3lVcGRhdGUoKSB2YWx1ZT0nICsgdiArICc+PGRpdiBpZD10dHlwZWxhYmVsPjwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCB0eXBlICsgIiBDb25uZWN0aW9uIiwgMywgZWRpdE1wc1BvbGljeU9rLCB4KTsNCiAgICAgICAgICAgIGVkaXRNcHNQb2xpY3lVcGRhdGUoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGVkaXRNcHNQb2xpY3lVcGRhdGUoKSB7DQogICAgICAgICAgICB2YXIgY2lsYVN1cHBvcnQgPSAoKGFtdHZlcnNpb24gPiAxMSkgfHwgKChhbXR2ZXJzaW9uID09IDExKSAmJiAoYW10dmVyc2lvbiA+PSA2KSkpOw0KICAgICAgICAgICAgdmFyIG9rID0gKHh4Q2lyYVNlcnZlcnMubGVuZ3RoIDw9IDEgfHwgKChRKCdkMnNlcnZlcjEnKS52YWx1ZSA9PSAtMSkgfHwgKFEoJ2Qyc2VydmVyMScpLnZhbHVlICE9IFEoJ2Qyc2VydmVyMicpLnZhbHVlKSkpOw0KICAgICAgICAgICAgaWYgKG9rID09IHRydWUgJiYgeHhFZGl0TXBzUG9saWN5VHlwZSA9PSAnUGVyaW9kaWMnICYmIFEoJ2QydHR5cGUnKS52YWx1ZSA9PSAxKSB7IHZhciBoaG1tID0gUSgnZDJ0aW1lcicpLnZhbHVlLnNwbGl0KCc6Jyk7IGlmIChoaG1tLmxlbmd0aCAhPSAyKSBvayA9IGZhbHNlOyBlbHNlIHsgdmFyIGhoID0gcGFyc2VJbnQoaGhtbVswXSk7IHZhciBtbSA9IHBhcnNlSW50KGhobW1bMV0pOyBpZiAoaGggPCAwIHx8IGhoID4gMjMgfHwgbW0gPCAwIHx8IG1tID4gNTkpIG9rID0gZmFsc2U7IH0gfQ0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgICAgIGlmICh4eENpcmFTZXJ2ZXJzLmxlbmd0aCA+IDEpIFFFKCdkMnNlcnZlcjInLCBRKCdkMnNlcnZlcjEnKS52YWx1ZSAhPSAtMSk7DQogICAgICAgICAgICBpZiAoeHhFZGl0TXBzUG9saWN5VHlwZSA9PSAnUGVyaW9kaWMnKSB7DQogICAgICAgICAgICAgICAgUUUoJ2QydGltZXInLCBRKCdkMnNlcnZlcjEnKS52YWx1ZSAhPSAtMSk7DQogICAgICAgICAgICAgICAgUUgoJ3R0eXBlbGFiZWwnLCBRKCdkMnR0eXBlJykudmFsdWUgPT0gMCA/ICdUcmlnZ2VyIGludGVydmFsIChTZWNvbmRzKScgOiAnVGltZSBvZiBkYXkgKEhIOk1NKScpOw0KICAgICAgICAgICAgICAgIFFFKCdkMnR0eXBlJywgUSgnZDJzZXJ2ZXIxJykudmFsdWUgIT0gLTEpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgUUUoJ2QybGlmZXRpbWUnLCBRKCdkMnNlcnZlcjEnKS52YWx1ZSAhPSAtMSk7DQoNCiAgICAgICAgICAgIC8vIElmIHdlIGFyZSBvbiBJbnRlbCBBTVQgMTEuNiBvciBoaWdoZXIsIGVuYWJsZSB0aGUgQ0lSQS9DSUxBIHNlbGVjdG9yIHdoZW4gbmVlZGVkLg0KICAgICAgICAgICAgaWYgKGNpbGFTdXBwb3J0KSB7DQogICAgICAgICAgICAgICAgUUUoJ2Qyc2VydmVyMWNpcmEnLCBRKCdkMnNlcnZlcjEnKS52YWx1ZSA+IC0xKQ0KICAgICAgICAgICAgICAgIGlmICh4eENpcmFTZXJ2ZXJzLmxlbmd0aCA+IDEpIHsgUUUoJ2Qyc2VydmVyMmNpcmEnLCAoUSgnZDJzZXJ2ZXIxJykudmFsdWUgPiAtMSkgJiYgKFEoJ2Qyc2VydmVyMicpLnZhbHVlID4gLTEpKTsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZWRpdE1wc1BvbGljeU9rKCkgew0KICAgICAgICAgICAgdmFyIG5hbWUgPSB4eEVkaXRNcHNQb2xpY3lUeXBlOw0KICAgICAgICAgICAgaWYgKG5hbWUgPT0gJ1VzZXInKSB7IG5hbWUgPSAnVXNlciBJbml0aWF0ZWQnOyB9DQoNCiAgICAgICAgICAgIGlmIChnZXRJdGVtKHh4UmVtb3RlQWNjZXNzWyJBTVRfUmVtb3RlQWNjZXNzUG9saWN5UnVsZSJdLnJlc3BvbnNlcywgIlBvbGljeVJ1bGVOYW1lIiwgbmFtZSkpIHsNCiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgb2xkIHBvbGljeQ0KICAgICAgICAgICAgICAgIGFtdHN0YWNrLkRlbGV0ZSgnQU1UX1JlbW90ZUFjY2Vzc1BvbGljeVJ1bGUnLCB7ICdQb2xpY3lSdWxlTmFtZSc6IG5hbWUgfSwgZWRpdE1wc1BvbGljeU9rMik7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIC8vIE5vIG9sZCBwb2xpY3kgdG8gcmVtb3ZlLCBza2lwIHRoaXMuDQogICAgICAgICAgICAgICAgZWRpdE1wc1BvbGljeU9rMigpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZWRpdE1wc1BvbGljeU9rMihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIHZhciBjaWxhU3VwcG9ydCA9ICgoYW10dmVyc2lvbiA+IDExKSB8fCAoKGFtdHZlcnNpb24gPT0gMTEpICYmIChhbXR2ZXJzaW9uID49IDYpKSk7DQogICAgICAgICAgICBpZiAoUSgnZDJzZXJ2ZXIxJykudmFsdWUgPT0gLTEpIHsgUHVsbFJlbW90ZUFjY2VzcygpOyByZXR1cm47IH0NCg0KICAgICAgICAgICAgdmFyIHRyaWdnZXIgPSAwOw0KICAgICAgICAgICAgaWYgKHh4RWRpdE1wc1BvbGljeVR5cGUgPT0gJ0FsZXJ0JykgdHJpZ2dlciA9IDE7DQogICAgICAgICAgICBpZiAoeHhFZGl0TXBzUG9saWN5VHlwZSA9PSAnUGVyaW9kaWMnKSB0cmlnZ2VyID0gMjsNCg0KICAgICAgICAgICAgLy8gU2V0dXAgZXh0ZW5kZWQgZGF0YQ0KICAgICAgICAgICAgdmFyIGV4dGVuZGVkRGF0YSA9IG51bGw7DQogICAgICAgICAgICBpZiAodHJpZ2dlciA9PSAyKSB7DQogICAgICAgICAgICAgICAgdmFyIHRpbWVydHlwZSA9IFEoJ2QydHR5cGUnKS52YWx1ZTsNCiAgICAgICAgICAgICAgICB2YXIgZXhkYXRhID0gSW50VG9TdHIoUSgnZDJ0aW1lcicpLnZhbHVlKTsgLy8gSW50ZXJ2YWwgdHJpZ2dlcg0KICAgICAgICAgICAgICAgIGlmICh0aW1lcnR5cGUgPT0gMSkgeyB2YXIgaGhtbSA9IFEoJ2QydGltZXInKS52YWx1ZS5zcGxpdCgnOicpOyBleGRhdGEgPSBJbnRUb1N0cihwYXJzZUludChoaG1tWzBdKSkgKyBJbnRUb1N0cihwYXJzZUludChoaG1tWzFdKSk7IH0gLy8gVGltZSBvZiBkYXkgdHJpZ2dlcg0KICAgICAgICAgICAgICAgIGV4dGVuZGVkRGF0YSA9IGJ0b2EoSW50VG9TdHIodGltZXJ0eXBlKSArIGV4ZGF0YSk7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgTVBTIHNlcnZlciByZWZlcmVuY2VzDQogICAgICAgICAgICB2YXIgc2VydmVyMSwgc2VydmVyMjsNCiAgICAgICAgICAgIGlmIChRKCdkMnNlcnZlcjEnKS52YWx1ZSA+PSAwKSB7IHNlcnZlcjEgPSAnPEFkZHJlc3MgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZyI+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nL3JvbGUvYW5vbnltb3VzPC9BZGRyZXNzPjxSZWZlcmVuY2VQYXJhbWV0ZXJzIHhtbG5zPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmciPjxSZXNvdXJjZVVSSSB4bWxucz0iaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZCI+aHR0cDovL2ludGVsLmNvbS93YmVtL3dzY2ltLzEvYW10LXNjaGVtYS8xL0FNVF9NYW5hZ2VtZW50UHJlc2VuY2VSZW1vdGVTQVA8L1Jlc291cmNlVVJJPjxTZWxlY3RvclNldCB4bWxucz0iaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZCI+PFNlbGVjdG9yIE5hbWU9Ik5hbWUiPicgKyB4eENpcmFTZXJ2ZXJzW1EoJ2Qyc2VydmVyMScpLnZhbHVlXVsnTmFtZSddICsgJzwvU2VsZWN0b3I+PC9TZWxlY3RvclNldD48L1JlZmVyZW5jZVBhcmFtZXRlcnM+JzsgfQ0KICAgICAgICAgICAgaWYgKFEoJ2Qyc2VydmVyMScpLnZhbHVlID49IDAgJiYgeHhDaXJhU2VydmVycy5sZW5ndGggPiAxICYmIFEoJ2Qyc2VydmVyMicpLnZhbHVlID49IDApIHsgc2VydmVyMiA9ICc8QWRkcmVzcyB4bWxucz0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nIj5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L0FkZHJlc3M+PFJlZmVyZW5jZVBhcmFtZXRlcnMgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZyI+PFJlc291cmNlVVJJIHhtbG5zPSJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkIj5odHRwOi8vaW50ZWwuY29tL3diZW0vd3NjaW0vMS9hbXQtc2NoZW1hLzEvQU1UX01hbmFnZW1lbnRQcmVzZW5jZVJlbW90ZVNBUDwvUmVzb3VyY2VVUkk+PFNlbGVjdG9yU2V0IHhtbG5zPSJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkIj48U2VsZWN0b3IgTmFtZT0iTmFtZSI+JyArIHh4Q2lyYVNlcnZlcnNbUSgnZDJzZXJ2ZXIyJykudmFsdWVdWydOYW1lJ10gKyAnPC9TZWxlY3Rvcj48L1NlbGVjdG9yU2V0PjwvUmVmZXJlbmNlUGFyYW1ldGVycz4nOyB9DQoNCiAgICAgICAgICAgIC8vIFB1dCB0aGUgQ0lSQS9DSUxBIHNlcnZlcnMgaW4gdGhlIHJpZ2h0IGJpbnMuDQogICAgICAgICAgICB2YXIgY2lyYVNlcnZlcnMgPSBbXTsNCiAgICAgICAgICAgIHZhciBjaWxhU2VydmVycyA9IFtdOw0KICAgICAgICAgICAgaWYgKGNpbGFTdXBwb3J0KSB7DQogICAgICAgICAgICAgICAgLy8gT25seSBJbnRlbCBBTVQgMTEuNiBzdXBwb3J0cyB0aGlzDQogICAgICAgICAgICAgICAgaWYgKHNlcnZlcjEpIHsNCiAgICAgICAgICAgICAgICAgICAgaWYgKFEoJ2Qyc2VydmVyMWNpcmEnKS52YWx1ZSA9PSAwKSB7IGNpcmFTZXJ2ZXJzLnB1c2goc2VydmVyMSk7IH0gZWxzZSB7IGNpbGFTZXJ2ZXJzLnB1c2goc2VydmVyMSk7IH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKHNlcnZlcjIpIHsgaWYgKFEoJ2Qyc2VydmVyMmNpcmEnKS52YWx1ZSA9PSAwKSB7IGNpcmFTZXJ2ZXJzLnB1c2goc2VydmVyMik7IH0gZWxzZSB7IGNpbGFTZXJ2ZXJzLnB1c2goc2VydmVyMik7IH0gfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gSWYgb2xkZXIgdGhhbiBJbnRlbCBBTVQgMTEuNiwgcHV0IGFsbCBzZXJ2ZXJzIGluIHRoZSBDSVJBIGJ1Y2tldC4NCiAgICAgICAgICAgICAgICBpZiAoc2VydmVyMSkgeyBjaXJhU2VydmVycy5wdXNoKHNlcnZlcjEpOyBpZiAoc2VydmVyMikgeyBjaXJhU2VydmVycy5wdXNoKHNlcnZlcjIpOyB9IH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gR28gYWhlYWQgYW5kIGNyZWF0ZSB0aGUgbmV3IENJUkEvQ0lMQSBwb2xpY3kuDQogICAgICAgICAgICBhbXRzdGFjay5BTVRfUmVtb3RlQWNjZXNzU2VydmljZV9BZGRSZW1vdGVBY2Nlc3NQb2xpY3lSdWxlKHRyaWdnZXIsIFEoJ2QybGlmZXRpbWUnKS52YWx1ZSwgZXh0ZW5kZWREYXRhLCBjaXJhU2VydmVycywgY2lsYVNlcnZlcnMsIFB1bGxSZW1vdGVBY2Nlc3MpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIGVkaXRFbnZpcm9ubWVudERldGVjdGlvblRtcDsNCiAgICAgICAgZnVuY3Rpb24gZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uKGEpIHsNCiAgICAgICAgICAgIGlmIChhICE9IDEpIHsgZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uVG1wID0gKHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uWydEZXRlY3Rpb25TdHJpbmdzJ10pID8gQ2xvbmUoeHhFbnZpcm9uZW1lbnREZXRlY3Rpb25bJ0RldGVjdGlvblN0cmluZ3MnXSkgOiBbXTsgfQ0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHggKz0gJ0VudGVyIHVwIHRvIDQgaW50cmFuZXQgZG9tYWluIHN1ZmZpeC4gSWYgdGhlIGNvbXB1dGVyIGlzIG91dHNpZGUgdGhlc2UgZG9tYWlucywgSW50ZWwmcmVnOyBBTVQgbG9jYWwgcG9ydHMgd2lsbCBiZSBjbG9zZWQgYW5kIHJlbW90ZSBzZXJ2ZXIgY29ubmVjdGlvbnMgd2lsbCBiZSBhY3RpdmUuPGJyPjxicj4nOw0KICAgICAgICAgICAgaWYgKGVkaXRFbnZpcm9ubWVudERldGVjdGlvblRtcC5sZW5ndGggPT0gMCkgeyB4ICs9ICI8aT5ObyBpbnRyYW5ldCBkb21haW5zLCBFbnZpcm9uZW1udCBkZXRlY3Rpb24gZGlzYWJsZWQuPC9pPjxicj4iOyB9DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIGVkaXRFbnZpcm9ubWVudERldGVjdGlvblRtcCkgeyB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgc3R5bGU9bWFyZ2luLXJpZ2h0OjA+PGRpdiBzdHlsZT1mbG9hdDpyaWdodD4iICsgQWRkQnV0dG9uMigiUmVtb3ZlIiwgImVkaXRFbnZpcm9ubWVudERldGVjdGlvblJlbW92ZSgiICsgaSArICIpIikgKyAiPC9kaXY+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDozcHg7bWF4LXdpZHRoOjI2MHB4O292ZXJmbG93OmhpZGRlbiB0aXRsZT0nIiArIGVkaXRFbnZpcm9ubWVudERldGVjdGlvblRtcFtpXSArICInPjxiPiIgKyBlZGl0RW52aXJvbm1lbnREZXRlY3Rpb25UbXBbaV0gKyAiPC9iPjwvZGl2PjwvZGl2PiI7IH0NCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUgJiYgZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uVG1wLmxlbmd0aCA8IDQpIHsgeCArPSAiPGJyPjxpbnB1dCBpZD1lZElucHV0IHBsYWNlaG9sZGVyPWludHJhbmV0Lm9yZyBzdHlsZT13aWR0aDoyNzZweCBvbmtleXVwPWVkSW5wdXRDaGcoKSBtYXhsZW5ndGg9NjM+PGlucHV0IHR5cGU9YnV0dG9uIGlkPWVkQWRkIHZhbHVlPUFkZCBzdHlsZT13aWR0aDo4MHB4O21hcmdpbi1sZWZ0OjVweCBvbmNsaWNrPWVkaXRFbnZpcm9ubWVudERldGVjdGlvbkFkZCgpPiI7IH0NCiAgICAgICAgICAgIGlmIChhID09IDEpIFFIKCdpZF9kaWFsb2dPcHRpb25zJywgeCk7IGVsc2Ugc2V0RGlhbG9nTW9kZSgxMSwgJ0Vudmlyb25tZW50IERldGVjdGlvbicsIHh4QWNjb3VudEFkbWluTmFtZT8zOjEsIGVkaXRFbnZpcm9ubWVudERldGVjdGlvbkRsZywgeCk7DQogICAgICAgICAgICBlZElucHV0Q2hnKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBlZGl0RW52aXJvbm1lbnREZXRlY3Rpb25EbGcoKSB7DQogICAgICAgICAgICBpZiAoeHhBY2NvdW50QWRtaW5OYW1lKSB7DQogICAgICAgICAgICAgICAgdmFyIHQgPSBDbG9uZSh4eEVudmlyb25lbWVudERldGVjdGlvbik7DQogICAgICAgICAgICAgICAgdFsnRGV0ZWN0aW9uU3RyaW5ncyddID0gZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uVG1wOw0KICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coJ0FNVF9FbnZpcm9ubWVudERldGVjdGlvblNldHRpbmdEYXRhJywgdCk7DQogICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfRW52aXJvbm1lbnREZXRlY3Rpb25TZXR0aW5nRGF0YScsIHQsIGVkaXRFbnZpcm9ubWVudERldGVjdGlvbkRsZzIsIDAsIDEpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uRGxnMihzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsgbWVzc2FnZWJveCgnRW52aXJvbm1lbnQgRGV0ZWN0aW9uJywgJ0ZhaWxlZCB0byBhZGQgc2VydmVyLCBzdGF0dXMgJyArIHN0YXR1cyk7IH0NCiAgICAgICAgICAgIGVsc2UgaWYgKChyZXNwb25zZS5Cb2R5WyJSZXR1cm5WYWx1ZSJdKSAmJiAocmVzcG9uc2UuQm9keVsiUmV0dXJuVmFsdWUiXSAhPSAwKSkgeyBtZXNzYWdlYm94KCdFbnZpcm9ubWVudCBEZXRlY3Rpb24nLCByZXNwb25zZS5Cb2R5LlJldHVyblZhbHVlU3RyLnJlcGxhY2UoL18vZywgJyAnKSk7IH0NCiAgICAgICAgICAgIGVsc2UgeyBQdWxsUmVtb3RlQWNjZXNzKCk7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGVkSW5wdXRDaGcoKSB7DQogICAgICAgICAgICBpZiAoZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uVG1wLmxlbmd0aCA8IDQpIFFFKCdlZEFkZCcsIFEoJ2VkSW5wdXQnKS52YWx1ZS5sZW5ndGggPiAwKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGVkaXRFbnZpcm9ubWVudERldGVjdGlvbkFkZCgpIHsNCiAgICAgICAgICAgIGVkaXRFbnZpcm9ubWVudERldGVjdGlvblRtcC5wdXNoKFEoJ2VkSW5wdXQnKS52YWx1ZSk7DQogICAgICAgICAgICBlZGl0RW52aXJvbm1lbnREZXRlY3Rpb24oMSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBlZGl0RW52aXJvbm1lbnREZXRlY3Rpb25SZW1vdmUoaCkgew0KICAgICAgICAgICAgZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uVG1wLnNwbGljZShoLCAxKTsNCiAgICAgICAgICAgIGVkaXRFbnZpcm9ubWVudERldGVjdGlvbigxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGVkaXRVc2VySW5pdGlhdGVkQ2lyYSgpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBzID0gIiI7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4VXNlckluaXRpYXRlZEVuYWJsZWRTdGF0ZSkgeyBzICs9ICc8aW5wdXQgdHlwZT1yYWRpbyBuYW1lPWQxMSBpZD13bCcgKyBpICsgJyB2YWx1ZT0nICsgaSArICcgJyArICgoeHhVc2VySW5pdGlhdGVkQ2lyYVsnRW5hYmxlZFN0YXRlJ10gPT0gaSkgPyAiY2hlY2tlZCIgOiAiIikgKyAnPicgKyB4eFVzZXJJbml0aWF0ZWRFbmFibGVkU3RhdGVbaV0gKyAnPGJyPic7IH0NCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdVc2VyIEluaXRpYXRlZCBUdW5uZWwnLCAzLCBlZGl0VXNlckluaXRpYXRlZENpcmFEbGcsIHMpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZWRpdFVzZXJJbml0aWF0ZWRDaXJhRGxnKCkgeyBhbXRzdGFjay5BTVRfVXNlckluaXRpYXRlZENvbm5lY3Rpb25TZXJ2aWNlX1JlcXVlc3RTdGF0ZUNoYW5nZShkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPWQxMV06Y2hlY2tlZCcpLnZhbHVlLCBudWxsLCBlZGl0VXNlckluaXRpYXRlZENpcmFEbGcyKTsgfQ0KICAgICAgICBmdW5jdGlvbiBlZGl0VXNlckluaXRpYXRlZENpcmFEbGcyKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7IGlmIChzdGF0dXMgPT0gMjAwKSB7IGFtdHN0YWNrLkdldCgnQU1UX1VzZXJJbml0aWF0ZWRDb25uZWN0aW9uU2VydmljZScsIGVkaXRVc2VySW5pdGlhdGVkQ2lyYURsZzMsIDAsIDEpOyB9IH0NCiAgICAgICAgZnVuY3Rpb24gZWRpdFVzZXJJbml0aWF0ZWRDaXJhRGxnMyhzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgeyBpZiAoc3RhdHVzID09IDIwMCkgeyB4eFVzZXJJbml0aWF0ZWRDaXJhID0gcmVzcG9uc2UuQm9keTsgdXBkYXRlUmVtb3RlQWNjZXNzKCk7IH0gfQ0KDQogICAgICAgIHZhciB4eFNob3dTZXJ2ZXJEZXRhaWxzSGFuZGxlOw0KICAgICAgICBmdW5jdGlvbiBzaG93U2VydmVyRGV0YWlscyhoKSB7DQogICAgICAgICAgICB4eFNob3dTZXJ2ZXJEZXRhaWxzSGFuZGxlID0gaDsNCiAgICAgICAgICAgIHZhciBzZXJ2ZXIgPSB4eENpcmFTZXJ2ZXJzW2hdOw0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJBY2Nlc3MgTmFtZSIsIHNlcnZlclsiQWNjZXNzSW5mbyJdKTsNCiAgICAgICAgICAgIGlmIChzZXJ2ZXJbIlBvcnQiXSkgeCArPSBhZGRIdG1sVmFsdWUoIlBvcnQiLCBzZXJ2ZXJbIlBvcnQiXSk7DQogICAgICAgICAgICBpZiAoc2VydmVyWyJDTiJdKSB4ICs9IGFkZEh0bWxWYWx1ZSgiQ29tbW9uIE5hbWUiLCBzZXJ2ZXJbIkNOIl0pOw0KDQogICAgICAgICAgICB2YXIgY3JlZGVudGlhbGxpbmsgPSBnZXRFbGVtZW50V2l0aENvbnRleHRTZWxlY3RvclZhbHVlKHh4UmVtb3RlQWNjZXNzQ3JlZGVudGlhTGlua3MsIHNlcnZlclsnTmFtZSddKTsNCiAgICAgICAgICAgIGlmIChjcmVkZW50aWFsbGluaykgew0KICAgICAgICAgICAgICAgIHZhciBjcmVkZW50aWFsc2VsZWN0b3J2YWx1ZSA9IGNyZWRlbnRpYWxsaW5rWydFbGVtZW50SW5Db250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXVsnVmFsdWUnXTsNCiAgICAgICAgICAgICAgICBpZiAoY3JlZGVudGlhbHNlbGVjdG9ydmFsdWUuaW5kZXhPZignVXNlcm5hbWUnKSA+IDApIHsNCiAgICAgICAgICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ0F1dGhlbnRpY2F0aW9uIFR5cGUnLCAnVXNlciAmIFBhc3MgLyBTZXJ2ZXItQXV0aCBUTFMnKTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ1JlbW90ZSBJRCcsIGdldEluc3RhbmNlKHh4TVBTVXNlclBhc3MsIGNyZWRlbnRpYWxzZWxlY3RvcnZhbHVlKVsnUmVtb3RlSUQnXSk7DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ0F1dGhlbnRpY2F0aW9uIFR5cGUnLCAnQ2VydGlmaWNhdGUgLyBNdXR1YWwtQXV0aCBUTFMnKTsNCg0KICAgICAgICAgICAgICAgICAgICB2YXIgYyA9IGdldEluc3RhbmNlKHh4Q2VydGlmaWNhdGVzLCBjcmVkZW50aWFsc2VsZWN0b3J2YWx1ZSk7DQogICAgICAgICAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCdDZXJ0aWZpY2F0ZSBOYW1lJywgcGFyc2VDZXJ0TmFtZShjWydTdWJqZWN0J10pWydDTiddKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHZhciBidXR0b25zID0gMTsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIGJ1dHRvbnMgPSA1Ow0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIlJlbW90ZSBTZXJ2ZXIgIyIgKyAoaCArIDEpLCBidXR0b25zLCBzaG93U2VydmVyRGV0YWlsc09rLCB4KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGdldEVsZW1lbnRXaXRoQ29udGV4dFNlbGVjdG9yVmFsdWUoZWxlbWVudHMsIHZhbHVlKSB7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIGVsZW1lbnRzKSB7DQogICAgICAgICAgICAgICAgZWxlbWVudHNbaV1bJ0VsZW1lbnRQcm92aWRpbmdDb250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXSA9IE1ha2VUb0FycmF5KGVsZW1lbnRzW2ldWydFbGVtZW50UHJvdmlkaW5nQ29udGV4dCddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ10pOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gZWxlbWVudHNbaV1bJ0VsZW1lbnRQcm92aWRpbmdDb250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXSkgeyBpZiAoZWxlbWVudHNbaV1bJ0VsZW1lbnRQcm92aWRpbmdDb250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXVtqXVsnVmFsdWUnXSA9PSB2YWx1ZSkgcmV0dXJuIGVsZW1lbnRzW2ldOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gbnVsbDsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dTZXJ2ZXJEZXRhaWxzT2socikgew0KICAgICAgICAgICAgLy8gRGVsZXRlIHRoZSBzZWxlY3RlZCBDSVJBIHNlcnZlciANCiAgICAgICAgICAgIGlmIChyID09IDIpIHsgYW10c3RhY2suRGVsZXRlKCdBTVRfTWFuYWdlbWVudFByZXNlbmNlUmVtb3RlU0FQJywgeyAnTmFtZSc6IHh4Q2lyYVNlcnZlcnNbeHhTaG93U2VydmVyRGV0YWlsc0hhbmRsZV1bJ05hbWUnXSB9LCBzaG93U2VydmVyRGV0YWlsc09rMik7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dTZXJ2ZXJEZXRhaWxzT2syKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSA0MDgpIHsgbWVzc2FnZWJveCgnUmVtb3RlIFNlcnZlciBSZW1vdmFsJywgJ1VuYWJsZSB0byByZW1vdmUgc2VydmVyLCBhY2Nlc3MgZGVuaWVkLicpOyB9IGVsc2UgeyBQdWxsUmVtb3RlQWNjZXNzKCk7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHBhcnNlQ2VydE5hbWUoeCkgew0KICAgICAgICAgICAgdmFyIGosIHIgPSB7fSwgeHggPSB4LnNwbGl0KCcsJyk7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4KSB7IGogPSB4eFtpXS5pbmRleE9mKCc9Jyk7IHJbeHhbaV0uc3Vic3RyaW5nKDAsIGopXSA9IHh4W2ldLnN1YnN0cmluZyhqICsgMSk7IH0NCiAgICAgICAgICAgIHJldHVybiByOw0KICAgICAgICB9DQogICAgICAgIA0KICAgICAgICBmdW5jdGlvbiBzaG93UHJveHlEZXRhaWxzKGgpIHsNCiAgICAgICAgICAgIHZhciBwcm94eSA9IHh4UmVtb3RlQWNjZXNzWyJJUFNfSFRUUFByb3h5QWNjZXNzUG9pbnQiXS5yZXNwb25zZXNbaF07DQoNCiAgICAgICAgICAgIHZhciB4ID0gYWRkSHRtbFZhbHVlKCJBY2Nlc3MgbmFtZSIsIHByb3h5WyJBY2Nlc3NJbmZvIl0gKyAnOicgKyBwcm94eVsiUHJveHlQb3J0Il0pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkROUyBzdWZmZXgiLCBwcm94eVsiTmV0d29ya0Ruc1N1ZmZpeCJdKTsNCiAgICAgICAgICAgIC8veCArPSBhZGRIdG1sVmFsdWUoIlByb3h5IHR5cGUiLCBbJ0FkbWluaXN0cmF0b3InLCAnT3BlcmF0aW5nIHN5c3RlbSddW3Byb3h5WyJQcm94eVR5cGUiXV0pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlByb3h5IHR5cGUiLCBbJ0FkbWluaXN0cmF0b3InLCAnT3BlcmF0aW5nIHN5c3RlbSddW3Byb3h5WyJUeXBlIl1dKTsNCiAgICAgICAgICAgIC8veCArPSBhZGRIdG1sVmFsdWUoIkxhc3QgdGltZSB1c2VkIiwgcHJveHlbIkxhc3RUaW1lVXNlZCJdKTsNCg0KICAgICAgICAgICAgdmFyIGJ1dHRvbnMgPSAxOw0KICAgICAgICAgICAgaWYgKHh4QWNjb3VudEFkbWluTmFtZSkgeyBidXR0b25zID0gNTsgfQ0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIkhUVFAgUHJveHkgIyIgKyAoaCArIDEpLCBidXR0b25zLCBzaG93UHJveHlEZXRhaWxzT2ssIHgsIGgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1Byb3h5RGV0YWlsc09rKHIsIGgpIHsNCiAgICAgICAgICAgIC8vIERlbGV0ZSB0aGUgc2VsZWN0ZWQgcHJveHkgc2VydmVyDQogICAgICAgICAgICB2YXIgcHJveHkgPSB4eFJlbW90ZUFjY2Vzc1siSVBTX0hUVFBQcm94eUFjY2Vzc1BvaW50Il0ucmVzcG9uc2VzW2hdOw0KICAgICAgICAgICAgaWYgKHIgPT0gMikgeyBhbXRzdGFjay5EZWxldGUoJ0lQU19IVFRQUHJveHlBY2Nlc3NQb2ludCcsIHsgJ05hbWUnOiBwcm94eVsnTmFtZSddIH0sIHNob3dQcm94eURldGFpbHNPazIpOyB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93UHJveHlEZXRhaWxzT2syKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSA0MDgpIHsgbWVzc2FnZWJveCgnSFRUUCBQcm94eSBSZW1vdmFsJywgJ1VuYWJsZSB0byByZW1vdmUgSFRUUCBwcm94eSwgYWNjZXNzIGRlbmllZC4nKTsgfSBlbHNlIHsgUHVsbFJlbW90ZUFjY2VzcygpOyB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NQcm94eSgpIHsNCiAgICAgICAgICAgIC8vIEFkZFJlbW90ZUFjY2Vzc1Byb3h5IEhvc3QgbmFtZSA9IDIsIElwdjQgPSAzLCBJcHY2ID0gNA0KICAgICAgICAgICAgdmFyIHggPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48c2VsZWN0IGlkPWQydHlwZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDZweCBvbmNoYW5nZT1BZGRSZW1vdGVBY2Nlc3NQcm94eVVwZGF0ZSgpPjxvcHRpb24gdmFsdWU9Mj5Ib3N0bmFtZSBGUUROPG9wdGlvbiB2YWx1ZT0zPklQdjQgYWRkcmVzczxvcHRpb24gdmFsdWU9ND5JUHY2IGFkZHJlc3M8L3NlbGVjdD48ZGl2PkNvbm5lY3Rpb24gdHlwZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1kMmhvc3Qgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHggbWF4bGVuZ3RoPTI1NSBvbmtleXVwPUFkZFJlbW90ZUFjY2Vzc1Byb3h5VXBkYXRlKCk+PGRpdiBpZD1kMnR5cGVzcGFuPjwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1kMnBvcnQgb25rZXlwcmVzcz0icmV0dXJuIChldmVudC5jaGFyQ29kZSA9PSAwIHx8IChldmVudC5jaGFyQ29kZSA+PSA0OCAmJiBldmVudC5jaGFyQ29kZSA8PSA1NykpIiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBvbmtleXVwPUFkZFJlbW90ZUFjY2Vzc1Byb3h5VXBkYXRlKCk+PGRpdj5Qb3J0PC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PGlucHV0IGlkPWQyZG9tYWluIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IG1heGxlbmd0aD0xOTEgb25rZXl1cD1BZGRSZW1vdGVBY2Nlc3NQcm94eVVwZGF0ZSgpPjxkaXY+RE5TIHN1ZmZpeDwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiQWRkIEhUVFAgUHJveHkiLCAzLCBBZGRSZW1vdGVBY2Nlc3NQcm94eU9rLCB4KTsNCiAgICAgICAgICAgIEFkZFJlbW90ZUFjY2Vzc1Byb3h5VXBkYXRlKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NQcm94eVVwZGF0ZSgpIHsNCiAgICAgICAgICAgIHZhciBvayA9IChRKCdkMmhvc3QnKS52YWx1ZS5sZW5ndGggIT0gMCkgJiYgKFEoJ2QyZG9tYWluJykudmFsdWUubGVuZ3RoICE9IDApOw0KICAgICAgICAgICAgaWYgKChRKCdkMnBvcnQnKS52YWx1ZS5sZW5ndGggPT0gMCkgfHwgKHBhcnNlSW50KFEoJ2QycG9ydCcpLnZhbHVlKSA+IDY1NTM1KSkgeyBvayA9IGZhbHNlOyB9DQogICAgICAgICAgICBRRSgnaWR4X2RsZ09rQnV0dG9uJywgb2spOw0KICAgICAgICAgICAgUUgoJ2QydHlwZXNwYW4nLCBbJycsICcnLCAnRlFETiAvIGhvc3RuYW1lJywgJ0lQdjQgYWRkcmVzcycsICdJUHY2IGFkZHJlc3MnXVtRKCdkMnR5cGUnKS52YWx1ZV0pOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkUmVtb3RlQWNjZXNzUHJveHlPaygpIHsNCiAgICAgICAgICAgIGFtdHN0YWNrLklQU19IVFRQUHJveHlTZXJ2aWNlX0FkZFByb3h5QWNjZXNzUG9pbnQoUSgnZDJob3N0JykudmFsdWUsIFEoJ2QydHlwZScpLnZhbHVlLCBwYXJzZUludChRKCdkMnBvcnQnKS52YWx1ZSksIFEoJ2QyZG9tYWluJykudmFsdWUsIEFkZFJlbW90ZUFjY2Vzc1Byb3h5T2syKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEFkZFJlbW90ZUFjY2Vzc1Byb3h5T2syKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgew0KICAgICAgICAgICAgICAgIG1lc3NhZ2Vib3goJ0FkZCBQcm94eSBTZXJ2ZXInLCAnRmFpbGVkIHRvIGFkZCBwcm94eSwgc3RhdHVzICcgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZS5Cb2R5WyJSZXR1cm5WYWx1ZSJdICE9IDApIHsNCiAgICAgICAgICAgICAgICBtZXNzYWdlYm94KCdBZGQgUHJveHkgU2VydmVyJywgcmVzcG9uc2UuQm9keS5SZXR1cm5WYWx1ZVN0ci5yZXBsYWNlKC9fL2csICcgJykpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBQdWxsUmVtb3RlQWNjZXNzKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NTZXJ2ZXIoKSB7DQoNCiAgICAgICAgICAgIHZhciBjZXJ0cyA9IFtdOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eENlcnRpZmljYXRlcykgeyBpZiAoeHhDZXJ0aWZpY2F0ZXNbaV0uWFByaXZhdGVLZXkpIHsgY2VydHMucHVzaCh4eENlcnRpZmljYXRlc1tpXSk7IH0gfQ0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PHNlbGVjdCBpZD1kMnR5cGUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjA2cHggb25jaGFuZ2U9QWRkUmVtb3RlQWNjZXNzU2VydmVyVXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT0yMDE+SG9zdG5hbWUgRlFETjxvcHRpb24gdmFsdWU9Mz5JUHY0IGFkZHJlc3M8L3NlbGVjdD48ZGl2PkNvbm5lY3Rpb24gdHlwZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1kMm5hbWUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHggb25rZXl1cD1BZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJVcGRhdGUoKT48ZGl2IGlkPWQybG5hbWU+PC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PGlucHV0IGlkPWQycG9ydCBvbmtleXByZXNzPSJyZXR1cm4gKGV2ZW50LmNoYXJDb2RlID09IDAgfHwgKGV2ZW50LmNoYXJDb2RlID49IDQ4ICYmIGV2ZW50LmNoYXJDb2RlIDw9IDU3KSkiIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IHZhbHVlPTQ0MzMgb25rZXl1cD1BZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJVcGRhdGUoKT48ZGl2PlNlcnZlciBwb3J0PC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHggaWQ9ZDJ1Y24+PGlucHV0IGlkPWQyY24gc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHggb25rZXl1cD1BZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJVcGRhdGUoKT48ZGl2PlNlcnZlciBDb21tb24gTmFtZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxzZWxlY3QgaWQ9ZDJhdXRoIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwNnB4IG9uY2hhbmdlPUFkZFJlbW90ZUFjY2Vzc1NlcnZlclVwZGF0ZSgpPic7DQogICAgICAgICAgICBpZiAoY2VydHMubGVuZ3RoID4gMCkgeyB4ICs9ICc8b3B0aW9uIHZhbHVlPTE+Q2VydGlmaWNhdGUnOyB9DQogICAgICAgICAgICB4ICs9ICc8b3B0aW9uIHZhbHVlPTI+VXNlcm5hbWUvUGFzc3dvcmQ8L3NlbGVjdD48ZGl2PkF1dGhlbnRpY2F0aW9uIHR5cGU8L2Rpdj48L2Rpdj4nOw0KICAgICAgICAgICAgeCArPSAnPHNwYW4gaWQ9ZDJ1dHlwZT4nOw0KICAgICAgICAgICAgeCArPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48aW5wdXQgaWQ9ZDJ1c2VyIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IG9ua2V5dXA9QWRkUmVtb3RlQWNjZXNzU2VydmVyVXBkYXRlKCk+PGRpdj5Vc2VybmFtZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1kMnBhc3Mgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHggb25rZXl1cD1BZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJVcGRhdGUoKT48ZGl2PlN0cm9uZyBQYXNzd29yZDwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8L3NwYW4+JzsNCiAgICAgICAgICAgIHggKz0gJzxzcGFuIGlkPWQyY3R5cGU+JzsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PHNlbGVjdCBpZD1kMmNlcnQgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjA2cHggb25jaGFuZ2U9QWRkUmVtb3RlQWNjZXNzU2VydmVyVXBkYXRlKCk+JzsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gY2VydHMpIHsgeCArPSAnPG9wdGlvbiB2YWx1ZT0nICsgY2VydHNbaV1bJ0luc3RhbmNlSUQnXS5zdWJzdHJpbmcoMzQpICsgJz4nICsgcGFyc2VDZXJ0TmFtZShjZXJ0c1tpXVsnU3ViamVjdCddKVsnQ04nXTsgfQ0KICAgICAgICAgICAgeCArPSAnPC9zZWxlY3Q+PGRpdj5DZXJ0aWZpY2F0ZTwvZGl2PjwvZGl2Pjwvc3Bhbj4nOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIkFkZCBSZW1vdGUgU2VydmVyIiwgMywgQWRkUmVtb3RlQWNjZXNzU2VydmVyT2ssIHgpOw0KICAgICAgICAgICAgQWRkUmVtb3RlQWNjZXNzU2VydmVyVXBkYXRlKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJPaygpIHsNCiAgICAgICAgICAgIHZhciBjcmVmLCB1c2VyLCBwYXNzLCBjbjsNCiAgICAgICAgICAgIGlmIChRKCdkMmF1dGgnKS52YWx1ZSA9PSAxKSB7DQogICAgICAgICAgICAgICAgY3JlZiA9ICc8QWRkcmVzcyB4bWxucz0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nIj5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmc8L0FkZHJlc3M+PFJlZmVyZW5jZVBhcmFtZXRlcnMgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZyI+PFJlc291cmNlVVJJIHhtbG5zPSJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkIj5odHRwOi8vaW50ZWwuY29tL3diZW0vd3NjaW0vMS9hbXQtc2NoZW1hLzEvQU1UX1B1YmxpY0tleUNlcnRpZmljYXRlPC9SZXNvdXJjZVVSST48U2VsZWN0b3JTZXQgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2QiPjxTZWxlY3RvciBOYW1lPSJJbnN0YW5jZUlEIj5JbnRlbChyKSBBTVQgQ2VydGlmaWNhdGU6IEhhbmRsZTogJyArIFEoJ2QyY2VydCcpLnZhbHVlICsgJzwvU2VsZWN0b3I+PC9TZWxlY3RvclNldD48L1JlZmVyZW5jZVBhcmFtZXRlcnM+JzsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgdXNlciA9IFEoJ2QydXNlcicpLnZhbHVlOw0KICAgICAgICAgICAgICAgIHBhc3MgPSBRKCdkMnBhc3MnKS52YWx1ZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChRKCdkMmNuJykudmFsdWUubGVuZ3RoID4gMCkgY24gPSBRKCdkMmNuJykudmFsdWU7DQogICAgICAgICAgICBhbXRzdGFjay5BTVRfUmVtb3RlQWNjZXNzU2VydmljZV9BZGRNcFNlcnZlcihRKCdkMm5hbWUnKS52YWx1ZSwgUSgnZDJ0eXBlJykudmFsdWUsIFEoJ2QycG9ydCcpLnZhbHVlLCBRKCdkMmF1dGgnKS52YWx1ZSwgY3JlZiwgdXNlciwgcGFzcywgY24sIEFkZFJlbW90ZUFjY2Vzc1NlcnZlck9rMik7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJPazIoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnQWRkIEludGVybmV0IFNlcnZlcicsICdGYWlsZWQgdG8gYWRkIHNlcnZlciwgc3RhdHVzICcgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZS5Cb2R5WyJSZXR1cm5WYWx1ZSJdICE9IDApIHsNCiAgICAgICAgICAgICAgICBtZXNzYWdlYm94KCdBZGQgSW50ZXJuZXQgU2VydmVyJywgcmVzcG9uc2UuQm9keS5SZXR1cm5WYWx1ZVN0ci5yZXBsYWNlKC9fL2csICcgJykpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBQdWxsUmVtb3RlQWNjZXNzKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJVcGRhdGUoKSB7DQogICAgICAgICAgICB2YXIgb2sgPSAoUSgnZDJuYW1lJykudmFsdWUubGVuZ3RoICE9IDApOw0KICAgICAgICAgICAgaWYgKFEoJ2QydHlwZScpLnZhbHVlID09IDMgJiYgb2sgPT0gdHJ1ZSkgIHsgb2sgPSAoUSgnZDJjbicpLnZhbHVlLmxlbmd0aCAhPSAwKTsgfQ0KICAgICAgICAgICAgaWYgKFEoJ2QyYXV0aCcpLnZhbHVlID09IDIgJiYgb2sgPT0gdHJ1ZSkgeyBvayA9ICgoUSgnZDJ1c2VyJykudmFsdWUubGVuZ3RoICE9IDApICYmIChwYXNzd29yZGNoZWNrKFEoJ2QycGFzcycpLnZhbHVlKSkpOyB9DQogICAgICAgICAgICBpZiAoKFEoJ2QycG9ydCcpLnZhbHVlLmxlbmd0aCA9PSAwKSB8fCAocGFyc2VJbnQoUSgnZDJwb3J0JykudmFsdWUpID4gNjU1MzUpKSB7IG9rID0gZmFsc2U7IH0NCiAgICAgICAgICAgIGlmICgoUSgnZDJuYW1lJykudmFsdWUuaW5kZXhPZignOicpICE9IC0xKSB8fCAoKFEoJ2QydHlwZScpLnZhbHVlID09IDMpICYmIChRKCdkMmNuJykudmFsdWUuaW5kZXhPZignOicpICE9IC0xKSkpIHsgb2sgPSBmYWxzZTsgfQ0KICAgICAgICAgICAgUUgoJ2QybG5hbWUnLCAoUSgnZDJ0eXBlJykudmFsdWUgPT0gMjAxKSA/ICdIb3N0bmFtZScgOiAnSVB2NCBBZGRyZXNzJyk7DQogICAgICAgICAgICBRVignZDJ1dHlwZScsIFEoJ2QyYXV0aCcpLnZhbHVlID09IDIpOw0KICAgICAgICAgICAgUVYoJ2QydWNuJywgUSgnZDJ0eXBlJykudmFsdWUgPT0gMyk7DQogICAgICAgICAgICBRVignZDJjdHlwZScsIFEoJ2QyYXV0aCcpLnZhbHVlID09IDEpOw0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gRWRpdCBDb21wdXRlciBOYW1lICYgRE5TIGZlYXR1cmUNCiAgICAgICAgLy8NCg0KICAgICAgICBmdW5jdGlvbiBzaG93RWRpdE5hbWVEbGcoeCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHQgPSBhbXRzeXNzdGF0ZVsnQU1UX0dlbmVyYWxTZXR0aW5ncyddLnJlc3BvbnNlWyJIb3N0TmFtZSJdLCB5ID0gYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZVsiRG9tYWluTmFtZSJdOw0KICAgICAgICAgICAgaWYgKHkgIT0gbnVsbCAmJiB5Lmxlbmd0aCA+IDApIHQgKz0gIi4iICsgeTsNCiAgICAgICAgICAgIHZhciByID0gJzxicj48ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1kMTFuYW1lIHZhbHVlPSInICsgdCArICciIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4PjxkaXY+TmFtZSAmIERvbWFpbjwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICBpZiAoeCA9PSAxKSB7DQogICAgICAgICAgICAgICAgdmFyIHMgPSAoYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZVsiU2hhcmVkRlFETiJdID09IHRydWUpOw0KICAgICAgICAgICAgICAgIHIgKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PHNlbGVjdCBpZD1kMTFmcWRuIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4PjxvcHRpb24gdmFsdWU9dHJ1ZSAnICsgKHM/J3NlbGVjdGVkJzonJykgKyAnPlNoYXJlZCwgc2FtZSBhcyBPUzxvcHRpb24gdmFsdWU9ImZhbHNlIiAnICsgKHM/Jyc6J3NlbGVjdGVkJykgKyAnPkRlZGljYXRlZCwgZGlmZmVyZW50IGZyb20gT1M8L3NlbGVjdD48ZGl2Pk5hbWUgU2hhcmluZzwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAnQ29tcHV0ZXIgTmFtZScsIDMsIGVkaXROYW1lRGxnT2ssIHIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZWRpdE5hbWVEbGdPaygpIHsNCiAgICAgICAgICAgIHZhciBpID0gUSgnZDExbmFtZScpLnZhbHVlLCBqID0gaS5pbmRleE9mKCcuJyksIGsgPSAnJzsNCiAgICAgICAgICAgIGlmIChqID49IDApIHsgayA9IGkuc3Vic3RyaW5nKGogKyAxKTsgaSA9IGkuc3Vic3RyaW5nKDAsIGopOyB9DQogICAgICAgICAgICB2YXIgY2xvbmUgPSBDbG9uZShhbXRzeXNzdGF0ZVsnQU1UX0dlbmVyYWxTZXR0aW5ncyddLnJlc3BvbnNlKTsNCiAgICAgICAgICAgIGNsb25lWyJIb3N0TmFtZSJdID0gaTsNCiAgICAgICAgICAgIGNsb25lWyJEb21haW5OYW1lIl0gPSBrOw0KICAgICAgICAgICAgaWYgKFEoJ2QxMWZxZG4nKSkgeyBjbG9uZVsiU2hhcmVkRlFETiJdID0gZDExZnFkbi52YWx1ZTsgfQ0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfR2VuZXJhbFNldHRpbmdzJywgY2xvbmUsIGZ1bmN0aW9uKCkgeyBhbXRzdGFjay5HZXQoJ0FNVF9HZW5lcmFsU2V0dGluZ3MnLCBjb21wdXRlck5hbWVHZXQsIDAsIDEpOyB9LCAwLCAxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGNvbXB1dGVyTmFtZUdldChzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZSA9IHJlc3BvbnNlLkJvZHk7IHVwZGF0ZVN5c3RlbVN0YXR1cygpOyB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93RWRpdERuc0RsZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBnID0gYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZTsNCiAgICAgICAgICAgIHZhciB2ID0gMDsNCiAgICAgICAgICAgIGlmIChnWyJERE5TVXBkYXRlQnlESENQU2VydmVyRW5hYmxlZCJdID09IHRydWUpIHYgPSAxOw0KICAgICAgICAgICAgaWYgKGdbIkRETlNVcGRhdGVFbmFibGVkIl0gPT0gdHJ1ZSkgdiA9IDI7DQogICAgICAgICAgICBpZHhfZDIzZGRucy52YWx1ZSA9IHY7DQogICAgICAgICAgICBpZHhfZDIzaW50ZXJ2YWwudmFsdWUgPSBnWydERE5TUGVyaW9kaWNVcGRhdGVJbnRlcnZhbCddOw0KICAgICAgICAgICAgaWR4X2QyM3R0bC52YWx1ZSA9IGdbJ0RETlNUVEwnXTsNCiAgICAgICAgICAgIHNob3dFZGl0RG5zRGxnQ2hhbmdlKCk7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDIzLCAnRHluYW1pYyBETlMgY2xpZW50JywgMywgc2hvd0VkaXREbnNEbGdPayk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93RWRpdERuc0RsZ09rKCkgew0KICAgICAgICAgICAgdmFyIGNsb25lID0gQ2xvbmUoYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZSk7DQogICAgICAgICAgICBjbG9uZVsiREROU1VwZGF0ZUVuYWJsZWQiXSA9ICgoaWR4X2QyM2RkbnMudmFsdWUgPT0gMik/dHJ1ZTpmYWxzZSk7DQogICAgICAgICAgICBjbG9uZVsiREROU1VwZGF0ZUJ5REhDUFNlcnZlckVuYWJsZWQiXSA9ICgoaWR4X2QyM2RkbnMudmFsdWUgPT0gMSk/dHJ1ZTpmYWxzZSk7DQogICAgICAgICAgICBpZiAoaWR4X2QyM2RkbnMudmFsdWUgPT0gMikgew0KICAgICAgICAgICAgICAgIGNsb25lWyJERE5TUGVyaW9kaWNVcGRhdGVJbnRlcnZhbCJdID0gaWR4X2QyM2ludGVydmFsLnZhbHVlOw0KICAgICAgICAgICAgICAgIGNsb25lWyJERE5TVFRMIl0gPSBpZHhfZDIzdHRsLnZhbHVlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfR2VuZXJhbFNldHRpbmdzJywgY2xvbmUsIGZ1bmN0aW9uKCkgeyBhbXRzdGFjay5HZXQoJ0FNVF9HZW5lcmFsU2V0dGluZ3MnLCBjb21wdXRlck5hbWVHZXQsIDAsIDEpOyB9LCAwLCAxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dFZGl0RG5zRGxnQ2hhbmdlKCkgew0KICAgICAgICAgICAgUUUoJ2lkeF9kMjNpbnRlcnZhbCcsIGlkeF9kMjNkZG5zLnZhbHVlID09IDIpOw0KICAgICAgICAgICAgUUUoJ2lkeF9kMjN0dGwnLCBpZHhfZDIzZGRucy52YWx1ZSA9PSAyKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vDQogICAgICAgIC8vIEludGVsIEFNVCBGZWF0dXJlcw0KICAgICAgICAvLw0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dGZWF0dXJlc0RsZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgfHwgIXh4QWNjb3VudEFkbWluTmFtZSkgcmV0dXJuOw0KICAgICAgICAgICAgaWR4X2Q5cmVkaXIuY2hlY2tlZCA9IGFtdGZlYXR1cmVzWzBdLCBpZHhfZDlrdm0uY2hlY2tlZCA9IGFtdGZlYXR1cmVzWzNdLCBpZHhfZDlpZGVyLmNoZWNrZWQgPSBhbXRmZWF0dXJlc1syXSwgaWR4X2Q5c29sLmNoZWNrZWQgPSBhbXRmZWF0dXJlc1sxXTsNCiAgICAgICAgICAgIFFWKCdpZHhfZDlrdm1fZGl2JywgYW10ZmVhdHVyZXNbM10gIT0gdW5kZWZpbmVkKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoOSwgJ0ludGVsJnJlZzsgQU1UIEZlYXR1cmVzJywgMywgZmVhdHVyZXNEbGdPaykNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGZlYXR1cmVzRGxnT2soKSB7DQogICAgICAgICAgICB2YXIgciA9IGFtdHN5c3N0YXRlWydBTVRfUmVkaXJlY3Rpb25TZXJ2aWNlJ10ucmVzcG9uc2U7DQogICAgICAgICAgICByWyJMaXN0ZW5lckVuYWJsZWQiXSA9IGlkeF9kOXJlZGlyLmNoZWNrZWQ7DQogICAgICAgICAgICByWyJFbmFibGVkU3RhdGUiXSA9IDMyNzY4ICsgKChpZHhfZDlpZGVyLmNoZWNrZWQ/MTowKSArIChpZHhfZDlzb2wuY2hlY2tlZD8yOjApKTsNCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9SZWRpcmVjdGlvblNlcnZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlKHJbIkVuYWJsZWRTdGF0ZSJdLA0KICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goIkVycm9yIiwgIlJlZGlyZWN0aW9uU2VydmljZSwgUmVxdWVzdFN0YXRlQ2hhbmdlIEVycm9yICIgKyBzdGF0dXMpOyByZXR1cm47IH0NCiAgICAgICAgICAgICAgICAgICAgYW10c3RhY2suQ0lNX0tWTVJlZGlyZWN0aW9uU0FQX1JlcXVlc3RTdGF0ZUNoYW5nZSgoaWR4X2Q5a3ZtLmNoZWNrZWQpPzI6MywgMCwNCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goIkVycm9yIiwgIktWTVJlZGlyZWN0aW9uU0FQLCBSZXF1ZXN0U3RhdGVDaGFuZ2UgRXJyb3IgIiArIHN0YXR1cyk7IHJldHVybjsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCJBTVRfUmVkaXJlY3Rpb25TZXJ2aWNlIiwgciwgZnVuY3Rpb24oc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBtZXNzYWdlYm94KCJFcnJvciIsICJSZWRpcmVjdGlvblNlcnZpY2UgUFVUIEVycm9yICIgKyBzdGF0dXMpOyByZXR1cm47IH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbXRzdGFjay5HZXQoIkFNVF9SZWRpcmVjdGlvblNlcnZpY2UiLCBmZWF0dXJlc0RsZ0dldDEsIDAsIDEpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFtdHN0YWNrLkdldCgiQ0lNX0tWTVJlZGlyZWN0aW9uU0FQIiwgZmVhdHVyZXNEbGdHZXQyLCAwLCAxKSB9LCAwLCAxKQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgKTt9DQogICAgICAgICAgICApOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZmVhdHVyZXNEbGdHZXQxKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCkgeyBhbXRzeXNzdGF0ZVsnQU1UX1JlZGlyZWN0aW9uU2VydmljZSddLnJlc3BvbnNlID0gcmVzcG9uc2UuQm9keTsgdXBkYXRlU3lzdGVtU3RhdHVzKCk7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGZlYXR1cmVzRGxnR2V0MihzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgYW10c3lzc3RhdGVbJ0NJTV9LVk1SZWRpcmVjdGlvblNBUCddLnJlc3BvbnNlID0gcmVzcG9uc2UuQm9keTsgdXBkYXRlU3lzdGVtU3RhdHVzKCk7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vDQogICAgICAgIC8vIEludGVsIEFNVCBVc2VyIENvbnNlbnQNCiAgICAgICAgLy8NCg0KICAgICAgICBmdW5jdGlvbiBzaG93Q29uc2VudERsZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBvcHRpbnJlcXVpcmVkID0gYW10c3lzc3RhdGVbJ0lQU19PcHRJblNlcnZpY2UnXS5yZXNwb25zZVsiT3B0SW5SZXF1aXJlZCJdOw0KICAgICAgICAgICAgaWR4X2QxMG5vbmUuY2hlY2tlZCA9IChvcHRpbnJlcXVpcmVkID09IDApOw0KICAgICAgICAgICAgaWR4X2QxMGt2bS5jaGVja2VkID0gKG9wdGlucmVxdWlyZWQgPT0gMSk7DQogICAgICAgICAgICBpZHhfZDEwYWxsLmNoZWNrZWQgPSAob3B0aW5yZXF1aXJlZCA9PSAweEZGRkZGRkZGKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTAsICdVc2VyIENvbnNlbnQnLCAzLCBjb25zZW50RGxnT2spDQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBjb25zZW50RGxnT2soKSB7DQogICAgICAgICAgICBhbXRzeXNzdGF0ZVsnSVBTX09wdEluU2VydmljZSddLnJlc3BvbnNlWyJPcHRJblJlcXVpcmVkIl0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPWQxMF06Y2hlY2tlZCcpLnZhbHVlOw0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCJJUFNfT3B0SW5TZXJ2aWNlIiwgYW10c3lzc3RhdGVbJ0lQU19PcHRJblNlcnZpY2UnXS5yZXNwb25zZSwgZnVuY3Rpb24oKSB7IGFtdHN0YWNrLkdldCgiSVBTX09wdEluU2VydmljZSIsIGNvbnNlbnRHZXQsIDAsIDEpOyB9LCAwLCAxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGNvbnNlbnRHZXQoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gMjAwKSB7IFB1bGxTeXN0ZW1TdGF0dXMoKTsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gTkVUV09SSyBTRVRUSU5HUw0KICAgICAgICAvLw0KDQoNCg0KICAgICAgICAvKg0KICAgICAgICBJUHY2ICVBZGRyVHlwZSU6DQogICAgICAgICAgICAwIC0gQWRkcmVzcyBnZW5lcmF0ZWQgZnJvbTogZmU4MDo6LzY0ICsgSW50ZXJmYWNlIElELA0KICAgICAgICAgICAgMSAtIEFkZHJlc3MgZ2VuZXJhdGVkIGZyb206IFtSb3V0ZXIgYWR2ZXJ0aXNlZCBwcmVmaXhdICsgW0ludGVyZmFjZSBJRF0sDQogICAgICAgICAgICAyIC0gR2xvYmFsIElQdjYgYWRkcmVzcyBvYnRhaW5lZCBmcm9tIERIQ1B2NiBTZXJ2ZXIsDQogICAgICAgICAgICAzIC0gSVB2NiB1bmljYXN0IGFkZHJlc3MgY29uZmlndXJlZCBieSB0aGUgdXNlciwNCiAgICAgICAgICAgIDQgLSBSZXR1cm5lZCBieSBGVyBmb3IgSVB2NiBhZGRyZXNzZXMgdGhhdCBhcmUgbm90IG93bmVkIGJ5IEZXIChzdWNoIGFzIElQdjYgcm91dGVyIGFkZHJlc3MsIGNvbmZpZ3VyYXRpb24gc2VydmVyIGFkZHJlc3MgZXRjLikNCg0KICAgICAgICBJUHY2ICVBZGRyU3RhdGUlOg0KICAgICAgICAgICAgMCAtIERBRCBpcyBzdGlsbCBpbiBwcm9jZXNzIGZvciB0aGlzIGFkZHJlc3MsDQogICAgICAgICAgICAxIC0gQWRkcmVzcyBpcyB2YWxpZCBhbmQgbWF5IGJlIHVzZWQgZm9yIG5ldyBjb21tdW5pY2F0aW9uLA0KICAgICAgICAgICAgMiAtIEFkZHJlc3MgaXMgZGVwcmVjYXRlZCBhbmQgc2hvdWxkIG5vdCBiZSB1c2VkIGZvciBuZXcgY29tbXVuaWNhdGlvbiwNCiAgICAgICAgICAgIDMgLSBDb3ZlcnMgYm90aCB0aGUgcHJlZmVycmVkIGFuZCBkZXByZWNhdGVkIHN0YXRlcywNCiAgICAgICAgICAgIDQgLSBUaGUgdmFsaWQgbGlmZXRpbWUgb2YgdGhlIGFkZHJlc3MgaGFzIGV4cGlyZWQsDQogICAgICAgICAgICA1IC0gQW4gaW50ZXJmYWNlIElEIGNvbGxpc2lvbiBoYXMgYmVlbiBkZXRlY3RlZCBmb3IgdGhpcyBhZGRyZXNzIHdoZW4gcGVyZm9ybWluZyBEQUQsDQogICAgICAgICAgICA2IC0gUmV0dXJuZWQgYnkgRlcgZm9yIElQdjYgYWRkcmVzc2VzIHRoYXQgYXJlIG5vdCBvd25lZCBieSBGVyAoc3VjaCBhcyBJUHY2IHJvdXRlciBhZGRyZXNzLCBjb25maWd1cmF0aW9uIHNlcnZlciBhZGRyZXNzIGV0Yy4NCiAgICAgICAgKi8NCiAgICAgICAgLy8gaXB2NmFkZHJ0eXBlIGFyZSBlbGVtZW50IDAgdG8gNCwgaXB2NmFkZHJzdGF0ZSBhcmUgNSBhbmQgYWZ0ZXIuIE1lcmdlZCBib3RoIGFycmF5cyB0byBjdXQgZG93biBzaXplDQogICAgICAgIHZhciBpcHY2YWRkcnR5cGUgPSBbIkxpbmsgbG9jYWwgYWRkcmVzcyIsICJOZXR3b3JrIGxvY2FsIGFkZHJlc3MiLCAiR2xvYmFsIGFkZHJlc3MiLCAiVXNlciBjb25maWd1cmVkIiwgIk5vdCBhbGxvd2VkIiwgIkRBRCBpbiBwcm9ncmVzcyIsICJ2YWxpZCIsICJkZXByZWNhdGVkIiwgInByZWZlcnJlZC9kZXByZWNhdGVkIiwgImV4cGlyZWQiLCAiY29sbGlzaW9uIiwgIm5vdCBhbGxvd2VkIl07DQogICAgICAgIGZ1bmN0aW9uIHNob3dJUHY2QWRkckRsZyhuZXRpZmlkLCBhZGRyc3RyKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9IFRhYmxlU3RhcnQoKTsNCiAgICAgICAgICAgIHQgPSBhZGRyc3RyLnNwbGl0KCcsJyk7DQogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHQubGVuZ3RoOyBpICs9IDMpIHsNCiAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIjxiPiIgKyB0W2ldICsgIjwvYj48YnI+PHNwYW4gc3R5bGU9Zm9udC1zaXplOjEwcHg+IiArIGlwdjZhZGRydHlwZVt0W2kgKyAxXV0gKyAiLCAiICsgaXB2NmFkZHJ0eXBlWyt0W2kgKyAyXSArIDVdICsgIjwvc3Bhbj4iLCAiIik7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAnSVB2NiBhZGRyZXNzZXMgZm9yICcgKyAobmV0aWZpZD09MD8nd2lyZWQnOid3aXJlbGVzcycpICsgJyBpbnRlcmZhY2UnLCAxLCBudWxsLCB4ICsgVGFibGVFbmQoKSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93SVB2NlN0YXRlRGxnKG5ldGlmaWQsIHN0YXRlKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlIHx8ICFhbXRzeXNzdGF0ZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHp6ID0gYW10c3lzc3RhdGVbJ0lQU19JUHY2UG9ydFNldHRpbmdzJ10ucmVzcG9uc2VzW25ldGlmaWRdOw0KICAgICAgICAgICAgaXB2Nm1hbnVhbCA9IChuZXRpZmlkID09IDAgJiYgKGlzSXBBZGRyZXNzKHp6WyJJUHY2QWRkcmVzcyJdKSB8fCBpc0lwQWRkcmVzcyh6elsiRGVmYXVsdFJvdXRlciJdKSB8fCBpc0lwQWRkcmVzcyh6elsiUHJpbWFyeUROUyJdKSB8fCBpc0lwQWRkcmVzcyh6elsiU2Vjb25kYXJ5RE5TIl0pKSk7DQoNCiAgICAgICAgICAgIFFWKCdpZF9kMjFtYW51YWxkaXYnLCBuZXRpZmlkID09IDApOw0KICAgICAgICAgICAgUVYoJ2lkX2QyMXN1Ym5ldGRpdicsIGZhbHNlKTsNCiAgICAgICAgICAgIFFWKCdkMjFvMCcsIHRydWUpOw0KICAgICAgICAgICAgUVYoJ2QyMWwwJywgdHJ1ZSk7DQogICAgICAgICAgICBRSCgnZDIxbDAnLCAnSVB2NiBkaXNhYmxlZCcpOw0KICAgICAgICAgICAgUUgoJ2QyMWwxJywgJ0lQdjYgZW5hYmxlZCwgYXV0b21hdGljJyk7DQogICAgICAgICAgICBRSCgnZDIxbDInLCAnSVB2NiBlbmFibGVkLCBhdXRvbWF0aWMgKyBtYW51YWwgYWRkcmVzc2UnKTsNCiAgICAgICAgICAgIGQyMW8wLmNoZWNrZWQgPSAhc3RhdGU7DQogICAgICAgICAgICBkMjFvMS5jaGVja2VkID0gc3RhdGUgJiYgIWlwdjZtYW51YWw7DQogICAgICAgICAgICBkMjFvMi5jaGVja2VkID0gc3RhdGUgJiYgaXB2Nm1hbnVhbDsNCiAgICAgICAgICAgIGlkeF9kMjFhZGRyZXNzLnZhbHVlID0gaXNJcEFkZHJlc3MoenpbIklQdjZBZGRyZXNzIl0sJycpOw0KICAgICAgICAgICAgaWR4X2QyMWdhdGV3YXkudmFsdWUgPSBpc0lwQWRkcmVzcyh6elsiRGVmYXVsdFJvdXRlciJdLCcnKTsNCiAgICAgICAgICAgIGlkeF9kMjFkbnMxLnZhbHVlID0gaXNJcEFkZHJlc3MoenpbIlByaW1hcnlETlMiXSwnJyk7DQogICAgICAgICAgICBpZHhfZDIxZG5zMi52YWx1ZSA9IGlzSXBBZGRyZXNzKHp6WyJTZWNvbmRhcnlETlMiXSwnJyk7DQogICAgICAgICAgICB1cGRhdGVJUFNldHVwRGxnKCk7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDIxLCAnSVB2NiBzdXBwb3J0IGZvciAnICsgKG5ldGlmaWQ9PTA/J3dpcmVkJzond2lyZWxlc3MnKSArICcgaW50ZXJmYWNlJywgMywgZnVuY3Rpb24oKSB7IHNob3dJUHY2U3RhdGVEbGdPayhuZXRpZmlkKSB9KQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0lQdjZTdGF0ZURsZ09rKG5ldGlmaWQpIHsNCiAgICAgICAgICAgIHZhciB6eiA9IGFtdHN5c3N0YXRlWydJUFNfSVB2NlBvcnRTZXR0aW5ncyddLnJlc3BvbnNlc1tuZXRpZmlkXTsNCiAgICAgICAgICAgIGlmIChuZXRpZmlkID09IDApIHsgLy8gV2UgY2FuIG9ubHkgc2V0IElQdjYgbWFudWFsIGFkZHJlc3MgZm9yIHdpcmVkIGludGVyZmFjZQ0KICAgICAgICAgICAgICAgIGlmIChkMjFvMS5jaGVja2VkKSB7IC8vIEZ1bGx5IGF1dG9tYXRpYywgY2xlYXIgYWxsIGFkZHJlc3Nlcw0KICAgICAgICAgICAgICAgICAgICB6elsiSVB2NkFkZHJlc3MiXSA9IHp6WyJEZWZhdWx0Um91dGVyIl0gPSB6elsiUHJpbWFyeUROUyJdID0genpbIlNlY29uZGFyeUROUyJdID0gIjo6IjsNCiAgICAgICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCJJUFNfSVB2NlBvcnRTZXR0aW5ncyIsIHp6LCBzaG93SVB2NlN0YXRlRGxnRG9uZSk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmIChkMjFvMi5jaGVja2VkKSB7IC8vIE1hbnVhbCwgc2V0IGFkZHJlc3Nlcw0KICAgICAgICAgICAgICAgICAgICB6elsiSVB2NkFkZHJlc3MiXSA9IGlkeF9kMjFhZGRyZXNzLnZhbHVlOw0KICAgICAgICAgICAgICAgICAgICB6elsiRGVmYXVsdFJvdXRlciJdID0gaWR4X2QyMWdhdGV3YXkudmFsdWU7DQogICAgICAgICAgICAgICAgICAgIHp6WyJQcmltYXJ5RE5TIl0gPSBpZHhfZDIxZG5zMS52YWx1ZTsNCiAgICAgICAgICAgICAgICAgICAgenpbIlNlY29uZGFyeUROUyJdID0gaWR4X2QyMWRuczIudmFsdWU7DQogICAgICAgICAgICAgICAgICAgIGFtdHN0YWNrLlB1dCgiSVBTX0lQdjZQb3J0U2V0dGluZ3MiLCB6eiwgc2hvd0lQdjZTdGF0ZURsZ0RvbmUpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIC8vIFRoaXMgY29kZSBlbmFibGVzL2Rpc2FibGVzIElQdjYgZm9yIGEgZ2l2ZW4gaW50ZXJmYWNlLg0KICAgICAgICAgICAgdmFyIGVsZW1lbnRTZXR0aW5ncyA9IGFtdHN5c3N0YXRlWydDSU1fRWxlbWVudFNldHRpbmdEYXRhJ10ucmVzcG9uc2VzOw0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50U2V0dGluZ3MubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudFNldHRpbmdzW2ldWydTZXR0aW5nRGF0YSddICYmIGVsZW1lbnRTZXR0aW5nc1tpXVsnU2V0dGluZ0RhdGEnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddWydWYWx1ZSddID09ICgnSW50ZWwocikgSVBTIElQdjYgU2V0dGluZ3MgJyArIG5ldGlmaWQpKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBjbG9uZSA9IENsb25lKGVsZW1lbnRTZXR0aW5nc1tpXSk7DQogICAgICAgICAgICAgICAgICAgIGNsb25lWydJc0N1cnJlbnQnXSA9ICgoZDIxbzAuY2hlY2tlZCk/MjoxKTsNCiAgICAgICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCJDSU1fRWxlbWVudFNldHRpbmdEYXRhIiwgY2xvbmUsIHNob3dJUHY2U3RhdGVEbGdEb25lKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93SVB2NlN0YXRlRGxnRG9uZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsNCiAgICAgICAgICAgICAgICBhbXRzeXNzdGF0ZSA9IHVuZGVmaW5lZDsNCiAgICAgICAgICAgICAgICBQdWxsU3lzdGVtU3RhdHVzKCk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIG1lc3NhZ2Vib3goJ0lQdjYgc3VwcG9ydCcsICdVbmFibGUgdG8gc2V0IElQdjYgc3RhdGUsIGVycm9yICcgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1BpbmdBY3Rpb25EbGcoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgZyA9IGFtdHN5c3N0YXRlWydBTVRfR2VuZXJhbFNldHRpbmdzJ10ucmVzcG9uc2U7DQogICAgICAgICAgICB2YXIgdiA9IChnWyJQaW5nUmVzcG9uc2VFbmFibGVkIl0gPT0gdHJ1ZSkgKyAoKGdbIlJtY3BQaW5nUmVzcG9uc2VFbmFibGVkIl0gPT0gdHJ1ZSkgPDwgMSk7DQogICAgICAgICAgICBkMjBhLmNoZWNrZWQgPSAodiA9PSAwKTsNCiAgICAgICAgICAgIGQyMGIuY2hlY2tlZCA9ICh2ID09IDEpOw0KICAgICAgICAgICAgZDIwYy5jaGVja2VkID0gKHYgPT0gMik7DQogICAgICAgICAgICBkMjBkLmNoZWNrZWQgPSAodiA9PSAzKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMjAsICdJbnRlbCZyZWc7IEFNVCBQaW5nIFJlc3BvbnNlJywgMywgc2hvd1BpbmdBY3Rpb25EbGdPayk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93UGluZ0FjdGlvbkRsZ09rKCkgew0KICAgICAgICAgICAgdmFyIGNsb25lID0gQ2xvbmUoYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZSk7DQogICAgICAgICAgICB2YXIgdiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W25hbWU9ZDIwXTpjaGVja2VkJykudmFsdWU7DQogICAgICAgICAgICBjbG9uZVsiUGluZ1Jlc3BvbnNlRW5hYmxlZCJdID0gKCh2ICYgMSkgIT0gMCk7DQogICAgICAgICAgICBjbG9uZVsiUm1jcFBpbmdSZXNwb25zZUVuYWJsZWQiXSA9ICgodiAmIDIpICE9IDApOw0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCJBTVRfR2VuZXJhbFNldHRpbmdzIiwgY2xvbmUsIFB1bGxTeXN0ZW1TdGF0dXMsIDAsIDEpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0lQU2V0dXBEbGcoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9IGFtdHN5c3N0YXRlWydBTVRfRXRoZXJuZXRQb3J0U2V0dGluZ3MnXS5yZXNwb25zZXNbMF07DQogICAgICAgICAgICBRVignaWRfZDIxbWFudWFsZGl2JywgdHJ1ZSk7DQogICAgICAgICAgICBRVignaWRfZDIxc3VibmV0ZGl2JywgdHJ1ZSk7DQogICAgICAgICAgICBRVignZDIxbzAnLCBmYWxzZSk7DQogICAgICAgICAgICBRVignZDIxbDAnLCBmYWxzZSk7DQogICAgICAgICAgICBRSCgnZDIxbDEnLCAnQXV0b21hdGljIGNvbmZpZ3VyYXRpb24gdXNpbmcgREhDUCBzZXJ2ZXInKTsNCiAgICAgICAgICAgIFFIKCdkMjFsMicsICdTdGF0aWMgY29uZmlndXJhdGlvbiB1c2luZyBJUHY0IHNldHRpbmdzIGJlbG93Jyk7DQogICAgICAgICAgICBkMjFvMS5jaGVja2VkID0gKHhbJ0RIQ1BFbmFibGVkJ10gPT0gdHJ1ZSk7DQogICAgICAgICAgICBkMjFvMi5jaGVja2VkID0gIWQyMW8xLmNoZWNrZWQ7DQogICAgICAgICAgICBpZHhfZDIxYWRkcmVzcy52YWx1ZSA9IGlzSXBBZGRyZXNzKHhbIklQQWRkcmVzcyJdLCcnKTsNCiAgICAgICAgICAgIGlkeF9kMjFzdWJuZXQudmFsdWUgPSBpc0lwQWRkcmVzcyh4WyJTdWJuZXRNYXNrIl0sJycpOw0KICAgICAgICAgICAgaWR4X2QyMWdhdGV3YXkudmFsdWUgPSBpc0lwQWRkcmVzcyh4WyJEZWZhdWx0R2F0ZXdheSJdLCcnKTsNCiAgICAgICAgICAgIGlkeF9kMjFkbnMxLnZhbHVlID0gaXNJcEFkZHJlc3MoeFsiUHJpbWFyeUROUyJdLCcnKTsNCiAgICAgICAgICAgIGlkeF9kMjFkbnMyLnZhbHVlID0gaXNJcEFkZHJlc3MoeFsiU2Vjb25kYXJ5RE5TIl0sJycpOw0KICAgICAgICAgICAgdXBkYXRlSVBTZXR1cERsZygpOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgyMSwgJ0lQdjQgU2V0dGluZ3MnLCAzLCBzaG93SVBTZXR1cERsZ09rKQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXBkYXRlSVBTZXR1cERsZygpIHsNCiAgICAgICAgICAgIGlkeF9kMjFhZGRyZXNzLmRpc2FibGVkID0gaWR4X2QyMXN1Ym5ldC5kaXNhYmxlZCA9IGlkeF9kMjFnYXRld2F5LmRpc2FibGVkID0gaWR4X2QyMWRuczEuZGlzYWJsZWQgPSBpZHhfZDIxZG5zMi5kaXNhYmxlZCA9ICFkMjFvMi5jaGVja2VkOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0lQU2V0dXBEbGdPaygpIHsNCiAgICAgICAgICAgIHZhciB4ID0gQ2xvbmUoYW10c3lzc3RhdGVbJ0FNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyddLnJlc3BvbnNlc1swXSk7DQogICAgICAgICAgICB4WydESENQRW5hYmxlZCddID0gZDIxbzEuY2hlY2tlZDsNCiAgICAgICAgICAgIGRlbGV0ZSB4WyJJUEFkZHJlc3MiXTsNCiAgICAgICAgICAgIGRlbGV0ZSB4WyJTdWJuZXRNYXNrIl07DQogICAgICAgICAgICBkZWxldGUgeFsiRGVmYXVsdEdhdGV3YXkiXTsNCiAgICAgICAgICAgIGRlbGV0ZSB4WyJQcmltYXJ5RE5TIl07DQogICAgICAgICAgICBkZWxldGUgeFsiU2Vjb25kYXJ5RE5TIl07DQogICAgICAgICAgICBpZiAoZDIxbzEuY2hlY2tlZCA9PSBmYWxzZSkgew0KICAgICAgICAgICAgICAgIHhbIklQQWRkcmVzcyJdID0gaWR4X2QyMWFkZHJlc3MudmFsdWU7DQogICAgICAgICAgICAgICAgeFsiU3VibmV0TWFzayJdID0gaWR4X2QyMXN1Ym5ldC52YWx1ZTsNCiAgICAgICAgICAgICAgICB4WyJEZWZhdWx0R2F0ZXdheSJdID0gaWR4X2QyMWdhdGV3YXkudmFsdWU7DQogICAgICAgICAgICAgICAgaWYgKGlkeF9kMjFkbnMxLnZhbHVlICE9ICcnKSB4WyJQcmltYXJ5RE5TIl0gPSBpZHhfZDIxZG5zMS52YWx1ZTsNCiAgICAgICAgICAgICAgICBpZiAoaWR4X2QyMWRuczIudmFsdWUgIT0gJycpIHhbIlNlY29uZGFyeUROUyJdID0gaWR4X2QyMWRuczIudmFsdWU7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBhbXRzdGFjay5QdXQoIkFNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyIsIHgsIHNob3dJUFNldHVwRGxnRG9uZSwgMCwgMSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93SVBTZXR1cERsZ0RvbmUoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gMjAwKSB7DQogICAgICAgICAgICAgICAgYW10c3lzc3RhdGUgPSB1bmRlZmluZWQ7DQogICAgICAgICAgICAgICAgUHVsbFN5c3RlbVN0YXR1cygpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBtZXNzYWdlYm94KCdJUHY0IFNldHRpbmdzJywgJ1VuYWJsZSB0byBzZXQgbmV0d29yayBwYXJhbWV0ZXJzLCBlcnJvciAnICsgc3RhdHVzKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQoNCg0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gU3RvcmFnZQ0KICAgICAgICAvLw0KDQogICAgICAgIHZhciB4eFN0b3JhZ2UgPSBudWxsOw0KICAgICAgICB2YXIgeHhTdG9yYWdlVmVuZG9ycyA9IFtdOw0KICAgICAgICB2YXIgeHhTdG9yYWdlQXBwbGljYXRpb25zID0gW107DQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbFN0b3JhZ2UoKSB7DQogICAgICAgICAgICBhbXRGaXJzdFB1bGwgfD0gODsNCiAgICAgICAgICAgIHdzc3RhY2suY29tbS5QZXJmb3JtQWpheCgiIiwgUHVsbFN0b3JhZ2VSZXNwb25zZSwgbnVsbCwgMCwgIi9hbXQtc3RvcmFnZS8iLCAiR0VUIik7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBQdWxsU3RvcmFnZVJlc3BvbnNlKGRhdGEsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICBpZiAoYW10c3RhY2suUGVuZGluZ0JhdGNoT3BlcmF0aW9ucyA9PSAwKSByZWZyZXNoQnV0dG9ucyh0cnVlKTsgLy8gSWYgbm90aGluZyBpcyBiZWluZyBkb25lLCByZS1lbmFibGUgcmVmcmVzaCBidXR0b25zDQogICAgICAgICAgICANCiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gMjAwKSB7DQogICAgICAgICAgICAgICAgUVYoJ2dvMjEnLCB0cnVlKTsgLy8gU2hvdyBTdG9yYWdlIFBhbmVsDQoNCiAgICAgICAgICAgICAgICB2YXIgbGVuOyAvLyBSZW1vdmUgYWxsIGNoYXJzIHRoYXQgYXJlIGJlbG93IDMyLCB0aGlzIHdpbGwgYWxsb3cgcGFyc2luZyBldmVuIHRoZSB0aGUgZmlybXdhcmUgZ2l2ZXMgdXMgZ2FyYmFnZS4NCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpKyspIHsgZG8geyBsZW4gPSBkYXRhLmxlbmd0aDsgZGF0YSA9IGRhdGEucmVwbGFjZShTdHJpbmcuZnJvbUNoYXJDb2RlKGkpLCAnJyk7IH0gd2hpbGUgKGxlbiA+IGRhdGEubGVuZ3RoKTsgfQ0KICAgICAgICAgICAgICAgIC8vZGF0YSA9ICd7ImluZm9ybWF0aW9uIjogeyJ2ZXJzaW9uIjogMS4xLCJyZWFsbXMiOiA3NzY1NzU5LCJ1c2VyIjogImFkbWluIn0sImNvbnRlbnQiOiBbeyJuYW1lIjogImluZGV4Lmh0bSIsInNpemUiOiAzODg2NH0seyJ2ZW5kb3IiOiAiVXNlciIsImFwcCI6ICJTREsiLCJuYW1lIjogIlNhbXBsZS5odG1sIiwic2l6ZSI6IDI2NzYwLCJsaW5rIjogIlNESyBTYW1wbGUifSx7InZlbmRvciI6ICJVc2VyIiwiYXBwIjogIlNESyIsIm5hbWUiOiAid3MuanMiLCJzaXplIjogNDI1NzUsImxpbmsiOiAiU0RLIFNhbXBsZSJ9LHsidmVuZG9yIjogIlVzZXIiLCJhcHAiOiAiU0RLIiwibmFtZSI6ICJidHAubWluLmNzcyIsInNpemUiOiAxMjEyNjUsImxpbmsiOiAiU0RLIFNhbXBsZSJ9LHsidmVuZG9yIjogIlVzZXIiLCJhcHAiOiAiU0RLIiwibmFtZSI6ICJsb2dvLnBuZyIsInNpemUiOiAyODAzLCJsaW5rIjogIlNESyBTYW1wbGUifV19JzsNCiAgICAgICAgICAgICAgICB0cnkgeyB4eFN0b3JhZ2UgPSBKU09OLnBhcnNlKGRhdGEpOyB9IGNhdGNoIChlKSB7IHJldHVybjsgfQ0KICAgICAgICAgICAgICAgIHh4U3RvcmFnZVZlbmRvcnMgPSBbXTsNCiAgICAgICAgICAgICAgICB4eFN0b3JhZ2VBcHBsaWNhdGlvbnMgPSBbXTsNCiAgICAgICAgICAgICAgICB2YXIgY29udGVudCA9IHh4U3RvcmFnZVsnY29udGVudCddOw0KDQogICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY29udGVudCkpIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gTmV3IGZsYXQgZm9ybWF0LCBjb252ZXJ0IHRvIHRyZWUgZm9ybWF0Lg0KICAgICAgICAgICAgICAgICAgICB2YXIgbmV3Y29udGVudCA9IHt9Ow0KICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIGNvbnRlbnQpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2ZW5kb3IgPSBjb250ZW50W2ldWyJ2ZW5kb3IiXSA/IGNvbnRlbnRbaV1bInZlbmRvciJdIDogJyc7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW5ld2NvbnRlbnRbdmVuZG9yXSkgeyBuZXdjb250ZW50W3ZlbmRvcl0gPSB7fTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFwcCA9IGNvbnRlbnRbaV1bImFwcCJdID8gY29udGVudFtpXVsiYXBwIl0gOiAnJzsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbmV3Y29udGVudFt2ZW5kb3JdW2FwcF0pIHsgbmV3Y29udGVudFt2ZW5kb3JdW2FwcF0gPSB7fTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRbaV1bIm5hbWUiXSkgeyBuZXdjb250ZW50W3ZlbmRvcl1bYXBwXVtjb250ZW50W2ldWyJuYW1lIl1dID0gY29udGVudFtpXTsgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIHh4U3RvcmFnZVsnY29udGVudCddID0gY29udGVudCA9IG5ld2NvbnRlbnQ7DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gVHJlZSBmb3JtYXQsIG1vdmUgaW5kZXguaHRtIGFuZCBsb2dvbi5odG0NCiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRbJ2luZGV4Lmh0bSddIHx8IGNvbnRlbnRbJ2xvZ29uLmh0bSddKSB7IGNvbnRlbnRbJyddID0geyAnJzoge30gfTsgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAoY29udGVudFsnaW5kZXguaHRtJ10pIHsgY29udGVudFsnJ11bJyddWydpbmRleC5odG0nXSA9IGNvbnRlbnRbJ2luZGV4Lmh0bSddOyBkZWxldGUgY29udGVudFsnaW5kZXguaHRtJ107IH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRbJ2xvZ29uLmh0bSddKSB7IGNvbnRlbnRbJyddWycnXVsnbG9nb24uaHRtJ10gPSBjb250ZW50Wydsb2dvbi5odG0nXTsgZGVsZXRlIGNvbnRlbnRbJ2xvZ29uLmh0bSddOyB9DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgLy8gRGlzcGxheSBhbGwgc3RvcmFnZSBmaWxlcw0KICAgICAgICAgICAgICAgIHZhciBjb3VudCA9IDAsIHggPSBUYWJsZVN0YXJ0MigpICsgIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPk1hbmFnZSBJbnRlbCZyZWc7IEFNVCBzdG9yYWdlIGZvciB0aGlzIGNvbXB1dGVyLjxicj48YnI+IjsNCiAgICAgICAgICAgICAgICB2YXIgaWksIGpqLCB4eCA9ICIiLCBsaW5rcyA9ICIiLCBsaW5raWQgPSAzMDsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIGNvbnRlbnQpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGpjb3VudCA9IDA7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gY29udGVudFtpXSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgamNvdW50Kys7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIga2NvdW50ID0gMDsNCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGsgaW4gY29udGVudFtpXVtqXSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtjb3VudCsrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpICE9IGlpIHx8IGogIT0gamopIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHh4ICE9ICIiKSB7IHggKz0geHg7IHh4ID0gIjxicj4iOyB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlpID0gaTsgamogPSBqOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSAhPSAnJykgeyB4eCArPSBFc2NhcGVIdG1sKGkgKyAiIC8gIiArIGopOyB9IGVsc2UgeyB4eCArPSAiUm9vdCIgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3ZhciBoYW5kbGUgPSAiXCIiICsgaSArICJcIixcIiIgKyBqICsgIlwiLFwiIiArIGsgKyAiXCIiOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGUgPSAiXCIiICsgaSArICgoaSAhPSAnJykgPyAnLycgOiAnJykgKyBqICsgKChqICE9ICcnKSA/ICcvJyA6ICcnKSArIGsgKyAiXCIiOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHh4ICs9ICc8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93U3RvcmFnZURldGFpbHMoIicgKyBpICsgJyIsIicgKyBqICsgJyIsIicgKyBrICsgJyIsJyArIGhhbmRsZSArICcpPjxkaXYgc3R5bGU9ZmxvYXQ6cmlnaHQ+JzsNCg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHh4ICs9ICIgIiArIEFkZEJ1dHRvbjIoIk9wZW4iLCAiT3BlbkZyb21TdG9yYWdlKCIgKyBoYW5kbGUgKyAiLGV2ZW50KSIpOw0KDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeHggKz0gIiAiICsgQWRkQnV0dG9uMigiRG93bmxvYWQiLCAiRG93bmxvYWRGcm9tU3RvcmFnZSgiICsgaGFuZGxlICsgIixcIiIgKyBrICsgIlwiLGV2ZW50KSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHh4ICs9ICI8L2Rpdj48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjNweD48Yj4iICsgRXNjYXBlSHRtbChrKSArICI8L2I+LCA8aT4iICsgY29udGVudFtpXVtqXVtrXVsnc2l6ZSddICsgIiBieXRlczwvaT48L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50Kys7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHh4U3RvcmFnZVZlbmRvcnMuaW5kZXhPZihpKSA9PSAtMSkgeHhTdG9yYWdlVmVuZG9ycy5wdXNoKGkpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4eFN0b3JhZ2VBcHBsaWNhdGlvbnMuaW5kZXhPZihqKSA9PSAtMSkgeHhTdG9yYWdlQXBwbGljYXRpb25zLnB1c2goaik7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoa2NvdW50ID09IDApIHsgIC8vIENsZWFyIGVtcHR5IGFwcGxpY2F0aW9uICYgdmVuZG9yDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgd3NzdGFjay5jb21tLlBlcmZvcm1BamF4KCIiLCBmdW5jdGlvbiAoKSB7IH0sIG51bGwsIDAsICIvYW10LXN0b3JhZ2UvIiArIGkgKyAiLyIgKyBqLCAiREVMRVRFIik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgd3NzdGFjay5jb21tLlBlcmZvcm1BamF4KCIiLCBmdW5jdGlvbiAoKSB7IH0sIG51bGwsIDAsICIvYW10LXN0b3JhZ2UvIiArIGksICJERUxFVEUiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAoamNvdW50ID09IDApIHsgd3NzdGFjay5jb21tLlBlcmZvcm1BamF4KCIiLCBmdW5jdGlvbiAoKSB7IH0sIG51bGwsIDAsICIvYW10LXN0b3JhZ2UvIiArIGksICJERUxFVEUiKTsgfSAvLyBDbGVhciBlbXB0eSB2ZW5kb3INCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYgKHh4ICE9ICIiKSB4ICs9IHh4Ow0KICAgICAgICAgICAgICAgIGlmIChjb3VudCA9PSAwKSB7IHggKz0gIjxkaXYgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPjxpPk5vIGZpbGVzIGZvdW5kLjwvaT48L2Rpdj48YnI+IjsgfQ0KICAgICAgICAgICAgICAgIHggKz0gIjxicj48dGQgY2xhc3M9cjE+IiArIFRhYmxlRW5kKEFkZFJlZnJlc2hCdXR0b24oIlB1bGxTdG9yYWdlKCkiKSArIEFkZEJ1dHRvbigiVXBsb2FkLi4uIiwgIlVwbG9hZFRvU3RvcmFnZSgpIikNCiAgICAgICAgICAgICAgICApOw0KICAgICAgICAgICAgICAgIFFIKCdpZF9UYWJsZVN5c3RlbVN0b3JhZ2UnLCB4KTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgUUgoJ2lkX1RhYmxlU3lzdGVtU3RvcmFnZScsICdVbmFibGUgdG8gbG9hZCBzdG9yYWdlIGRhdGEuLi48YnIvPicgKyBBZGRCdXR0b24oIlJlZnJlc2giLCAiUHVsbFN0b3JhZ2UoKSIpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dTdG9yYWdlRGV0YWlscyhpLCBqLCBrLCBoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9ICcnLCBpdGVtID0geHhTdG9yYWdlWydjb250ZW50J11baV1bal1ba107DQogICAgICAgICAgICBpZiAoaSAhPSAnJykgeCArPSBhZGRIdG1sVmFsdWUoIlZlbmRvciIsIGkpOw0KICAgICAgICAgICAgaWYgKGogIT0gJycpIHggKz0gYWRkSHRtbFZhbHVlKCJBcHBsaWNhdGlvbiIsIGopOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIk5hbWUiLCBrKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJTaXplIiwgaXRlbVsnc2l6ZSddICsgJyBieXRlcycpOw0KICAgICAgICAgICAgaWYgKGl0ZW1bJ2xpbmsnXSkgeyB4ICs9IGFkZEh0bWxWYWx1ZSgiTGluayIsIGl0ZW1bJ2xpbmsnXSk7IH0NCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdTdG9yYWdlIEl0ZW0nLCA1LCBzaG93U3RvcmFnZURldGFpbHNFeCwgeCwgaCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93U3RvcmFnZURldGFpbHNFeChidXR0b25zLCBoYW5kbGUpIHsNCiAgICAgICAgICAgIGlmIChidXR0b25zID09IDIpIHsgd3NzdGFjay5jb21tLlBlcmZvcm1BamF4KCIiLCBzdG9yYWdlRGVsZXRlUmVzcG9uc2UsIG51bGwsIDAsICcvYW10LXN0b3JhZ2UvJyArIGhhbmRsZSwgIkRFTEVURSIpOyB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzdG9yYWdlRGVsZXRlUmVzcG9uc2UoZGF0YSwgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgew0KICAgICAgICAgICAgICAgIG1lc3NhZ2Vib3goIlN0b3JhZ2UiLCAiVW5hYmxlIHRvIGRlbGV0ZSBmaWxlIChFUlIiICsgc3RhdHVzICsgIiksIGNoZWNrIHRoYXQgdGhlIGNvbXB1dGVyIGlzIHBvd2VyZWQgb24uIik7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFB1bGxTdG9yYWdlKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KDQogICAgICAgIGZ1bmN0aW9uIERvd25sb2FkRnJvbVN0b3JhZ2UoaGFuZGxlLCBmaWxlbmFtZSwgZSkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgaGFsdEV2ZW50KGUpOw0KICAgICAgICAgICAgd3NzdGFjay5jb21tLlBlcmZvcm1BamF4KCIiLCBEb3dubG9hZEZyb21TdG9yYWdlRXgsIGZpbGVuYW1lLCAwLCAnL2FtdC1zdG9yYWdlLycgKyBoYW5kbGUsICJHRVQiKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIERvd25sb2FkRnJvbVN0b3JhZ2VFeChkYXRhLCBzdGF0dXMsIHRhZykgew0KICAgICAgICAgICAgaWYgKChzdGF0dXMgIT0gMjAwKSB8fCAoZGF0YSA9PSBudWxsKSkgeyBjb25zb2xlLmxvZyhzdGF0dXMsICdEYXRhID0gbnVsbCcpOyByZXR1cm47IH0NCiAgICAgICAgICAgIHNhdmVBcyhkYXRhMmJsb2IoZGF0YSksIHRhZyk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBPcGVuRnJvbVN0b3JhZ2UoaGFuZGxlLCBlKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQoNCiAgICAgICAgICAgIHZhciBuZXdXaW5kb3cgPSB3aW5kb3cub3BlbignaHR0cDovLycgKyB3c3N0YWNrLmNvbW0uaG9zdCArICc6JyArIHdzc3RhY2suY29tbS5wb3J0ICsgJy9hbXQtc3RvcmFnZS8nICsgaGFuZGxlLCAnX2JsYW5rJyk7DQogICAgICAgICAgICBuZXdXaW5kb3cub3BlbmVyID0gbnVsbDsNCiAgICAgICAgICAgIG5ld1dpbmRvdy5mb2N1cygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gUHVzaFRvU3RvcmFnZSh2ZW5kb3JBcHBuYW1lRmlsZW5hbWUsIGRhdGEsIGFwcGVuZCkgew0KICAgICAgICAgICAgdmFyIHRhZyA9IG51bGw7DQogICAgICAgICAgICBpZiAoZGF0YS5sZW5ndGggPiA3MDAwKSB7IHRhZyA9IFt2ZW5kb3JBcHBuYW1lRmlsZW5hbWUsIGRhdGEuc3Vic3RyaW5nKDcwMDApXTsgZGF0YSA9IGRhdGEuc3Vic3RyaW5nKDAsIDcwMDApOyB9DQogICAgICAgICAgICB3c3N0YWNrLmNvbW0uUGVyZm9ybUFqYXgoZGF0YSwgUHVzaFRvU3RvcmFnZVJlc3BvbnNlLCB0YWcsIDAsICIvYW10LXN0b3JhZ2UvIiArIHZlbmRvckFwcG5hbWVGaWxlbmFtZSArIChhcHBlbmQgPT0gdHJ1ZSA/ICI/YXBwZW5kPSIgOiAiIiksICJQVVQiKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIFB1c2hUb1N0b3JhZ2VSZXNwb25zZShkYXRhLCBzdGF0dXMsIHRhZykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsgbWVzc2FnZWJveCgiU3RvcmFnZSIsICJVbmFibGUgdG8gcHVzaCBmaWxlIChFUlIiICsgc3RhdHVzICsgIiksIGNoZWNrIHRoYXQgdGhlIGNvbXB1dGVyIGlzIHBvd2VyZWQgb24uIik7IH0gZWxzZSB7DQogICAgICAgICAgICAgICAgaWYgKHRhZyAhPSBudWxsKSB7IFB1c2hUb1N0b3JhZ2UodGFnWzBdLCB0YWdbMV0sIHRydWUpOyB9IGVsc2UgeyBQdWxsU3RvcmFnZSgpOyB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBVcGxvYWRUb1N0b3JhZ2UoZmlsZSwgZmlsZW5hbWUpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIGlmICghZmlsZW5hbWUpIHsgZmlsZW5hbWUgPSAnJzsgfQ0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gJzxicj5TZWxlY3QgYSBzbWFsbCBmaWxlIHRvIHVwbG9hZCB0byBzdG9yYWdlIGFuZCBlbnRlciBhIHZlbmRvciwgYXBwbGljYXRpb24gYW5kIGZpbGVuYW1lLjxicj4nOw0KICAgICAgICAgICAgaWYgKCFmaWxlKSB7DQogICAgICAgICAgICAgICAgeCArPSAnPGJyPjxkaXYgc3R5bGU9aGVpZ2h0OjIwcHg+PGlucHV0IHR5cGU9ZmlsZSBpZD1tc3RvcmFnZWZpbGUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjQwcHggb25jaGFuZ2U9U2V0U3RvcmFnZU5hbWUoKT48ZGl2PlVwbG9hZCBmaWxlPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgeCArPSAnPGJyPjxkaXYgc3R5bGU9aGVpZ2h0OjIwcHg+PGlucHV0IGlkPW1zdG9yYWdlZmlsZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNDBweCByZWFkb25seSBkaXNhYmxlZD1kaXNhYmxlZCB2YWx1ZT0iJyArIGZpbGVuYW1lICsgJyIgPjxkaXY+VXBsb2FkIGZpbGU8L2Rpdj48L2Rpdj4nOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSAnPGJyPjxkaXYgc3R5bGU9aGVpZ2h0OjE2cHg+PGlucHV0IGlkPW1zdG9yYWdldmVuZG9yIHBsYWNlaG9sZGVyPVZlbmRvciBsaXN0PW1zdG9yYWdldmVuZG9ybGlzdCBtYXhsZW5ndGg9MTEgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjQwcHg+PGRpdj5WZW5kb3IgbmFtZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8YnI+PGRpdiBzdHlsZT1oZWlnaHQ6MTZweD48aW5wdXQgaWQ9bXN0b3JhZ2VhcHBsaWNhdGlvbiBwbGFjZWhvbGRlcj1BcHAgbGlzdD1tc3RvcmFnZWFwcGxpY2F0aW9ubGlzdCBtYXhsZW5ndGg9MTEgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjQwcHg+PGRpdj5BcHBsaWNhdGlvbiBuYW1lPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gJzxicj48ZGl2IHN0eWxlPWhlaWdodDoxNnB4PjxpbnB1dCBpZD1tc3RvcmFnZWZpbGVuYW1lIHBsYWNlaG9sZGVyPUZpbGVuYW1lIG1heGxlbmd0aD0xMSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNDBweD48ZGl2PkZpbGVuYW1lPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gJzxicj48ZGl2IHN0eWxlPWhlaWdodDoxNnB4PjxpbnB1dCBpZD1tc3RvcmFnZXR5cGUgcGxhY2Vob2xkZXI9YXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIGxpc3Q9bXN0b3JhZ2V0eXBlbGlzdCBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNDBweD48ZGl2Pk1JTUUgVHlwZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8YnI+PGRpdiBzdHlsZT1oZWlnaHQ6MTZweD48aW5wdXQgaWQ9bXN0b3JhZ2VsaW5rIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI0MHB4PjxkaXYgdGl0bGU9IklmIHNldCwgY3JlYXRlcyBhIGxpbmsgdG8gdGhpcyBjb250ZW50IGZyb20gdGhlIG1haW4gd2ViIHBhZ2UiPkxpbms8L2Rpdj48L2Rpdj48YnI+JzsNCiAgICAgICAgICAgIHggKz0gJzxkYXRhbGlzdCBpZD1tc3RvcmFnZXZlbmRvcmxpc3Q+JzsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhTdG9yYWdlVmVuZG9ycykgeyB4ICs9ICc8b3B0aW9uIHZhbHVlPSInICsgeHhTdG9yYWdlVmVuZG9yc1tpXSArICciPic7IH0NCiAgICAgICAgICAgIHggKz0gJzwvZGF0YWxpc3Q+JzsNCiAgICAgICAgICAgIHggKz0gJzxkYXRhbGlzdCBpZD1tc3RvcmFnZWFwcGxpY2F0aW9ubGlzdD4nOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eFN0b3JhZ2VBcHBsaWNhdGlvbnMpIHsgeCArPSAnPG9wdGlvbiB2YWx1ZT0iJyArIHh4U3RvcmFnZUFwcGxpY2F0aW9uc1tpXSArICciPic7IH0NCiAgICAgICAgICAgIHggKz0gJzwvZGF0YWxpc3Q+PGRhdGFsaXN0IGlkPW1zdG9yYWdldHlwZWxpc3Q+PG9wdGlvbiB2YWx1ZT0iYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIj48b3B0aW9uIHZhbHVlPSJpbWFnZS9qcGVnIj48b3B0aW9uIHZhbHVlPSJ0ZXh0L2h0bWwiPjxvcHRpb24gdmFsdWU9InRleHQvcGxhaW4iPjwvZGF0YWxpc3Q+JzsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdTdG9yYWdlIFVwbG9hZCcsIDMsIFVwbG9hZFRvU3RvcmFnZUV4LCB4LCBmaWxlKTsNCiAgICAgICAgICAgIGlmIChmaWxlKSB7IFNldFN0b3JhZ2VOYW1lKGZpbGVuYW1lKTsgfQ0KICAgICAgICB9DQoNCg0KICAgICAgICBmdW5jdGlvbiBVcGxvYWRUb1N0b3JhZ2VFeChidXR0b24sIHRhZykgew0KICAgICAgICAgICAgaWYgKCF0YWcpIHsNCiAgICAgICAgICAgICAgICB2YXIgeCA9IFEoJ21zdG9yYWdlZmlsZScpOw0KICAgICAgICAgICAgICAgIGlmICh4LmZpbGVzLmxlbmd0aCAhPSAxKSByZXR1cm47DQogICAgICAgICAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7DQogICAgICAgICAgICAgICAgcmVhZGVyLm9ubG9hZCA9IFVwbG9hZFRvU3RvcmFnZUV4MjsNCiAgICAgICAgICAgICAgICByZWFkZXIuZmlsZW5hbWUgPSB4LmZpbGVzWzBdLm5hbWU7DQogICAgICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyh4LmZpbGVzWzBdKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7DQogICAgICAgICAgICAgICAgcmVhZGVyLm9ubG9hZCA9IFVwbG9hZFRvU3RvcmFnZUV4MjsNCiAgICAgICAgICAgICAgICByZWFkZXIuZmlsZW5hbWUgPSBRKCdtc3RvcmFnZWZpbGUnKS52YWx1ZTsNCiAgICAgICAgICAgICAgICByZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKHRhZyk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBTZXRTdG9yYWdlTmFtZShmaWxlbmFtZSkgew0KICAgICAgICAgICAgaWYgKCFmaWxlbmFtZSkgew0KICAgICAgICAgICAgICAgIHZhciB4ID0gUSgnbXN0b3JhZ2VmaWxlJyk7DQogICAgICAgICAgICAgICAgaWYgKHguZmlsZXMubGVuZ3RoID09IDEpIHsgZmlsZW5hbWUgPSB4LmZpbGVzWzBdLm5hbWU7IH0gZWxzZSB7IGZpbGVuYW1lID0gJyc7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGZpbGVuYW1lID0gZmlsZW5hbWUuc3BsaXQoJyAnKS5qb2luKCcnKTsNCiAgICAgICAgICAgIHZhciBmaWxlbmFtZVNwbGl0ID0gZmlsZW5hbWUuc3BsaXQoJy0nKTsNCiAgICAgICAgICAgIGlmIChmaWxlbmFtZVNwbGl0Lmxlbmd0aCA9PSAzICYmIGZpbGVuYW1lU3BsaXRbMF0ubGVuZ3RoIDwgMTIgJiYgZmlsZW5hbWVTcGxpdFsxXS5sZW5ndGggPCAxMikgew0KICAgICAgICAgICAgICAgIFEoJ21zdG9yYWdldmVuZG9yJykudmFsdWUgPSBmaWxlbmFtZVNwbGl0WzBdOw0KICAgICAgICAgICAgICAgIFEoJ21zdG9yYWdlYXBwbGljYXRpb24nKS52YWx1ZSA9IGZpbGVuYW1lU3BsaXRbMV07DQogICAgICAgICAgICAgICAgZmlsZW5hbWUgPSBmaWxlbmFtZVNwbGl0WzJdOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZmlsZW5hbWUgPSBmaWxlbmFtZS5zcGxpdCgnLScpLmpvaW4oJycpOw0KICAgICAgICAgICAgaWYgKGZpbGVuYW1lLmVuZHNXaXRoKCcuZ3onKSkgZmlsZW5hbWUgPSBmaWxlbmFtZS5zdWJzdHJpbmcoMCwgZmlsZW5hbWUubGVuZ3RoIC0gMyk7DQogICAgICAgICAgICBpZiAoZmlsZW5hbWUuZW5kc1dpdGgoJy5odG0nKSB8fCBmaWxlbmFtZS5lbmRzV2l0aCgnLmh0bWwnKSkgUSgnbXN0b3JhZ2V0eXBlJykudmFsdWUgPSAidGV4dC9odG1sIjsNCiAgICAgICAgICAgIGVsc2UgaWYgKGZpbGVuYW1lLmVuZHNXaXRoKCcudHh0JykpIFEoJ21zdG9yYWdldHlwZScpLnZhbHVlID0gInRleHQvcGxhaW4iOw0KICAgICAgICAgICAgaWYgKGZpbGVuYW1lLmxlbmd0aCA+IDExKSBmaWxlbmFtZSA9IGZpbGVuYW1lLnN1YnN0cmluZygwLCAxMSk7DQogICAgICAgICAgICBRKCdtc3RvcmFnZWZpbGVuYW1lJykudmFsdWUgPSBmaWxlbmFtZTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIFVwbG9hZFRvU3RvcmFnZUV4MihmaWxlKSB7DQogICAgICAgICAgICB2YXIgdmFmLCB2ZW5kb3IgPSBRKCdtc3RvcmFnZXZlbmRvcicpLnZhbHVlOw0KICAgICAgICAgICAgdmFyIGFwcCA9IFEoJ21zdG9yYWdlYXBwbGljYXRpb24nKS52YWx1ZTsNCiAgICAgICAgICAgIHZhciBmaWxlbmFtZSA9IFEoJ21zdG9yYWdlZmlsZW5hbWUnKS52YWx1ZTsNCiAgICAgICAgICAgIGlmIChmaWxlbmFtZSA9PSAnJykgZmlsZW5hbWUgPSAnRmlsZW5hbWUnOw0KICAgICAgICAgICAgdmFyIG1pbWV0eXBlID0gUSgnbXN0b3JhZ2V0eXBlJykudmFsdWU7DQogICAgICAgICAgICBpZiAobWltZXR5cGUgPT0gJycpIG1pbWV0eXBlID0gJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSc7DQogICAgICAgICAgICB2YXIgbGluayA9IFEoJ21zdG9yYWdlbGluaycpLnZhbHVlOw0KICAgICAgICAgICAgaWYgKHZlbmRvciA9PSAnJyAmJiBhcHAgPT0gJycgJiYgKGZpbGVuYW1lLnRvTG93ZXJDYXNlKCkgPT0gJ2xvZ29uLmh0bScgfHwgZmlsZW5hbWUudG9Mb3dlckNhc2UoKSA9PSAnaW5kZXguaHRtJykpIHsNCiAgICAgICAgICAgICAgICB2YWYgPSBmaWxlbmFtZS50b0xvd2VyQ2FzZSgpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBpZiAodmVuZG9yID09ICcnKSB2ZW5kb3IgPSAnVmVuZG9yJzsNCiAgICAgICAgICAgICAgICBpZiAoYXBwID09ICcnKSBhcHAgPSAnQXBwJzsNCiAgICAgICAgICAgICAgICB2YWYgPSB2ZW5kb3IgKyAiLyIgKyBhcHAgKyAiLyIgKyBmaWxlbmFtZTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgdmFyIGRhdGEgPSAiPG1ldGFkYXRhPjxoZWFkZXJzPiI7DQogICAgICAgICAgICB2YXIgZmlsZW5hbWUgPSBmaWxlLnRhcmdldC5maWxlbmFtZTsNCiAgICAgICAgICAgIGlmICghZmlsZW5hbWUpIHsgZmlsZW5hbWUgPSBRKCdtc3RvcmFnZWZpbGUnKS5maWxlc1swXS5uYW1lOyB9DQogICAgICAgICAgICBpZiAoZmlsZW5hbWUuZW5kc1dpdGgoJy5neicpKSB7IGRhdGEgKz0gIjxoPkNvbnRlbnQtRW5jb2Rpbmc6IGd6aXA8L2g+IjsgfQ0KICAgICAgICAgICAgZGF0YSArPSAiPGg+Q29udGVudC1UeXBlOiAiICsgbWltZXR5cGUgKyAiPC9oPjwvaGVhZGVycz4iOyAvLyA8aD5YLVVBLUNvbXBhdGlibGU6IElFPUVkZ2U8L2g+DQogICAgICAgICAgICBpZiAobGluayAhPSAnJykgZGF0YSArPSAiPGxpbms+IiArIGxpbmsgKyAiPC9saW5rPiI7DQogICAgICAgICAgICBkYXRhICs9ICI8L21ldGFkYXRhPiIgKyBmaWxlLnRhcmdldC5yZXN1bHQ7DQoNCiAgICAgICAgICAgIFB1c2hUb1N0b3JhZ2UodmFmLCBkYXRhKTsNCiAgICAgICAgfQ0KDQoNCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIEFsYXJtIFBhbmVsDQogICAgICAgIC8vDQoNCiAgICAgICAgZnVuY3Rpb24gX2ZtdGRhdGV0aW1lKHN0cikgew0KICAgICAgICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKCJUIiwiICIpLnJlcGxhY2UoIloiLCIiKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIF9mbXRpbnRlcnZhbChzdHIpIHsNCiAgICAgICAgICAgIHZhciBjbCA9IHN0ci5yZXBsYWNlKCJUIiwgIiIpLnN1YnN0cmluZyhzdHIuaW5kZXhPZignUCcpICsgMSk7DQogICAgICAgICAgICBjbCA9ICcgJyArIGNsLnJlcGxhY2UoIkQiLCAiIGRheXMgIikucmVwbGFjZSgiSCIsICIgaG91cnMgIikucmVwbGFjZSgiTSIsIiBtaW51dGVzICIpOw0KICAgICAgICAgICAgY2wgPSBjbC5yZXBsYWNlKCIgMSBkYXlzICIsICIgMSBkYXkgIikucmVwbGFjZSgiIDEgaG91cnMgIiwgIiAxIGhvdXIgIikucmVwbGFjZSgiIDEgbWludXRlcyAiLCIgMSBtaW51dGUgIik7DQogICAgICAgICAgICByZXR1cm4gY2wuc3Vic3RyaW5nKDAsIGNsLmxlbmd0aCAtIDEpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gX2ZtdHRpbWVwYWQoc3RyKSB7DQogICAgICAgICAgICBzdHIgPSAnJyArIHN0cjsNCiAgICAgICAgICAgIHdoaWxlIChzdHIubGVuZ3RoIDwgMikgeyBzdHIgPSAnMCcgKyBzdHI7IH0NCiAgICAgICAgICAgIHJldHVybiBzdHI7DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgeHhBbGFybXMgPSBudWxsOw0KDQogICAgICAgIGZ1bmN0aW9uIFB1bGxBbGFybXMoKSB7DQogICAgICAgICAgICB2YXIgeCA9IFRhYmxlU3RhcnQyKCkgKyAiPHRyPjx0ZCBjbGFzcz1yMSBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweD48YnI+TWFuYWdlIHdha2UgYWxhcm1zLjxicj48YnI+Ig0KICAgICAgICAgICAgYW10c3RhY2suRW51bSgiSVBTX0FsYXJtQ2xvY2tPY2N1cnJlbmNlIiwgZnVuY3Rpb24oc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCkgew0KICAgICAgICAgICAgICAgICAgICBRVigiZ28yMyIsIHRydWUpOw0KICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UubGVuZ3RoID4gMCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgeHhBbGFybXMgPSByZXNwb25zZTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzcG9uc2UubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2FrZXRpbWUgPSBuZXcgRGF0ZShyZXNwb25zZVtpXVsiU3RhcnRUaW1lIl1bIkRhdGV0aW1lIl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZXRhaWxzID0gJzxiPicgKyByZXNwb25zZVtpXVsiRWxlbWVudE5hbWUiXSArICc8L2I+LCB3YWtlIG9uICcgKyB3YWtldGltZS50b0xvY2FsZVN0cmluZygpLnJlcGxhY2UoJywgJywgJyBhdCAnKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2VbaV1bIkludGVydmFsIl0gIT0gdW5kZWZpbmVkKSB7IGRldGFpbHMgKz0gJyBhbmQgZWFjaCcgKyBfZm10aW50ZXJ2YWwocmVzcG9uc2VbaV1bIkludGVydmFsIl1bIkludGVydmFsIl0pOyB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlW2ldWyJEZWxldGVPbkNvbXBsZXRpb24iXSA9PSB0cnVlKSB7IGRldGFpbHMgKz0gJywgZGVsZXRlIHdoZW4gZG9uZSc7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93QWxlcnREZXRhaWxzKCIgKyBpICsgIik+PGRpdiBzdHlsZT1mbG9hdDpyaWdodD4iOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHggKz0gIiAiICsgQWRkQnV0dG9uMigiRWRpdC4uLiIsICJzaG93QWRkQWxhcm0oIiArIGkgKyAiKSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gIjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4O3dpZHRoOmF1dG87ZmxvYXQ6bGVmdDtvdmVyZmxvdy14OmhpZGRlbj4iICsgZGV0YWlscyArICI8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgeHhBbGFybXMgPSBudWxsOw0KICAgICAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweD48YnI+PGk+Tm8gd2FrZSBhbGFybXMgcmVnaXN0ZXJlZC48L2k+PC9kaXY+PGJyPiI7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgdmFyIHkgPSAiPGRpdj4mbmJzcDsiICsgQWRkUmVmcmVzaEJ1dHRvbigiUHVsbEFsYXJtcygpIik7DQogICAgICAgICAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHsgeSArPSBBZGRCdXR0b24oIlJlbW92ZSBhbGwgYWxhcm1zIiwgIlJlbW92ZUFsbEFsYXJtcygpIikgKyBBZGRCdXR0b24oIkFkZCIsICJzaG93QWRkQWxhcm0oKSIpOyB9DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjxicj48dGQgY2xhc3M9cjE+IiArIFRhYmxlRW5kKHkgKyAiPC9kaXY+Iik7DQogICAgICAgICAgICAgICAgICAgIFFIKCdpZF9UYWJsZUFsYXJtJywgeCk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwgbnVsbCwgdHJ1ZSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBwcmVwYXJlQWxhcm1PY2N1cmVuY2VUZW1wbGF0ZShpZCwgbm0sIHN0YXJ0LCBpbnRlcnZhbCwgZGVsKSB7DQogICAgICAgICAgICByZXR1cm4gIjxkOkFsYXJtVGVtcGxhdGUgeG1sbnM6ZD1cImh0dHA6Ly9pbnRlbC5jb20vd2JlbS93c2NpbS8xL2FtdC1zY2hlbWEvMS9BTVRfQWxhcm1DbG9ja1NlcnZpY2VcIiB4bWxuczpzPVwiaHR0cDovL2ludGVsLmNvbS93YmVtL3dzY2ltLzEvaXBzLXNjaGVtYS8xL0lQU19BbGFybUNsb2NrT2NjdXJyZW5jZVwiPjxzOkluc3RhbmNlSUQ+IiArIGlkICsgIjwvczpJbnN0YW5jZUlEPjxzOlN0YXJ0VGltZT48cDpEYXRldGltZSB4bWxuczpwPVwiaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NvbW1vblwiPiIgKyBzdGFydCArICI8L3A6RGF0ZXRpbWU+PC9zOlN0YXJ0VGltZT48czpJbnRlcnZhbD48cDpJbnRlcnZhbCB4bWxuczpwPVwiaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NvbW1vblwiPiIgKyBpbnRlcnZhbCArICI8L3A6SW50ZXJ2YWw+PC9zOkludGVydmFsPjxzOkRlbGV0ZU9uQ29tcGxldGlvbj4iICsgZGVsICsgIjwvczpEZWxldGVPbkNvbXBsZXRpb24+PC9kOkFsYXJtVGVtcGxhdGU+IjsNCiAgICAgICAgfQ0KICAgICAgICANCiAgICAgICAgZnVuY3Rpb24gUmVtb3ZlQWxsQWxhcm1zKCl7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDEsICJSZW1vdmUgYWxsIHdha2UgYWxhcm1zIiwgMywgUmVtb3ZlQWxsQWxhcm1zRXgsICJDb25maXJtIHJlbW92YWwgb2YgYWxsIHdha2UgYWxhcm1zPyIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gUmVtb3ZlQWxsQWxhcm1zRXgoKSB7DQogICAgICAgICAgICB2YXIgZGVsZXRlQ291bnQgPSB4eEFsYXJtcy5sZW5ndGg7DQogICAgICAgICAgICBmb3IgKHZhciBhIGluIHh4QWxhcm1zKSB7IGFtdHN0YWNrLkRlbGV0ZSgiSVBTX0FsYXJtQ2xvY2tPY2N1cnJlbmNlIiwgeHhBbGFybXNbYV0sIGZ1bmN0aW9uKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7IGlmICgtLWRlbGV0ZUNvdW50ID09IDApIHsgUHVsbEFsYXJtcygpOyB9fSk7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dBZGRBbGFybShhbHJtKXsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIFFFKCdkMjVhbGFybV9uYW1lJywgIWFscm0pOw0KICAgICAgICAgICAgaWYgKGFscm0gIT0gdW5kZWZpbmVkKSB7DQogICAgICAgICAgICAgICAgdmFyIGFsYXJtID0geHhBbGFybXNbYWxybV0sIHdha2V0aW1lID0gbmV3IERhdGUoYWxhcm1bIlN0YXJ0VGltZSJdWyJEYXRldGltZSJdKTsNCiAgICAgICAgICAgICAgICBRKCdkMjVhbGFybV9uYW1lJykudmFsdWUgPSBhbGFybVsiRWxlbWVudE5hbWUiXTsNCiAgICAgICAgICAgICAgICBRKCdkMjVhbGFybV9zZGF0ZScpLnZhbHVlID0gd2FrZXRpbWUuZ2V0RnVsbFllYXIoKSArICctJyArIF9mbXR0aW1lcGFkKHdha2V0aW1lLmdldE1vbnRoKCkgKyAxKSArICctJyArIF9mbXR0aW1lcGFkKHdha2V0aW1lLmdldERhdGUoKSk7DQogICAgICAgICAgICAgICAgUSgnZDI1YWxhcm1fc3RpbWUnKS52YWx1ZSA9IHdha2V0aW1lLmdldEhvdXJzKCkgKyAnOicgKyBfZm10dGltZXBhZCh3YWtldGltZS5nZXRNaW51dGVzKCkpICsgJzonICsgX2ZtdHRpbWVwYWQod2FrZXRpbWUuZ2V0U2Vjb25kcygpKTsNCiAgICAgICAgICAgICAgICBpZiAoYWxhcm1bIkludGVydmFsIl0pIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGogPSBhbGFybVsiSW50ZXJ2YWwiXVsiSW50ZXJ2YWwiXS5yZXBsYWNlKCdQJywnJykucmVwbGFjZSgnVCcsJycpLnJlcGxhY2UoJ0QnLCdELCcpLnJlcGxhY2UoJ0gnLCdILCcpLnJlcGxhY2UoJ00nLCdNLCcpLnNwbGl0KCcsJyksIGsgPSBbMCwgMCwgMF07DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gaikgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGpsID0galtpXS5sZW5ndGggLSAxOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGpbaV1bamxdID09ICdEJykgeyBrWzBdID0gcGFyc2VJbnQoaltpXS5zdWJzdHJpbmcoMCwgamwpKTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGpbaV1bamxdID09ICdIJykgeyBrWzFdID0gcGFyc2VJbnQoaltpXS5zdWJzdHJpbmcoMCwgamwpKTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGpbaV1bamxdID09ICdNJykgeyBrWzJdID0gcGFyc2VJbnQoaltpXS5zdWJzdHJpbmcoMCwgamwpKTsgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIFEoJ2QyNWFsYXJtX2ludGVydmFsJykudmFsdWUgPSBrLmpvaW4oJy0nKTsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBRKCdkMjVhbGFybV9pbnRlcnZhbCcpLnZhbHVlID0gJyc7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIFEoJ2QyNWFsYXJtX2RvYycpLnZhbHVlID0gKGFsYXJtWyJEZWxldGVPbkNvbXBsZXRpb24iXSA9PSB0cnVlKT8xOjA7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHZhciBjdXJyZW50VGltZSA9IG5ldyBEYXRlKCk7DQogICAgICAgICAgICAgICAgY3VycmVudFRpbWUuc2V0RGF0ZShuZXcgRGF0ZSgpLmdldERhdGUoKSArIDEpOw0KICAgICAgICAgICAgICAgIFEoJ2QyNWFsYXJtX25hbWUnKS52YWx1ZSA9ICcnOw0KICAgICAgICAgICAgICAgIFEoJ2QyNWFsYXJtX3NkYXRlJykudmFsdWUgPSBjdXJyZW50VGltZS5nZXRGdWxsWWVhcigpICsgJy0nICsgX2ZtdHRpbWVwYWQoY3VycmVudFRpbWUuZ2V0TW9udGgoKSArIDEpICsgJy0nICsgX2ZtdHRpbWVwYWQoY3VycmVudFRpbWUuZ2V0RGF0ZSgpKTsNCiAgICAgICAgICAgICAgICBRKCdkMjVhbGFybV9zdGltZScpLnZhbHVlID0gY3VycmVudFRpbWUuZ2V0SG91cnMoKSArICc6JyArIF9mbXR0aW1lcGFkKGN1cnJlbnRUaW1lLmdldE1pbnV0ZXMoKSkgKyAnOjAwJzsNCiAgICAgICAgICAgICAgICBRKCdkMjVhbGFybV9pbnRlcnZhbCcpLnZhbHVlID0gJyc7DQogICAgICAgICAgICAgICAgUSgnZDI1YWxhcm1fZG9jJykudmFsdWUgPSAwOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgyNSwgIkFkZCBuZXcgYWxhcm0iLCAoYWxybSAhPSB1bmRlZmluZWQpPzc6Mywgc2hvd0FkZEFsYXJtT2ssICcnLCBhbHJtKTsNCiAgICAgICAgICAgIGFsZXJ0RGlhbG9nVXBkYXRlKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBhbGVydERpYWxvZ1VwZGF0ZSgpIHsNCiAgICAgICAgICAgIHZhciBpbCA9IFEoJ2QyNWFsYXJtX2ludGVydmFsJykudmFsdWUuc3BsaXQoJy0nKS5sZW5ndGg7DQogICAgICAgICAgICB2YXIgb2sgPSAoUSgnZDI1YWxhcm1fbmFtZScpLnZhbHVlLmxlbmd0aCA+IDApICYmIChRKCdkMjVhbGFybV9zZGF0ZScpLnZhbHVlLnNwbGl0KCctJykubGVuZ3RoID09IDMpICYmIChRKCdkMjVhbGFybV9zdGltZScpLnZhbHVlLnNwbGl0KCc6JykubGVuZ3RoID09IDMpICYmICgoaWwgPT0gMSkgfHwgKGlsID09IDMpKTsNCiAgICAgICAgICAgIFFFKCdpZHhfZGxnT2tCdXR0b24nLCBvayk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93QWRkQWxhcm1PayhidXR0b24sIGFscm0pIHsNCiAgICAgICAgICAgIGlmIChidXR0b24gPT0gMikgeyBzaG93QWxlcnREZXRhaWxzRGVsZXRlKGJ1dHRvbiwgYWxybSk7IHJldHVybjsgfQ0KICAgICAgICAgICAgdmFyIGFsYXJtX25hbWUgPSBRKCdkMjVhbGFybV9uYW1lJykudmFsdWU7DQogICAgICAgICAgICB2YXIgeDEgPSBRKCdkMjVhbGFybV9zZGF0ZScpLnZhbHVlLnNwbGl0KCctJyk7DQogICAgICAgICAgICB2YXIgeDIgPSBRKCdkMjVhbGFybV9zdGltZScpLnZhbHVlLnNwbGl0KCc6Jyk7DQogICAgICAgICAgICB2YXIgdCA9IG5ldyBEYXRlKHgxWzBdLCB4MVsxXSAtIDEsIHgxWzJdLCB4MlswXSwgeDJbMV0sIHgyWzJdLCAwKTsgLy8gTm90IHN1cmUgd2h5LCBidXQgbW9udGggaXMgMCA9IEpBTiwgMTEgPSBERUMNCiAgICAgICAgICAgIHZhciBhbGFybV9zdGFydHRpbWUgPSBfZm10dGltZXBhZCh0LmdldFVUQ0Z1bGxZZWFyKCkpICsgJy0nICsgX2ZtdHRpbWVwYWQodC5nZXRVVENNb250aCgpICsgMSkgKyAnLScgKyBfZm10dGltZXBhZCh0LmdldFVUQ0RhdGUoKSkgKyAnVCcgKyBfZm10dGltZXBhZCh0LmdldFVUQ0hvdXJzKCkpICsgJzonICsgX2ZtdHRpbWVwYWQodC5nZXRVVENNaW51dGVzKCkpICsgJzonICsgX2ZtdHRpbWVwYWQodC5nZXRVVENTZWNvbmRzKCkpICsgJ1onOw0KICAgICAgICAgICAgdmFyIHggPSBRKCdkMjVhbGFybV9pbnRlcnZhbCcpLnZhbHVlLnNwbGl0KCctJyk7DQogICAgICAgICAgICBpZiAoeC5sZW5ndGggIT0gMykgeyB4ID0gWzAsIDAsIDBdOyB9DQogICAgICAgICAgICB2YXIgYWxhcm1faW50ZXJ2YWwgPSAnUCcgKyB4WzBdICsgJ0RUJyArIHhbMV0gKyAnSCcgKyB4WzJdICsgJ00nOw0KICAgICAgICAgICAgdmFyIGFsYXJtX2RvYyA9IChRKCdkMjVhbGFybV9kb2MnKS52YWx1ZSA9PSAxKTsNCiAgICAgICAgICAgIHZhciB0cGwgPSBwcmVwYXJlQWxhcm1PY2N1cmVuY2VUZW1wbGF0ZShhbGFybV9uYW1lLCBhbGFybV9uYW1lLCBhbGFybV9zdGFydHRpbWUsIGFsYXJtX2ludGVydmFsLCBhbGFybV9kb2MpOw0KICAgICAgICAgICAgaWYgKGFscm0gPT0gdW5kZWZpbmVkKSB7DQogICAgICAgICAgICAgICAgd3NzdGFjay5FeGVjTWV0aG9kWG1sKGFtdHN0YWNrLkNvbXBsZXRlTmFtZSgiQU1UX0FsYXJtQ2xvY2tTZXJ2aWNlIiksICJBZGRBbGFybSIsIHRwbCwNCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goJ0FkZCBhbGFybScsICdGYWlsZWQgdG8gYWRkIGFsYXJtLiBTdGF0dXM6ICcgKyBzdGF0dXMgKyAnLjxici8+VmVyaWZ5IHRoZSBhbGFybSBpcyBmb3IgYSBmdXR1cmUgdGltZS4nKTsgcmV0dXJuOyB9DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UuQm9keVsnUmV0dXJuVmFsdWUnXSAhPSAwKSB7IG1lc3NhZ2Vib3goJ0FkZCBhbGFybScsICdGYWlsZWQgdG8gYWRkIGFsYXJtLCAnICsgcmVzcG9uc2UuQm9keVsnUmV0dXJuVmFsdWVTdHInXSArICcuPGJyLz5WZXJpZnkgdGhlIGFsYXJtIGlzIGZvciBhIGZ1dHVyZSB0aW1lLicpOyByZXR1cm47IH0NCiAgICAgICAgICAgICAgICAgICAgICAgIFB1bGxBbGFybXMoKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHZhciBhbGFybXggPSBDbG9uZSh4eEFsYXJtc1thbHJtXSk7DQogICAgICAgICAgICAgICAgYWxhcm14WyJTdGFydFRpbWUiXSA9ICI8cDpEYXRldGltZSB4bWxuczpwPVwiaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NvbW1vblwiPiIgKyBhbGFybV9zdGFydHRpbWUgKyAiPC9wOkRhdGV0aW1lPiI7DQogICAgICAgICAgICAgICAgYWxhcm14WyJJbnRlcnZhbCJdID0gIjxwOkludGVydmFsIHhtbG5zOnA9XCJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY29tbW9uXCI+IiArIGFsYXJtX2ludGVydmFsICsgIjwvcDpJbnRlcnZhbD4iOw0KICAgICAgICAgICAgICAgIGFsYXJteFsiRGVsZXRlT25Db21wbGV0aW9uIl0gPSBhbGFybV9kb2M7DQogICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCJJUFNfQWxhcm1DbG9ja09jY3VycmVuY2UiLCBhbGFybXgsIGZ1bmN0aW9uICh3cywgcmVzdXJpLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goJ0VkaXQgYWxhcm0nLCAnRmFpbGVkIHRvIGNoYW5nZSBhbGFybS4gU3RhdHVzOiAnICsgc3RhdHVzICsgJy48YnIvPlZlcmlmeSB0aGUgYWxhcm0gZm9yIGF0IGEgZnV0dXJlIHRpbWUuJyk7IHJldHVybjsgfQ0KICAgICAgICAgICAgICAgICAgICBQdWxsQWxhcm1zKCk7DQogICAgICAgICAgICAgICAgfSwgbnVsbCwgbnVsbCwgeyAiSW5zdGFuY2VJRCIgOiBhbGFybXhbIkluc3RhbmNlSUQiXX0pOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0FsZXJ0RGV0YWlscyhpKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgYWxhcm0gPSB4eEFsYXJtc1tpXSwgd2FrZXRpbWUgPSBuZXcgRGF0ZShhbGFybVsiU3RhcnRUaW1lIl1bIkRhdGV0aW1lIl0pOw0KICAgICAgICAgICAgdmFyIHggPSAnPGRpdiBzdHlsZT10ZXh0LWFsaWduOmxlZnQ+JyArIGFkZEh0bWxWYWx1ZSgiTmFtZSIsIGFsYXJtWyJFbGVtZW50TmFtZSJdKSArIGFkZEh0bWxWYWx1ZSgiV2FrZSB0aW1lIiwgd2FrZXRpbWUudG9Mb2NhbGVTdHJpbmcoKS5yZXBsYWNlKCcsICcsICcgYXQgJykpOw0KICAgICAgICAgICAgaWYgKGFsYXJtWyJJbnRlcnZhbCJdICE9IHVuZGVmaW5lZCkgeyB4ICs9IGFkZEh0bWxWYWx1ZSgiSW50ZXJuYWwiLCBfZm10aW50ZXJ2YWwoYWxhcm1bIkludGVydmFsIl1bIkludGVydmFsIl0pKTsgfQ0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkFmdGVyIHdha2UiLCAoYWxhcm1bIkRlbGV0ZU9uQ29tcGxldGlvbiJdID09IHRydWUpPyJEZWxldGUgQWxhcm0iOiJLZWVwIEFsYXJtIikgKyAiPC9kaXY+IjsNCiAgICAgICAgICAgIG1lc3NhZ2Vib3goIkFsYXJtICIgKyBhbGFybVsiRWxlbWVudE5hbWUiXSwgeCk7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiQWxhcm0gIiArIGFsYXJtWyJFbGVtZW50TmFtZSJdLCA1LCBzaG93QWxlcnREZXRhaWxzRGVsZXRlLCB4LCBpKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dBbGVydERldGFpbHNEZWxldGUoYnV0dG9uLCB0YWcpIHsNCiAgICAgICAgICAgIGlmIChidXR0b24gPT0gMikgeyBhbXRzdGFjay5EZWxldGUoIklQU19BbGFybUNsb2NrT2NjdXJyZW5jZSIsIHh4QWxhcm1zW3RhZ10sIGZ1bmN0aW9uKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7IFB1bGxBbGFybXMoKTsgfSk7IH0NCiAgICAgICAgfQ0KDQoNCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIFNjcmlwdGluZw0KICAgICAgICAvLw0KDQogICAgICAgIC8vIENhbGxlZCBieSB0aGUgIlJ1biBTY3JpcHQuLi4iIGJ1dHRvbi4gRGlzcGxheSBhIGRpYWxvZyBib3ggdG8gYXNrIGZvciB0aGUgc2NyaXB0IGZpbGUuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9ydW5TY3JpcHREbGcoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlIHx8IHNjcmlwdHN0YXRlKSByZXR1cm47DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiUnVuIFNjcmlwdCIsIDMsIHNjcmlwdF9ydW5TY3JpcHREbGdPaywgIjxicj48aW5wdXQgaWQ9c2NyaXB0b3BlbiB0eXBlPWZpbGUgc3R5bGU9d2lkdGg6MTAwJSBhY2NlcHQ9Lm1lc2NyaXB0PiIpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gT25jZSB0aGUgc2NyaXB0IGZpbGUgaXMgc2VsZWN0ZWQsIGRlY29kZSB0aGUgc2NyaXB0IGhlcmUuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9ydW5TY3JpcHREbGdPayhyKSB7DQogICAgICAgICAgICBpZiAociAhPSAxKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9IFEoJ3NjcmlwdG9wZW4nKTsNCiAgICAgICAgICAgIGlmICh4LmZpbGVzLmxlbmd0aCAhPSAxKSByZXR1cm47DQogICAgICAgICAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsNCiAgICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSBzY3JpcHRfb25TY3JpcHRSZWFkOw0KICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyh4LmZpbGVzWzBdKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENhbGxlZCBvbmNlIHRoZSBzY3JpcHQgaXMgZGVjb2RlZCwgZ2V0IHRoZSBzY3JpcHQgc2V0dXAgYW5kIHN0YXJ0IHJ1bm5pbmcgaXQuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9vblNjcmlwdFJlYWQoZmlsZSkgew0KICAgICAgICAgICAgdmFyIHg7DQogICAgICAgICAgICB0cnkgeyB4ID0gSlNPTi5wYXJzZShmaWxlLnRhcmdldC5yZXN1bHQpOyB9IGNhdGNoIChlKSB7fQ0KDQogICAgICAgICAgICBpZiAoY3VycmVudFZpZXcgPT0gMjApIHsNCiAgICAgICAgICAgICAgICAvLyBMb2FkIHNjcmlwdCBpbnRvIGVkaXRvcg0KICAgICAgICAgICAgICAgIGlmICh4WydzY3JpcHRUZXh0J10pIFEoJ3NjcmlwdGFyZWEnKS52YWx1ZSA9IHhbJ3NjcmlwdFRleHQnXTsNCiAgICAgICAgICAgICAgICBpZiAoeFsnbWVzY3JpcHQnXSkgUSgnY29tcGlsZWRhcmVhJykudmFsdWUgPSByc3RyMmhleChhdG9iKHhbJ21lc2NyaXB0J10pKTsNCiAgICAgICAgICAgICAgICBpZiAoeFsnYmxvY2tzJ10pIHsgc2NyaXB0X3NldEJ1aWxkQmxvY2tzKHhbJ2Jsb2NrcyddKTsgc2NyaXB0Vmlld0J1dHRvbigxKTsgfSBlbHNlIHsgc2NyaXB0X3NldEJ1aWxkQmxvY2tzKCk7IHNjcmlwdFZpZXdCdXR0b24oMCk7IH0NCiAgICAgICAgICAgICAgICBpZiAoeFsnc2NyaXB0QmxvY2tzJ10pIHsgc2NyaXB0X0Jsb2NrU2NyaXB0ID0geFsnc2NyaXB0QmxvY2tzJ107IH0gZWxzZSB7IGlmICghc2NyaXB0X0J1aWxkaW5nQmxvY2tzKSB7IHNjcmlwdF9CbG9ja1NjcmlwdCA9IFtdOyB9IH0NCg0KICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgc2NyaXB0QmxvY2tzIHRvIHRoZSBsYXRlc3QgYmxvY2tzLiBUaGlzIGlzIGRvZXMgYmVjYXVzZSB3ZSBtYXkgdXBkYXRlIGFuIGV4aXN0aW5nIHNjcmlwdCB0byBuZXcgYmxvY2tzLg0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gc2NyaXB0X0Jsb2NrU2NyaXB0KSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBibG9jayA9IHNjcmlwdF9CbG9ja1NjcmlwdFtpXTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHhibG9jayA9IHNjcmlwdF9CdWlsZGluZ0Jsb2Nrc1tibG9ja1sneG5hbWUnXV07DQogICAgICAgICAgICAgICAgICAgIGlmICh4YmxvY2spIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBiID0gQ2xvbmUoeGJsb2NrKTsgLy8gQ2xvbmUgYSBuZXcgYmxvY2ssIHRoZW4gc2V0IGFsbCB0aGUgdmFyaWFibGVzLg0KICAgICAgICAgICAgICAgICAgICAgICAgYlsnaWQnXSA9IGJsb2NrWydpZCddOw0KICAgICAgICAgICAgICAgICAgICAgICAgYlsneG5hbWUnXSA9IGJsb2NrWyd4bmFtZSddOw0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiBpbiBiLnZhcnMpIHsgaWYgKGJsb2NrLnZhcnNbal0pIHsgYi52YXJzW2pdWyd2YWx1ZSddID0gYmxvY2sudmFyc1tqXVsndmFsdWUnXTsgfSB9DQogICAgICAgICAgICAgICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHRbaV0gPSBiOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgLy8gUmVzZXQgdGhlIHNjcmlwdCBzdGF0ZQ0KICAgICAgICAgICAgICAgIGZ1cGRhdGVzY3JpcHQoKTsNCiAgICAgICAgICAgICAgICBkZWxldGUgc2NyaXB0c3RhdGU7DQogICAgICAgICAgICAgICAgcmVzZXRTY3JpcHRCdXR0b24oKTsNCiAgICAgICAgICAgICAgICByZXR1cm47DQogICAgICAgICAgICB9DQogICAgICAgICAgICB2YXIgc3RhcnR2YXJzID0geyAnX2ludGVyYWN0aXZlJzoxIH07DQoNCiAgICAgICAgICAgIHN0YXJ0dmFyc1snX2NlcnRpZmljYXRlcyddID0gMTsNCg0KICAgICAgICAgICAgc3RhcnR2YXJzWydfbW9kZSddID0gJ0Zpcm13YXJlJzsNCg0KICAgICAgICAgICAgc3RhcnR2YXJzWydfbW9kZSddID0gJ01lc2hDZW50cmFsMic7DQoNCiAgICAgICAgICAgIHN0YXJ0dmFyc1snX21vZGUnXSA9ICdMTVMnOw0KICAgICAgICAgICAgaWYgKHggJiYgeFsnbWVzY3JpcHQnXSkgc2NyaXB0c3RhdGUgPSBzY3JpcHRfc2V0dXAoYXRvYih4WydtZXNjcmlwdCddKSwgc3RhcnR2YXJzKTsNCiAgICAgICAgICAgIGlmIChzY3JpcHRzdGF0ZSkgew0KICAgICAgICAgICAgICAgIHNjcmlwdHN0YXRlLndzc3RhY2sgPSB3c3N0YWNrOw0KICAgICAgICAgICAgICAgIHNjcmlwdHN0YXRlLmFtdHN0YWNrID0gYW10c3RhY2s7DQogICAgICAgICAgICAgICAgc2NyaXB0c3RhdGUub25TdGVwID0gc2NyaXB0X3VwZGF0ZVNjcmlwdFN0YXRlOw0KICAgICAgICAgICAgICAgIHNjcmlwdHN0YXRlLm9uQ29uc29sZSA9IHNjcmlwdF9jb25zb2xlOw0KICAgICAgICAgICAgICAgIHNjcmlwdHN0YXRlLnN0YXJ0KDEwMCk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIG1lc3NhZ2Vib3goIlJ1biBTY3JpcHQiLCAiSW52YWxpZCBzY3JpcHQgZmlsZS4iKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENhbGxlZCB3aGVuIHRoZSBzY3JpcHQgY2hhbmdlcyBzdGF0ZSwgZGlzcGxheXMgdGhlIGdyZWVuIHN0YXR1cyBiYXIgYXQgdGhlIHRvcCBvZiB0aGUgd2ViIHBhZ2UuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF91cGRhdGVTY3JpcHRTdGF0ZSgpIHsNCiAgICAgICAgICAgIGlmIChzY3JpcHRzdGF0ZSkgew0KICAgICAgICAgICAgICAgIFFWKCdpZF9zY3JpcHRzdGF0dXMnLCBzY3JpcHRzdGF0ZS5zdGF0ZSA+IDApOyBjZW50ZXIoKTsNCiAgICAgICAgICAgICAgICBpZiAoc2NyaXB0c3RhdGUuc3RhdGUgPT0gMCkgew0KICAgICAgICAgICAgICAgICAgICBzY3JpcHRzdGF0ZSA9IHVuZGVmaW5lZDsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgYnkgYSBydW5uaW5nIHNjcmlwdCB0byB1cGRhdGUgdGhlIGNvbnNvbGUuIFRoZSBsYXN0IG1lc3NhZ2UgaW4gdGhlIGNvbnNvbGUgaXMgZGlzcGxheWVkIGluIHRoZSB0b3AgZ3JlZW4gYmFyLg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRfY29uc29sZShtc2cpIHsNCiAgICAgICAgICAgIGlmIChtc2cuaW5kZXhPZigiSU5GTzogIikgPT0gMCkgeyBtc2cgPSBtc2cuc3Vic3RyaW5nKDYpOyB9DQogICAgICAgICAgICBpZiAobXNnLmluZGV4T2YoIlNVQ0NFU1M6ICIpID09IDApIHsgbXNnID0gbXNnLnN1YnN0cmluZyg5KTsgfQ0KICAgICAgICAgICAgaWYgKG1zZy5pbmRleE9mKCJFUlJPUjogIikgPT0gMCkgeyBtc2cgPSBtc2cuc3Vic3RyaW5nKDcpOyB9DQogICAgICAgICAgICBRSCgnaWRfc2NyaXB0c3RhdHVzc3RyJywgJywgJyArIG1zZyk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgYnkgdGhlICJTdG9wIiBidXR0b24gb24gdGhlIHNjcmlwdCBzdGF0dXMgYmFyLiBDYXVzZXMgdGhlIHNjcmlwdCB0byBzdG9wLg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRfU3RvcCgpIHsNCiAgICAgICAgICAgIGlmIChzY3JpcHRzdGF0ZSkgew0KICAgICAgICAgICAgICAgIGlmIChzY3JpcHRzdGF0ZS5kaWFsb2cgPT0gdHJ1ZSkgeyBzZXREaWFsb2dNb2RlKDApOyB9DQogICAgICAgICAgICAgICAgc2NyaXB0c3RhdGUuc3RvcCgpOw0KICAgICAgICAgICAgICAgIHNjcmlwdHN0YXRlLnN0YXRlID0gMDsNCiAgICAgICAgICAgICAgICBzY3JpcHRfdXBkYXRlU2NyaXB0U3RhdGUoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQoNCg0KICAgICAgICANCiAgICAgICAgdmFyIHNjcmlwdF9CdWlsZGluZ0Jsb2NrczsgLy8gTGlzdCBvZiBibG9jayB0aGF0IGNhbiBiZSB1c2VkIHRvIGJ1aWxkIGEgc2NyaXB0LiBUaGlzIGlzIHNob3duIG9uIHRoZSBsaXN0IHNpZGUuDQogICAgICAgIHZhciBzY3JpcHRfU3RhcnRpbmdCdWlsZGluZ0Jsb2NrczsgLy8gTGlzdCBvZiBibG9jayB0aGF0IGNhbiBiZSB1c2VkIHRvIGJ1aWxkIGEgc2NyaXB0IHdoZW4geW91IGdldCBzdGFydGVkLg0KICAgICAgICB2YXIgc2NyaXB0X0Jsb2NrU2NyaXB0ID0gW107IC8vIExpc3Qgb2YgYmxvY2tzIHRoYXQgYXJlIHBhcnQgb2YgdGhlIGN1cnJlbnQgc2NyaXB0Lg0KICAgICAgICB2YXIgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IG51bGw7IC8vIFRoZSBpZGVudGlmaWVyIG9mIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgYmxvY2suDQogICAgICAgIHZhciBzY3JpcHRfQnVpbGRlclZpZXcgPSAwOyAvLyAwID0gRWRpdG9yIFZpZXcsIDEgPSBCdWlsZGVyIFZpZXcNCiAgICAgICAgdmFyIGVkaXRzY3JpcHRzdGF0ZTsgLy8gVGhpcyBpcyB0aGUgaW5zdGFuY2Ugb2YgdGhlIHNjcmlwdCBydW5uZXIgdXNlZCBieSB0aGUgZWRpdG9yLiBUaGlzIGlzIGRpZmZlcmVudCBmcm9tIHRoZSBydW5uZXIgdXNlZCBieSB0aGUgd2ViIHBhZ2UuDQoNCg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRMb2FkU3RhcnRpbmdCbG9ja3MoKSB7DQoNCiAgICAgICAgICAgIHZhciByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7DQogICAgICAgICAgICByZXF1ZXN0Lm9ubG9hZCA9IGZ1bmN0aW9uKCkgew0KICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0LnN0YXR1cyA+PSAyMDAgJiYgcmVxdWVzdC5zdGF0dXMgPCA0MDApIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gU3VjY2Vzcw0KICAgICAgICAgICAgICAgICAgICB2YXIgeDsNCiAgICAgICAgICAgICAgICAgICAgdHJ5IHsgeCA9IEpTT04ucGFyc2UocmVxdWVzdC5yZXNwb25zZVRleHQpOyB9IGNhdGNoIChlKSB7fQ0KICAgICAgICAgICAgICAgICAgICBpZiAoKHgpICYmICh4WydibG9ja3MnXSkpIHsgc2NyaXB0X1N0YXJ0aW5nQnVpbGRpbmdCbG9ja3MgPSB4WydibG9ja3MnXTsgc2NyaXB0X3NldEJ1aWxkQmxvY2tzKHNjcmlwdF9TdGFydGluZ0J1aWxkaW5nQmxvY2tzKTsgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH07DQogICAgICAgICAgICByZXF1ZXN0Lm9uZXJyb3IgPSBmdW5jdGlvbigpIHsgY29uc29sZS5sb2coJ0ZhaWxlZCB0byBnZXQgc2NyaXB0IGJsb2NrcycpOyB9Ow0KICAgICAgICAgICAgcmVxdWVzdC5vcGVuKCdHRVQnLCAnc2NyaXB0YmxvY2tzLnR4dCcsIHRydWUpOw0KICAgICAgICAgICAgcmVxdWVzdC5zZW5kKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgYnkgdGhlICJWaWV3IEVkaXRvciIgb3IgIlZpZXcgQnVpbGRlciIgYnV0dG9uIHRvIHRvZ2dsZSBiZXR3ZWVuIHRoZSB2aWV3IG1vZGVzLg0KICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBjb25zdHJ1Y3Rpb24gYmxvY2tzLCBkaXNwbGF5IHRoZSBzY3JpcHQgZWRpdG9yIG9ubHkuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdFZpZXdCdXR0b24oeCkgew0KICAgICAgICAgICAgc2NyaXB0X0J1aWxkZXJWaWV3ID0geDsNCiAgICAgICAgICAgIFFWKCdzY3JpcHRlZGl0b3InLCB4ID09IDApOw0KICAgICAgICAgICAgUVYoJ3NjcmlwdGJ1aWxkZXInLCB4ID09IDEpOw0KICAgICAgICAgICAgUVYoJ3ZpZXdFZGl0b3JCdXR0b24nLCBzY3JpcHRfQnVpbGRpbmdCbG9ja3MgJiYgKHggPT0gMSkpOw0KICAgICAgICAgICAgUVYoJ3ZpZXdCdWlsZGVyQnV0dG9uJywgc2NyaXB0X0J1aWxkaW5nQmxvY2tzICYmICh4ID09IDApKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIERpc3BsYXkgdGhlIGxpc3Qgb2YgY29uc3RydWN0aW9uIHNjcmlwdCBibG9jayBvbiB0aGUgbGVmdCBzaWRlLg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRfc2V0QnVpbGRCbG9ja3MoYmxvY2tzKSB7DQogICAgICAgICAgICBzY3JpcHRfQnVpbGRpbmdCbG9ja3MgPSBibG9ja3M7DQogICAgICAgICAgICB2YXIgeCA9ICcnOw0KICAgICAgICAgICAgaWYgKGJsb2Nrcykgew0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYmxvY2tzKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChpLmNoYXJDb2RlQXQoMCkgIT0gOTUpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gJzxkaXYgaWQ9c2Jsb2NrXycgKyBpICsgJyBzdHlsZT1jdXJzb3I6cG9pbnRlcjtiYWNrZ3JvdW5kLWNvbG9yOiNjY2M7d2lkdGg6YXV0bztwYWRkaW5nOjVweDttYXJnaW46MnB4IG9uZGJsY2xpY2s9c2NyaXB0X2ZhZGRibG9jaygiJyArIGkgKyAnIikgZHJhZ2dhYmxlPXRydWUgb25kcmFnc3RhcnQ9c2NyaXB0X2ZvbmRyYWdzdGFydChldmVudCx0aGlzKSBvbmRyYWdlbmQ9c2NyaXB0X2ZvbmRyYWdlbmQoZXZlbnQsdGhpcykgdGl0bGU9IicgKyBibG9ja3NbaV1bJ2Rlc2MnXSArICciJzsNCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gJz4nICsgYmxvY2tzW2ldWyduYW1lJ10gKyAnPC9kaXY+JzsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIFFIKCdibG9ja3MnLCB4KTsNCiAgICAgICAgICAgIHNjcmlwdF9mb25maWx0ZXJjaGFuZ2VkKCk7DQogICAgICAgICAgICBzY3JpcHRWaWV3QnV0dG9uKHNjcmlwdF9CdWlsZGluZ0Jsb2Nrcz8xOjApOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQWRkIGEgbmV3IGJsb2NrIHRvIHRoZSBlbmQgb2YgdGhlIGJsb2NrIHNjcmlwdC4gVGhpcyBpcyBjYWxsZWQgd2hlbiB5b3UgcmlnaHQgY2xpY2sgb24gYSBibG9jayBhbmQgaGl0ICJBZGQiIGluIHRoZSBjb250ZXh0IG1lbnUuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mYWRkYmxvY2soaCkgew0KICAgICAgICAgICAgdmFyIGIgPSBDbG9uZShzY3JpcHRfQnVpbGRpbmdCbG9ja3NbaF0pOyAvLyBUbyBhZGQgYSBuZXcgYmxvY2sgdG8gdGhlIHNjcmlwdCwgY2xvbmUgdGhlIGJsb2NrLCBhc3NpZ24gaXQgYSByYW5kb20gaWQgYW5kIHNldCB0aGUgeG5hbWUgdG8gdGhlIG5hbWUgb2YgdGhlIGJsb2NrLg0KICAgICAgICAgICAgYlsnaWQnXSA9IE1hdGgucmFuZG9tKCk7DQogICAgICAgICAgICBiWyd4bmFtZSddID0gaDsNCiAgICAgICAgICAgIHNjcmlwdF9CbG9ja1NjcmlwdC5wdXNoKGIpOyAvLyBOb3cgdGhhdCBhIGJsb2NrIGlzIGNyZWF0ZWQsIGFkZCBpdCBhdCB0aGUgZW5kIG9mIHRoZSBzY3JpcHQgYW5kIHNldCBpdCBhcyB0aGUgc2VsZWN0ZWQgYmxvY2suDQogICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkID0gc2NyaXB0X0Jsb2NrU2NyaXB0Lmxlbmd0aCAtIDE7DQogICAgICAgICAgICBmdXBkYXRlc2NyaXB0KCk7IC8vIFJlLWRpc3BsYXkgdGhlIGxpc3Qgb2Ygc2NyaXB0IGJsb2Nrcy4gVGhlIHNlbGVjdGVkIGJsb2NrIHdpbGwgYWxzbyBiZSBoaWdobGlnaHRlZC4NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIEVkaXQgYSBzY3JpcHQgYmxvY2sNCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZlZGl0YmxvY2soaCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgJ0VkaXQgJyArIHNjcmlwdF9CdWlsZGluZ0Jsb2Nrc1toXVsnbmFtZSddLCAzLCBzY3JpcHRfZmVkaXRibG9ja0V4LCAnRWRpdCB0aGlzIGJsb2NrPyBUaGlzIG9wZXJhdGlvbiB3aWxsIHJlc2V0IHRoZSBibG9jayBlZGl0b3IgYW5kIGxvYWQgdGhlIGJsb2NrIGNvZGUgaW50byB0aGUgY29kZSBlZGl0b3IuJywgaCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgd2hlbiB0aGUgc2NyaXB0IGJsb2NrIGVkaXQgZGlhbG9nIGlzIGNsb3NlZC4NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZlZGl0YmxvY2tFeChidXR0b24sIGgpIHsNCiAgICAgICAgICAgIHNjcmlwdF9uZXdTY3JpcHREbGdPaygpOw0KICAgICAgICAgICAgc2NyaXB0Vmlld0J1dHRvbigwKTsNCiAgICAgICAgICAgIHZhciB4ID0gJycsIGIgPSBzY3JpcHRfQnVpbGRpbmdCbG9ja3NbaF07DQogICAgICAgICAgICB4ICs9ICcjIyFCTE9DSyEjI1xyXG4jaWQ9JyArIGggKyAnXHJcbiNuYW1lPScgKyBiWyduYW1lJ10gKyAnXHJcbiNkZXNjPScgKyBiWydkZXNjJ10gKyAnXHJcbiMjIUJMT0NLISMjXHJcbic7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIGJbJ3ZhcnMnXSkgew0KICAgICAgICAgICAgICAgIHZhciB2ID0gYlsndmFycyddW2ldOw0KICAgICAgICAgICAgICAgIHggKz0gJyMjIVZBUiEjI1xyXG4jaWQ9JyArIGkgKyAnXHJcbiNuYW1lPScgKyB2WyduYW1lJ10gKyAnXHJcbiNkZXNjPScgKyB2WydkZXNjJ10gKyAnXHJcbiN0eXBlPScgKyB2Wyd0eXBlJ10gKyAnXHJcbic7DQogICAgICAgICAgICAgICAgaWYgKHZbJ21heGxlbmd0aCddKSB7IHggKz0gJyNtYXhsZW5ndGg9JyArIHZbJ21heGxlbmd0aCddICsgJ1xyXG4nOyB9DQogICAgICAgICAgICAgICAgaWYgKHZbJ3ZhbHVlcyddKSB7IGZvciAodmFyIGogaW4gdlsndmFsdWVzJ10pIHsgeCArPSAnI3ZhbHVlcy0nICsgaiArJz0nICsgdlsndmFsdWVzJ11bal0gKyAnXHJcbic7IH0gfQ0KICAgICAgICAgICAgICAgIHggKz0gJyN2YWx1ZT0nICsgdlsndmFsdWUnXSArICdcclxuIyNTV0FQICUlJScgKyBpICsgJyUlJSAnICsgdlsndmFsdWUnXSArICdcclxuJzsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gJyMjIVZBUiEjI1xyXG4jI1NXQVAgJSUlfiUlJSAwXHJcblxyXG4jIyFCTE9DSyEjI1xyXG4nICsgYlsnY29kZSddICsgJ1xyXG4jIyFCTE9DSyEjI1xyXG4nOw0KICAgICAgICAgICAgUSgnc2NyaXB0YXJlYScpLnZhbHVlID0geDsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mQ29udmVydFNjcmlwdFRvSnNvbkJsb2NrKHNjcmlwdCkgew0KICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHt9LCBzY3JpcHRwYXJ0cyA9IHNjcmlwdC5zcGxpdCgnIyMhQkxPQ0shIyNcbicpLCBzY3JpcHRsaW5lcyA9IHNjcmlwdHBhcnRzWzFdLnNwbGl0KCdcbicpOw0KDQogICAgICAgICAgICAvLyBQYXJzZSBpbmZvcm1hdGlvbiBwYXJ0DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHNjcmlwdGxpbmVzKSB7DQogICAgICAgICAgICAgICAgdmFyIHMgPSBzY3JpcHRsaW5lc1tpXS5zcGxpdCgnPScpOw0KICAgICAgICAgICAgICAgIGlmIChzLmxlbmd0aCA9PSAyKSB7IHJlc3VsdFtzWzBdLnN1YnN0cmluZygxKV0gPSBzWzFdOyB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIFBhcnNlIHZhcmlhYmxlcyBwYXJ0DQogICAgICAgICAgICByZXN1bHRbJ3ZhcnMnXSA9IHt9Ow0KICAgICAgICAgICAgc2NyaXB0dmFyaWFibGVzID0gc2NyaXB0cGFydHNbMl0uc3BsaXQoJyMjIVZBUiEjI1xuJyk7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHNjcmlwdHZhcmlhYmxlcykgew0KICAgICAgICAgICAgICAgIHNjcmlwdGxpbmVzID0gc2NyaXB0dmFyaWFibGVzW2ldLnNwbGl0KCdcbicpOw0KICAgICAgICAgICAgICAgIHZhciB2ID0ge30sIHZhbHVlcyA9IHt9LCB2YWx1ZXNsZW4gPSAwOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gc2NyaXB0bGluZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHMgPSBzY3JpcHRsaW5lc1tqXS5zcGxpdCgnPScpOw0KICAgICAgICAgICAgICAgICAgICBpZiAoKHMubGVuZ3RoID09IDIpICYmIChzWzFdKSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChzWzBdKSAmJiAoc1swXS5sZW5ndGggPiAwKSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzWzBdLnN1YnN0cmluZygwLCA4KSA9PSAnI3ZhbHVlcy0nKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlc1tzWzBdLnN1YnN0cmluZyg4KV0gPSBzWzFdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXNsZW4rKzsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2W3NbMF0uc3Vic3RyaW5nKDEpXSA9IHNbMV07DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmICh2LmlkKSB7DQogICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZXNsZW4gPiAwKSB7IHZbJ3ZhbHVlcyddID0gdmFsdWVzOyB9DQogICAgICAgICAgICAgICAgICAgIHZhciBpZCA9IHYuaWQ7DQogICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB2LmlkOw0KICAgICAgICAgICAgICAgICAgICByZXN1bHRbJ3ZhcnMnXVtpZF0gPSB2Ow0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gUGFyc2UgY29kZSBwYXJ0DQogICAgICAgICAgICByZXN1bHRbJ2NvZGUnXSA9IHNjcmlwdHBhcnRzWzNdOw0KDQogICAgICAgICAgICAvLyBQYWNrYWdlIHRoZSByZXN1bHQNCiAgICAgICAgICAgIHZhciBpZCA9IHJlc3VsdC5pZDsNCiAgICAgICAgICAgIGRlbGV0ZSByZXN1bHQuaWQ7DQogICAgICAgICAgICB2YXIgciA9IHt9Ow0KICAgICAgICAgICAgcltpZF0gPSByZXN1bHQ7DQogICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkociwgbnVsbCwgJyAgJyk7DQogICAgICAgIH0NCg0KICAgICAgICAvKg0KICAgICAgICAvLyBJZiB0aGUgZGVsZXRlIGtleSBpcyBwcmVzc2VkLCBkZWxldGUgdGhlIGJsb2NrDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mb25rZXlwcmVzcyhlKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBpZiAoZS5rZXkgPT0gJ0RlbGV0ZScgJiYgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCAhPSBudWxsKSB7DQogICAgICAgICAgICAgICAgLy9kZWxldGUgc2NyaXB0X0Jsb2NrU2NyaXB0W3NjcmlwdF9CbG9ja1NjcmlwdFNlbGVjdGVkSWRdOw0KICAgICAgICAgICAgICAgIHNjcmlwdF9CbG9ja1NjcmlwdC5zcGxpY2Uoc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCwgMSk7DQogICAgICAgICAgICAgICAgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IG51bGw7DQogICAgICAgICAgICAgICAgZnVwZGF0ZXNjcmlwdCgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgICovDQoNCiAgICAgICAgLy8gRmlsZXIgdGhlIGxpc3Qgb2YgYmxvY2tzIG9uIHRoZSBsZWZ0IHNpZGUgbGlzdC4NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZvbmZpbHRlcmNoYW5nZWQoKSB7DQogICAgICAgICAgICB2YXIgZmlsdGVyID0gUSgnYmxvY2tmaWx0ZXInKS52YWx1ZS50b0xvd2VyQ2FzZSgpOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBzY3JpcHRfQnVpbGRpbmdCbG9ja3MpIHsNCiAgICAgICAgICAgICAgICAvLyBTY3JpcHQgYmxvY2tzIHRoYXQgc3RhcnQgd2l0aCAiXyIgYXJlIGhpZGRlbiBibG9ja3MgYW5kIHNob3VsZCBuZXZlciBiZSBzaG93bi4NCiAgICAgICAgICAgICAgICBpZiAoaS5jaGFyQ29kZUF0KDApICE9IDk1KSB7IFFWKCdzYmxvY2tfJyArIGksIChzY3JpcHRfQnVpbGRpbmdCbG9ja3NbaV1bJ25hbWUnXS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoZmlsdGVyKSA+PSAwIHx8IHNjcmlwdF9CdWlsZGluZ0Jsb2Nrc1tpXVsnZGVzYyddLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihmaWx0ZXIpID49IDApKTsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQ2FsbGVkIHdoZW4geW91IGNsaWNrIG9uIGEgYmxvY2suIElmIHlvdSBkb3VibGUgY2xpY2ssIG9uIGEgYmxvY2ssIGRvIGxpa2UgcHJlc3Npbmcgb24gdGhlICJFZGl0Li4uIiBidXR0b24uDQogICAgICAgIHZhciBzY3JpcHRfZm9uY2xpY2tEYmxDbGlja0RldGVjdEluZGV4ID0gbnVsbDsNCiAgICAgICAgdmFyIHNjcmlwdF9mb25jbGlja0RibENsaWNrRGV0ZWN0VGltZSA9IG51bGw7DQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mb25jbGljayhlLCB0KSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkID0gbnVsbDsNCiAgICAgICAgICAgIGlmICh0KSB7IHQgPSBmZ2V0UGFyZW50V2l0aElkKHQpOyBpZiAodC5pZC5zdGFydHNXaXRoKCd4YmxvY2tfJykpIHsgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IHQuaWQuc3Vic3RyaW5nKDcpOyB9IH0gLy8gRmlndXJlIG91dCB3aGF0IGJsb2NrIHdhcyBjbGlja2VkIG9uDQogICAgICAgICAgICBmdXBkYXRlc2NyaXB0KCk7IC8vIFRoaXMgd2lsbCBzaG93IHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgYmxvY2sgaW4gYSBkaWZmZXJlbnQgY29sb3IuDQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQoNCiAgICAgICAgICAgIC8vIEZpZ3VyZSBvdXQgaWYgdGhpcyBpcyBhIGRvdWJsZSBjbGljay4gV2UgbmVlZCB0d28gY2xpY2tzIG9uIHRoZSBzYW1lIG9iamVjdCB3aXRoaW4gMjUwbXMuDQogICAgICAgICAgICBpZiAoc2NyaXB0X2ZvbmNsaWNrRGJsQ2xpY2tEZXRlY3RJbmRleCA9PSBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkICYmIChuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHNjcmlwdF9mb25jbGlja0RibENsaWNrRGV0ZWN0VGltZSkgPCAyNTApIHsgcmV0dXJuIHNjcmlwdF9mb25lZGl0Y2xpY2soc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCk7IH0NCiAgICAgICAgICAgIHNjcmlwdF9mb25jbGlja0RibENsaWNrRGV0ZWN0SW5kZXggPSBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkOw0KICAgICAgICAgICAgc2NyaXB0X2ZvbmNsaWNrRGJsQ2xpY2tEZXRlY3RUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBTY3JpcHQgYmxvY2sgZHJhZyAmIGRyb3AgZnVuY3Rpb25zLCBhbGxvdyB0aGUgdXNlciB0byBjcmVhdGUgYW5kIG1vdmUgc2NyaXB0IGJsb2Nrcy4NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZvbmRyYWdzdGFydChlLCB0KSB7IGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsgdCA9IGZnZXRQYXJlbnRXaXRoSWQodCk7IHQuc3R5bGUub3BhY2l0eSA9ICcwLjQnOyBlLmRhdGFUcmFuc2Zlci5lZmZlY3RBbGxvd2VkID0gJ21vdmUnOyBlLmRhdGFUcmFuc2Zlci5zZXREYXRhKCdzY3JpcHRidWlsZGVyL2Jsb2NrJywgdC5pZCk7IH0NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZvbmRyYWdlbmQoZSwgdCkgICB7IGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsgdCA9IGZnZXRQYXJlbnRXaXRoSWQodCk7IHQuc3R5bGUub3BhY2l0eSA9ICcxLjAnOyB9DQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mb25kcmFnZW50ZXIoZSwgdCkgeyBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47IGZnZXRQYXJlbnRXaXRoSWQodCkuc3R5bGVbJ2JvcmRlci10b3AnXSA9ICdzb2xpZCAycHggYmxhY2snOyB9DQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mb25kcmFnbGVhdmUoZSwgdCkgeyBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47IGUgPSBlLm9yaWdpbmFsRXZlbnQgfHwgZTsgdmFyIGN1cnJlbnRFbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnBhZ2VYLCBlLnBhZ2VZKTsgaWYgKCF0LmNvbnRhaW5zKGN1cnJlbnRFbGVtZW50KSkgeyBmZ2V0UGFyZW50V2l0aElkKHQpLnN0eWxlWydib3JkZXItdG9wJ10gPSAnbm9uZSc7IH0gfQ0KDQogICAgICAgIC8vIENhbGxlZCB3aGVuIHlvdSBkcm9wIGEgYmxvY2sgb24gdGhlIGJsb2NrIHNjcmlwdCBhcmVhLiBUaGlzIGNvZGUgd2lsbCBhZGQgb3IgbW92ZSBhIGJsb2NrIGludG8gaXQncyBuZXcgcGxhY2UuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mb25kcm9wKGUsIHQpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHQgPSBmZ2V0UGFyZW50V2l0aElkKHQpOw0KICAgICAgICAgICAgdmFyIGIsIHggPSBlLmRhdGFUcmFuc2Zlci5nZXREYXRhKCdzY3JpcHRidWlsZGVyL2Jsb2NrJyksIGRwID0gcGFyc2VJbnQodC5pZC5zdWJzdHJpbmcoNykpOw0KICAgICAgICAgICAgaWYgKHggPT0gJycpIHsgZG9jdW1lbnRGaWxlU2VsZWN0SGFuZGxlcihlKTsgcmV0dXJuOyB9DQogICAgICAgICAgICBpZiAoeC5zdGFydHNXaXRoKCJzYmxvY2tfIikpIHsNCiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYSBuZXcgc2NyaXB0IGJsb2NrDQogICAgICAgICAgICAgICAgYiA9IENsb25lKHNjcmlwdF9CdWlsZGluZ0Jsb2Nrc1t4LnN1YnN0cmluZyg3KV0pOw0KICAgICAgICAgICAgICAgIGJbJ2lkJ10gPSBNYXRoLnJhbmRvbSgpOw0KICAgICAgICAgICAgICAgIGJbJ3huYW1lJ10gPSB4LnN1YnN0cmluZyg3KTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gUHVsbCBhbiBleGlzdGluZyBzY3JpcHQgYmxvY2sgZnJvbSB0aGUgbGlzdA0KICAgICAgICAgICAgICAgIHZhciBpID0gcGFyc2VJbnQoeC5zdWJzdHJpbmcoNykpOw0KICAgICAgICAgICAgICAgIGIgPSBzY3JpcHRfQmxvY2tTY3JpcHRbaV07DQogICAgICAgICAgICAgICAgc2NyaXB0X0Jsb2NrU2NyaXB0LnNwbGljZShpLCAxKTsNCiAgICAgICAgICAgICAgICBpZiAoZHAgPiBpKSBkcC0tOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYgKHQuaWQgPT0gJ3NjcmlwdGJsb2NrcycpIHsNCiAgICAgICAgICAgICAgICAvLyBQdXQgdGhlIGJsb2NrIGF0IHRoZSBlbmQgb2YgdGhlIGxpc3QNCiAgICAgICAgICAgICAgICBpZiAoYikgc2NyaXB0X0Jsb2NrU2NyaXB0LnB1c2goYik7DQogICAgICAgICAgICAgICAgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IHNjcmlwdF9CbG9ja1NjcmlwdC5sZW5ndGggLSAxOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAvLyBJbnNlcnQgdGhlIGJsb2NrIHdpdGhpbiB0aGUgbGlzdCwgYWJvdmUgdGhlIGRyb3AgcG9pbnQNCiAgICAgICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHQuc3BsaWNlKGRwLCAwLCBiKTsNCiAgICAgICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkID0gZHA7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBmdXBkYXRlc2NyaXB0KCk7DQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgd2hlbiB5b3UgaGl0ICJFZGl0Li4uIiBvbiBhIGJsb2NrLCBkaXNwbGF5cyBhIGRpYWxvZyBib3ggd2l0aCBhbGwgYmxvY2sgYXR0cmlidXRlcy4NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZvbmVkaXRjbGljayhoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgYmxvY2sgPSBzY3JpcHRfQmxvY2tTY3JpcHRbaF07DQogICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkID0gaDsNCiAgICAgICAgICAgIGZ1cGRhdGVzY3JpcHQoKTsNCg0KICAgICAgICAgICAgaWYgKGJsb2NrICE9IG51bGwpIHsNCiAgICAgICAgICAgICAgICB2YXIgYiA9IGJsb2NrWyd2YXJzJ10gPyA3IDogNTsNCiAgICAgICAgICAgICAgICB2YXIgYyA9IGJsb2NrWydkZXNjJ10gKyAiPGJyPjxicj4iOw0KICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIEZvciBlYWNoIHZhcmlhYmxlIGluIGEgYmxvY2ssIGFkZCB0aGUgcHJvcGVyIGlucHV0IGNvbnRyb2wgZm9yIHRoaXMgdmFyaWFibGUgYW5kIHNldCB0aGUgY29udHJvbCB0byB0aGUgY3VycmVudCB2YWx1ZS4NCiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBibG9ja1sndmFycyddKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZCA9IGJsb2NrWyd2YXJzJ11baV1bJ3ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9ICcnOw0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gQmxvY2sgdmFsdWVzIGNhbiBiZSBvbiB0eXBlIDE6VGV4dCwyOk51bWJlciwzOkRyb3BEb3duTGlzdCw0OnBhc3N3b3JkLDU6TXVsdGlTZWxlY3QNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWydtYXhsZW5ndGgnXSkgYXR0cmlidXRlcyArPSAoIiBtYXhsZW5ndGg9IiArIGJsb2NrWyd2YXJzJ11baV1bJ21heGxlbmd0aCddKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gMikgeyBhdHRyaWJ1dGVzICs9ICIgb25rZXlwcmVzcz0ncmV0dXJuIG51bWJlcnNPbmx5KGV2ZW50KSciIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gMSB8fCBibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gMikgeyBkID0gIjxpbnB1dCB0aXRsZT0nIiArIGJsb2NrWyd2YXJzJ11baV1bJ2Rlc2MnXSArICInIGlkPXNjcmlwdFh2YWx1ZV8iICsgaSArICIgdmFsdWU9JyIgKyBibG9ja1sndmFycyddW2ldWyd2YWx1ZSddICsgIicgIiArIGF0dHJpYnV0ZXMgKyAiIHN0eWxlPXdpZHRoOjEwMCU+PC9pbnB1dD4iOyB9DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tbJ3ZhcnMnXVtpXVsndHlwZSddID09IDMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkID0gIjxzZWxlY3QgdGl0bGU9JyIgKyBibG9ja1sndmFycyddW2ldWydkZXNjJ10gKyAiJyBpZD1zY3JpcHRYdmFsdWVfIiArIGkgKyAiIHN0eWxlPXdpZHRoOjEwMCU7cGFkZGluZzowO21hcmdpbjowPiI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiBpbiBibG9ja1sndmFycyddW2ldWyd2YWx1ZXMnXSkgeyBkICs9ICI8b3B0aW9uIHZhbHVlPSIgKyBqICsgKGogPT0gYmxvY2tbJ3ZhcnMnXVtpXVsndmFsdWUnXSA/ICIgc2VsZWN0ZWQiIDogIiIpICsgIj4iICsgYmxvY2tbJ3ZhcnMnXVtpXVsndmFsdWVzJ11bal0gKyAiPC9vcHRpb24+IjsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQgKz0gIjwvc2VsZWN0PiI7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tbJ3ZhcnMnXVtpXVsndHlwZSddID09IDQpIHsgZCA9ICI8aW5wdXQgdHlwZT1wYXNzd29yZCBhdXRvY29tcGxldGU9b2ZmIHRpdGxlPSciICsgYmxvY2tbJ3ZhcnMnXVtpXVsnZGVzYyddICsgIicgaWQ9c2NyaXB0WHZhbHVlXyIgKyBpICsgIiB2YWx1ZT0nIiArIGJsb2NrWyd2YXJzJ11baV1bJ3ZhbHVlJ10gKyAiJyAiICsgYXR0cmlidXRlcyArICIgc3R5bGU9d2lkdGg6MTAwJT48L2lucHV0PiI7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gNSkgeyBkID0gJyc7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gNikgeyBkID0gIjxpbnB1dCB0eXBlPWZpbGUgdGl0bGU9JyIgKyBibG9ja1sndmFycyddW2ldWydkZXNjJ10gKyAiJyBpZD1zY3JpcHRYdmFsdWVfIiArIGkgKyAiICIgKyBhdHRyaWJ1dGVzICsgIiBzdHlsZT13aWR0aDoxMDAlPjwvaW5wdXQ+IjsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgYyArPSAnPHRhYmxlIHN0eWxlPXdpZHRoOjEwMCUgdGl0bGU9IicgKyBibG9ja1sndmFycyddW2ldWydkZXNjJ10gKyAnIj48dGQgc3R5bGU9d2lkdGg6MTIwcHg+JyArIGJsb2NrWyd2YXJzJ11baV1bJ25hbWUnXSArICc8dGQ+PGI+JyArIGQgKyAnPC9iPjwvdGFibGU+JzsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gNSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4ID0gJyc7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyArPSAnPHVsIGlkPXNjcmlwdFh2YWx1ZV8nICsgaSArICcgc3R5bGU9Imxpc3Qtc3R5bGUtdHlwZTpub25lO2hlaWdodDoxMDBweDtvdmVyZmxvdzphdXRvO3dpZHRoOjEwMCU7Ym9yZGVyOjFweCBzb2xpZCAjMDAwO2JhY2tncm91bmQtY29sb3I6d2hpdGU7b3ZlcmZsb3cteDpoaWRkZW47bWFyZ2luOjA7cGFkZGluZzowIj4nOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIHkgaW4gYmxvY2tbJ3ZhcnMnXVtpXVsndmFsdWVzJ10pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHhjID0gJyc7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd2YWx1ZSddLmluZGV4T2YoeSkgPj0gMCkgeGMgPSAnIGNoZWNrZWQnOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjICs9ICc8bGk+PGxhYmVsPjxpbnB1dCB0eXBlPWNoZWNrYm94IGlkPXNjcmlwdFh2YWx1ZXhfJyArIGkgKyAnLScgKyB5ICsgJycgKyB4YyArICc+JyArIGJsb2NrWyd2YXJzJ11baV1bJ3ZhbHVlcyddW3ldICsgJzwvbGFiZWw+PC9saT4nOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjICs9ICc8L3VsPic7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIFBhcmFtZXRlcnM6IERpYWxvZyBNb2RlICgwID0gbm9uZSksIERpYWxvZyBUaXRsZSwgQnV0dG9ucyAoMSA9IE9LLCAyID0gQ2FuY2VsLCAzID0gT0sgJiBDYW5jZWwpLCBDYWxsIGJhY2sgZnVuY3Rpb24oMCA9IENhbmNlbCwgMSA9IE9LKSwgRGlhbG9nIENvbnRlbnQgKE1vZGUgMTEgb25seSkNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsIGJsb2NrLm5hbWUsIGIsIHNjcmlwdF9mb25lZGl0Y2xpY2tFeCwgYywgaCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgd2hlbiB0aGUgc2NyaXB0IGJsb2NrIGVkaXQgZGlhbG9nIGlzIGNsb3NlZC4NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZvbmVkaXRjbGlja0V4KGJ1dHRvbiwgdGFnKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBpZiAoYnV0dG9uID09IDIpIHsNCiAgICAgICAgICAgICAgICAvLyBEZWxldGUgdGhpcyBibG9jaw0KICAgICAgICAgICAgICAgIHNjcmlwdF9CbG9ja1NjcmlwdC5zcGxpY2UodGFnLCAxKTsNCiAgICAgICAgICAgICAgICBpZiAoc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9PSB0YWcpIHsgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IG51bGw7IH0NCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gQ2hhbmdlIHRoaXMgYmxvY2sgd2l0aCBuZXcgYXJndW1lbnRzDQogICAgICAgICAgICAgICAgdmFyIGJsb2NrID0gc2NyaXB0X0Jsb2NrU2NyaXB0W3RhZ107DQogICAgICAgICAgICAgICAgaWYgKGJsb2NrWyd2YXJzJ10pIHsNCiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBibG9ja1sndmFycyddKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tbJ3ZhcnMnXVtpXVsndHlwZSddID09IDUpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBibG9ja1sndmFycyddW2ldWyd2YWx1ZSddID0gW107DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgeSBpbiBibG9ja1sndmFycyddW2ldWyd2YWx1ZXMnXSkgeyBpZiAoUSgnc2NyaXB0WHZhbHVleF8nICsgaSArICctJyArIHkpLmNoZWNrZWQpIGJsb2NrWyd2YXJzJ11baV1bJ3ZhbHVlJ10ucHVzaCh5KTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gNikgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4ID0gUSgnc2NyaXB0WHZhbHVlXycgKyBpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoeC5maWxlcy5sZW5ndGggPT0gMSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uKGZpbGUpIHsgYmxvY2tbJ3ZhcnMnXVtpXVsndmFsdWUnXSA9IGJ0b2EoZmlsZS50YXJnZXQucmVzdWx0KTsgZnVwZGF0ZXNjcmlwdCgpOyB9Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKHguZmlsZXNbMF0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tbJ3ZhcnMnXVtpXVsndmFsdWUnXSA9IFEoJ3NjcmlwdFh2YWx1ZV8nICsgaSkudmFsdWU7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICBmdXBkYXRlc2NyaXB0KCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBTdGFydGluZyB3aXRoIGEgY2hpbGQgZWxlbWVudCwgZ28gdXAgb25lIHBhcmVudCBhdCBhIHRpbWUgdW50aWwgd2UgZmluZCBhbiBlbGVtZW50IHdpdGggYW4gSUQuDQogICAgICAgIGZ1bmN0aW9uIGZnZXRQYXJlbnRXaXRoSWQoeCkgeyB3aGlsZSAoIXguaWQpIHsgeCA9IHgucGFyZW50RWxlbWVudDsgfSByZXR1cm4geDsgfQ0KDQogICAgICAgIC8vIERpc3BsYXlzIHRoZSBsaXN0IG9mIHNjcmlwdCBibG9ja3MgdG8gdGhlIEhUTUwgcGFnZS4gRWFjaCBibG9jayBpcyBkaXNwbGF5ZWQgd2l0aCBpdCdzIG5hbWUsIGF0dHJpYnV0ZXMgYW5kIGFuIGVkaXQgYnV0dG9uLg0KICAgICAgICBmdW5jdGlvbiBmdXBkYXRlc2NyaXB0KCkgew0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gc2NyaXB0X0Jsb2NrU2NyaXB0KSB7DQogICAgICAgICAgICAgICAgeCArPSAnPGRpdiBpZD14YmxvY2tfJyArIGkgKyAnIHN0eWxlPWN1cnNvcjpwb2ludGVyO21pbi1oZWlnaHQ6MjRweDtiYWNrZ3JvdW5kLWNvbG9yOiMnICsgKChzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkID09IGkpID8gJ2FhYScgOiAnY2NjJykgKyAnO3dpZHRoOmF1dG87cGFkZGluZzo1cHg7bWFyZ2luOjJweCBkcmFnZ2FibGU9dHJ1ZSBvbmNsaWNrPXNjcmlwdF9mb25jbGljayhldmVudCx0aGlzKSBvbmRyYWdlbnRlcj1zY3JpcHRfZm9uZHJhZ2VudGVyKGV2ZW50LHRoaXMpIG9uZHJhZ2xlYXZlPXNjcmlwdF9mb25kcmFnbGVhdmUoZXZlbnQsdGhpcykgb25kcmFnc3RhcnQ9c2NyaXB0X2ZvbmRyYWdzdGFydChldmVudCx0aGlzKSBvbmRyYWdlbmQ9c2NyaXB0X2ZvbmRyYWdlbmQoZXZlbnQsdGhpcykgb25kcm9wPXNjcmlwdF9mb25kcm9wKGV2ZW50LHRoaXMpIHRpdGxlPSInICsgc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWydkZXNjJ10gKyAnIic7DQogICAgICAgICAgICAgICAgeCArPSAnPjxpbnB1dCBzdHlsZT1mbG9hdDpyaWdodCB0eXBlPWJ1dHRvbiB2YWx1ZT1FZGl0Li4uIG9uY2xpY2s9c2NyaXB0X2ZvbmVkaXRjbGljaygnICsgaSArICcpPjxkaXYgc3R5bGU9Zm9udC1zaXplOjE2cHg+PGI+JyArIHNjcmlwdF9CbG9ja1NjcmlwdFtpXS5uYW1lICsgJzwvYj4nOw0KICAgICAgICAgICAgICAgIGlmIChzY3JpcHRfQmxvY2tTY3JpcHRbaV1bJ3ZhcnMnXSkgew0KICAgICAgICAgICAgICAgICAgICB2YXIgciA9IDA7DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjx0YWJsZSBjbGFzcz0nc2NyaXB0QmxvY2tWYXIgdXMnIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCBzdHlsZT13aWR0aDoxMDAlO2JvcmRlci1yYWRpdXM6NXB4O21hcmdpbi10b3A6OHB4PiI7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ10pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2ID0gc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ11bal1bJ3ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ11bal1bJ3R5cGUnXSA9PSA0ICYmIHNjcmlwdF9CbG9ja1NjcmlwdFtpXVsndmFycyddW2pdWyd2YWx1ZSddLmxlbmd0aCA+IDApIHYgPSAiKioqKioiOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcmlwdF9CbG9ja1NjcmlwdFtpXVsndmFycyddW2pdWyd0eXBlJ10gPT0gMykgdiA9IHNjcmlwdF9CbG9ja1NjcmlwdFtpXVsndmFycyddW2pdWyd2YWx1ZXMnXVtzY3JpcHRfQmxvY2tTY3JpcHRbaV1bJ3ZhcnMnXVtqXVsndmFsdWUnXV07DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ11bal1bJ3R5cGUnXSA9PSA2KSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcmlwdF9CbG9ja1NjcmlwdFtpXVsndmFycyddW2pdWyd2YWx1ZSddKSB7IHYgPSAiQmluYXJ5IGZpbGUsICIgKyBzY3JpcHRfQmxvY2tTY3JpcHRbaV1bJ3ZhcnMnXVtqXVsndmFsdWUnXS5sZW5ndGggKyAiIGJ5dGVzIjsgfSBlbHNlIHsgdiA9ICJOb3Qgc2V0IjsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgeCArPSAiPHRyIHRpdGxlPSciICsgc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ11bal1bJ2Rlc2MnXSArICInPjx0ZCB3aWR0aD0yMDBweCBzdHlsZT0nIiArIChyID4gMCA/ICJib3JkZXItdG9wOjFweCBzb2xpZCAjYTgxMGE4IiA6ICIiKSArICInPjxwPiIgKyBzY3JpcHRfQmxvY2tTY3JpcHRbaV1bJ3ZhcnMnXVtqXVsnbmFtZSddICsgIjx0ZCBzdHlsZT0nIiArIChyID4gMCA/ICJib3JkZXItdG9wOjFweCBzb2xpZCAjYTgxMGE4IiA6ICIiKSArICInPiIgKyB2Ow0KICAgICAgICAgICAgICAgICAgICAgICAgcisrOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjx0cj48dGQgc3R5bGU9aGVpZ2h0OjNweD48L3RhYmxlPiI7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHggKz0gJzwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAoeCA9PSAnJykgeyB4ID0gJzxkaXYgc3R5bGU9InBhZGRpbmc6MTVweDtjb2xvcjpncmF5Ij5TdGFydCB5b3VyIHNjcmlwdCBieSBkcmFnICYgZHJvcHBpbmcgYmxvY2tzIGZyb20gdGhlIGxlZnQgc2lkZSBpbnRvIHRoaXMgc2NyaXB0aW5nIGJveC48ZGl2Pic7IH0NCiAgICAgICAgICAgIFFIKCdzY3JpcHRibG9ja3MnLCB4ICsgIjxkaXYgc3R5bGU9aGVpZ2h0OjgwcHg+PC9kaXY+Iik7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHNjcmlwdF9CbG9ja1NjcmlwdCkgeyBRUygneGJsb2NrXycgKyBpKS5ib3JkZXJMZWZ0ID0gKHNjcmlwdF9DdXJyZW50SGlnaGxpZ2h0QmxvY2sgPT0gaSkgPyAiM3B4IHNvbGlkIGJsYWNrIiA6ICIiOyB9DQogICAgICAgICAgICBzY3JpcHRfYmxvY2tzVG9TY3JpcHQoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENvbnZlcnQgdGhlIGxpc3Qgb2YgYmxvY2tzIGludG8gYSBzY3JpcHQgdGhhdCBjYW4gYmUgY29tcGlsZWQNCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2Jsb2Nrc1RvU2NyaXB0KCkgew0KICAgICAgICAgICAgdmFyIHNjcmlwdCA9ICcnOw0KICAgICAgICAgICAgaWYgKHNjcmlwdF9CdWlsZGluZ0Jsb2Nrcykgew0KICAgICAgICAgICAgICAgIGlmIChzY3JpcHRfQnVpbGRpbmdCbG9ja3NbJ19zdGFydCddKSB7IHNjcmlwdCArPSAnIyMjIyMgU3RhcnRpbmcgQmxvY2sgIyMjIyNcclxuJyArIHNjcmlwdF9CdWlsZGluZ0Jsb2Nrc1snX3N0YXJ0J11bJ2NvZGUnXSArICdcclxuXHJcbic7IH0NCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHNjcmlwdF9CbG9ja1NjcmlwdCkgew0KICAgICAgICAgICAgICAgICAgICB2YXIgY29kZSA9IHNjcmlwdF9CbG9ja1NjcmlwdFtpXVsnY29kZSddOw0KICAgICAgICAgICAgICAgICAgICBjb2RlID0gY29kZS5zcGxpdCgiJSUlfiUlJSIpLmpvaW4oaSk7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ10pIHsgY29kZSA9IGNvZGUuc3BsaXQoIiUlJSIgKyBqICsgIiUlJSIpLmpvaW4oc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ11bal1bJ3ZhbHVlJ10pOyB9DQogICAgICAgICAgICAgICAgICAgIHNjcmlwdCArPSAnIyMjIyMgQmxvY2s6ICcgKyBzY3JpcHRfQmxvY2tTY3JpcHRbaV1bJ25hbWUnXSArICcgIyMjIyNcclxuSGlnaGxpZ2h0QmxvY2sgX190ICcgKyBpICsgJ1xyXG4nICsgY29kZSArICdcclxuXHJcbic7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmIChzY3JpcHRfQnVpbGRpbmdCbG9ja3NbJ19lbmQnXSkgeyBzY3JpcHQgKz0gJyMjIyMjIEVuZGluZyBCbG9jayAjIyMjI1xyXG4nICsgc2NyaXB0X0J1aWxkaW5nQmxvY2tzWydfZW5kJ11bJ2NvZGUnXSArICdcclxuSGlnaGxpZ2h0QmxvY2tcclxuJzsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgUSgnc2NyaXB0YXJlYScpLnZhbHVlID0gc2NyaXB0Ow0KICAgICAgICB9DQoNCiAgICAgICAgLy8gSGlnaGxpZ2h0IGEgc2NyaXB0IGJsb2NrLiBUaGlzIGlzIHVzZWZ1bCB0byBrbm93IHdoYXQgYmxvY2sgdGhlIHNjcmlwdCBpcyBjdXJyZW50bHkgcnVubmluZw0KICAgICAgICB2YXIgc2NyaXB0X0N1cnJlbnRIaWdobGlnaHRCbG9jazsNCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X0hpZ2hsaWdodEJsb2NrKHJ1bm5lciwgeCkgew0KICAgICAgICAgICAgaWYgKHJ1bm5lciA9PSBlZGl0c2NyaXB0c3RhdGUpIHsgLy8gT25seSBoaWdobGlnaHQgYmxvY2tzIGlmIHRoZSBzY3JwdCBlZGl0b3IgaXMgcnVubmluZyB0aGUgc2NyaXB0LiBJZiBydW5uaW5nIGEgc2NyaXB0IG9uIHRoZSBwYWdlLCBkb24ndCBoaWdobGlnaHQgYmxvY2tzIGluIHRoZSBlZGl0b3IuDQogICAgICAgICAgICAgICAgc2NyaXB0X0N1cnJlbnRIaWdobGlnaHRCbG9jayA9IHg7DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBzY3JpcHRfQmxvY2tTY3JpcHQpIHsgUVMoJ3hibG9ja18nICsgaSkuYm9yZGVyTGVmdCA9IChzY3JpcHRfQ3VycmVudEhpZ2hsaWdodEJsb2NrID09IGkpID8gIjNweCBzb2xpZCBibGFjayIgOiAiIjsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQ2FsbGVkIGJ5IHRoZSAiTmV3Li4uIiBidXR0b24gdG8gcmVzZXQgdGhlIHNjcmlwdCBlZGl0b3IgdG8gdGhlIHN0YXJ0DQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9uZXdTY3JpcHREbGcoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiTmV3IFNjcmlwdCIsIDMsIHNjcmlwdF9uZXdTY3JpcHREbGdPaywgIjxicj5SZXNldCAmIGNsZWFyIHRoZSBzY3JpcHQgZWRpdG9yPyIpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQ2xlYXIgdGhlIHNjcmlwdCBlZGl0b3INCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X25ld1NjcmlwdERsZ09rKCkgew0KICAgICAgICAgICAgc2NyaXB0X3NldEJ1aWxkQmxvY2tzKHNjcmlwdF9TdGFydGluZ0J1aWxkaW5nQmxvY2tzKTsNCiAgICAgICAgICAgIHNjcmlwdF9CbG9ja1NjcmlwdCA9IFtdOw0KICAgICAgICAgICAgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IG51bGw7DQogICAgICAgICAgICBkZWxldGUgZWRpdHNjcmlwdHN0YXRlOw0KICAgICAgICAgICAgc2NyaXB0Vmlld0J1dHRvbihzY3JpcHRfQnVpbGRpbmdCbG9ja3M/MTowKTsNCiAgICAgICAgICAgIFFIKCd2YXJpYWJsZXMnLCAnJyk7DQogICAgICAgICAgICBRKCdzY3JpcHRhcmVhJykudmFsdWUgPSAnJzsNCiAgICAgICAgICAgIHJlc2V0U2NyaXB0QnV0dG9uKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDb21waWxlIGFuZCByZXNldCBhIHNjcmlwdCB0byB0aGUgc3RhcnRpbmcgcG9zaXRpb24NCiAgICAgICAgZnVuY3Rpb24gcmVzZXRTY3JpcHRCdXR0b24oKSB7DQogICAgICAgICAgICAvLyBDb21waWxlIHRoZSBzY3JpcHQNCiAgICAgICAgICAgIGJyZWFrU2NyaXB0QnV0dG9uKCk7DQogICAgICAgICAgICBRKCdjb21waWxlZGFyZWEnKS52YWx1ZSA9IHJzdHIyaGV4KHNjcmlwdF9jb21waWxlKFEoJ3NjcmlwdGFyZWEnKS52YWx1ZSwgZnVuY3Rpb24obSkgeyBtZXNzYWdlYm94KCJTY3JpcHQgQ29tcGlsZSBFcnJvciIsIG0pOyB9KSk7DQogICAgICAgICAgICBkZWxldGUgZWRpdHNjcmlwdHN0YXRlOw0KDQogICAgICAgICAgICAvLyBSZXNldCB0aGUgc2NyaXB0IGVudmlyb25tZW50DQogICAgICAgICAgICBRKCdjb25zb2xlJykudmFsdWUgPSAnJzsNCiAgICAgICAgICAgIFFIKCd2YXJpYWJsZXMnLCAnJyk7DQogICAgICAgICAgICBRSCgnRWRpdFNjcmlwdFN0YXR1cycsICdTdG9wcGVkJyk7DQogICAgICAgICAgICBpZiAoc2NyaXB0X0J1aWxkZXJWaWV3ID09IDEpIHsgZnVwZGF0ZXNjcmlwdCgpOyB9DQogICAgICAgICAgICBpZiAoUSgnY29tcGlsZWRhcmVhJykudmFsdWUubGVuZ3RoID09IDApIHJldHVybjsNCg0KICAgICAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IHNjcmlwdCBydW50aW1lIG9iamVjdA0KICAgICAgICAgICAgdmFyIHN0YXJ0dmFycyA9IHsgJ19pbnRlcmFjdGl2ZSc6MSB9Ow0KDQogICAgICAgICAgICBzdGFydHZhcnNbJ19jZXJ0aWZpY2F0ZXMnXSA9IDE7DQoNCiAgICAgICAgICAgIHN0YXJ0dmFyc1snX21vZGUnXSA9ICdGaXJtd2FyZSc7DQoNCiAgICAgICAgICAgIHN0YXJ0dmFyc1snX21vZGUnXSA9ICdNZXNoQ2VudHJhbDInOw0KDQogICAgICAgICAgICBzdGFydHZhcnNbJ19tb2RlJ10gPSAnTE1TJzsNCiAgICAgICAgICAgIGVkaXRzY3JpcHRzdGF0ZSA9IHNjcmlwdF9zZXR1cChoZXgycnN0cihRKCdjb21waWxlZGFyZWEnKS52YWx1ZSksIHN0YXJ0dmFycyk7DQogICAgICAgICAgICBlZGl0c2NyaXB0c3RhdGUud3NzdGFjayA9IHdzc3RhY2s7DQogICAgICAgICAgICBlZGl0c2NyaXB0c3RhdGUuYW10c3RhY2sgPSBhbXRzdGFjazsNCiAgICAgICAgICAgIGVkaXRzY3JpcHRzdGF0ZS5vblN0ZXAgPSBlZGl0c2NyaXB0X3VwZGF0ZVNjcmlwdFN0YXRlOw0KICAgICAgICAgICAgZWRpdHNjcmlwdHN0YXRlLm9uQ29uc29sZSA9IGVkaXRzY3JpcHRfY29uc29sZTsNCiAgICAgICAgICAgIGVkaXRzY3JpcHRfdXBkYXRlU2NyaXB0U3RhdGUoZWRpdHNjcmlwdHN0YXRlKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIFN0YXJ0IHJ1bm5pbmcgdGhlIHNjcmlwdA0KICAgICAgICBmdW5jdGlvbiBydW5TY3JpcHRCdXR0b24oKSB7DQogICAgICAgICAgICBpZiAoZWRpdHNjcmlwdHN0YXRlID09IG51bGwpIHJlc2V0U2NyaXB0QnV0dG9uKCk7DQogICAgICAgICAgICBpZiAoZWRpdHNjcmlwdHN0YXRlID09IG51bGwpIHJldHVybjsNCiAgICAgICAgICAgIGVkaXRzY3JpcHRzdGF0ZS5zdGFydCgxMDApOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gU3RvcC9QYXVzZSB0aGUgc2NyaXB0DQogICAgICAgIGZ1bmN0aW9uIGJyZWFrU2NyaXB0QnV0dG9uKCkgew0KICAgICAgICAgICAgaWYgKGVkaXRzY3JpcHRzdGF0ZSA9PSBudWxsKSByZXR1cm47DQogICAgICAgICAgICBlZGl0c2NyaXB0c3RhdGUuc3RvcCgpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gUnVuIG9uZSBzdGVwIG9mIHRoZSBzY3JpcHQNCiAgICAgICAgZnVuY3Rpb24gc3RlcFNjcmlwdEJ1dHRvbigpIHsNCiAgICAgICAgICAgIGlmIChlZGl0c2NyaXB0c3RhdGUgPT0gbnVsbCkgcmVzZXRTY3JpcHRCdXR0b24oKTsNCiAgICAgICAgICAgIGlmIChlZGl0c2NyaXB0c3RhdGUgPT0gbnVsbCkgcmV0dXJuOw0KICAgICAgICAgICAgYnJlYWtTY3JpcHRCdXR0b24oKTsNCiAgICAgICAgICAgIGVkaXRzY3JpcHRzdGF0ZS5zdGVwKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBEaXNwbGF5IGEgbmV3IGxpbmUgaW50byB0aGUgc2NyaXB0IGNvbnNvbGUNCiAgICAgICAgZnVuY3Rpb24gZWRpdHNjcmlwdF9jb25zb2xlKG1zZykgew0KICAgICAgICAgICAgUSgnY29uc29sZScpLnZhbHVlICs9IChtc2cgKyAnXG4nKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIFVwZGF0ZSB0aGUgc2NyaXB0IHN0YXRlIGluZm9ybWF0aW9uIGFuZCBkaXNwbGF5ZWQgdmFyaWFibGVzDQogICAgICAgIHZhciBzY3JpcHRfc3RhdGVzID0gWydTdG9wcGVkJywgJ1J1bm5pbmcnLCAnUGF1c2VkJ107DQogICAgICAgIGZ1bmN0aW9uIGVkaXRzY3JpcHRfdXBkYXRlU2NyaXB0U3RhdGUocnVuc3RhdGUpIHsNCiAgICAgICAgICAgIC8vIFVwZGF0ZSB2YXJpYWJsZXMNCiAgICAgICAgICAgIHZhciByID0gJyc7DQogICAgICAgICAgICBpZiAocnVuc3RhdGUgJiYgcnVuc3RhdGUgIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgIHZhciB2cyA9IFtdOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gcnVuc3RhdGUudmFyaWFibGVzKSB7IGlmICghaS5zdGFydHNXaXRoKCdfXycpKSB2cy5wdXNoKGkpOyB9DQogICAgICAgICAgICAgICAgdnMuc29ydCgpOw0KICAgICAgICAgICAgICAgIC8vZm9yICh2YXIgaSBpbiB2cykgeyByICs9IHZzW2ldICsgIiA9ICIgKyBzY3JpcHRfdG9TdHJpbmcocnVuc3RhdGUudmFyaWFibGVzW3ZzW2ldXSkgKyAiXG4iOyB9DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB2cykgew0KICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJ1bnN0YXRlLnZhcmlhYmxlc1t2c1tpXV0gPT0gJ29iamVjdCcpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHIgKz0gIjxiPiIgKyB2c1tpXSArICI8L2I+ID0gIiArIE9iamVjdFRvU3RyaW5nRXgocnVuc3RhdGUudmFyaWFibGVzW3ZzW2ldXSwgMikgKyAiPGJyPiI7DQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICByICs9ICI8Yj4iICsgdnNbaV0gKyAiPC9iPiA9ICIgKyBFc2NhcGVIdG1sKHNjcmlwdF90b1N0cmluZyhydW5zdGF0ZS52YXJpYWJsZXNbdnNbaV1dKSkgKyAiPGJyPiI7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICBRSCgndmFyaWFibGVzJywgcik7DQoNCiAgICAgICAgICAgIC8vIFVwZGF0ZSBzdGF0ZQ0KICAgICAgICAgICAgciA9ICdTdG9wcGVkLCBObyBTY3JpcHQnOw0KICAgICAgICAgICAgaWYgKHJ1bnN0YXRlICYmIHJ1bnN0YXRlICE9IG51bGwpIHsgciA9IHNjcmlwdF9zdGF0ZXNbcnVuc3RhdGUuc3RhdGVdOyBpZiAocnVuc3RhdGUuc3RhdGUgPiAwKSByICs9ICIsICIgKyBydW5zdGF0ZS5pcCArICIgOiAiICsgc2NyaXB0X2RlY29tcGlsZShydW5zdGF0ZS5zY3JpcHQsIHJ1bnN0YXRlLmlwKTsgfQ0KICAgICAgICAgICAgaWYgKHIubGVuZ3RoID4gNTApIHsgciA9IHIuc3Vic3RyaW5nKDAsIDUwKSArICIuLi4iOyB9DQogICAgICAgICAgICBRSCgnRWRpdFNjcmlwdFN0YXR1cycsIHIpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gUmV0dXJuIGEgc3RyaW5nIGZyb20gYW55IGlucHV0LCBpZiB0aGUgaW5wdXQgaXMgYW4gb2JqZWN0LCBzdHJpbmdpZnkgaXQuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF90b1N0cmluZyh4KSB7IGlmICh0eXBlb2YgeCA9PSAnb2JqZWN0JykgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHgpOyByZXR1cm4geDsgfQ0KDQoNCiAgICAgICAgLy8gU2F2ZSBhIHNjcmlwdCB0byBkaXNrLCBzdGFydCBieSBzaG93aW5nIGEgZGlhbG9nIGJveCB0byBwcm9tcHQgdG8gdGhlIGZpbGVuYW1lLg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRfc2F2ZVNjcmlwdChlKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlIHx8IHNjcmlwdHN0YXRlKSByZXR1cm47DQogICAgICAgICAgICBpZiAoZSAmJiAoZS5zaGlmdEtleSA9PSB0cnVlKSkgew0KICAgICAgICAgICAgICAgIC8vIFNhdmUgYXMgc2NyaXB0IGJsb2NrDQogICAgICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIlNjcmlwdCBCbG9jayIsIDEsIG51bGwsICI8YnI+PHRleHRhcmVhIGlkPXNjcmlwdFNhdmVTY3JpcHRKc29uQmxvY2sgc3R5bGU9d2lkdGg6MTAwJTtoZWlnaHQ6MjAwcHg7cmVzaXplOnZlcnRpY2FsIC8+Iik7DQogICAgICAgICAgICAgICAgUUgoJ3NjcmlwdFNhdmVTY3JpcHRKc29uQmxvY2snLCBzY3JpcHRfZkNvbnZlcnRTY3JpcHRUb0pzb25CbG9jayhRKCdzY3JpcHRhcmVhJykudmFsdWUpKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gU2F2ZSBhcyAubWVzY3JpcHQgZmlsZQ0KDQogICAgICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIlNhdmUgU2NyaXB0IiwgMywgc2NyaXB0X3NhdmVTY3JpcHRPaywgIjxicj48aW5wdXQgaWQ9c2NyaXB0c2F2ZW5hbWUgc3R5bGU9d2lkdGg6MTAwJSB2YWx1ZT10ZXN0Lm1lc2NyaXB0ID4iKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIE9uY2UgdGhlIGZpbGVuYW1lIGlzIHNlbGVjdGVkLCBzYXZlIHRoZSBmaWxlLg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRfc2F2ZVNjcmlwdE9rKCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHggPSBKU09OLnN0cmluZ2lmeSh7DQogICAgICAgICAgICAgICAgInNjcmlwdFRleHQiOiBRKCdzY3JpcHRhcmVhJykudmFsdWUsDQogICAgICAgICAgICAgICAgIm1lc2NyaXB0IjogYnRvYShzY3JpcHRfY29tcGlsZShRKCdzY3JpcHRhcmVhJykudmFsdWUpKSwNCiAgICAgICAgICAgICAgICAiYmxvY2tzIjogc2NyaXB0X1N0YXJ0aW5nQnVpbGRpbmdCbG9ja3MsDQogICAgICAgICAgICAgICAgInNjcmlwdEJsb2NrcyI6IHNjcmlwdF9CbG9ja1NjcmlwdA0KICAgICAgICAgICAgfSwgbnVsbCwgJyAgJyk7DQogICAgICAgICAgICBzYXZlQXMoZGF0YTJibG9iKHgpLCBRKCdzY3JpcHRzYXZlbmFtZScpLnZhbHVlKTsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgDQoNCg0KICAgICAgICAvLw0KICAgICAgICAvLyBVU0IgU0VUVVAuQklODQogICAgICAgIC8vDQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX25ld1NldHVwQmluKCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgaWR4X2QxNHZlcnNpb24udmFsdWUgPSA0Ow0KICAgICAgICAgICAgaWR4X2QxNGNvbnN1bWUudmFsdWUgPSAxOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxNCwgIkNyZWF0ZSBuZXcgU2V0dXAuYmluIGZpbGUiLCAzLCB1c2JfbmV3U2V0dXBCaW5Payk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2JfbmV3U2V0dXBCaW5PayhyKSB7DQogICAgICAgICAgICBpZiAociA9PSAxKSB7IHNldHVwYmluID0gQW10U2V0dXBCaW5DcmVhdGUoaWR4X2QxNHZlcnNpb24udmFsdWUsIGlkeF9kMTRjb25zdW1lLnZhbHVlKTsgfSAvLyBPSyBCdXR0b24NCiAgICAgICAgICAgIHVzYl9kaXNwbGF5U2V0dXBCaW4oKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9vcGVuU2V0dXBCaW4oKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQoNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTUsICJPcGVuIFNldHVwLmJpbiBmaWxlIiwgMywgdXNiX29wZW5TZXR1cEJpbk9rKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9vcGVuU2V0dXBCaW5PaygpIHsNCiAgICAgICAgICAgIHZhciB4ID0gUSgnZDE1c2V0dXBiaW5maWxlJyk7DQogICAgICAgICAgICBpZiAoeC5maWxlcy5sZW5ndGggIT0gMSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7DQogICAgICAgICAgICByZWFkZXIub25sb2FkID0gdXNiX29uU2V0dXBCaW5SZWFkOw0KICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyh4LmZpbGVzWzBdKTsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX3NhdmVTZXR1cEJpbigpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgfHwgIXNldHVwYmluKSByZXR1cm47DQoNCiAgICAgICAgICAgIHNhdmVBcyhkYXRhMmJsb2IoQW10U2V0dXBCaW5FbmNvZGUoc2V0dXBiaW4pKSwgInNldHVwLmJpbiIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX29uU2V0dXBCaW5SZWFkKGZpbGUpIHsNCiAgICAgICAgICAgIHNldHVwYmluID0gQW10U2V0dXBCaW5EZWNvZGUoZmlsZS50YXJnZXQucmVzdWx0KTsNCiAgICAgICAgICAgIGlmICghc2V0dXBiaW4pIHsgbWVzc2FnZWJveCgiT3BlbiBGaWxlIiwgIkludmFsaWQgb3IgY29ycnVwdCBzZXR1cC5iaW4gZmlsZS4gVW5hYmxlIHRvIG9wZW4uIik7IH0gZWxzZSB7IHVzYl9kaXNwbGF5U2V0dXBCaW4oKTsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2Rpc3BsYXlTZXR1cEJpbigpIHsNCiAgICAgICAgICAgIFFWKCdpZF9TdGFydHVwU2NyZWVuJywgIXNldHVwYmluKTsNCg0KICAgICAgICAgICAgUVYoJ2lkX3NhdmVTZXR1cEJpbicsIHNldHVwYmluKTsNCiAgICAgICAgICAgIGlmICghc2V0dXBiaW4pIHsgcmV0dXJuIFFIKCdpZF9TZXR1cEJpbkFyZWEnLCAnJyk7IH0NCiAgICAgICAgICAgIA0KICAgICAgICAgICAgLy8gVXBkYXRlIHJlY29yZCBjb3VudA0KICAgICAgICAgICAgdmFyIGNvbnN1bWVkID0gMDsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gc2V0dXBiaW4ucmVjb3JkcykgeyBpZiAoKHNldHVwYmluLnJlY29yZHNbaV0uZmxhZ3MgJiAxKSA9PSAwKSB7IGNvbnN1bWVkKys7IH0gfQ0KICAgICAgICAgICAgc2V0dXBiaW4uZGF0YVJlY29yZHNDb25zdW1lZCA9IGNvbnN1bWVkOw0KDQogICAgICAgICAgICAvLyBNYWluIEhlYWRlciAgICAgICAgICAgIA0KICAgICAgICAgICAgdmFyIHggPSAiPHRhYmxlIG9uY2xpY2s9dXNiX2VkaXRoZWFkZXIoZXZlbnQpIGNsYXNzPSdsb2cxIHVzJyBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgc3R5bGU9d2lkdGg6MTAwJTtib3JkZXItcmFkaXVzOjhweDtjdXJzb3I6cG9pbnRlcj48dHI+PHRkPjxwPjx0ZD4iOw0KICAgICAgICAgICAgeCArPSAiPHRyPjx0ZCBjbGFzcz1yMiBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweD4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1mbG9hdDpyaWdodDttYXJnaW4tcmlnaHQ6MTJweCBvbmNsaWNrPXVzYl9hZGRSZWNvcmRTZXR1cEJpbigpPjxhPjx1IHRpdGxlPSdBZGQgYSBuZXcgcmVjb3JkJz5BZGQgUmVjb3JkPC91PjwvYT48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdj48c3Ryb25nPkludGVsJnJlZzsgQU1UIFNldHVwLmJpbiBmaWxlIHZlcnNpb24gIiArIHNldHVwYmluLm1ham9yVmVyc2lvbiArICIuIiArIHNldHVwYmluLm1pbm9yVmVyc2lvbiArICI8L3N0cm9uZz4uPC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gKCgoc2V0dXBiaW4uZmxhZ3MgJiAxKSA9PSAwKSA/ICJSZWNvcmRzIHdpbGwgYmUgY29uc3VtZWQuIiA6ICJSZWNvcmRzIHdpbGwgbm90IGJlIGNvbnN1bWVkLiIpOw0KICAgICAgICAgICAgeCArPSAiPGJyPlJlY29yZHM6ICIgKyBzZXR1cGJpbi5yZWNvcmRzLmxlbmd0aCArICIsIENvbnN1bWVkOiAiICsgc2V0dXBiaW4uZGF0YVJlY29yZHNDb25zdW1lZCArICI8YnI+IjsNCiAgICAgICAgICAgIHggKz0gIjx0ciBzdHlsZT1oZWlnaHQ6NHB4PjwvdGFibGU+IjsNCg0KICAgICAgICAgICAgLy8gRGlzcGxheSBlYWNoIHJlY29yZA0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBzZXR1cGJpbi5yZWNvcmRzKSB7DQogICAgICAgICAgICAgICAgdmFyIHJlYyA9IHNldHVwYmluLnJlY29yZHNbaV07DQogICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6NHB4PjwvZGl2Pjx0YWJsZSBjbGFzcz0nbG9nMSB1cycgY2VsbHBhZGRpbmc9MCBjZWxsc3BhY2luZz0wIHN0eWxlPXdpZHRoOjEwMCU7Ym9yZGVyLXJhZGl1czo4cHg+PHRyPjx0ZD48cD48dGQ+PHRyPjx0ZCBjbGFzcz1yMiBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweDtjdXJzb3I6cG9pbnRlcj4iOw0KICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9ZmxvYXQ6cmlnaHQ7bWFyZ2luLXJpZ2h0OjEycHggb25jbGljaz0ndXNiX2FkZHZhcmlhYmxlKGV2ZW50LCIgKyBpICsgIiknPjxhPjx1IHRpdGxlPSdBZGQgYSBuZXcgdmFyaWFibGUnPkFkZCBWYXJpYWJsZTwvdT48L2E+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IG9uY2xpY2s9J3VzYl9lZGl0cmVjb3JkKGV2ZW50LCAiICsgaSArICIpJz5SZWNvcmQgIzxzdHJvbmc+IiArICgraSArIDEpICsgIjwvc3Ryb25nPi4gVGhpcyByZWNvcmQgaXM6IDxzdHJvbmc+IiArICgocmVjLmZsYWdzICYgMSkgPyAiVmFsaWQiIDogIkNvbnN1bWVkIikgKyAoKHJlYy5mbGFncyAmIDIpID8gIiwgU2NyYW1ibGVkIiA6ICIiKSArICI8L3N0cm9uZz48L2Rpdj4iOw0KDQogICAgICAgICAgICAgICAgLy8gRGlzcGxheSBlYWNoIHZhcmlhYmxlDQogICAgICAgICAgICAgICAgZm9yICh2YXIgaiBpbiByZWMudmFyaWFibGVzKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciB2ID0gcmVjLnZhcmlhYmxlc1tqXSwgdmFsID0gdi52YWx1ZTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKEFtdFNldHVwQmluVmFySWRzW3YubW9kdWxlaWRdW3YudmFyaWRdWzJdICYmIEFtdFNldHVwQmluVmFySWRzW3YubW9kdWxlaWRdW3YudmFyaWRdWzJdW3ZhbF0pIHsgdmFsID0gQW10U2V0dXBCaW5WYXJJZHNbdi5tb2R1bGVpZF1bdi52YXJpZF1bMl1bdmFsXTsgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAodi5tb2R1bGVpZCA9PSAyICYmIHYudmFyaWQgPT0gOCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2h0eXBlID0gdmFsLmNoYXJDb2RlQXQoMCk7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzaHR5cGUgPj0gMCAmJiBoYXNodHlwZSA8PSAzKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2hzaXplID0gWzIwLCAzMiwgNDhdW2hhc2h0eXBlIC0gMV07DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2ggPSByc3RyMmhleCh2YWwuc3Vic3RyaW5nKDEsIGhhc2hzaXplICsgMSkpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYXNobmFtZXNpemUgPSB2YWwuY2hhckNvZGVBdCgxICsgaGFzaHNpemUpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYXNobmFtZSA9IHZhbC5zdWJzdHJpbmcoMiArIGhhc2hzaXplLCAyICsgaGFzaHNpemUgKyBoYXNobmFtZXNpemUpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsID0gWydTSEExJywgJ1NIQTI1NicsICdTSEEzODQnXVtoYXNodHlwZSAtIDFdICsgJywgJyArIGhhc2huYW1lICsgJywgJyArIGhhc2g7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1tYXJnaW4tcmlnaHQ6MTJweD48dGFibGUgb25jbGljaz0ndXNiX2VkaXR2YXJpYWJsZShldmVudCwgIiArIGkgKyAiLCIgKyBqICsgIiknIGNsYXNzPSdpdGVtQmFyIHVzJyBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgc3R5bGU9d2lkdGg6MTAwJTtib3JkZXItcmFkaXVzOjRweDttYXJnaW4tdG9wOjJweDttYXJnaW4tYm90dG9tOjJweDtwYWRkaW5nOjA+PHRyPjx0ZD48cCBzdHlsZT1mbG9hdDpyaWdodDttYXJnaW4tcmlnaHQ6OHB4PjxiPiIgKyB2YWwgKyAiPC9iPjxwPiIgKyB2WydkZXNjJ10gKyAiPHRyIHN0eWxlPWhlaWdodDo0cHg+PC90YWJsZT48L2Rpdj4iOw0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIHggKz0gIjx0ciBzdHlsZT1oZWlnaHQ6NHB4PjwvdGFibGU+IjsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgUUgoJ2lkX1NldHVwQmluQXJlYScsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2FkZFJlY29yZFNldHVwQmluKCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgZDEzdmFsaWQuY2hlY2tlZCA9IDE7DQogICAgICAgICAgICBkMTNzY3JhbWJsZS5jaGVja2VkID0gMDsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTMsICJOZXcgUmVjb3JkICMiLCAzLCB1c2JfYWRkUmVjb3JkU2V0dXBCaW5Payk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2JfYWRkUmVjb3JkU2V0dXBCaW5PaygpIHsNCiAgICAgICAgICAgIHZhciByID0ge307DQogICAgICAgICAgICByLnR5cGVJZGVudGlmaWVyID0gMTsNCiAgICAgICAgICAgIHIuZmxhZ3MgPSAoZDEzdmFsaWQuY2hlY2tlZCA/IDEgOiAwKSArIChkMTNzY3JhbWJsZS5jaGVja2VkID8gMiA6IDApOw0KICAgICAgICAgICAgci5jaHVua0NvdW50ID0gMDsNCiAgICAgICAgICAgIHIuaGVhZGVyQnl0ZUNvdW50ID0gMDsNCiAgICAgICAgICAgIHIubnVtYmVyID0gMDsNCiAgICAgICAgICAgIHIudmFyaWFibGVzID0gW107DQogICAgICAgICAgICBzZXR1cGJpbi5yZWNvcmRzLnB1c2gocik7DQogICAgICAgICAgICB1c2JfZGlzcGxheVNldHVwQmluKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2JfZWRpdGhlYWRlcihlKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQogICAgICAgICAgICBpZHhfZDE0dmVyc2lvbi52YWx1ZSA9IHNldHVwYmluLm1ham9yVmVyc2lvbjsNCiAgICAgICAgICAgIGlkeF9kMTRjb25zdW1lLnZhbHVlID0gKHNldHVwYmluLmZsYWdzICYgMSk7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDE0LCAiRWRpdCBIZWFkZXIiLCA3LCB1c2JfZWRpdGhlYWRlcm9rKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9lZGl0aGVhZGVyb2socikgew0KICAgICAgICAgICAgaWYgKHIgPT0gMikgew0KICAgICAgICAgICAgICAgIGRlbGV0ZSBzZXR1cGJpbjsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgc2V0dXBiaW4ubWFqb3JWZXJzaW9uID0gaWR4X2QxNHZlcnNpb24udmFsdWU7DQogICAgICAgICAgICAgICAgc2V0dXBiaW4uZmxhZ3MgPSBpZHhfZDE0Y29uc3VtZS52YWx1ZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHVzYl9kaXNwbGF5U2V0dXBCaW4oKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9lZGl0cmVjb3JkKGUsIGkpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHNlbGVjdGVkUmVjb3JkID0gaTsNCiAgICAgICAgICAgIHNlbGVjdGVkVmFyaWFibGUgPSAtMTsNCiAgICAgICAgICAgIGhhbHRFdmVudChlKTsNCiAgICAgICAgICAgIGQxM3ZhbGlkLmNoZWNrZWQgPSAoc2V0dXBiaW4ucmVjb3Jkc1tzZWxlY3RlZFJlY29yZF0uZmxhZ3MgJiAxKTsNCiAgICAgICAgICAgIGQxM3NjcmFtYmxlLmNoZWNrZWQgPSAoc2V0dXBiaW4ucmVjb3Jkc1tzZWxlY3RlZFJlY29yZF0uZmxhZ3MgJiAyKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTMsICJFZGl0IFJlY29yZCAjIiArIChpICsgMSksIDcsIHVzYl9lZGl0cmVjb3Jkb2spOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2VkaXRyZWNvcmRvayhyKSB7DQogICAgICAgICAgICBpZiAociA9PSAxKSB7IHNldHVwYmluLnJlY29yZHNbc2VsZWN0ZWRSZWNvcmRdLmZsYWdzID0gKGQxM3ZhbGlkLmNoZWNrZWQgPyAxIDogMCkgKyAoZDEzc2NyYW1ibGUuY2hlY2tlZCA/IDIgOiAwKTsgfSAvLyBFZGl0IFJlY29yZA0KICAgICAgICAgICAgaWYgKHIgPT0gMikgeyBzZXR1cGJpbi5yZWNvcmRzLnNwbGljZShzZWxlY3RlZFJlY29yZCwgMSk7IH0gLy8gRGVsZXRlIFJlY29yZA0KICAgICAgICAgICAgdXNiX2Rpc3BsYXlTZXR1cEJpbigpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2VkaXR2YXJpYWJsZShlLCBpLCBqKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBzZWxlY3RlZFJlY29yZCA9IGk7DQogICAgICAgICAgICBzZWxlY3RlZFZhcmlhYmxlID0gajsNCiAgICAgICAgICAgIHZhciBtb2RpZCA9IHNldHVwYmluLnJlY29yZHNbaV0udmFyaWFibGVzW2pdLm1vZHVsZWlkOw0KICAgICAgICAgICAgdmFyIHZhcmlkID0gc2V0dXBiaW4ucmVjb3Jkc1tpXS52YXJpYWJsZXNbal0udmFyaWQ7DQogICAgICAgICAgICBkMTZ0eXBlLnZhbHVlID0gbW9kaWQgKyAiLSIgKyB2YXJpZDsNCiAgICAgICAgICAgIGQxNnR5cGUuZGlzYWJsZWQgPSB0cnVlOw0KICAgICAgICAgICAgdXNiX29uZDE2dHlwZWNoYW5nZSgpOw0KICAgICAgICAgICAgUVYoJ2QxNmdlbmVyaWN2YWx1ZScsIGZhbHNlKTsNCiAgICAgICAgICAgIFFWKCdkMTZjdXN0b212YWx1ZScsIGZhbHNlKTsNCiAgICAgICAgICAgIGlmIChtb2RpZCA9PSAyICYmIHZhcmlkID09IDgpIHsNCiAgICAgICAgICAgICAgICB2YXIgeCA9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxzZWxlY3QgaWQ9aWR4X2QxNnZhbGMxIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG9uY2hhbmdlPXVzYl9vbmQxNmNoZWNraGFzaCgpPjxvcHRpb24gdmFsdWU9MT5TSEExPC9vcHRpb24+JzsNCiAgICAgICAgICAgICAgICBpZiAoc2V0dXBiaW4ubWFqb3JWZXJzaW9uID49IDMpIHsgeCArPSAnPG9wdGlvbiB2YWx1ZT0yPlNIQTI1Njwvb3B0aW9uPjxvcHRpb24gdmFsdWU9Mz5TSEEzODQ8L29wdGlvbj4nOyB9DQogICAgICAgICAgICAgICAgeCArPSAnPC9zZWxlY3Q+PGRpdj5IYXNoIFR5cGU8L2Rpdj48L2Rpdj4nOw0KICAgICAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PGlucHV0IGlkPWlkeF9kMTZ2YWxjMiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjBweCBvbmtleXVwPXVzYl9vbmQxNmNoZWNraGFzaCgpPjxkaXY+SGFzaCAoSEVYKTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICAgICAgeCArPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48aW5wdXQgaWQ9aWR4X2QxNnZhbGMzIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG9ua2V5dXA9dXNiX29uZDE2Y2hlY2toYXNoKCkgbWF4bGVuZ3RoPTMxPjxkaXY+SGFzaCBOYW1lPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgICAgICBRSCgnZDE2Y3VzdG9tdmFsdWUnLCB4KTsNCiAgICAgICAgICAgICAgICBRVignZDE2Y3VzdG9tdmFsdWUnLCB0cnVlKTsNCiAgICAgICAgICAgICAgICB2YXIgdmFsID0gc2V0dXBiaW4ucmVjb3Jkc1tpXS52YXJpYWJsZXNbal0udmFsdWU7DQogICAgICAgICAgICAgICAgdmFyIGhhc2h0eXBlID0gdmFsLmNoYXJDb2RlQXQoMCk7DQogICAgICAgICAgICAgICAgaWYgKGhhc2h0eXBlID49IDAgJiYgaGFzaHR5cGUgPD0gMykgew0KICAgICAgICAgICAgICAgICAgICB2YXIgaGFzaHNpemUgPSBbMjAsIDMyLCA0OF1baGFzaHR5cGUgLSAxXTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2ggPSByc3RyMmhleCh2YWwuc3Vic3RyaW5nKDEsIGhhc2hzaXplICsgMSkpOw0KICAgICAgICAgICAgICAgICAgICB2YXIgaGFzaG5hbWVzaXplID0gdmFsLmNoYXJDb2RlQXQoMSArIGhhc2hzaXplKTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2huYW1lID0gdmFsLnN1YnN0cmluZygyICsgaGFzaHNpemUsIDIgKyBoYXNoc2l6ZSArIGhhc2huYW1lc2l6ZSkNCiAgICAgICAgICAgICAgICAgICAgdmFsID0gWydTSEExJywgJ1NIQTI1NicsICdTSEEzODQnXVtoYXNodHlwZSAtIDFdICsgJywgJyArIGhhc2huYW1lICsgJywgJyArIGhhc2g7DQogICAgICAgICAgICAgICAgICAgIFEoJ2lkeF9kMTZ2YWxjMScpLnZhbHVlID0gaGFzaHR5cGU7DQogICAgICAgICAgICAgICAgICAgIFEoJ2lkeF9kMTZ2YWxjMicpLnZhbHVlID0gaGFzaDsNCiAgICAgICAgICAgICAgICAgICAgUSgnaWR4X2QxNnZhbGMzJykudmFsdWUgPSBoYXNobmFtZTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgdXNiX29uZDE2Y2hlY2toYXNoKCk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFFWKCdkMTZnZW5lcmljdmFsdWUnLCB0cnVlKTsNCiAgICAgICAgICAgICAgICBpZHhfZDE2dmFsdWUxLnZhbHVlID0gaWR4X2QxNnZhbHVlMi52YWx1ZSA9IHNldHVwYmluLnJlY29yZHNbaV0udmFyaWFibGVzW2pdLnZhbHVlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaGFsdEV2ZW50KGUpOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxNiwgIkVkaXQgUmVjb3JkICMiICsgKGkgKyAxKSArICIsIFZhcmlhYmxlICMiICsgKGogKyAxKSwgNywgdXNiX2VkaXR2YXJpYWJsZW9rKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9lZGl0dmFyaWFibGVvayhyKSB7DQogICAgICAgICAgICBpZiAociA9PSAxKSB7IC8vIE9LDQogICAgICAgICAgICAgICAgdmFyIGlkcyA9IGQxNnR5cGUudmFsdWUuc3BsaXQoJy0nKTsNCiAgICAgICAgICAgICAgICB2YXIgbW9kaWQgPSAraWRzWzBdOw0KICAgICAgICAgICAgICAgIHZhciB2YXJpZCA9ICtpZHNbMV07DQogICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gIiI7DQogICAgICAgICAgICAgICAgdmFyIHZhcmRlc2NyaXB0aW9uID0gQW10U2V0dXBCaW5WYXJJZHNbbW9kaWRdW3ZhcmlkXTsNCiAgICAgICAgICAgICAgICBpZiAobW9kaWQgPT0gMiAmJiB2YXJpZCA9PSA4KSB7DQogICAgICAgICAgICAgICAgICAgIHZhbHVlID0gU3RyaW5nLmZyb21DaGFyQ29kZShRKCdpZHhfZDE2dmFsYzEnKS52YWx1ZSkgKyBoZXgycnN0cihRKCdpZHhfZDE2dmFsYzInKS52YWx1ZSkgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKFEoJ2lkeF9kMTZ2YWxjMycpLnZhbHVlLmxlbmd0aCkgKyBRKCdpZHhfZDE2dmFsYzMnKS52YWx1ZTsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBpZiAodmFyZGVzY3JpcHRpb25bMl0pIHsgdmFsdWUgPSBpZHhfZDE2dmFsdWUxLnZhbHVlOyB9IGVsc2UgeyB2YWx1ZSA9IGlkeF9kMTZ2YWx1ZTIudmFsdWU7IH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgc2V0dXBiaW4ucmVjb3Jkc1tzZWxlY3RlZFJlY29yZF0udmFyaWFibGVzW3NlbGVjdGVkVmFyaWFibGVdLnZhbHVlID0gdmFsdWU7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAociA9PSAyKSB7IHNldHVwYmluLnJlY29yZHNbc2VsZWN0ZWRSZWNvcmRdLnZhcmlhYmxlcy5zcGxpY2Uoc2VsZWN0ZWRWYXJpYWJsZSwgMSk7IH0gLy8gRGVsZXRlDQogICAgICAgICAgICB1c2JfZGlzcGxheVNldHVwQmluKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2JfYWRkdmFyaWFibGUoZSwgaSkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgc2VsZWN0ZWRSZWNvcmQgPSBpOw0KICAgICAgICAgICAgZDE2dHlwZS52YWx1ZSA9ICIxLTEiOw0KICAgICAgICAgICAgZDE2dHlwZS5kaXNhYmxlZCA9IGZhbHNlOw0KICAgICAgICAgICAgaWR4X2QxNnZhbHVlMS52YWx1ZSA9IGlkeF9kMTZ2YWx1ZTIudmFsdWUgPSAiIjsNCiAgICAgICAgICAgIHVzYl9vbmQxNnR5cGVjaGFuZ2UoKTsNCiAgICAgICAgICAgIGhhbHRFdmVudChlKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTYsICJBZGQgVmFyaWFibGUgdG8gUmVjb3JkICMiICsgKGkgKyAxKSwgMywgdXNiX2FkZHZhcmlhYmxlb2spOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2FkZHZhcmlhYmxlb2soKSB7DQogICAgICAgICAgICB2YXIgaWRzID0gZDE2dHlwZS52YWx1ZS5zcGxpdCgnLScpOw0KICAgICAgICAgICAgdmFyIG1vZGlkID0gK2lkc1swXTsNCiAgICAgICAgICAgIHZhciB2YXJpZCA9ICtpZHNbMV07DQogICAgICAgICAgICB2YXIgdmFsdWUgPSAiIjsNCiAgICAgICAgICAgIHZhciB2YXJkZXNjcmlwdGlvbiA9IEFtdFNldHVwQmluVmFySWRzW21vZGlkXVt2YXJpZF07DQogICAgICAgICAgICBpZiAobW9kaWQgPT0gMiAmJiB2YXJpZCA9PSA4KSB7DQogICAgICAgICAgICAgICAgdmFsdWUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKFEoJ2lkeF9kMTZ2YWxjMScpLnZhbHVlKSArIGhleDJyc3RyKFEoJ2lkeF9kMTZ2YWxjMicpLnZhbHVlKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoUSgnaWR4X2QxNnZhbGMzJykudmFsdWUubGVuZ3RoKSArIFEoJ2lkeF9kMTZ2YWxjMycpLnZhbHVlOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBpZiAodmFyZGVzY3JpcHRpb25bMl0pIHsgdmFsdWUgPSBpZHhfZDE2dmFsdWUxLnZhbHVlOyB9IGVsc2UgeyB2YWx1ZSA9IGlkeF9kMTZ2YWx1ZTIudmFsdWU7IH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IHZhcmlhYmxlDQogICAgICAgICAgICB2YXIgdiA9IHt9Ow0KICAgICAgICAgICAgdi5tb2R1bGVpZCA9IG1vZGlkOw0KICAgICAgICAgICAgdi52YXJpZCA9IHZhcmlkOw0KICAgICAgICAgICAgdi5sZW5ndGggPSAtMTsNCiAgICAgICAgICAgIHYudHlwZSA9IEFtdFNldHVwQmluVmFySWRzW21vZGlkXVt2YXJpZF1bMF07DQogICAgICAgICAgICB2LmRlc2MgPSBBbXRTZXR1cEJpblZhcklkc1ttb2RpZF1bdmFyaWRdWzFdOw0KICAgICAgICAgICAgdi52YWx1ZSA9IHZhbHVlOw0KICAgICAgICAgICAgc2V0dXBiaW4ucmVjb3Jkc1tzZWxlY3RlZFJlY29yZF0udmFyaWFibGVzLnB1c2godik7DQoNCiAgICAgICAgICAgIHNldHVwYmluLnJlY29yZHNbc2VsZWN0ZWRSZWNvcmRdLnZhcmlhYmxlcy5zb3J0KEFtdFNldHVwQmluVmFyaWFibGVDb21wYXJlKTsgLy8gU29ydCB0aGUgdmFyaWFibGVzDQogICAgICAgICAgICB1c2JfZGlzcGxheVNldHVwQmluKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2Jfb25kMTZ0eXBlY2hhbmdlKCkgew0KICAgICAgICAgICAgdmFyIGlkcyA9IGQxNnR5cGUudmFsdWUuc3BsaXQoJy0nKTsNCiAgICAgICAgICAgIHZhciBtb2RpZCA9ICtpZHNbMF07DQogICAgICAgICAgICB2YXIgdmFyaWQgPSAraWRzWzFdOw0KICAgICAgICAgICAgdmFyIHZhcmRlc2NyaXB0aW9uID0gQW10U2V0dXBCaW5WYXJJZHNbbW9kaWRdW3ZhcmlkXTsNCiAgICAgICAgICAgIFFWKCdkMTZnZW5lcmljdmFsdWUnLCBmYWxzZSk7DQogICAgICAgICAgICBRVignZDE2Y3VzdG9tdmFsdWUnLCBmYWxzZSk7DQogICAgICAgICAgICBpZiAobW9kaWQgPT0gMiAmJiB2YXJpZCA9PSA4KSB7DQogICAgICAgICAgICAgICAgdmFyIHggPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48c2VsZWN0IGlkPWlkeF9kMTZ2YWxjMSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjBweCBvbmNoYW5nZT11c2Jfb25kMTZjaGVja2hhc2goKT48b3B0aW9uIHZhbHVlPTE+U0hBMTwvb3B0aW9uPic7DQogICAgICAgICAgICAgICAgaWYgKHNldHVwYmluLm1ham9yVmVyc2lvbiA+PSAzKSB7IHggKz0gJzxvcHRpb24gdmFsdWU9Mj5TSEEyNTY8L29wdGlvbj48b3B0aW9uIHZhbHVlPTM+U0hBMzg0PC9vcHRpb24+JzsgfQ0KICAgICAgICAgICAgICAgIHggKz0gJzwvc2VsZWN0PjxkaXY+SGFzaCBUeXBlPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1pZHhfZDE2dmFsYzIgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHggb25rZXl1cD11c2Jfb25kMTZjaGVja2hhc2goKT48ZGl2Pkhhc2ggKEhFWCk8L2Rpdj48L2Rpdj4nOw0KICAgICAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PGlucHV0IGlkPWlkeF9kMTZ2YWxjMyBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjBweCBvbmtleXVwPXVzYl9vbmQxNmNoZWNraGFzaCgpIG1heGxlbmd0aD0zMT48ZGl2Pkhhc2ggTmFtZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICAgICAgUVYoJ2QxNmN1c3RvbXZhbHVlJywgdHJ1ZSk7DQogICAgICAgICAgICAgICAgUUgoJ2QxNmN1c3RvbXZhbHVlJywgeCk7DQogICAgICAgICAgICAgICAgdXNiX29uZDE2Y2hlY2toYXNoKCk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFFWKCdkMTZnZW5lcmljdmFsdWUnLCB0cnVlKTsNCiAgICAgICAgICAgICAgICBpZiAodmFyZGVzY3JpcHRpb25bMl0pIHsNCiAgICAgICAgICAgICAgICAgICAgUVYoJ2lkeF9kMTZ2YWx1ZTEnLCB0cnVlKTsNCiAgICAgICAgICAgICAgICAgICAgUVYoJ2lkeF9kMTZ2YWx1ZTInLCBmYWxzZSk7DQogICAgICAgICAgICAgICAgICAgIHZhciBvcHRpb25zID0gIiI7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gdmFyZGVzY3JpcHRpb25bMl0pIHsgb3B0aW9ucyArPSAnPG9wdGlvbiB2YWx1ZT0iJyArIGkgKyAnIj4nICsgdmFyZGVzY3JpcHRpb25bMl1baV0gfQ0KICAgICAgICAgICAgICAgICAgICBRSCgnaWR4X2QxNnZhbHVlMScsIG9wdGlvbnMpOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIFFWKCdpZHhfZDE2dmFsdWUxJywgZmFsc2UpOw0KICAgICAgICAgICAgICAgICAgICBRVignaWR4X2QxNnZhbHVlMicsIHRydWUpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9vbmQxNmNoZWNraGFzaCgpIHsNCiAgICAgICAgICAgIHZhciBoYXNodHlwZSA9IFEoJ2lkeF9kMTZ2YWxjMScpLnZhbHVlOw0KICAgICAgICAgICAgdmFyIGhhc2hsZW4gPSBoZXgycnN0cihRKCdpZHhfZDE2dmFsYzInKS52YWx1ZSkubGVuZ3RoOw0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIChRKCdpZHhfZDE2dmFsYzMnKS52YWx1ZS5sZW5ndGggPiAwKSAmJiAoKGhhc2h0eXBlID09IDEpICYmIChoYXNobGVuID09IDIwKSkgfHwgKChoYXNodHlwZSA9PSAyKSAmJiAoaGFzaGxlbiA9PSAzMikpIHx8ICgoaGFzaHR5cGUgPT0gMykgJiYgKGhhc2hsZW4gPT0gNDgpKSk7DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgdXNiX2FscGhhYmV0ID0gIjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiI7DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2NvbXB1dGVDaGVja3N1bShzKSB7DQogICAgICAgICAgICB2YXIgQSA9IDA7DQogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHMubGVuZ3RoOyBpKyspIEEgKz0gcy5jaGFyQ29kZUF0KGkpOw0KICAgICAgICAgICAgcmV0dXJuIHVzYl9hbHBoYWJldFtBICUgMzZdOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2dlbmVyYXRlUmFuZG9tUGlkKCkgew0KICAgICAgICAgICAgdmFyIHBpZCA9ICIiOw0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA3OyBpKyspIHsgcGlkICs9IHVzYl9hbHBoYWJldFtyYW5kb20oMzYpXTsgfQ0KICAgICAgICAgICAgcmV0dXJuIHBpZCArIHVzYl9jb21wdXRlQ2hlY2tzdW0ocGlkKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9nZW5lcmF0ZVJhbmRvbVBwcygpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBwcHMgPSAiIiwgczsNCiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgODsgaisrKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHMgPSAiIjsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDM7IGkrKykgcyArPSB1c2JfYWxwaGFiZXRbcmFuZG9tKDM2KV07DQogICAgICAgICAgICAgICAgcHBzICs9IHMgKyB1c2JfY29tcHV0ZUNoZWNrc3VtKHMpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIHBwczsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gUE9QVVAgRElBTE9HDQogICAgICAgIC8vDQoNCiAgICAgICAgLy8gdW5kZWZpbmVkID0gSGlkZGVuLCAxID0gR2VuZXJpYyBNZXNzYWdlDQogICAgICAgIHZhciB4eGRpYWxvZ01vZGU7DQogICAgICAgIHZhciB4eGRpYWxvZ0Z1bmM7DQogICAgICAgIHZhciB4eGRpYWxvZ0J1dHRvbnM7DQogICAgICAgIHZhciB4eGRpYWxvZ1RhZzsNCg0KICAgICAgICAvLyBEaXNwbGF5IGEgZGlhbG9nIGJveA0KICAgICAgICAvLyBQYXJhbWV0ZXJzOiBEaWFsb2cgTW9kZSAoMCA9IG5vbmUpLCBEaWFsb2cgVGl0bGUsIEJ1dHRvbnMgKDEgPSBPSywgMiA9IENhbmNlbCwgMyA9IE9LICYgQ2FuY2VsKSwgQ2FsbCBiYWNrIGZ1bmN0aW9uKDAgPSBDYW5jZWwsIDEgPSBPSyksIERpYWxvZyBDb250ZW50IChNb2RlIDExIG9ubHkpDQogICAgICAgIGZ1bmN0aW9uIHNldERpYWxvZ01vZGUoeCwgeSwgYiwgZiwgYywgdGFnKSB7DQogICAgICAgICAgICB4eGRpYWxvZ01vZGUgPSB4Ow0KICAgICAgICAgICAgeHhkaWFsb2dGdW5jID0gZjsNCiAgICAgICAgICAgIHh4ZGlhbG9nQnV0dG9ucyA9IGI7DQogICAgICAgICAgICB4eGRpYWxvZ1RhZyA9IHRhZzsNCiAgICAgICAgICAgIFFFKCdpZHhfZGxnT2tCdXR0b24nLCB0cnVlKTsNCiAgICAgICAgICAgIFFWKCdpZHhfZGxnT2tCdXR0b24nLCBiICYgMSk7DQogICAgICAgICAgICBRVignaWR4X2RsZ0NhbmNlbEJ1dHRvbicsIGIgJiAyKTsNCiAgICAgICAgICAgIFFWKCdpZF9kaWFsb2djbG9zZScsIGIgJiAyKTsNCiAgICAgICAgICAgIFFWKCdpZHhfZGxnRGVsZXRlQnV0dG9uJywgYiAmIDQpOw0KICAgICAgICAgICAgaWYgKHkpIFFIKCdpZF9kaWFsb2d0aXRsZScsIHkpOw0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCAyNjsgaSsrKSB7IFFWKCdkaWFsb2cnICsgaSwgaSA9PSB4KTsgfSAvLyBFZGl0IHRoaXMgbGluZSB3aGVuIG1vcmUgZGlhbG9ncyBhcmUgYWRkZWQNCiAgICAgICAgICAgIFFWKCdkaWFsb2cnLCB4KTsNCiAgICAgICAgICAgIGlmIChjKSB7IGlmICh4ID09IDExKSB7IFFIKCdpZF9kaWFsb2dPcHRpb25zJywgYyk7IH0gZWxzZSB7IFFIKCdpZF9kaWFsb2dNZXNzYWdlJywgYyk7IH0gfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZGlhbG9nY2xvc2UoeCkgew0KICAgICAgICAgICAgdmFyIGYgPSB4eGRpYWxvZ0Z1bmMsIGIgPSB4eGRpYWxvZ0J1dHRvbnMsIHQgPSB4eGRpYWxvZ1RhZzsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoKTsNCiAgICAgICAgICAgIGlmICgoKGIgJiA4KSB8fCB4KSAmJiBmKSBmKHgsIHQpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gY2VudGVyKCkgew0KICAgICAgICAgICAgUVMoJ2RpYWxvZycpLmxlZnQgPSAoKCgoZ2V0RG9jV2lkdGgoKSAtIDQwMCkgLyAyKSkgKyAicHgiKTsNCg0KICAgICAgICAgICAgLy9RUygnaWRfbWFpbmFyZWFfZnJhbWUnKS5oZWlnaHQgPSBRKCdpZF9tYWluYXJlYScpLm9mZnNldEhlaWdodDsNCiAgICAgICAgfQ0KICAgICAgICBmdW5jdGlvbiBtZXNzYWdlYm94KHQsIG0pIHsgUUgoJ2lkX2RpYWxvZ01lc3NhZ2UnLCBtKTsgc2V0RGlhbG9nTW9kZSgxLCB0LCAxKTsgfQ0KICAgICAgICBmdW5jdGlvbiBzdGF0dXNib3godCwgbSkgeyBRSCgnaWRfZGlhbG9nTWVzc2FnZScsIG0pOyBzZXREaWFsb2dNb2RlKDEsIHQpOyB9DQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gR0VORVJJQyBNRVRIT0RTDQogICAgICAgIC8vDQoNCg0KICAgICAgICBmdW5jdGlvbiBTYXZlSnNvbkZpbGUobmFtZSwgbmFtZTIsIGRlc2MsIGRhdGEpIHsNCiAgICAgICAgICAgIHZhciBuID0gJycsIHIgPSB7fSwgZCA9IG5ldyBEYXRlKCk7DQogICAgICAgICAgICBpZiAoYW10c3lzc3RhdGUpIHsNCiAgICAgICAgICAgICAgICBuID0gIi0iICsgYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZVsnSG9zdE5hbWUnXTsNCiAgICAgICAgICAgICAgICByID0geyd3ZWJhcHB2ZXJzaW9uJzp2ZXJzaW9uLCdkZXNjcmlwdGlvbic6ZGVzYywnaG9zdG5hbWUnOmFtdHN5c3N0YXRlWydBTVRfR2VuZXJhbFNldHRpbmdzJ10ucmVzcG9uc2VbJ0hvc3ROYW1lJ10sJ2xvY2FsdGltZSc6RGF0ZSgpLCd1dGN0aW1lJzpuZXcgRGF0ZSgpLnRvVVRDU3RyaW5nKCksJ2lzb3RpbWUnOm5ldyBEYXRlKCkudG9JU09TdHJpbmcoKX07DQogICAgICAgICAgICAgICAgaWYgKEhhcmR3YXJlSW52ZW50b3J5KSByWydzeXN0ZW1pZCddID0gZ3VpZFRvU3RyKEhhcmR3YXJlSW52ZW50b3J5WydDSU1fQ29tcHV0ZXJTeXN0ZW1QYWNrYWdlJ10ucmVzcG9uc2VbIlBsYXRmb3JtR1VJRCJdLnRvTG93ZXJDYXNlKCkpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgbiArPSAnLScgKyBkLmdldEZ1bGxZZWFyKCkgKyAiLSIgKyAoIjAiKyhkLmdldE1vbnRoKCkrMSkpLnNsaWNlKC0yKSArICItIiArICgiMCIgKyBkLmdldERhdGUoKSkuc2xpY2UoLTIpICsgIi0iICsgKCIwIiArIGQuZ2V0SG91cnMoKSkuc2xpY2UoLTIpICsgIi0iICsgKCIwIiArIGQuZ2V0TWludXRlcygpKS5zbGljZSgtMik7Ow0KICAgICAgICAgICAgcltuYW1lMl0gPSBkYXRhOw0KDQogICAgICAgICAgICBzYXZlQXMoZGF0YTJibG9iKEpTT04uc3RyaW5naWZ5KHIsIG51bGwsICcgICcpLnJlcGxhY2UoL1xuL2csICdcclxuJykpLCBuYW1lICsgbiArICcuanNvbicpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIGh0dHBFcnJvclRhYmxlID0gew0KICAgICAgICAgICAgMjAwOiAnT0snLA0KICAgICAgICAgICAgNDAxOiAnQXV0aGVudGljYXRpb24gRXJyb3InLA0KICAgICAgICAgICAgNDA4OiAnVGltZW91dCBFcnJvcicsDQogICAgICAgICAgICA2MDE6ICdXU01BTiBQYXJzaW5nIEVycm9yJywNCiAgICAgICAgICAgIDYwMjogJ1VuYWJsZSB0byBwYXJzZSBIVFRQIHJlc3BvbnNlIGhlYWRlcicsDQogICAgICAgICAgICA2MDM6ICdVbmV4cGVjdGVkIEhUVFAgZW51bSByZXNwb25zZScsDQogICAgICAgICAgICA2MDQ6ICdVbmV4cGVjdGVkIEhUVFAgcHVsbCByZXNwb25zZScsDQogICAgICAgIH0NCiAgICAgICAgZnVuY3Rpb24gZXJyY2hlY2socywgc3RhY2spIHsNCiAgICAgICAgICAgIGlmICh3c3N0YWNrID09IG51bGwgfHwgYW10c3RhY2sgIT0gc3RhY2spIHJldHVybiB0cnVlOw0KICAgICAgICAgICAgaWYgKHMgIT0gMjAwICYmIHMgIT0gOSkgew0KICAgICAgICAgICAgICAgIHNldERpYWxvZ01vZGUoKTsNCiAgICAgICAgICAgICAgICB3c3N0YWNrLmNvbW0uRmFpbEFsbEVycm9yID0gOTk5OyAvLyBDYXVzZSBhbGwgbmV3IHJlc3BvbnNlcyB0byBiZSBzaWxlbnQNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5DYW5jZWxBbGxRdWVyaWVzKDk5OSk7DQogICAgICAgICAgICAgICAgUUgoJ2lkX21lc3NhZ2V2aWV3c3RyJywgKChodHRwRXJyb3JUYWJsZVtzXSk/KGh0dHBFcnJvclRhYmxlW3NdKTooJ0Vycm9yICMnICsgcykpKTsNCiAgICAgICAgICAgICAgICBnbygxMDApOw0KICAgICAgICAgICAgICAgIFFTKCdpZF9wcm9ncmVzc2JhcicpLndpZHRoID0gMDsNCg0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIChzICE9IDIwMCk7DQogICAgICAgIH0NCg0KDQogICAgICAgIGZ1bmN0aW9uIGdvaUZyYW1lKGUseCx5KSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBnbyh4KTsNCiAgICAgICAgICAgIGlmICgoZS5zaGlmdEtleSA9PSB0cnVlKSB8fCAoUSgnaWRfU3RvcmFnZUlGcmFtZScpLnNyYy5lbmRzV2l0aCh5KSA9PSBmYWxzZSkpIFEoJ2lkX1N0b3JhZ2VJRnJhbWUnKS5zcmMgPSB5Ow0KICAgICAgICAgICAgUVYoJ2lkX21haW5hcmVhX3BhZCcsIGZhbHNlKTsNCiAgICAgICAgICAgIFFWKCdpZF9tYWluYXJlYV9mcmFtZScsIHRydWUpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZ28oeCwgZm9yY2UpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgJiYgZm9yY2UgIT0gMSkgcmV0dXJuOw0KDQogICAgICAgICAgICBRVignaWRfbWFpbmFyZWFfZnJhbWUnLCBmYWxzZSk7DQogICAgICAgICAgICBRVignaWRfbWFpbmFyZWFfcGFkJywgdHJ1ZSk7DQoNCiAgICAgICAgICAgIFFWKCdpZF9sbXNNYWluUGFuZWwnLCB4ID09IDEwMSk7DQoNCiAgICAgICAgICAgIFFWKCdpZF91c2JTZXR1cFBhbmVsJywgeCA9PSAxMDIpOw0KICAgICAgICAgICAgUVYoJ2lkX21lc3NhZ2V2aWV3JywgeCA9PSAxMDApOw0KICAgICAgICAgICAgUVYoJ2lkX21haW52aWV3JywgeCA8IDEwMCk7DQogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDgwOyBpKyspIHsgLy8gRWRpdCB0aGlzIGxpbmUgd2hlbiBhZGRpbmcgYSBuZXcgc2NyZWVuDQogICAgICAgICAgICAgICAgUVYoJ3AnICsgaSwgaSA9PSB4KTsNCiAgICAgICAgICAgICAgICB2YXIgcSA9IFFTKCdnbycgKyBpKTsNCi8vICMjI0JFR0lOIyMje0xvb2stSW50ZWx9DQogICAgICAgICAgICAgICAgaWYgKHEpIHsgcVsnYmFja2dyb3VuZC1jb2xvciddID0gKChpID09IHgpPyIjYWJjYWUxIjoiIik7IH0gLy8gI2U4ZWVmZQ0KLy8gIyMjRU5EIyMje0xvb2stSW50ZWx9DQoNCiAgICAgICAgICAgICAgICBpZiAocSkgeyBxWydiYWNrZ3JvdW5kLWNvbG9yJ10gPSAoKGkgPT0geCk/ImdyYXkiOiIiKTsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY3VycmVudFZpZXcgPSB4Ow0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gcG9ydHNGcm9tSG9zdChob3N0LCB0bHMpIHsgdmFyIHggPSBkZWNvZGVVUklDb21wb25lbnQoaG9zdCkuc3BsaXQoJzonKSwgaHAgPSAoKHRscyA9PSAwKSA/IDE2OTkyIDogMTY5OTMpLCBycCA9ICgodGxzID09IDApID8gMTY5OTQgOiAxNjk5NSk7IGlmICh4Lmxlbmd0aCA+IDEpIHsgaHAgPSBwYXJzZUludCh4WzFdKTsgfSBpZiAoeC5sZW5ndGggPiAyKSB7IHJwID0gcGFyc2VJbnQoeFsyXSk7IH0gcmV0dXJuIHsgaG9zdDogeFswXSwgaHR0cDogaHAsIHJlZGlyOiBycCB9IH0NCiAgICAgICAgZnVuY3Rpb24gYWRkTGluayh4LCBmKSB7IHJldHVybiAiPGEgc3R5bGU9Y3Vyc29yOnBvaW50ZXI7Y29sb3I6Ymx1ZSBvbmNsaWNrPSciICsgZiArICInPiZkaWFtczsgIiArIHggKyAiPC9hPiI7IH0NCiAgICAgICAgZnVuY3Rpb24gYWRkTGlua0NvbmRpdGlvbmFsKHgsIGYsIGMpIHsgaWYgKGMpIHJldHVybiBhZGRMaW5rKHgsIGYpOyByZXR1cm4geDsgfQ0KICAgICAgICBmdW5jdGlvbiBoYWx0RXZlbnQoZSkgeyBpZiAoZS5wcmV2ZW50RGVmYXVsdCkgZS5wcmV2ZW50RGVmYXVsdCgpOyBpZiAoZS5zdG9wUHJvcGFnYXRpb24pIGUuc3RvcFByb3BhZ2F0aW9uKCk7IHJldHVybiBmYWxzZTsgfQ0KICAgICAgICBmdW5jdGlvbiBhZGRPcHRpb24ocSwgdCwgaSkgeyB2YXIgb3B0aW9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgib3B0aW9uIik7IG9wdGlvbi50ZXh0ID0gdDsgb3B0aW9uLnZhbHVlID0gaTsgUShxKS5hZGQob3B0aW9uKTsgfQ0KICAgICAgICBmdW5jdGlvbiBhZGREaXNhYmxlZE9wdGlvbihxLCB0LCBpKSB7IHZhciBvcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJvcHRpb24iKTsgb3B0aW9uLnRleHQgPSB0OyBvcHRpb24udmFsdWUgPSBpOyBvcHRpb24uZGlzYWJsZWQgPSAxOyBRKHEpLmFkZChvcHRpb24pOyB9DQogICAgICAgIGZ1bmN0aW9uIHBhc3N3b3JkY2hlY2socCkgeyBpZiAocC5sZW5ndGggPCA4KSByZXR1cm4gZmFsc2U7IHZhciB1cHBlciA9IDAsIGxvd2VyID0gMCwgbnVtYmVyID0gMCwgbm9uYWxwaGEgPSAwOyBmb3IgKHZhciBpIGluIHApIHsgdmFyIGMgPSBwLmNoYXJDb2RlQXQoaSk7IGlmICgoYyA+IDY0KSAmJiAoYyA8IDkxKSkgeyB1cHBlciA9IDE7IH0gZWxzZSBpZiAoKGMgPiA5NikgJiYgKGMgPCAxMjMpKSB7IGxvd2VyID0gMTsgfSBlbHNlIGlmICgoYyA+IDQ3KSAmJiAoYyA8IDU4KSkgeyBudW1iZXIgPSAxOyB9IGVsc2UgeyBub25hbHBoYSA9IDE7IH0gfSByZXR1cm4gKCh1cHBlciArIGxvd2VyICsgbnVtYmVyICsgbm9uYWxwaGEpID09IDQpOyB9DQogICAgICAgIGZ1bmN0aW9uIG1ldGhvZGNoZWNrKHIpIHsgaWYgKHIgJiYgciAhPSBudWxsICYmIHIuQm9keSAmJiByLkJvZHlbJ1JldHVyblZhbHVlJ10gIT0gMCkgeyBtZXNzYWdlYm94KCJDYWxsIEVycm9yIiwgci5IZWFkZXJbJ01ldGhvZCddICsgIjogIiArIChyLkJvZHkuUmV0dXJuVmFsdWVTdHIgKyAnJykucmVwbGFjZSgiXyIsICIgIikpOyByZXR1cm4gdHJ1ZTsgfSByZXR1cm4gZmFsc2U7IH0NCiAgICAgICAgZnVuY3Rpb24gVGFibGVTdGFydCgpIHsgcmV0dXJuICI8dGFibGUgY2xhc3M9J2xvZzEgdXMnIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCBzdHlsZT13aWR0aDoxMDAlO2JvcmRlci1yYWRpdXM6OHB4Pjx0cj48dGQgd2lkdGg9MjAwcHg+PHA+PHRkPiI7IH0NCiAgICAgICAgZnVuY3Rpb24gVGFibGVTdGFydDIoKSB7IHJldHVybiAiPHRhYmxlIGNsYXNzPSdsb2cxIHVzJyBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgc3R5bGU9d2lkdGg6MTAwJTtib3JkZXItcmFkaXVzOjhweD48dHI+PHRkPjxwPjx0ZD4iOyB9DQogICAgICAgIGZ1bmN0aW9uIFRhYmxlRW50cnkobiwgdikgeyByZXR1cm4gIjx0cj48dGQgY2xhc3M9cjE+PHA+IiArIG4gKyAiPHRkIGNsYXNzPXIxPiIgKyB2OyB9DQogICAgICAgIGZ1bmN0aW9uIEZ1bGxUYWJsZSh4LCBlKSB7IHZhciByID0gVGFibGVTdGFydCgpOyBmb3IgKGkgaW4geCkgeyBpZiAoaSAmJiB4W2ldKSByICs9IFRhYmxlRW50cnkoaSwgeFtpXSk7IH0gcmV0dXJuIHIgKyBUYWJsZUVuZChlKTsgfQ0KICAgICAgICBmdW5jdGlvbiBUYWJsZUVuZChuKSB7IHJldHVybiAiPHRyPjx0ZCBjb2xzcGFuPTI+PHA+IiArIChuP246JycpICsgIjwvdGFibGU+IjsgfQ0KICAgICAgICBmdW5jdGlvbiBBZGRCdXR0b24odiwgZikgeyByZXR1cm4gIjxpbnB1dCB0eXBlPWJ1dHRvbiB2YWx1ZT0nIiArIHYgKyAiJyBvbmNsaWNrPSciICsgZiArICInIHN0eWxlPW1hcmdpbjo0cHg+IjsgfQ0KICAgICAgICBmdW5jdGlvbiBBZGRCdXR0b24yKHYsIGYsIHMpIHsgcmV0dXJuICI8aW5wdXQgdHlwZT1idXR0b24gdmFsdWU9JyIgKyB2ICsgIicgb25jbGljaz0nIiArIGYgKyAiJyAiICsgcyArICI+IjsgfQ0KICAgICAgICBmdW5jdGlvbiBBZGRSZWZyZXNoQnV0dG9uKGYpIHsgcmV0dXJuICI8aW5wdXQgdHlwZT1idXR0b24gbmFtZT1yZWZyZXNoYnRuIHZhbHVlPVJlZnJlc2ggb25jbGljaz0ncmVmcmVzaEJ1dHRvbnMoZmFsc2UpOyIgKyBmICsgIicgc3R5bGU9bWFyZ2luOjRweCAiICsgKHJlZnJlc2hCdXR0b25zU3RhdGU9PWZhbHNlPyJkaXNhYmxlZCI6IiIpICsgIj4iOyB9DQogICAgICAgIGZ1bmN0aW9uIE1vcmVTdGFydCgpIHsgcmV0dXJuICI8YSBzdHlsZT1jdXJzb3I6cG9pbnRlcjtjb2xvcjpibHVlIGlkPW1vcmV4eHgxIG9uY2xpY2s9UVYoXCJtb3JleHh4MVwiLGZhbHNlKTtRVihcIm1vcmV4eHgyXCIsdHJ1ZSk+JiN4MjVCQzsgTW9yZTwvYT48ZGl2IGlkPW1vcmV4eHgyIHN0eWxlPWRpc3BsYXk6bm9uZT48YnI+PGhyPiI7IH07DQogICAgICAgIGZ1bmN0aW9uIE1vcmVFbmQoKSB7IHJldHVybiAiPGEgc3R5bGU9Y3Vyc29yOnBvaW50ZXI7Y29sb3I6Ymx1ZSBvbmNsaWNrPVFWKFwibW9yZXh4eDJcIixmYWxzZSk7UVYoXCJtb3JleHh4MVwiLHRydWUpPiYjeDI1QjI7IExlc3M8L2E+PC9kaXY+IjsgfTsNCiAgICAgICAgZnVuY3Rpb24gZ2V0U2VsZWN0ZWRPcHRpb25zKHNlbCkgeyB2YXIgb3B0cyA9IFtdLCBvcHQ7IGZvciAodmFyIGkgPSAwLCBsZW4gPSBzZWwub3B0aW9ucy5sZW5ndGg7IGkgPCBsZW47IGkrKykgeyBvcHQgPSBzZWwub3B0aW9uc1tpXTsgaWYgKG9wdC5zZWxlY3RlZCkgeyBvcHRzLnB1c2gob3B0LnZhbHVlKTsgfSB9IHJldHVybiBvcHRzOyB9DQogICAgICAgIGZ1bmN0aW9uIGdldEluc3RhbmNlKHgsIHkpIHsgZm9yICh2YXIgaSBpbiB4KSB7IGlmICh4W2ldWyJJbnN0YW5jZUlEIl0gPT0geSkgcmV0dXJuIHhbaV07IH0gcmV0dXJuIG51bGw7IH0NCiAgICAgICAgZnVuY3Rpb24gZ2V0SXRlbSh4LCB5LCB6KSB7IGZvciAodmFyIGkgaW4geCkgeyBpZiAoeFtpXVt5XSA9PSB6KSByZXR1cm4geFtpXTsgfSByZXR1cm4gbnVsbDsgfQ0KICAgICAgICBmdW5jdGlvbiBndWlkVG9TdHIoZykgeyByZXR1cm4gZy5zdWJzdHJpbmcoNiwgOCkgKyBnLnN1YnN0cmluZyg0LCA2KSArIGcuc3Vic3RyaW5nKDIsIDQpICsgZy5zdWJzdHJpbmcoMCwgMikgKyAiLSIgKyBnLnN1YnN0cmluZygxMCwgMTIpICsgZy5zdWJzdHJpbmcoOCwgMTApICsgIi0iICsgZy5zdWJzdHJpbmcoMTQsIDE2KSArIGcuc3Vic3RyaW5nKDEyLCAxNCkgKyAiLSIgKyBnLnN1YnN0cmluZygxNiwgMjApICsgIi0iICsgZy5zdWJzdHJpbmcoMjApOyB9DQogICAgICAgIGZ1bmN0aW9uIGdldFVybFZhcnMoKSB7IHZhciBqLCBoYXNoLCB2YXJzID0gW10sIGhhc2hlcyA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNsaWNlKHdpbmRvdy5sb2NhdGlvbi5ocmVmLmluZGV4T2YoJz8nKSArIDEpLnNwbGl0KCcmJyk7IGZvciAodmFyIGkgPSAwOyBpIDwgaGFzaGVzLmxlbmd0aDsgaSsrKSB7IGogPSBoYXNoZXNbaV0uaW5kZXhPZignPScpOyBpZiAoaiA+IDApIHsgdmFyc1toYXNoZXNbaV0uc3Vic3RyaW5nKDAsIGopXSA9IGhhc2hlc1tpXS5zdWJzdHJpbmcoaiArIDEsIGhhc2hlc1tpXS5sZW5ndGgpOyB9IH0gcmV0dXJuIHZhcnM7IH0NCiAgICAgICAgZnVuY3Rpb24gZ2V0RG9jV2lkdGgoKSB7IGlmICh3aW5kb3cuaW5uZXJXaWR0aCkgcmV0dXJuIHdpbmRvdy5pbm5lcldpZHRoOyBpZiAoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50ICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aCAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGggIT0gMCkgcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aDsgcmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdib2R5JylbMF0uY2xpZW50V2lkdGg7IH0NCiAgICAgICAgZnVuY3Rpb24gZ2V0RG9jSGVpZ2h0KCkgeyBpZiAod2luZG93LmlubmVySGVpZ2h0KSByZXR1cm4gd2luZG93LmlubmVySGVpZ2h0OyBpZiAoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50ICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCAhPSAwKSByZXR1cm4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodDsgcmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdib2R5JylbMF0uY2xpZW50SGVpZ2h0OyB9DQogICAgICAgIGZ1bmN0aW9uIGFkZEh0bWxWYWx1ZSh0LCB2KSB7IHJldHVybiAnPGRpdiBzdHlsZT1oZWlnaHQ6MjBweD48ZGl2IHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIyMHB4O292ZXJmbG93OmhpZGRlbj48YiB0aXRsZT0iJyArIHYgKyAnIj4nICsgdiArICc8L2I+PC9kaXY+PGRpdj4nICsgdCArICc8L2Rpdj48L2Rpdj4nOyB9DQogICAgICAgIGZ1bmN0aW9uIGFkZEh0bWxWYWx1ZU5vVGl0bGUodCwgdikgeyByZXR1cm4gJzxkaXYgc3R5bGU9aGVpZ2h0OjIwcHg+PGRpdiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMjBweDtvdmVyZmxvdzpoaWRkZW4+JyArIHYgKyAnPC9iPjwvZGl2PjxkaXY+JyArIHQgKyAnPC9kaXY+PC9kaXY+JzsgfQ0KICAgICAgICBmdW5jdGlvbiBudW1iZXJzT25seShlLCB4KSB7IHJldHVybiAoZXZlbnQuY2hhckNvZGUgPT0gMCkgfHwgKGV2ZW50LmNoYXJDb2RlID09IHgpIHx8IChldmVudC5jaGFyQ29kZSA+PSA0OCAmJiBldmVudC5jaGFyQ29kZSA8PSA1Nyk7IH0NCg0KDQogICAgICAgIC8vIEdldCB0aGluZ3Mgc3RhcnRlZA0KICAgICAgICBzdGFydHVwKCk7DQogICAgPC9zY3JpcHQ+"; + + amtLms.meshCommander = http.createServer(); + amtLms.meshCommander.listen(16994); + amtLms.meshCommander.on('upgrade', function (req, socket, head) { + //console.log("WebSocket for " + req.url.split('?')[0]); + switch (req.url.split('?')[0]) { + case '/lms.ashx': // MeshCommander control channel (PTHI) + socket.ws = socket.upgradeWebSocket(); + socket.ws.on('data', processLmsControlData); + socket.ws.on('end', function () { if (lmsControlSockets[this.id]) { delete lmsControlSockets[this.id]; /*console.log('removeControl', JSON.stringify(lmsControlSockets));*/ } }); + var id = lmsControlSocketsNextId++; + lmsControlSockets[id] = socket.ws; + socket.ws.id = id; + //socket.ws.write(Buffer.concat([Buffer.from('0900', 'hex'), Buffer.from(JSON.stringify(lmsNotifications))])); // Send out full list of notifications + //console.log('addControl', JSON.stringify(lmsControlSockets)); + break; + case '/webrelay.ashx': // MeshCommander data channel (LME) + socket.ws = socket.upgradeWebSocket(); + if (amtLms.connected == true) { + // Route traffic directly into MicroLMS + amtLms.bindDuplexStream(socket.ws, 'IPv4', 16992); + } else { + // Route traffic to real LMS service + var net = require('net'); + socket.relay = net.connect({ host: '127.0.0.1', port: 16992 }) + socket.relay.on('connect', function () { + socket.ws.on('data', function (data) { socket.relay.write(data); }); + socket.ws.on('end', function () { socket.relay.end(); }); + }); + socket.relay.on('data', function (data) { socket.ws.write(data); }); + socket.relay.on('close', function () { socket.ws.end(); }); + } + break; + default: + socket.end(); + break; + } + }); + amtLms.meshCommander.on('request', function (req, rsp) { + //console.log("WebRequest for " + req.url.split('?')[0]); + switch (req.url.split('?')[0]) { + case '/': // Serve MeshCommander Web Application for LMS + var lmscommander = null; + try { lmscommander = fs.readFileSync('lmscommander.htm'); } catch (e) { } + if (lmscommander != null) { + rsp.writeHead(200, 'OK', { Server: 'JSLMS', 'Cache-Control': 'max-age=0, no-cache', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Transfer-Encoding': 'chunked' }); + rsp.end(lmscommander); + } else { + rsp.writeHead(200, 'OK', { Server: 'JSLMS', 'Cache-Control': 'max-age=0, no-cache', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/html', 'Content-Encoding': 'gzip', 'Transfer-Encoding': 'chunked', ETag: _IntelAmtWebApp_etag }); + rsp.end(Buffer.from(_IntelAmtWebApp, 'base64')); + } + break; + default: // Unknown request + rsp.statusCode = 404; + rsp.statusMessage = "Not Found"; + rsp.end(); + break; + } + + }); +} + +function setupMeiOsAdmin(func, state) { + if (amtMei == null) { + if (func) { func(state); } + } else { + amtMei.getLocalSystemAccount(function (x) { + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + oswsstack = new wsman(transport, '127.0.0.1', 16992, x.user, x.pass, false); + osamtstack = new amt(oswsstack); + if (func) { func(state); } + + //var AllWsman = "CIM_SoftwareIdentity,IPS_SecIOService,IPS_ScreenSettingData,IPS_ProvisioningRecordLog,IPS_HostBasedSetupService,IPS_HostIPSettings,IPS_IPv6PortSettings".split(','); + //osamtstack.BatchEnum(null, AllWsman, startLmsWsmanResponse, null, true); + //************************************* + + // Setup KVM data channel if this is Intel AMT 12 or above + amtMei.getVersion(function (x) { + var amtver = null; + try { for (var i in x.Versions) { if (x.Versions[i].Description == 'AMT') amtver = parseInt(x.Versions[i].Version.split('.')[0]); } } catch (e) { } + if ((amtver != null) && (amtver >= 12)) { + kvmGetData('skip'); // Clear any previous data, this is a dummy read to about handling old data. + tempTimer = setInterval(function () { kvmGetData(); }, 2000); // Start polling for KVM data. + kvmSetData(JSON.stringify({ action: 'restart', ver: 1 })); // Send a restart command to advise the console if present that MicroLMS just started. + } + }); + }); + } +} + +function kvmGetData(tag) { + osamtstack.IPS_KVMRedirectionSettingData_DataChannelRead(kvmDataGetResponse, tag); +} + +function kvmDataGetResponse(stack, name, response, status, tag) { + if ((tag != 'skip') && (status == 200) && (response.Body.ReturnValue == 0)) { + var val = null; + try { val = Buffer.from(response.Body.DataMessage, 'base64').toString(); } catch (e) { return } + if (val != null) { kvmProcessData(response.Body.RealmsBitmap, response.Body.MessageId, val); } + } +} + +var webRtcDesktop = null; +function kvmProcessData(realms, messageId, val) { + var data = null; + try { data = JSON.parse(val) } catch (e) { } + if ((data != null) && (data.action)) { + if (data.action == 'present') { kvmSetData(JSON.stringify({ action: 'present', ver: 1, platform: process.platform })); } + if (data.action == 'offer') { + webRtcDesktop = {}; + var rtc = require('ILibWebRTC'); + webRtcDesktop.webrtc = rtc.createConnection(); + webRtcDesktop.webrtc.on('connected', function () { }); + webRtcDesktop.webrtc.on('disconnected', function () { webRtcCleanUp(); }); + webRtcDesktop.webrtc.on('dataChannel', function (rtcchannel) { + webRtcDesktop.rtcchannel = rtcchannel; + var kvmmodule = require('meshDesktop'); + webRtcDesktop.kvm = kvmmodule.getRemoteDesktopStream(); + webRtcDesktop.kvm.pipe(webRtcDesktop.rtcchannel, { dataTypeSkip: 1, end: false }); + webRtcDesktop.rtcchannel.on('end', function () { webRtcCleanUp(); }); + webRtcDesktop.rtcchannel.on('data', function (x) { kvmCtrlData(this, x); }); + webRtcDesktop.rtcchannel.pipe(webRtcDesktop.kvm, { dataTypeSkip: 1, end: false }); + //webRtcDesktop.kvm.on('end', function () { console.log('WebRTC DataChannel closed2'); webRtcCleanUp(); }); + //webRtcDesktop.rtcchannel.on('data', function (data) { console.log('WebRTC data: ' + data); }); + }); + kvmSetData(JSON.stringify({ action: 'answer', ver: 1, sdp: webRtcDesktop.webrtc.setOffer(data.sdp) })); + } + } +} + +// Polyfill path.join +var path = { + join: function () { + var x = []; + for (var i in arguments) { + var w = arguments[i]; + if (w != null) { + while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); } + if (i != 0) { + while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); } + } + x.push(w); + } + } + if (x.length == 0) return '/'; + return x.join('/'); + } +}; + +// Get a formated response for a given directory path +function getDirectoryInfo(reqpath) { + var response = { path: reqpath, dir: [] }; + if (((reqpath == undefined) || (reqpath == '')) && (process.platform == 'win32')) { + // List all the drives in the root, or the root itself + var results = null; + try { results = fs.readDrivesSync(); } catch (e) { } // TODO: Anyway to get drive total size and free space? Could draw a progress bar. + //console.log('a', objToString(results, 0, ' ')); + if (results != null) { + for (var i = 0; i < results.length; ++i) { + var drive = { n: results[i].name, t: 1 }; + if (results[i].type == 'REMOVABLE') { drive.dt = 'removable'; } // TODO: See if this is USB/CDROM or something else, we can draw icons. + response.dir.push(drive); + } + } + } else { + // List all the files and folders in this path + if (reqpath == '') { reqpath = '/'; } + var xpath = path.join(reqpath, '*'); + var results = null; + + try { results = fs.readdirSync(xpath); } catch (e) { } + if (results != null) { + for (var i = 0; i < results.length; ++i) { + if ((results[i] != '.') && (results[i] != '..')) { + var stat = null, p = path.join(reqpath, results[i]); + try { stat = fs.statSync(p); } catch (e) { } // TODO: Get file size/date + if ((stat != null) && (stat != undefined)) { + if (stat.isDirectory() == true) { + response.dir.push({ n: results[i], t: 2, d: stat.mtime }); + } else { + response.dir.push({ n: results[i], t: 3, s: stat.size, d: stat.mtime }); + } + } + } + } + } + } + return response; +} + +// Process KVM control channel data +function kvmCtrlData(channel, cmd) { + if (cmd.length > 0 && cmd.charCodeAt(0) != 123) { + // This is upload data + if (this.fileupload != null) { + cmd = Buffer.from(cmd, 'base64'); + var header = cmd.readUInt32BE(0); + if ((header == 0x01000000) || (header == 0x01000001)) { + fs.writeSync(this.fileupload.fp, cmd.slice(4)); + channel.write({ action: 'upload', sub: 'ack', reqid: this.fileupload.reqid }); + if (header == 0x01000001) { fs.closeSync(this.fileupload.fp); this.fileupload = null; } // Close the file + } + } + return; + } + //console.log('KVM Ctrl Data', cmd); + + try { cmd = JSON.parse(cmd); } catch (ex) { console.error('Invalid JSON: ' + cmd); return; } + if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows + switch (cmd.action) { + case 'ping': { + // This is a keep alive + channel.write({ action: 'pong' }); + break; + } + case 'ls': { + /* + // Close the watcher if required + var samepath = ((this.httprequest.watcher != undefined) && (cmd.path == this.httprequest.watcher.path)); + if ((this.httprequest.watcher != undefined) && (samepath == false)) { + //console.log('Closing watcher: ' + this.httprequest.watcher.path); + //this.httprequest.watcher.close(); // TODO: This line causes the agent to crash!!!! + delete this.httprequest.watcher; + } + */ + + // Send the folder content to the browser + var response = getDirectoryInfo(cmd.path); + if (cmd.reqid != undefined) { response.reqid = cmd.reqid; } + channel.write(response); + + /* + // Start the directory watcher + if ((cmd.path != '') && (samepath == false)) { + var watcher = fs.watch(cmd.path, onFileWatcher); + watcher.tunnel = this.httprequest; + watcher.path = cmd.path; + this.httprequest.watcher = watcher; + //console.log('Starting watcher: ' + this.httprequest.watcher.path); + } + */ + break; + } + case 'mkdir': { + // Create a new empty folder + fs.mkdirSync(cmd.path); + break; + } + case 'rm': { + // Remove many files or folders + for (var i in cmd.delfiles) { + var fullpath = path.join(cmd.path, cmd.delfiles[i]); + try { fs.unlinkSync(fullpath); } catch (e) { console.log(e); } + } + break; + } + case 'rename': { + // Rename a file or folder + var oldfullpath = path.join(cmd.path, cmd.oldname); + var newfullpath = path.join(cmd.path, cmd.newname); + try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); } + break; + } + case 'download': { + // Download a file, to browser + var sendNextBlock = 0; + if (cmd.sub == 'start') { // Setup the download + if (this.filedownload != null) { channel.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; } + this.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 } + try { this.filedownload.f = fs.openSync(this.filedownload.path, 'rbN'); } catch (e) { channel.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; } + if (this.filedownload) { channel.write({ action: 'download', sub: 'start', id: cmd.id }); } + } else if ((this.filedownload != null) && (cmd.id == this.filedownload.id)) { // Download commands + if (cmd.sub == 'startack') { sendNextBlock = 8; } else if (cmd.sub == 'stop') { delete this.filedownload; } else if (cmd.sub == 'ack') { sendNextBlock = 1; } + } + // Send the next download block(s) + while (sendNextBlock > 0) { + sendNextBlock--; + var buf = Buffer.alloc(4096); + var len = fs.readSync(this.filedownload.f, buf, 4, 4092, null); + this.filedownload.ptr += len; + if (len < 4092) { buf.writeInt32BE(0x01000001, 0); fs.closeSync(this.filedownload.f); delete this.filedownload; sendNextBlock = 0; } else { buf.writeInt32BE(0x01000000, 0); } + channel.write(buf.slice(0, len + 4).toString('base64')); // Write as Base64 + } + break; + } + case 'upload': { + // Upload a file, from browser + if (cmd.sub == 'start') { // Start the upload + if (this.fileupload != null) { fs.closeSync(this.fileupload.fp); } + if (!cmd.path || !cmd.name) break; + this.fileupload = { reqid: cmd.reqid }; + var filepath = path.join(cmd.path, cmd.name); + try { this.fileupload.fp = fs.openSync(filepath, 'wbN'); } catch (e) { } + if (this.fileupload.fp) { channel.write({ action: 'upload', sub: 'start', reqid: this.fileupload.reqid }); } else { this.fileupload = null; channel.write({ action: 'upload', sub: 'error', reqid: this.fileupload.reqid }); } + } + else if (cmd.sub == 'cancel') { // Stop the upload + if (this.fileupload != null) { fs.closeSync(this.fileupload.fp); this.fileupload = null; } + } + break; + } + case 'copy': { + // Copy a bunch of files from scpath to dspath + for (var i in cmd.names) { + var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]); + if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } } + } + break; + } + case 'move': { + // Move a bunch of files from scpath to dspath + for (var i in cmd.names) { + var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]); + if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } } + } + break; + } + default: + // Unknown action, ignore it. + break; + } +} + +function webRtcCleanUp() { + if (webRtcDesktop == null) return; + if (webRtcDesktop.rtcchannel) { + try { webRtcDesktop.rtcchannel.close(); } catch (e) { } + try { webRtcDesktop.rtcchannel.removeAllListeners('data'); } catch (e) { } + try { webRtcDesktop.rtcchannel.removeAllListeners('end'); } catch (e) { } + delete webRtcDesktop.rtcchannel; + } + if (webRtcDesktop.webrtc) { + try { webRtcDesktop.webrtc.close(); } catch (e) { } + try { webRtcDesktop.webrtc.removeAllListeners('connected'); } catch (e) { } + try { webRtcDesktop.webrtc.removeAllListeners('disconnected'); } catch (e) { } + try { webRtcDesktop.webrtc.removeAllListeners('dataChannel'); } catch (e) { } + delete webRtcDesktop.webrtc; + } + if (webRtcDesktop.kvm) { + try { webRtcDesktop.kvm.end(); } catch (e) { } + delete webRtcDesktop.kvm; + } + webRtcDesktop = null; +} + +function kvmSetData(x) { + osamtstack.IPS_KVMRedirectionSettingData_DataChannelWrite(Buffer.from(x).toString('base64'), function () { }); +} + +function startLmsWsmanResponse(stack, name, responses, status) { + if (status == 600) { console.log('ERROR: Unable to connect to Intel(R) AMT.'); } + else if (status != 200) { console.log('ERROR: Unable to get object from Intel(R) AMT, status = ' + status + '.'); } + else { + //console.log(JSON.stringify(responses), status); + var amtlogicalelements = responses["CIM_SoftwareIdentity"].responses; + if (amtlogicalelements.length > 0) { + var v = getInstance(amtlogicalelements, "AMT")["VersionString"]; + amtversion = parseInt(v.split('.')[0]); + amtversionmin = parseInt(v.split('.')[1]); + //console.log(amtversion, amtversionmin); + } + } +} + + +// Process commands in the LMS control channel +// Command 9 is add a notification. +function processLmsControlData(data) { + if (data.length < 2) return; + var cmdid = data.readUInt16LE(0); + switch (cmdid) { + case 1: // Request basic Intel AMT information (CMD = 1) + { getAmtInfo(function (meinfo, socket) { meinfo.LoginMode = 2; socket.write(Buffer.concat([Buffer.from('0100', 'hex'), Buffer.from(JSON.stringify(meinfo))])); }, this); break; } + case 2: // Intel AMT MEI Unprovision (CMD = 2) + { if (data.length < 6) break; amtMei.unprovision(data.readUInt32LE(2), function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(2, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; } + case 3: // Intel AMT MEI GetLocalSystemAccount (CMD = 3) + { amtMei.getLocalSystemAccount(function (account, socket) { socket.write(Buffer.concat([Buffer.from('030000000000', 'hex'), account.raw])); }, this); break; } + case 4: // Instruct Intel AMT to start remote configuration (CMD = 4) + { amtMei.startConfiguration(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; } + case 5: // Instruct Intel AMT to stop remote configuration (CMD = 5) + { amtMei.stopConfiguration(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; } + case 6: // Instruct Intel AMT connect CIRA (CMD = 6) + { amtMei.openUserInitiatedConnection(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; } + case 7: // Instruct Intel AMT disconnect CIRA (CMD = 7) + { amtMei.closeUserInitiatedConnection(function (status, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(7, 0); data.writeUInt32LE(status, 2); socket.write(data); }, this); break; } + case 8: // Get Intel AMT CIRA State (CMD = 8) + { amtMei.getRemoteAccessConnectionStatus(function (state, socket) { var data = Buffer.alloc(6); data.writeUInt16LE(8, 0); data.writeUInt32LE(state.status, 2); socket.write(Buffer.concat([data, state.raw])); }, this); break; } + default: + // Unknown action, ignore it. + break; + } +} + + +// +// MeshCentral TCP port router +// + +function startRouter() { + tcpserver = net.createServer(OnTcpClientConnected); + tcpserver.on('error', function (e) { console.log('ERROR: ' + JSON.stringify(e)); exit(0); return; }); + tcpserver.listen(settings.localport, function () { + // We started listening. + if (settings.remotename == null) { + console.log('Redirecting local port ' + settings.localport + ' to remote port ' + settings.remoteport + '.'); + } else { + console.log('Redirecting local port ' + settings.localport + ' to ' + settings.remotename + ':' + settings.remoteport + '.'); + } + console.log('Press ctrl-c to exit.'); + + // If settings has a "cmd", run it now. + //process.exec("notepad.exe"); + }); +} + +// Called when a TCP connect is received on the local port. Launch a tunnel. +function OnTcpClientConnected(c) { + try { + // 'connection' listener + debug(1, 'Client connected'); + c.on('end', function () { disconnectTunnel(this, this.websocket, 'Client closed'); }); + c.pause(); + try { + options = http.parseUri(settings.serverurl + '?user=' + settings.username + '&pass=' + settings.password + '&nodeid=' + settings.remotenodeid + '&tcpport=' + settings.remoteport); + } catch (e) { console.log('Unable to parse \"serverUrl\".'); process.exit(1); return; } + options.checkServerIdentity = onVerifyServer; + options.rejectUnauthorized = false; + c.websocket = http.request(options); + c.websocket.tcp = c; + c.websocket.tunneling = false; + c.websocket.upgrade = OnWebSocket; + c.websocket.on('error', function (e) { console.log('ERROR: ' + JSON.stringify(e)); }); + c.websocket.end(); + } catch (e) { debug(2, e); } +} + +// Disconnect both TCP & WebSocket connections and display a message. +function disconnectTunnel(tcp, ws, msg) { + if (ws != null) { try { ws.end(); } catch (e) { debug(2, e); } } + if (tcp != null) { try { tcp.end(); } catch (e) { debug(2, e); } } + debug(1, 'Tunnel disconnected: ' + msg); +} + +// Called when the web socket gets connected +function OnWebSocket(msg, s, head) { + debug(1, 'Websocket connected'); + s.on('data', function (msg) { + if (this.parent.tunneling == false) { + msg = msg.toString(); + if (msg == 'c') { + this.parent.tunneling = true; this.pipe(this.parent.tcp); this.parent.tcp.pipe(this); debug(1, 'Tunnel active'); + } else if ((msg.length > 6) && (msg.substring(0, 6) == 'error:')) { + console.log(msg.substring(6)); + disconnectTunnel(this.tcp, this, msg.substring(6)); + } + } + }); + s.on('error', function (msg) { disconnectTunnel(this.tcp, this, 'Websocket error'); }); + s.on('close', function (msg) { disconnectTunnel(this.tcp, this, 'Websocket closed'); }); + s.parent = this; +} + +// Try to discover the location of the mesh server +function discoverMeshServer() { console.log('Looking for server...'); discoveryInterval = setInterval(discoverMeshServerOnce, 5000); discoverMeshServerOnce(); } + +// Try to discover the location of the mesh server only once +function discoverMeshServerOnce() { + var interfaces = os.networkInterfaces(); + for (var adapter in interfaces) { + if (interfaces.hasOwnProperty(adapter)) { + for (var i = 0; i < interfaces[adapter].length; ++i) { + var addr = interfaces[adapter][i]; + multicastSockets[i] = dgram.createSocket({ type: (addr.family == "IPv4" ? "udp4" : "udp6") }); + multicastSockets[i].bind({ address: addr.address, exclusive: false }); + if (addr.family == "IPv4") { + try { + multicastSockets[i].addMembership(membershipIPv4); + //multicastSockets[i].setMulticastLoopback(true); + multicastSockets[i].once('message', OnMulticastMessage); + multicastSockets[i].send(settings.serverid, 16989, membershipIPv4); + } catch (e) { } + } + } + } + } +} + +// Called when a multicast packet is received +function OnMulticastMessage(msg, rinfo) { + var m = msg.toString().split('|'); + if ((m.length == 3) && (m[0] == 'MeshCentral2') && (m[1] == settings.serverid)) { + settings.serverurl = m[2].replace('%s', rinfo.address).replace('/agent.ashx', '/meshrelay.ashx'); + console.log('Found server at ' + settings.serverurl + '.'); + if (discoveryInterval != null) { clearInterval(discoveryInterval); discoveryInterval = null; } + startRouter(); + } +} + + +// +// PUSH MESHCOMMANDER INTO FIRMWARE +// + +function nextStepStorageUpload() { + debug(3, "nextStepStorageUpload"); + getAmtStorage(function (statusCode, data) { + if (statusCode == 200) { + debug(2, "getAmtStorage: " + JSON.stringify(data, null, 2)); + if ((data['content'] != null) && (data['content']['index.htm'] != null)) { nextStepStorageUpload3('index.htm'); } + else if ((data['content'] != null) && (data['content']['logon.htm'] != null)) { nextStepStorageUpload3('logon.htm'); } + else if ((data['content'] != null) && (data['content']['logon.htm'] != null)) { nextStepStorageUpload3('logon.htm'); } + else { nextStepStorageUpload2('index.htm', null); } + } else { + console.log("Unable to read storage state."); + exit(); + return; + } + }); +} + +function nextStepStorageUpload2(uploadName, linkName) { + debug(3, "nextStepStorageUpload2"); + if (settings.webapp == null) { console.log("Done."); exit(); return; } else { + console.log("Uploading MeshCommander..."); + pushToStorage(uploadName, linkName, Buffer.from(settings.webapp, 'base64'), function (statusCode) { + if (statusCode == 500) { console.log("Error, check that computer is powered on."); exit(); return; } + if (statusCode != 200) { + if (uploadName == 'index.htm') { + nextStepStorageUpload2('mesh/commander/console', 'MeshCommander'); + } else { + console.log("Unable to upload MeshCommander, status = " + statusCode + "."); exit(); return; + } + } else { + console.log("Verifying MeshCommander..."); + verifyStorage(uploadName, Buffer.from(settings.webapp, 'base64'), function (verified) { + if (verified == true) { console.log('Done.'); } else { console.log('MeshCommander verification failed.'); } + exit(); return; + }); + } + }); + } +} + +function nextStepStorageUpload3(deleteName) { + console.log("Deleting " + deleteName + " from storage..."); + deleteStorage(deleteName, function (statusCode) { + if (statusCode == 500) { console.log("Error, check that computer is powered on."); exit(); return; } + if (statusCode == 200) { nextStepStorageUpload(); } else { console.log("Unable to delete " + deleteName + "."); exit(); return; } + }); +} + +// Fetch the Intel AMT storage document +function getAmtStorage(func, noretry) { + var req = digest.request({ protocol: settings.protocol, method: "GET", host: settings.hostname, path: "/amt-storage/", port: settings.localport }, + function (response) { + if (response.statusCode != 200) { console.log("Unable to connect to Intel(R) AMT."); func(response.statusCode, null); } + response.on('data', function (chunk) { if (response.acc == null) { response.acc = chunk; } else { response.acc += chunk; } }); + response.on('end', function () { + var data = response.acc.toString(), len, data2, amtstorage = null; + data = data.split('\t').join('').split('\r').join('').split('\n').join(''); + try { + do { len = data.length; data2 = data; data = data2.replace('": ', '":'); } while (data != data2); // Remove all zero's, this is needed because firmware sometimes returns garbage we must fix. + do { len = data.length; data2 = data; data = data2.replace('\x00', ''); } while (data != data2); // Remove all zero's, this is needed because firmware sometimes returns garbage we must fix. + do { len = data.length; data2 = data; data = data2.replace('\x22\x01\x22', '\x22\x22'); } while (data != data2); // "\x01", this is needed because firmware sometimes returns garbage we must fix. + var xopen = data.split("{").length, xclose = data.split("}").length, xadd = ''; + while (xopen > xclose) { data += '}'; xclose++; } // Close any missing close brackets + amtstorage = JSON.parse(data); + } catch (e) { console.log("Error: Unable to parse Intel AMT response: " + data, e); func(null); } + if (func != null) { func(response.statusCode, amtstorage); } + }); + }); + req.on('error', function (e) { console.log("Error occured: " + JSON.stringify(e)); if (noretry == true) { if (func != null) { func(null); } } else { getAmtStorage(func, true); } }); + req.end(); +} + +// Fetch the Intel AMT storage document +function pushToStorage(name, linkname, data, func, ptr) { + if (ptr == null) { ptr = 0; } + var req = digest.request({ protocol: settings.protocol, method: "PUT", host: settings.hostname, path: ("/amt-storage/" + name + ((ptr != 0) ? '?append=' : '')), port: settings.localport }); + req.on('error', function (e) { console.log("Error occured: " + JSON.stringify(e)); if (func != null) { func(null); } }); + req.on('response', function (response) { + debug(1, 'Chunk Done', data.length, ptr); + if ((response.statusCode == 200) && (ptr < data.length)) { pushToStorage(name, linkname, data, func, ptr); } else { if (func != null) { func(response.statusCode); } } + }); + var header = (ptr > 0) ? '' : 'Content-Encoding:gzipContent-Type:text/html' + ((linkname != null) ? ('' + linkname + '') : '') + ''; + var blocklen = ((data.length - ptr) > (7000 - header.length)) ? (7000 - header.length) : (data.length - ptr); + req.write(Buffer.concat([new Buffer(header), data.slice(ptr, ptr + blocklen)])); + ptr += blocklen; + req.end(); +} + +// Fetch the Intel AMT storage document +function verifyStorage(name, data, func) { + var req = digest.request({ protocol: settings.protocol, method: "GET", host: settings.hostname, path: ("/amt-storage/" + name), port: settings.localport }); + req.on('error', function (e) { console.log("Verify error occured: " + JSON.stringify(e)); if (func != null) { func(null); } }); + req.on('response', function (response) { + response.ptr = 0; + response.ok = true; + response.on('data', function (data2) { if (data2.toString('hex') != data.slice(response.ptr, response.ptr + data2.length).toString('hex')) { response.ok = false; console.log('Verifiy failed (' + response.ptr + ', ' + data2.length + ').'); } response.ptr += data2.length; }); + response.on('end', function () { if (func != null) { func(response.ok); } }); + }); + req.end(); +} + +// Fetch the Intel AMT storage document +function deleteStorage(name, func, noretry) { + var req = digest.request({ protocol: settings.protocol, method: "DELETE", host: settings.hostname, path: "/amt-storage/" + name, port: settings.localport }); + req.on('error', function (e) { if ((e == 'Error: Socket was unexpectedly closed') && (noretry != true)) { deleteStorage(name, func, true); } else { if (func != null) { if (e.statusCode) { func(e.statusCode); } else { func(null); } } } }); + req.on('response', function (response) { if (func != null) { func(response.statusCode); } }); + req.end(); +} + + +// +// IDER +// + +ider = null; +iderIdleTimer = null; + +// Perform IDER +function performIder() { + if ((settings.floppy != null) && fs.existsSync(settings.floppy) == false) { console.log("Unable to floppy image file: " + settings.floppy); process.exit(); return; } + if ((settings.cdrom != null) && fs.existsSync(settings.cdrom) == false) { console.log("Unable to CDROM image file: " + settings.cdrom); process.exit(); return; } + try { + var sfloppy = null, scdrom = null; + if (settings.floppy) { try { if (sfloppy = fs.statSync(settings.floppy)) { sfloppy.file = fs.openSync(settings.floppy, 'rbN'); } } catch (ex) { console.log(ex); process.exit(1); return; } } + if (settings.cdrom) { try { scdrom = fs.statSync(settings.cdrom); if (scdrom) { scdrom.file = fs.openSync(settings.cdrom, 'rbN'); } } catch (ex) { console.log(ex); process.exit(1); return; } } + + ider = require('amt-redir-duk')(require('amt-ider')()); + ider.onStateChanged = onIderStateChange; + ider.m.floppy = sfloppy; + ider.m.cdrom = scdrom; + ider.m.iderStart = 1; // OnReboot = 0, Graceful = 1, Now = 2 + ider.m.debug = (settings.debuglevel > 0); + if (settings.timeout > 0) { ider.m.sectorStats = iderSectorStats; } + //ider.digestRealmMatch = wsstack.comm.digestRealm; + //ider.tlsv1only = amtstack.wsman.comm.tlsv1only; + ider.Start(settings.hostname, (settings.tls == true) ? 16995 : 16994, settings.username ? 'admin' : settings.username, settings.password, settings.tls); + } catch (ex) { console.log(ex); } +} + +function onIderStateChange(stack, state) { console.log(['Disconnected', 'Connecting...', 'Connected...', 'Started IDER...'][state]); } + +function iderSectorStats(mode, dev, mediaBlocks, lba, len) { + if (iderIdleTimer != null) { clearTimeout(iderIdleTimer); } + iderIdleTimer = setTimeout(function () { console.log('Idle timeout'); process.exit(1); }, 1000 * settings.timeout); +} + +// +// Startup +// + +// Parse URL arguments +function parseUrlArguments(url) { + var r = {}, x = url.split('?'); + if (x.length < 2) return r; + x = x[1].split('&'); + for (var i in x) { var j = x[i].indexOf('='); if (j > 0) { r[x[i].substring(0, j).toLowerCase()] = x[i].substring(j + 1); } } + return r; +} + +// Remove a element from a array +function removeItemFromArray(array, element) { + var index = array.indexOf(element); + if (index !== -1) { array.splice(index, 1); } +} + +// Run MeshCmd, but before we do, we need to see if what type of service we are going to be +var serviceName = null; +var serviceOpSpecified = 0; +var serviceInstall = 0; + +for (var i in process.argv) { + if (process.argv[i].toLowerCase() == 'install') { serviceInstall = 1 } else if (process.argv[i].toLowerCase() == 'uninstall') { serviceInstall = -1 } + if ((process.argv[i].toLowerCase() == 'microlms') || (process.argv[i].toLowerCase() == 'amtlms') || (process.argv[i].toLowerCase() == 'lms')) { serviceName = 'MicroLMS'; break; } + if ((process.argv[i].toLowerCase() == 'meshcommander') || (process.argv[i].toLowerCase() == 'commander')) { serviceName = 'MeshCommander'; break; } +} + +if (serviceName == null) { + for (var i in process.argv) { + if ((process.argv[i].toLowerCase() == 'install') || (process.argv[i].toLowerCase() == 'uninstall')) { + console.log('In order to install/uninstall, a service type must be specified.'); + process.exit(); + } + } + if (process.execPath.includes('MicroLMS')) { serviceName = 'MicroLMS'; } + else if (process.execPath.includes('MeshCommander')) { serviceName = 'MeshCommander'; } + else { serviceName = 'not_a_service'; } +} + +if (serviceInstall == 0) { + run(process.argv); +} else { + var serviceHost = require('service-host'); + var meshcmdService = new serviceHost({ name: serviceName, startType: 'AUTO_START' }); + + // Called when the background service is started. + meshcmdService.on('serviceStart', function onStart() { + console.setDestination(console.Destinations.DISABLED); // Disable console.log(). + if (process.execPath.includes('MicroLMS')) { run([process.execPath, 'microlms']); } // + else if (process.execPath.includes('MeshCommander')) { run([process.execPath, 'meshcommander']); } + else { console.log('Aborting Service Start, because unknown binary: ' + process.execPath); process.exit(1); } + }); + + // Called when the background service is stopping + meshcmdService.on('serviceStop', function onStop() { console.log('Stopping service'); process.exit(); }); // The console.log() is for debugging, will be ignored unless "console.setDestination()" is set. + + // Called when the executable is not running as a service, run normally. + meshcmdService.on('normalStart', function onNormalStart() { try { run(process.argv); } catch (e) { console.log('ERROR: ' + e); } }); + meshcmdService.run(); +} diff --git a/agents/meshcore.min.js b/agents/meshcore.min.js new file mode 100644 index 00000000..d4cf9522 --- /dev/null +++ b/agents/meshcore.min.js @@ -0,0 +1,2229 @@ +/* +Copyright 2018-2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +process.on('uncaughtException', function (ex) { + require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": "uncaughtException1: " + ex }); +}); + +// NOTE: This seems to cause big problems, don't enable the debugger in the server's meshcore. +//attachDebugger({ webport: 9999, wait: 1 }).then(function (prt) { console.log('Point Browser for Debug to port: ' + prt); }); + +// Mesh Rights +var MNG_ERROR = 65; +var MESHRIGHT_EDITMESH = 1; +var MESHRIGHT_MANAGEUSERS = 2; +var MESHRIGHT_MANAGECOMPUTERS = 4; +var MESHRIGHT_REMOTECONTROL = 8; +var MESHRIGHT_AGENTCONSOLE = 16; +var MESHRIGHT_SERVERFILES = 32; +var MESHRIGHT_WAKEDEVICE = 64; +var MESHRIGHT_SETNOTES = 128; +var MESHRIGHT_REMOTEVIEW = 256; +var MESHRIGHT_NOTERMINAL = 512; +var MESHRIGHT_NOFILES = 1024; +var MESHRIGHT_NOAMT = 2048; +var MESHRIGHT_LIMITEDINPUT = 4096; + +function createMeshCore(agent) +{ + var obj = {}; + + if (process.platform == 'darwin' && !process.versions) + { + // This is an older MacOS Agent, so we'll need to check the service definition so that Auto-Update will function correctly + var child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write("cat /Library/LaunchDaemons/meshagent_osx64_LaunchDaemon.plist | tr '\n' '\.' | awk '{split($0, a, \"KeepAlive\"); split(a[2], b, \"<\"); split(b[2], c, \">\"); "); + child.stdin.write(" if(c[1]==\"dict\"){ split(a[2], d, \"\"); if(split(d[1], truval, \"\")>1) { split(truval[1], kn1, \"\"); split(kn1[2], kn2, \"\"); print kn2[1]; } }"); + child.stdin.write(" else { split(c[1], ka, \"/\"); if(ka[1]==\"true\") {print \"ALWAYS\";} } }'\nexit\n"); + child.waitExit(); + if (child.stdout.str.trim() == 'Crashed') + { + child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write("launchctl list | grep 'meshagent' | awk '{ if($3==\"meshagent\"){print $1;}}'\nexit\n"); + child.waitExit(); + + if (parseInt(child.stdout.str.trim()) == process.pid) + { + // The currently running MeshAgent is us, so we can continue with the update + var plist = require('fs').readFileSync('/Library/LaunchDaemons/meshagent_osx64_LaunchDaemon.plist').toString(); + var tokens = plist.split('KeepAlive'); + if (tokens[1].split('>')[0].split('<')[1] == 'dict') + { + var tmp = tokens[1].split(''); + tmp.shift(); + tokens[1] = '\n ' + tmp.join(''); + tokens = tokens.join('KeepAlive'); + + require('fs').writeFileSync('/Library/LaunchDaemons/meshagent_osx64_LaunchDaemon.plist', tokens); + + var fix = ''; + fix += ("function macosRepair()\n"); + fix += ("{\n"); + fix += (" var child = require('child_process').execFile('/bin/sh', ['sh']);\n"); + fix += (" child.stdout.str = '';\n"); + fix += (" child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });\n"); + fix += (" child.stderr.on('data', function (chunk) { });\n"); + fix += (" child.stdin.write('launchctl unload /Library/LaunchDaemons/meshagent_osx64_LaunchDaemon.plist\\n');\n"); + fix += (" child.stdin.write('launchctl load /Library/LaunchDaemons/meshagent_osx64_LaunchDaemon.plist\\n');\n"); + fix += (" child.stdin.write('rm /Library/LaunchDaemons/meshagentRepair.plist\\n');\n"); + fix += (" child.stdin.write('rm " + process.cwd() + "/macosRepair.js\\n');\n"); + fix += (" child.stdin.write('launchctl stop meshagentRepair\\nexit\\n');\n"); + fix += (" child.waitExit();\n"); + fix += ("}\n"); + fix += ("macosRepair();\n"); + fix += ("process.exit();\n"); + require('fs').writeFileSync(process.cwd() + '/macosRepair.js', fix); + + var plist = '\n'; + plist += '\n'; + plist += '\n'; + plist += ' \n'; + plist += ' Label\n'; + plist += (' meshagentRepair\n'); + plist += ' ProgramArguments\n'; + plist += ' \n'; + plist += (' ' + process.execPath + '\n'); + plist += ' macosRepair.js\n'; + plist += ' \n'; + plist += ' WorkingDirectory\n'; + plist += (' ' + process.cwd() + '\n'); + plist += ' RunAtLoad\n'; + plist += ' \n'; + plist += ' \n'; + plist += ''; + require('fs').writeFileSync('/Library/LaunchDaemons/meshagentRepair.plist', plist); + + child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write("launchctl load /Library/LaunchDaemons/meshagentRepair.plist\nexit\n"); + child.waitExit(); + } + } + } + } + + // Create Secure IPC for Diagnostic Agent Communications + obj.DAIPC = require('net').createServer(); + if (process.platform != 'win32') { try { require('fs').unlinkSync(process.cwd() + '/DAIPC'); } catch (ee) { } } + obj.DAIPC.IPCPATH = process.platform == 'win32' ? ('\\\\.\\pipe\\' + require('_agentNodeId')() + '-DAIPC') : (process.cwd() + '/DAIPC'); + try { obj.DAIPC.listen({ path: obj.DAIPC.IPCPATH }); } catch (e) { } + obj.DAIPC.on('connection', function (c) + { + c._send = function (j) + { + var data = JSON.stringify(j); + var packet = Buffer.alloc(data.length + 4); + packet.writeUInt32LE(data.length + 4, 0); + Buffer.from(data).copy(packet, 4); + this.end(packet); + }; + this._daipc = c; + c.parent = this; + c.on('end', function () { console.log('Connection Closed'); this.parent._daipc = null; }); + c.on('data', function (chunk) + { + if (chunk.length < 4) { this.unshift(chunk); return; } + var len = chunk.readUInt32LE(0); + if (len > 8192) { this.parent._daipc = null; this.end(); return; } + if (chunk.length < len) { this.unshift(chunk); return; } + + var data = chunk.slice(4, len); + try + { + data = JSON.parse(data.toString()); + } + catch(de) + { + this.parent._daipc = null; this.end(); return; + } + + if (!data.cmd) { this.parent._daipc = null; this.end(); return; } + + try + { + switch(data.cmd) + { + case 'query': + switch(data.value) + { + case 'connection': + data.result = require('MeshAgent').ConnectedServer; + this._send(data); + break; + } + break; + default: + this.parent._daipc = null; this.end(); return; + break; + } + } + catch(xe) + { + this.parent._daipc = null; this.end(); return; + } + }); + }); + function diagnosticAgent_uninstall() + { + require('service-manager').manager.uninstallService('meshagentDiagnostic'); + require('task-scheduler').delete('meshagentDiagnostic/periodicStart'); + }; + function diagnosticAgent_installCheck(install) + { + try + { + var diag = require('service-manager').manager.getService('meshagentDiagnostic'); + return (diag); + } + catch (e) + { + } + if (!install) { return (null); } + + var svc = null; + try + { + require('service-manager').manager.installService( + { + name: 'meshagentDiagnostic', + displayName: 'Mesh Agent Diagnostic Service', + description: 'Mesh Agent Diagnostic Service', + servicePath: process.execPath, + parameters: ['-recovery'] + //files: [{ newName: 'diagnostic.js', _buffer: Buffer.from('LyoNCkNvcHlyaWdodCAyMDE5IEludGVsIENvcnBvcmF0aW9uDQoNCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQoNCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCg0KVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQoqLw0KDQp2YXIgaG9zdCA9IHJlcXVpcmUoJ3NlcnZpY2UtaG9zdCcpLmNyZWF0ZSgnbWVzaGFnZW50RGlhZ25vc3RpYycpOw0KdmFyIFJlY292ZXJ5QWdlbnQgPSByZXF1aXJlKCdNZXNoQWdlbnQnKTsNCg0KaG9zdC5vbignc2VydmljZVN0YXJ0JywgZnVuY3Rpb24gKCkNCnsNCiAgICBjb25zb2xlLnNldERlc3RpbmF0aW9uKGNvbnNvbGUuRGVzdGluYXRpb25zLkxPR0ZJTEUpOw0KICAgIGhvc3Quc3RvcCA9IGZ1bmN0aW9uKCkNCiAgICB7DQogICAgICAgIHJlcXVpcmUoJ3NlcnZpY2UtbWFuYWdlcicpLm1hbmFnZXIuZ2V0U2VydmljZSgnbWVzaGFnZW50RGlhZ25vc3RpYycpLnN0b3AoKTsNCiAgICB9DQogICAgUmVjb3ZlcnlBZ2VudC5vbignQ29ubmVjdGVkJywgZnVuY3Rpb24gKHN0YXR1cykNCiAgICB7DQogICAgICAgIGlmIChzdGF0dXMgPT0gMCkNCiAgICAgICAgew0KICAgICAgICAgICAgY29uc29sZS5sb2coJ0RpYWdub3N0aWMgQWdlbnQ6IFNlcnZlciBjb25uZWN0aW9uIGxvc3QuLi4nKTsNCiAgICAgICAgICAgIHJldHVybjsNCiAgICAgICAgfQ0KICAgICAgICBjb25zb2xlLmxvZygnRGlhZ25vc3RpYyBBZ2VudDogQ29ubmVjdGlvbiBFc3RhYmxpc2hlZCB3aXRoIFNlcnZlcicpOw0KICAgICAgICBzdGFydCgpOw0KICAgIH0pOw0KfSk7DQpob3N0Lm9uKCdub3JtYWxTdGFydCcsIGZ1bmN0aW9uICgpDQp7DQogICAgaG9zdC5zdG9wID0gZnVuY3Rpb24gKCkNCiAgICB7DQogICAgICAgIHByb2Nlc3MuZXhpdCgpOw0KICAgIH0NCiAgICBjb25zb2xlLmxvZygnTm9uIFNlcnZpY2UgTW9kZScpOw0KICAgIFJlY292ZXJ5QWdlbnQub24oJ0Nvbm5lY3RlZCcsIGZ1bmN0aW9uIChzdGF0dXMpDQogICAgew0KICAgICAgICBpZiAoc3RhdHVzID09IDApDQogICAgICAgIHsNCiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdEaWFnbm9zdGljIEFnZW50OiBTZXJ2ZXIgY29ubmVjdGlvbiBsb3N0Li4uJyk7DQogICAgICAgICAgICByZXR1cm47DQogICAgICAgIH0NCiAgICAgICAgY29uc29sZS5sb2coJ0RpYWdub3N0aWMgQWdlbnQ6IENvbm5lY3Rpb24gRXN0YWJsaXNoZWQgd2l0aCBTZXJ2ZXInKTsNCiAgICAgICAgc3RhcnQoKTsNCiAgICB9KTsNCn0pOw0KaG9zdC5vbignc2VydmljZVN0b3AnLCBmdW5jdGlvbiAoKSB7IHByb2Nlc3MuZXhpdCgpOyB9KTsNCmhvc3QucnVuKCk7DQoNCg0KZnVuY3Rpb24gc3RhcnQoKQ0Kew0KDQp9Ow0K', 'base64') }] + }); + svc = require('service-manager').manager.getService('meshagentDiagnostic'); + } + catch (e) + { + return (null); + } + var proxyConfig = require('global-tunnel').proxyConfig; + var cert = require('MeshAgent').GenerateAgentCertificate('CN=MeshNodeDiagnosticCertificate'); + var nodeid = require('tls').loadCertificate(cert.root).getKeyHash().toString('base64'); + ddb = require('SimpleDataStore').Create(svc.appWorkingDirectory().replace('\\', '/') + '/meshagentDiagnostic.db'); + ddb.Put('disableUpdate', '1'); + ddb.Put('MeshID', Buffer.from(require('MeshAgent').ServerInfo.MeshID, 'hex')); + ddb.Put('ServerID', require('MeshAgent').ServerInfo.ServerID); + ddb.Put('MeshServer', require('MeshAgent').ServerInfo.ServerUri); + if (cert.root.pfx) { ddb.Put('SelfNodeCert', cert.root.pfx); } + if (cert.tls) { ddb.Put('SelfNodeTlsCert', cert.tls.pfx); } + if (proxyConfig) + { + ddb.Put('WebProxy', proxyConfig.host + ':' + proxyConfig.port); + } + else + { + ddb.Put('ignoreProxyFile', '1'); + } + + require('MeshAgent').SendCommand({ action: 'diagnostic', value: { command: 'register', value: nodeid } }); + require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: 'Diagnostic Agent Registered [' + nodeid.length + '/' + nodeid + ']' }); + + delete ddb; + + // Set a recurrent task, to run the Diagnostic Agent every 2 days + require('task-scheduler').create({name: 'meshagentDiagnostic/periodicStart', daily: 2, time: require('tls').generateRandomInteger('0', '23') + ':' + require('tls').generateRandomInteger('0', '59').padStart(2, '0'), service: 'meshagentDiagnostic'}); + //require('task-scheduler').create({ name: 'meshagentDiagnostic/periodicStart', daily: '1', time: '17:16', service: 'meshagentDiagnostic' }); + + return (svc); + } + + /* + function borderController() { + this.container = null; + this.Start = function Start(user) { + if (this.container == null) { + if (process.platform == 'win32') { + try { + this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.SessionId }); + } catch (ex) { + this.container = require('ScriptContainer').Create({ processIsolation: 1 }); + } + } else { + this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.uid }); + } + this.container.parent = this; + this.container.addModule('monitor-info', getJSModule('monitor-info')); + this.container.addModule('monitor-border', getJSModule('monitor-border')); + this.container.addModule('promise', getJSModule('promise')); + this.container.once('exit', function (code) { sendConsoleText('Border Process Exited with code: ' + code); this.parent.container = this.parent._container = null; }); + this.container.ExecuteString("var border = require('monitor-border'); border.Start();"); + } + } + this.Stop = function Stop() { + if (this.container != null) { + this._container = this.container; + this._container.parent = this; + this.container = null; + this._container.exit(); + } + } + } + obj.borderManager = new borderController(); + */ + + // MeshAgent JavaScript Core Module. This code is sent to and running on the mesh agent. + var meshCoreObj = { "action": "coreinfo", "value": "MeshCore v6", "caps": 14 }; // Capability bitmask: 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript, 32 = Temporary Agent, 64 = Recovery Agent + + // Get the operating system description string + try { require('os').name().then(function (v) { meshCoreObj.osdesc = v; }); } catch (ex) { } + + var meshServerConnectionState = 0; + var tunnels = {}; + var lastMeInfo = null; + var lastNetworkInfo = null; + var lastPublicLocationInfo = null; + var selfInfoUpdateTimer = null; + var http = require('http'); + var net = require('net'); + var fs = require('fs'); + var rtc = require('ILibWebRTC'); + var amt = null; + var processManager = require('process-manager'); + var wifiScannerLib = null; + var wifiScanner = null; + var networkMonitor = null; + var amtscanner = null; + var nextTunnelIndex = 1; + var amtPolicy = null; + + // If we are running in Duktape, agent will be null + if (agent == null) { + // Running in native agent, Import libraries + db = require('SimpleDataStore').Shared(); + sha = require('SHA256Stream'); + mesh = require('MeshAgent'); + childProcess = require('child_process'); + if (mesh.hasKVM == 1) { // if the agent is compiled with KVM support + // Check if this computer supports a desktop + try { if ((process.platform == 'win32') || (process.platform == 'darwin') || (require('monitor-info').kvm_x11_support)) { meshCoreObj.caps |= 1; } } catch (ex) { } + } + } else { + // Running in nodejs + meshCoreObj.value += '-NodeJS'; + meshCoreObj.caps = 8; + mesh = agent.getMeshApi(); + } + + mesh.DAIPC = obj.DAIPC; + + /* + var AMTScanner = require("AMTScanner"); + var scan = new AMTScanner(); + + scan.on("found", function (data) { + if (typeof data === 'string') { + console.log(data); + } else { + console.log(JSON.stringify(data, null, " ")); + } + }); + scan.scan("10.2.55.140", 1000); + scan.scan("10.2.55.139-10.2.55.145", 1000); + scan.scan("10.2.55.128/25", 2000); + */ + + /* + // Try to load up the network monitor + try { + networkMonitor = require('NetworkMonitor'); + networkMonitor.on('change', function () { sendNetworkUpdateNagle(); }); + networkMonitor.on('add', function (addr) { sendNetworkUpdateNagle(); }); + networkMonitor.on('remove', function (addr) { sendNetworkUpdateNagle(); }); + } catch (e) { networkMonitor = null; } + */ + + // Try to load up the Intel AMT scanner + try { + var AMTScannerModule = require('amt-scanner'); + amtscanner = new AMTScannerModule(); + //amtscanner.on('found', function (data) { if (typeof data != 'string') { data = JSON.stringify(data, null, " "); } sendConsoleText(data); }); + } catch (ex) { amtscanner = null; } + + // Fetch the SMBios Tables + var SMBiosTables = null; + var SMBiosTablesRaw = null; + try { + var SMBiosModule = null; + try { SMBiosModule = require('smbios'); } catch (ex) { } + if (SMBiosModule != null) { + SMBiosModule.get(function (data) { + if (data != null) { + SMBiosTablesRaw = data; + SMBiosTables = require('smbios').parse(data) + if (mesh.isControlChannelConnected) { mesh.SendCommand({ "action": "smbios", "value": SMBiosTablesRaw }); } + + // If SMBios tables say that AMT is present, try to connect MEI + if (SMBiosTables.amtInfo && (SMBiosTables.amtInfo.AMT == true)) { + var amtmodule = require('amt-manage'); + amt = new amtmodule(mesh, db, true); + amt.onStateChange = function (state) { if (state == 2) { sendPeriodicServerUpdate(1); } } + if (amtPolicy != null) { amt.setPolicy(amtPolicy); } + amt.start(); + } + } + }); + } + } catch (ex) { sendConsoleText("ex1: " + ex); } + + // Try to load up the WIFI scanner + try { + var wifiScannerLib = require('wifi-scanner'); + wifiScanner = new wifiScannerLib(); + wifiScanner.on('accessPoint', function (data) { sendConsoleText("wifiScanner: " + data); }); + } catch (ex) { wifiScannerLib = null; wifiScanner = null; } + + // Get our location (lat/long) using our public IP address + var getIpLocationDataExInProgress = false; + var getIpLocationDataExCounts = [0, 0]; + function getIpLocationDataEx(func) { + if (getIpLocationDataExInProgress == true) { return false; } + try { + getIpLocationDataExInProgress = true; + getIpLocationDataExCounts[0]++; + var options = http.parseUri("http://ipinfo.io/json"); + options.method = 'GET'; + http.request(options, function (resp) { + if (resp.statusCode == 200) { + var geoData = ''; + resp.data = function (geoipdata) { geoData += geoipdata; }; + resp.end = function () { + var location = null; + try { + if (typeof geoData == 'string') { + var result = JSON.parse(geoData); + if (result.ip && result.loc) { location = result; } + } + } catch (e) { } + if (func) { getIpLocationDataExCounts[1]++; func(location); } + } + } else { func(null); } + getIpLocationDataExInProgress = false; + }).end(); + return true; + } + catch (e) { return false; } + } + + // Remove all Gateway MAC addresses for interface list. This is useful because the gateway MAC is not always populated reliably. + function clearGatewayMac(str) { + if (str == null) return null; + var x = JSON.parse(str); + for (var i in x.netif) { if (x.netif[i].gatewaymac) { delete x.netif[i].gatewaymac } } + return JSON.stringify(x); + } + + function getIpLocationData(func) { + // Get the location information for the cache if possible + var publicLocationInfo = db.Get('publicLocationInfo'); + if (publicLocationInfo != null) { publicLocationInfo = JSON.parse(publicLocationInfo); } + if (publicLocationInfo == null) { + // Nothing in the cache, fetch the data + getIpLocationDataEx(function (locationData) { + if (locationData != null) { + publicLocationInfo = {}; + publicLocationInfo.netInfoStr = lastNetworkInfo; + publicLocationInfo.locationData = locationData; + var x = db.Put('publicLocationInfo', JSON.stringify(publicLocationInfo)); // Save to database + if (func) func(locationData); // Report the new location + } else { + if (func) func(null); // Report no location + } + }); + } else { + // Check the cache + if (clearGatewayMac(publicLocationInfo.netInfoStr) == clearGatewayMac(lastNetworkInfo)) { + // Cache match + if (func) func(publicLocationInfo.locationData); + } else { + // Cache mismatch + getIpLocationDataEx(function (locationData) { + if (locationData != null) { + publicLocationInfo = {}; + publicLocationInfo.netInfoStr = lastNetworkInfo; + publicLocationInfo.locationData = locationData; + var x = db.Put('publicLocationInfo', JSON.stringify(publicLocationInfo)); // Save to database + if (func) func(locationData); // Report the new location + } else { + if (func) func(publicLocationInfo.locationData); // Can't get new location, report the old location + } + }); + } + } + } + + // Polyfill String.endsWith + if (!String.prototype.endsWith) { + String.prototype.endsWith = function (searchString, position) { + var subjectString = this.toString(); + if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) { position = subjectString.length; } + position -= searchString.length; + var lastIndex = subjectString.lastIndexOf(searchString, position); + return lastIndex !== -1 && lastIndex === position; + }; + } + + // Polyfill path.join + obj.path = { + join: function () { + var x = []; + for (var i in arguments) { + var w = arguments[i]; + if (w != null) { + while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); } + if (i != 0) { + while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); } + } + x.push(w); + } + } + if (x.length == 0) return '/'; + return x.join('/'); + } + }; + + // Replace a string with a number if the string is an exact number + function toNumberIfNumber(x) { if ((typeof x == 'string') && (+parseInt(x) === x)) { x = parseInt(x); } return x; } + + // Convert decimal to hex + function char2hex(i) { return (i + 0x100).toString(16).substr(-2).toUpperCase(); } + + // Convert a raw string to a hex string + function rstr2hex(input) { var r = '', i; for (i = 0; i < input.length; i++) { r += char2hex(input.charCodeAt(i)); } return r; } + + // Convert a buffer into a string + function buf2rstr(buf) { var r = ''; for (var i = 0; i < buf.length; i++) { r += String.fromCharCode(buf[i]); } return r; } + + // Convert a hex string to a raw string // TODO: Do this using Buffer(), will be MUCH faster + function hex2rstr(d) { + if (typeof d != "string" || d.length == 0) return ''; + var r = '', m = ('' + d).match(/../g), t; + while (t = m.shift()) r += String.fromCharCode('0x' + t); + return r + } + + // Convert an object to string with all functions + function objToString(x, p, pad, ret) { + if (ret == undefined) ret = ''; + if (p == undefined) p = 0; + if (x == null) { return '[null]'; } + if (p > 8) { return '[...]'; } + if (x == undefined) { return '[undefined]'; } + if (typeof x == 'string') { if (p == 0) return x; return '"' + x + '"'; } + if (typeof x == 'buffer') { return '[buffer]'; } + if (typeof x != 'object') { return x; } + var r = '{' + (ret ? '\r\n' : ' '); + for (var i in x) { if (i != '_ObjectID') { r += (addPad(p + 2, pad) + i + ': ' + objToString(x[i], p + 2, pad, ret) + (ret ? '\r\n' : ' ')); } } + return r + addPad(p, pad) + '}'; + } + + // Return p number of spaces + function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ret; } return r; } + + // Split a string taking into account the quoats. Used for command line parsing + function splitArgs(str) { + var myArray = [], myRegexp = /[^\s"]+|"([^"]*)"/gi; + do { var match = myRegexp.exec(str); if (match != null) { myArray.push(match[1] ? match[1] : match[0]); } } while (match != null); + return myArray; + } + + // Parse arguments string array into an object + function parseArgs(argv) { + var results = { '_': [] }, current = null; + for (var i = 1, len = argv.length; i < len; i++) { + var x = argv[i]; + if (x.length > 2 && x[0] == '-' && x[1] == '-') { + if (current != null) { results[current] = true; } + current = x.substring(2); + } else { + if (current != null) { results[current] = toNumberIfNumber(x); current = null; } else { results['_'].push(toNumberIfNumber(x)); } + } + } + if (current != null) { results[current] = true; } + return results; + } + + // Get server target url with a custom path + function getServerTargetUrl(path) { + var x = mesh.ServerUrl; + //sendConsoleText("mesh.ServerUrl: " + mesh.ServerUrl); + if (x == null) { return null; } + if (path == null) { path = ''; } + x = http.parseUri(x); + if (x == null) return null; + return x.protocol + '//' + x.host + ':' + x.port + '/' + path; + } + + // Get server url. If the url starts with "*/..." change it, it not use the url as is. + function getServerTargetUrlEx(url) { + if (url.substring(0, 2) == '*/') { return getServerTargetUrl(url.substring(2)); } + return url; + } + + // Send a wake-on-lan packet + function sendWakeOnLan(hexMac) { + var count = 0; + try { + var interfaces = require('os').networkInterfaces(); + var magic = 'FFFFFFFFFFFF'; + for (var x = 1; x <= 16; ++x) { magic += hexMac; } + var magicbin = Buffer.from(magic, 'hex'); + + for (var adapter in interfaces) { + if (interfaces.hasOwnProperty(adapter)) { + for (var i = 0; i < interfaces[adapter].length; ++i) { + var addr = interfaces[adapter][i]; + if ((addr.family == 'IPv4') && (addr.mac != '00:00:00:00:00:00')) { + var socket = require('dgram').createSocket({ type: "udp4" }); + socket.bind({ address: addr.address }); + socket.setBroadcast(true); + socket.send(magicbin, 7, "255.255.255.255"); + count++; + } + } + } + } + } catch (e) { } + return count; + } + + // Handle a mesh agent command + function handleServerCommand(data) { + if (typeof data == 'object') { + // If this is a console command, parse it and call the console handler + switch (data.action) { + case 'msg': { + switch (data.type) { + case 'console': { // Process a console command + if (data.value && data.sessionid) { + var args = splitArgs(data.value); + processConsoleCommand(args[0].toLowerCase(), parseArgs(args), data.rights, data.sessionid); + } + break; + } + case 'tunnel': { + if (data.value != null) { // Process a new tunnel connection request + // Create a new tunnel object + var xurl = getServerTargetUrlEx(data.value); + if (xurl != null) { + var woptions = http.parseUri(xurl); + woptions.rejectUnauthorized = 0; + //sendConsoleText(JSON.stringify(woptions)); + //sendConsoleText('TUNNEL: ' + JSON.stringify(data)); + var tunnel = http.request(woptions); + tunnel.upgrade = onTunnelUpgrade; + tunnel.on('error', function (e) { sendConsoleText('ERROR: ' + JSON.stringify(e)); }); + tunnel.sessionid = data.sessionid; + tunnel.rights = data.rights; + tunnel.consent = data.consent; + tunnel.username = data.username; + tunnel.state = 0; + tunnel.url = xurl; + tunnel.protocol = 0; + tunnel.tcpaddr = data.tcpaddr; + tunnel.tcpport = data.tcpport; + tunnel.udpaddr = data.udpaddr; + tunnel.udpport = data.udpport; + tunnel.end(); + // Put the tunnel in the tunnels list + var index = nextTunnelIndex++; + tunnel.index = index; + tunnels[index] = tunnel; + + //sendConsoleText('New tunnel connection #' + index + ': ' + tunnel.url + ', rights: ' + tunnel.rights, data.sessionid); + } + } + break; + } + case 'ps': { + // Return the list of running processes + if (data.sessionid) { + processManager.getProcesses(function (plist) { mesh.SendCommand({ "action": "msg", "type": "ps", "value": JSON.stringify(plist), "sessionid": data.sessionid }); }); + } + break; + } + case 'pskill': { + // Kill a process + if (data.value) { + try { process.kill(data.value); } catch (e) { sendConsoleText("pskill: " + JSON.stringify(e)); } + } + break; + } + case 'openUrl': { + // Open a local web browser and return success/fail + sendConsoleText('OpenURL: ' + data.url); + if (data.url) { mesh.SendCommand({ "action": "msg", "type":"openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); } + break; + } + case 'getclip': { + // Send the load clipboard back to the user + //sendConsoleText('getClip: ' + JSON.stringify(data)); + if (require('MeshAgent').isService) + { + require('clipboard').dispatchRead().then(function (str) { mesh.SendCommand({ "action": "msg", "type": "getclip", "sessionid": data.sessionid, "data": str }); }); + } + else + { + require("clipboard").read().then(function (str) { mesh.SendCommand({ "action": "msg", "type": "getclip", "sessionid": data.sessionid, "data": str }); }); + } + break; + } + case 'setclip': { + // Set the load clipboard to a user value + //sendConsoleText('setClip: ' + JSON.stringify(data)); + if (typeof data.data == 'string') + { + if (require('MeshAgent').isService) + { + require('clipboard').dispatchWrite(data.data); + } + else + { + require("clipboard")(data.data); // Set the clipboard + } + mesh.SendCommand({ "action": "msg", "type": "setclip", "sessionid": data.sessionid, "success": true }); + } + break; + } + default: + // Unknown action, ignore it. + break; + } + break; + } + case 'wakeonlan': { + // Send wake-on-lan on all interfaces for all MAC addresses in data.macs array. The array is a list of HEX MAC addresses. + sendConsoleText('Server requesting wake-on-lan for: ' + data.macs.join(', ')); + for (var i in data.macs) { sendWakeOnLan(data.macs[i]); } + break; + } + case 'poweraction': { + // Server telling us to execute a power action + if ((mesh.ExecPowerState != undefined) && (data.actiontype)) { + var forced = 0; + if (data.forced == 1) { forced = 1; } + data.actiontype = parseInt(data.actiontype); + sendConsoleText('Performing power action=' + data.actiontype + ', forced=' + forced + '.'); + var r = mesh.ExecPowerState(data.actiontype, forced); + sendConsoleText('ExecPowerState returned code: ' + r); + } + break; + } + case 'iplocation': { + // Update the IP location information of this node. Only do this when requested by the server since we have a limited amount of time we can call this per day + getIpLocationData(function (location) { mesh.SendCommand({ "action": "iplocation", "type": "publicip", "value": location }); }); + break; + } + case 'toast': { + // Display a toast message + if (data.title && data.msg) { + try { require('toaster').Toast(data.title, data.msg); } catch (ex) { } + } + break; + } + case 'openUrl': { + // Open a local web browser and return success/fail + sendConsoleText('OpenURL: ' + data.url); + if (data.url) { mesh.SendCommand({ "action": "openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); } + break; + } + case 'amtPolicy': { + // Store the latest Intel AMT policy + amtPolicy = data.amtPolicy; + if (data.amtPolicy != null) { db.Put('amtPolicy', JSON.stringify(data.amtPolicy)); } else { db.Put('amtPolicy', null); } + if (amt != null) { amt.setPolicy(amtPolicy); } + break; + } + case 'getScript': { + // Received a configuration script from the server + sendConsoleText('getScript: ' + JSON.stringify(data)); + break; + } + case 'ping': { mesh.SendCommand('{"action":"pong"}'); break; } + case 'pong': { break; } + default: + // Unknown action, ignore it. + break; + } + } + } + + // Called when a file changed in the file system + /* + function onFileWatcher(a, b) { + console.log('onFileWatcher', a, b, this.path); + var response = getDirectoryInfo(this.path); + if ((response != undefined) && (response != null)) { this.tunnel.s.write(JSON.stringify(response)); } + } + */ + + // Get a formated response for a given directory path + function getDirectoryInfo(reqpath) { + var response = { path: reqpath, dir: [] }; + if (((reqpath == undefined) || (reqpath == '')) && (process.platform == 'win32')) { + // List all the drives in the root, or the root itself + var results = null; + try { results = fs.readDrivesSync(); } catch (e) { } // TODO: Anyway to get drive total size and free space? Could draw a progress bar. + if (results != null) { + for (var i = 0; i < results.length; ++i) { + var drive = { n: results[i].name, t: 1 }; + if (results[i].type == 'REMOVABLE') { drive.dt = 'removable'; } // TODO: See if this is USB/CDROM or something else, we can draw icons. + response.dir.push(drive); + } + } + } else { + // List all the files and folders in this path + if (reqpath == '') { reqpath = '/'; } + var results = null, xpath = obj.path.join(reqpath, '*'); + //if (process.platform == "win32") { xpath = xpath.split('/').join('\\'); } + try { results = fs.readdirSync(xpath); } catch (e) { } + if (results != null) { + for (var i = 0; i < results.length; ++i) { + if ((results[i] != '.') && (results[i] != '..')) { + var stat = null, p = obj.path.join(reqpath, results[i]); + //if (process.platform == "win32") { p = p.split('/').join('\\'); } + try { stat = fs.statSync(p); } catch (e) { } // TODO: Get file size/date + if ((stat != null) && (stat != undefined)) { + if (stat.isDirectory() == true) { + response.dir.push({ n: results[i], t: 2, d: stat.mtime }); + } else { + response.dir.push({ n: results[i], t: 3, s: stat.size, d: stat.mtime }); + } + } + } + } + } + } + return response; + } + + // Tunnel callback operations + function onTunnelUpgrade(response, s, head) { + this.s = s; + s.httprequest = this; + s.end = onTunnelClosed; + s.tunnel = this; + + //sendConsoleText('onTunnelUpgrade - ' + this.tcpport + ' - ' + this.udpport); + + if (this.tcpport != null) { + // This is a TCP relay connection, pause now and try to connect to the target. + s.pause(); + s.data = onTcpRelayServerTunnelData; + var connectionOptions = { port: parseInt(this.tcpport) }; + if (this.tcpaddr != null) { connectionOptions.host = this.tcpaddr; } else { connectionOptions.host = '127.0.0.1'; } + s.tcprelay = net.createConnection(connectionOptions, onTcpRelayTargetTunnelConnect); + s.tcprelay.peerindex = this.index; + } if (this.udpport != null) { + // This is a UDP relay connection, get the UDP socket setup. // TODO: *************** + s.data = onUdpRelayServerTunnelData; + s.udprelay = require('dgram').createSocket({ type: 'udp4' }); + s.udprelay.bind({ port: 0 }); + s.udprelay.peerindex = this.index; + s.udprelay.on('message', onUdpRelayTargetTunnelConnect); + s.udprelay.udpport = this.udpport; + s.udprelay.udpaddr = this.udpaddr; + s.udprelay.first = true; + } else { + // This is a normal connect for KVM/Terminal/Files + s.data = onTunnelData; + } + } + + // Called when UDP relay data is received // TODO**** + function onUdpRelayTargetTunnelConnect(data) { + var peerTunnel = tunnels[this.peerindex]; + peerTunnel.s.write(data); + } + + // Called when we get data from the server for a TCP relay (We have to skip the first received 'c' and pipe the rest) + function onUdpRelayServerTunnelData(data) { + if (this.udprelay.first === true) { + delete this.udprelay.first; // Skip the first 'c' that is received. + } else { + this.udprelay.send(data, parseInt(this.udprelay.udpport), this.udprelay.udpaddr ? this.udprelay.udpaddr : '127.0.0.1'); + } + } + + // Called when the TCP relay target is connected + function onTcpRelayTargetTunnelConnect() { + var peerTunnel = tunnels[this.peerindex]; + this.pipe(peerTunnel.s); // Pipe Target --> Server + peerTunnel.s.first = true; + peerTunnel.s.resume(); + } + + // Called when we get data from the server for a TCP relay (We have to skip the first received 'c' and pipe the rest) + function onTcpRelayServerTunnelData(data) { + if (this.first == true) { this.first = false; this.pipe(this.tcprelay); } // Pipe Server --> Target + } + + function onTunnelClosed() { + if (tunnels[this.httprequest.index] == null) return; // Stop duplicate calls. + //sendConsoleText("Tunnel #" + this.httprequest.index + " closed.", this.httprequest.sessionid); + delete tunnels[this.httprequest.index]; + + /* + // Close the watcher if required + if (this.httprequest.watcher != undefined) { + //console.log('Closing watcher: ' + this.httprequest.watcher.path); + //this.httprequest.watcher.close(); // TODO: This line causes the agent to crash!!!! + delete this.httprequest.watcher; + } + */ + + // If there is a upload or download active on this connection, close the file + if (this.httprequest.uploadFile) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; } + if (this.httprequest.downloadFile) { fs.closeSync(this.httprequest.downloadFile); this.httprequest.downloadFile = undefined; } + + // Clean up WebRTC + if (this.webrtc != null) { + if (this.webrtc.rtcchannel) { try { this.webrtc.rtcchannel.close(); } catch (e) { } this.webrtc.rtcchannel.removeAllListeners('data'); this.webrtc.rtcchannel.removeAllListeners('end'); delete this.webrtc.rtcchannel; } + if (this.webrtc.websocket) { delete this.webrtc.websocket; } + try { this.webrtc.close(); } catch (e) { } + this.webrtc.removeAllListeners('connected'); + this.webrtc.removeAllListeners('disconnected'); + this.webrtc.removeAllListeners('dataChannel'); + delete this.webrtc; + } + + // Clean up WebSocket + this.removeAllListeners('data'); + } + function onTunnelSendOk() { /*sendConsoleText("Tunnel #" + this.index + " SendOK.", this.sessionid);*/ } + function onTunnelData(data) { + //console.log("OnTunnelData"); + //sendConsoleText('OnTunnelData, ' + data.length + ', ' + typeof data + ', ' + data); + + // If this is upload data, save it to file + if (this.httprequest.uploadFile) { + try { fs.writeSync(this.httprequest.uploadFile, data); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'uploaderror' }))); return; } // Write to the file, if there is a problem, error out. + this.write(new Buffer(JSON.stringify({ action: 'uploadack', reqid: this.httprequest.uploadFileid }))); // Ask for more data + return; + } + /* + // If this is a download, send more of the file + if (this.httprequest.downloadFile) { + var buf = new Buffer(4096); + var len = fs.readSync(this.httprequest.downloadFile, buf, 0, 4096, null); + this.httprequest.downloadFilePtr += len; + if (len > 0) { this.write(buf.slice(0, len)); } else { fs.closeSync(this.httprequest.downloadFile); this.httprequest.downloadFile = undefined; this.end(); } + return; + } + */ + + if (this.httprequest.state == 0) { + // Check if this is a relay connection + if (data == 'c') { this.httprequest.state = 1; /*sendConsoleText("Tunnel #" + this.httprequest.index + " now active", this.httprequest.sessionid);*/ } + } else { + // Handle tunnel data + if (this.httprequest.protocol == 0) { // 1 = Terminal, 2 = Desktop, 5 = Files + // Take a look at the protocol + this.httprequest.protocol = parseInt(data); + if (typeof this.httprequest.protocol != 'number') { this.httprequest.protocol = 0; } + if (this.httprequest.protocol == 1) { + // Check user access rights for terminal + if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NOTERMINAL) != 0))) { + // Disengage this tunnel, user does not have the rights to do this!! + this.httprequest.protocol = 999999; + this.httprequest.s.end(); + sendConsoleText('Error: No Terminal Control Rights.'); + return; + } + + + this.end = function () { + if (process.platform == "win32") { + // Unpipe the web socket + this.unpipe(this.httprequest._term); + this.httprequest._term.unpipe(this); + + // Unpipe the WebRTC channel if needed (This will also be done when the WebRTC channel ends). + if (this.rtcchannel) { + this.rtcchannel.unpipe(this.httprequest._term); + this.httprequest._term.unpipe(this.rtcchannel); + } + + // Clean up + this.httprequest._term.end(); + this.httprequest._term = null; + } else { + // TODO!! + } + }; + + // Remote terminal using native pipes + if (process.platform == "win32") { + this.httprequest._term = require('win-terminal').Start(80, 25); + this.httprequest._term.pipe(this, { dataTypeSkip: 1 }); + this.pipe(this.httprequest._term, { dataTypeSkip: 1, end: false }); + this.prependListener('end', function () { this.httprequest._term.end(function () { console.log('Terminal was closed'); }); }); + } else { + if (fs.existsSync("/bin/bash")) { + this.httprequest.process = childProcess.execFile("/bin/bash", ["bash", "-i"], { type: childProcess.SpawnTypes.TERM }); + if (process.platform == 'linux') { this.httprequest.process.stdin.write("alias ls='ls --color=auto'\nclear\n"); } + } else { + this.httprequest.process = childProcess.execFile("/bin/sh", ["sh"], { type: childProcess.SpawnTypes.TERM }); + if (process.platform == 'linux') { this.httprequest.process.stdin.write("stty erase ^H\nalias ls='ls --color=auto'\nPS1='\\u@\\h:\\w\\$ '\nclear\n"); } + } + this.httprequest.process.tunnel = this; + this.httprequest.process.on('exit', function (ecode, sig) { this.tunnel.end(); }); + this.httprequest.process.stderr.on('data', function (chunk) { this.parent.tunnel.write(chunk); }); + this.httprequest.process.stdout.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. + this.pipe(this.httprequest.process.stdin, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. + this.prependListener('end', function () { this.httprequest.process.kill(); }); + this.httprequest.process.stdin.write("stty erase ^H\nalias ls='ls --color=auto'\nclear\n"); + } + + // Perform notification if needed. Toast messages may not be supported on all platforms. + if (this.httprequest.consent && (this.httprequest.consent & 16)) { + // User Consent Prompt is required + + // Send a console message back using the console channel, "\n" is supported. + this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'Waiting for user to grant access...' })); + + var pr = require('message-box').create('MeshCentral', this.httprequest.username + ' requesting Terminal Access. Grant access?', 10); + pr.ws = this; + this.pause(); + + pr.then( + function () { + // Success! + this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null })); + if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 2)) { + // User Notifications is required + try { require('toaster').Toast('MeshCentral', this.ws.httprequest.username + ' started a remote terminal session.'); } catch (ex) { } + } + + this.ws.resume(); + }, + function (e) { + // User Consent Denied/Failed! + this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString() })); + this.ws.end(); + }); + } + else { + // User Consent Prompt is not required + if (this.httprequest.consent && (this.httprequest.consent & 2)) { + // User Notifications is required + try { require('toaster').Toast('MeshCentral', this.httprequest.username + ' started a remote terminal session.'); } catch (ex) { } + } + this.resume(); + } + + + + + + this.removeAllListeners('data'); + this.on('data', onTunnelControlData); + //this.write('MeshCore Terminal Hello'); + } else if (this.httprequest.protocol == 2) + { + // Check user access rights for desktop + if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0)) { + // Disengage this tunnel, user does not have the rights to do this!! + this.httprequest.protocol = 999999; + this.httprequest.s.end(); + sendConsoleText('Error: No Desktop Control Rights.'); + return; + } + + + // Remote desktop using native pipes + this.httprequest.desktop = { state: 0, kvm: mesh.getRemoteDesktopStream(), tunnel: this }; + this.httprequest.desktop.kvm.parent = this.httprequest.desktop; + this.desktop = this.httprequest.desktop; + + this.end = function () { + --this.desktop.kvm.connectionCount; + + // Unpipe the web socket + this.unpipe(this.httprequest.desktop.kvm); + this.httprequest.desktop.kvm.unpipe(this); + + // Unpipe the WebRTC channel if needed (This will also be done when the WebRTC channel ends). + if (this.rtcchannel) { + this.rtcchannel.unpipe(this.httprequest.desktop.kvm); + this.httprequest.desktop.kvm.unpipe(this.rtcchannel); + } + + if (this.desktop.kvm.connectionCount == 0) { + // Display a toast message. This may not be supported on all platforms. + // try { require('toaster').Toast('MeshCentral', 'Remote Desktop Control Ended.'); } catch (ex) { } + + this.httprequest.desktop.kvm.end(); + } + }; + if (this.httprequest.desktop.kvm.hasOwnProperty("connectionCount")) { this.httprequest.desktop.kvm.connectionCount++; } else { this.httprequest.desktop.kvm.connectionCount = 1; } + + if ((this.httprequest.rights == 0xFFFFFFFF) || (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) != 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0))) { + // If we have remote control rights, pipe the KVM input + this.pipe(this.httprequest.desktop.kvm, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. Pipe the Browser --> KVM input. + } else { + // We need to only pipe non-mouse & non-keyboard inputs. + //sendConsoleText('Warning: No Remote Desktop Input Rights.'); + // TODO!!! + } + + // Perform notification if needed. Toast messages may not be supported on all platforms. + if (this.httprequest.consent && (this.httprequest.consent & 8)) + { + // User Consent Prompt is required + + // Send a console message back using the console channel, "\n" is supported. + this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'Waiting for user to grant access...' })); + + var pr = require('message-box').create('MeshCentral', this.httprequest.username + ' requesting KVM Access. Grant access?', 10); + pr.ws = this; + this.pause(); + + pr.then( + function () + { + // Success! + this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null })); + if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 1)) + { + // User Notifications is required + try { require('toaster').Toast('MeshCentral', this.ws.httprequest.username + ' started a remote desktop session.'); } catch (ex) { } + } + + this.ws.httprequest.desktop.kvm.pipe(this.ws, { dataTypeSkip: 1 }); + this.ws.resume(); + }, + function (e) + { + // User Consent Denied/Failed! + this.ws.end(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString() })); + + //var err = 'User consent: ' + e.toString(); + //var b = Buffer.alloc(5 + err.length); + //b.writeUInt16BE(MNG_ERROR, 0); + //b.writeUInt16BE(err.length + 4, 2); + //Buffer.from(err).copy(b, 4); + //this.ws.end(b); + }); + } + else + { + // User Consent Prompt is not required + if (this.httprequest.consent && (this.httprequest.consent & 1)) + { + // User Notifications is required + try { require('toaster').Toast('MeshCentral', this.httprequest.username + ' started a remote desktop session.'); } catch (ex) { } + } + this.httprequest.desktop.kvm.pipe(this, { dataTypeSkip: 1 }); + } + + this.removeAllListeners('data'); + this.on('data', onTunnelControlData); + //this.write('MeshCore KVM Hello!1'); + + } else if (this.httprequest.protocol == 5) { + + // Check user access rights for files + if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NOFILES) != 0))) { + // Disengage this tunnel, user does not have the rights to do this!! + this.httprequest.protocol = 999999; + this.httprequest.s.end(); + sendConsoleText('Error: No files control rights.'); + return; + } + + // Perform notification if needed. Toast messages may not be supported on all platforms. + if (this.httprequest.consent && (this.httprequest.consent & 32)) + { + // User Consent Prompt is required + + // Send a console message back using the console channel, "\n" is supported. + this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'Waiting for user to grant access...' })); + + var pr = require('message-box').create('MeshCentral', this.httprequest.username + ' requesting remote file access. Grant access?', 10); + pr.ws = this; + this.pause(); + + pr.then( + function () { + // Success! + this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null })); + if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 4)) + { + // User Notifications is required + try { require('toaster').Toast('MeshCentral', this.ws.httprequest.username + ' started a remote file session.'); } catch (ex) { } + } + this.ws.resume(); + }, + function (e) { + // User Consent Denied/Failed! + this.ws.end(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString() })); + }); + } + else { + // User Consent Prompt is not required + if (this.httprequest.consent && (this.httprequest.consent & 4)) { + // User Notifications is required + try { require('toaster').Toast('MeshCentral', this.httprequest.username + ' started a remote file session.'); } catch (ex) { } + } + this.resume(); + } + + // Setup files + // NOP + } + } else if (this.httprequest.protocol == 1) { + // Send data into terminal stdin + //this.write(data); // Echo back the keys (Does not seem to be a good idea) + this.httprequest.process.write(data); + } else if (this.httprequest.protocol == 2) { + // Send data into remote desktop + if (this.httprequest.desktop.state == 0) { + this.write(new Buffer(String.fromCharCode(0x11, 0xFE, 0x00, 0x00, 0x4D, 0x45, 0x53, 0x48, 0x00, 0x00, 0x00, 0x00, 0x02))); + this.httprequest.desktop.state = 1; + } else { + this.httprequest.desktop.write(data); + } + } else if (this.httprequest.protocol == 5) { + // Process files commands + var cmd = null; + try { cmd = JSON.parse(data); } catch (e) { }; + if (cmd == null) { return; } + if ((cmd.ctrlChannel == '102938') || ((cmd.type == 'offer') && (cmd.sdp != null))) { onTunnelControlData(cmd, this); return; } // If this is control data, handle it now. + if (cmd.action == undefined) { return; } + //sendConsoleText('CMD: ' + JSON.stringify(cmd)); + + if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows + //console.log(objToString(cmd, 0, ' ')); + switch (cmd.action) { + case 'ls': { + /* + // Close the watcher if required + var samepath = ((this.httprequest.watcher != undefined) && (cmd.path == this.httprequest.watcher.path)); + if ((this.httprequest.watcher != undefined) && (samepath == false)) { + //console.log('Closing watcher: ' + this.httprequest.watcher.path); + //this.httprequest.watcher.close(); // TODO: This line causes the agent to crash!!!! + delete this.httprequest.watcher; + } + */ + + // Send the folder content to the browser + var response = getDirectoryInfo(cmd.path); + if (cmd.reqid != undefined) { response.reqid = cmd.reqid; } + this.write(new Buffer(JSON.stringify(response))); + + /* + // Start the directory watcher + if ((cmd.path != '') && (samepath == false)) { + var watcher = fs.watch(cmd.path, onFileWatcher); + watcher.tunnel = this.httprequest; + watcher.path = cmd.path; + this.httprequest.watcher = watcher; + //console.log('Starting watcher: ' + this.httprequest.watcher.path); + } + */ + break; + } + case 'mkdir': { + // Create a new empty folder + fs.mkdirSync(cmd.path); + break; + } + case 'rm': { + // Delete, possibly recursive delete + for (var i in cmd.delfiles) { + try { deleteFolderRecursive(obj.path.join(cmd.path, cmd.delfiles[i]), cmd.rec); } catch (e) { } + } + break; + } + case 'rename': { + // Rename a file or folder + var oldfullpath = obj.path.join(cmd.path, cmd.oldname); + var newfullpath = obj.path.join(cmd.path, cmd.newname); + try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); } + break; + } + case 'download': { + // Download a file + var sendNextBlock = 0; + if (cmd.sub == 'start') { // Setup the download + if (this.filedownload != null) { this.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; } + this.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 } + try { this.filedownload.f = fs.openSync(this.filedownload.path, 'rbN'); } catch (e) { this.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; } + if (this.filedownload) { this.write({ action: 'download', sub: 'start', id: cmd.id }); } + } else if ((this.filedownload != null) && (cmd.id == this.filedownload.id)) { // Download commands + if (cmd.sub == 'startack') { sendNextBlock = 8; } else if (cmd.sub == 'stop') { delete this.filedownload; } else if (cmd.sub == 'ack') { sendNextBlock = 1; } + } + // Send the next download block(s) + while (sendNextBlock > 0) { + sendNextBlock--; + var buf = new Buffer(4096); + var len = fs.readSync(this.filedownload.f, buf, 4, 4092, null); + this.filedownload.ptr += len; + if (len < 4092) { buf.writeInt32BE(0x01000001, 0); fs.closeSync(this.filedownload.f); delete this.filedownload; sendNextBlock = 0; } else { buf.writeInt32BE(0x01000000, 0); } + this.write(buf.slice(0, len + 4)); // Write as binary + } + break; + } + /* + case 'download': { + // Packet download of a file, agent to browser + if (cmd.path == undefined) break; + var filepath = cmd.name ? obj.path.join(cmd.path, cmd.name) : cmd.path; + //console.log('Download: ' + filepath); + try { this.httprequest.downloadFile = fs.openSync(filepath, 'rbN'); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'downloaderror', reqid: cmd.reqid }))); break; } + this.httprequest.downloadFileId = cmd.reqid; + this.httprequest.downloadFilePtr = 0; + if (this.httprequest.downloadFile) { this.write(new Buffer(JSON.stringify({ action: 'downloadstart', reqid: this.httprequest.downloadFileId }))); } + break; + } + case 'download2': { + // Stream download of a file, agent to browser + if (cmd.path == undefined) break; + var filepath = cmd.name ? obj.path.join(cmd.path, cmd.name) : cmd.path; + try { this.httprequest.downloadFile = fs.createReadStream(filepath, { flags: 'rbN' }); } catch (e) { console.log(e); } + this.httprequest.downloadFile.pipe(this); + this.httprequest.downloadFile.end = function () { } + break; + } + */ + case 'upload': { + // Upload a file, browser to agent + if (this.httprequest.uploadFile != undefined) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; } + if (cmd.path == undefined) break; + var filepath = cmd.name ? obj.path.join(cmd.path, cmd.name) : cmd.path; + try { this.httprequest.uploadFile = fs.openSync(filepath, 'wbN'); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'uploaderror', reqid: cmd.reqid }))); break; } + this.httprequest.uploadFileid = cmd.reqid; + if (this.httprequest.uploadFile) { this.write(new Buffer(JSON.stringify({ action: 'uploadstart', reqid: this.httprequest.uploadFileid }))); } + break; + } + case 'copy': { + // Copy a bunch of files from scpath to dspath + for (var i in cmd.names) { + var sc = obj.path.join(cmd.scpath, cmd.names[i]), ds = obj.path.join(cmd.dspath, cmd.names[i]); + if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } } + } + break; + } + case 'move': { + // Move a bunch of files from scpath to dspath + for (var i in cmd.names) { + var sc = obj.path.join(cmd.scpath, cmd.names[i]), ds = obj.path.join(cmd.dspath, cmd.names[i]); + if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } } + } + break; + } + default: + // Unknown action, ignore it. + break; + } + } + //sendConsoleText("Got tunnel #" + this.httprequest.index + " data: " + data, this.httprequest.sessionid); + } + } + + // Delete a directory with a files and directories within it + function deleteFolderRecursive(path, rec) { + if (fs.existsSync(path)) { + if (rec == true) { + fs.readdirSync(obj.path.join(path, '*')).forEach(function (file, index) { + var curPath = obj.path.join(path, file); + if (fs.statSync(curPath).isDirectory()) { // recurse + deleteFolderRecursive(curPath, true); + } else { // delete file + fs.unlinkSync(curPath); + } + }); + } + fs.unlinkSync(path); + } + }; + + // Called when receiving control data on WebRTC + function onTunnelWebRTCControlData(data) { + if (typeof data != 'string') return; + var obj; + try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON on WebRTC: ' + data); return; } + if (obj.type == 'close') { + //sendConsoleText('Tunnel #' + this.xrtc.websocket.tunnel.index + ' WebRTC control close'); + try { this.close(); } catch (e) { } + try { this.xrtc.close(); } catch (e) { } + } + } + + // Called when receiving control data on websocket + function onTunnelControlData(data, ws) { + var obj; + if (ws == null) { ws = this; } + if (typeof data == 'string') { try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON: ' + data); return; } } + else if (typeof data == 'object') { obj = data; } else { return; } + //sendConsoleText('onTunnelControlData(' + ws.httprequest.protocol + '): ' + JSON.stringify(data)); + //console.log('onTunnelControlData: ' + JSON.stringify(data)); + + if (obj.action) { + switch (obj.action) { + case 'lock': { + // Lock the current user out of the desktop + try { + if (process.platform == 'win32') { + var child = require('child_process'); + child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'RunDll32.exe user32.dll,LockWorkStation'], { type: 1 }); + } + } catch (e) { } + break; + } + default: + // Unknown action, ignore it. + break; + } + return; + } + + if (obj.type == 'close') { + // We received the close on the websocket + //sendConsoleText('Tunnel #' + ws.tunnel.index + ' WebSocket control close'); + try { ws.close(); } catch (e) { } + } else if (obj.type == 'webrtc0') { // Browser indicates we can start WebRTC switch-over. + if (ws.httprequest.protocol == 1) { // Terminal + // This is a terminal data stream, unpipe the terminal now and indicate to the other side that terminal data will no longer be received over WebSocket + if (process.platform == 'win32') + { + ws.httprequest._term.unpipe(ws); + } + else + { + ws.httprequest.process.stdout.unpipe(ws); + ws.httprequest.process.stderr.unpipe(ws); + } + } else if (ws.httprequest.protocol == 2) { // Desktop + // This is a KVM data stream, unpipe the KVM now and indicate to the other side that KVM data will no longer be received over WebSocket + ws.httprequest.desktop.kvm.unpipe(ws); + } else { + // Switch things around so all WebRTC data goes to onTunnelData(). + ws.rtcchannel.httprequest = ws.httprequest; + ws.rtcchannel.removeAllListeners('data'); + ws.rtcchannel.on('data', onTunnelData); + } + ws.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc1\"}"); // End of data marker + } else if (obj.type == 'webrtc1') { + if (ws.httprequest.protocol == 1) { // Terminal + // Switch the user input from websocket to webrtc at this point. + if (process.platform == 'win32') + { + ws.unpipe(ws.httprequest._term); + ws.rtcchannel.pipe(ws.httprequest._term, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. + } + else + { + ws.unpipe(ws.httprequest.process.stdin); + ws.rtcchannel.pipe(ws.httprequest.process.stdin, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. + } + ws.resume(); // Resume the websocket to keep receiving control data + } else if (ws.httprequest.protocol == 2) { // Desktop + // Switch the user input from websocket to webrtc at this point. + ws.unpipe(ws.httprequest.desktop.kvm); + try { ws.webrtc.rtcchannel.pipe(ws.httprequest.desktop.kvm, { dataTypeSkip: 1, end: false }); } catch (e) { sendConsoleText('EX2'); } // 0 = Binary, 1 = Text. + ws.resume(); // Resume the websocket to keep receiving control data + } + ws.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc2\"}"); // Indicates we will no longer get any data on websocket, switching to WebRTC at this point. + } else if (obj.type == 'webrtc2') { + // Other side received websocket end of data marker, start sending data on WebRTC channel + if (ws.httprequest.protocol == 1) { // Terminal + if (process.platform == 'win32') + { + ws.httprequest._term.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. + } + else + { + ws.httprequest.process.stdout.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. + ws.httprequest.process.stderr.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. + } + } else if (ws.httprequest.protocol == 2) { // Desktop + ws.httprequest.desktop.kvm.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. + } + } else if (obj.type == 'offer') { + // This is a WebRTC offer. + if (ws.httprequest.protocol == 1) return; // TODO: Terminal is currently broken with WebRTC. Reject WebRTC upgrade for now. + ws.webrtc = rtc.createConnection(); + ws.webrtc.websocket = ws; + ws.webrtc.on('connected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC connected');*/ }); + ws.webrtc.on('disconnected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC disconnected');*/ }); + ws.webrtc.on('dataChannel', function (rtcchannel) { + //sendConsoleText('WebRTC Datachannel open, protocol: ' + this.websocket.httprequest.protocol); + rtcchannel.xrtc = this; + rtcchannel.websocket = this.websocket; + this.rtcchannel = rtcchannel; + this.websocket.rtcchannel = rtcchannel; + this.websocket.rtcchannel.on('data', onTunnelWebRTCControlData); + this.websocket.rtcchannel.on('end', function () { + // The WebRTC channel closed, unpipe the KVM now. This is also done when the web socket closes. + //sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC data channel closed'); + if (this.websocket.desktop && this.websocket.desktop.kvm) { + this.unpipe(this.websocket.desktop.kvm); + this.websocket.httprequest.desktop.kvm.unpipe(this); + } + }); + this.websocket.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc0\"}"); // Indicate we are ready for WebRTC switch-over. + }); + var sdp = null; + try { sdp = ws.webrtc.setOffer(obj.sdp); } catch (ex) { } + if (sdp != null) { ws.write({ type: 'answer', ctrlChannel: '102938', sdp: sdp }); } + } + } + + // Console state + var consoleWebSockets = {}; + var consoleHttpRequest = null; + + // Console HTTP response + function consoleHttpResponse(response) { + response.data = function (data) { sendConsoleText(rstr2hex(buf2rstr(data)), this.sessionid); consoleHttpRequest = null; } + response.close = function () { sendConsoleText('httprequest.response.close', this.sessionid); consoleHttpRequest = null; } + }; + + // Open a web browser to a specified URL on current user's desktop + function openUserDesktopUrl(url) { + var child = null; + try { + switch (process.platform) { + case 'win32': + //child = require('child_process').execFile(process.env['windir'] + '\\system32\\cmd.exe', ["/c", "start", url], { type: childProcess.SpawnTypes.USER, uid: require('user-sessions').Current().Active[0].SessionId }); + child = require('child_process').execFile(process.env['windir'] + '\\system32\\cmd.exe', ["/c", "start", url], { type: childProcess.SpawnTypes.USER }); + break; + case 'linux': + child = require('child_process').execFile('/usr/bin/xdg-open', ['xdg-open', url], { uid: require('user-sessions').consoleUid() }); + break; + case 'darwin': + child = require('child_process').execFile('/usr/bin/open', ['open', url], { uid: require('user-sessions').consoleUid() }); + break; + default: + // Unknown platform, ignore this command. + break; + } + } catch (ex) { } + return child; + } + + // Process a mesh agent console command + function processConsoleCommand(cmd, args, rights, sessionid) { + try { + var response = null; + switch (cmd) { + case 'help': { // Displays available commands + response = 'Available commands: help, info, osinfo,args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock, users, sendcaps, openurl, amtreset, amtccm, amtacm, amtdeactivate,\r\namtpolicy, getscript, getclip, setclip.'; + break; + } + /* + case 'border': + { + if ((args['_'].length == 1) && (args['_'][0] == 'on')) { + if (meshCoreObj.users.length > 0) { + obj.borderManager.Start(meshCoreObj.users[0]); + response = 'Border blinking is on.'; + } else { + response = 'Cannot turn on border blinking, no logged in users.'; + } + } else if ((args['_'].length == 1) && (args['_'][0] == 'off')) { + obj.borderManager.Stop(); + response = 'Border blinking is off.'; + } else { + response = 'Proper usage: border "on|off"'; // Display correct command usage + } + } + break; + */ + case 'getclip': + if (require('MeshAgent').isService) { + require('clipboard').dispatchRead().then(function (str) { sendConsoleText(str, sessionid); }); + } else { + require("clipboard").read().then(function (str) { sendConsoleText(str, sessionid); }); + } + break; + case 'setclip': { + if (args['_'].length != 1) { + response = 'Proper usage: setclip "sample text"'; + } else { + if (require('MeshAgent').isService) { + require('clipboard').dispatchWrite(args['_'][0]); + response = 'Setting clipboard to: "' + args['_'][0] + '"'; + } + else { + require("clipboard")(args['_'][0]); response = 'Setting clipboard to: "' + args['_'][0] + '"'; + } + } + break; + } + case 'amtreset': { + if (amt != null) { amt.reset(); response = 'Done.'; } + break; + } + case 'amtlmsreset': { + if (amt != null) { amt.lmsreset(); response = 'Done.'; } + break; + } + case 'amtccm': { + if (amt == null) { response = 'Intel AMT not supported.'; } else { + if (args['_'].length != 1) { response = 'Proper usage: amtccm (adminPassword)'; } // Display usage + else { amt.setPolicy({ type: 0 }); amt.activeToCCM(args['_'][0]); } + } + break; + } + case 'amtacm': { + if (amt == null) { response = 'Intel AMT not supported.'; } else { + amt.setPolicy({ type: 0 }); + amt.getAmtInfo(function (meinfo) { amt.activeToACM(meinfo); }); + } + break; + } + case 'amtdeactivate': { + if (amt == null) { response = 'Intel AMT not supported.'; } else { amt.setPolicy({ type: 0 }); amt.deactivateCCM(); } + break; + } + case 'amtpolicy': { + if (amtPolicy == null) { + response = 'No Intel(R) AMT policy.'; + } else { + response = JSON.stringify(amtPolicy); + } + break; + } + case 'openurl': { + if (args['_'].length != 1) { response = 'Proper usage: openurl (url)'; } // Display usage + else { if (openUserDesktopUrl(args['_'][0]) == null) { response = 'Failed.'; } else { response = 'Success.'; } } + break; + } + case 'users': { + if (meshCoreObj.users == null) { response = 'Active users are unknown.'; } else { response = 'Active Users: ' + meshCoreObj.users.join(', ') + '.'; } + require('user-sessions').enumerateUsers().then(function (u) { for (var i in u) { sendConsoleText(u[i]); } }); + break; + } + case 'toast': { + if (args['_'].length < 1) { response = 'Proper usage: toast "message"'; } else + { + require('toaster').Toast('MeshCentral', args['_'][0]).then(sendConsoleText, sendConsoleText); + } + break; + } + case 'setdebug': { + if (args['_'].length < 1) { response = 'Proper usage: setdebug (target), 0 = Disabled, 1 = StdOut, 2 = This Console, * = All Consoles, 4 = WebLog, 8 = Logfile'; } // Display usage + else { if (args['_'][0] == '*') { console.setDestination(2); } else { console.setDestination(parseInt(args['_'][0]), sessionid); } } + break; + } + case 'ps': { + processManager.getProcesses(function (plist) { + var x = ''; + for (var i in plist) { x += i + ', ' + plist[i].cmd + ((plist[i].user) ? (', ' + plist[i].user):'') + '\r\n'; } + sendConsoleText(x, sessionid); + }); + break; + } + case 'kill': { + if ((args['_'].length < 1)) { + response = 'Proper usage: kill [pid]'; // Display correct command usage + } else { + process.kill(parseInt(args['_'][0])); + response = 'Killed process ' + args['_'][0] + '.'; + } + break; + } + case 'smbios': { + if (SMBiosTables == null) { response = 'SMBios tables not available.'; } else { response = objToString(SMBiosTables, 0, ' ', true); } + break; + } + case 'rawsmbios': { + if (SMBiosTablesRaw == null) { response = 'SMBios tables not available.'; } else { + response = ''; + for (var i in SMBiosTablesRaw) { + var header = false; + for (var j in SMBiosTablesRaw[i]) { + if (SMBiosTablesRaw[i][j].length > 0) { + if (header == false) { response += ('Table type #' + i + ((require('smbios').smTableTypes[i] == null) ? '' : (', ' + require('smbios').smTableTypes[i]))) + '\r\n'; header = true; } + response += (' ' + SMBiosTablesRaw[i][j].toString('hex')) + '\r\n'; + } + } + } + } + break; + } + case 'eval': { // Eval JavaScript + if (args['_'].length < 1) { + response = 'Proper usage: eval "JavaScript code"'; // Display correct command usage + } else { + response = JSON.stringify(mesh.eval(args['_'][0])); + } + break; + } + case 'notify': { // Send a notification message to the mesh + if (args['_'].length != 1) { + response = 'Proper usage: notify "message" [--session]'; // Display correct command usage + } else { + var notification = { "action": "msg", "type": "notify", "value": args['_'][0], "tag": "console" }; + if (args.session) { notification.sessionid = sessionid; } // If "--session" is specified, notify only this session, if not, the server will notify the mesh + mesh.SendCommand(notification); // no sessionid or userid specified, notification will go to the entire mesh + response = 'ok'; + } + break; + } + case 'info': { // Return information about the agent and agent core module + response = 'Current Core: ' + meshCoreObj.value + '.\r\nAgent Time: ' + Date() + '.\r\nUser Rights: 0x' + rights.toString(16) + '.\r\nPlatform: ' + process.platform + '.\r\nCapabilities: ' + meshCoreObj.caps + '.\r\nServer URL: ' + mesh.ServerUrl + '.'; + if (amt != null) { response += '\r\nBuilt-in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amt.lmsstate] + '.'; } + if (meshCoreObj.osdesc) { response += '\r\nOS: ' + meshCoreObj.osdesc + '.'; } + response += '\r\nModules: ' + addedModules.join(', ') + '.'; + response += '\r\nServer Connection: ' + mesh.isControlChannelConnected + ', State: ' + meshServerConnectionState + '.'; + response += '\r\lastMeInfo: ' + lastMeInfo + '.'; + var oldNodeId = db.Get('OldNodeId'); + if (oldNodeId != null) { response += '\r\nOldNodeID: ' + oldNodeId + '.'; } + if (process.platform != 'win32') { response += '\r\nX11 support: ' + require('monitor-info').kvm_x11_support + '.'; } + break; + } + case 'osinfo': { // Return the operating system information + var i = 1; + if (args['_'].length > 0) { i = parseInt(args['_'][0]); if (i > 8) { i = 8; } response = 'Calling ' + i + ' times.'; } + for (var j = 0; j < i; j++) { + var pr = require('os').name(); + pr.sessionid = sessionid; + pr.then(function (v) { sendConsoleText("OS: " + v, this.sessionid); }); + } + break; + } + case 'sendcaps': { // Send capability flags to the server + if (args['_'].length == 0) { + response = 'Proper usage: sendcaps (number)'; // Display correct command usage + } else { + meshCoreObj.caps = parseInt(args['_'][0]); + mesh.SendCommand(meshCoreObj); + response = JSON.stringify(meshCoreObj); + } + break; + } + case 'sendosdesc': { // Send OS description + if (args['_'].length > 0) { + meshCoreObj.osdesc = args['_'][0]; + mesh.SendCommand(meshCoreObj); + response = JSON.stringify(meshCoreObj); + } else { + response = 'Proper usage: sendosdesc [os description]'; // Display correct command usage + } + break; + } + case 'args': { // Displays parsed command arguments + response = 'args ' + objToString(args, 0, ' ', true); + break; + } + case 'print': { // Print a message on the mesh agent console, does nothing when running in the background + var r = []; + for (var i in args['_']) { r.push(args['_'][i]); } + console.log(r.join(' ')); + response = 'Message printed on agent console.'; + break; + } + case 'type': { // Returns the content of a file + if (args['_'].length == 0) { + response = 'Proper usage: type (filepath) [maxlength]'; // Display correct command usage + } else { + var max = 4096; + if ((args['_'].length > 1) && (typeof args['_'][1] == 'number')) { max = args['_'][1]; } + if (max > 4096) max = 4096; + var buf = Buffer.alloc(max), fd = fs.openSync(args['_'][0], "r"), r = fs.readSync(fd, buf, 0, max); // Read the file content + response = buf.toString(); + var i = response.indexOf('\n'); + if ((i > 0) && (response[i - 1] != '\r')) { response = response.split('\n').join('\r\n'); } + if (r == max) response += '...'; + fs.closeSync(fd); + } + break; + } + case 'dbkeys': { // Return all data store keys + response = JSON.stringify(db.Keys); + break; + } + case 'dbget': { // Return the data store value for a given key + if (db == null) { response = 'Database not accessible.'; break; } + if (args['_'].length != 1) { + response = 'Proper usage: dbget (key)'; // Display the value for a given database key + } else { + response = db.Get(args['_'][0]); + } + break; + } + case 'dbset': { // Set a data store key and value pair + if (db == null) { response = 'Database not accessible.'; break; } + if (args['_'].length != 2) { + response = 'Proper usage: dbset (key) (value)'; // Set a database key + } else { + var r = db.Put(args['_'][0], args['_'][1]); + response = 'Key set: ' + r; + } + break; + } + case 'dbcompact': { // Compact the data store + if (db == null) { response = 'Database not accessible.'; break; } + var r = db.Compact(); + response = 'Database compacted: ' + r; + break; + } + case 'httpget': { + if (consoleHttpRequest != null) { + response = 'HTTP operation already in progress.'; + } else { + if (args['_'].length != 1) { + response = 'Proper usage: httpget (url)'; + } else { + var options = http.parseUri(args['_'][0]); + options.method = 'GET'; + if (options == null) { + response = 'Invalid url.'; + } else { + try { consoleHttpRequest = http.request(options, consoleHttpResponse); } catch (e) { response = 'Invalid HTTP GET request'; } + consoleHttpRequest.sessionid = sessionid; + if (consoleHttpRequest != null) { + consoleHttpRequest.end(); + response = 'HTTPGET ' + options.protocol + '//' + options.host + ':' + options.port + options.path; + } + } + } + } + break; + } + case 'wslist': { // List all web sockets + response = ''; + for (var i in consoleWebSockets) { + var httprequest = consoleWebSockets[i]; + response += 'Websocket #' + i + ', ' + httprequest.url + '\r\n'; + } + if (response == '') { response = 'no websocket sessions.'; } + break; + } + case 'wsconnect': { // Setup a web socket + if (args['_'].length == 0) { + response = 'Proper usage: wsconnect (url)\r\nFor example: wsconnect wss://localhost:443/meshrelay.ashx?id=abc'; // Display correct command usage + } else { + var httprequest = null; + try { + var options = http.parseUri(args['_'][0]); + options.rejectUnauthorized = 0; + httprequest = http.request(options); + } catch (e) { response = 'Invalid HTTP websocket request'; } + if (httprequest != null) { + httprequest.upgrade = onWebSocketUpgrade; + httprequest.on('error', function (e) { sendConsoleText('ERROR: ' + JSON.stringify(e)); }); + + var index = 1; + while (consoleWebSockets[index]) { index++; } + httprequest.sessionid = sessionid; + httprequest.index = index; + httprequest.url = args['_'][0]; + consoleWebSockets[index] = httprequest; + response = 'New websocket session #' + index; + } + } + break; + } + case 'wssend': { // Send data on a web socket + if (args['_'].length == 0) { + response = 'Proper usage: wssend (socketnumber)\r\n'; // Display correct command usage + for (var i in consoleWebSockets) { + var httprequest = consoleWebSockets[i]; + response += 'Websocket #' + i + ', ' + httprequest.url + '\r\n'; + } + } else { + var i = parseInt(args['_'][0]); + var httprequest = consoleWebSockets[i]; + if (httprequest != undefined) { + httprequest.s.write(args['_'][1]); + response = 'ok'; + } else { + response = 'Invalid web socket number'; + } + } + break; + } + case 'wsclose': { // Close a websocket + if (args['_'].length == 0) { + response = 'Proper usage: wsclose (socketnumber)'; // Display correct command usage + } else { + var i = parseInt(args['_'][0]); + var httprequest = consoleWebSockets[i]; + if (httprequest != undefined) { + if (httprequest.s != null) { httprequest.s.end(); } else { httprequest.end(); } + response = 'ok'; + } else { + response = 'Invalid web socket number'; + } + } + break; + } + case 'tunnels': { // Show the list of current tunnels + response = ''; + for (var i in tunnels) { response += 'Tunnel #' + i + ', ' + tunnels[i].url + '\r\n'; } + if (response == '') { response = 'No websocket sessions.'; } + break; + } + case 'ls': { // Show list of files and folders + response = ''; + var xpath = '*'; + if (args['_'].length > 0) { xpath = obj.path.join(args['_'][0], '*'); } + response = 'List of ' + xpath + '\r\n'; + var results = fs.readdirSync(xpath); + for (var i = 0; i < results.length; ++i) { + var stat = null, p = obj.path.join(args['_'][0], results[i]); + try { stat = fs.statSync(p); } catch (e) { } + if ((stat == null) || (stat == undefined)) { + response += (results[i] + "\r\n"); + } else { + response += (results[i] + " " + ((stat.isDirectory()) ? "(Folder)" : "(File)") + "\r\n"); + } + } + break; + } + case 'lsx': { // Show list of files and folders + response = objToString(getDirectoryInfo(args['_'][0]), 0, ' ', true); + break; + } + case 'lock': { // Lock the current user out of the desktop + if (process.platform == 'win32') { var child = require('child_process'); child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'RunDll32.exe user32.dll,LockWorkStation'], { type: 1 }); response = 'Ok'; } + else { response = 'Not supported on the platform'; } + break; + } + case 'amt': { // Show Intel AMT status + if (amt != null) { + amt.getAmtInfo(function (state) { + var resp = 'Intel AMT not detected.'; + if (state != null) { resp = objToString(state, 0, ' ', true); } + sendConsoleText(resp, sessionid); + }); + } else { + response = 'Intel AMT not detected.'; + } + break; + } + case 'netinfo': { // Show network interface information + //response = objToString(mesh.NetInfo, 0, ' '); + var interfaces = require('os').networkInterfaces(); + response = objToString(interfaces, 0, ' ', true); + break; + } + case 'netinfo2': { // Show network interface information + response = objToString(mesh.NetInfo, 0, ' ', true); + break; + } + case 'wakeonlan': { // Send wake-on-lan + if ((args['_'].length != 1) || (args['_'][0].length != 12)) { + response = 'Proper usage: wakeonlan [mac], for example "wakeonlan 010203040506".'; + } else { + var count = sendWakeOnLan(args['_'][0]); + response = 'Sent wake-on-lan on ' + count + ' interface(s).'; + } + break; + } + case 'sendall': { // Send a message to all consoles on this mesh + sendConsoleText(args['_'].join(' ')); + break; + } + case 'power': { // Execute a power action on this computer + if (mesh.ExecPowerState == undefined) { + response = 'Power command not supported on this agent.'; + } else { + if ((args['_'].length == 0) || (typeof args['_'][0] != 'number')) { + response = 'Proper usage: power (actionNumber), where actionNumber is:\r\n LOGOFF = 1\r\n SHUTDOWN = 2\r\n REBOOT = 3\r\n SLEEP = 4\r\n HIBERNATE = 5\r\n DISPLAYON = 6\r\n KEEPAWAKE = 7\r\n BEEP = 8\r\n CTRLALTDEL = 9\r\n VIBRATE = 13\r\n FLASH = 14'; // Display correct command usage + } else { + var r = mesh.ExecPowerState(args['_'][0], args['_'][1]); + response = 'Power action executed with return code: ' + r + '.'; + } + } + break; + } + case 'location': { + getIpLocationData(function (location) { + sendConsoleText(objToString({ "action": "iplocation", "type": "publicip", "value": location }, 0, ' ')); + }); + break; + } + case 'parseuri': { + response = JSON.stringify(http.parseUri(args['_'][0])); + break; + } + case 'scanwifi': { + if (wifiScanner != null) { + var wifiPresent = wifiScanner.hasWireless; + if (wifiPresent) { response = "Perfoming Wifi scan..."; wifiScanner.Scan(); } else { response = "Wifi absent."; } + } else { response = "Wifi module not present."; } + break; + } + case 'scanamt': { + if (amtscanner != null) { + if (args['_'].length != 1) { + response = 'Usage examples:\r\n scanamt 1.2.3.4\r\n scanamt 1.2.3.0-1.2.3.255\r\n scanamt 1.2.3.0/24\r\n'; // Display correct command usage + } else { + response = 'Scanning: ' + args['_'][0] + '...'; + amtscanner.scan(args['_'][0], 2000, function (data) { + if (data.length > 0) { + var r = '', pstates = ['NotActivated', 'InActivation', 'Activated']; + for (var i in data) { + var x = data[i]; + if (r != '') { r += '\r\n'; } + r += x.address + ' - Intel AMT v' + x.majorVersion + '.' + x.minorVersion; + if (x.provisioningState < 3) { r += (', ' + pstates[x.provisioningState]); } + if (x.provisioningState == 2) { r += (', ' + x.openPorts.join(', ')); } + r += '.'; + } + } else { + r = 'No Intel AMT found.'; + } + sendConsoleText(r); + }); + } + } else { response = "Intel AMT scanner module not present."; } + break; + } + case 'modules': { + response = JSON.stringify(addedModules); + break; + } + case 'getscript': { + if (args['_'].length != 1) { + response = 'Proper usage: getscript [scriptNumber].'; + } else { + mesh.SendCommand({ "action": "getScript", "type": args['_'][0] }); + } + break; + } + case 'diagnostic': + { + if (!mesh.DAIPC.listening) + { + response = 'Unable to bind to Diagnostic IPC, most likely because the path (' + process.cwd() + ') is not on a local file system'; + break; + } + var diag = diagnosticAgent_installCheck(); + if (diag) + { + if (args['_'].length == 1 && args['_'][0] == 'uninstall') + { + diagnosticAgent_uninstall(); + response = 'Diagnostic Agent uninstalled'; + } + else + { + response = 'Diagnostic Agent installed at: ' + diag.appLocation(); + } + } + else + { + if (args['_'].length == 1 && args['_'][0] == 'install') + { + diag = diagnosticAgent_installCheck(true); + if (diag) + { + response = 'Diagnostic agent was installed at: ' + diag.appLocation(); + } + else + { + response = 'Diagnostic agent installation failed'; + } + } + else + { + response = 'Diagnostic Agent Not installed. To install: diagnostic install'; + } + } + if (diag) { diag.close(); diag = null; } + break; + } + default: { // This is an unknown command, return an error message + response = 'Unknown command \"' + cmd + '\", type \"help\" for list of avaialble commands.'; + break; + } + } + } catch (e) { response = 'Command returned an exception error: ' + e; console.log(e); } + if (response != null) { sendConsoleText(response, sessionid); } + } + + // Send a mesh agent console command + function sendConsoleText(text, sessionid) { + if (typeof text == 'object') { text = JSON.stringify(text); } + mesh.SendCommand({ "action": "msg", "type": "console", "value": text, "sessionid": sessionid }); + } + + // Called before the process exits + //process.exit = function (code) { console.log("Exit with code: " + code.toString()); } + + // Called when the server connection state changes + function handleServerConnection(state) { + meshServerConnectionState = state; + if (meshServerConnectionState == 0) { + // Server disconnected + if (selfInfoUpdateTimer != null) { clearInterval(selfInfoUpdateTimer); selfInfoUpdateTimer = null; } + lastSelfInfo = null; + } else { + // Server connected, send mesh core information + var oldNodeId = db.Get('OldNodeId'); + if (oldNodeId != null) { mesh.SendCommand({ action: 'mc1migration', oldnodeid: oldNodeId }); } + + // Update the server with basic info, logged in users and more. + mesh.SendCommand(meshCoreObj); + + // Send SMBios tables if present + if (SMBiosTablesRaw != null) { mesh.SendCommand({ "action": "smbios", "value": SMBiosTablesRaw }); } + + // Update the server on more advanced stuff, like Intel ME and Network Settings + meInfoStr = null; + sendPeriodicServerUpdate(); + //if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); } // 20 minutes + } + } + + // Update the server with the latest network interface information + var sendNetworkUpdateNagleTimer = null; + function sendNetworkUpdateNagle() { if (sendNetworkUpdateNagleTimer != null) { clearTimeout(sendNetworkUpdateNagleTimer); sendNetworkUpdateNagleTimer = null; } sendNetworkUpdateNagleTimer = setTimeout(sendNetworkUpdate, 5000); } + function sendNetworkUpdate(force) { + sendNetworkUpdateNagleTimer = null; + + // Update the network interfaces information data + var netInfo = mesh.NetInfo; + if (netInfo) { + netInfo.action = 'netinfo'; + var netInfoStr = JSON.stringify(netInfo); + if ((force == true) || (clearGatewayMac(netInfoStr) != clearGatewayMac(lastNetworkInfo))) { mesh.SendCommand(netInfo); lastNetworkInfo = netInfoStr; } + } + } + + // Called periodically to check if we need to send updates to the server + function sendPeriodicServerUpdate(flags) { + if (meshServerConnectionState == 0) return; // Not connected to server, do nothing. + if (!flags) { flags = 0xFFFFFFFF; } + + if ((flags & 1) && (amt != null)) { + // If we have a connected MEI, get Intel ME information + amt.getAmtInfo(function (meinfo) { + try { + if (meinfo == null) return; + var intelamt = {}, p = false; + if ((meinfo.Versions != null) && (meinfo.Versions.AMT != null)) { intelamt.ver = meinfo.Versions.AMT; p = true; } + if (meinfo.ProvisioningState != null) { intelamt.state = meinfo.ProvisioningState; p = true; } + if (meinfo.Flags != null) { intelamt.flags = meinfo.Flags; p = true; } + if (meinfo.OsHostname != null) { intelamt.host = meinfo.OsHostname; p = true; } + if (meinfo.UUID != null) { intelamt.uuid = meinfo.UUID; p = true; } + if ((meinfo.ProvisioningState == 0) && (meinfo.net0 != null) && (meinfo.net0.enabled == 1)) { // If not activated, look to see if we have wired net working. + // Not activated and we have wired ethernet, look for the trusted DNS + var dns = meinfo.DNS; + if (dns == null) { + // Trusted DNS not set, let's look for the OS network DNS suffix + var interfaces = require('os').networkInterfaces(); + for (var i in interfaces) { + for (var j in interfaces[i]) { + if ((interfaces[i][j].mac == mestate.net0.mac) && (interfaces[i][j].fqdn != null) && (interfaces[i][j].fqdn != '')) { dns = interfaces[i][j].fqdn; } + } + } + } + if (intelamt.dns != dns) { intelamt.dns = dns; p = true; } + } else { if (intelamt.dns != null) { delete intelamt.dns; p = true; } } + if (p == true) { + var meInfoStr = JSON.stringify(intelamt); + if (meInfoStr != lastMeInfo) { + meshCoreObj.intelamt = intelamt; + mesh.SendCommand(meshCoreObj); + lastMeInfo = meInfoStr; + } + } + } catch (ex) { } + }); + } + + if (flags & 2) { + // Update network information + sendNetworkUpdateNagle(false); + } + } + + + // Starting function + obj.start = function () { + // Setup the mesh agent event handlers + mesh.AddCommandHandler(handleServerCommand); + mesh.AddConnectHandler(handleServerConnection); + + // Parse input arguments + //var args = parseArgs(process.argv); + //console.log(args); + + //resetMicroLms(); + + // Setup logged in user monitoring (THIS IS BROKEN IN WIN7) + try { + var userSession = require('user-sessions'); + userSession.on('changed', function onUserSessionChanged() { + userSession.enumerateUsers().then(function (users) { + var u = [], a = users.Active; + for (var i = 0; i < a.length; i++) { + var un = a[i].Domain ? (a[i].Domain + '\\' + a[i].Username) : (a[i].Username); + if (u.indexOf(un) == -1) { u.push(un); } // Only push users in the list once. + } + meshCoreObj.users = u; + mesh.SendCommand(meshCoreObj); + }); + }); + userSession.emit('changed'); + //userSession.on('locked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has LOCKED the desktop'); }); + //userSession.on('unlocked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has UNLOCKED the desktop'); }); + } catch (ex) { } + } + + obj.stop = function () { + mesh.AddCommandHandler(null); + mesh.AddConnectHandler(null); + } + + function onWebSocketClosed() { sendConsoleText("WebSocket #" + this.httprequest.index + " closed.", this.httprequest.sessionid); delete consoleWebSockets[this.httprequest.index]; } + function onWebSocketData(data) { sendConsoleText("Got WebSocket #" + this.httprequest.index + " data: " + data, this.httprequest.sessionid); } + function onWebSocketSendOk() { sendConsoleText("WebSocket #" + this.index + " SendOK.", this.sessionid); } + + function onWebSocketUpgrade(response, s, head) { + sendConsoleText("WebSocket #" + this.index + " connected.", this.sessionid); + this.s = s; + s.httprequest = this; + s.end = onWebSocketClosed; + s.data = onWebSocketData; + } + + return obj; +} + +// +// Module startup +// + +try { + var xexports = null, mainMeshCore = null; + try { xexports = module.exports; } catch (e) { } + + if (xexports != null) { + // If we are running within NodeJS, export the core + module.exports.createMeshCore = createMeshCore; + } else { + // If we are not running in NodeJS, launch the core + mainMeshCore = createMeshCore(); + mainMeshCore.start(null); + } +} catch (ex) { + require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": "uncaughtException2: " + ex }); +} \ No newline at end of file diff --git a/agents/modules_meshcmd_min/amt-ider.min.js b/agents/modules_meshcmd_min/amt-ider.min.js new file mode 100644 index 00000000..fe99b6e2 --- /dev/null +++ b/agents/modules_meshcmd_min/amt-ider.min.js @@ -0,0 +1 @@ +module.exports=function CreateAmtRemoteIder(){var B={};B.protocol=3;B.bytesToAmt=0;B.bytesFromAmt=0;B.rx_timeout=30000;B.tx_timeout=0;B.heartbeat=20000;B.version=1;B.acc=null;B.inSequence=0;B.outSequence=0;B.iderinfo=null;B.enabled=false;B.iderStart=0;B.floppy=null;B.cdrom=null;B.floppyReady=false;B.cdromReady=false;B.sectorStats=null;B.debug=false;var z=new Buffer([0,38,49,128,0,0,0,0,5,30,16,169,8,32,2,0,3,195,0,0,0,0,0,0,0,0,0,0,40,0,0,0,0,0,0,0,2,208,0,0]);var s=new Buffer([0,92,36,128,0,0,0,0,1,10,0,1,0,0,0,0,2,0,0,0,3,22,0,160,0,0,0,0,0,18,2,0,0,0,0,0,0,0,160,0,0,0,5,30,16,169,8,32,2,0,3,195,0,0,0,0,0,0,0,0,0,0,40,0,0,0,0,0,0,0,2,208,0,0,8,10,0,0,0,0,0,0,0,0,0,0,11,6,0,0,0,17,36,49]);var x=new Buffer([0,38,36,128,0,0,0,0,5,30,4,176,2,18,2,0,0,80,0,0,0,0,0,0,0,0,0,0,40,0,0,0,0,0,0,0,2,208,0,0]);var r=new Buffer([0,92,36,128,0,0,0,0,1,10,0,1,0,0,0,0,2,0,0,0,3,22,0,160,0,0,0,0,0,18,2,0,0,0,0,0,0,0,160,0,0,0,5,30,4,176,2,18,2,0,0,80,0,0,0,0,0,0,0,0,0,0,40,0,0,0,0,0,0,0,2,208,0,0,8,10,0,0,0,0,0,0,0,0,0,0,11,6,0,0,0,17,36,49]);var t=new Buffer([0,18,1,128,0,0,0,0,26,10,0,0,0,0,0,0,0,0,0,0]);var u=new Buffer([0,18,1,128,0,0,0,0,29,10,0,0,0,0,0,0,0,0,0,0]);var v=new Buffer([0,32,1,128,0,0,0,0,42,24,0,0,0,0,32,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0]);var q=new Buffer([0,40,1,128,0,0,0,0,1,6,0,255,0,0,0,0,42,24,0,0,0,0,2,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0]);var i=new Buffer([0,0,0,40,0,0,0,8]);var j=new Buffer([0,0,3,4,0,8,1,0]);var h=new Buffer([0,1,3,4,0,0,0,2]);var m=new Buffer([0,2,3,4,0,0,0,0]);var l=new Buffer([0,3,3,4,41,0,0,2]);var k=new Buffer([0,16,1,8,0,0,8,0,0,1,0,0]);var o=new Buffer([0,30,3,0]);var n=new Buffer([1,0,3,0]);var p=new Buffer([1,5,3,0]);var y=new Buffer([0,18,36,128,0,0,0,0,1,10,0,1,0,0,0,0,2,0,0,0]);var A=new Buffer([0,18,49,128,0,0,0,0,1,10,0,1,0,0,0,0,2,0,0,0]);var w=new Buffer([0,14,1,128,0,0,0,0,1,6,0,255,0,0,0,0]);B.xxStateChange=function(E){if(B.debug){console.log("IDER-StateChange",E)}if(E==0){B.Stop()}if(E==3){B.Start()}};B.Start=function(){if(B.debug){console.log("IDER-Start");console.log(B.floppy,B.cdrom)}B.bytesToAmt=0;B.bytesFromAmt=0;B.inSequence=0;B.outSequence=0;e=[];B.SendCommand(64,Buffer.concat([ShortToStrX(B.rx_timeout),ShortToStrX(B.tx_timeout),ShortToStrX(B.heartbeat),IntToStrX(B.version)]));if(B.sectorStats){B.sectorStats(0,0,B.floppy?(B.floppy.size>>9):0);B.sectorStats(0,1,B.cdrom?(B.cdrom.size>>11):0)}};B.Stop=function(){if(B.debug){console.log("IDER-Stop")}B.parent.Stop()};B.ProcessData=function(E){B.bytesFromAmt+=E.length;if(B.acc==null){B.acc=E}else{B.acc=Buffer.concat(B.acc,E)}if(B.debug){console.log("IDER-ProcessData",B.acc.length,B.acc.toString("hex"))}while(B.acc!=null){var F=B.ProcessDataEx();if(F==0){return}if(B.inSequence!=ReadIntX(B.acc,4)){if(B.debug){console.log("ERROR: Out of sequence",B.inSequence,ReadIntX(B.acc,4))}B.Stop();return}B.inSequence++;if(F==B.acc.length){B.acc=null}else{B.acc=B.acc.slice(F)}}};B.SendCommand=function(F,H,G,I){if(H==null){H=new Buffer(0)}var E=((F>50)&&(G==true))?2:0;if(I){E+=1}var J=Buffer.concat([Buffer([F,0,0,E]),IntToStrX(B.outSequence++),H]);B.parent.xxSend(J);B.bytesToAmt+=J.length};B.SendCommandEndResponse=function(H,I,G,E,F){if(H){B.SendCommand(81,new Buffer([0,0,0,0,0,0,0,0,0,0,0,0,197,0,3,0,0,0,G,80,0,0,0]),true)}else{B.SendCommand(81,new Buffer([0,0,0,0,0,0,0,0,0,0,0,0,135,(I<<4),3,0,0,0,G,81,I,E,F]),true)}};B.SendDataToHost=function(G,E,F,H){var I=(H)?0:F.length;if(E==true){B.SendCommand(84,Buffer.concat([new Buffer([0,(F.length&255),(F.length>>8),0,H?180:181,0,2,0,(I&255),(I>>8),G,88,133,0,3,0,0,0,G,80,0,0,0,0,0,0]),F]),E,H)}else{B.SendCommand(84,Buffer.concat([new Buffer([0,(F.length&255),(F.length>>8),0,H?180:181,0,2,0,(I&255),(I>>8),G,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),F]),E,H)}};B.SendGetDataFromHost=function(F,E){B.SendCommand(82,new Buffer([0,(E&255),(E>>8),0,181,0,0,0,(E&255),(E>>8),F,88,0,0,0,0,0,0,0,0,0,0,0]),false)};B.SendDisableEnableFeatures=function(F,E){if(E==null){E=""}B.SendCommand(72,Buffer.concat([new Buffer([F]),E]))};B.ProcessDataEx=function(){if(B.acc.length<8){return 0}switch(B.acc[0]){case 65:if(B.acc.length<30){return 0}var I=B.acc[29];if(B.acc.length<(30+I)){return 0}B.iderinfo={};B.iderinfo.major=B.acc[8];B.iderinfo.minor=B.acc[9];B.iderinfo.fwmajor=B.acc[10];B.iderinfo.fwminor=B.acc[11];B.iderinfo.readbfr=ReadShortX(B.acc,16);B.iderinfo.writebfr=ReadShortX(B.acc,18);B.iderinfo.proto=B.acc[21];B.iderinfo.iana=ReadIntX(B.acc,25);if(B.debug){console.log(B.iderinfo)}if(B.iderinfo.proto!=0){if(B.debug){console.log("Unknown proto",B.iderinfo.proto)}B.Stop()}if(B.iderinfo.readbfr>8192){if(B.debug){console.log("Illegal read buffer size",B.iderinfo.readbfr)}B.Stop()}if(B.iderinfo.writebfr>8192){if(B.debug){console.log("Illegal write buffer size",B.iderinfo.writebfr)}B.Stop()}if(B.iderStart==0){B.SendDisableEnableFeatures(3,IntToStrX(1+8))}else{if(B.iderStart==1){B.SendDisableEnableFeatures(3,IntToStrX(1+16))}else{if(B.iderStart==2){B.SendDisableEnableFeatures(3,IntToStrX(1+24))}}}return 30+I;case 67:if(B.debug){console.log("CLOSE")}B.Stop();return 8;case 68:B.SendCommand(69);return 8;case 69:if(B.debug){console.log("PONG")}return 8;case 70:if(B.acc.length<9){return 0}var J=B.acc[8];if(d===null){B.SendCommand(71);if(B.debug){console.log("RESETOCCURED1",J)}}else{f=true;if(B.debug){console.log("RESETOCCURED2",J)}}return 9;case 73:if(B.acc.length<13){return 0}var K=B.acc[8];var L=ReadIntX(B.acc,9);if(B.debug){console.log("STATUS_DATA",K,L)}switch(K){case 1:if(L&1){if(B.iderStart==0){B.SendDisableEnableFeatures(3,IntToStrX(1+8))}else{if(B.iderStart==1){B.SendDisableEnableFeatures(3,IntToStrX(1+16))}else{if(B.iderStart==2){B.SendDisableEnableFeatures(3,IntToStrX(1+24))}}}}break;case 2:B.enabled=(L&2)?true:false;if(B.debug){console.log("IDER Status: "+B.enabled)}break;case 3:if(L!=1){if(B.debug){console.log("Register toggle failure")}}break}return 13;case 74:if(B.acc.length<11){return 0}if(B.debug){console.log("IDER: ABORT",B.acc[8])}return 11;case 75:return 8;case 80:if(B.acc.length<28){return 0}var F=(B.acc[14]&16)?176:160;var G=B.acc[14];var E=B.acc.slice(16,28);var H=B.acc[9];if(B.debug){console.log("SCSI_CMD",F,E.toString("hex"),H,G)}g(F,E,H,G);return 28;case 83:if(B.acc.length<14){return 0}var I=ReadShortX(B.acc,9);if(B.acc.length<(14+I)){return 0}if(B.debug){console.log("SCSI_WRITE, len = "+(14+I))}B.SendCommand(81,new Buffer([0,0,0,0,0,0,0,0,0,0,0,0,135,112,3,0,0,0,160,81,7,39,0]),true);return 14+I;default:if(B.debug){console.log("Unknown IDER command",B.acc[0])}B.Stop();break}return 0};function g(I,H,K,J){var N;var O;switch(H[0]){case 0:if(B.debug){console.log("SCSI: TEST_UNIT_READY",I)}switch(I){case 160:if(B.floppy==null){B.SendCommandEndResponse(1,2,I,58,0);return -1}if(B.floppyReady==false){B.floppyReady=true;B.SendCommandEndResponse(1,6,I,40,0);return -1}break;case 176:if(B.cdrom==null){B.SendCommandEndResponse(1,2,I,58,0);return -1}if(B.cdromReady==false){B.cdromReady=true;B.SendCommandEndResponse(1,6,I,40,0);return -1}break;default:if(B.debug){console.log("SCSI Internal error 3",I)}return -1}B.SendCommandEndResponse(1,0,I,0,0);break;case 8:N=((H[1]&31)<<16)+(H[2]<<8)+H[3];O=H[4];if(O==0){O=256}if(B.debug){console.log("SCSI: READ_6",I,N,O)}C(I,N,O,K);break;case 10:N=((H[1]&31)<<16)+(H[2]<<8)+H[3];O=H[4];if(O==0){O=256}if(B.debug){console.log("SCSI: WRITE_6",I,N,O)}B.SendCommandEndResponse(1,2,I,58,0);return -1;case 26:if(B.debug){console.log("SCSI: MODE_SENSE_6",I)}if((H[2]==63)&&(H[3]==0)){var E=0,F=0;switch(I){case 160:if(B.floppy==null){B.SendCommandEndResponse(1,2,I,58,0);return -1}E=0;F=128;break;case 176:if(B.cdrom==null){B.SendCommandEndResponse(1,2,I,58,0);return -1}E=5;F=128;break;default:if(B.debug){console.log("SCSI Internal error 6",I)}return -1}B.SendDataToHost(I,true,new Buffer([0,E,F,0]),K&1);return}B.SendCommandEndResponse(1,5,I,36,0);break;case 27:B.SendCommandEndResponse(1,0,I);break;case 30:if(B.debug){console.log("SCSI: ALLOW_MEDIUM_REMOVAL",I)}if((I==160)&&(B.floppy==null)){B.SendCommandEndResponse(1,2,I,58,0);return -1}if((I==176)&&(B.cdrom==null)){B.SendCommandEndResponse(1,2,I,58,0);return -1}B.SendCommandEndResponse(1,0,I,0,0);break;case 35:if(B.debug){console.log("SCSI: READ_FORMAT_CAPACITIES",I)}var G=ReadShort(H,7);var Q=0,V;var P=G/8;switch(I){case 160:if((B.floppy==null)||(B.floppy.size==0)){B.SendCommandEndResponse(0,5,I,36,0);return -1}V=(B.floppy.size>>9)-1;break;case 176:if((B.cdrom==null)||(B.cdrom.size==0)){B.SendCommandEndResponse(0,5,I,36,0);return -1}V=(B.cdrom.size>>11)-1;break;default:if(B.debug){console.log("SCSI Internal error 4",I)}return -1}B.SendDataToHost(I,true,Buffer.concat([IntToStr(8),new Buffer([0,0,11,64,2,0,2,0])]),K&1);break;case 37:if(B.debug){console.log("SCSI: READ_CAPACITY",I)}var O=0;switch(I){case 160:if((B.floppy==null)||(B.floppy.size==0)){B.SendCommandEndResponse(0,2,I,58,0);return -1}if(B.floppy!=null){O=(B.floppy.size>>9)-1}if(B.debug){console.log("DEV_FLOPPY",O)}break;case 176:if((B.cdrom==null)||(B.cdrom.size==0)){B.SendCommandEndResponse(0,2,I,58,0);return -1}if(B.cdrom!=null){O=(B.cdrom.size>>11)-1}if(B.debug){console.log("DEV_CDDVD",O)}break;default:if(B.debug){console.log("SCSI Internal error 4",I)}return -1}if(B.debug){console.log("SCSI: READ_CAPACITY2",I,J)}B.SendDataToHost(J,true,Buffer.concat([IntToStr(O),new Buffer([0,0,((I==176)?8:2),0])]),K&1);break;case 40:N=ReadInt(H,2);O=ReadShort(H,7);if(B.debug){console.log("SCSI: READ_10",I,N,O)}C(I,N,O,K);break;case 42:case 46:N=ReadInt(H,2);O=ReadShort(H,7);if(B.debug){console.log("SCSI: WRITE_10",I,N,O)}B.SendGetDataFromHost(I,512*O);break;case 67:var G=ReadShort(H,7);var R=H[1]&2;var M=H[2]&7;if(M==0){M=H[9]>>6}if(B.debug){console.log("SCSI: READ_TOC, dev="+I+", buflen="+G+", msf="+R+", format="+M)}switch(I){case 160:B.SendCommandEndResponse(1,5,I,32,0);return -1;case 176:break;default:if(B.debug){console.log("SCSI Internal error 9",I)}return -1}if(M==1){B.SendDataToHost(I,true,new Buffer([0,10,1,1,0,20,1,0,0,0,0,0]),K&1)}else{if(M==0){if(R){B.SendDataToHost(I,true,new Buffer([0,18,1,1,0,20,1,0,0,0,2,0,0,20,170,0,0,0,52,19]),K&1)}else{B.SendDataToHost(I,true,new Buffer([0,18,1,1,0,20,1,0,0,0,0,0,0,20,170,0,0,0,0,0]),K&1)}}}break;case 70:var W=(H[1]!=2);var L=ReadShort(H,2);var G=ReadShort(H,7);if(B.debug){console.log("SCSI: GET_CONFIGURATION",I,W,L,G)}if(G==0){B.SendDataToHost(I,true,Buffer.concat([IntToStr(60),IntToStr(8)]),K&1);return -1}var T=null;if(L==0){T=j}if((L==1)||(W&&(L<1))){T=h}if((L==2)||(W&&(L<2))){T=m}if((L==3)||(W&&(L<3))){T=l}if((L==16)||(W&&(L<16))){T=k}if((L==30)||(W&&(L<30))){T=o}if((L==256)||(W&&(L<256))){T=n}if((L==261)||(W&&(L<261))){T=p}if(T==null){T=Buffer.concat([IntToStr(8),IntToStr(4)])}else{T=Buffer.concat([IntToStr(8),IntToStr(T.length+4),T])}if(T.length>G){T=T.slice(0,G)}B.SendDataToHost(I,true,T,K&1);return -1;case 74:if(B.debug){console.log("SCSI: GET_EVENT_STATUS_NOTIFICATION",I,H[1],H[4],H[9])}if((H[1]!=1)&&(H[4]!=16)){if(B.debug){console.log("SCSI ERROR")}B.SendCommandEndResponse(1,5,I,38,1);break}var S=0;if((I==160)&&(B.floppy!=null)){S=2}else{if((I==176)&&(B.cdrom!=null)){S=2}}B.SendDataToHost(I,true,new Buffer([0,S,128,0]),K&1);break;case 76:B.SendCommand(81,Buffer.concat([IntToStrX(0),IntToStrX(0),IntToStrX(0),new Buffer([135,80,3,0,0,0,176,81,5,32,0])]),true);break;case 81:if(B.debug){console.log("SCSI READ_DISC_INFO",I)}B.SendCommandEndResponse(0,5,I,32,0);return -1;case 85:if(B.debug){console.log("SCSI ERROR: MODE_SELECT_10",I)}B.SendCommandEndResponse(1,5,I,32,0);return -1;case 90:if(B.debug){console.log("SCSI: MODE_SENSE_10",I,H[2]&63)}var G=ReadShort(H,7);var T=null;if(G==0){B.SendDataToHost(I,true,Buffer.concat([IntToStr(60),IntToStr(8)]),K&1);return -1}var U=0;if(I==160){if(B.floppy!=null){U=(B.floppy.size>>9)}}else{if(B.cdrom!=null){U=(B.cdrom.size>>11)}}switch(H[2]&63){case 1:if(I==160){T=(U<=2880)?y:A}else{T=w}break;case 5:if(I==160){T=(U<=2880)?x:z}break;case 63:if(I==160){T=(U<=2880)?r:s}else{T=q}break;case 26:if(I==176){T=t}break;case 29:if(I==176){T=u}break;case 42:if(I==176){T=v}break}if(T==null){B.SendCommandEndResponse(0,5,I,32,0)}else{B.SendDataToHost(I,true,T,K&1)}break;default:if(B.debug){console.log("IDER: Unknown SCSI command",H[0])}B.SendCommandEndResponse(0,5,I,32,0);return -1}return 0}function C(E,G,H,F){var I=null;var J=0;if(E==160){I=B.floppy;if(B.floppy!=null){J=(B.floppy.size>>9)}}if(E==176){I=B.cdrom;if(B.cdrom!=null){J=(B.cdrom.size>>11)}}if((H<0)||(G+H>J)){B.SendCommandEndResponse(1,5,E,33,0);return 0}if(H==0){B.SendCommandEndResponse(1,0,E,0,0);return 0}if(I!=null){if(B.sectorStats){B.sectorStats(1,(E==160)?0:1,J,G,H)}if(E==160){G<<=9;H<<=9}else{G<<=11;H<<=11}if(d!==null){e.push({media:I,dev:E,lba:G,len:H,fr:F})}else{d=I;a=E;b=G;c=H;D(F)}}}var e=[];var f=false;var d=null;var a;var b;var c;function D(E){var G=c,F=b;if(c>B.iderinfo.readbfr){G=B.iderinfo.readbfr}c-=G;b+=G;var I=new Buffer(G);fs.readSync(d.file,I,0,G,F);B.SendDataToHost(a,(c==0),I,E&1);if((c>0)&&(f==false)){D(E)}else{d=null;if(f){B.SendCommand(71);e=[];f=false}else{if(e.length>0){var H=e.shift();d=H.media;a=H.dev;b=H.lba;c=H.len;D(H.fr)}}}}return B};function ShortToStr(a){return new Buffer([(a>>8)&255,a&255])}function ShortToStrX(a){return new Buffer([a&255,(a>>8)&255])}function IntToStr(a){return new Buffer([(a>>24)&255,(a>>16)&255,(a>>8)&255,a&255])}function IntToStrX(a){return new Buffer([a&255,(a>>8)&255,(a>>16)&255,(a>>24)&255])}function ReadShort(b,a){return(b[a]<<8)+b[a+1]}function ReadShortX(b,a){return(b[a+1]<<8)+b[a]}function ReadInt(b,a){return(b[a]*16777216)+(b[a+1]<<16)+(b[a+2]<<8)+b[a+3]}function ReadSInt(b,a){return(b[a]<<24)+(b[a+1]<<16)+(b[a+2]<<8)+b[a+3]}function ReadIntX(b,a){return(b[a+3]*16777216)+(b[a+2]<<16)+(b[a+1]<<8)+b[a]}; \ No newline at end of file diff --git a/agents/modules_meshcmd_min/amt-lme.min.js b/agents/modules_meshcmd_min/amt-lme.min.js new file mode 100644 index 00000000..1d43678a --- /dev/null +++ b/agents/modules_meshcmd_min/amt-lme.min.js @@ -0,0 +1 @@ +var MemoryStream=require("MemoryStream");var lme_id=0;var lme_port_offset=0;var xmlParser=require("amt-xml");var APF_DISCONNECT=1;var APF_SERVICE_REQUEST=5;var APF_SERVICE_ACCEPT=6;var APF_USERAUTH_REQUEST=50;var APF_USERAUTH_FAILURE=51;var APF_USERAUTH_SUCCESS=52;var APF_GLOBAL_REQUEST=80;var APF_REQUEST_SUCCESS=81;var APF_REQUEST_FAILURE=82;var APF_CHANNEL_OPEN=90;var APF_CHANNEL_OPEN_CONFIRMATION=91;var APF_CHANNEL_OPEN_FAILURE=92;var APF_CHANNEL_WINDOW_ADJUST=93;var APF_CHANNEL_DATA=94;var APF_CHANNEL_CLOSE=97;var APF_PROTOCOLVERSION=192;function lme_object(){this.ourId=++lme_id;this.amtId=-1;this.LME_CHANNEL_STATUS="LME_CS_FREE";this.txWindow=0;this.rxWindow=0;this.localPort=0;this.errorCount=0}function stream_bufferedWrite(){var a=require("events").inherits(this);this.buffer=[];this._readCheckImmediate=undefined;this._ObjectID="bufferedWriteStream";a.createEvent("close");a.createEvent("drain");a.createEvent("error");a.createEvent("finish");a.createEvent("pipe");a.createEvent("unpipe");a.createEvent("readable");this.isEmpty=function(){return(this.buffer.length==0)};this.isWaiting=function(){return(this._readCheckImmediate==undefined)};this.write=function(c){for(var b in arguments){if(typeof(arguments[b])=="function"){this.once("drain",arguments[b]);break}}var d=Buffer.alloc(c.length);c.copy(d);this.buffer.push({offset:0,data:d});this.emit("readable");return(this.buffer.length==0?true:false)};this.read=function(){var f=arguments.length==0?undefined:arguments[0];var b=0;var d=[];while((f==undefined||b0){var c=this.buffer[0].data.length-this.buffer[0].offset;var e=this.buffer[0].offset;if(c>(f-b)){d.push(this.buffer[0].data.slice(e,e+f-b));this.buffer[0].offset+=(f-b);b+=(f-b)}else{d.push(this.buffer[0].data.slice(e));b+=c;this.buffer.shift()}}this._readCheckImmediate=setImmediate(function(g){g._readCheckImmediate=undefined;if(g.buffer.length==0){g.emit("drain")}else{g.emit("readable")}},this);return(Buffer.concat(d))}}function lme_heci(c){var a=require("events").inherits(this);a.createEvent("error");a.createEvent("connect");a.createEvent("notify");a.createEvent("bind");if((c!=null)&&(c.debug==true)){lme_port_offset=-100}var b=require("heci");this.INITIAL_RXWINDOW_SIZE=4096;this._ObjectID="lme";this._LME=b.create();this._LME._binded={};this._LME.LMS=this;this._LME.on("error",function(d){this.LMS.emit("error",d)});this._LME.on("connect",function(){this.on("data",function(k){var l=k.readUInt8(0);switch(l){default:console.log("Unhandled LME Command "+l+", "+k.length+" byte(s).");break;case APF_SERVICE_REQUEST:var z=k.readUInt32BE(1);var y=k.slice(5,z+5);if(y=="pfwd@amt.intel.com"||y=="auth@amt.intel.com"){var F=Buffer.alloc(5+z);F.writeUInt8(6,0);F.writeUInt32BE(z,1);F.write(y.toString(),5);this.write(F)}else{}break;case APF_GLOBAL_REQUEST:var z=k.readUInt32BE(1);var y=k.slice(5,z+5).toString();switch(y){case"tcpip-forward":var v=k.readUInt32BE(z+6);var G=k.readUInt32BE(z+10+v);if(this[y]==undefined){this[y]={}}if(this[y][G]!=null){for(var s in this.sockets){var h=this.sockets[s];if(h.localPort==G){this.sockets[s].end();delete this.sockets[s]}}}if(this[y][G]==null){this[y][G]=require("net").createServer();this[y][G].HECI=this;if(lme_port_offset==0){this[y][G].listen({port:G,host:"127.0.0.1"})}else{this[y][G].listen({port:(G+lme_port_offset)})}this[y][G].on("connection",function(e){this.HECI.LMS.bindDuplexStream(e,e.remoteFamily,e.localPort-lme_port_offset)});this._binded[G]=true;this.LMS.emit("bind",this._binded)}var F=Buffer.alloc(5);F.writeUInt8(81,0);F.writeUInt32BE(G,1);this.write(F);break;case"cancel-tcpip-forward":var F=Buffer.alloc(1);F.writeUInt8(APF_REQUEST_SUCCESS,0);this.write(F);break;case"udp-send-to@amt.intel.com":var F=Buffer.alloc(1);F.writeUInt8(APF_REQUEST_FAILURE,0);this.write(F);break;default:break}break;case APF_CHANNEL_OPEN_CONFIRMATION:var I=k.readUInt32BE(1);var M=k.readUInt32BE(5);var N=k.readUInt32BE(9);if(this.sockets[I]!=undefined){this.sockets[I].lme.amtId=M;this.sockets[I].lme.rxWindow=N;this.sockets[I].lme.txWindow=N;this.sockets[I].lme.LME_CHANNEL_STATUS="LME_CS_CONNECTED";this.sockets[I].bufferedStream=new stream_bufferedWrite();this.sockets[I].bufferedStream.socket=this.sockets[I];this.sockets[I].bufferedStream.on("readable",function(){if(this.socket.lme.txWindow>0){var e=this.read(this.socket.lme.txWindow);var i=Buffer.alloc(9+e.length);i.writeUInt8(APF_CHANNEL_DATA,0);i.writeUInt32BE(this.socket.lme.amtId,1);i.writeUInt32BE(e.length,5);e.copy(i,9);this.socket.lme.txWindow-=e.length;this.socket.HECI.write(i)}});this.sockets[I].bufferedStream.on("drain",function(){this.socket.resume()});this.sockets[I].on("data",function(e){if(!this.bufferedStream.write(e)){this.pause()}});this.sockets[I].on("end",function(){var e=Buffer.alloc(5);e.writeUInt8(APF_CHANNEL_CLOSE,0);e.writeUInt32BE(this.lme.amtId,1);this.HECI.write(e)});this.sockets[I].resume()}break;case APF_PROTOCOLVERSION:var w=k.readUInt32BE(1);var x=k.readUInt32BE(5);var K=k.readUInt32BE(9);var F=Buffer.alloc(93);F.writeUInt8(192,0);F.writeUInt32BE(1,1);F.writeUInt32BE(0,5);F.writeUInt32BE(K,9);this.write(F);break;case APF_CHANNEL_WINDOW_ADJUST:var J=k.readUInt32BE(1);var g=k.readUInt32BE(5);if(this.sockets[J]!=undefined){this.sockets[J].lme.txWindow+=g;if(!this.sockets[J].bufferedStream.isEmpty()&&this.sockets[J].bufferedStream.isWaiting()){this.sockets[J].bufferedStream.emit("readable")}}else{console.log("Unknown Recipient ID/"+J+" for APF_CHANNEL_WINDOW_ADJUST")}break;case APF_CHANNEL_DATA:var J=k.readUInt32BE(1);var n=k.readUInt32BE(5);var m=k.slice(9,9+n);if((this.sockets!=null)&&(this.sockets[J]!=undefined)){this.sockets[J].pendingBytes.push(m.length);this.sockets[J].write(m,function(){var i=this.pendingBytes.shift();var e=Buffer.alloc(9);e.writeUInt8(APF_CHANNEL_WINDOW_ADJUST,0);e.writeUInt32BE(this.lme.amtId,1);e.writeUInt32BE(i,5);this.HECI.write(e)})}else{if((this.insockets!=null)&&(this.insockets[J]!=undefined)){var h=this.insockets[J];if(h.data==null){h.data=m.toString()}else{h.data+=m.toString()}h.rxWindow+=n;var r=parseHttp(h.data);if((r!=null)||(h.data.length>=8000)){var A=null;try{A=xmlParser.ParseWsman(r)}catch(o){}if(A!=null){this.LMS.emit("notify",A,h.options,_lmsNotifyToString(A),_lmsNotifyToCode(A))}var f=Buffer.alloc(5);f.writeUInt8(APF_CHANNEL_CLOSE,0);f.writeUInt32BE(d,1);this.write(f)}else{if(h.rxWindow>6000){var f=Buffer.alloc(9);f.writeUInt8(APF_CHANNEL_WINDOW_ADJUST,0);f.writeUInt32BE(h.amtId,1);f.writeUInt32BE(h.rxWindow,5);this.write(f);h.rxWindow=0}}}else{console.log("Unknown Recipient ID/"+J+" for APF_CHANNEL_DATA")}}break;case APF_CHANNEL_OPEN_FAILURE:var J=k.readUInt32BE(1);var L=k.readUInt32BE(5);if((this.sockets!=null)&&(this.sockets[J]!=undefined)){this.sockets[J].end();delete this.sockets[J]}else{if((this.insockets!=null)&&(this.insockets[J]!=undefined)){delete this.insockets[J]}else{console.log("Unknown Recipient ID/"+J+" for APF_CHANNEL_OPEN_FAILURE")}}break;case APF_CHANNEL_CLOSE:var J=k.readUInt32BE(1);if((this.sockets!=null)&&(this.sockets[J]!=undefined)){this.sockets[J].end();var d=this.sockets[J].lme.amtId;var f=Buffer.alloc(5);delete this.sockets[J];f.writeUInt8(APF_CHANNEL_CLOSE,0);f.writeUInt32BE(d,1);this.write(f)}else{if((this.insockets!=null)&&(this.insockets[J]!=undefined)){delete this.insockets[J]}else{console.log("Unknown Recipient ID/"+J+" for APF_CHANNEL_CLOSE")}}break;case APF_CHANNEL_OPEN:var z=k.readUInt32BE(1);var y=k.slice(5,z+5).toString();var j=k.readUInt32BE(z+5);var t=k.readUInt32BE(z+9);var q=k.readUInt32BE(z+17);var p=k.slice(z+21,z+21+q).toString();var H=k.readUInt32BE(z+21+q);var C=k.readUInt32BE(z+25+q);var B=k.slice(z+29+q,z+29+q+C).toString();var D=k.readUInt32BE(z+29+q+C);if(this.insockets==null){this.insockets={}}var E=++lme_id;var u=new lme_object();u.ourId=E;u.amtId=j;u.txWindow=t;u.rxWindow=0;u.options={target:p,targetPort:H,source:B,sourcePort:D};this.insockets[E]=u;var f=Buffer.alloc(17);f.writeUInt8(APF_CHANNEL_OPEN_CONFIRMATION,0);f.writeUInt32BE(j,1);f.writeUInt32BE(E,5);f.writeUInt32BE(4000,9);f.writeUInt32BE(4294967295,13);this.write(f);break}});this.LMS.emit("connect");this.resume()});this.bindDuplexStream=function(e,h,g){var j=e;j.pendingBytes=[];j.HECI=this._LME;j.LMS=this;j.lme=new lme_object();j.lme.Socket=j;j.localPort=g;var d=new MemoryStream();d.writeUInt8(90);d.writeUInt32BE(15);d.write("forwarded-tcpip");d.writeUInt32BE(j.lme.ourId);d.writeUInt32BE(this.INITIAL_RXWINDOW_SIZE);d.writeUInt32BE(4294967295);for(var f=0;f<2;++f){if(h=="IPv6"){d.writeUInt32BE(3);d.write("::1")}else{d.writeUInt32BE(9);d.write("127.0.0.1")}d.writeUInt32BE(g)}this._LME.write(d.buffer);if(this._LME.sockets==undefined){this._LME.sockets={}}this._LME.sockets[j.lme.ourId]=j;j.pause()};this._LME.connect(b.GUIDS.LME,{noPipeline:0})}function parseHttp(c){var d=c.indexOf("\r\n\r\n");if((d==-1)||(c.length<(d+2))){return null}var b=require("http-headers")(c.substring(0,d),true);var a=parseInt(b["content-length"]);if(c.length>=a+d+4){return c.substring(d+4,d+4+a)}return null}function _lmsNotifyToCode(c){if((c==null)||(c.Body==null)||(c.Body.MessageID==null)){return null}var b=c.Body.MessageID;try{b+="-"+c.Body.MessageArguments[0]}catch(a){}return b}function _lmsNotifyToString(c){if((c==null)||(c.Body==null)||(c.Body.MessageID==null)){return null}var b=c.Body.MessageID;try{b+="-"+c.Body.MessageArguments[0]}catch(a){}if(lmsEvents[b]){return lmsEvents[b]}return null}var lmsEvents={iAMT0001:"System Defense Policy %1s triggered.",iAMT0002:"Agent Presence Agent %1s not started.",iAMT0003:"Agent Presence Agent %1s stopped.",iAMT0004:"Agent Presence Agent %1s running.",iAMT0005:"Agent Presence Agent %1s expired.",iAMT0006:"Agent Presence Agent %1s suspended.",iAMT0007:"Host software attempt to disable AMT Network link detected.",iAMT0008:"Host software attempt to disable AMT Network link detected -- Host Network link blocked.",iAMT0009:"AMT clock or FLASH wear-out protection disabled.",iAMT0010:"Intel(R) AMT Network Interface %1s heuristics defense slow threshold trespassed.",iAMT0011:"Intel(R) AMT Network Interface %1s heuristics defense fast threshold trespassed.",iAMT0012:"Intel(R) AMT Network Interface %1s heuristics defense factory defined threshold trespassed.",iAMT0013:"Intel(R) AMT Network Interface %1s heuristics defense Encounter timeout expired.",iAMT0014:"General certificate error.",iAMT0015:"Certificate expired.",iAMT0016:"No trusted root certificate.",iAMT0017:"Not configured to work with server certificate.",iAMT0018:"Certificate revoked.",iAMT0019:"RSA exponent too large.",iAMT0020:"RSA modulus too large.",iAMT0021:"Unsupported digest.",iAMT0022:"Distinguished name too long.",iAMT0023:"Key usage missing.",iAMT0024:"General SSL handshake error.",iAMT0025:"General 802.1x error.",iAMT0026:"AMT Diagnostic AlertEAC error - General NAC error.",iAMT0027:"AMT Diagnostic AlertEAC error - attempt to get a NAC posture while AMT NAC is disabled.",iAMT0028:"AMT Diagnostic AlertEAC error - attempt to get a posture of an unsupported type.",iAMT0029:"Audit log storage is 50% full.",iAMT0030:"Audit log storage is 75% full.",iAMT0031:"Audit log storage is 85% full.",iAMT0032:"Audit log storage is 95% full.",iAMT0033:"Audit log storage is full.",iAMT0034:"Firmware Update Event - Partial.",iAMT0035:"Firmware Update Event - Failure.",iAMT0036:"Remote connectivity initiated.",iAMT0037:"ME Presence event.","iAMT0038-0":"AMT is being unprovisioned using BIOS command.","iAMT0038-1":"AMT is being unprovisioned using Local MEI command.","iAMT0038-2":"AMT is being unprovisioned using Local WS-MAN/SOAP command.","iAMT0038-3":"AMT is being unprovisioned using Remote WS-MAN/SOAP command.",iAMT0039:"HW Asset Error.",iAMT0050:"User Notification Alert - General Notification.","iAMT0050-16":"User Notification Alert - Circuit Breaker notification (CB Drop TX filter hit.).","iAMT0050-17":"User Notification Alert - Circuit Breaker notification (CB Rate Limit TX filter hit.).","iAMT0050-18":"User Notification Alert - Circuit Breaker notification (CB Drop RX filter hit.).","iAMT0050-19":"User Notification Alert - Circuit Breaker notification (CB Rate Limit RX filter hit.).","iAMT0050-32":"User Notification Alert - EAC notification.","iAMT0050-48":"User Notification Alert - Remote diagnostics - (Remote Redirection session started - SOL).","iAMT0050-49":"User Notification Alert - Remote diagnostics - (Remote Redirection session stopped - SOL).","iAMT0050-50":"User Notification Alert - Remote diagnostics. (Remote Redirection session started - IDE-R).","iAMT0050-51":"User Notification Alert - Remote diagnostics. (Remote Redirection session stopped - IDE-R).","iAMT0050-66":"User Notification Alert - WLAN notification (Host profile mismatch - Management Interface ignored).","iAMT0050-67":"User Notification Alert - WLAN notification (Management device overrides host radio).","iAMT0050-68":"User Notification Alert - WLAN notification (Host profile security mismatch).","iAMT0050-69":"User Notification Alert - WLAN notification (Management device relinquishes control over host Radio).",iAMT0051:"User Notification Alert - SecIo event.","iAMT0051-0":"User Notification Alert - SecIo event semaphore at host.","iAMT0051-1":"User Notification Alert - semaphore at ME.","iAMT0051-2":"User Notification Alert - SecIo event - semaphore timeout.",iAMT0052:"User Notification Alert - KVM session event.","iAMT0052-0":"User Notification Alert - KVM session requested.","iAMT0052-1":"User Notification Alert - KVM session started.","iAMT0052-2":"User Notification Alert - KVM session stopped.","iAMT0052-3":"User Notification Alert - KVM data channel.",iAMT0053:"User Notification Alert - RCS notification.","iAMT0053-50":"User Notification Alert - RCS notification (HW button pressed. Connection initiated automatically).","iAMT0053-52":"User Notification Alert - RCS notification (HW button pressed. Connection wasn't initiated automatically).","iAMT0053-53":"User Notification Alert - RCS notification (Contracts updated).",iAMT0054:"User Notification Alert - WLAN notification. Wireless Profile sync enablement state changed.",iAMT0055:"User Notification Alert - Provisioning state change notification.","iAMT0055-0":"User Notification Alert - Provisioning state change notification - Pre-configuration.","iAMT0055-1":"User Notification Alert - Provisioning state change notification - In configuration.","iAMT0055-2":"User Notification Alert - Provisioning state change notification - Post-configuration.","iAMT0055-3":"User Notification Alert - Provisioning state change notification - Unprovision process has started.",iAMT0056:"User Notification Alert - System Defense change notification.",iAMT0057:"User Notification Alert - Network State change notification.",iAMT0058:"User Notification Alert - Remote Access change notification.","iAMT0058-1":"User Notification Alert - Remote Access change notification - tunnel is closed.",iAMT0059:"User Notification Alert - KVM enabled event.","iAMT0059-0":"User Notification Alert - KVM enabled event - KVM disabled.","iAMT0059-1":"User Notification Alert - KVM enabled event - KVM enabled (both from MEBx and PTNI).",iAMT0060:"User Notification Alert - SecIO configuration event.",iAMT0061:"ME FW reset occurred.",iAMT0062:"User Notification Alert - IpSyncEnabled event.","iAMT0062-0":"User Notification Alert - IpSyncEnabled event - IpSync disabled.","iAMT0062-1":"User Notification Alert - IpSyncEnabled event - IpSync enabled.",iAMT0063:"User Notification Alert - HTTP Proxy sync enabled event.","iAMT0063-0":"User Notification Alert - HTTP Proxy sync enabled event - HTTP Proxy Sync disabled.","iAMT0063-1":"User Notification Alert - HTTP Proxy sync enabled event - HTTP Proxy Sync enabled.",iAMT0064:"User Notification Alert - User Consent event.","iAMT0064-1":"User Notification Alert - User Consent event - User Consent granted.","iAMT0064-2":"User Notification Alert - User Consent event - User Consent ended.","iAMT0067-0":"Graceful Remote Control Operation - Shutdown.","iAMT0067-1":"Graceful Remote Control Operation - Reset.","iAMT0067-2":"Graceful Remote Control Operation - Hibernate.","iAMT0068-0":"Link Protection Notification - No link protection.","iAMT0068-1":"Link Protection Notification - Passive link protection.","iAMT0068-2":"Link Protection Notification - High link protection.","iAMT0069-0":"Local Time Sync Enablement Notification - Local Time Sync Disabled.","iAMT0069-1":"Local Time Sync Enablement Notification - Local Time Sync Enabled.",iAMT0070:"Host Reset Triggered by WD Expiration Notification.",PLAT0004:"The chassis %1s was opened.",PLAT0005:"The chassis %1s was closed.",PLAT0006:"The drive bay %1s was opened.",PLAT0007:"The drive bay %1s was closed.",PLAT0008:"The I/O card area %1s was opened.",PLAT0009:"The I/O card area %1s was closed.",PLAT0010:"The processor area %1s was opened.",PLAT0011:"The processor area %1s was closed.",PLAT0012:"The LAN %1s has been disconnected.",PLAT0013:"The LAN %1s has been connected.",PLAT0016:"The permission to insert package %1s has been granted.",PLAT0017:"The permission to insert package %1s has been removed.",PLAT0018:"The fan card area %1s is open.",PLAT0019:"The fan card area %1s is closed.",PLAT0022:"The computer system %1s has detected a secure mode violation.",PLAT0024:"The computer system %1s has detected a pre-boot user password violation.",PLAT0026:"The computer system %1s has detected a pre-boot setup password violation.",PLAT0028:"The computer system %1s has detected a network boot password violation.",PLAT0030:"The computer system %1s has detected a password violation.",PLAT0032:"The management controller %1s has detected an out-of-band password violation.",PLAT0034:"The processor %1s has been added.",PLAT0035:"The processor %1s has been removed.",PLAT0036:"An over-temperature condition has been detected on the processor %1s.",PLAT0037:"An over-temperature condition has been removed on the processor %1s.",PLAT0038:"The processor %1s is operating in a degraded State.",PLAT0039:"The processor %1s is no longer operating in a degraded State.",PLAT0040:"The processor %1s has failed.",PLAT0042:"The processor %1s has failed.",PLAT0044:"The processor %1s has failed.",PLAT0046:"The processor %1s has failed.",PLAT0048:"The processor %1s has failed.",PLAT0060:"The processor %1s has been enabled.",PLAT0061:"The processor %1s has been disabled.",PLAT0062:"The processor %1s has a configuration mismatch.",PLAT0064:"A terminator has been detected on the processor %1s.",PLAT0084:"The Power Supply %1s has been added.",PLAT0085:"The Power Supply %1s has been removed.",PLAT0086:"The Power Supply %1s has failed.",PLAT0088:"Failure predicted on power supply %1s.",PLAT0096:"The input to power supply %1s has been lost or fallen out of range.",PLAT0098:"The power supply %1s is operating in an input state that is out of range.",PLAT0099:"The power supply %1s has returned to a normal input state.",PLAT0100:"The power supply %1s has lost input.",PLAT0104:"The power supply %1s has a configuration mismatch.",PLAT0106:"Power supply %1s has been disabled.",PLAT0107:"Power supply %1s has been enabled.",PLAT0108:"Power supply %1s has been power cycled.",PLAT0110:"Power supply %1s has encountered an error during power down.",PLAT0112:"Power supply %1s has lost power.",PLAT0114:"Soft power control has failed for power supply %1s.",PLAT0116:"Power supply %1s has failed.",PLAT0118:"Failure predicted on power supply %1s.",PLAT0120:"Memory subsystem failure.",PLAT0122:"DIMM missing.",PLAT0124:"Memory error detected & corrected for DIMM %1s.",PLAT0128:"Memory DIMM %1s added.",PLAT0129:"Memory DIMM %1s removed.",PLAT0130:"Memory DIMM %1s enabled.",PLAT0131:"Memory DIMM %1s disabled.",PLAT0134:"Memory parity error for DIMM %1s.",PLAT0136:"Memory scrub failure for DIMM %1s.",PLAT0138:"Memory uncorrectable error detected for DIMM %1s.",PLAT0140:"Memory sparing initiated for DIMM %1s.",PLAT0141:"Memory sparing concluded for DIMM %1s.",PLAT0142:"Memory DIMM %1s Throttled.",PLAT0144:"Memory logging limit reached for DIMM %1s.",PLAT0145:"Memory logging limit removed for DIMM %1s.",PLAT0146:"An over-temperature condition has been detected on the Memory DIMM %1s.",PLAT0147:"An over-temperature condition has been removed on the Memory DIMM %1s.",PLAT0162:"The drive %1s has been added.",PLAT0163:"The drive %1s has been removed.",PLAT0164:"The drive %1s has been disabled due to a detected fault.",PLAT0167:"The drive %1s has been enabled.",PLAT0168:"Failure predicted on drive %1s.",PLAT0170:"Hot spare enabled for %1s.",PLAT0171:"Hot spare disabled for %1s.",PLAT0172:"Consistency check has begun for %1s.",PLAT0173:"Consistency check completed for %1s.",PLAT0174:"Array %1s is in critical condition.",PLAT0176:"Array %1s has failed.",PLAT0177:"Array %1s has been restored.",PLAT0178:"Rebuild in progress for array %1s.",PLAT0179:"Rebuild completed for array %1s.",PLAT0180:"Rebuild Aborted for array %1s.",PLAT0184:"The system %1s encountered a POST error.",PLAT0186:"The system %1s encountered a firmware hang.",PLAT0188:"The system %1s encountered firmware progress.",PLAT0192:"The log %1s has been disabled.",PLAT0193:"The log %1s has been enabled.",PLAT0194:"The log %1s has been disabled.",PLAT0195:"The log %1s has been enabled.",PLAT0196:"The log %1s has been disabled.",PLAT0198:"The log %1s has been enabled.",PLAT0200:"The log %1s has been cleared.",PLAT0202:"The log %1s is full.",PLAT0203:"The log %1s is no longer full.",PLAT0204:"The log %1s is almost full.",PLAT0208:"The log %1s has a configuration error.",PLAT0210:"The system %1s has been reconfigured.",PLAT0212:"The system %1s has encountered an OEM system boot event.",PLAT0214:"The system %1s has encountered an unknown system hardware fault.",PLAT0216:"The system %1s has generated an auxiliary log entry.",PLAT0218:"The system %1s has executed a PEF action.",PLAT0220:"The system %1s has synchronized the system clock.",PLAT0222:"A diagnostic interrupt has occurred on system %1s.",PLAT0224:"A bus timeout has occurred on system %1s.",PLAT0226:"An I/O channel check NMI has occurred on system %1s.",PLAT0228:"A software NMI has occurred on system %1s.",PLAT0230:"System %1s has recovered from an NMI.",PLAT0232:"A PCI PERR has occurred on system %1s.",PLAT0234:"A PCI SERR has occurred on system %1s.",PLAT0236:"An EISA fail safe timeout occurred on system %1s.",PLAT0238:"A correctable bus error has occurred on system %1s.",PLAT0240:"An uncorrectable bus error has occurred on system %1s.",PLAT0242:"A fatal NMI error has occurred on system %1s.",PLAT0244:"A fatal bus error has occurred on system %1s.",PLAT0246:"A bus on system %1s is operating in a degraded state.",PLAT0247:"A bus on system %1s is no longer operating in a degraded state.",PLAT0248:"The power button %1s has been pressed.",PLAT0249:"The power button %1s has been released.",PLAT0250:"The sleep button %1s has been pressed.",PLAT0251:"The sleep button %1s has been released.",PLAT0252:"The reset button %1s has been pressed.",PLAT0253:"The reset button %1s has been released.",PLAT0254:"The latch to %1s has been opened.",PLAT0255:"The latch to %1s has been closed.",PLAT0256:"The service request %1s has been enabled.",PLAT0257:"The service request %1s has been completed.",PLAT0258:"Power control of system %1s has failed.",PLAT0262:"The network port %1s has been connected.",PLAT0263:"The network port %1s has been disconnected.",PLAT0266:"The connector %1s has encountered a configuration error.",PLAT0267:"The connector %1s configuration error has been repaired.",PLAT0272:"Power on for system %1s.",PLAT0274:"Power cycle hard requested for system %1s.",PLAT0276:"Power cycle soft requested for system %1s.",PLAT0278:"PXE boot requested for system %1s.",PLAT0280:"Diagnostics boot requested for system %1s.",PLAT0282:"System restart requested for system %1s.",PLAT0284:"System restart begun for system %1s.",PLAT0286:"No bootable media available for system %1s.",PLAT0288:"Non-bootable media selected for system %1s.",PLAT0290:"PXE server not found for system %1s.",PLAT0292:"User timeout on boot for system %1s.",PLAT0296:"System %1s boot from floppy initiated.",PLAT0298:"System %1s boot from local drive initiated.",PLAT0300:"System %1s boot from PXE on network port initiated.",PLAT0302:"System %1s boot diagnostics initiated.",PLAT0304:"System %1s boot from CD initiated.",PLAT0306:"System %1s boot from ROM initiated.",PLAT0312:"System %1s boot initiated.",PLAT0320:"Critical stop during OS load on system %1s.",PLAT0322:"Run-time critical stop on system %1s.",PLAT0324:"OS graceful stop on system %1s.",PLAT0326:"OS graceful shutdown begun on system %1s.",PLAT0327:"OS graceful shutdown completed on system %1s.",PLAT0328:"Agent not responding on system %1s.",PLAT0329:"Agent has begun responding on system %1s.",PLAT0330:"Fault in slot on system %1s.",PLAT0331:"Fault condition removed on system %1s.",PLAT0332:"Identifying slot on system %1s.",PLAT0333:"Identify stopped on slot for system %1s.",PLAT0334:"Package installed in slot for system %1s.",PLAT0336:"Slot empty system %1s.",PLAT0338:"Slot in system %1s is ready for installation.",PLAT0340:"Slot in system %1s is ready for removal.",PLAT0342:"Power is off on slot of system %1s.",PLAT0344:"Power is on for slot of system %1s.",PLAT0346:"Removal requested for slot of system %1s.",PLAT0348:"Interlock activated on slot of system %1s.",PLAT0349:"Interlock de-asserted on slot of system %1s.",PLAT0350:"Slot disabled on system %1s.",PLAT0351:"Slot enabled on system %1s.",PLAT0352:"Slot of system %1s holds spare.",PLAT0353:"Slot of system %1s no longer holds spare.",PLAT0354:"Computer system %1s enabled.",PLAT0356:"Computer system %1s is in sleep - light mode.",PLAT0358:"Computer system %1s is in hibernate.",PLAT0360:"Computer system %1s is in standby.",PLAT0362:"Computer system %1s is in soft off mode.",PLAT0364:"Computer system %1s is in hard off mode.",PLAT0366:"Computer system %1s is sleeping.",PLAT0368:"Watchdog timer expired for %1s.",PLAT0370:"Reboot of system initiated by watchdog %1s.",PLAT0372:"Powering off system initiated by watchdog %1s.",PLAT0374:"Power cycle of system initiated by watchdog %1s.",PLAT0376:"Watchdog timer interrupt occurred for %1s.",PLAT0378:"A page alert has been generated for system %1s.",PLAT0380:"A LAN alert has been generated for system %1s.",PLAT0382:"An event trap has been generated for system %1s.",PLAT0384:"An SNMP trap has been generated for system %1s.",PLAT0390:"%1s detected as present.",PLAT0392:"%1s detected as absent.",PLAT0394:"%1s has been disabled.",PLAT0395:"%1s has been enabled.",PLAT0396:"Heartbeat lost for LAN %1s.",PLAT0397:"Heartbeat detected for LAN %1s.",PLAT0398:"Sensor %1s is unavailable or degraded on management system.",PLAT0399:"Sensor %1s has returned to normal on management system.",PLAT0400:"Controller %1s is unavailable or degraded on management system.",PLAT0401:"Controller %1s has returned to normal on management system.",PLAT0402:"Management system %1s is off-line.",PLAT0404:"Management system %1s is disabled.",PLAT0405:"Management system %1s is enabled.",PLAT0406:"Sensor %1s has failed on management system.",PLAT0408:"FRU %1s has failed on management system.",PLAT0424:"The battery %1s is critically low.",PLAT0427:"The battery %1s is no longer critically low.",PLAT0430:"The battery %1s has been removed from unit.",PLAT0431:"The battery %1s has been added.",PLAT0432:"The battery %1s has failed.",PLAT0434:"Session audit is deactivated on system %1s.",PLAT0435:"Session audit is activated on system %1s.",PLAT0436:"A hardware change occurred on system %1s.",PLAT0438:"A firmware or software change occurred on system %1s.",PLAT0440:"A hardware incompatibility was detected on system %1s.",PLAT0442:"A firmware or software incompatibility was detected on system %1s.",PLAT0444:"Invalid or unsupported hardware was detected on system %1s.",PLAT0446:"Invalid or unsupported firmware or software was detected on system %1s.",PLAT0448:"A successful hardware change was detected on system %1s.",PLAT0450:"A successful software or firmware change was detected on system %1s.",PLAT0464:"FRU %1s not installed on system.",PLAT0465:"FRU %1s installed on system.",PLAT0466:"Activation requested for FRU %1s on system.",PLAT0467:"FRU %1s on system is active.",PLAT0468:"Activation in progress for FRU %1s on system.",PLAT0470:"Deactivation request for FRU %1s on system.",PLAT0471:'FRU %1s on system is in standby or "hot spare" state.',PLAT0472:"Deactivation in progress for FRU %1s on system.",PLAT0474:"Communication lost with FRU %1s on system.",PLAT0476:"Numeric sensor %1s going low (lower non-critical).",PLAT0478:"Numeric sensor %1s going high (lower non-critical).",PLAT0480:"Numeric sensor %1s going low (lower critical).",PLAT0482:"Numeric sensor %1s going high (lower critical).",PLAT0484:"Numeric sensor %1s going low (lower non-recoverable).",PLAT0486:"Numeric sensor %1s going high (lower non-critical).",PLAT0488:"Numeric sensor %1s going low (upper non-critical).",PLAT0490:"Numeric sensor %1s going high (upper non-critical).",PLAT0492:"Numeric sensor %1s going low (upper critical).",PLAT0494:"Numeric sensor %1s going high (upper critical).",PLAT0496:"Numeric sensor %1s going low (upper non-recoverable).",PLAT0498:"Numeric sensor %1s going high (upper non-recoverable).",PLAT0500:"Sensor %1s has transitioned to idle.",PLAT0502:"Sensor %1s has transitioned to active.",PLAT0504:"Sensor %1s has transitioned to busy.",PLAT0508:"Sensor %1s has asserted.",PLAT0509:"Sensor %1s has de-asserted.",PLAT0510:"Sensor %1s is asserting predictive failure.",PLAT0511:"Sensor %1s is de-asserting predictive failure.",PLAT0512:"Sensor %1s has indicated limit exceeded.",PLAT0513:"Sensor %1s has indicated limit no longer exceeded.",PLAT0514:"Sensor %1s has indicated performance met.",PLAT0516:"Sensor %1s has indicated performance lags.",PLAT0518:"Sensor %1s has transitioned to normal state.",PLAT0520:"Sensor %1s has transitioned from normal to non-critical state.",PLAT0522:"Sensor %1s has transitioned to critical from a less severe state.",PLAT0524:"Sensor %1s has transitioned to non-recoverable from a less severe state.",PLAT0526:"Sensor %1s has transitioned to non-critical from a more severe state.",PLAT0528:"Sensor %1s has transitioned to critical from a non-recoverable state.",PLAT0530:"Sensor %1s has transitioned to non-recoverable.",PLAT0532:"Sensor %1s indicates a monitor state.",PLAT0534:"Sensor %1s has an informational state.",PLAT0536:"Device %1s has been added.",PLAT0537:"Device %1s has been removed from unit.",PLAT0538:"Device %1s has been enabled.",PLAT0539:"Device %1s has been disabled.",PLAT0540:"Sensor %1s has indicated a running state.",PLAT0544:"Sensor %1s has indicated a power off state.",PLAT0546:"Sensor %1s has indicated an on-line state.",PLAT0548:"Sensor %1s has indicated an off-line state.",PLAT0550:"Sensor %1s has indicated an off-duty state.",PLAT0552:"Sensor %1s has indicated a degraded state.",PLAT0554:"Sensor %1s has indicated a power save state.",PLAT0556:"Sensor %1s has indicated an install error.",PLAT0558:"Redundancy %1s has been lost.",PLAT0560:"Redundancy %1s has been reduced.",PLAT0561:"Redundancy %1s has been restored.",PLAT0562:"%1s has transitioned to a D0 power state.",PLAT0564:"%1s has transitioned to a D1 power state.",PLAT0566:"%1s has transitioned to a D2 power state.",PLAT0568:"%1s has transitioned to a D3 power state.",PLAT0720:"The System %1s encountered firmware progress - memory initialization entry.",PLAT0721:"The System %1s encountered firmware progress - memory initialization exit.",PLAT0722:"The System %1s encountered firmware progress - hard drive initialization entry.",PLAT0723:"The System %1s encountered firmware progress - hard drive initialization exit.",PLAT0724:"The System %1s encountered firmware progress - user authentication.",PLAT0728:"The System %1s encountered firmware progress - USR resource configuration entry.",PLAT0729:"The System %1s encountered firmware progress - USR resource configuration exit.",PLAT0730:"The System %1s encountered firmware progress - PCI recource configuration entry.",PLAT0731:"The System %1s encountered firmware progress - PCI recource configuration exit.",PLAT0732:"The System %1s encountered firmware progress - Option ROM initialization entry.",PLAT0733:"The System %1s encountered firmware progress - Option ROM initialization entry exit.",PLAT0734:"The System %1s encountered firmware progress -video initialization entry entry.",PLAT0735:"The System %1s encountered firmware progress - video initialization entry exit.",PLAT0736:"The System %1s encountered firmware progress - cache initialization entry.",PLAT0737:"The System %1s encountered firmware progress - cache initialization exit.",PLAT0738:"The System %1s encountered firmware progress - keyboard controller initialization entry.",PLAT0739:"The System %1s encountered firmware progress - keyboard controller initialization exit.",PLAT0740:"The System %1s encountered firmware progress - motherboard initialization entry.",PLAT0741:"The System %1s encountered firmware progress - motherboard initialization exit.",PLAT0742:"The System %1s encountered firmware progress - floppy disk initialization entry.",PLAT0743:"The System %1s encountered firmware progress - floppy disk initialization exit.",PLAT0744:"The System %1s encountered firmware progress - keyboard test entry.",PLAT0745:"The System %1s encountered firmware progress - keyboard test exit.",PLAT0746:"The System %1s encountered firmware progress - pointing device test entry.",PLAT0747:"The System %1s encountered firmware progress - pointing device test exit.",PLAT0750:"The System %1s encountered firmware progress - dock enable entry.",PLAT0751:"The System %1s encountered firmware progress - dock enable exit.",PLAT0752:"The System %1s encountered firmware progress - dock disable entry.",PLAT0753:"The System %1s encountered firmware progress - dock disable exit.",PLAT0760:"The System %1s encountered firmware progress - start OS boot process.",PLAT0762:"The System %1s encountered firmware progress - call OS wake vector.",PLAT0764:"The System %1s encountered firmware progress - unrecoverable keyboard failure.",PLAT0766:"The System %1s encountered firmware progress - no video device detected.",PLAT0768:"The System %1s encountered firmware progress - SMART alert detected on drive.",PLAT0770:"The System %1s encountered firmware progress - unrecoverable boot device failure.",PLAT0789:"Corrupt BIOS detected.",PLAT0790:"The System %1s encountered PCI configuration failure.",PLAT0791:"The System %1s encountered a video subsystem failure.",PLAT0792:"The System %1s encountered a storage subsystem failure.",PLAT0793:"The System %1s encountered a USB subsystem failure.",PLAT0794:"The System %1s has detected no memory in the system.",PLAT0795:"The System %1s encountered a motherboard failure.",PLAT0796:"The System %1s encountered a memory Regulator Voltage Bad.",PLAT0797:"%1s PCI reset is not deasserting.",PLAT0798:"%1s Non-Motherboard Regulator Failure.",PLAT0799:"%1s Power Supply Cable failure.",PLAT0800:"%1s Motherboard regulator failure.",PLAT0801:"%1s System component compatibility mismatch."};module.exports=lme_heci; \ No newline at end of file diff --git a/agents/modules_meshcmd_min/amt-mei.min.js b/agents/modules_meshcmd_min/amt-mei.min.js new file mode 100644 index 00000000..35b4455b --- /dev/null +++ b/agents/modules_meshcmd_min/amt-mei.min.js @@ -0,0 +1 @@ +var Q=require("queue");function amt_heci(){var d=require("events").inherits(this);d.createEvent("error");var u=require("heci");this._ObjectID="pthi";this._rq=new Q();this._setupPTHI=function b(){this._amt=u.create();this._amt.BiosVersionLen=65;this._amt.UnicodeStringLen=20;this._amt.Parent=this;this._amt.on("error",function E(G){if(this.Parent._rq.isEmpty()){this.Parent.emit("error",G)}else{var I=this.Parent._rq.deQueue();var H=I.optional;var F=I.func;H.unshift({Status:-1});F.apply(this.Parent,H);if(!this.Parent._rq.isEmpty()){this.connect(u.GUIDS.AMT,{noPipeline:1})}}});this._amt.on("connect",function D(){this.on("data",function F(H){var I=this.Parent.getCommand(H);var K=this.Parent._rq.deQueue();var J=K.optional;var G=K.func;J.unshift(I);G.apply(this.Parent,J);if(this.Parent._rq.isEmpty()){this.Parent._amt.disconnect();this.Parent._amt=null}else{this.write(this.Parent._rq.peekQueue().send)}});this.write(this.Parent._rq.peekQueue().send)})};function A(D){var E=D.indexOf("\0");if(E>=0){return D.substring(0,E)}else{return D}}this.getCommand=function g(D){var E=D.length==0?(this._rq.peekQueue().cmd|8388608):D.readUInt32LE(4);var F={IsResponse:(E&8388608)==8388608?true:false,Command:(E&8388607),Status:D.length!=0?D.readUInt32LE(12):-1,Data:D.length!=0?D.slice(16):null};return(F)};this.sendCommand=function x(){if(arguments.length<3||typeof(arguments[0])!="number"||typeof(arguments[1])!="object"||typeof(arguments[2])!="function"){throw ("invalid parameters")}var D=[];for(var F=3;F0){M.BiosVersion=M.BiosVersion.substring(0,M.BiosVersion.indexOf("\0"))}K.unshift(M)}else{K.unshift(null)}H.apply(this,K)},D,F)};function C(F,E){if((E==null)&&(typeof(E)!="number")){return null}if(F==null){F=""}var G="";for(var D=0;D0){I.unshift(H.Data.slice(2,2+J).toString())}else{I.unshift(null)}}else{I.unshift(null)}G.apply(this,I)},D,F)};this.getHashHandles=function k(D){var F=[];for(var E=1;E0){this.getCertHashEntry(F.shift(),this._getHashEntrySink,E,G,D,F)}else{G.unshift(D);E.apply(this,G)}};this.getLocalSystemAccount=function m(D){var F=[];for(var E=1;E>24)&255)+"."+((J>>16)&255)+"."+((J>>8)&255)+"."+(J&255);N.unshift(M);K.apply(this,N)}else{N.unshift(null);K.apply(this,N)}},D,I)};this.unprovision=function B(G,D){var H=[];for(var F=2;F=0){b.xxSend(String.fromCharCode(19,0,0,0,4)+IntToStrX(b.user.length+b.authuri.length+8)+String.fromCharCode(b.user.length)+b.user+String.fromCharCode(0,0)+String.fromCharCode(b.authuri.length)+b.authuri+String.fromCharCode(0,0,0,0))}else{if(d.indexOf(3)>=0){b.xxSend(String.fromCharCode(19,0,0,0,3)+IntToStrX(b.user.length+b.authuri.length+7)+String.fromCharCode(b.user.length)+b.user+String.fromCharCode(0,0)+String.fromCharCode(b.authuri.length)+b.authuri+String.fromCharCode(0,0,0))}else{if(d.indexOf(1)>=0){b.xxSend(String.fromCharCode(19,0,0,0,1)+IntToStrX(b.user.length+b.pass.length+2)+String.fromCharCode(b.user.length)+b.user+String.fromCharCode(b.pass.length)+b.pass)}else{b.Stop()}}}}else{if((g==3||g==4)&&y==1){var m=0;var w=e[m];var v=e.slice(m+1,m+1+w).toString();m+=(w+1);if(b.digestRealmMatch&&(b.digestRealmMatch!=v)){b.Stop();return}var r=e[m];var q=e.slice(m+1,m+1+r).toString();m+=(r+1);var u=0;var t=null;var k=b.xxRandomValueHex(32);var x="00000002";var p="";if(g==4){u=e[m];t=e.slice(m+1,m+1+u).toString();m+=(u+1);p=x+":"+k+":"+t+":"}var o=hex_md5(hex_md5(b.user+":"+v+":"+b.pass)+":"+q+":"+p+hex_md5("POST:"+b.authuri));var A=b.user.length+v.length+q.length+b.authuri.length+k.length+x.length+o.length+7;if(g==4){A+=(t.length+1)}var h=Buffer.concat([new Buffer([19,0,0,0,g]),new Buffer([A&255,(A>>8)&255,0,0]),new Buffer([b.user.length]),new Buffer(b.user),new Buffer([v.length]),new Buffer(v),new Buffer([q.length]),new Buffer(q),new Buffer([b.authuri.length]),new Buffer(b.authuri),new Buffer([k.length]),new Buffer(k),new Buffer([x.length]),new Buffer(x),new Buffer([o.length]),new Buffer(o)]);if(g==4){h=Buffer.concat([h,new Buffer([t.length]),new Buffer(t)])}b.xxSend(h)}else{if(y==0){if(b.protocol==1){}if(b.protocol==2){b.xxSend(new Buffer([64,0,0,0,0,0,0,0]))}if(b.protocol==3){b.connectstate=1;b.xxStateChange(3)}}else{b.Stop()}}}break;case 33:if(b.amtaccumulator.length<23){break}j=23;b.xxSend(String.fromCharCode(39,0,0,0)+ToIntStr(b.amtsequence++)+String.fromCharCode(0,0,27,0,0,0));if(b.protocol==1){b.amtkeepalivetimer=setInterval(b.xxSendAmtKeepAlive,2000)}b.connectstate=1;b.xxStateChange(3);break;case 41:if(b.amtaccumulator.length<10){break}j=10;break;case 42:if(b.amtaccumulator.length<10){break}var l=(10+((b.amtaccumulator[9]&255)<<8)+(b.amtaccumulator[8]&255));if(b.amtaccumulator.length8){b.m.ProcessData(b.amtaccumulator.substring(8))}j=b.amtaccumulator.length;break;default:console.log("Unknown Intel AMT command: "+b.amtaccumulator[0]+" acclen="+b.amtaccumulator.length);b.Stop();return}if(j==0){return}if(j==b.amtaccumulator.length){b.amtaccumulator=null}else{b.amtaccumulator=b.amtaccumulator.slice(j)}}};b.xxSend=function(d){if(c&&c.redirtrace){console.log("REDIR-SEND("+d.length+"): "+rstr2hex(d))}if(typeof d=="string"){b.socket.write(new Buffer(d,"binary"))}else{b.socket.write(d)}};b.Send=function(d){if(b.socket==null||b.connectstate!=1){return}if(b.protocol==1){b.xxSend(String.fromCharCode(40,0,0,0)+ToIntStr(b.amtsequence++)+ToShortStr(d.length)+d)}else{b.xxSend(d)}};b.xxSendAmtKeepAlive=function(){if(b.socket==null){return}b.xxSend(String.fromCharCode(43,0,0,0)+ToIntStr(b.amtsequence++))};b.xxRandomValueHex=function(f){var g=[],e=Math.floor(f/2);for(var d=0;d>8)&255),((a>>16)&255),((a>>24)&255))}function ToShortStr(a){return String.fromCharCode((a&255),((a>>8)&255))}function ShortToStr(a){return String.fromCharCode((a>>8)&255,a&255)}function ShortToStrX(a){return String.fromCharCode(a&255,(a>>8)&255)}function IntToStr(a){return String.fromCharCode((a>>24)&255,(a>>16)&255,(a>>8)&255,a&255)}function IntToStrX(a){return String.fromCharCode(a&255,(a>>8)&255,(a>>16)&255,(a>>24)&255)}var md5hasher=require("MD5Stream").create();function hex_md5(b){return md5hasher.syncHash(b).toString("hex").toLowerCase()}; \ No newline at end of file diff --git a/agents/modules_meshcmd_min/amt-scanner.min.js b/agents/modules_meshcmd_min/amt-scanner.min.js new file mode 100644 index 00000000..9b755c70 --- /dev/null +++ b/agents/modules_meshcmd_min/amt-scanner.min.js @@ -0,0 +1 @@ +function AMTScanner(){var a=require("events").inherits(this);a.createEvent("found");this.dgram=require("dgram");this.buildRmcpPing=function(c){var b=Buffer.from("06000006000011BE80000000","hex");b[9]=c;return b};this.parseRmcpPacket=function(h,b,g,d){if(b==null||b.length<20){return}var f={};if(((b[12]==0)||(b[13]!=0)||(b[14]!=1)||(b[15]!=87))&&(b[21]&32)){f.servertag=b[9];f.minorVersion=b[18]&15;f.majorVersion=(b[18]>>4)&15;f.provisioningState=b[19]&3;var e=(b[16]*256)+b[17];var c=((b[19]&4)!=0)?true:false;f.openPorts=[e];f.address=g.address;if(c==true){f.openPorts=[16992,16993]}if(d!==undefined){d(h,f)}}};this.parseIPv4Range=function(f){if(f==undefined||f==null){return null}var g=f.split("-");if(g.length==2){return{min:this.parseIpv4Addr(g[0]),max:this.parseIpv4Addr(g[1])}}g=f.split("/");if(g.length==2){var c=this.parseIpv4Addr(g[0]),e=parseInt(g[1]),d=0;if(e<=16||e>32){return null}e=32-e;for(var b=0;b>24)&255)+"."+((b>>16)&255)+"."+((b>>8)&255)+"."+(b&255)};this.scan=function(d,g){var c=this.parseIPv4Range(d);var e=this.buildRmcpPing(0);var f=this.dgram.createSocket({type:"udp4"});f.parent=this;f.scanResults=[];f.on("error",function(i){console.log("Error:"+i)});f.on("message",function(i,j){if(j.size>4){this.parent.parseRmcpPacket(this,i,j,function(l,k){l.scanResults.push(k)})}});f.on("listening",function(){for(var j=c.min;j<=c.max;j++){f.send(e,623,f.parent.IPv4NumToStr(j))}});f.bind({address:"0.0.0.0",port:0,exclusive:true});var h=setTimeout(function b(){f.close();f.parent.emit("found",f.scanResults);delete f},g)}}module.exports=AMTScanner; \ No newline at end of file diff --git a/agents/modules_meshcmd_min/amt-script.min.js b/agents/modules_meshcmd_min/amt-script.min.js new file mode 100644 index 00000000..62a1a11e --- /dev/null +++ b/agents/modules_meshcmd_min/amt-script.min.js @@ -0,0 +1 @@ +script_functionTable1=["nop","jump","set","print","dialog","getitem","substr","indexof","split","join","length","jsonparse","jsonstr","add","substract","parseint","wsbatchenum","wsput","wscreate","wsdelete","wsexec","scriptspeed","wssubscribe","wsunsubscribe","readchar","signwithdummyca"];script_functionTable2=["encodeuri","decodeuri","passwordcheck","atob","btoa","hex2str","str2hex","random","md5","maketoarray","readshort","readshortx","readint","readsint","readintx","shorttostr","shorttostrx","inttostr","inttostrx"];script_functionTableX2=[encodeURI,decodeURI,passwordcheck,atob,btoa,hex2rstr,rstr2hex,random,rstr_md5,MakeToArray,ReadShort,ReadShortX,ReadInt,ReadSInt,ReadIntX,ShortToStr,ShortToStrX,IntToStr,IntToStrX];function MakeToArray(a){if(!a||a==null||typeof a=="object"){return a}return[a]}function ReadShort(b,a){return(b[a]<<8)+b[a+1]}function ReadShortX(b,a){return(b[a+1]<<8)+b[a]}function ReadInt(b,a){return(b[a]*16777216)+(b[a+1]<<16)+(b[a+2]<<8)+b[a+3]}function ReadSInt(b,a){return(b[a]<<24)+(b[a+1]<<16)+(b[a+2]<<8)+b[a+3]}function ReadIntX(b,a){return(b[a+3]*16777216)+(b[a+2]<<16)+(b[a+1]<<8)+b[a]}function ShortToStr(a){return String.fromCharCode((a>>8)&255,a&255)}function ShortToStrX(a){return String.fromCharCode(a&255,(a>>8)&255)}function IntToStr(a){return String.fromCharCode((a>>24)&255,(a>>16)&255,(a>>8)&255,a&255)}function IntToStrX(a){return String.fromCharCode(a&255,(a>>8)&255,(a>>16)&255,(a>>24)&255)}function btoa(a){return Buffer.from(a).toString("base64")}function atob(b){var c=null;try{c=Buffer.from(b,"base64").toString()}catch(a){console.log(a)}return c}function passwordcheck(g){if(g.length<8){return false}var h=0,d=0,f=0,e=0;for(var b in g){var a=g.charCodeAt(b);if((a>64)&&(a<91)){h=1}else{if((a>96)&&(a<123)){d=1}else{if((a>47)&&(a<58)){f=1}else{e=1}}}}return((h+d+f+e)==4)}function hex2rstr(a){Buffer.from(a,"hex").toString()}function rstr2hex(a){Buffer.from(a).toString("hex")}function random(){return Math.floor(Math.random()*max)}function rstr_md5(a){return hex2rstr(hex_md5(a))}function getItem(b,c,d){for(var a in b){if(b[a][c]==d){return b[a]}}return null}var httpErrorTable={200:"OK",401:"Authentication Error",408:"Timeout Error",601:"WSMAN Parsing Error",602:"Unable to parse HTTP response header",603:"Unexpected HTTP enum response",604:"Unexpected HTTP pull response",998:"Invalid TLS certificate"};module.exports.setup=function(a,c){var b={startvars:c,onCompleted:null};if(a.length<6){console.error("Invalid script length");return null}if(ReadInt(a,0)!=612182341){console.error("Invalid binary script");return null}if(ReadShort(a,4)>1){console.error("Unsupported script version");return null}b.script=a.slice(6);b.reset=function(d){b.stop();b.ip=0;b.variables=c;b.state=1};b.start=function(d){b.stop();if(d==null){b.stepspeed=10}else{b.stepspeed=d}if(b.stepspeed>0){b.timer=setInterval(function(){b.step()},b.stepspeed)}};b.stop=function(){if(b.timer!=null){clearInterval(b.timer)}b.timer=null;b.stepspeed=0};b.getVar=function(d){if(d==undefined){return undefined}return b.getVarEx(d.split("."),b.variables)};b.getVarEx=function(f,g){try{if(f==undefined){return undefined}if(f.length==0){return g}return b.getVarEx(f.slice(1),g[f[0]])}catch(d){return null}};b.setVar=function(d,e){b.setVarEx(d.split("."),b.variables,e)};b.setVarEx=function(d,f,e){if(d.length==1){f[d[0]]=e}else{b.setVarEx(d.slice(1),f[d[0]],e)}};b.step=function(){if(b.state!=1){return}if(b.ip1){var r=l.split("{").pop().split("}").shift();l=l.replace("{"+r+"}",b.getVar(r))}}if(k==1){b.variables["__"+p]=decodeURI(l);l="__"+p}h.push(l)}if(k==2||k==3){b.variables["__"+p]=ReadSInt(l,0);h.push("__"+p)}g+=(2+f)}b.ip+=n;var j=[];for(var p=0;p<10;p++){j.push(b.getVar(h[p]))}var q;try{if(m<10000){switch(m){case 0:break;case 1:if(j[2]){if((j[2]=="<"&&j[1]="&&j[1]>=j[3])||(j[2]==">"&&j[1]>j[3])){b.ip=j[0]}}else{b.ip=j[0]}break;case 2:if(h[1]==undefined){delete b.variables[h[0]]}else{b.setVar(h[0],j[1])}break;case 3:var s=b.toString(j[0]);if(s.indexOf("INFO: ")==0){s=s.substring(6)}if(s.indexOf("SUCCESS: ")==0){s=s.substring(9)}if(b.onConsole){b.onConsole(s,b)}else{console.log(s)}break;case 4:b.state=2;b.dialog=true;setDialogMode(11,j[0],j[2],b.xxStepDialogOk,j[1],b);break;case 5:for(var p in j[1]){if(j[1][p][j[2]]==j[3]){q=p}}break;case 6:q=j[1].substr(j[2],j[3]);break;case 7:q=j[1].indexOf(j[2]);break;case 8:q=j[1].split(j[2]);break;case 9:q=j[1].join(j[2]);break;case 10:if(j[1]==null){q=0}else{q=j[1].length}break;case 11:q=JSON.parse(j[1]);break;case 12:q=JSON.stringify(j[1]);break;case 13:q=(j[1]+j[2]);break;case 14:q=(j[1]-j[2]);break;case 15:q=parseInt(j[1]);break;case 16:b.state=2;b.amtstack.BatchEnum(j[0],j[1],b.xxWsmanReturn,b);break;case 17:b.state=2;b.amtstack.Put(j[0],j[1],b.xxWsmanReturn,b);break;case 18:b.state=2;b.amtstack.Create(j[0],j[1],b.xxWsmanReturn,b);break;case 19:b.state=2;b.amtstack.Delete(j[0],j[1],b.xxWsmanReturn,b);break;case 20:b.state=2;b.amtstack.Exec(j[0],j[1],j[2],b.xxWsmanReturn,b,0,j[3]);break;case 21:b.stepspeed=j[0];if(b.timer!=null){clearInterval(b.timer);b.timer=setInterval(function(){b.step()},b.stepspeed)}break;case 22:b.state=2;b.amtstack.Subscribe(j[0],j[1],j[2],b.xxWsmanReturn,b,0,j[3],j[4],j[5],j[6]);break;case 23:b.state=2;b.amtstack.UnSubscribe(j[0],b.xxWsmanReturn,b,0,j[1]);break;case 24:console.log(j[1],j[2],j[1].charCodeAt(j[2]));q=j[1].charCodeAt(j[2]);break;case 25:break;default:b.state=9;console.error("Script Error, unknown command: "+m)}}else{if(m<20000){q=script_functionTableX2[m-10000](j[1],j[2],j[3],j[4],j[5],j[6])}else{}}if(q!=undefined){b.setVar(h[0],q)}}catch(o){if(typeof o=="object"){o=o.message}b.setVar("_exception",o)}}if(b.state==1&&b.ip>=b.script.length){b.state=0;b.stop();if(b.onCompleted){b.onCompleted()}}if(b.onStep){b.onStep(b)}return b};b.xxStepDialogOk=function(d){b.variables.DialogSelect=d;b.state=1;b.dialog=false;if(b.onStep){b.onStep(b)}};b.xxWsmanReturn=function(f,d,e,g){b.setVar(d,e);b.setVar("wsman_result",g);b.setVar("wsman_result_str",((httpErrorTable[g])?(httpErrorTable[g]):("Error #"+g)));b.state=1;if(b.onStep){b.onStep(b)}};b.toString=function(d){if(typeof d=="object"){return JSON.stringify(d)}return d};b.reset();return b};module.exports.compile=function(o,l){var n="",q=o.split("\n"),h={},k=[],s=[];for(var d in q){var p=q[d];if(p.startsWith("##SWAP ")){var u=p.split(" ");if(u.length==3){s[u[1]]=u[2]}}if(p[0]=="#"||p.length==0){continue}for(var u in s){p=p.split(u).join(s[u])}var f=p.match(/"[^"]*"|[^\s"]+/g);if(f.length==0){continue}if(p[0]==":"){h[f[0].toUpperCase()]=n.length;continue}var c=script_functionTable1.indexOf(f[0].toLowerCase());if(c==-1){c=script_functionTable2.indexOf(f[0].toLowerCase());if(c>=0){c+=10000}}if(c==-1){if(l){l("Unabled to compile, unknown command: "+f[0])}return""}var b=ShortToStr(f.length-1);for(var e in f){if(e==0){continue}if(f[e][0]==":"){k.push([f[e],n.length+b.length+7]);b+=ShortToStr(5)+String.fromCharCode(3)+IntToStr(4294967295)}else{var a=parseInt(f[e]);if(a==f[e]){b+=ShortToStr(5)+String.fromCharCode(2)+IntToStr(a)}else{if(f[e][0]=='"'&&f[e][f[e].length-1]=='"'){b+=ShortToStr(f[e].length-1)+String.fromCharCode(1)+f[e].substring(1,f[e].length-1)}else{b+=ShortToStr(f[e].length+1)+String.fromCharCode(0)+f[e]}}}}b=ShortToStr(c)+ShortToStr(b.length+4)+b;n+=b}for(d in k){var g=k[d][0].toUpperCase(),m=k[d][1],t=h[g];if(t==undefined){if(l){l("Unabled to compile, unknown label: "+g)}return""}n=n.substr(0,m)+IntToStr(t)+n.substr(m+4)}return IntToStr(612182341)+ShortToStr(1)+n};module.exports.decompile=function(g,q){var t="",s=6,m=0,n={};if(q>=0){s=q}else{if(g.length<6){return"# Invalid script length"}var p=ReadInt(g,0);var w=ReadShort(g,4);if(p!=612182341){return"# Invalid binary script: "+p}if(w!=1){return"# Invalid script version"}}while(s=0)){t+=":label"+(s-6)+"\n"}for(var k=0;k=10000)&&(h<10000)){t+=script_functionTable2[h-10000]+d+"\n"}}s+=j;if(q>=0){return t}}var u=t.split("\n");t="";for(var k in u){var o=u[k];if(o[0]!=":"){t+=o+"\n"}else{if(n[o]){t+=o+"\n"}}}return t}; \ No newline at end of file diff --git a/agents/modules_meshcmd_min/amt-wsman-duk.min.js b/agents/modules_meshcmd_min/amt-wsman-duk.min.js new file mode 100644 index 00000000..d83115f4 --- /dev/null +++ b/agents/modules_meshcmd_min/amt-wsman-duk.min.js @@ -0,0 +1 @@ +function CreateWsmanComm(){var a={};a.PendingAjax=[];a.ActiveAjaxCount=0;a.MaxActiveAjaxCount=1;a.FailAllError=0;a.digest=null;a.RequestCount=0;if(arguments.length==1&&typeof(arguments[0]=="object")){a.host=arguments[0].host;a.port=arguments[0].port;a.authToken=arguments[0].authToken;a.tls=arguments[0].tls}else{a.host=arguments[0];a.port=arguments[1];a.user=arguments[2];a.pass=arguments[3];a.tls=arguments[4]}a.PerformAjax=function(d,c,f,e,g,b){if((a.ActiveAjaxCount==0||((a.ActiveAjaxCount=a.MaxActiveAjaxCount||a.PendingAjax.length==0){return}var b=a.PendingAjax.shift();a.PerformAjaxEx(b[0],b[1],b[2],b[3],b[4]);a.PerformNextAjax()};a.PerformAjaxEx=function(d,c,g,h,b){if(a.FailAllError!=0){if(a.FailAllError!=999){a.gotNextMessagesError({status:a.FailAllError},"error",null,[d,c,g])}return}if(!d){d=""}if(globalDebugFlags&1){console.log("SEND: "+d+"\r\n\r\n")}if(a.digest==null){if(a.authToken){a.digest=require("http-digest").create({authToken:a.authToken})}else{a.digest=require("http-digest").create(a.user,a.pass)}a.digest.http=require("http")}var f={protocol:(a.tls==1?"https:":"http:"),method:"POST",host:a.host,path:"/wsman",port:a.port,rejectUnauthorized:false,checkServerIdentity:function(i){console.log("checkServerIdentity",JSON.stringify(i))}};var e=a.digest.request(f);e.on("error",function(i){a.gotNextMessagesError({status:600},"error",null,[d,c,g])});e.on("response",function(i){if(globalDebugFlags&1){console.log("Response: "+i.statusCode)}if(i.statusCode!=200){if(globalDebugFlags&1){console.log("ERR:"+JSON.stringify(i))}a.gotNextMessagesError({status:i.statusCode},"error",null,[d,c,g])}else{i.acc="";i.on("data",function(j){this.acc+=j});i.on("end",function(){a.gotNextMessages(i.acc,"success",{status:i.statusCode},[d,c,g])})}});e.end(d);a.ActiveAjaxCount++;return e};a.pendingAjaxCall=[];a.gotNextMessages=function(c,e,d,b){a.ActiveAjaxCount--;if(a.FailAllError==999){return}if(globalDebugFlags&1){console.log("RECV: "+c+"\r\n\r\n")}if(a.FailAllError!=0){b[1](null,a.FailAllError,b[2]);return}if(d.status!=200){b[1](null,d.status,b[2]);return}b[1](c,200,b[2]);a.PerformNextAjax()};a.gotNextMessagesError=function(d,e,c,b){a.ActiveAjaxCount--;if(a.FailAllError==999){return}if(a.FailAllError!=0){b[1](null,a.FailAllError,b[2]);return}if(a.FailAllError!=999){b[1]({Header:{HttpError:d.status}},d.status,b[2])}a.PerformNextAjax()};a.CancelAllQueries=function(b){while(a.PendingAjax.length>0){var c=a.PendingAjax.shift();c[1](null,b,c[2])}};return a}module.exports=CreateWsmanComm; \ No newline at end of file diff --git a/agents/modules_meshcmd_min/amt-wsman.min.js b/agents/modules_meshcmd_min/amt-wsman.min.js new file mode 100644 index 00000000..e8afb796 --- /dev/null +++ b/agents/modules_meshcmd_min/amt-wsman.min.js @@ -0,0 +1 @@ +function WsmanStackCreateService(){var p={_ObjectID:"WSMAN"};p.NextMessageId=1;p.Address="/wsman";p.xmlParser=require("amt-xml");if(arguments.length==1&&typeof(arguments[0]=="object")){var e=arguments[0].transport;if(e){p.comm=new e(arguments[0])}}else{var e=arguments[0];if(e){p.comm=new e(arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6])}}p.PerformAjax=function q(t,r,v,u,s){if(s==null){s=""}p.comm.PerformAjax('
"+t,function(w,x,y){if(x!=200){r(p,null,{Header:{HttpError:x}},x,y);return}var z=p.xmlParser.ParseWsman(w);if(!z||z==null){r(p,null,{Header:{HttpError:x}},601,y)}else{r(p,z.Header.ResourceURI,z,200,y)}},v,u)};p.CancelAllQueries=function d(r){p.comm.CancelAllQueries(r)};p.GetNameFromUrl=function(r){var s=r.lastIndexOf("/");return(s==-1)?r:r.substring(s+1)};p.ExecSubscribe=function n(z,t,C,r,B,y,A,w,D,x){var u="",v="",w="";if(D!=null&&x!=null){u='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken'+D+''+x+"";v=''}if(w!=null){w=""+w+""}if(t=="PushWithAck"){t="dmtf.org/wbem/wsman/1/wsman/PushWithAck"}else{if(t=="Push"){t="xmlsoap.org/ws/2004/08/eventing/DeliveryModes/Push"}}var s="http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe"+p.Address+""+z+""+(p.NextMessageId++)+"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"+c(A)+u+'
'+C+""+w+""+v+"";p.PerformAjax(s+"
",r,B,y,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:m="http://x.com"')};p.ExecUnSubscribe=function o(u,r,w,t,v){var s="http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe"+p.Address+""+u+""+(p.NextMessageId++)+"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"+c(v)+"";p.PerformAjax(s+"",r,w,t,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"')};p.ExecPut=function m(v,u,r,x,t,w){var s="http://schemas.xmlsoap.org/ws/2004/09/transfer/Put"+p.Address+""+v+""+(p.NextMessageId++)+"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60.000S"+c(w)+""+b(v,u);p.PerformAjax(s+"",r,x,t)};p.ExecCreate=function f(x,w,r,z,v,y){var u=p.GetNameFromUrl(x);var s="http://schemas.xmlsoap.org/ws/2004/09/transfer/Create"+p.Address+""+x+""+(p.NextMessageId++)+"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S"+c(y)+"';for(var t in w){s+=""+w[t]+""}p.PerformAjax(s+"",r,z,v)};p.ExecDelete=function g(v,u,r,w,t){var s="http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete"+p.Address+""+v+""+(p.NextMessageId++)+"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S"+c(u)+"";p.PerformAjax(s,r,w,t)};p.ExecGet=function i(t,r,u,s){p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get"+p.Address+""+t+""+(p.NextMessageId++)+"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S",r,u,s)};p.ExecMethod=function j(y,v,r,t,A,w,z){var s="";for(var u in r){if(r[u]!=null){if(Array.isArray(r[u])){for(var B in r[u]){s+=""+r[u][B]+""}}else{s+=""+r[u]+""}}}p.ExecMethodXml(y,v,s,t,A,w,z)};p.ExecMethodXml=function k(v,t,r,s,x,u,w){p.PerformAjax(v+"/"+t+""+p.Address+""+v+""+(p.NextMessageId++)+"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S"+c(w)+"'+r+"",s,x,u)};p.ExecEnum=function h(t,r,u,s){p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate"+p.Address+""+t+""+(p.NextMessageId++)+'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S',r,u,s)};p.ExecPull=function l(u,s,r,v,t){p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull"+p.Address+""+u+""+(p.NextMessageId++)+'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S'+s+"99999999",r,v,t)};function b(w,u){if(!w||u==null){return""}var s=p.GetNameFromUrl(w);var v="';for(var t in u){if(!u.hasOwnProperty(t)||t.indexOf("__")===0||t.indexOf("@")===0){continue}if(u[t]==null||typeof u[t]==="function"){continue}if(typeof u[t]==="object"&&u[t]["ReferenceParameters"]){v+=""+u[t].Address+""+u[t]["ReferenceParameters"]["ResourceURI"]+"";var x=u[t]["ReferenceParameters"]["SelectorSet"]["Selector"];if(Array.isArray(x)){for(var r=0;r"+x[r]["Value"]+""}}else{v+=""+x.Value+""}v+=""}else{if(Array.isArray(u[t])){for(var r=0;r"+u[t][r].toString()+""}}else{v+=""+u[t].toString()+""}}}v+="";return v}function a(r){if(!r){return""}var t=" ";for(var s in r){if(!r.hasOwnProperty(s)||s.indexOf("@")!==0){continue}t+=s.substring(1)+'="'+r[s]+'" '}return t}function c(v){if((v==null)||(v=="null")){return""}if(typeof v=="string"){return v}if(v.InstanceID){return''+v.InstanceID+""}var t="";for(var s in v){if(!v.hasOwnProperty(s)){continue}t+='';if(v[s]["ReferenceParameters"]){t+="";t+=""+v[s]["Address"]+""+v[s]["ReferenceParameters"]["ResourceURI"]+"";var u=v[s]["ReferenceParameters"]["SelectorSet"]["Selector"];if(Array.isArray(u)){for(var r=0;r"+u[r]["Value"]+""}}else{t+=""+u.Value+""}t+=""}else{t+=v[s]}t+=""}t+="";return t}return p}module.exports=WsmanStackCreateService; \ No newline at end of file diff --git a/agents/modules_meshcmd_min/amt-xml.min.js b/agents/modules_meshcmd_min/amt-xml.min.js new file mode 100644 index 00000000..4b2308ed --- /dev/null +++ b/agents/modules_meshcmd_min/amt-xml.min.js @@ -0,0 +1 @@ +try{Object.defineProperty(Array.prototype,"peek",{value:function(){return(this.length>0?this[this.length-1]:undefined)}})}catch(e){}module.exports.ParseWsman=function(j){try{if(!j.childNodes){j=_turnToXml(j)}var g={Header:{}},d=j.getElementsByTagName("Header")[0],h;if(!d){d=j.getElementsByTagName("a:Header")[0]}if(!d){return null}for(var f=0;f0){h=a.childNodes[0].localName;if(h.indexOf("_OUTPUT")==h.length-7){h=h.substring(0,h.length-7)}g.Header.Method=h;g.Body=_ParseWsmanRec(a.childNodes[0])}return g}catch(c){console.error("Unable to parse XML: "+j,c);return null}};function _ParseWsmanRec(g){var c,h={};for(var d=0;d0)){b={Value:c};for(var f=0;f';for(var c in d){if(!d.hasOwnProperty(c)||c.indexOf("__")===0||c.indexOf("@")===0){continue}if(d[c]==null||typeof d[c]==="function"){continue}if(typeof d[c]==="object"&&d[c]["ReferenceParameters"]){f+=""+d[c].Address+""+d[c]["ReferenceParameters"]["ResourceURI"]+"";var h=d[c]["ReferenceParameters"]["SelectorSet"]["Selector"];if(Array.isArray(h)){for(var a=0;a"+h[a]["Value"]+""}}else{f+=""+h.Value+""}f+=""}else{if(Array.isArray(d[c])){for(var a=0;a"+d[c][a].toString()+""}}else{f+=""+d[c].toString()+""}}}f+="";return f}function _treeBuilder(){this.tree=[];this.push=function(a){this.tree.push(a)};this.pop=function(){var a=this.tree.pop();if(this.tree.length>0){var b=this.tree.peek();b.childNodes.push(a);b.childElementCount=b.childNodes.length}return(a)};this.peek=function(){return(this.tree.peek())};this.addNamespace=function(g,d){this.tree.peek().nsTable[g]=d;if(this.tree.peek().attributes.length>0){for(var c=0;c=0;--a){if(this.tree[a].nsTable[b]!=null){return(this.tree[a].nsTable[b])}}return null}}function _turnToXml(a){if(a==null){return null}return({childNodes:[_turnToXmlRec(a)],getElementsByTagName:_getElementsByTagName,getChildElementsByTagName:_getChildElementsByTagName,getElementsByTagNameNS:_getElementsByTagNameNS})}function _getElementsByTagNameNS(b,a){var c=[];_xmlTraverseAllRec(this.childNodes,function(d){if(d.localName==a&&(d.namespace==b||b=="*")){c.push(d)}});return c}function _getElementsByTagName(a){var b=[];_xmlTraverseAllRec(this.childNodes,function(c){if(c.localName==a){b.push(c)}});return b}function _getChildElementsByTagName(a){var c=[];if(this.childNodes!=null){for(var b in this.childNodes){if(this.childNodes[b].localName==a){c.push(this.childNodes[b])}}}return(c)}function _getChildElementsByTagNameNS(c,a){var d=[];if(this.childNodes!=null){for(var b in this.childNodes){if(this.childNodes[b].localName==a&&(c=="*"||this.childNodes[b].namespace==c)){d.push(this.childNodes[b])}}}return(d)}function _xmlTraverseAllRec(c,a){for(var b in c){a(c[b]);if(c[b].childNodes){_xmlTraverseAllRec(c[b].childNodes,a)}}}function _turnToXmlRec(w){try{if(w==null){return null}var m=new _treeBuilder(),r=null,z=w.split("<"),u=[],h=null,g=null;for(var o in z){var A=z[o].split(">"),B=A[0].split(" "),l=B[0];if((l.length>0)&&(l[0]!="?")){if(l[0]!="/"){var a=[],s,t=l.split(" ")[0].split(":"),s=(t.length>1)?t[1]:t[0];Object.defineProperty(a,"get",{value:function(){if(arguments.length==1){for(var i in this){if(this[i].name==arguments[0]){return(this[i])}}}else{if(arguments.length==2){for(var i in this){if(this[i].name==arguments[1]&&(arguments[0]=="*"||this[i].namespace==arguments[0])){return(this[i])}}}else{throw ("attributes.get(): Invalid number of parameters")}}}});m.push({name:l,localName:s,getChildElementsByTagName:_getChildElementsByTagName,getElementsByTagNameNS:_getElementsByTagNameNS,getChildElementsByTagNameNS:_getChildElementsByTagNameNS,attributes:a,childNodes:[],nsTable:{}});if(B.length>0){var v=false;for(var p in B){if(B[p]=="/"){m.peek().namespace=m.peek().name==m.peek().localName?m.getNamespace("*"):m.getNamespace(m.peek().name.substring(0,m.peek().name.indexOf(":")));m.peek().textContent="";r=m.pop();v=true;break}var q=B[p].indexOf("=");if(q>0){var b=B[p].substring(0,q);var d=B[p].substring(q+2,B[p].length-1);var c=m.getNamespace("*");if(b=="xmlns"){m.addNamespace("*",d);c=d}else{if(b.startsWith("xmlns:")){m.addNamespace(b.substring(6),d)}else{var f=b.split(":");if(f.length==2){b=f[1];c=m.getNamespace(f[0])}}}var y={name:b,value:d};if(c!=null){y.namespace=c}m.peek().attributes.push(y)}}if(v){continue}}m.peek().namespace=m.peek().name==m.peek().localName?m.getNamespace("*"):m.getNamespace(m.peek().name.substring(0,m.peek().name.indexOf(":")));if(A[1]){m.peek().textContent=A[1]}}else{r=m.pop()}}}}catch(n){return null}return r}; \ No newline at end of file diff --git a/agents/modules_meshcmd_min/amt.min.js b/agents/modules_meshcmd_min/amt.min.js new file mode 100644 index 00000000..6984729b --- /dev/null +++ b/agents/modules_meshcmd_min/amt.min.js @@ -0,0 +1 @@ +function AmtStackCreateService(R){var J=new Object();J._ObjectID="AMT";J.wsman=R;J.pfx=["http://intel.com/wbem/wscim/1/amt-schema/1/","http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/","http://intel.com/wbem/wscim/1/ips-schema/1/"];J.PendingEnums=[];J.PendingBatchOperations=0;J.ActiveEnumsCount=0;J.MaxActiveEnumsCount=1;J.onProcessChanged=null;var n=0;var m=0;J.GetPendingActions=function(){return(J.PendingEnums.length*2)+(J.ActiveEnumsCount)+J.wsman.comm.PendingAjax.length+J.wsman.comm.ActiveAjaxCount+J.PendingBatchOperations};function r(){var S=J.GetPendingActions();if(n=J.MaxActiveEnumsCount||J.PendingEnums.length==0){return}var T=J.PendingEnums.shift();J.Enum(T[0],T[1],T[2]);d(0)}J.BatchEnum=function(S,V,T,X,U,W){J.PendingBatchOperations+=(V.length*2);b(S,x(V),T,X,{},U,W);r()};function x(S){return JSON.parse(JSON.stringify(S))}function b(S,X,T,aa,Z,U,Y){J.PendingBatchOperations-=2;var W=X.shift(),V=J.Enum;if(W[0]=="*"){V=J.Get;W=W.substring(1)}V(W,function(ad,ab,ac,ae,af){af[2][ab]={response:(ac==null?null:ac.Body),responses:ac,status:ae};if(af[1].length==0||ae==401||(U!=true&&ae!=200&&ae!=400)){J.PendingBatchOperations-=(X.length*2);r();T.call(J,J,S,af[2],ae,aa)}else{r();b(S,X,T,aa,af[2],Y)}},[S,X,Z],Y);r()}J.BatchGet=function(S,U,T,W,V){h({name:S,names:U,callback:T,current:0,responses:{},tag:W,pri:V});r()};function h(S){if(S.names.length<=S.current){S.callback.call(J,J,S.name,S.responses,200,S.tag)}else{J.wsman.ExecGet(J.CompleteName(S.names[S.current]),function(V,U,T,W){g(S,T,W)},S.pri);S.current++}r()}function g(S,T,U){if(T==null||U!=200){S.callback.call(J,J,S.name,null,U,S.tag)}else{S.responses[T.Header.Method]=T;h(S)}}J.CompleteName=function(S){if(S.indexOf("AMT_")==0){return J.pfx[0]+S}if(S.indexOf("CIM_")==0){return J.pfx[1]+S}if(S.indexOf("IPS_")==0){return J.pfx[2]+S}};J.CompleteExecResponse=function(S){if(S&&S!=null&&S.Body&&(S.Body.ReturnValue!=undefined)){S.Body.ReturnValueStr=J.AmtStatusToStr(S.Body.ReturnValue)}return S};J.RequestPowerStateChange=function(T,S){J.CIM_PowerManagementService_RequestPowerStateChange(T,'
http://schemas.xmlsoap.org/ws/2004/08/addressing
http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ComputerSystemCIM_ComputerSystemManagedSystem',null,null,S)};J.SetBootConfigRole=function(T,S){J.CIM_BootService_SetBootConfigRole('
http://schemas.xmlsoap.org/ws/2004/08/addressing
http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_BootConfigSettingIntel(r) AMT: Boot Configuration 0',T,S)};J.CancelAllQueries=function(S){J.wsman.CancelAllQueries(S)};J.AMT_AgentPresenceWatchdog_RegisterAgent=function(S,V,T,U){J.Exec("AMT_AgentPresenceWatchdog","RegisterAgent",{},S,V,T,U)};J.AMT_AgentPresenceWatchdog_AssertPresence=function(V,S,W,T,U){J.Exec("AMT_AgentPresenceWatchdog","AssertPresence",{SequenceNumber:V},S,W,T,U)};J.AMT_AgentPresenceWatchdog_AssertShutdown=function(V,S,W,T,U){J.Exec("AMT_AgentPresenceWatchdog","AssertShutdown",{SequenceNumber:V},S,W,T,U)};J.AMT_AgentPresenceWatchdog_AddAction=function(X,W,V,T,S,U,aa,Y,Z){J.Exec("AMT_AgentPresenceWatchdog","AddAction",{OldState:X,NewState:W,EventOnTransition:V,ActionSd:T,ActionEac:S},U,aa,Y,Z)};J.AMT_AgentPresenceWatchdog_DeleteAllActions=function(S,V,T,U){J.Exec("AMT_AgentPresenceWatchdog","DeleteAllActions",{},S,V,T,U)};J.AMT_AgentPresenceWatchdogAction_GetActionEac=function(S){J.Exec("AMT_AgentPresenceWatchdogAction","GetActionEac",{},S)};J.AMT_AgentPresenceWatchdogVA_RegisterAgent=function(S){J.Exec("AMT_AgentPresenceWatchdogVA","RegisterAgent",{},S)};J.AMT_AgentPresenceWatchdogVA_AssertPresence=function(T,S){J.Exec("AMT_AgentPresenceWatchdogVA","AssertPresence",{SequenceNumber:T},S)};J.AMT_AgentPresenceWatchdogVA_AssertShutdown=function(T,S){J.Exec("AMT_AgentPresenceWatchdogVA","AssertShutdown",{SequenceNumber:T},S)};J.AMT_AgentPresenceWatchdogVA_AddAction=function(X,W,V,T,S,U){J.Exec("AMT_AgentPresenceWatchdogVA","AddAction",{OldState:X,NewState:W,EventOnTransition:V,ActionSd:T,ActionEac:S},U)};J.AMT_AgentPresenceWatchdogVA_DeleteAllActions=function(S,T){J.Exec("AMT_AgentPresenceWatchdogVA","DeleteAllActions",{_method_dummy:S},T)};J.AMT_AlarmClockService_AddAlarm=function s(S,T){var V=S.InstanceID;var X=S.ElementName;var Y=S.StartTime.Datetime;var W=S.Interval?S.Interval.Datetime:undefined;var U=S.DeleteOnCompletion;var Z=''+V+""+X+''+Y+""+((W!=undefined)?(''+W+""):"")+""+U+"";J.wsman.ExecMethodXml(J.CompleteName("AMT_AlarmClockService"),"AddAlarm",Z,T)};J.AMT_AuditLog_ClearLog=function(S){J.Exec("AMT_AuditLog","ClearLog",{},S)};J.AMT_AuditLog_RequestStateChange=function(T,U,S){J.Exec("AMT_AuditLog","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.AMT_AuditLog_ReadRecords=function(T,S,U){J.Exec("AMT_AuditLog","ReadRecords",{StartIndex:T},S,U)};J.AMT_AuditLog_SetAuditLock=function(V,T,U,S){J.Exec("AMT_AuditLog","SetAuditLock",{LockTimeoutInSeconds:V,Flag:T,Handle:U},S)};J.AMT_AuditLog_ExportAuditLogSignature=function(T,S){J.Exec("AMT_AuditLog","ExportAuditLogSignature",{SigningMechanism:T},S)};J.AMT_AuditLog_SetSigningKeyMaterial=function(W,V,U,T,S){J.Exec("AMT_AuditLog","SetSigningKeyMaterial",{SigningMechanismType:W,SigningKey:V,LengthOfCertificates:U,Certificates:T},S)};J.AMT_AuditPolicyRule_SetAuditPolicy=function(U,S,V,W,T){J.Exec("AMT_AuditPolicyRule","SetAuditPolicy",{Enable:U,AuditedAppID:S,EventID:V,PolicyType:W},T)};J.AMT_AuditPolicyRule_SetAuditPolicyBulk=function(U,S,V,W,T){J.Exec("AMT_AuditPolicyRule","SetAuditPolicyBulk",{Enable:U,AuditedAppID:S,EventID:V,PolicyType:W},T)};J.AMT_AuthorizationService_AddUserAclEntryEx=function(V,U,W,S,X,T){J.Exec("AMT_AuthorizationService","AddUserAclEntryEx",{DigestUsername:V,DigestPassword:U,KerberosUserSid:W,AccessPermission:S,Realms:X},T)};J.AMT_AuthorizationService_EnumerateUserAclEntries=function(T,S){J.Exec("AMT_AuthorizationService","EnumerateUserAclEntries",{StartIndex:T},S)};J.AMT_AuthorizationService_GetUserAclEntryEx=function(T,S,U){J.Exec("AMT_AuthorizationService","GetUserAclEntryEx",{Handle:T},S,U)};J.AMT_AuthorizationService_UpdateUserAclEntryEx=function(W,V,U,X,S,Y,T){J.Exec("AMT_AuthorizationService","UpdateUserAclEntryEx",{Handle:W,DigestUsername:V,DigestPassword:U,KerberosUserSid:X,AccessPermission:S,Realms:Y},T)};J.AMT_AuthorizationService_RemoveUserAclEntry=function(T,S){J.Exec("AMT_AuthorizationService","RemoveUserAclEntry",{Handle:T},S)};J.AMT_AuthorizationService_SetAdminAclEntryEx=function(U,T,S){J.Exec("AMT_AuthorizationService","SetAdminAclEntryEx",{Username:U,DigestPassword:T},S)};J.AMT_AuthorizationService_GetAdminAclEntry=function(S){J.Exec("AMT_AuthorizationService","GetAdminAclEntry",{},S)};J.AMT_AuthorizationService_GetAdminAclEntryStatus=function(S){J.Exec("AMT_AuthorizationService","GetAdminAclEntryStatus",{},S)};J.AMT_AuthorizationService_GetAdminNetAclEntryStatus=function(S){J.Exec("AMT_AuthorizationService","GetAdminNetAclEntryStatus",{},S)};J.AMT_AuthorizationService_SetAclEnabledState=function(U,T,S,V){J.Exec("AMT_AuthorizationService","SetAclEnabledState",{Handle:U,Enabled:T},S,V)};J.AMT_AuthorizationService_GetAclEnabledState=function(T,S,U){J.Exec("AMT_AuthorizationService","GetAclEnabledState",{Handle:T},S,U)};J.AMT_EndpointAccessControlService_RequestStateChange=function(T,U,S){J.Exec("AMT_EndpointAccessControlService","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.AMT_EndpointAccessControlService_GetPosture=function(T,S){J.Exec("AMT_EndpointAccessControlService","GetPosture",{PostureType:T},S)};J.AMT_EndpointAccessControlService_GetPostureHash=function(T,S){J.Exec("AMT_EndpointAccessControlService","GetPostureHash",{PostureType:T},S)};J.AMT_EndpointAccessControlService_UpdatePostureState=function(T,S){J.Exec("AMT_EndpointAccessControlService","UpdatePostureState",{UpdateType:T},S)};J.AMT_EndpointAccessControlService_GetEacOptions=function(S){J.Exec("AMT_EndpointAccessControlService","GetEacOptions",{},S)};J.AMT_EndpointAccessControlService_SetEacOptions=function(T,U,S){J.Exec("AMT_EndpointAccessControlService","SetEacOptions",{EacVendors:T,PostureHashAlgorithm:U},S)};J.AMT_EnvironmentDetectionSettingData_SetSystemDefensePolicy=function(T,S){J.Exec("AMT_EnvironmentDetectionSettingData","SetSystemDefensePolicy",{Policy:T},S)};J.AMT_EnvironmentDetectionSettingData_EnableVpnRouting=function(T,S){J.Exec("AMT_EnvironmentDetectionSettingData","EnableVpnRouting",{Enable:T},S)};J.AMT_EthernetPortSettings_SetLinkPreference=function(T,U,S){J.Exec("AMT_EthernetPortSettings","SetLinkPreference",{LinkPreference:T,Timeout:U},S)};J.AMT_HeuristicPacketFilterStatistics_ResetSelectedStats=function(T,S){J.Exec("AMT_HeuristicPacketFilterStatistics","ResetSelectedStats",{SelectedStatistics:T},S)};J.AMT_KerberosSettingData_GetCredentialCacheState=function(S){J.Exec("AMT_KerberosSettingData","GetCredentialCacheState",{},S)};J.AMT_KerberosSettingData_SetCredentialCacheState=function(T,S){J.Exec("AMT_KerberosSettingData","SetCredentialCacheState",{Enable:T},S)};J.AMT_MessageLog_CancelIteration=function(T,S){J.Exec("AMT_MessageLog","CancelIteration",{IterationIdentifier:T},S)};J.AMT_MessageLog_RequestStateChange=function(T,U,S){J.Exec("AMT_MessageLog","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.AMT_MessageLog_ClearLog=function(S){J.Exec("AMT_MessageLog","ClearLog",{},S)};J.AMT_MessageLog_GetRecords=function(T,U,S,V){J.Exec("AMT_MessageLog","GetRecords",{IterationIdentifier:T,MaxReadRecords:U},S,V)};J.AMT_MessageLog_GetRecord=function(T,U,S){J.Exec("AMT_MessageLog","GetRecord",{IterationIdentifier:T,PositionToNext:U},S)};J.AMT_MessageLog_PositionAtRecord=function(T,U,V,S){J.Exec("AMT_MessageLog","PositionAtRecord",{IterationIdentifier:T,MoveAbsolute:U,RecordNumber:V},S)};J.AMT_MessageLog_PositionToFirstRecord=function(S,T){J.Exec("AMT_MessageLog","PositionToFirstRecord",{},S,T)};J.AMT_MessageLog_FreezeLog=function(T,S){J.Exec("AMT_MessageLog","FreezeLog",{Freeze:T},S)};J.AMT_PublicKeyManagementService_AddCRL=function(U,T,S){J.Exec("AMT_PublicKeyManagementService","AddCRL",{Url:U,SerialNumbers:T},S)};J.AMT_PublicKeyManagementService_ResetCRLList=function(S,T){J.Exec("AMT_PublicKeyManagementService","ResetCRLList",{_method_dummy:S},T)};J.AMT_PublicKeyManagementService_AddCertificate=function(T,S,U){J.Exec("AMT_PublicKeyManagementService","AddCertificate",{CertificateBlob:T},S,U)};J.AMT_PublicKeyManagementService_AddTrustedRootCertificate=function(T,S){J.Exec("AMT_PublicKeyManagementService","AddTrustedRootCertificate",{CertificateBlob:T},S)};J.AMT_PublicKeyManagementService_AddKey=function(T,S){J.Exec("AMT_PublicKeyManagementService","AddKey",{KeyBlob:T},S)};J.AMT_PublicKeyManagementService_GeneratePKCS10Request=function(U,T,V,S){J.Exec("AMT_PublicKeyManagementService","GeneratePKCS10Request",{KeyPair:U,DNName:T,Usage:V},S)};J.AMT_PublicKeyManagementService_GeneratePKCS10RequestEx=function(T,V,U,S){J.Exec("AMT_PublicKeyManagementService","GeneratePKCS10RequestEx",{KeyPair:T,SigningAlgorithm:V,NullSignedCertificateRequest:U},S)};J.AMT_PublicKeyManagementService_GenerateKeyPair=function(T,U,S){J.Exec("AMT_PublicKeyManagementService","GenerateKeyPair",{KeyAlgorithm:T,KeyLength:U},S)};J.AMT_RedirectionService_RequestStateChange=function(T,S){J.Exec("AMT_RedirectionService","RequestStateChange",{RequestedState:T},S)};J.AMT_RedirectionService_TerminateSession=function(T,S){J.Exec("AMT_RedirectionService","TerminateSession",{SessionType:T},S)};J.AMT_RemoteAccessService_AddMpServer=function(S,X,Z,T,V,aa,Y,W,U){J.Exec("AMT_RemoteAccessService","AddMpServer",{AccessInfo:S,InfoFormat:X,Port:Z,AuthMethod:T,Certificate:V,Username:aa,Password:Y,CN:W},U)};J.AMT_RemoteAccessService_AddRemoteAccessPolicyRule=function(V,W,T,U,S){J.Exec("AMT_RemoteAccessService","AddRemoteAccessPolicyRule",{Trigger:V,TunnelLifeTime:W,ExtendedData:T,MpServer:U},S)};J.AMT_RemoteAccessService_CloseRemoteAccessConnection=function(S,T){J.Exec("AMT_RemoteAccessService","CloseRemoteAccessConnection",{_method_dummy:S},T)};J.AMT_SetupAndConfigurationService_CommitChanges=function(S,T,U){J.Exec("AMT_SetupAndConfigurationService","CommitChanges",{_method_dummy:S},T,U)};J.AMT_SetupAndConfigurationService_Unprovision=function(T,S){J.Exec("AMT_SetupAndConfigurationService","Unprovision",{ProvisioningMode:T},S)};J.AMT_SetupAndConfigurationService_PartialUnprovision=function(S,T){J.Exec("AMT_SetupAndConfigurationService","PartialUnprovision",{_method_dummy:S},T)};J.AMT_SetupAndConfigurationService_ResetFlashWearOutProtection=function(S,T){J.Exec("AMT_SetupAndConfigurationService","ResetFlashWearOutProtection",{_method_dummy:S},T)};J.AMT_SetupAndConfigurationService_ExtendProvisioningPeriod=function(T,S){J.Exec("AMT_SetupAndConfigurationService","ExtendProvisioningPeriod",{Duration:T},S)};J.AMT_SetupAndConfigurationService_SetMEBxPassword=function(T,S){J.Exec("AMT_SetupAndConfigurationService","SetMEBxPassword",{Password:T},S)};J.AMT_SetupAndConfigurationService_SetTLSPSK=function(T,U,S){J.Exec("AMT_SetupAndConfigurationService","SetTLSPSK",{PID:T,PPS:U},S)};J.AMT_SetupAndConfigurationService_GetProvisioningAuditRecord=function(S){J.Exec("AMT_SetupAndConfigurationService","GetProvisioningAuditRecord",{},S)};J.AMT_SetupAndConfigurationService_GetUuid=function(S){J.Exec("AMT_SetupAndConfigurationService","GetUuid",{},S)};J.AMT_SetupAndConfigurationService_GetUnprovisionBlockingComponents=function(S){J.Exec("AMT_SetupAndConfigurationService","GetUnprovisionBlockingComponents",{},S)};J.AMT_SetupAndConfigurationService_GetProvisioningAuditRecordV2=function(S){J.Exec("AMT_SetupAndConfigurationService","GetProvisioningAuditRecordV2",{},S)};J.AMT_SystemDefensePolicy_GetTimeout=function(S){J.Exec("AMT_SystemDefensePolicy","GetTimeout",{},S)};J.AMT_SystemDefensePolicy_SetTimeout=function(T,S){J.Exec("AMT_SystemDefensePolicy","SetTimeout",{Timeout:T},S)};J.AMT_SystemDefensePolicy_UpdateStatistics=function(T,V,S,X,U,W){J.Exec("AMT_SystemDefensePolicy","UpdateStatistics",{NetworkInterface:T,ResetOnRead:V},S,X,U,W)};J.AMT_SystemPowerScheme_SetPowerScheme=function(S,T,U){J.Exec("AMT_SystemPowerScheme","SetPowerScheme",{},S,U,0,{InstanceID:T})};J.AMT_TimeSynchronizationService_GetLowAccuracyTimeSynch=function(S,T){J.Exec("AMT_TimeSynchronizationService","GetLowAccuracyTimeSynch",{},S,T)};J.AMT_TimeSynchronizationService_SetHighAccuracyTimeSynch=function(T,V,W,S,U){J.Exec("AMT_TimeSynchronizationService","SetHighAccuracyTimeSynch",{Ta0:T,Tm1:V,Tm2:W},S,U)};J.AMT_TLSCredentialContext_Create=function t(T,U,S,V){J.Create("AMT_TLSCredentialContext",{ElementInContext:T,ElementProvidingContext:U},S,V)};J.AMT_UserInitiatedConnectionService_RequestStateChange=function(T,U,S){J.Exec("AMT_UserInitiatedConnectionService","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.AMT_WebUIService_RequestStateChange=function(T,V,S,U){J.Exec("AMT_WebUIService","RequestStateChange",{RequestedState:T,TimeoutPeriod:V},S,U)};J.AMT_WiFiPortConfigurationService_AddWiFiSettings=function(W,X,V,U,S,T){J.ExecWithXml("AMT_WiFiPortConfigurationService","AddWiFiSettings",{WiFiEndpoint:W,WiFiEndpointSettingsInput:X,IEEE8021xSettingsInput:V,ClientCredential:U,CACredential:S},T)};J.AMT_WiFiPortConfigurationService_UpdateWiFiSettings=function(W,X,V,U,S,T){J.ExecWithXml("AMT_WiFiPortConfigurationService","UpdateWiFiSettings",{WiFiEndpointSettings:W,WiFiEndpointSettingsInput:X,IEEE8021xSettingsInput:V,ClientCredential:U,CACredential:S},T)};J.AMT_WiFiPortConfigurationService_DeleteAllITProfiles=function(S,T){J.Exec("AMT_WiFiPortConfigurationService","DeleteAllITProfiles",{_method_dummy:S},T)};J.AMT_WiFiPortConfigurationService_DeleteAllUserProfiles=function(S,T){J.Exec("AMT_WiFiPortConfigurationService","DeleteAllUserProfiles",{_method_dummy:S},T)};J.CIM_Account_RequestStateChange=function(T,U,S){J.Exec("CIM_Account","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_AccountManagementService_CreateAccount=function(U,S,T){J.Exec("CIM_AccountManagementService","CreateAccount",{System:U,AccountTemplate:S},T)};J.CIM_BootConfigSetting_ChangeBootOrder=function(T,S){J.Exec("CIM_BootConfigSetting","ChangeBootOrder",{Source:T},S)};J.CIM_BootService_SetBootConfigRole=function(S,U,T){J.Exec("CIM_BootService","SetBootConfigRole",{BootConfigSetting:S,Role:U},T,0,1)};J.CIM_Card_ConnectorPower=function(T,U,S){J.Exec("CIM_Card","ConnectorPower",{Connector:T,PoweredOn:U},S)};J.CIM_Card_IsCompatible=function(T,S){J.Exec("CIM_Card","IsCompatible",{ElementToCheck:T},S)};J.CIM_Chassis_IsCompatible=function(T,S){J.Exec("CIM_Chassis","IsCompatible",{ElementToCheck:T},S)};J.CIM_Fan_SetSpeed=function(T,S){J.Exec("CIM_Fan","SetSpeed",{DesiredSpeed:T},S)};J.CIM_KVMRedirectionSAP_RequestStateChange=function(T,U,S){J.Exec("CIM_KVMRedirectionSAP","RequestStateChange",{RequestedState:T},S)};J.CIM_MediaAccessDevice_LockMedia=function(T,S){J.Exec("CIM_MediaAccessDevice","LockMedia",{Lock:T},S)};J.CIM_MediaAccessDevice_SetPowerState=function(T,U,S){J.Exec("CIM_MediaAccessDevice","SetPowerState",{PowerState:T,Time:U},S)};J.CIM_MediaAccessDevice_Reset=function(S){J.Exec("CIM_MediaAccessDevice","Reset",{},S)};J.CIM_MediaAccessDevice_EnableDevice=function(T,S){J.Exec("CIM_MediaAccessDevice","EnableDevice",{Enabled:T},S)};J.CIM_MediaAccessDevice_OnlineDevice=function(T,S){J.Exec("CIM_MediaAccessDevice","OnlineDevice",{Online:T},S)};J.CIM_MediaAccessDevice_QuiesceDevice=function(T,S){J.Exec("CIM_MediaAccessDevice","QuiesceDevice",{Quiesce:T},S)};J.CIM_MediaAccessDevice_SaveProperties=function(S){J.Exec("CIM_MediaAccessDevice","SaveProperties",{},S)};J.CIM_MediaAccessDevice_RestoreProperties=function(S){J.Exec("CIM_MediaAccessDevice","RestoreProperties",{},S)};J.CIM_MediaAccessDevice_RequestStateChange=function(T,U,S){J.Exec("CIM_MediaAccessDevice","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_PhysicalFrame_IsCompatible=function(T,S){J.Exec("CIM_PhysicalFrame","IsCompatible",{ElementToCheck:T},S)};J.CIM_PhysicalPackage_IsCompatible=function(T,S){J.Exec("CIM_PhysicalPackage","IsCompatible",{ElementToCheck:T},S)};J.CIM_PowerManagementService_RequestPowerStateChange=function(U,T,V,W,S){J.Exec("CIM_PowerManagementService","RequestPowerStateChange",{PowerState:U,ManagedElement:T,Time:V,TimeoutPeriod:W},S,0,1)};J.CIM_PowerSupply_SetPowerState=function(T,U,S){J.Exec("CIM_PowerSupply","SetPowerState",{PowerState:T,Time:U},S)};J.CIM_PowerSupply_Reset=function(S){J.Exec("CIM_PowerSupply","Reset",{},S)};J.CIM_PowerSupply_EnableDevice=function(T,S){J.Exec("CIM_PowerSupply","EnableDevice",{Enabled:T},S)};J.CIM_PowerSupply_OnlineDevice=function(T,S){J.Exec("CIM_PowerSupply","OnlineDevice",{Online:T},S)};J.CIM_PowerSupply_QuiesceDevice=function(T,S){J.Exec("CIM_PowerSupply","QuiesceDevice",{Quiesce:T},S)};J.CIM_PowerSupply_SaveProperties=function(S){J.Exec("CIM_PowerSupply","SaveProperties",{},S)};J.CIM_PowerSupply_RestoreProperties=function(S){J.Exec("CIM_PowerSupply","RestoreProperties",{},S)};J.CIM_PowerSupply_RequestStateChange=function(T,U,S){J.Exec("CIM_PowerSupply","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_Processor_SetPowerState=function(T,U,S){J.Exec("CIM_Processor","SetPowerState",{PowerState:T,Time:U},S)};J.CIM_Processor_Reset=function(S){J.Exec("CIM_Processor","Reset",{},S)};J.CIM_Processor_EnableDevice=function(T,S){J.Exec("CIM_Processor","EnableDevice",{Enabled:T},S)};J.CIM_Processor_OnlineDevice=function(T,S){J.Exec("CIM_Processor","OnlineDevice",{Online:T},S)};J.CIM_Processor_QuiesceDevice=function(T,S){J.Exec("CIM_Processor","QuiesceDevice",{Quiesce:T},S)};J.CIM_Processor_SaveProperties=function(S){J.Exec("CIM_Processor","SaveProperties",{},S)};J.CIM_Processor_RestoreProperties=function(S){J.Exec("CIM_Processor","RestoreProperties",{},S)};J.CIM_Processor_RequestStateChange=function(T,U,S){J.Exec("CIM_Processor","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_RecordLog_ClearLog=function(S){J.Exec("CIM_RecordLog","ClearLog",{},S)};J.CIM_RecordLog_RequestStateChange=function(T,U,S){J.Exec("CIM_RecordLog","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_RedirectionService_RequestStateChange=function(T,U,S){J.Exec("CIM_RedirectionService","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_Sensor_SetPowerState=function(T,U,S){J.Exec("CIM_Sensor","SetPowerState",{PowerState:T,Time:U},S)};J.CIM_Sensor_Reset=function(S){J.Exec("CIM_Sensor","Reset",{},S)};J.CIM_Sensor_EnableDevice=function(T,S){J.Exec("CIM_Sensor","EnableDevice",{Enabled:T},S)};J.CIM_Sensor_OnlineDevice=function(T,S){J.Exec("CIM_Sensor","OnlineDevice",{Online:T},S)};J.CIM_Sensor_QuiesceDevice=function(T,S){J.Exec("CIM_Sensor","QuiesceDevice",{Quiesce:T},S)};J.CIM_Sensor_SaveProperties=function(S){J.Exec("CIM_Sensor","SaveProperties",{},S)};J.CIM_Sensor_RestoreProperties=function(S){J.Exec("CIM_Sensor","RestoreProperties",{},S)};J.CIM_Sensor_RequestStateChange=function(T,U,S){J.Exec("CIM_Sensor","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_StatisticalData_ResetSelectedStats=function(T,S){J.Exec("CIM_StatisticalData","ResetSelectedStats",{SelectedStatistics:T},S)};J.CIM_Watchdog_KeepAlive=function(S){J.Exec("CIM_Watchdog","KeepAlive",{},S)};J.CIM_Watchdog_SetPowerState=function(T,U,S){J.Exec("CIM_Watchdog","SetPowerState",{PowerState:T,Time:U},S)};J.CIM_Watchdog_Reset=function(S){J.Exec("CIM_Watchdog","Reset",{},S)};J.CIM_Watchdog_EnableDevice=function(T,S){J.Exec("CIM_Watchdog","EnableDevice",{Enabled:T},S)};J.CIM_Watchdog_OnlineDevice=function(T,S){J.Exec("CIM_Watchdog","OnlineDevice",{Online:T},S)};J.CIM_Watchdog_QuiesceDevice=function(T,S){J.Exec("CIM_Watchdog","QuiesceDevice",{Quiesce:T},S)};J.CIM_Watchdog_SaveProperties=function(S){J.Exec("CIM_Watchdog","SaveProperties",{},S)};J.CIM_Watchdog_RestoreProperties=function(S){J.Exec("CIM_Watchdog","RestoreProperties",{},S)};J.CIM_Watchdog_RequestStateChange=function(T,U,S){J.Exec("CIM_Watchdog","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_WiFiPort_SetPowerState=function(T,U,S){J.Exec("CIM_WiFiPort","SetPowerState",{PowerState:T,Time:U},S)};J.CIM_WiFiPort_Reset=function(S){J.Exec("CIM_WiFiPort","Reset",{},S)};J.CIM_WiFiPort_EnableDevice=function(T,S){J.Exec("CIM_WiFiPort","EnableDevice",{Enabled:T},S)};J.CIM_WiFiPort_OnlineDevice=function(T,S){J.Exec("CIM_WiFiPort","OnlineDevice",{Online:T},S)};J.CIM_WiFiPort_QuiesceDevice=function(T,S){J.Exec("CIM_WiFiPort","QuiesceDevice",{Quiesce:T},S)};J.CIM_WiFiPort_SaveProperties=function(S){J.Exec("CIM_WiFiPort","SaveProperties",{},S)};J.CIM_WiFiPort_RestoreProperties=function(S){J.Exec("CIM_WiFiPort","RestoreProperties",{},S)};J.CIM_WiFiPort_RequestStateChange=function(T,U,S){J.Exec("CIM_WiFiPort","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.IPS_HostBasedSetupService_Setup=function(W,X,V,T,Y,U,S){J.Exec("IPS_HostBasedSetupService","Setup",{NetAdminPassEncryptionType:W,NetworkAdminPassword:X,McNonce:V,Certificate:T,SigningAlgorithm:Y,DigitalSignature:U},S)};J.IPS_HostBasedSetupService_AddNextCertInChain=function(V,T,U,S){J.Exec("IPS_HostBasedSetupService","AddNextCertInChain",{NextCertificate:V,IsLeafCertificate:T,IsRootCertificate:U},S)};J.IPS_HostBasedSetupService_AdminSetup=function(V,W,U,X,T,S){J.Exec("IPS_HostBasedSetupService","AdminSetup",{NetAdminPassEncryptionType:V,NetworkAdminPassword:W,McNonce:U,SigningAlgorithm:X,DigitalSignature:T},S)};J.IPS_HostBasedSetupService_UpgradeClientToAdmin=function(U,V,T,S){J.Exec("IPS_HostBasedSetupService","UpgradeClientToAdmin",{McNonce:U,SigningAlgorithm:V,DigitalSignature:T},S)};J.IPS_HostBasedSetupService_DisableClientControlMode=function(S,T){J.Exec("IPS_HostBasedSetupService","DisableClientControlMode",{_method_dummy:S},T)};J.IPS_KVMRedirectionSettingData_TerminateSession=function(S){J.Exec("IPS_KVMRedirectionSettingData","TerminateSession",{},S)};J.IPS_KVMRedirectionSettingData_DataChannelRead=function(S){J.Exec("IPS_KVMRedirectionSettingData","DataChannelRead",{},S)};J.IPS_KVMRedirectionSettingData_DataChannelWrite=function(T,S){J.Exec("IPS_KVMRedirectionSettingData","DataChannelWrite",{DataMessage:T},S)};J.IPS_OptInService_StartOptIn=function(S){J.Exec("IPS_OptInService","StartOptIn",{},S)};J.IPS_OptInService_CancelOptIn=function(S){J.Exec("IPS_OptInService","CancelOptIn",{},S)};J.IPS_OptInService_SendOptInCode=function(T,S){J.Exec("IPS_OptInService","SendOptInCode",{OptInCode:T},S)};J.IPS_OptInService_StartService=function(S){J.Exec("IPS_OptInService","StartService",{},S)};J.IPS_OptInService_StopService=function(S){J.Exec("IPS_OptInService","StopService",{},S)};J.IPS_OptInService_RequestStateChange=function(T,U,S){J.Exec("IPS_OptInService","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.IPS_ProvisioningRecordLog_RequestStateChange=function(T,U,S){J.Exec("IPS_ProvisioningRecordLog","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.IPS_ProvisioningRecordLog_ClearLog=function(S,T){J.Exec("IPS_ProvisioningRecordLog","ClearLog",{_method_dummy:S},T)};J.IPS_SecIOService_RequestStateChange=function(T,U,S){J.Exec("IPS_SecIOService","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.AmtStatusToStr=function(S){if(J.AmtStatusCodes[S]){return J.AmtStatusCodes[S]}else{return"UNKNOWN_ERROR"}};J.AmtStatusCodes={0:"SUCCESS",1:"INTERNAL_ERROR",2:"NOT_READY",3:"INVALID_PT_MODE",4:"INVALID_MESSAGE_LENGTH",5:"TABLE_FINGERPRINT_NOT_AVAILABLE",6:"INTEGRITY_CHECK_FAILED",7:"UNSUPPORTED_ISVS_VERSION",8:"APPLICATION_NOT_REGISTERED",9:"INVALID_REGISTRATION_DATA",10:"APPLICATION_DOES_NOT_EXIST",11:"NOT_ENOUGH_STORAGE",12:"INVALID_NAME",13:"BLOCK_DOES_NOT_EXIST",14:"INVALID_BYTE_OFFSET",15:"INVALID_BYTE_COUNT",16:"NOT_PERMITTED",17:"NOT_OWNER",18:"BLOCK_LOCKED_BY_OTHER",19:"BLOCK_NOT_LOCKED",20:"INVALID_GROUP_PERMISSIONS",21:"GROUP_DOES_NOT_EXIST",22:"INVALID_MEMBER_COUNT",23:"MAX_LIMIT_REACHED",24:"INVALID_AUTH_TYPE",25:"AUTHENTICATION_FAILED",26:"INVALID_DHCP_MODE",27:"INVALID_IP_ADDRESS",28:"INVALID_DOMAIN_NAME",29:"UNSUPPORTED_VERSION",30:"REQUEST_UNEXPECTED",31:"INVALID_TABLE_TYPE",32:"INVALID_PROVISIONING_STATE",33:"UNSUPPORTED_OBJECT",34:"INVALID_TIME",35:"INVALID_INDEX",36:"INVALID_PARAMETER",37:"INVALID_NETMASK",38:"FLASH_WRITE_LIMIT_EXCEEDED",39:"INVALID_IMAGE_LENGTH",40:"INVALID_IMAGE_SIGNATURE",41:"PROPOSE_ANOTHER_VERSION",42:"INVALID_PID_FORMAT",43:"INVALID_PPS_FORMAT",44:"BIST_COMMAND_BLOCKED",45:"CONNECTION_FAILED",46:"CONNECTION_TOO_MANY",47:"RNG_GENERATION_IN_PROGRESS",48:"RNG_NOT_READY",49:"CERTIFICATE_NOT_READY",1024:"DISABLED_BY_POLICY",2048:"NETWORK_IF_ERROR_BASE",2049:"UNSUPPORTED_OEM_NUMBER",2050:"UNSUPPORTED_BOOT_OPTION",2051:"INVALID_COMMAND",2052:"INVALID_SPECIAL_COMMAND",2053:"INVALID_HANDLE",2054:"INVALID_PASSWORD",2055:"INVALID_REALM",2056:"STORAGE_ACL_ENTRY_IN_USE",2057:"DATA_MISSING",2058:"DUPLICATE",2059:"EVENTLOG_FROZEN",2060:"PKI_MISSING_KEYS",2061:"PKI_GENERATING_KEYS",2062:"INVALID_KEY",2063:"INVALID_CERT",2064:"CERT_KEY_NOT_MATCH",2065:"MAX_KERB_DOMAIN_REACHED",2066:"UNSUPPORTED",2067:"INVALID_PRIORITY",2068:"NOT_FOUND",2069:"INVALID_CREDENTIALS",2070:"INVALID_PASSPHRASE",2072:"NO_ASSOCIATION",2075:"AUDIT_FAIL",2076:"BLOCKING_COMPONENT",2081:"USER_CONSENT_REQUIRED",4096:"APP_INTERNAL_ERROR",4097:"NOT_INITIALIZED",4098:"LIB_VERSION_UNSUPPORTED",4099:"INVALID_PARAM",4100:"RESOURCES",4101:"HARDWARE_ACCESS_ERROR",4102:"REQUESTOR_NOT_REGISTERED",4103:"NETWORK_ERROR",4104:"PARAM_BUFFER_TOO_SHORT",4105:"COM_NOT_INITIALIZED_IN_THREAD",4106:"URL_REQUIRED"};J.GetMessageLog=function(S,T){J.AMT_MessageLog_PositionToFirstRecord(k,[S,T,[]])};function k(U,S,T,V,W){if(V!=200||T.Body.ReturnValue!="0"){W[0](J,null,W[2],V);return}J.AMT_MessageLog_GetRecords(T.Body.IterationIdentifier,390,l,W)}function l(Z,W,Y,aa,ac){if(aa!=200||Y.Body.ReturnValue!="0"){ac[0](J,null,ac[2],aa);return}var U,V,ae,T,S=ac[2],ab=new Date(),ad,X=Y.Body.RecordArray;if(typeof X==="string"){Y.Body.RecordArray=[Y.Body.RecordArray]}for(U in X){T=Buffer.from(X[U],"base64");if(T!=null){ad=M(T,0);if((ad>0)&&(ad<4294967295)){ae={DeviceAddress:T[4],EventSensorType:T[5],EventType:T[6],EventOffset:T[7],EventSourceType:T[8],EventSeverity:T[9],SensorNumber:T[10],Entity:T[11],EntityInstance:T[12],EventData:[],Time:new Date((ad+(ab.getTimezoneOffset()*60))*1000)};for(V=13;V<21;V++){ae.EventData.push(T[V])}ae.EntityStr=o[ae.Entity];ae.Desc=j(ae.EventSensorType,ae.EventOffset,ae.EventData,ae.Entity);if(!ae.EntityStr){ae.EntityStr="Unknown"}S.push(ae)}}}if(Y.Body.NoMoreRecords!=true){J.AMT_MessageLog_GetRecords(Y.Body.IterationIdentifier,390,l,[ac[0],S,ac[2]])}else{ac[0](J,S,ac[2])}}var f="Platform firmware (e.g. BIOS)|SMI handler|ISV system management software|Alert ASIC|IPMI|BIOS vendor|System board set vendor|System integrator|Third party add-in|OSV|NIC|System management card".split("|");var p="Unspecified.|No system memory is physically installed in the system.|No usable system memory, all installed memory has experienced an unrecoverable failure.|Unrecoverable hard-disk/ATAPI/IDE device failure.|Unrecoverable system-board failure.|Unrecoverable diskette subsystem failure.|Unrecoverable hard-disk controller failure.|Unrecoverable PS/2 or USB keyboard failure.|Removable boot media not found.|Unrecoverable video controller failure.|No video device detected.|Firmware (BIOS) ROM corruption detected.|CPU voltage mismatch (processors that share same supply have mismatched voltage requirements)|CPU speed matching failure".split("|");var q="Unspecified.|Memory initialization.|Starting hard-disk initialization and test|Secondary processor(s) initialization|User authentication|User-initiated system setup|USB resource configuration|PCI resource configuration|Option ROM initialization|Video initialization|Cache initialization|SM Bus initialization|Keyboard controller initialization|Embedded controller/management controller initialization|Docking station attachment|Enabling docking station|Docking station ejection|Disabling docking station|Calling operating system wake-up vector|Starting operating system boot process|Baseboard or motherboard initialization|reserved|Floppy initialization|Keyboard test|Pointing device test|Primary processor initialization".split("|");var o="Unspecified|Other|Unknown|Processor|Disk|Peripheral|System management module|System board|Memory module|Processor module|Power supply|Add in card|Front panel board|Back panel board|Power system board|Drive backplane|System internal expansion board|Other system board|Processor board|Power unit|Power module|Power management board|Chassis back panel board|System chassis|Sub chassis|Other chassis board|Disk drive bay|Peripheral bay|Device bay|Fan cooling|Cooling unit|Cable interconnect|Memory device|System management software|BIOS|Intel(r) ME|System bus|Group|Intel(r) ME|External environment|Battery|Processing blade|Connectivity switch|Processor/memory module|I/O module|Processor I/O module|Management controller firmware|IPMI channel|PCI bus|PCI express bus|SCSI bus|SATA/SAS bus|Processor front side bus".split("|");J.RealmNames="||Redirection|PT Administration|Hardware Asset|Remote Control|Storage|Event Manager|Storage Admin|Agent Presence Local|Agent Presence Remote|Circuit Breaker|Network Time|General Information|Firmware Update|EIT|LocalUN|Endpoint Access Control|Endpoint Access Control Admin|Event Log Reader|Audit Log|ACL Realm|||Local System".split("|");J.WatchdogCurrentStates={1:"Not Started",2:"Stopped",4:"Running",8:"Expired",16:"Suspended"};function j(V,U,T,S){if(V==15){if(T[0]==235){return"Invalid Data"}if(U==0){return p[T[1]]}return q[T[1]]}if(V==18&&T[0]==170){return"Agent watchdog "+char2hex(T[4])+char2hex(T[3])+char2hex(T[2])+char2hex(T[1])+"-"+char2hex(T[6])+char2hex(T[5])+"-... changed to "+J.WatchdogCurrentStates[T[7]]}if(V==6){return"Authentication failed "+(T[1]+(T[2]<<8))+" times. The system may be under attack."}if(V==30){return"No bootable media"}if(V==32){return"Operating system lockup or power interrupt"}if(V==35){return"System boot failure"}if(V==37){return"System firmware started (at least one CPU is properly executing)."}return"Unknown Sensor Type #"+V}var a={16:"Security Admin",17:"RCO",18:"Redirection Manager",19:"Firmware Update Manager",20:"Security Audit Log",21:"Network Time",22:"Network Administration",23:"Storage Administration",24:"Event Manager",25:"Circuit Breaker Manager",26:"Agent Presence Manager",27:"Wireless Configuration",28:"EAC",29:"KVM",30:"User Opt-In Events",32:"Screen Blanking",33:"Watchdog Events",1600:"Provisioning Started",1601:"Provisioning Completed",1602:"ACL Entry Added",1603:"ACL Entry Modified",1604:"ACL Entry Removed",1605:"ACL Access with Invalid Credentials",1606:"ACL Entry State",1607:"TLS State Changed",1608:"TLS Server Certificate Set",1609:"TLS Server Certificate Remove",1610:"TLS Trusted Root Certificate Added",1611:"TLS Trusted Root Certificate Removed",1612:"TLS Preshared Key Set",1613:"Kerberos Settings Modified",1614:"Kerberos Master Key Modified",1615:"Flash Wear out Counters Reset",1616:"Power Package Modified",1617:"Set Realm Authentication Mode",1618:"Upgrade Client to Admin Control Mode",1619:"Unprovisioning Started",1700:"Performed Power Up",1701:"Performed Power Down",1702:"Performed Power Cycle",1703:"Performed Reset",1704:"Set Boot Options",1800:"IDER Session Opened",1801:"IDER Session Closed",1802:"IDER Enabled",1803:"IDER Disabled",1804:"SoL Session Opened",1805:"SoL Session Closed",1806:"SoL Enabled",1807:"SoL Disabled",1808:"KVM Session Started",1809:"KVM Session Ended",1810:"KVM Enabled",1811:"KVM Disabled",1812:"VNC Password Failed 3 Times",1900:"Firmware Updated",1901:"Firmware Update Failed",2000:"Security Audit Log Cleared",2001:"Security Audit Policy Modified",2002:"Security Audit Log Disabled",2003:"Security Audit Log Enabled",2004:"Security Audit Log Exported",2005:"Security Audit Log Recovered",2100:"Intel(R) ME Time Set",2200:"TCPIP Parameters Set",2201:"Host Name Set",2202:"Domain Name Set",2203:"VLAN Parameters Set",2204:"Link Policy Set",2205:"IPv6 Parameters Set",2300:"Global Storage Attributes Set",2301:"Storage EACL Modified",2302:"Storage FPACL Modified",2303:"Storage Write Operation",2400:"Alert Subscribed",2401:"Alert Unsubscribed",2402:"Event Log Cleared",2403:"Event Log Frozen",2500:"CB Filter Added",2501:"CB Filter Removed",2502:"CB Policy Added",2503:"CB Policy Removed",2504:"CB Default Policy Set",2505:"CB Heuristics Option Set",2506:"CB Heuristics State Cleared",2600:"Agent Watchdog Added",2601:"Agent Watchdog Removed",2602:"Agent Watchdog Action Set",2700:"Wireless Profile Added",2701:"Wireless Profile Removed",2702:"Wireless Profile Updated",2800:"EAC Posture Signer SET",2801:"EAC Enabled",2802:"EAC Disabled",2803:"EAC Posture State",2804:"EAC Set Options",2900:"KVM Opt-in Enabled",2901:"KVM Opt-in Disabled",2902:"KVM Password Changed",2903:"KVM Consent Succeeded",2904:"KVM Consent Failed",3000:"Opt-In Policy Change",3001:"Send Consent Code Event",3002:"Start Opt-In Blocked Event"};J.GetAuditLogExtendedDataStr=function(T,S){if((T==1602||T==1604)&&S[0]==0){return w(S).splice(2,2+S[1]).toString()}if(T==1603){if(S[1]==0){return w(S).splice(3).toString()}return null}if(T==1605){return["Invalid ME access","Invalid MEBx access"][S[0]]}if(T==1606){var U=["Disabled","Enabled"][S[0]];if(S[1]==0){U+=", "+S[3]}return U}if(T==1607){return"Remote "+["NoAuth","ServerAuth","MutualAuth"][S[0]]+", Local "+["NoAuth","ServerAuth","MutualAuth"][S[1]]}if(T==1617){return J.RealmNames[L(S,0)]+", "+["NoAuth","Auth","Disabled"][S[4]]}if(T==1619){return["BIOS","MEBx","Local MEI","Local WSMAN","Remote WSAMN"][S[0]]}if(T==1900){return"From "+N(S,0)+"."+N(S,2)+"."+N(S,4)+"."+N(S,6)+" to "+N(S,8)+"."+N(S,10)+"."+N(S,12)+"."+N(S,14)}if(T==2100){var V=new Date();V.setTime(L(S,0)*1000+(new Date().getTimezoneOffset()*60000));return V.toLocaleString()}if(T==3000){return"From "+["None","KVM","All"][S[0]]+" to "+["None","KVM","All"][S[1]]}if(T==3001){return["Success","Failed 3 times"][S[0]]}return null};J.GetAuditLog=function(S){J.AMT_AuditLog_ReadRecords(1,i,[S,[]])};function I(S){if(!S||S==null||typeof S=="object"){return S}return[S]}function N(T,S){return(T[S]<<8)+T[S+1]}function L(T,S){return(T[S]*16777216)+(T[S+1]<<16)+(T[S+2]<<8)+T[S+3]}function M(T,S){return(T[S+3]*16777216)+(T[S+2]<<16)+(T[S+1]<<8)+T[S]}function v(S){return Buffer.from(S).toString("base64")}function u(T){var U=null;try{U=Buffer.from(T,"base64").toString()}catch(S){console.log(S)}return U}function w(S){var U=[];for(var T in S){U.push(S[T])}return U}function i(ab,W,aa,ac,ae){if(ac!=200){ae[0](J,[],ac);return}var Y,V,S,ah,Z=ae[1],ad=new Date(),af;if(aa.Body.RecordsReturned>0){aa.Body.EventRecords=I(aa.Body.EventRecords);for(V in aa.Body.EventRecords){S=null;try{S=Buffer.from(aa.Body.EventRecords[V],"base64")}catch(T){console.log(T+" "+aa.Body.EventRecords[V])}ah={AuditAppID:N(S,0),EventID:N(S,2),InitiatorType:S[4]};ah.AuditApp=a[ah.AuditAppID];ah.Event=a[(ah.AuditAppID*100)+ah.EventID];if(!ah.Event){ah.Event="#"+ah.EventID}if(ah.InitiatorType==0){var ag=S[5];ah.Initiator=S.slice(6,6+ag).toString();Y=6+ag}if(ah.InitiatorType==1){ah.KerberosUserInDomain=L(S,5);var ag=S[9];ah.Initiator=G(S.slice(10,10+ag));Y=10+ag}if(ah.InitiatorType==2){ah.Initiator="Local";Y=5}if(ah.InitiatorType==3){ah.Initiator="KVM Default Port";Y=5}af=L(S,Y);ah.Time=new Date((af+(ad.getTimezoneOffset()*60))*1000);Y+=4;ah.MCLocationType=S[Y++];var X=S[Y++];ah.NetAddress=S.slice(Y,Y+X).toString();Y+=X;var U=S[Y++];ah.Ex=S.slice(Y,Y+U);ah.ExStr=J.GetAuditLogExtendedDataStr((ah.AuditAppID*100)+ah.EventID,ah.Ex);Z.push(ah)}}if(aa.Body.TotalRecordCount>Z.length){J.AMT_AuditLog_ReadRecords(Z.length+1,i,[ae[0],Z])}else{ae[0](J,Z,ac)}}function C(U){if(U===undefined||U===null){return null}var V="";for(var T in U){var S=U[T];if(!S){continue}if(S.__parameterType==="reference"){V+=O(T,S)}else{V+=H(T,S)}}return V}function H(V,U){if(U===undefined||U===null){return null}var T=!!U.__namespace;var Z=T?"";for(var X in U){if(!U.hasOwnProperty(X)||X.indexOf("__")===0){continue}if(typeof U[X]==="function"||Array.isArray(U[X])){continue}if(typeof U[X]==="object"){console.error("only convert one level down...")}else{Y+=Z+X+">"+U[X].toString()+S+X+">"}}Y+="";return Y}function O(T,S){if(S===undefined||S===null){return null}var U="/wsman"+S.__resourceUri+"";for(var V in S){if(!S.hasOwnProperty(V)||V.indexOf("__")===0){continue}if(typeof S[V]==="function"||typeof S[V]==="object"||Array.isArray(S[V])){continue}U+=''+S[V].toString()+""}U+="";return U}function G(U){var T="S-"+U.charCodeAt(0)+"-"+U.charCodeAt(7);for(var S=2;S<(U.length/4);S++){T+="-"+M(U,S*4)}return T}function F(V){if(!V||V==null){return null}var U=V.split("-");if(U.length<4||(U[0]!="s"&&U[0]!="S")){return null}for(var S=1;SStandardOutPath\n"+r.stdout+""):"");var i=(r.startType=="AUTO_START"?"":"");var s=" ProgramArguments\n";s+=" \n";s+=(" /usr/local/mesh_services/"+r.name+"/"+r.name+"\n");if(r.parameters){for(var p in r.parameters){s+=(" "+r.parameters[p]+"\n")}}s+=" \n";var t='\n';t+='\n';t+='\n';t+=" \n";t+=" Label\n";t+=(" "+r.name+"\n");t+=(s+"\n");t+=" WorkingDirectory\n";t+=(" /usr/local/mesh_services/"+r.name+"\n");t+=(y+"\n");t+=" RunAtLoad\n";t+=(i+"\n");t+=" \n";t+="";if(!require("fs").existsSync("/usr/local/mesh_services")){require("fs").mkdirSync("/usr/local/mesh_services")}if(!require("fs").existsSync("/Library/LaunchDaemons/"+r.name+".plist")){if(!require("fs").existsSync("/usr/local/mesh_services/"+r.name)){require("fs").mkdirSync("/usr/local/mesh_services/"+r.name)}if(r.binary){require("fs").writeFileSync("/usr/local/mesh_services/"+r.name+"/"+r.name,r.binary)}else{require("fs").copyFileSync(r.servicePath,"/usr/local/mesh_services/"+r.name+"/"+r.name)}require("fs").writeFileSync("/Library/LaunchDaemons/"+r.name+".plist",t);var q=require("fs").statSync("/usr/local/mesh_services/"+r.name+"/"+r.name).mode;q|=(require("fs").CHMOD_MODES.S_IXUSR|require("fs").CHMOD_MODES.S_IXGRP);require("fs").chmodSync("/usr/local/mesh_services/"+r.name+"/"+r.name,q)}else{throw ("Service: "+r.name+" already exists")}}};this.uninstallService=function f(i){if(!this.isAdmin()){throw ("Uninstalling a service, requires admin")}if(typeof(i)=="object"){i=i.name}if(process.platform=="win32"){var j=this.getService(i);if(j.status.state==undefined||j.status.state=="STOPPED"){if(this.proxy.DeleteService(j._service)==0){throw ("Uninstall Service for: "+i+", failed with error: "+this.proxy2.GetLastError())}else{try{require("fs").unlinkSync(this.getServiceFolder()+"\\"+i+".exe")}catch(h){}}}else{throw ("Cannot uninstall service: "+i+", because it is: "+j.status.state)}}else{if(process.platform=="linux"){switch(this.getServiceType()){case"init":this._update=require("child_process").execFile("/bin/sh",["sh"],{type:require("child_process").SpawnTypes.TERM});this._update.stdout.on("data",function(k){});this._update.stdin.write("service "+i+" stop\n");this._update.stdin.write("update-rc.d -f "+i+" remove\n");this._update.stdin.write("exit\n");this._update.waitExit();try{require("fs").unlinkSync("/etc/init.d/"+i);console.log(i+" uninstalled")}catch(h){console.log(i+" could not be uninstalled",h)}break;case"systemd":this._update=require("child_process").execFile("/bin/sh",["sh"],{type:require("child_process").SpawnTypes.TERM});this._update.stdout.on("data",function(k){});this._update.stdin.write("systemctl stop "+i+".service\n");this._update.stdin.write("systemctl disable "+i+".service\n");this._update.stdin.write("exit\n");this._update.waitExit();try{require("fs").unlinkSync("/usr/local/mesh/"+i);require("fs").unlinkSync("/lib/systemd/system/"+i+".service");console.log(i+" uninstalled")}catch(h){console.log(i+" could not be uninstalled",h)}break;default:break}}else{if(process.platform=="darwin"){if(require("fs").existsSync("/Library/LaunchDaemons/"+i+".plist")){var g=require("child_process").execFile("/bin/sh",["sh"]);g.stdout.on("data",function(k){});g.stdin.write("launchctl stop "+i+"\n");g.stdin.write("launchctl unload /Library/LaunchDaemons/"+i+".plist\n");g.stdin.write("exit\n");g.waitExit();try{require("fs").unlinkSync("/usr/local/mesh_services/"+i+"/"+i);require("fs").unlinkSync("/Library/LaunchDaemons/"+i+".plist")}catch(h){throw ("Error uninstalling service: "+i+" => "+h)}try{require("fs").rmdirSync("/usr/local/mesh_services/"+i)}catch(h){}}else{throw ("Service: "+i+" does not exist")}}}}};if(process.platform=="linux"){this.getServiceType=function c(){return(require("process-manager").getProcessInfo(1).Name)}}}module.exports=serviceManager; \ No newline at end of file diff --git a/agents/modules_meshcmd_min/smbios.min.js b/agents/modules_meshcmd_min/smbios.min.js new file mode 100644 index 00000000..451b12c3 --- /dev/null +++ b/agents/modules_meshcmd_min/smbios.min.js @@ -0,0 +1 @@ +try{Object.defineProperty(Array.prototype,"peek",{value:function(){return(this.length>0?this[this.length-1]:undefined)}})}catch(e){}try{Object.defineProperty(String.prototype,"replaceAll",{value:function replaceAll(b,a){return(this.split(b).join(a))}})}catch(e){}var RSMB=1381190978;var memoryLocation={1:"Other",2:"Unknown",3:"System Board",4:"ISA",5:"EISA",6:"PCI",7:"MCA",8:"PCMCIA",9:"Proprietary",10:"NuBus",160:"PC-98/C20",161:"PC-98/C24",162:"PC-98/E",163:"PC-98/LB"};var wakeReason=["Reserved","Other","Unknown","APM Timer","Modem Ring","LAN","Power Switch","PCI","AC Power"];function zeroLeftPad(c,b){if((b==null)&&(typeof(b)!="number")){return null}if(c==null){c=""}var d="";for(var a=0;a1){var r=v[1].split("\x0A\x0A")[0].split("\x0A");var s=[];for(var t in r){var u=r[t].trim().replaceAll(" ","").replaceAll("\x09","");if(!(u[0]=='"')){s.push(u)}}p.write(Buffer.from(s.join(""),"hex"));p.write(Buffer.from("00","hex"))}else{p.write(Buffer.from("0000","hex"))}}var q=p.buffer;q.ms=p;return(q)}}this._parse=function b(o){var n={};var m;var l=0;var o;var s=0;while(o&&l0){var n=l[4].pop();var o=n[20]&64;var s=n[20]&7;if(o){var m={_ObjectID:"SMBiosTables.processorInfo"};m.Processor=q[n[1]];m.MaxSpeed=n.readUInt16LE(16)+" Mhz";if(n[31]){m.Cores=n[31]}if(n[33]){m.Threads=n[33]}m.Populated=1;m.Status=t[s];m.Socket=n._strings[n[0]-1];m.Manufacturer=n._strings[n[3]-1];m.Version=n._strings[n[12]-1];r.push(m)}}return(r)};this.memoryInfo=function f(k){if(!k){throw ("no data")}var n={_ObjectID:"SMBiosTables.memoryInfo"};if(k[16]){var l=k[16].peek();n.location=memoryLocation[l[0]];if((n.maxCapacityKb=l.readUInt32LE(3))==2147483648){n.maxCapacityKb="A really big number"}}return(n)};this.systemInfo=function i(k){if(!k){throw ("no data")}var l={_ObjectID:"SMBiosTables.systemInfo"};if(k[1]){var m=k[1].peek();var n=m.slice(4,20);l.uuid=[zeroLeftPad(n.readUInt32LE(0).toString(16),8),zeroLeftPad(n.readUInt16LE(4).toString(16),4),zeroLeftPad(n.readUInt16LE(6).toString(16),4),zeroLeftPad(n.readUInt16BE(8).toString(16),4),zeroLeftPad(n.slice(10).toString("hex").toLowerCase(),12)].join("-");l.wakeReason=wakeReason[m[20]]}return(l)};this.systemSlots=function j(k){if(!k){throw ("no data")}var l=[];if(k[9]){while(k[9].length>0){var m=k[9].pop();l.push({name:m._strings[m[0]-1]})}}return(l)};this.amtInfo=function c(l){if(!l){throw ("no data")}var n={AMT:false};if(l[130]&&l[130].peek().slice(0,4).toString()=="$AMT"){var k=l[130].peek();n.AMT=k[4]?true:false;if(n.AMT){n.enabled=k[5]?true:false;n.storageRedirection=k[6]?true:false;n.serialOverLan=k[7]?true:false;n.kvm=k[14]?true:false;if(l[131].peek()&&l[131].peek().slice(52,56).toString()=="vPro"){var o=l[131].peek();if(o[0]&4){n.TXT=(o[0]&8)?true:false}if(o[0]&16){n.VMX=(o[0]&32)?true:false}n.MEBX=o.readUInt16LE(10).toString()+"."+o.readUInt16LE(8).toString()+"."+o.readUInt16LE(6).toString()+"."+o.readUInt16LE(4).toString();var m=o.slice(20,32);n.ManagementEngine=m.readUInt16LE(6).toString()+"."+m.readUInt16LE(4).toString()+"."+m.readUInt16LE(2).toString()+"."+m.readUInt16LE(0).toString()}}}return(n)};this.smTableTypes={0:"BIOS information",1:"System information",2:"Baseboard (or Module) information",4:"Processor information",5:"memory controller information",6:"Memory module information",7:"Cache information",8:"Port connector information",9:"System slots",10:"On board devices information",11:"OEM strings",12:"System configuration options",13:"BIOS language information",14:"Group associations",15:"System event log",16:"Physical memory array",17:"Memory device",18:"32bit memory error information",19:"Memory array mapped address",20:"Memory device mapped address",21:"Built-in pointing device",22:"Portable battery",23:"System reset",24:"Hardware security",25:"System power controls",26:"Voltage probe",27:"Cooling device",28:"Temperature probe",29:"Electrical current probe",30:"Out-of-band remote access",31:"Boot integrity services (BIS) entry point",32:"System boot information",33:"64bit memory error information",34:"Management device",35:"Management device component",36:"Management device threshold data",37:"Memory channel",38:"IPMI device information",39:"System power supply",40:"Additional information",41:"Onboard devices extended information",42:"Management controller host interface",126:"Inactive",127:"End-of-table"}}module.exports=new SMBiosTables(); \ No newline at end of file diff --git a/agents/modules_meshcmd_min/user-sessions.min.js b/agents/modules_meshcmd_min/user-sessions.min.js new file mode 100644 index 00000000..a059a1fc --- /dev/null +++ b/agents/modules_meshcmd_min/user-sessions.min.js @@ -0,0 +1 @@ +var NOTIFY_FOR_THIS_SESSION=0;var NOTIFY_FOR_ALL_SESSIONS=1;var WM_WTSSESSION_CHANGE=689;var WM_POWERBROADCAST=536;var PBT_POWERSETTINGCHANGE=32787;var PBT_APMSUSPEND=4;var PBT_APMRESUMESUSPEND=7;var PBT_APMRESUMEAUTOMATIC=18;var PBT_APMPOWERSTATUSCHANGE=10;var WTS_CONSOLE_CONNECT=(1);var WTS_CONSOLE_DISCONNECT=(2);var WTS_REMOTE_CONNECT=(3);var WTS_REMOTE_DISCONNECT=(4);var WTS_SESSION_LOGON=(5);var WTS_SESSION_LOGOFF=(6);var WTS_SESSION_LOCK=(7);var WTS_SESSION_UNLOCK=(8);var WTS_SESSION_REMOTE_CONTROL=(9);var WTS_SESSION_CREATE=(10);var WTS_SESSION_TERMINATE=(11);var GUID_ACDC_POWER_SOURCE;var GUID_BATTERY_PERCENTAGE_REMAINING;var GUID_CONSOLE_DISPLAY_STATE;function UserSessions(){this._ObjectID="user-sessions";require("events").EventEmitter.call(this,true).createEvent("changed").createEvent("locked").createEvent("unlocked");this.enumerateUsers=function h(){var s=require("promise");var r=new s(function(t,p){this.__resolver=t;this.__rejector=p});r.__handler=function o(p){r.__resolver(p)};try{this.Current(r.__handler)}catch(q){r.__rejector(q)}r.parent=this;return(r)};if(process.platform=="win32"){this._serviceHooked=false;this._marshal=require("_GenericMarshal");this._kernel32=this._marshal.CreateNativeProxy("Kernel32.dll");this._kernel32.CreateMethod("GetLastError");try{this._wts=this._marshal.CreateNativeProxy("Wtsapi32.dll");this._wts.CreateMethod("WTSEnumerateSessionsA");this._wts.CreateMethod("WTSQuerySessionInformationA");this._wts.CreateMethod("WTSRegisterSessionNotification");this._wts.CreateMethod("WTSUnRegisterSessionNotification");this._wts.CreateMethod("WTSFreeMemory")}catch(i){}this._advapi=this._marshal.CreateNativeProxy("Advapi32.dll");this._advapi.CreateMethod("AllocateAndInitializeSid");this._advapi.CreateMethod("CheckTokenMembership");this._advapi.CreateMethod("FreeSid");this._user32=this._marshal.CreateNativeProxy("user32.dll");this._user32.CreateMethod({method:"RegisterPowerSettingNotification",threadDispatch:1});this._user32.CreateMethod("UnregisterPowerSettingNotification");this._rpcrt=this._marshal.CreateNativeProxy("Rpcrt4.dll");this._rpcrt.CreateMethod("UuidFromStringA");this._rpcrt.StringToUUID=function n(o){var p=n.us._marshal.CreateVariable(16);if(n.us._rpcrt.UuidFromStringA(n.us._marshal.CreateVariable(o),p).Val==0){return(p)}else{throw ("Could not convert string to UUID")}};this._rpcrt.StringToUUID.us=this;GUID_ACDC_POWER_SOURCE=this._rpcrt.StringToUUID("5d3e9a59-e9D5-4b00-a6bd-ff34ff516548");GUID_BATTERY_PERCENTAGE_REMAINING=this._rpcrt.StringToUUID("a7ad8041-b45a-4cae-87a3-eecbb468a9e1");GUID_CONSOLE_DISPLAY_STATE=this._rpcrt.StringToUUID("6fe69556-704a-47a0-8f24-c28d936fda47");this.SessionStates=["Active","Connected","ConnectQuery","Shadow","Disconnected","Idle","Listening","Reset","Down","Init"];this.InfoClass={WTSInitialProgram:0,WTSApplicationName:1,WTSWorkingDirectory:2,WTSOEMId:3,WTSSessionId:4,WTSUserName:5,WTSWinStationName:6,WTSDomainName:7,WTSConnectState:8,WTSClientBuildNumber:9,WTSClientName:10,WTSClientDirectory:11,WTSClientProductId:12,WTSClientHardwareId:13,WTSClientAddress:14,WTSClientDisplay:15,WTSClientProtocolType:16,WTSIdleTime:17,WTSLogonTime:18,WTSIncomingBytes:19,WTSOutgoingBytes:20,WTSIncomingFrames:21,WTSOutgoingFrames:22,WTSClientInfo:23,WTSSessionInfo:24,WTSSessionInfoEx:25,WTSConfigInfo:26,WTSValidationInfo:27,WTSSessionAddressV4:28,WTSIsRemoteSession:29};this.isRoot=function k(){var r=this._marshal.CreateVariable(6);r.toBuffer().writeInt8(5,5);var p=this._marshal.CreatePointer();var o=false;if(this._advapi.AllocateAndInitializeSid(r,2,32,544,0,0,0,0,0,0,p).Val!=0){var q=this._marshal.CreateInteger();if(this._advapi.CheckTokenMembership(0,p.Deref(),q).Val!=0){if(q.toBuffer().readUInt32LE()!=0){o=true}}this._advapi.FreeSid(p.Deref())}return o};this.getSessionAttribute=function j(s,o){var p=this._marshal.CreatePointer();var q=this._marshal.CreateVariable(4);if(this._wts.WTSQuerySessionInformationA(0,s,o,p,q).Val==0){throw ("Error calling WTSQuerySessionInformation: "+this._kernel32.GetLastError.Val)}var r=p.Deref().String;this._wts.WTSFreeMemory(p.Deref());return(r)};this.Current=function f(o){var u={};var t=this._marshal.CreatePointer();var p=this._marshal.CreateVariable(4);if(this._wts.WTSEnumerateSessionsA(0,0,1,t,p).Val==0){throw ("Error calling WTSEnumerateSessionsA: "+this._kernel32.GetLastError().Val)}for(var q=0;q= 0) {printf \"%s:%s\\n\", $1, $3}' /etc/passwd\nexit\n");o.waitExit();var p=o.stdout.str.split("\n");var r={},s;for(var q in p){s=p[q].split(":");if(s[0]){r[s[0]]=s[1]}}return(r)};this._uids=function c(){var o=require("child_process").execFile("/bin/sh",["sh"]);o.stdout.str="";o.stdout.on("data",function(t){this.str+=t.toString()});o.stdin.write("awk -F: '($3 >= 0) {printf \"%s:%s\\n\", $1, $3}' /etc/passwd\nexit\n");o.waitExit();var p=o.stdout.str.split("\n");var r={},s;for(var q in p){s=p[q].split(":");if(s[0]){r[s[1]]=s[0]}}return(r)};this.Self=function m(){var q=require("promise");var o=new q(function(r,p){this.__resolver=r;this.__rejector=p;this.__child=require("child_process").execFile("/usr/bin/id",["id","-u"]);this.__child.promise=this;this.__child.stdout._txt="";this.__child.stdout.on("data",function(s){this._txt+=s.toString()});this.__child.on("exit",function(s){try{parseInt(this.stdout._txt)}catch(t){this.promise.__rejector("invalid uid");return}var u=parseInt(this.stdout._txt);this.promise.__resolver(u)})});return(o)};this.Current=function f(o){var p={};p._ObjectID="UserSession";Object.defineProperty(p,"_callback",{value:o});Object.defineProperty(p,"_child",{value:require("child_process").execFile("/usr/bin/last",["last","-f","/var/run/utmp"])});p._child.Parent=p;p._child._txt="";p._child.on("exit",function(q){var u=this._txt.split("\n");var A=[];var D={};for(var t in u){if(u[t]){var B=getTokens(u[t]);var z={Username:B[0],SessionId:B[1]};if(B[3].includes("still logged in")){z.State="Active"}else{z.LastActive=B[3]}A.push(z)}}A.pop();var C={};var y=[];for(var t in A){if(A[t].Username!="reboot"){D[A[t].SessionId]=A[t];if(C[A[t].Username]==null){C[A[t].Username]=-1}}}try{require("promise")}catch(r){Object.defineProperty(D,"Active",{value:showActiveOnly(D)});if(this.Parent._callback){this.Parent._callback.call(this.Parent,D)}return}var x=require("promise");for(var v in C){var w=new x(function(E,s){this.__username=v;this.__resolver=E;this.__rejector=s;this.__child=require("child_process").execFile("/usr/bin/id",["id","-u",v]);this.__child.promise=this;this.__child.stdout._txt="";this.__child.stdout.on("data",function(F){this._txt+=F.toString()});this.__child.on("exit",function(F){try{parseInt(this.stdout._txt)}catch(G){this.promise.__rejector("invalid uid");return}var H=parseInt(this.stdout._txt);this.promise.__resolver(H)})});y.push(w)}x.all(y).then(function(E){var F={};for(var s in E){F[E[s].__username]=E[s]._internal.completedArgs[0]}for(var s in D){D[s].uid=F[D[s].Username]}Object.defineProperty(D,"Active",{value:showActiveOnly(D)});if(p._callback){p._callback.call(p,D)}},function(s){Object.defineProperty(D,"Active",{value:showActiveOnly(D)});if(p._callback){p._callback.call(p,D)}})});p._child.stdout.Parent=p._child;p._child.stdout.on("data",function(q){this.Parent._txt+=q.toString()});return(p)};this._recheckLoggedInUsers=function a(){this.enumerateUsers().then(function(o){if(o.Active.length>0){if(this.parent._linux_lock_watcher!=null&&this.parent._linux_lock_watcher.uid!=o.Active[0].uid){delete this.parent._linux_lock_watcher}this.parent._linux_lock_watcher=new g(process.env.XDG_CURRENT_DESKTOP=="Unity"?"com.ubuntu.Upstart0_6":"org.gnome.ScreenSaver",o.Active[0].uid);this.parent._linux_lock_watcher.user_session=this.parent;this.parent._linux_lock_watcher.on("signal",function(r){var q=this.user_session.enumerateUsers();q.signalData=r.data[0];q.then(function(p){switch(this.signalData){case true:case"desktop-lock":this.parent.emit("locked",p.Active[0]);break;case false:case"desktop-unlock":this.parent.emit("unlocked",p.Active[0]);break}})})}else{if(this.parent._linux_lock_watcher!=null){delete this.parent._linux_lock_watcher}}})};this.on("changed",this._recheckLoggedInUsers);this._recheckLoggedInUsers()}else{if(process.platform=="darwin"){this._users=function(){var o=require("child_process").execFile("/usr/bin/dscl",["dscl",".","list","/Users","UniqueID"]);o.stdout.str="";o.stdout.on("data",function(t){this.str+=t.toString()});o.stdin.write("exit\n");o.waitExit();var q=o.stdout.str.split("\n");var r,p;var s={};for(p=0;p0;++r){if(!u[s[r].split(" ")[0]]){try{u[s[r].split(" ")[0]]={Username:s[r].split(" ")[0],State:s[r].split("still logged in").length>1?"Active":"Inactive",uid:t.uid[s[r].split(" ")[0]]}}catch(q){}}else{if(u[s[r].split(" ")[0]].State!="Active"&&s[r].split("still logged in").length>1){u[s[r].split(" ")[0]].State="Active"}}}Object.defineProperty(u,"Active",{value:showActiveOnly(u)});if(o){o.call(this,u)}}}}}if(process.platform=="linux"||process.platform=="darwin"){this._self=function b(){var o=require("child_process").execFile("/usr/bin/id",["id","-u"]);o.stdout.str="";o.stdout.on("data",function(p){this.str+=p.toString()});o.waitExit();return(parseInt(o.stdout.str))};this.isRoot=function k(){return(this._self()==0)};this.consoleUid=function e(){var o=process.platform=="darwin"?"console":((process.env.DISPLAY)?process.env.DISPLAY:":0");var p=require("child_process").execFile("/bin/sh",["sh"]);p.stdout.str="";p.stdout.on("data",function(u){this.str+=u.toString()});p.stdin.write("who\nexit\n");p.waitExit();var s=p.stdout.str.split("\n");var t,q,r;for(q in s){t=s[q].split(" ");for(r=1;r0){return(parseInt(this._users()[t[0]]))}}}throw ("nobody logged into console")}}}function showActiveOnly(c){var b=[];var e={};var f=[];var d;for(var a in c){if(c[a].State=="Active"){b.push(c[a]);d=(c[a].Domain?(c[a].Domain+"\\"):"")+c[a].Username;if(!e[d]){e[d]=d}}}for(var a in e){f.push(a)}Object.defineProperty(b,"usernames",{value:f});return(b)}function getTokens(d){var a=[];var b;a.push(d.substring(0,(b=d.indexOf(" "))));while(d[++b]==" "){}a.push(d.substring(b,(b=d.substring(b).indexOf(" ")+b)));while(d[++b]==" "){}a.push(d.substring(b,(b=d.substring(b).indexOf(" ")+b)));while(d[++b]==" "){}var c=d.substring(b).trim();a.push(c);return(a)}module.exports=new UserSessions(); \ No newline at end of file diff --git a/agents/modules_meshcore_min/amt-lme.min.js b/agents/modules_meshcore_min/amt-lme.min.js new file mode 100644 index 00000000..6e19dfe3 --- /dev/null +++ b/agents/modules_meshcore_min/amt-lme.min.js @@ -0,0 +1 @@ +var MemoryStream=require("MemoryStream");var lme_id=0;var lme_port_offset=0;var xmlParser=require("amt-xml");var APF_DISCONNECT=1;var APF_SERVICE_REQUEST=5;var APF_SERVICE_ACCEPT=6;var APF_USERAUTH_REQUEST=50;var APF_USERAUTH_FAILURE=51;var APF_USERAUTH_SUCCESS=52;var APF_GLOBAL_REQUEST=80;var APF_REQUEST_SUCCESS=81;var APF_REQUEST_FAILURE=82;var APF_CHANNEL_OPEN=90;var APF_CHANNEL_OPEN_CONFIRMATION=91;var APF_CHANNEL_OPEN_FAILURE=92;var APF_CHANNEL_WINDOW_ADJUST=93;var APF_CHANNEL_DATA=94;var APF_CHANNEL_CLOSE=97;var APF_PROTOCOLVERSION=192;function lme_object(){this.ourId=++lme_id;this.amtId=-1;this.LME_CHANNEL_STATUS="LME_CS_FREE";this.txWindow=0;this.rxWindow=0;this.localPort=0;this.errorCount=0}function stream_bufferedWrite(){var a=require("events").inherits(this);this.buffer=[];this._readCheckImmediate=undefined;this._ObjectID="bufferedWriteStream";a.createEvent("close");a.createEvent("drain");a.createEvent("error");a.createEvent("finish");a.createEvent("pipe");a.createEvent("unpipe");a.createEvent("readable");this.isEmpty=function(){return(this.buffer.length==0)};this.isWaiting=function(){return(this._readCheckImmediate==undefined)};this.write=function(c){for(var b in arguments){if(typeof(arguments[b])=="function"){this.once("drain",arguments[b]);break}}var d=Buffer.alloc(c.length);c.copy(d);this.buffer.push({offset:0,data:d});this.emit("readable");return(this.buffer.length==0?true:false)};this.read=function(){var f=arguments.length==0?undefined:arguments[0];var b=0;var d=[];while((f==undefined||b0){var c=this.buffer[0].data.length-this.buffer[0].offset;var e=this.buffer[0].offset;if(c>(f-b)){d.push(this.buffer[0].data.slice(e,e+f-b));this.buffer[0].offset+=(f-b);b+=(f-b)}else{d.push(this.buffer[0].data.slice(e));b+=c;this.buffer.shift()}}this._readCheckImmediate=setImmediate(function(g){g._readCheckImmediate=undefined;if(g.buffer.length==0){g.emit("drain")}else{g.emit("readable")}},this);return(Buffer.concat(d))}}function lme_heci(c){var a=require("events").inherits(this);a.createEvent("error");a.createEvent("connect");a.createEvent("notify");a.createEvent("bind");if((c!=null)&&(c.debug==true)){lme_port_offset=-100}var b=require("heci");this.INITIAL_RXWINDOW_SIZE=4096;this._ObjectID="lme";this._LME=b.create();this._LME._binded={};this._LME.LMS=this;this._LME.on("error",function(d){this.LMS.emit("error",d)});this._LME.on("connect",function(){this.on("data",function(k){var l=k.readUInt8(0);switch(l){default:console.log("Unhandled LME Command "+l+", "+k.length+" byte(s).");break;case APF_SERVICE_REQUEST:var A=k.readUInt32BE(1);var z=k.slice(5,A+5);if(z=="pfwd@amt.intel.com"||z=="auth@amt.intel.com"){var G=Buffer.alloc(5+A);G.writeUInt8(6,0);G.writeUInt32BE(A,1);G.write(z.toString(),5);this.write(G)}else{}break;case APF_GLOBAL_REQUEST:var A=k.readUInt32BE(1);var z=k.slice(5,A+5).toString();switch(z){case"tcpip-forward":var w=k.readUInt32BE(A+6);var H=k.readUInt32BE(A+10+w);if(this[z]==undefined){this[z]={}}if(this[z][H]!=null){for(var t in this.sockets){var h=this.sockets[t];if(h.localPort==H){this.sockets[t].end();delete this.sockets[t]}}}if(this[z][H]==null){this[z][H]=require("net").createServer();this[z][H].HECI=this;try{if(lme_port_offset==0){this[z][H].listen({port:H,host:"127.0.0.1"})}else{this[z][H].listen({port:(H+lme_port_offset)})}}catch(p){console.log("Binding error, LMS port "+(H+lme_port_offset)+": "+p)}this[z][H].on("connection",function(e){this.HECI.LMS.bindDuplexStream(e,e.remoteFamily,e.localPort-lme_port_offset)});this._binded[H]=true;this.LMS.emit("bind",this._binded)}var G=Buffer.alloc(5);G.writeUInt8(81,0);G.writeUInt32BE(H,1);this.write(G);break;case"cancel-tcpip-forward":var G=Buffer.alloc(1);G.writeUInt8(APF_REQUEST_SUCCESS,0);this.write(G);break;case"udp-send-to@amt.intel.com":var G=Buffer.alloc(1);G.writeUInt8(APF_REQUEST_FAILURE,0);this.write(G);break;default:break}break;case APF_CHANNEL_OPEN_CONFIRMATION:var J=k.readUInt32BE(1);var N=k.readUInt32BE(5);var O=k.readUInt32BE(9);if(this.sockets[J]!=undefined){this.sockets[J].lme.amtId=N;this.sockets[J].lme.rxWindow=O;this.sockets[J].lme.txWindow=O;this.sockets[J].lme.LME_CHANNEL_STATUS="LME_CS_CONNECTED";this.sockets[J].bufferedStream=new stream_bufferedWrite();this.sockets[J].bufferedStream.socket=this.sockets[J];this.sockets[J].bufferedStream.on("readable",function(){if(this.socket.lme.txWindow>0){var e=this.read(this.socket.lme.txWindow);var i=Buffer.alloc(9+e.length);i.writeUInt8(APF_CHANNEL_DATA,0);i.writeUInt32BE(this.socket.lme.amtId,1);i.writeUInt32BE(e.length,5);e.copy(i,9);this.socket.lme.txWindow-=e.length;this.socket.HECI.write(i)}});this.sockets[J].bufferedStream.on("drain",function(){this.socket.resume()});this.sockets[J].on("data",function(e){if(!this.bufferedStream.write(e)){this.pause()}});this.sockets[J].on("end",function(){var e=Buffer.alloc(5);e.writeUInt8(APF_CHANNEL_CLOSE,0);e.writeUInt32BE(this.lme.amtId,1);this.HECI.write(e)});this.sockets[J].resume()}break;case APF_PROTOCOLVERSION:var x=k.readUInt32BE(1);var y=k.readUInt32BE(5);var L=k.readUInt32BE(9);var G=Buffer.alloc(93);G.writeUInt8(192,0);G.writeUInt32BE(1,1);G.writeUInt32BE(0,5);G.writeUInt32BE(L,9);this.write(G);break;case APF_CHANNEL_WINDOW_ADJUST:var K=k.readUInt32BE(1);var g=k.readUInt32BE(5);if(this.sockets[K]!=undefined){this.sockets[K].lme.txWindow+=g;if(!this.sockets[K].bufferedStream.isEmpty()&&this.sockets[K].bufferedStream.isWaiting()){this.sockets[K].bufferedStream.emit("readable")}}else{console.log("Unknown Recipient ID/"+K+" for APF_CHANNEL_WINDOW_ADJUST")}break;case APF_CHANNEL_DATA:var K=k.readUInt32BE(1);var n=k.readUInt32BE(5);var m=k.slice(9,9+n);if((this.sockets!=null)&&(this.sockets[K]!=undefined)){this.sockets[K].pendingBytes.push(m.length);this.sockets[K].write(m,function(){var i=this.pendingBytes.shift();var e=Buffer.alloc(9);e.writeUInt8(APF_CHANNEL_WINDOW_ADJUST,0);e.writeUInt32BE(this.lme.amtId,1);e.writeUInt32BE(i,5);this.HECI.write(e)})}else{if((this.insockets!=null)&&(this.insockets[K]!=undefined)){var h=this.insockets[K];if(h.data==null){h.data=m.toString()}else{h.data+=m.toString()}h.rxWindow+=n;var s=parseHttp(h.data);if((s!=null)||(h.data.length>=8000)){var B=null;try{B=xmlParser.ParseWsman(s)}catch(o){}if(B!=null){this.LMS.emit("notify",B,h.options,_lmsNotifyToString(B),_lmsNotifyToCode(B))}var f=Buffer.alloc(5);f.writeUInt8(APF_CHANNEL_CLOSE,0);f.writeUInt32BE(d,1);this.write(f)}else{if(h.rxWindow>6000){var f=Buffer.alloc(9);f.writeUInt8(APF_CHANNEL_WINDOW_ADJUST,0);f.writeUInt32BE(h.amtId,1);f.writeUInt32BE(h.rxWindow,5);this.write(f);h.rxWindow=0}}}else{console.log("Unknown Recipient ID/"+K+" for APF_CHANNEL_DATA")}}break;case APF_CHANNEL_OPEN_FAILURE:var K=k.readUInt32BE(1);var M=k.readUInt32BE(5);if((this.sockets!=null)&&(this.sockets[K]!=undefined)){this.sockets[K].end();delete this.sockets[K]}else{if((this.insockets!=null)&&(this.insockets[K]!=undefined)){delete this.insockets[K]}else{console.log("Unknown Recipient ID/"+K+" for APF_CHANNEL_OPEN_FAILURE")}}break;case APF_CHANNEL_CLOSE:var K=k.readUInt32BE(1);if((this.sockets!=null)&&(this.sockets[K]!=undefined)){this.sockets[K].end();var d=this.sockets[K].lme.amtId;var f=Buffer.alloc(5);delete this.sockets[K];f.writeUInt8(APF_CHANNEL_CLOSE,0);f.writeUInt32BE(d,1);this.write(f)}else{if((this.insockets!=null)&&(this.insockets[K]!=undefined)){delete this.insockets[K]}else{console.log("Unknown Recipient ID/"+K+" for APF_CHANNEL_CLOSE")}}break;case APF_CHANNEL_OPEN:var A=k.readUInt32BE(1);var z=k.slice(5,A+5).toString();var j=k.readUInt32BE(A+5);var u=k.readUInt32BE(A+9);var r=k.readUInt32BE(A+17);var q=k.slice(A+21,A+21+r).toString();var I=k.readUInt32BE(A+21+r);var D=k.readUInt32BE(A+25+r);var C=k.slice(A+29+r,A+29+r+D).toString();var E=k.readUInt32BE(A+29+r+D);if(this.insockets==null){this.insockets={}}var F=++lme_id;var v=new lme_object();v.ourId=F;v.amtId=j;v.txWindow=u;v.rxWindow=0;v.options={target:q,targetPort:I,source:C,sourcePort:E};this.insockets[F]=v;var f=Buffer.alloc(17);f.writeUInt8(APF_CHANNEL_OPEN_CONFIRMATION,0);f.writeUInt32BE(j,1);f.writeUInt32BE(F,5);f.writeUInt32BE(4000,9);f.writeUInt32BE(4294967295,13);this.write(f);break}});this.LMS.emit("connect");this.resume()});this.bindDuplexStream=function(e,h,g){var j=e;j.pendingBytes=[];j.HECI=this._LME;j.LMS=this;j.lme=new lme_object();j.lme.Socket=j;j.localPort=g;var d=new MemoryStream();d.writeUInt8(90);d.writeUInt32BE(15);d.write("forwarded-tcpip");d.writeUInt32BE(j.lme.ourId);d.writeUInt32BE(this.INITIAL_RXWINDOW_SIZE);d.writeUInt32BE(4294967295);for(var f=0;f<2;++f){if(h=="IPv6"){d.writeUInt32BE(3);d.write("::1")}else{d.writeUInt32BE(9);d.write("127.0.0.1")}d.writeUInt32BE(g)}this._LME.write(d.buffer);if(this._LME.sockets==undefined){this._LME.sockets={}}this._LME.sockets[j.lme.ourId]=j;j.pause()};this._LME.connect(b.GUIDS.LME,{noPipeline:0})}function parseHttp(c){var d=c.indexOf("\r\n\r\n");if((d==-1)||(c.length<(d+2))){return null}var b=require("http-headers")(c.substring(0,d),true);var a=parseInt(b["content-length"]);if(c.length>=a+d+4){return c.substring(d+4,d+4+a)}return null}function _lmsNotifyToCode(c){if((c==null)||(c.Body==null)||(c.Body.MessageID==null)){return null}var b=c.Body.MessageID;try{b+="-"+c.Body.MessageArguments[0]}catch(a){}return b}function _lmsNotifyToString(c){if((c==null)||(c.Body==null)||(c.Body.MessageID==null)){return null}var b=c.Body.MessageID;try{b+="-"+c.Body.MessageArguments[0]}catch(a){}if(lmsEvents[b]){return lmsEvents[b]}return null}var lmsEvents={iAMT0001:"System Defense Policy %1s triggered.",iAMT0002:"Agent Presence Agent %1s not started.",iAMT0003:"Agent Presence Agent %1s stopped.",iAMT0004:"Agent Presence Agent %1s running.",iAMT0005:"Agent Presence Agent %1s expired.",iAMT0006:"Agent Presence Agent %1s suspended.",iAMT0007:"Host software attempt to disable AMT Network link detected.",iAMT0008:"Host software attempt to disable AMT Network link detected -- Host Network link blocked.",iAMT0009:"AMT clock or FLASH wear-out protection disabled.",iAMT0010:"Intel(R) AMT Network Interface %1s heuristics defense slow threshold trespassed.",iAMT0011:"Intel(R) AMT Network Interface %1s heuristics defense fast threshold trespassed.",iAMT0012:"Intel(R) AMT Network Interface %1s heuristics defense factory defined threshold trespassed.",iAMT0013:"Intel(R) AMT Network Interface %1s heuristics defense Encounter timeout expired.",iAMT0014:"General certificate error.",iAMT0015:"Certificate expired.",iAMT0016:"No trusted root certificate.",iAMT0017:"Not configured to work with server certificate.",iAMT0018:"Certificate revoked.",iAMT0019:"RSA exponent too large.",iAMT0020:"RSA modulus too large.",iAMT0021:"Unsupported digest.",iAMT0022:"Distinguished name too long.",iAMT0023:"Key usage missing.",iAMT0024:"General SSL handshake error.",iAMT0025:"General 802.1x error.",iAMT0026:"AMT Diagnostic AlertEAC error - General NAC error.",iAMT0027:"AMT Diagnostic AlertEAC error - attempt to get a NAC posture while AMT NAC is disabled.",iAMT0028:"AMT Diagnostic AlertEAC error - attempt to get a posture of an unsupported type.",iAMT0029:"Audit log storage is 50% full.",iAMT0030:"Audit log storage is 75% full.",iAMT0031:"Audit log storage is 85% full.",iAMT0032:"Audit log storage is 95% full.",iAMT0033:"Audit log storage is full.",iAMT0034:"Firmware Update Event - Partial.",iAMT0035:"Firmware Update Event - Failure.",iAMT0036:"Remote connectivity initiated.",iAMT0037:"ME Presence event.","iAMT0038-0":"AMT is being unprovisioned using BIOS command.","iAMT0038-1":"AMT is being unprovisioned using Local MEI command.","iAMT0038-2":"AMT is being unprovisioned using Local WS-MAN/SOAP command.","iAMT0038-3":"AMT is being unprovisioned using Remote WS-MAN/SOAP command.",iAMT0039:"HW Asset Error.",iAMT0050:"User Notification Alert - General Notification.","iAMT0050-16":"User Notification Alert - Circuit Breaker notification (CB Drop TX filter hit.).","iAMT0050-17":"User Notification Alert - Circuit Breaker notification (CB Rate Limit TX filter hit.).","iAMT0050-18":"User Notification Alert - Circuit Breaker notification (CB Drop RX filter hit.).","iAMT0050-19":"User Notification Alert - Circuit Breaker notification (CB Rate Limit RX filter hit.).","iAMT0050-32":"User Notification Alert - EAC notification.","iAMT0050-48":"User Notification Alert - Remote diagnostics - (Remote Redirection session started - SOL).","iAMT0050-49":"User Notification Alert - Remote diagnostics - (Remote Redirection session stopped - SOL).","iAMT0050-50":"User Notification Alert - Remote diagnostics. (Remote Redirection session started - IDE-R).","iAMT0050-51":"User Notification Alert - Remote diagnostics. (Remote Redirection session stopped - IDE-R).","iAMT0050-66":"User Notification Alert - WLAN notification (Host profile mismatch - Management Interface ignored).","iAMT0050-67":"User Notification Alert - WLAN notification (Management device overrides host radio).","iAMT0050-68":"User Notification Alert - WLAN notification (Host profile security mismatch).","iAMT0050-69":"User Notification Alert - WLAN notification (Management device relinquishes control over host Radio).",iAMT0051:"User Notification Alert - SecIo event.","iAMT0051-0":"User Notification Alert - SecIo event semaphore at host.","iAMT0051-1":"User Notification Alert - semaphore at ME.","iAMT0051-2":"User Notification Alert - SecIo event - semaphore timeout.",iAMT0052:"User Notification Alert - KVM session event.","iAMT0052-0":"User Notification Alert - KVM session requested.","iAMT0052-1":"User Notification Alert - KVM session started.","iAMT0052-2":"User Notification Alert - KVM session stopped.","iAMT0052-3":"User Notification Alert - KVM data channel.",iAMT0053:"User Notification Alert - RCS notification.","iAMT0053-50":"User Notification Alert - RCS notification (HW button pressed. Connection initiated automatically).","iAMT0053-52":"User Notification Alert - RCS notification (HW button pressed. Connection wasn't initiated automatically).","iAMT0053-53":"User Notification Alert - RCS notification (Contracts updated).",iAMT0054:"User Notification Alert - WLAN notification. Wireless Profile sync enablement state changed.",iAMT0055:"User Notification Alert - Provisioning state change notification.","iAMT0055-0":"User Notification Alert - Provisioning state change notification - Pre-configuration.","iAMT0055-1":"User Notification Alert - Provisioning state change notification - In configuration.","iAMT0055-2":"User Notification Alert - Provisioning state change notification - Post-configuration.","iAMT0055-3":"User Notification Alert - Provisioning state change notification - Unprovision process has started.",iAMT0056:"User Notification Alert - System Defense change notification.",iAMT0057:"User Notification Alert - Network State change notification.",iAMT0058:"User Notification Alert - Remote Access change notification.","iAMT0058-1":"User Notification Alert - Remote Access change notification - tunnel is closed.",iAMT0059:"User Notification Alert - KVM enabled event.","iAMT0059-0":"User Notification Alert - KVM enabled event - KVM disabled.","iAMT0059-1":"User Notification Alert - KVM enabled event - KVM enabled (both from MEBx and PTNI).",iAMT0060:"User Notification Alert - SecIO configuration event.",iAMT0061:"ME FW reset occurred.",iAMT0062:"User Notification Alert - IpSyncEnabled event.","iAMT0062-0":"User Notification Alert - IpSyncEnabled event - IpSync disabled.","iAMT0062-1":"User Notification Alert - IpSyncEnabled event - IpSync enabled.",iAMT0063:"User Notification Alert - HTTP Proxy sync enabled event.","iAMT0063-0":"User Notification Alert - HTTP Proxy sync enabled event - HTTP Proxy Sync disabled.","iAMT0063-1":"User Notification Alert - HTTP Proxy sync enabled event - HTTP Proxy Sync enabled.",iAMT0064:"User Notification Alert - User Consent event.","iAMT0064-1":"User Notification Alert - User Consent event - User Consent granted.","iAMT0064-2":"User Notification Alert - User Consent event - User Consent ended.","iAMT0067-0":"Graceful Remote Control Operation - Shutdown.","iAMT0067-1":"Graceful Remote Control Operation - Reset.","iAMT0067-2":"Graceful Remote Control Operation - Hibernate.","iAMT0068-0":"Link Protection Notification - No link protection.","iAMT0068-1":"Link Protection Notification - Passive link protection.","iAMT0068-2":"Link Protection Notification - High link protection.","iAMT0069-0":"Local Time Sync Enablement Notification - Local Time Sync Disabled.","iAMT0069-1":"Local Time Sync Enablement Notification - Local Time Sync Enabled.",iAMT0070:"Host Reset Triggered by WD Expiration Notification.",PLAT0004:"The chassis %1s was opened.",PLAT0005:"The chassis %1s was closed.",PLAT0006:"The drive bay %1s was opened.",PLAT0007:"The drive bay %1s was closed.",PLAT0008:"The I/O card area %1s was opened.",PLAT0009:"The I/O card area %1s was closed.",PLAT0010:"The processor area %1s was opened.",PLAT0011:"The processor area %1s was closed.",PLAT0012:"The LAN %1s has been disconnected.",PLAT0013:"The LAN %1s has been connected.",PLAT0016:"The permission to insert package %1s has been granted.",PLAT0017:"The permission to insert package %1s has been removed.",PLAT0018:"The fan card area %1s is open.",PLAT0019:"The fan card area %1s is closed.",PLAT0022:"The computer system %1s has detected a secure mode violation.",PLAT0024:"The computer system %1s has detected a pre-boot user password violation.",PLAT0026:"The computer system %1s has detected a pre-boot setup password violation.",PLAT0028:"The computer system %1s has detected a network boot password violation.",PLAT0030:"The computer system %1s has detected a password violation.",PLAT0032:"The management controller %1s has detected an out-of-band password violation.",PLAT0034:"The processor %1s has been added.",PLAT0035:"The processor %1s has been removed.",PLAT0036:"An over-temperature condition has been detected on the processor %1s.",PLAT0037:"An over-temperature condition has been removed on the processor %1s.",PLAT0038:"The processor %1s is operating in a degraded State.",PLAT0039:"The processor %1s is no longer operating in a degraded State.",PLAT0040:"The processor %1s has failed.",PLAT0042:"The processor %1s has failed.",PLAT0044:"The processor %1s has failed.",PLAT0046:"The processor %1s has failed.",PLAT0048:"The processor %1s has failed.",PLAT0060:"The processor %1s has been enabled.",PLAT0061:"The processor %1s has been disabled.",PLAT0062:"The processor %1s has a configuration mismatch.",PLAT0064:"A terminator has been detected on the processor %1s.",PLAT0084:"The Power Supply %1s has been added.",PLAT0085:"The Power Supply %1s has been removed.",PLAT0086:"The Power Supply %1s has failed.",PLAT0088:"Failure predicted on power supply %1s.",PLAT0096:"The input to power supply %1s has been lost or fallen out of range.",PLAT0098:"The power supply %1s is operating in an input state that is out of range.",PLAT0099:"The power supply %1s has returned to a normal input state.",PLAT0100:"The power supply %1s has lost input.",PLAT0104:"The power supply %1s has a configuration mismatch.",PLAT0106:"Power supply %1s has been disabled.",PLAT0107:"Power supply %1s has been enabled.",PLAT0108:"Power supply %1s has been power cycled.",PLAT0110:"Power supply %1s has encountered an error during power down.",PLAT0112:"Power supply %1s has lost power.",PLAT0114:"Soft power control has failed for power supply %1s.",PLAT0116:"Power supply %1s has failed.",PLAT0118:"Failure predicted on power supply %1s.",PLAT0120:"Memory subsystem failure.",PLAT0122:"DIMM missing.",PLAT0124:"Memory error detected & corrected for DIMM %1s.",PLAT0128:"Memory DIMM %1s added.",PLAT0129:"Memory DIMM %1s removed.",PLAT0130:"Memory DIMM %1s enabled.",PLAT0131:"Memory DIMM %1s disabled.",PLAT0134:"Memory parity error for DIMM %1s.",PLAT0136:"Memory scrub failure for DIMM %1s.",PLAT0138:"Memory uncorrectable error detected for DIMM %1s.",PLAT0140:"Memory sparing initiated for DIMM %1s.",PLAT0141:"Memory sparing concluded for DIMM %1s.",PLAT0142:"Memory DIMM %1s Throttled.",PLAT0144:"Memory logging limit reached for DIMM %1s.",PLAT0145:"Memory logging limit removed for DIMM %1s.",PLAT0146:"An over-temperature condition has been detected on the Memory DIMM %1s.",PLAT0147:"An over-temperature condition has been removed on the Memory DIMM %1s.",PLAT0162:"The drive %1s has been added.",PLAT0163:"The drive %1s has been removed.",PLAT0164:"The drive %1s has been disabled due to a detected fault.",PLAT0167:"The drive %1s has been enabled.",PLAT0168:"Failure predicted on drive %1s.",PLAT0170:"Hot spare enabled for %1s.",PLAT0171:"Hot spare disabled for %1s.",PLAT0172:"Consistency check has begun for %1s.",PLAT0173:"Consistency check completed for %1s.",PLAT0174:"Array %1s is in critical condition.",PLAT0176:"Array %1s has failed.",PLAT0177:"Array %1s has been restored.",PLAT0178:"Rebuild in progress for array %1s.",PLAT0179:"Rebuild completed for array %1s.",PLAT0180:"Rebuild Aborted for array %1s.",PLAT0184:"The system %1s encountered a POST error.",PLAT0186:"The system %1s encountered a firmware hang.",PLAT0188:"The system %1s encountered firmware progress.",PLAT0192:"The log %1s has been disabled.",PLAT0193:"The log %1s has been enabled.",PLAT0194:"The log %1s has been disabled.",PLAT0195:"The log %1s has been enabled.",PLAT0196:"The log %1s has been disabled.",PLAT0198:"The log %1s has been enabled.",PLAT0200:"The log %1s has been cleared.",PLAT0202:"The log %1s is full.",PLAT0203:"The log %1s is no longer full.",PLAT0204:"The log %1s is almost full.",PLAT0208:"The log %1s has a configuration error.",PLAT0210:"The system %1s has been reconfigured.",PLAT0212:"The system %1s has encountered an OEM system boot event.",PLAT0214:"The system %1s has encountered an unknown system hardware fault.",PLAT0216:"The system %1s has generated an auxiliary log entry.",PLAT0218:"The system %1s has executed a PEF action.",PLAT0220:"The system %1s has synchronized the system clock.",PLAT0222:"A diagnostic interrupt has occurred on system %1s.",PLAT0224:"A bus timeout has occurred on system %1s.",PLAT0226:"An I/O channel check NMI has occurred on system %1s.",PLAT0228:"A software NMI has occurred on system %1s.",PLAT0230:"System %1s has recovered from an NMI.",PLAT0232:"A PCI PERR has occurred on system %1s.",PLAT0234:"A PCI SERR has occurred on system %1s.",PLAT0236:"An EISA fail safe timeout occurred on system %1s.",PLAT0238:"A correctable bus error has occurred on system %1s.",PLAT0240:"An uncorrectable bus error has occurred on system %1s.",PLAT0242:"A fatal NMI error has occurred on system %1s.",PLAT0244:"A fatal bus error has occurred on system %1s.",PLAT0246:"A bus on system %1s is operating in a degraded state.",PLAT0247:"A bus on system %1s is no longer operating in a degraded state.",PLAT0248:"The power button %1s has been pressed.",PLAT0249:"The power button %1s has been released.",PLAT0250:"The sleep button %1s has been pressed.",PLAT0251:"The sleep button %1s has been released.",PLAT0252:"The reset button %1s has been pressed.",PLAT0253:"The reset button %1s has been released.",PLAT0254:"The latch to %1s has been opened.",PLAT0255:"The latch to %1s has been closed.",PLAT0256:"The service request %1s has been enabled.",PLAT0257:"The service request %1s has been completed.",PLAT0258:"Power control of system %1s has failed.",PLAT0262:"The network port %1s has been connected.",PLAT0263:"The network port %1s has been disconnected.",PLAT0266:"The connector %1s has encountered a configuration error.",PLAT0267:"The connector %1s configuration error has been repaired.",PLAT0272:"Power on for system %1s.",PLAT0274:"Power cycle hard requested for system %1s.",PLAT0276:"Power cycle soft requested for system %1s.",PLAT0278:"PXE boot requested for system %1s.",PLAT0280:"Diagnostics boot requested for system %1s.",PLAT0282:"System restart requested for system %1s.",PLAT0284:"System restart begun for system %1s.",PLAT0286:"No bootable media available for system %1s.",PLAT0288:"Non-bootable media selected for system %1s.",PLAT0290:"PXE server not found for system %1s.",PLAT0292:"User timeout on boot for system %1s.",PLAT0296:"System %1s boot from floppy initiated.",PLAT0298:"System %1s boot from local drive initiated.",PLAT0300:"System %1s boot from PXE on network port initiated.",PLAT0302:"System %1s boot diagnostics initiated.",PLAT0304:"System %1s boot from CD initiated.",PLAT0306:"System %1s boot from ROM initiated.",PLAT0312:"System %1s boot initiated.",PLAT0320:"Critical stop during OS load on system %1s.",PLAT0322:"Run-time critical stop on system %1s.",PLAT0324:"OS graceful stop on system %1s.",PLAT0326:"OS graceful shutdown begun on system %1s.",PLAT0327:"OS graceful shutdown completed on system %1s.",PLAT0328:"Agent not responding on system %1s.",PLAT0329:"Agent has begun responding on system %1s.",PLAT0330:"Fault in slot on system %1s.",PLAT0331:"Fault condition removed on system %1s.",PLAT0332:"Identifying slot on system %1s.",PLAT0333:"Identify stopped on slot for system %1s.",PLAT0334:"Package installed in slot for system %1s.",PLAT0336:"Slot empty system %1s.",PLAT0338:"Slot in system %1s is ready for installation.",PLAT0340:"Slot in system %1s is ready for removal.",PLAT0342:"Power is off on slot of system %1s.",PLAT0344:"Power is on for slot of system %1s.",PLAT0346:"Removal requested for slot of system %1s.",PLAT0348:"Interlock activated on slot of system %1s.",PLAT0349:"Interlock de-asserted on slot of system %1s.",PLAT0350:"Slot disabled on system %1s.",PLAT0351:"Slot enabled on system %1s.",PLAT0352:"Slot of system %1s holds spare.",PLAT0353:"Slot of system %1s no longer holds spare.",PLAT0354:"Computer system %1s enabled.",PLAT0356:"Computer system %1s is in sleep - light mode.",PLAT0358:"Computer system %1s is in hibernate.",PLAT0360:"Computer system %1s is in standby.",PLAT0362:"Computer system %1s is in soft off mode.",PLAT0364:"Computer system %1s is in hard off mode.",PLAT0366:"Computer system %1s is sleeping.",PLAT0368:"Watchdog timer expired for %1s.",PLAT0370:"Reboot of system initiated by watchdog %1s.",PLAT0372:"Powering off system initiated by watchdog %1s.",PLAT0374:"Power cycle of system initiated by watchdog %1s.",PLAT0376:"Watchdog timer interrupt occurred for %1s.",PLAT0378:"A page alert has been generated for system %1s.",PLAT0380:"A LAN alert has been generated for system %1s.",PLAT0382:"An event trap has been generated for system %1s.",PLAT0384:"An SNMP trap has been generated for system %1s.",PLAT0390:"%1s detected as present.",PLAT0392:"%1s detected as absent.",PLAT0394:"%1s has been disabled.",PLAT0395:"%1s has been enabled.",PLAT0396:"Heartbeat lost for LAN %1s.",PLAT0397:"Heartbeat detected for LAN %1s.",PLAT0398:"Sensor %1s is unavailable or degraded on management system.",PLAT0399:"Sensor %1s has returned to normal on management system.",PLAT0400:"Controller %1s is unavailable or degraded on management system.",PLAT0401:"Controller %1s has returned to normal on management system.",PLAT0402:"Management system %1s is off-line.",PLAT0404:"Management system %1s is disabled.",PLAT0405:"Management system %1s is enabled.",PLAT0406:"Sensor %1s has failed on management system.",PLAT0408:"FRU %1s has failed on management system.",PLAT0424:"The battery %1s is critically low.",PLAT0427:"The battery %1s is no longer critically low.",PLAT0430:"The battery %1s has been removed from unit.",PLAT0431:"The battery %1s has been added.",PLAT0432:"The battery %1s has failed.",PLAT0434:"Session audit is deactivated on system %1s.",PLAT0435:"Session audit is activated on system %1s.",PLAT0436:"A hardware change occurred on system %1s.",PLAT0438:"A firmware or software change occurred on system %1s.",PLAT0440:"A hardware incompatibility was detected on system %1s.",PLAT0442:"A firmware or software incompatibility was detected on system %1s.",PLAT0444:"Invalid or unsupported hardware was detected on system %1s.",PLAT0446:"Invalid or unsupported firmware or software was detected on system %1s.",PLAT0448:"A successful hardware change was detected on system %1s.",PLAT0450:"A successful software or firmware change was detected on system %1s.",PLAT0464:"FRU %1s not installed on system.",PLAT0465:"FRU %1s installed on system.",PLAT0466:"Activation requested for FRU %1s on system.",PLAT0467:"FRU %1s on system is active.",PLAT0468:"Activation in progress for FRU %1s on system.",PLAT0470:"Deactivation request for FRU %1s on system.",PLAT0471:'FRU %1s on system is in standby or "hot spare" state.',PLAT0472:"Deactivation in progress for FRU %1s on system.",PLAT0474:"Communication lost with FRU %1s on system.",PLAT0476:"Numeric sensor %1s going low (lower non-critical).",PLAT0478:"Numeric sensor %1s going high (lower non-critical).",PLAT0480:"Numeric sensor %1s going low (lower critical).",PLAT0482:"Numeric sensor %1s going high (lower critical).",PLAT0484:"Numeric sensor %1s going low (lower non-recoverable).",PLAT0486:"Numeric sensor %1s going high (lower non-critical).",PLAT0488:"Numeric sensor %1s going low (upper non-critical).",PLAT0490:"Numeric sensor %1s going high (upper non-critical).",PLAT0492:"Numeric sensor %1s going low (upper critical).",PLAT0494:"Numeric sensor %1s going high (upper critical).",PLAT0496:"Numeric sensor %1s going low (upper non-recoverable).",PLAT0498:"Numeric sensor %1s going high (upper non-recoverable).",PLAT0500:"Sensor %1s has transitioned to idle.",PLAT0502:"Sensor %1s has transitioned to active.",PLAT0504:"Sensor %1s has transitioned to busy.",PLAT0508:"Sensor %1s has asserted.",PLAT0509:"Sensor %1s has de-asserted.",PLAT0510:"Sensor %1s is asserting predictive failure.",PLAT0511:"Sensor %1s is de-asserting predictive failure.",PLAT0512:"Sensor %1s has indicated limit exceeded.",PLAT0513:"Sensor %1s has indicated limit no longer exceeded.",PLAT0514:"Sensor %1s has indicated performance met.",PLAT0516:"Sensor %1s has indicated performance lags.",PLAT0518:"Sensor %1s has transitioned to normal state.",PLAT0520:"Sensor %1s has transitioned from normal to non-critical state.",PLAT0522:"Sensor %1s has transitioned to critical from a less severe state.",PLAT0524:"Sensor %1s has transitioned to non-recoverable from a less severe state.",PLAT0526:"Sensor %1s has transitioned to non-critical from a more severe state.",PLAT0528:"Sensor %1s has transitioned to critical from a non-recoverable state.",PLAT0530:"Sensor %1s has transitioned to non-recoverable.",PLAT0532:"Sensor %1s indicates a monitor state.",PLAT0534:"Sensor %1s has an informational state.",PLAT0536:"Device %1s has been added.",PLAT0537:"Device %1s has been removed from unit.",PLAT0538:"Device %1s has been enabled.",PLAT0539:"Device %1s has been disabled.",PLAT0540:"Sensor %1s has indicated a running state.",PLAT0544:"Sensor %1s has indicated a power off state.",PLAT0546:"Sensor %1s has indicated an on-line state.",PLAT0548:"Sensor %1s has indicated an off-line state.",PLAT0550:"Sensor %1s has indicated an off-duty state.",PLAT0552:"Sensor %1s has indicated a degraded state.",PLAT0554:"Sensor %1s has indicated a power save state.",PLAT0556:"Sensor %1s has indicated an install error.",PLAT0558:"Redundancy %1s has been lost.",PLAT0560:"Redundancy %1s has been reduced.",PLAT0561:"Redundancy %1s has been restored.",PLAT0562:"%1s has transitioned to a D0 power state.",PLAT0564:"%1s has transitioned to a D1 power state.",PLAT0566:"%1s has transitioned to a D2 power state.",PLAT0568:"%1s has transitioned to a D3 power state.",PLAT0720:"The System %1s encountered firmware progress - memory initialization entry.",PLAT0721:"The System %1s encountered firmware progress - memory initialization exit.",PLAT0722:"The System %1s encountered firmware progress - hard drive initialization entry.",PLAT0723:"The System %1s encountered firmware progress - hard drive initialization exit.",PLAT0724:"The System %1s encountered firmware progress - user authentication.",PLAT0728:"The System %1s encountered firmware progress - USR resource configuration entry.",PLAT0729:"The System %1s encountered firmware progress - USR resource configuration exit.",PLAT0730:"The System %1s encountered firmware progress - PCI recource configuration entry.",PLAT0731:"The System %1s encountered firmware progress - PCI recource configuration exit.",PLAT0732:"The System %1s encountered firmware progress - Option ROM initialization entry.",PLAT0733:"The System %1s encountered firmware progress - Option ROM initialization entry exit.",PLAT0734:"The System %1s encountered firmware progress -video initialization entry entry.",PLAT0735:"The System %1s encountered firmware progress - video initialization entry exit.",PLAT0736:"The System %1s encountered firmware progress - cache initialization entry.",PLAT0737:"The System %1s encountered firmware progress - cache initialization exit.",PLAT0738:"The System %1s encountered firmware progress - keyboard controller initialization entry.",PLAT0739:"The System %1s encountered firmware progress - keyboard controller initialization exit.",PLAT0740:"The System %1s encountered firmware progress - motherboard initialization entry.",PLAT0741:"The System %1s encountered firmware progress - motherboard initialization exit.",PLAT0742:"The System %1s encountered firmware progress - floppy disk initialization entry.",PLAT0743:"The System %1s encountered firmware progress - floppy disk initialization exit.",PLAT0744:"The System %1s encountered firmware progress - keyboard test entry.",PLAT0745:"The System %1s encountered firmware progress - keyboard test exit.",PLAT0746:"The System %1s encountered firmware progress - pointing device test entry.",PLAT0747:"The System %1s encountered firmware progress - pointing device test exit.",PLAT0750:"The System %1s encountered firmware progress - dock enable entry.",PLAT0751:"The System %1s encountered firmware progress - dock enable exit.",PLAT0752:"The System %1s encountered firmware progress - dock disable entry.",PLAT0753:"The System %1s encountered firmware progress - dock disable exit.",PLAT0760:"The System %1s encountered firmware progress - start OS boot process.",PLAT0762:"The System %1s encountered firmware progress - call OS wake vector.",PLAT0764:"The System %1s encountered firmware progress - unrecoverable keyboard failure.",PLAT0766:"The System %1s encountered firmware progress - no video device detected.",PLAT0768:"The System %1s encountered firmware progress - SMART alert detected on drive.",PLAT0770:"The System %1s encountered firmware progress - unrecoverable boot device failure.",PLAT0789:"Corrupt BIOS detected.",PLAT0790:"The System %1s encountered PCI configuration failure.",PLAT0791:"The System %1s encountered a video subsystem failure.",PLAT0792:"The System %1s encountered a storage subsystem failure.",PLAT0793:"The System %1s encountered a USB subsystem failure.",PLAT0794:"The System %1s has detected no memory in the system.",PLAT0795:"The System %1s encountered a motherboard failure.",PLAT0796:"The System %1s encountered a memory Regulator Voltage Bad.",PLAT0797:"%1s PCI reset is not deasserting.",PLAT0798:"%1s Non-Motherboard Regulator Failure.",PLAT0799:"%1s Power Supply Cable failure.",PLAT0800:"%1s Motherboard regulator failure.",PLAT0801:"%1s System component compatibility mismatch."};module.exports=lme_heci; \ No newline at end of file diff --git a/agents/modules_meshcore_min/amt-manage.min.js b/agents/modules_meshcore_min/amt-manage.min.js new file mode 100644 index 00000000..7f7499cd --- /dev/null +++ b/agents/modules_meshcore_min/amt-manage.min.js @@ -0,0 +1 @@ +function AmtManager(d,q,v){var L=function(R){d.SendCommand({action:"msg",type:"console",value:R})};var r=function(R){if(v){L("amt-manager: "+R+"
")}};var h=null,i=0;var f=null,g=0;var e=null;var H=null;var G=null;var k=null;var F=this;var E;F.state=0;F.lmsstate=0;F.onStateChange=null;F.setDebug=function(R){v=R};F.setPolicy=function(R){if(JSON.stringify(k)!=JSON.stringify(R)){k=R;if(m==null){F.applyPolicy()}}};var K=0;F.reset=function(){++K;h=null,i=0,f=null,g=0,F.state=0,F.lmsstate=0;try{var R=require("amt-mei");h=new R();h.on("error",function(T){r("MEI error");h=null;i=-1;F.state=-1;F.onStateChange(i)});h.getVersion(function(T){if(T==null){i=-1;F.state=-1;if(F.onStateChange!=null){F.onStateChange(i)}if(K<10){setTimeout(F.reset,10000)}}else{e=T;i=2;F.state=2;K=0;if(F.onStateChange!=null){F.onStateChange(i)}F.lmsreset()}})}catch(S){r("MEI exception: "+S);h=null;i=-1;F.state=-1}};var j=null;F.getAmtInfo=function(S){if((h==null)||(i<2)){if(S!=null){S(null)}return}try{j={Flags:0};h.getProtocolVersion(function(T){if(T!=null){j.MeiVersion=T}});h.getVersion(function(T){if(T){j.Versions={};for(var U in T.Versions){j.Versions[T.Versions[U].Description]=T.Versions[U].Version}}});h.getProvisioningMode(function(T){if(T){j.ProvisioningMode=T.mode}});h.getProvisioningState(function(T){if(T){j.ProvisioningState=T.state}});h.getEHBCState(function(T){if((T!=null)&&(T.EHBC==true)){j.Flags+=1}});h.getControlMode(function(T){if(T!=null){if(T.controlMode==1){j.Flags+=2}if(T.controlMode==2){j.Flags+=4}}});h.getLanInterfaceSettings(0,function(T){if(T){j.net0=T}});h.getLanInterfaceSettings(1,function(T){if(T){j.net1=T}});h.getUuid(function(T){if((T!=null)&&(T.uuid!=null)){j.UUID=T.uuid}});h.getDnsSuffix(function(T){if(T!=null){j.DNS=T}if(S!=null){S(j)}})}catch(R){if(S!=null){S(null)}return}};var t=function(U){if((U==null)||(U.Body==null)||(U.Body.MessageID==null)||(U.Body.MessageArguments==null)){return null}var R=U.Body.MessageID,S=U.Body.MessageArguments[0],T=null;switch(R){case"iAMT0050":if(S=="48"){T="Intel® AMT Serial-over-LAN connected"}else{if(S=="49"){T="Intel® AMT Serial-over-LAN disconnected"}}break;case"iAMT0052":if(S=="1"){T="Intel® AMT KVM connected"}else{if(S=="2"){T="Intel® AMT KVM disconnected"}}break;default:break}if(T!=null){d.SendCommand({action:"msg",type:"notify",value:T,tag:"general"})}};F.lmsreset=function(){var R=null,S=0;F.lmsstate=0;try{var U=require("amt-lme");S=1;F.lmsstate=1;R=new U();R.on("error",function(V){S=0;F.lmsstate=0;R=null;r("LMS error");M(1)});R.on("connect",function(){S=2;F.lmsstate=2;r("LMS connected");M(2)});R.on("notify",function(W,X,Y,V){if(V=="iAMT0052-3"){y()}else{t(W)}})}catch(T){S=-1;F.lmsstate=-1;R=null}};var M=function(R){if((h==null)||(i<2)||(e==null)){return}h.getLocalSystemAccount(function(Y){if(Y==null){return}var W=require("amt-wsman-duk");var X=require("amt-wsman");var S=require("amt");H=new X(W,"127.0.0.1",16992,Y.user,Y.pass,false);G=new S(H);i=3;F.state=3;if(F.onStateChange!=null){F.onStateChange(i)}if(m==null){F.applyPolicy()}var T=null;try{for(var V in e.Versions){if(e.Versions[V].Description=="AMT"){T=parseInt(e.Versions[V].Version.split(".")[0])}}}catch(U){}if((T!=null)&&(T>=12)){y("skip");F.kvmTempTimer=setInterval(function(){y()},2000);A(JSON.stringify({action:"restart",ver:1}))}})};var y=function(R){G.IPS_KVMRedirectionSettingData_DataChannelRead(F.kvmDataGetResponse,R)};var x=function(U,S,T,V,W){if((W!="skip")&&(V==200)&&(T.Body.ReturnValue==0)){var X=null;try{X=Buffer.from(T.Body.DataMessage,"base64").toString()}catch(R){return}if(X!=null){F.kvmProcessData(T.Body.RealmsBitmap,T.Body.MessageId,X)}}};var O=null;var z=function(U,T,W){var R=null;try{R=JSON.parse(W)}catch(S){}if((R!=null)&&(R.action)){if(R.action=="present"){A(JSON.stringify({action:"present",ver:1,platform:process.platform}))}if(R.action=="offer"){O={};var V=require("ILibWebRTC");O.webrtc=V.createConnection();O.webrtc.on("connected",function(){});O.webrtc.on("disconnected",function(){F.webRtcCleanUp()});O.webrtc.on("dataChannel",function(X){O.rtcchannel=X;O.kvm=mesh.getRemoteDesktopStream();O.kvm.pipe(O.rtcchannel,{dataTypeSkip:1,end:false});O.rtcchannel.on("end",function(){F.webRtcCleanUp()});O.rtcchannel.on("data",function(Y){F.kvmCtrlData(this,Y)});O.rtcchannel.pipe(O.kvm,{dataTypeSkip:1,end:false})});A(JSON.stringify({action:"answer",ver:1,sdp:O.webrtc.setOffer(R.sdp)}))}}};var w=function(S,U){if(U.length>0&&U.charCodeAt(0)!=123){if(F.fileupload!=null){U=Buffer.from(U,"base64");var aa=U.readUInt32BE(0);if((aa==16777216)||(aa==16777217)){fs.writeSync(F.fileupload.fp,U.slice(4));S.write({action:"upload",sub:"ack",reqid:F.fileupload.reqid});if(aa==16777217){fs.closeSync(F.fileupload.fp);F.fileupload=null}}}return}r("KVM Ctrl Data: "+U);try{U=JSON.parse(U)}catch(X){r("Invalid JSON: "+U);return}if((U.path!=null)&&(process.platform!="win32")&&(U.path[0]!="/")){U.path="/"+U.path}switch(U.action){case"ping":S.write({action:"pong"});break;case"lock":if(process.platform=="win32"){var T=require("child_process");T.execFile(process.env.windir+"\\system32\\cmd.exe",["/c","RunDll32.exe user32.dll,LockWorkStation"],{type:1})}break;case"ls":var ad=getDirectoryInfo(U.path);if(U.reqid!=undefined){ad.reqid=U.reqid}S.write(ad);break;case"mkdir":fs.mkdirSync(U.path);break;case"rm":for(var ab in U.delfiles){var Z=I.join(U.path,U.delfiles[ab]);try{fs.unlinkSync(Z)}catch(W){r(W)}}break;case"rename":try{fs.renameSync(I.join(U.path,U.oldname),I.join(U.path,U.newname))}catch(W){r(W)}break;case"download":var af=0;if(U.sub=="start"){if(F.filedownload!=null){S.write({action:"download",sub:"cancel",id:F.filedownload.id});delete F.filedownload}F.filedownload={id:U.id,path:U.path,ptr:0};try{F.filedownload.f=fs.openSync(F.filedownload.path,"rbN")}catch(W){S.write({action:"download",sub:"cancel",id:F.filedownload.id});delete F.filedownload}if(F.filedownload){S.write({action:"download",sub:"start",id:U.id})}}else{if((F.filedownload!=null)&&(U.id==F.filedownload.id)){if(U.sub=="startack"){af=8}else{if(U.sub=="stop"){delete F.filedownload}else{if(U.sub=="ack"){af=1}}}}}while(af>0){af--;var R=Buffer.alloc(4096);var ac=fs.readSync(F.filedownload.f,R,4,4092,null);F.filedownload.ptr+=ac;if(ac<4092){R.writeInt32BE(16777217,0);fs.closeSync(F.filedownload.f);delete F.filedownload;af=0}else{R.writeInt32BE(16777216,0)}S.write(R.slice(0,ac+4).toString("base64"))}break;case"upload":if(U.sub=="start"){if(F.fileupload!=null){fs.closeSync(F.fileupload.fp)}if(!U.path||!U.name){break}F.fileupload={reqid:U.reqid};var Y=I.join(U.path,U.name);try{F.fileupload.fp=fs.openSync(Y,"wbN")}catch(W){}if(F.fileupload.fp){S.write({action:"upload",sub:"start",reqid:F.fileupload.reqid})}else{F.fileupload=null;S.write({action:"upload",sub:"error",reqid:F.fileupload.reqid})}}else{if(U.sub=="cancel"){if(F.fileupload!=null){fs.closeSync(F.fileupload.fp);F.fileupload=null}}}break;case"copy":for(var ab in U.names){var ae=I.join(U.scpath,U.names[ab]),V=I.join(U.dspath,U.names[ab]);if(ae!=V){try{fs.copyFileSync(ae,V)}catch(W){}}}break;case"move":for(var ab in U.names){var ae=I.join(U.scpath,U.names[ab]),V=I.join(U.dspath,U.names[ab]);if(ae!=V){try{fs.copyFileSync(ae,V);fs.unlinkSync(ae)}catch(W){}}}break;default:r("Invalid KVM command: "+U);break}};var N=function(){r("webRtcCleanUp");if(O==null){return}if(O.rtcchannel){try{O.rtcchannel.close()}catch(R){}try{O.rtcchannel.removeAllListeners("data")}catch(R){}try{O.rtcchannel.removeAllListeners("end")}catch(R){}delete O.rtcchannel}if(O.webrtc){try{O.webrtc.close()}catch(R){}try{O.webrtc.removeAllListeners("connected")}catch(R){}try{O.webrtc.removeAllListeners("disconnected")}catch(R){}try{O.webrtc.removeAllListeners("dataChannel")}catch(R){}delete O.webrtc}if(O.kvm){try{O.kvm.end()}catch(R){}delete O.kvm}O=null};var A=function(R){G.IPS_KVMRedirectionSettingData_DataChannelWrite(Buffer.from(R).toString("base64"),function(){})};var s=function(R,S){if(fs.existsSync(R)){if(S==true){fs.readdirSync(F.path.join(R,"*")).forEach(function(U,V){var T=F.path.join(R,U);if(fs.statSync(T).isDirectory()){s(T,true)}else{fs.unlinkSync(T)}})}fs.unlinkSync(R)}};var I={join:function(){var T=[];for(var R in arguments){var S=arguments[R];if(S!=null){while(S.endsWith("/")||S.endsWith("\\")){S=S.substring(0,S.length-1)}if(R!=0){while(S.startsWith("/")||S.startsWith("\\")){S=S.substring(1)}}T.push(S)}}if(T.length==0){return"/"}return T.join("/")}};function D(R){return require("MD5Stream").create().syncHash(R).toString("hex")}F.deactivateCCM=function(){h.unprovision(1,function(R){if(R==0){r("Success deactivating Intel AMT CCM.");d.SendCommand({action:"coreinfo",intelamt:{state:0,flags:0}});m=setTimeout(F.applyPolicy,8000)}else{r("Intel AMT CCM deactivation error: "+R)}})};F.activeToACM=function(U){if(U.ProvisioningState!=0){return}var V=null;if((U.net0==null)&&(U.net0.enabled!=0)){return}if(U.DNS){V=U.DNS}else{var S=require("os").networkInterfaces();for(var R in S){for(var T in S[R]){if((S[R][T].mac==U.net0.mac)&&(S[R][T].fqdn!=null)&&(S[R][T].fqdn!="")){V=S[R][T].fqdn}}}}if(V==null){return}if(G!=null){G.BatchEnum(null,["*AMT_GeneralSettings","*IPS_HostBasedSetupService"],a,V)}else{h.getLocalSystemAccount(function(Z){if((Z!=null)&&Z.user&&Z.pass){var X=require("amt-wsman-duk");var Y=require("amt-wsman");var W=require("amt");H=new Y(X,"127.0.0.1",16992,Z.user,Z.pass,false);G=new W(H);G.BatchEnum(null,["*AMT_GeneralSettings","*IPS_HostBasedSetupService"],a,V)}else{}})}};function a(V,T,U,W,X){r("activeToACM2: "+X);if(W!=200){return}var S=U.IPS_HostBasedSetupService.response.ConfigurationNonce;var R=U.AMT_GeneralSettings.response.DigestRealm;d.SendCommand({action:"acmactivate",nonce:S,realm:R,fqdn:X})}function B(S){var U="",T="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";for(var R=0;R";l.AMT_RemoteAccessService_AddRemoteAccessPolicyRule(2,0,"AAAAAAAAAAo=",[S],null,function(W,U,V,X){if(X!=200){r("Add AddRemoteAccessPolicyRule Error "+X)}else{o(R)}})}function o(R){var T=[];if((k.ciraserver!=null)&&(k.ciraserver.home!=null)){T=k.ciraserver.home}var S=R.AMT_EnvironmentDetectionSettingData.response;S.DetectionStrings=C(S.DetectionStrings);if(p(S.DetectionStrings,T)==false){S.DetectionStrings=T;l.Put("AMT_EnvironmentDetectionSettingData",S,function(W,U,V,X){if(X!=200){r("Put AMT_EnvironmentDetectionSettingData Error "+X)}},0,1)}}function p(R,S){if(R==S){return true}if(R==null){R=[]}if(S==null){S=[]}if(R.length!=S.length){return false}for(var T in R){if(S.indexOf(R[T])==-1){return false}}return true}function C(R){if(!R||R==null||typeof R=="object"){return R}return[R]}}module.exports=AmtManager; \ No newline at end of file diff --git a/agents/modules_meshcore_min/amt-mei.min.js b/agents/modules_meshcore_min/amt-mei.min.js new file mode 100644 index 00000000..f3bea3f5 --- /dev/null +++ b/agents/modules_meshcore_min/amt-mei.min.js @@ -0,0 +1 @@ +var Q=require("queue");function amt_heci(){var d=require("events").inherits(this);d.createEvent("error");var u=require("heci");var y=function(E){require("MeshAgent").SendCommand({action:"msg",type:"console",value:E})};this._ObjectID="pthi";this._rq=new Q();this._setupPTHI=function b(){this._amt=u.create();this._amt.BiosVersionLen=65;this._amt.UnicodeStringLen=20;this._amt.Parent=this;this._amt.on("error",function F(H){if(this.Parent._rq.isEmpty()){this.Parent.emit("error",H)}else{var J=this.Parent._rq.deQueue();var I=J.optional;var G=J.func;I.unshift({Status:-1});G.apply(this.Parent,I);if(!this.Parent._rq.isEmpty()){this.connect(u.GUIDS.AMT,{noPipeline:1})}}});this._amt.on("connect",function E(){this.on("data",function G(I){var J=this.Parent.getCommand(I);var L=this.Parent._rq.deQueue();var K=L.optional;var H=L.func;K.unshift(J);H.apply(this.Parent,K);if(this.Parent._rq.isEmpty()){this.Parent._amt.disconnect();this.Parent._amt=null}else{this.write(this.Parent._rq.peekQueue().send)}});this.write(this.Parent._rq.peekQueue().send)})};function B(E){var F=E.indexOf("\0");if(F>=0){return E.substring(0,F)}else{return E}}this.getCommand=function g(E){var F=E.length==0?(this._rq.peekQueue().cmd|8388608):E.readUInt32LE(4);var G={IsResponse:(F&8388608)==8388608?true:false,Command:(F&8388607),Status:E.length!=0?E.readUInt32LE(12):-1,Data:E.length!=0?E.slice(16):null};return(G)};this.sendCommand=function x(){if(arguments.length<3||typeof(arguments[0])!="number"||typeof(arguments[1])!="object"||typeof(arguments[2])!="function"){throw ("invalid parameters")}var E=[];for(var G=3;G0){N.BiosVersion=N.BiosVersion.substring(0,N.BiosVersion.indexOf("\0"))}L.unshift(N)}else{L.unshift(null)}I.apply(this,L)},E,G)};function D(G,F){if((F==null)&&(typeof(F)!="number")){return null}if(G==null){G=""}var H="";for(var E=0;E0){J.unshift(I.Data.slice(2,2+K).toString())}else{J.unshift(null)}}else{J.unshift(null)}H.apply(this,J)},E,G)};this.getHashHandles=function k(E){var G=[];for(var F=1;F0){this.getCertHashEntry(G.shift(),this._getHashEntrySink,F,H,E,G)}else{H.unshift(E);F.apply(this,H)}};this.getLocalSystemAccount=function m(E){var G=[];for(var F=1;F>24)&255)+"."+((K>>16)&255)+"."+((K>>8)&255)+"."+(K&255);O.unshift(N);L.apply(this,O)}else{O.unshift(null);L.apply(this,O)}},E,J)};this.unprovision=function C(H,E){var I=[];for(var G=2;G>4)&15;f.provisioningState=b[19]&3;var e=(b[16]*256)+b[17];var c=((b[19]&4)!=0)?true:false;f.openPorts=[e];f.address=g.address;if(c==true){f.openPorts=[16992,16993]}if(d!==undefined){d(h,f)}}};this.parseIPv4Range=function(f){if(f==undefined||f==null){return null}var g=f.split("-");if(g.length==2){return{min:this.parseIpv4Addr(g[0]),max:this.parseIpv4Addr(g[1])}}g=f.split("/");if(g.length==2){var c=this.parseIpv4Addr(g[0]),e=parseInt(g[1]),d=0;if(e<=16||e>32){return null}e=32-e;for(var b=0;b>24)&255)+"."+((b>>16)&255)+"."+((b>>8)&255)+"."+(b&255)};this.scan=function(d,g){var c=this.parseIPv4Range(d);var e=this.buildRmcpPing(0);var f=this.dgram.createSocket({type:"udp4"});f.parent=this;f.scanResults=[];f.on("error",function(i){console.log("Error:"+i)});f.on("message",function(i,j){if(j.size>4){this.parent.parseRmcpPacket(this,i,j,function(l,k){l.scanResults.push(k)})}});f.on("listening",function(){for(var j=c.min;j<=c.max;j++){f.send(e,623,f.parent.IPv4NumToStr(j))}});f.bind({address:"0.0.0.0",port:0,exclusive:true});var h=setTimeout(function b(){f.close();f.parent.emit("found",f.scanResults);delete f},g)}}module.exports=AMTScanner; \ No newline at end of file diff --git a/agents/modules_meshcore_min/amt-wsman-duk.min.js b/agents/modules_meshcore_min/amt-wsman-duk.min.js new file mode 100644 index 00000000..b12434af --- /dev/null +++ b/agents/modules_meshcore_min/amt-wsman-duk.min.js @@ -0,0 +1 @@ +function CreateWsmanComm(){var a={};a.PendingAjax=[];a.ActiveAjaxCount=0;a.MaxActiveAjaxCount=1;a.FailAllError=0;a.digest=null;a.RequestCount=0;if(arguments.length==1&&typeof(arguments[0]=="object")){a.host=arguments[0].host;a.port=arguments[0].port;a.authToken=arguments[0].authToken;a.tls=arguments[0].tls}else{a.host=arguments[0];a.port=arguments[1];a.user=arguments[2];a.pass=arguments[3];a.tls=arguments[4]}a.PerformAjax=function(d,c,f,e,g,b){if((a.ActiveAjaxCount==0||((a.ActiveAjaxCount=a.MaxActiveAjaxCount||a.PendingAjax.length==0){return}var b=a.PendingAjax.shift();a.PerformAjaxEx(b[0],b[1],b[2],b[3],b[4]);a.PerformNextAjax()};a.PerformAjaxEx=function(d,c,g,h,b){if(a.FailAllError!=0){if(a.FailAllError!=999){a.gotNextMessagesError({status:a.FailAllError},"error",null,[d,c,g])}return}if(!d){d=""}if(a.digest==null){if(a.authToken){a.digest=require("http-digest").create({authToken:a.authToken})}else{a.digest=require("http-digest").create(a.user,a.pass)}a.digest.http=require("http")}var f={protocol:(a.tls==1?"https:":"http:"),method:"POST",host:a.host,path:"/wsman",port:a.port,rejectUnauthorized:false,checkServerIdentity:function(i){console.log("checkServerIdentity",JSON.stringify(i))}};var e=a.digest.request(f);e.on("error",function(i){a.gotNextMessagesError({status:600},"error",null,[d,c,g])});e.on("response",function(i){if(i.statusCode!=200){a.gotNextMessagesError({status:i.statusCode},"error",null,[d,c,g])}else{i.acc="";i.on("data",function(j){this.acc+=j});i.on("end",function(){a.gotNextMessages(i.acc,"success",{status:i.statusCode},[d,c,g])})}});e.end(d);a.ActiveAjaxCount++;return e};a.pendingAjaxCall=[];a.gotNextMessages=function(c,e,d,b){a.ActiveAjaxCount--;if(a.FailAllError==999){return}if(a.FailAllError!=0){b[1](null,a.FailAllError,b[2]);return}if(d.status!=200){b[1](null,d.status,b[2]);return}b[1](c,200,b[2]);a.PerformNextAjax()};a.gotNextMessagesError=function(d,e,c,b){a.ActiveAjaxCount--;if(a.FailAllError==999){return}if(a.FailAllError!=0){b[1](null,a.FailAllError,b[2]);return}if(a.FailAllError!=999){b[1]({Header:{HttpError:d.status}},d.status,b[2])}a.PerformNextAjax()};a.CancelAllQueries=function(b){while(a.PendingAjax.length>0){var c=a.PendingAjax.shift();c[1](null,b,c[2])}};return a}module.exports=CreateWsmanComm; \ No newline at end of file diff --git a/agents/modules_meshcore_min/amt-wsman.min.js b/agents/modules_meshcore_min/amt-wsman.min.js new file mode 100644 index 00000000..e8afb796 --- /dev/null +++ b/agents/modules_meshcore_min/amt-wsman.min.js @@ -0,0 +1 @@ +function WsmanStackCreateService(){var p={_ObjectID:"WSMAN"};p.NextMessageId=1;p.Address="/wsman";p.xmlParser=require("amt-xml");if(arguments.length==1&&typeof(arguments[0]=="object")){var e=arguments[0].transport;if(e){p.comm=new e(arguments[0])}}else{var e=arguments[0];if(e){p.comm=new e(arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6])}}p.PerformAjax=function q(t,r,v,u,s){if(s==null){s=""}p.comm.PerformAjax('
"+t,function(w,x,y){if(x!=200){r(p,null,{Header:{HttpError:x}},x,y);return}var z=p.xmlParser.ParseWsman(w);if(!z||z==null){r(p,null,{Header:{HttpError:x}},601,y)}else{r(p,z.Header.ResourceURI,z,200,y)}},v,u)};p.CancelAllQueries=function d(r){p.comm.CancelAllQueries(r)};p.GetNameFromUrl=function(r){var s=r.lastIndexOf("/");return(s==-1)?r:r.substring(s+1)};p.ExecSubscribe=function n(z,t,C,r,B,y,A,w,D,x){var u="",v="",w="";if(D!=null&&x!=null){u='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken'+D+''+x+"";v=''}if(w!=null){w=""+w+""}if(t=="PushWithAck"){t="dmtf.org/wbem/wsman/1/wsman/PushWithAck"}else{if(t=="Push"){t="xmlsoap.org/ws/2004/08/eventing/DeliveryModes/Push"}}var s="http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe"+p.Address+""+z+""+(p.NextMessageId++)+"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"+c(A)+u+'
'+C+""+w+""+v+"";p.PerformAjax(s+"
",r,B,y,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:m="http://x.com"')};p.ExecUnSubscribe=function o(u,r,w,t,v){var s="http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe"+p.Address+""+u+""+(p.NextMessageId++)+"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"+c(v)+"";p.PerformAjax(s+"",r,w,t,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"')};p.ExecPut=function m(v,u,r,x,t,w){var s="http://schemas.xmlsoap.org/ws/2004/09/transfer/Put"+p.Address+""+v+""+(p.NextMessageId++)+"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60.000S"+c(w)+""+b(v,u);p.PerformAjax(s+"",r,x,t)};p.ExecCreate=function f(x,w,r,z,v,y){var u=p.GetNameFromUrl(x);var s="http://schemas.xmlsoap.org/ws/2004/09/transfer/Create"+p.Address+""+x+""+(p.NextMessageId++)+"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S"+c(y)+"';for(var t in w){s+=""+w[t]+""}p.PerformAjax(s+"",r,z,v)};p.ExecDelete=function g(v,u,r,w,t){var s="http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete"+p.Address+""+v+""+(p.NextMessageId++)+"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S"+c(u)+"";p.PerformAjax(s,r,w,t)};p.ExecGet=function i(t,r,u,s){p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get"+p.Address+""+t+""+(p.NextMessageId++)+"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S",r,u,s)};p.ExecMethod=function j(y,v,r,t,A,w,z){var s="";for(var u in r){if(r[u]!=null){if(Array.isArray(r[u])){for(var B in r[u]){s+=""+r[u][B]+""}}else{s+=""+r[u]+""}}}p.ExecMethodXml(y,v,s,t,A,w,z)};p.ExecMethodXml=function k(v,t,r,s,x,u,w){p.PerformAjax(v+"/"+t+""+p.Address+""+v+""+(p.NextMessageId++)+"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S"+c(w)+"'+r+"",s,x,u)};p.ExecEnum=function h(t,r,u,s){p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate"+p.Address+""+t+""+(p.NextMessageId++)+'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S',r,u,s)};p.ExecPull=function l(u,s,r,v,t){p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull"+p.Address+""+u+""+(p.NextMessageId++)+'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S'+s+"99999999",r,v,t)};function b(w,u){if(!w||u==null){return""}var s=p.GetNameFromUrl(w);var v="';for(var t in u){if(!u.hasOwnProperty(t)||t.indexOf("__")===0||t.indexOf("@")===0){continue}if(u[t]==null||typeof u[t]==="function"){continue}if(typeof u[t]==="object"&&u[t]["ReferenceParameters"]){v+=""+u[t].Address+""+u[t]["ReferenceParameters"]["ResourceURI"]+"";var x=u[t]["ReferenceParameters"]["SelectorSet"]["Selector"];if(Array.isArray(x)){for(var r=0;r"+x[r]["Value"]+""}}else{v+=""+x.Value+""}v+=""}else{if(Array.isArray(u[t])){for(var r=0;r"+u[t][r].toString()+""}}else{v+=""+u[t].toString()+""}}}v+="";return v}function a(r){if(!r){return""}var t=" ";for(var s in r){if(!r.hasOwnProperty(s)||s.indexOf("@")!==0){continue}t+=s.substring(1)+'="'+r[s]+'" '}return t}function c(v){if((v==null)||(v=="null")){return""}if(typeof v=="string"){return v}if(v.InstanceID){return''+v.InstanceID+""}var t="";for(var s in v){if(!v.hasOwnProperty(s)){continue}t+='';if(v[s]["ReferenceParameters"]){t+="";t+=""+v[s]["Address"]+""+v[s]["ReferenceParameters"]["ResourceURI"]+"";var u=v[s]["ReferenceParameters"]["SelectorSet"]["Selector"];if(Array.isArray(u)){for(var r=0;r"+u[r]["Value"]+""}}else{t+=""+u.Value+""}t+=""}else{t+=v[s]}t+=""}t+="";return t}return p}module.exports=WsmanStackCreateService; \ No newline at end of file diff --git a/agents/modules_meshcore_min/amt-xml.min.js b/agents/modules_meshcore_min/amt-xml.min.js new file mode 100644 index 00000000..c8fe1c88 --- /dev/null +++ b/agents/modules_meshcore_min/amt-xml.min.js @@ -0,0 +1 @@ +try{Object.defineProperty(Array.prototype,"peek",{value:function(){return(this.length>0?this[this.length-1]:undefined)}})}catch(e){}module.exports.ParseWsman=function(j){try{if(!j.childNodes){j=_turnToXml(j)}var g={Header:{}},d=j.getElementsByTagName("Header")[0],h;if(!d){d=j.getElementsByTagName("a:Header")[0]}if(!d){return null}for(var f=0;f0){h=a.childNodes[0].localName;if(h.indexOf("_OUTPUT")==h.length-7){h=h.substring(0,h.length-7)}g.Header.Method=h;g.Body=_ParseWsmanRec(a.childNodes[0])}return g}catch(c){console.error("Unable to parse XML: "+j,c);return null}};function _ParseWsmanRec(g){var c,h={};for(var d=0;d0)){b={Value:c};for(var f=0;f';for(var c in d){if(!d.hasOwnProperty(c)||c.indexOf("__")===0||c.indexOf("@")===0){continue}if(d[c]==null||typeof d[c]==="function"){continue}if(typeof d[c]==="object"&&d[c]["ReferenceParameters"]){f+=""+d[c].Address+""+d[c]["ReferenceParameters"]["ResourceURI"]+"";var h=d[c]["ReferenceParameters"]["SelectorSet"]["Selector"];if(Array.isArray(h)){for(var a=0;a"+h[a]["Value"]+""}}else{f+=""+h.Value+""}f+=""}else{if(Array.isArray(d[c])){for(var a=0;a"+d[c][a].toString()+""}}else{f+=""+d[c].toString()+""}}}f+="";return f}function _treeBuilder(){this.tree=[];this.push=function(a){this.tree.push(a)};this.pop=function(){var a=this.tree.pop();if(this.tree.length>0){var b=this.tree.peek();b.childNodes.push(a);b.childElementCount=b.childNodes.length}return(a)};this.peek=function(){return(this.tree.peek())};this.addNamespace=function(g,d){this.tree.peek().nsTable[g]=d;if(this.tree.peek().attributes.length>0){for(var c=0;c=0;--a){if(this.tree[a].nsTable[b]!=null){return(this.tree[a].nsTable[b])}}return null}}function _turnToXml(a){if(a==null){return null}return({childNodes:[_turnToXmlRec(a)],getElementsByTagName:_getElementsByTagName,getChildElementsByTagName:_getChildElementsByTagName,getElementsByTagNameNS:_getElementsByTagNameNS})}function _getElementsByTagNameNS(b,a){var c=[];_xmlTraverseAllRec(this.childNodes,function(d){if(d.localName==a&&(d.namespace==b||b=="*")){c.push(d)}});return c}function _getElementsByTagName(a){var b=[];_xmlTraverseAllRec(this.childNodes,function(c){if(c.localName==a){b.push(c)}});return b}function _getChildElementsByTagName(a){var c=[];if(this.childNodes!=null){for(var b in this.childNodes){if(this.childNodes[b].localName==a){c.push(this.childNodes[b])}}}return(c)}function _getChildElementsByTagNameNS(c,a){var d=[];if(this.childNodes!=null){for(var b in this.childNodes){if(this.childNodes[b].localName==a&&(c=="*"||this.childNodes[b].namespace==c)){d.push(this.childNodes[b])}}}return(d)}function _xmlTraverseAllRec(c,a){for(var b in c){a(c[b]);if(c[b].childNodes){_xmlTraverseAllRec(c[b].childNodes,a)}}}function _turnToXmlRec(v){if(v==null){return null}var m=new _treeBuilder(),q=null,y=v.split("<"),t=[],h=null,g=null;for(var n in y){var z=y[n].split(">"),A=z[0].split(" "),l=A[0];if((l.length>0)&&(l[0]!="?")){if(l[0]!="/"){var a=[],r,s=l.split(" ")[0].split(":"),r=(s.length>1)?s[1]:s[0];Object.defineProperty(a,"get",{value:function(){if(arguments.length==1){for(var i in this){if(this[i].name==arguments[0]){return(this[i])}}}else{if(arguments.length==2){for(var i in this){if(this[i].name==arguments[1]&&(arguments[0]=="*"||this[i].namespace==arguments[0])){return(this[i])}}}else{throw ("attributes.get(): Invalid number of parameters")}}}});m.push({name:l,localName:r,getChildElementsByTagName:_getChildElementsByTagName,getElementsByTagNameNS:_getElementsByTagNameNS,getChildElementsByTagNameNS:_getChildElementsByTagNameNS,attributes:a,childNodes:[],nsTable:{}});if(A.length>0){var u=false;for(var o in A){if(A[o]=="/"){m.peek().namespace=m.peek().name==m.peek().localName?m.getNamespace("*"):m.getNamespace(m.peek().name.substring(0,m.peek().name.indexOf(":")));m.peek().textContent="";q=m.pop();u=true;break}var p=A[o].indexOf("=");if(p>0){var b=A[o].substring(0,p);var d=A[o].substring(p+2,A[o].length-1);var c=m.getNamespace("*");if(b=="xmlns"){m.addNamespace("*",d);c=d}else{if(b.startsWith("xmlns:")){m.addNamespace(b.substring(6),d)}else{var f=b.split(":");if(f.length==2){b=f[1];c=m.getNamespace(f[0])}}}var w={name:b,value:d};if(c!=null){w.namespace=c}m.peek().attributes.push(w)}}if(u){continue}}m.peek().namespace=m.peek().name==m.peek().localName?m.getNamespace("*"):m.getNamespace(m.peek().name.substring(0,m.peek().name.indexOf(":")));if(z[1]){m.peek().textContent=z[1]}}else{q=m.pop()}}}return q}; \ No newline at end of file diff --git a/agents/modules_meshcore_min/amt.min.js b/agents/modules_meshcore_min/amt.min.js new file mode 100644 index 00000000..6984729b --- /dev/null +++ b/agents/modules_meshcore_min/amt.min.js @@ -0,0 +1 @@ +function AmtStackCreateService(R){var J=new Object();J._ObjectID="AMT";J.wsman=R;J.pfx=["http://intel.com/wbem/wscim/1/amt-schema/1/","http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/","http://intel.com/wbem/wscim/1/ips-schema/1/"];J.PendingEnums=[];J.PendingBatchOperations=0;J.ActiveEnumsCount=0;J.MaxActiveEnumsCount=1;J.onProcessChanged=null;var n=0;var m=0;J.GetPendingActions=function(){return(J.PendingEnums.length*2)+(J.ActiveEnumsCount)+J.wsman.comm.PendingAjax.length+J.wsman.comm.ActiveAjaxCount+J.PendingBatchOperations};function r(){var S=J.GetPendingActions();if(n=J.MaxActiveEnumsCount||J.PendingEnums.length==0){return}var T=J.PendingEnums.shift();J.Enum(T[0],T[1],T[2]);d(0)}J.BatchEnum=function(S,V,T,X,U,W){J.PendingBatchOperations+=(V.length*2);b(S,x(V),T,X,{},U,W);r()};function x(S){return JSON.parse(JSON.stringify(S))}function b(S,X,T,aa,Z,U,Y){J.PendingBatchOperations-=2;var W=X.shift(),V=J.Enum;if(W[0]=="*"){V=J.Get;W=W.substring(1)}V(W,function(ad,ab,ac,ae,af){af[2][ab]={response:(ac==null?null:ac.Body),responses:ac,status:ae};if(af[1].length==0||ae==401||(U!=true&&ae!=200&&ae!=400)){J.PendingBatchOperations-=(X.length*2);r();T.call(J,J,S,af[2],ae,aa)}else{r();b(S,X,T,aa,af[2],Y)}},[S,X,Z],Y);r()}J.BatchGet=function(S,U,T,W,V){h({name:S,names:U,callback:T,current:0,responses:{},tag:W,pri:V});r()};function h(S){if(S.names.length<=S.current){S.callback.call(J,J,S.name,S.responses,200,S.tag)}else{J.wsman.ExecGet(J.CompleteName(S.names[S.current]),function(V,U,T,W){g(S,T,W)},S.pri);S.current++}r()}function g(S,T,U){if(T==null||U!=200){S.callback.call(J,J,S.name,null,U,S.tag)}else{S.responses[T.Header.Method]=T;h(S)}}J.CompleteName=function(S){if(S.indexOf("AMT_")==0){return J.pfx[0]+S}if(S.indexOf("CIM_")==0){return J.pfx[1]+S}if(S.indexOf("IPS_")==0){return J.pfx[2]+S}};J.CompleteExecResponse=function(S){if(S&&S!=null&&S.Body&&(S.Body.ReturnValue!=undefined)){S.Body.ReturnValueStr=J.AmtStatusToStr(S.Body.ReturnValue)}return S};J.RequestPowerStateChange=function(T,S){J.CIM_PowerManagementService_RequestPowerStateChange(T,'
http://schemas.xmlsoap.org/ws/2004/08/addressing
http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ComputerSystemCIM_ComputerSystemManagedSystem',null,null,S)};J.SetBootConfigRole=function(T,S){J.CIM_BootService_SetBootConfigRole('
http://schemas.xmlsoap.org/ws/2004/08/addressing
http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_BootConfigSettingIntel(r) AMT: Boot Configuration 0',T,S)};J.CancelAllQueries=function(S){J.wsman.CancelAllQueries(S)};J.AMT_AgentPresenceWatchdog_RegisterAgent=function(S,V,T,U){J.Exec("AMT_AgentPresenceWatchdog","RegisterAgent",{},S,V,T,U)};J.AMT_AgentPresenceWatchdog_AssertPresence=function(V,S,W,T,U){J.Exec("AMT_AgentPresenceWatchdog","AssertPresence",{SequenceNumber:V},S,W,T,U)};J.AMT_AgentPresenceWatchdog_AssertShutdown=function(V,S,W,T,U){J.Exec("AMT_AgentPresenceWatchdog","AssertShutdown",{SequenceNumber:V},S,W,T,U)};J.AMT_AgentPresenceWatchdog_AddAction=function(X,W,V,T,S,U,aa,Y,Z){J.Exec("AMT_AgentPresenceWatchdog","AddAction",{OldState:X,NewState:W,EventOnTransition:V,ActionSd:T,ActionEac:S},U,aa,Y,Z)};J.AMT_AgentPresenceWatchdog_DeleteAllActions=function(S,V,T,U){J.Exec("AMT_AgentPresenceWatchdog","DeleteAllActions",{},S,V,T,U)};J.AMT_AgentPresenceWatchdogAction_GetActionEac=function(S){J.Exec("AMT_AgentPresenceWatchdogAction","GetActionEac",{},S)};J.AMT_AgentPresenceWatchdogVA_RegisterAgent=function(S){J.Exec("AMT_AgentPresenceWatchdogVA","RegisterAgent",{},S)};J.AMT_AgentPresenceWatchdogVA_AssertPresence=function(T,S){J.Exec("AMT_AgentPresenceWatchdogVA","AssertPresence",{SequenceNumber:T},S)};J.AMT_AgentPresenceWatchdogVA_AssertShutdown=function(T,S){J.Exec("AMT_AgentPresenceWatchdogVA","AssertShutdown",{SequenceNumber:T},S)};J.AMT_AgentPresenceWatchdogVA_AddAction=function(X,W,V,T,S,U){J.Exec("AMT_AgentPresenceWatchdogVA","AddAction",{OldState:X,NewState:W,EventOnTransition:V,ActionSd:T,ActionEac:S},U)};J.AMT_AgentPresenceWatchdogVA_DeleteAllActions=function(S,T){J.Exec("AMT_AgentPresenceWatchdogVA","DeleteAllActions",{_method_dummy:S},T)};J.AMT_AlarmClockService_AddAlarm=function s(S,T){var V=S.InstanceID;var X=S.ElementName;var Y=S.StartTime.Datetime;var W=S.Interval?S.Interval.Datetime:undefined;var U=S.DeleteOnCompletion;var Z=''+V+""+X+''+Y+""+((W!=undefined)?(''+W+""):"")+""+U+"";J.wsman.ExecMethodXml(J.CompleteName("AMT_AlarmClockService"),"AddAlarm",Z,T)};J.AMT_AuditLog_ClearLog=function(S){J.Exec("AMT_AuditLog","ClearLog",{},S)};J.AMT_AuditLog_RequestStateChange=function(T,U,S){J.Exec("AMT_AuditLog","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.AMT_AuditLog_ReadRecords=function(T,S,U){J.Exec("AMT_AuditLog","ReadRecords",{StartIndex:T},S,U)};J.AMT_AuditLog_SetAuditLock=function(V,T,U,S){J.Exec("AMT_AuditLog","SetAuditLock",{LockTimeoutInSeconds:V,Flag:T,Handle:U},S)};J.AMT_AuditLog_ExportAuditLogSignature=function(T,S){J.Exec("AMT_AuditLog","ExportAuditLogSignature",{SigningMechanism:T},S)};J.AMT_AuditLog_SetSigningKeyMaterial=function(W,V,U,T,S){J.Exec("AMT_AuditLog","SetSigningKeyMaterial",{SigningMechanismType:W,SigningKey:V,LengthOfCertificates:U,Certificates:T},S)};J.AMT_AuditPolicyRule_SetAuditPolicy=function(U,S,V,W,T){J.Exec("AMT_AuditPolicyRule","SetAuditPolicy",{Enable:U,AuditedAppID:S,EventID:V,PolicyType:W},T)};J.AMT_AuditPolicyRule_SetAuditPolicyBulk=function(U,S,V,W,T){J.Exec("AMT_AuditPolicyRule","SetAuditPolicyBulk",{Enable:U,AuditedAppID:S,EventID:V,PolicyType:W},T)};J.AMT_AuthorizationService_AddUserAclEntryEx=function(V,U,W,S,X,T){J.Exec("AMT_AuthorizationService","AddUserAclEntryEx",{DigestUsername:V,DigestPassword:U,KerberosUserSid:W,AccessPermission:S,Realms:X},T)};J.AMT_AuthorizationService_EnumerateUserAclEntries=function(T,S){J.Exec("AMT_AuthorizationService","EnumerateUserAclEntries",{StartIndex:T},S)};J.AMT_AuthorizationService_GetUserAclEntryEx=function(T,S,U){J.Exec("AMT_AuthorizationService","GetUserAclEntryEx",{Handle:T},S,U)};J.AMT_AuthorizationService_UpdateUserAclEntryEx=function(W,V,U,X,S,Y,T){J.Exec("AMT_AuthorizationService","UpdateUserAclEntryEx",{Handle:W,DigestUsername:V,DigestPassword:U,KerberosUserSid:X,AccessPermission:S,Realms:Y},T)};J.AMT_AuthorizationService_RemoveUserAclEntry=function(T,S){J.Exec("AMT_AuthorizationService","RemoveUserAclEntry",{Handle:T},S)};J.AMT_AuthorizationService_SetAdminAclEntryEx=function(U,T,S){J.Exec("AMT_AuthorizationService","SetAdminAclEntryEx",{Username:U,DigestPassword:T},S)};J.AMT_AuthorizationService_GetAdminAclEntry=function(S){J.Exec("AMT_AuthorizationService","GetAdminAclEntry",{},S)};J.AMT_AuthorizationService_GetAdminAclEntryStatus=function(S){J.Exec("AMT_AuthorizationService","GetAdminAclEntryStatus",{},S)};J.AMT_AuthorizationService_GetAdminNetAclEntryStatus=function(S){J.Exec("AMT_AuthorizationService","GetAdminNetAclEntryStatus",{},S)};J.AMT_AuthorizationService_SetAclEnabledState=function(U,T,S,V){J.Exec("AMT_AuthorizationService","SetAclEnabledState",{Handle:U,Enabled:T},S,V)};J.AMT_AuthorizationService_GetAclEnabledState=function(T,S,U){J.Exec("AMT_AuthorizationService","GetAclEnabledState",{Handle:T},S,U)};J.AMT_EndpointAccessControlService_RequestStateChange=function(T,U,S){J.Exec("AMT_EndpointAccessControlService","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.AMT_EndpointAccessControlService_GetPosture=function(T,S){J.Exec("AMT_EndpointAccessControlService","GetPosture",{PostureType:T},S)};J.AMT_EndpointAccessControlService_GetPostureHash=function(T,S){J.Exec("AMT_EndpointAccessControlService","GetPostureHash",{PostureType:T},S)};J.AMT_EndpointAccessControlService_UpdatePostureState=function(T,S){J.Exec("AMT_EndpointAccessControlService","UpdatePostureState",{UpdateType:T},S)};J.AMT_EndpointAccessControlService_GetEacOptions=function(S){J.Exec("AMT_EndpointAccessControlService","GetEacOptions",{},S)};J.AMT_EndpointAccessControlService_SetEacOptions=function(T,U,S){J.Exec("AMT_EndpointAccessControlService","SetEacOptions",{EacVendors:T,PostureHashAlgorithm:U},S)};J.AMT_EnvironmentDetectionSettingData_SetSystemDefensePolicy=function(T,S){J.Exec("AMT_EnvironmentDetectionSettingData","SetSystemDefensePolicy",{Policy:T},S)};J.AMT_EnvironmentDetectionSettingData_EnableVpnRouting=function(T,S){J.Exec("AMT_EnvironmentDetectionSettingData","EnableVpnRouting",{Enable:T},S)};J.AMT_EthernetPortSettings_SetLinkPreference=function(T,U,S){J.Exec("AMT_EthernetPortSettings","SetLinkPreference",{LinkPreference:T,Timeout:U},S)};J.AMT_HeuristicPacketFilterStatistics_ResetSelectedStats=function(T,S){J.Exec("AMT_HeuristicPacketFilterStatistics","ResetSelectedStats",{SelectedStatistics:T},S)};J.AMT_KerberosSettingData_GetCredentialCacheState=function(S){J.Exec("AMT_KerberosSettingData","GetCredentialCacheState",{},S)};J.AMT_KerberosSettingData_SetCredentialCacheState=function(T,S){J.Exec("AMT_KerberosSettingData","SetCredentialCacheState",{Enable:T},S)};J.AMT_MessageLog_CancelIteration=function(T,S){J.Exec("AMT_MessageLog","CancelIteration",{IterationIdentifier:T},S)};J.AMT_MessageLog_RequestStateChange=function(T,U,S){J.Exec("AMT_MessageLog","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.AMT_MessageLog_ClearLog=function(S){J.Exec("AMT_MessageLog","ClearLog",{},S)};J.AMT_MessageLog_GetRecords=function(T,U,S,V){J.Exec("AMT_MessageLog","GetRecords",{IterationIdentifier:T,MaxReadRecords:U},S,V)};J.AMT_MessageLog_GetRecord=function(T,U,S){J.Exec("AMT_MessageLog","GetRecord",{IterationIdentifier:T,PositionToNext:U},S)};J.AMT_MessageLog_PositionAtRecord=function(T,U,V,S){J.Exec("AMT_MessageLog","PositionAtRecord",{IterationIdentifier:T,MoveAbsolute:U,RecordNumber:V},S)};J.AMT_MessageLog_PositionToFirstRecord=function(S,T){J.Exec("AMT_MessageLog","PositionToFirstRecord",{},S,T)};J.AMT_MessageLog_FreezeLog=function(T,S){J.Exec("AMT_MessageLog","FreezeLog",{Freeze:T},S)};J.AMT_PublicKeyManagementService_AddCRL=function(U,T,S){J.Exec("AMT_PublicKeyManagementService","AddCRL",{Url:U,SerialNumbers:T},S)};J.AMT_PublicKeyManagementService_ResetCRLList=function(S,T){J.Exec("AMT_PublicKeyManagementService","ResetCRLList",{_method_dummy:S},T)};J.AMT_PublicKeyManagementService_AddCertificate=function(T,S,U){J.Exec("AMT_PublicKeyManagementService","AddCertificate",{CertificateBlob:T},S,U)};J.AMT_PublicKeyManagementService_AddTrustedRootCertificate=function(T,S){J.Exec("AMT_PublicKeyManagementService","AddTrustedRootCertificate",{CertificateBlob:T},S)};J.AMT_PublicKeyManagementService_AddKey=function(T,S){J.Exec("AMT_PublicKeyManagementService","AddKey",{KeyBlob:T},S)};J.AMT_PublicKeyManagementService_GeneratePKCS10Request=function(U,T,V,S){J.Exec("AMT_PublicKeyManagementService","GeneratePKCS10Request",{KeyPair:U,DNName:T,Usage:V},S)};J.AMT_PublicKeyManagementService_GeneratePKCS10RequestEx=function(T,V,U,S){J.Exec("AMT_PublicKeyManagementService","GeneratePKCS10RequestEx",{KeyPair:T,SigningAlgorithm:V,NullSignedCertificateRequest:U},S)};J.AMT_PublicKeyManagementService_GenerateKeyPair=function(T,U,S){J.Exec("AMT_PublicKeyManagementService","GenerateKeyPair",{KeyAlgorithm:T,KeyLength:U},S)};J.AMT_RedirectionService_RequestStateChange=function(T,S){J.Exec("AMT_RedirectionService","RequestStateChange",{RequestedState:T},S)};J.AMT_RedirectionService_TerminateSession=function(T,S){J.Exec("AMT_RedirectionService","TerminateSession",{SessionType:T},S)};J.AMT_RemoteAccessService_AddMpServer=function(S,X,Z,T,V,aa,Y,W,U){J.Exec("AMT_RemoteAccessService","AddMpServer",{AccessInfo:S,InfoFormat:X,Port:Z,AuthMethod:T,Certificate:V,Username:aa,Password:Y,CN:W},U)};J.AMT_RemoteAccessService_AddRemoteAccessPolicyRule=function(V,W,T,U,S){J.Exec("AMT_RemoteAccessService","AddRemoteAccessPolicyRule",{Trigger:V,TunnelLifeTime:W,ExtendedData:T,MpServer:U},S)};J.AMT_RemoteAccessService_CloseRemoteAccessConnection=function(S,T){J.Exec("AMT_RemoteAccessService","CloseRemoteAccessConnection",{_method_dummy:S},T)};J.AMT_SetupAndConfigurationService_CommitChanges=function(S,T,U){J.Exec("AMT_SetupAndConfigurationService","CommitChanges",{_method_dummy:S},T,U)};J.AMT_SetupAndConfigurationService_Unprovision=function(T,S){J.Exec("AMT_SetupAndConfigurationService","Unprovision",{ProvisioningMode:T},S)};J.AMT_SetupAndConfigurationService_PartialUnprovision=function(S,T){J.Exec("AMT_SetupAndConfigurationService","PartialUnprovision",{_method_dummy:S},T)};J.AMT_SetupAndConfigurationService_ResetFlashWearOutProtection=function(S,T){J.Exec("AMT_SetupAndConfigurationService","ResetFlashWearOutProtection",{_method_dummy:S},T)};J.AMT_SetupAndConfigurationService_ExtendProvisioningPeriod=function(T,S){J.Exec("AMT_SetupAndConfigurationService","ExtendProvisioningPeriod",{Duration:T},S)};J.AMT_SetupAndConfigurationService_SetMEBxPassword=function(T,S){J.Exec("AMT_SetupAndConfigurationService","SetMEBxPassword",{Password:T},S)};J.AMT_SetupAndConfigurationService_SetTLSPSK=function(T,U,S){J.Exec("AMT_SetupAndConfigurationService","SetTLSPSK",{PID:T,PPS:U},S)};J.AMT_SetupAndConfigurationService_GetProvisioningAuditRecord=function(S){J.Exec("AMT_SetupAndConfigurationService","GetProvisioningAuditRecord",{},S)};J.AMT_SetupAndConfigurationService_GetUuid=function(S){J.Exec("AMT_SetupAndConfigurationService","GetUuid",{},S)};J.AMT_SetupAndConfigurationService_GetUnprovisionBlockingComponents=function(S){J.Exec("AMT_SetupAndConfigurationService","GetUnprovisionBlockingComponents",{},S)};J.AMT_SetupAndConfigurationService_GetProvisioningAuditRecordV2=function(S){J.Exec("AMT_SetupAndConfigurationService","GetProvisioningAuditRecordV2",{},S)};J.AMT_SystemDefensePolicy_GetTimeout=function(S){J.Exec("AMT_SystemDefensePolicy","GetTimeout",{},S)};J.AMT_SystemDefensePolicy_SetTimeout=function(T,S){J.Exec("AMT_SystemDefensePolicy","SetTimeout",{Timeout:T},S)};J.AMT_SystemDefensePolicy_UpdateStatistics=function(T,V,S,X,U,W){J.Exec("AMT_SystemDefensePolicy","UpdateStatistics",{NetworkInterface:T,ResetOnRead:V},S,X,U,W)};J.AMT_SystemPowerScheme_SetPowerScheme=function(S,T,U){J.Exec("AMT_SystemPowerScheme","SetPowerScheme",{},S,U,0,{InstanceID:T})};J.AMT_TimeSynchronizationService_GetLowAccuracyTimeSynch=function(S,T){J.Exec("AMT_TimeSynchronizationService","GetLowAccuracyTimeSynch",{},S,T)};J.AMT_TimeSynchronizationService_SetHighAccuracyTimeSynch=function(T,V,W,S,U){J.Exec("AMT_TimeSynchronizationService","SetHighAccuracyTimeSynch",{Ta0:T,Tm1:V,Tm2:W},S,U)};J.AMT_TLSCredentialContext_Create=function t(T,U,S,V){J.Create("AMT_TLSCredentialContext",{ElementInContext:T,ElementProvidingContext:U},S,V)};J.AMT_UserInitiatedConnectionService_RequestStateChange=function(T,U,S){J.Exec("AMT_UserInitiatedConnectionService","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.AMT_WebUIService_RequestStateChange=function(T,V,S,U){J.Exec("AMT_WebUIService","RequestStateChange",{RequestedState:T,TimeoutPeriod:V},S,U)};J.AMT_WiFiPortConfigurationService_AddWiFiSettings=function(W,X,V,U,S,T){J.ExecWithXml("AMT_WiFiPortConfigurationService","AddWiFiSettings",{WiFiEndpoint:W,WiFiEndpointSettingsInput:X,IEEE8021xSettingsInput:V,ClientCredential:U,CACredential:S},T)};J.AMT_WiFiPortConfigurationService_UpdateWiFiSettings=function(W,X,V,U,S,T){J.ExecWithXml("AMT_WiFiPortConfigurationService","UpdateWiFiSettings",{WiFiEndpointSettings:W,WiFiEndpointSettingsInput:X,IEEE8021xSettingsInput:V,ClientCredential:U,CACredential:S},T)};J.AMT_WiFiPortConfigurationService_DeleteAllITProfiles=function(S,T){J.Exec("AMT_WiFiPortConfigurationService","DeleteAllITProfiles",{_method_dummy:S},T)};J.AMT_WiFiPortConfigurationService_DeleteAllUserProfiles=function(S,T){J.Exec("AMT_WiFiPortConfigurationService","DeleteAllUserProfiles",{_method_dummy:S},T)};J.CIM_Account_RequestStateChange=function(T,U,S){J.Exec("CIM_Account","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_AccountManagementService_CreateAccount=function(U,S,T){J.Exec("CIM_AccountManagementService","CreateAccount",{System:U,AccountTemplate:S},T)};J.CIM_BootConfigSetting_ChangeBootOrder=function(T,S){J.Exec("CIM_BootConfigSetting","ChangeBootOrder",{Source:T},S)};J.CIM_BootService_SetBootConfigRole=function(S,U,T){J.Exec("CIM_BootService","SetBootConfigRole",{BootConfigSetting:S,Role:U},T,0,1)};J.CIM_Card_ConnectorPower=function(T,U,S){J.Exec("CIM_Card","ConnectorPower",{Connector:T,PoweredOn:U},S)};J.CIM_Card_IsCompatible=function(T,S){J.Exec("CIM_Card","IsCompatible",{ElementToCheck:T},S)};J.CIM_Chassis_IsCompatible=function(T,S){J.Exec("CIM_Chassis","IsCompatible",{ElementToCheck:T},S)};J.CIM_Fan_SetSpeed=function(T,S){J.Exec("CIM_Fan","SetSpeed",{DesiredSpeed:T},S)};J.CIM_KVMRedirectionSAP_RequestStateChange=function(T,U,S){J.Exec("CIM_KVMRedirectionSAP","RequestStateChange",{RequestedState:T},S)};J.CIM_MediaAccessDevice_LockMedia=function(T,S){J.Exec("CIM_MediaAccessDevice","LockMedia",{Lock:T},S)};J.CIM_MediaAccessDevice_SetPowerState=function(T,U,S){J.Exec("CIM_MediaAccessDevice","SetPowerState",{PowerState:T,Time:U},S)};J.CIM_MediaAccessDevice_Reset=function(S){J.Exec("CIM_MediaAccessDevice","Reset",{},S)};J.CIM_MediaAccessDevice_EnableDevice=function(T,S){J.Exec("CIM_MediaAccessDevice","EnableDevice",{Enabled:T},S)};J.CIM_MediaAccessDevice_OnlineDevice=function(T,S){J.Exec("CIM_MediaAccessDevice","OnlineDevice",{Online:T},S)};J.CIM_MediaAccessDevice_QuiesceDevice=function(T,S){J.Exec("CIM_MediaAccessDevice","QuiesceDevice",{Quiesce:T},S)};J.CIM_MediaAccessDevice_SaveProperties=function(S){J.Exec("CIM_MediaAccessDevice","SaveProperties",{},S)};J.CIM_MediaAccessDevice_RestoreProperties=function(S){J.Exec("CIM_MediaAccessDevice","RestoreProperties",{},S)};J.CIM_MediaAccessDevice_RequestStateChange=function(T,U,S){J.Exec("CIM_MediaAccessDevice","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_PhysicalFrame_IsCompatible=function(T,S){J.Exec("CIM_PhysicalFrame","IsCompatible",{ElementToCheck:T},S)};J.CIM_PhysicalPackage_IsCompatible=function(T,S){J.Exec("CIM_PhysicalPackage","IsCompatible",{ElementToCheck:T},S)};J.CIM_PowerManagementService_RequestPowerStateChange=function(U,T,V,W,S){J.Exec("CIM_PowerManagementService","RequestPowerStateChange",{PowerState:U,ManagedElement:T,Time:V,TimeoutPeriod:W},S,0,1)};J.CIM_PowerSupply_SetPowerState=function(T,U,S){J.Exec("CIM_PowerSupply","SetPowerState",{PowerState:T,Time:U},S)};J.CIM_PowerSupply_Reset=function(S){J.Exec("CIM_PowerSupply","Reset",{},S)};J.CIM_PowerSupply_EnableDevice=function(T,S){J.Exec("CIM_PowerSupply","EnableDevice",{Enabled:T},S)};J.CIM_PowerSupply_OnlineDevice=function(T,S){J.Exec("CIM_PowerSupply","OnlineDevice",{Online:T},S)};J.CIM_PowerSupply_QuiesceDevice=function(T,S){J.Exec("CIM_PowerSupply","QuiesceDevice",{Quiesce:T},S)};J.CIM_PowerSupply_SaveProperties=function(S){J.Exec("CIM_PowerSupply","SaveProperties",{},S)};J.CIM_PowerSupply_RestoreProperties=function(S){J.Exec("CIM_PowerSupply","RestoreProperties",{},S)};J.CIM_PowerSupply_RequestStateChange=function(T,U,S){J.Exec("CIM_PowerSupply","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_Processor_SetPowerState=function(T,U,S){J.Exec("CIM_Processor","SetPowerState",{PowerState:T,Time:U},S)};J.CIM_Processor_Reset=function(S){J.Exec("CIM_Processor","Reset",{},S)};J.CIM_Processor_EnableDevice=function(T,S){J.Exec("CIM_Processor","EnableDevice",{Enabled:T},S)};J.CIM_Processor_OnlineDevice=function(T,S){J.Exec("CIM_Processor","OnlineDevice",{Online:T},S)};J.CIM_Processor_QuiesceDevice=function(T,S){J.Exec("CIM_Processor","QuiesceDevice",{Quiesce:T},S)};J.CIM_Processor_SaveProperties=function(S){J.Exec("CIM_Processor","SaveProperties",{},S)};J.CIM_Processor_RestoreProperties=function(S){J.Exec("CIM_Processor","RestoreProperties",{},S)};J.CIM_Processor_RequestStateChange=function(T,U,S){J.Exec("CIM_Processor","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_RecordLog_ClearLog=function(S){J.Exec("CIM_RecordLog","ClearLog",{},S)};J.CIM_RecordLog_RequestStateChange=function(T,U,S){J.Exec("CIM_RecordLog","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_RedirectionService_RequestStateChange=function(T,U,S){J.Exec("CIM_RedirectionService","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_Sensor_SetPowerState=function(T,U,S){J.Exec("CIM_Sensor","SetPowerState",{PowerState:T,Time:U},S)};J.CIM_Sensor_Reset=function(S){J.Exec("CIM_Sensor","Reset",{},S)};J.CIM_Sensor_EnableDevice=function(T,S){J.Exec("CIM_Sensor","EnableDevice",{Enabled:T},S)};J.CIM_Sensor_OnlineDevice=function(T,S){J.Exec("CIM_Sensor","OnlineDevice",{Online:T},S)};J.CIM_Sensor_QuiesceDevice=function(T,S){J.Exec("CIM_Sensor","QuiesceDevice",{Quiesce:T},S)};J.CIM_Sensor_SaveProperties=function(S){J.Exec("CIM_Sensor","SaveProperties",{},S)};J.CIM_Sensor_RestoreProperties=function(S){J.Exec("CIM_Sensor","RestoreProperties",{},S)};J.CIM_Sensor_RequestStateChange=function(T,U,S){J.Exec("CIM_Sensor","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_StatisticalData_ResetSelectedStats=function(T,S){J.Exec("CIM_StatisticalData","ResetSelectedStats",{SelectedStatistics:T},S)};J.CIM_Watchdog_KeepAlive=function(S){J.Exec("CIM_Watchdog","KeepAlive",{},S)};J.CIM_Watchdog_SetPowerState=function(T,U,S){J.Exec("CIM_Watchdog","SetPowerState",{PowerState:T,Time:U},S)};J.CIM_Watchdog_Reset=function(S){J.Exec("CIM_Watchdog","Reset",{},S)};J.CIM_Watchdog_EnableDevice=function(T,S){J.Exec("CIM_Watchdog","EnableDevice",{Enabled:T},S)};J.CIM_Watchdog_OnlineDevice=function(T,S){J.Exec("CIM_Watchdog","OnlineDevice",{Online:T},S)};J.CIM_Watchdog_QuiesceDevice=function(T,S){J.Exec("CIM_Watchdog","QuiesceDevice",{Quiesce:T},S)};J.CIM_Watchdog_SaveProperties=function(S){J.Exec("CIM_Watchdog","SaveProperties",{},S)};J.CIM_Watchdog_RestoreProperties=function(S){J.Exec("CIM_Watchdog","RestoreProperties",{},S)};J.CIM_Watchdog_RequestStateChange=function(T,U,S){J.Exec("CIM_Watchdog","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.CIM_WiFiPort_SetPowerState=function(T,U,S){J.Exec("CIM_WiFiPort","SetPowerState",{PowerState:T,Time:U},S)};J.CIM_WiFiPort_Reset=function(S){J.Exec("CIM_WiFiPort","Reset",{},S)};J.CIM_WiFiPort_EnableDevice=function(T,S){J.Exec("CIM_WiFiPort","EnableDevice",{Enabled:T},S)};J.CIM_WiFiPort_OnlineDevice=function(T,S){J.Exec("CIM_WiFiPort","OnlineDevice",{Online:T},S)};J.CIM_WiFiPort_QuiesceDevice=function(T,S){J.Exec("CIM_WiFiPort","QuiesceDevice",{Quiesce:T},S)};J.CIM_WiFiPort_SaveProperties=function(S){J.Exec("CIM_WiFiPort","SaveProperties",{},S)};J.CIM_WiFiPort_RestoreProperties=function(S){J.Exec("CIM_WiFiPort","RestoreProperties",{},S)};J.CIM_WiFiPort_RequestStateChange=function(T,U,S){J.Exec("CIM_WiFiPort","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.IPS_HostBasedSetupService_Setup=function(W,X,V,T,Y,U,S){J.Exec("IPS_HostBasedSetupService","Setup",{NetAdminPassEncryptionType:W,NetworkAdminPassword:X,McNonce:V,Certificate:T,SigningAlgorithm:Y,DigitalSignature:U},S)};J.IPS_HostBasedSetupService_AddNextCertInChain=function(V,T,U,S){J.Exec("IPS_HostBasedSetupService","AddNextCertInChain",{NextCertificate:V,IsLeafCertificate:T,IsRootCertificate:U},S)};J.IPS_HostBasedSetupService_AdminSetup=function(V,W,U,X,T,S){J.Exec("IPS_HostBasedSetupService","AdminSetup",{NetAdminPassEncryptionType:V,NetworkAdminPassword:W,McNonce:U,SigningAlgorithm:X,DigitalSignature:T},S)};J.IPS_HostBasedSetupService_UpgradeClientToAdmin=function(U,V,T,S){J.Exec("IPS_HostBasedSetupService","UpgradeClientToAdmin",{McNonce:U,SigningAlgorithm:V,DigitalSignature:T},S)};J.IPS_HostBasedSetupService_DisableClientControlMode=function(S,T){J.Exec("IPS_HostBasedSetupService","DisableClientControlMode",{_method_dummy:S},T)};J.IPS_KVMRedirectionSettingData_TerminateSession=function(S){J.Exec("IPS_KVMRedirectionSettingData","TerminateSession",{},S)};J.IPS_KVMRedirectionSettingData_DataChannelRead=function(S){J.Exec("IPS_KVMRedirectionSettingData","DataChannelRead",{},S)};J.IPS_KVMRedirectionSettingData_DataChannelWrite=function(T,S){J.Exec("IPS_KVMRedirectionSettingData","DataChannelWrite",{DataMessage:T},S)};J.IPS_OptInService_StartOptIn=function(S){J.Exec("IPS_OptInService","StartOptIn",{},S)};J.IPS_OptInService_CancelOptIn=function(S){J.Exec("IPS_OptInService","CancelOptIn",{},S)};J.IPS_OptInService_SendOptInCode=function(T,S){J.Exec("IPS_OptInService","SendOptInCode",{OptInCode:T},S)};J.IPS_OptInService_StartService=function(S){J.Exec("IPS_OptInService","StartService",{},S)};J.IPS_OptInService_StopService=function(S){J.Exec("IPS_OptInService","StopService",{},S)};J.IPS_OptInService_RequestStateChange=function(T,U,S){J.Exec("IPS_OptInService","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.IPS_ProvisioningRecordLog_RequestStateChange=function(T,U,S){J.Exec("IPS_ProvisioningRecordLog","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.IPS_ProvisioningRecordLog_ClearLog=function(S,T){J.Exec("IPS_ProvisioningRecordLog","ClearLog",{_method_dummy:S},T)};J.IPS_SecIOService_RequestStateChange=function(T,U,S){J.Exec("IPS_SecIOService","RequestStateChange",{RequestedState:T,TimeoutPeriod:U},S)};J.AmtStatusToStr=function(S){if(J.AmtStatusCodes[S]){return J.AmtStatusCodes[S]}else{return"UNKNOWN_ERROR"}};J.AmtStatusCodes={0:"SUCCESS",1:"INTERNAL_ERROR",2:"NOT_READY",3:"INVALID_PT_MODE",4:"INVALID_MESSAGE_LENGTH",5:"TABLE_FINGERPRINT_NOT_AVAILABLE",6:"INTEGRITY_CHECK_FAILED",7:"UNSUPPORTED_ISVS_VERSION",8:"APPLICATION_NOT_REGISTERED",9:"INVALID_REGISTRATION_DATA",10:"APPLICATION_DOES_NOT_EXIST",11:"NOT_ENOUGH_STORAGE",12:"INVALID_NAME",13:"BLOCK_DOES_NOT_EXIST",14:"INVALID_BYTE_OFFSET",15:"INVALID_BYTE_COUNT",16:"NOT_PERMITTED",17:"NOT_OWNER",18:"BLOCK_LOCKED_BY_OTHER",19:"BLOCK_NOT_LOCKED",20:"INVALID_GROUP_PERMISSIONS",21:"GROUP_DOES_NOT_EXIST",22:"INVALID_MEMBER_COUNT",23:"MAX_LIMIT_REACHED",24:"INVALID_AUTH_TYPE",25:"AUTHENTICATION_FAILED",26:"INVALID_DHCP_MODE",27:"INVALID_IP_ADDRESS",28:"INVALID_DOMAIN_NAME",29:"UNSUPPORTED_VERSION",30:"REQUEST_UNEXPECTED",31:"INVALID_TABLE_TYPE",32:"INVALID_PROVISIONING_STATE",33:"UNSUPPORTED_OBJECT",34:"INVALID_TIME",35:"INVALID_INDEX",36:"INVALID_PARAMETER",37:"INVALID_NETMASK",38:"FLASH_WRITE_LIMIT_EXCEEDED",39:"INVALID_IMAGE_LENGTH",40:"INVALID_IMAGE_SIGNATURE",41:"PROPOSE_ANOTHER_VERSION",42:"INVALID_PID_FORMAT",43:"INVALID_PPS_FORMAT",44:"BIST_COMMAND_BLOCKED",45:"CONNECTION_FAILED",46:"CONNECTION_TOO_MANY",47:"RNG_GENERATION_IN_PROGRESS",48:"RNG_NOT_READY",49:"CERTIFICATE_NOT_READY",1024:"DISABLED_BY_POLICY",2048:"NETWORK_IF_ERROR_BASE",2049:"UNSUPPORTED_OEM_NUMBER",2050:"UNSUPPORTED_BOOT_OPTION",2051:"INVALID_COMMAND",2052:"INVALID_SPECIAL_COMMAND",2053:"INVALID_HANDLE",2054:"INVALID_PASSWORD",2055:"INVALID_REALM",2056:"STORAGE_ACL_ENTRY_IN_USE",2057:"DATA_MISSING",2058:"DUPLICATE",2059:"EVENTLOG_FROZEN",2060:"PKI_MISSING_KEYS",2061:"PKI_GENERATING_KEYS",2062:"INVALID_KEY",2063:"INVALID_CERT",2064:"CERT_KEY_NOT_MATCH",2065:"MAX_KERB_DOMAIN_REACHED",2066:"UNSUPPORTED",2067:"INVALID_PRIORITY",2068:"NOT_FOUND",2069:"INVALID_CREDENTIALS",2070:"INVALID_PASSPHRASE",2072:"NO_ASSOCIATION",2075:"AUDIT_FAIL",2076:"BLOCKING_COMPONENT",2081:"USER_CONSENT_REQUIRED",4096:"APP_INTERNAL_ERROR",4097:"NOT_INITIALIZED",4098:"LIB_VERSION_UNSUPPORTED",4099:"INVALID_PARAM",4100:"RESOURCES",4101:"HARDWARE_ACCESS_ERROR",4102:"REQUESTOR_NOT_REGISTERED",4103:"NETWORK_ERROR",4104:"PARAM_BUFFER_TOO_SHORT",4105:"COM_NOT_INITIALIZED_IN_THREAD",4106:"URL_REQUIRED"};J.GetMessageLog=function(S,T){J.AMT_MessageLog_PositionToFirstRecord(k,[S,T,[]])};function k(U,S,T,V,W){if(V!=200||T.Body.ReturnValue!="0"){W[0](J,null,W[2],V);return}J.AMT_MessageLog_GetRecords(T.Body.IterationIdentifier,390,l,W)}function l(Z,W,Y,aa,ac){if(aa!=200||Y.Body.ReturnValue!="0"){ac[0](J,null,ac[2],aa);return}var U,V,ae,T,S=ac[2],ab=new Date(),ad,X=Y.Body.RecordArray;if(typeof X==="string"){Y.Body.RecordArray=[Y.Body.RecordArray]}for(U in X){T=Buffer.from(X[U],"base64");if(T!=null){ad=M(T,0);if((ad>0)&&(ad<4294967295)){ae={DeviceAddress:T[4],EventSensorType:T[5],EventType:T[6],EventOffset:T[7],EventSourceType:T[8],EventSeverity:T[9],SensorNumber:T[10],Entity:T[11],EntityInstance:T[12],EventData:[],Time:new Date((ad+(ab.getTimezoneOffset()*60))*1000)};for(V=13;V<21;V++){ae.EventData.push(T[V])}ae.EntityStr=o[ae.Entity];ae.Desc=j(ae.EventSensorType,ae.EventOffset,ae.EventData,ae.Entity);if(!ae.EntityStr){ae.EntityStr="Unknown"}S.push(ae)}}}if(Y.Body.NoMoreRecords!=true){J.AMT_MessageLog_GetRecords(Y.Body.IterationIdentifier,390,l,[ac[0],S,ac[2]])}else{ac[0](J,S,ac[2])}}var f="Platform firmware (e.g. BIOS)|SMI handler|ISV system management software|Alert ASIC|IPMI|BIOS vendor|System board set vendor|System integrator|Third party add-in|OSV|NIC|System management card".split("|");var p="Unspecified.|No system memory is physically installed in the system.|No usable system memory, all installed memory has experienced an unrecoverable failure.|Unrecoverable hard-disk/ATAPI/IDE device failure.|Unrecoverable system-board failure.|Unrecoverable diskette subsystem failure.|Unrecoverable hard-disk controller failure.|Unrecoverable PS/2 or USB keyboard failure.|Removable boot media not found.|Unrecoverable video controller failure.|No video device detected.|Firmware (BIOS) ROM corruption detected.|CPU voltage mismatch (processors that share same supply have mismatched voltage requirements)|CPU speed matching failure".split("|");var q="Unspecified.|Memory initialization.|Starting hard-disk initialization and test|Secondary processor(s) initialization|User authentication|User-initiated system setup|USB resource configuration|PCI resource configuration|Option ROM initialization|Video initialization|Cache initialization|SM Bus initialization|Keyboard controller initialization|Embedded controller/management controller initialization|Docking station attachment|Enabling docking station|Docking station ejection|Disabling docking station|Calling operating system wake-up vector|Starting operating system boot process|Baseboard or motherboard initialization|reserved|Floppy initialization|Keyboard test|Pointing device test|Primary processor initialization".split("|");var o="Unspecified|Other|Unknown|Processor|Disk|Peripheral|System management module|System board|Memory module|Processor module|Power supply|Add in card|Front panel board|Back panel board|Power system board|Drive backplane|System internal expansion board|Other system board|Processor board|Power unit|Power module|Power management board|Chassis back panel board|System chassis|Sub chassis|Other chassis board|Disk drive bay|Peripheral bay|Device bay|Fan cooling|Cooling unit|Cable interconnect|Memory device|System management software|BIOS|Intel(r) ME|System bus|Group|Intel(r) ME|External environment|Battery|Processing blade|Connectivity switch|Processor/memory module|I/O module|Processor I/O module|Management controller firmware|IPMI channel|PCI bus|PCI express bus|SCSI bus|SATA/SAS bus|Processor front side bus".split("|");J.RealmNames="||Redirection|PT Administration|Hardware Asset|Remote Control|Storage|Event Manager|Storage Admin|Agent Presence Local|Agent Presence Remote|Circuit Breaker|Network Time|General Information|Firmware Update|EIT|LocalUN|Endpoint Access Control|Endpoint Access Control Admin|Event Log Reader|Audit Log|ACL Realm|||Local System".split("|");J.WatchdogCurrentStates={1:"Not Started",2:"Stopped",4:"Running",8:"Expired",16:"Suspended"};function j(V,U,T,S){if(V==15){if(T[0]==235){return"Invalid Data"}if(U==0){return p[T[1]]}return q[T[1]]}if(V==18&&T[0]==170){return"Agent watchdog "+char2hex(T[4])+char2hex(T[3])+char2hex(T[2])+char2hex(T[1])+"-"+char2hex(T[6])+char2hex(T[5])+"-... changed to "+J.WatchdogCurrentStates[T[7]]}if(V==6){return"Authentication failed "+(T[1]+(T[2]<<8))+" times. The system may be under attack."}if(V==30){return"No bootable media"}if(V==32){return"Operating system lockup or power interrupt"}if(V==35){return"System boot failure"}if(V==37){return"System firmware started (at least one CPU is properly executing)."}return"Unknown Sensor Type #"+V}var a={16:"Security Admin",17:"RCO",18:"Redirection Manager",19:"Firmware Update Manager",20:"Security Audit Log",21:"Network Time",22:"Network Administration",23:"Storage Administration",24:"Event Manager",25:"Circuit Breaker Manager",26:"Agent Presence Manager",27:"Wireless Configuration",28:"EAC",29:"KVM",30:"User Opt-In Events",32:"Screen Blanking",33:"Watchdog Events",1600:"Provisioning Started",1601:"Provisioning Completed",1602:"ACL Entry Added",1603:"ACL Entry Modified",1604:"ACL Entry Removed",1605:"ACL Access with Invalid Credentials",1606:"ACL Entry State",1607:"TLS State Changed",1608:"TLS Server Certificate Set",1609:"TLS Server Certificate Remove",1610:"TLS Trusted Root Certificate Added",1611:"TLS Trusted Root Certificate Removed",1612:"TLS Preshared Key Set",1613:"Kerberos Settings Modified",1614:"Kerberos Master Key Modified",1615:"Flash Wear out Counters Reset",1616:"Power Package Modified",1617:"Set Realm Authentication Mode",1618:"Upgrade Client to Admin Control Mode",1619:"Unprovisioning Started",1700:"Performed Power Up",1701:"Performed Power Down",1702:"Performed Power Cycle",1703:"Performed Reset",1704:"Set Boot Options",1800:"IDER Session Opened",1801:"IDER Session Closed",1802:"IDER Enabled",1803:"IDER Disabled",1804:"SoL Session Opened",1805:"SoL Session Closed",1806:"SoL Enabled",1807:"SoL Disabled",1808:"KVM Session Started",1809:"KVM Session Ended",1810:"KVM Enabled",1811:"KVM Disabled",1812:"VNC Password Failed 3 Times",1900:"Firmware Updated",1901:"Firmware Update Failed",2000:"Security Audit Log Cleared",2001:"Security Audit Policy Modified",2002:"Security Audit Log Disabled",2003:"Security Audit Log Enabled",2004:"Security Audit Log Exported",2005:"Security Audit Log Recovered",2100:"Intel(R) ME Time Set",2200:"TCPIP Parameters Set",2201:"Host Name Set",2202:"Domain Name Set",2203:"VLAN Parameters Set",2204:"Link Policy Set",2205:"IPv6 Parameters Set",2300:"Global Storage Attributes Set",2301:"Storage EACL Modified",2302:"Storage FPACL Modified",2303:"Storage Write Operation",2400:"Alert Subscribed",2401:"Alert Unsubscribed",2402:"Event Log Cleared",2403:"Event Log Frozen",2500:"CB Filter Added",2501:"CB Filter Removed",2502:"CB Policy Added",2503:"CB Policy Removed",2504:"CB Default Policy Set",2505:"CB Heuristics Option Set",2506:"CB Heuristics State Cleared",2600:"Agent Watchdog Added",2601:"Agent Watchdog Removed",2602:"Agent Watchdog Action Set",2700:"Wireless Profile Added",2701:"Wireless Profile Removed",2702:"Wireless Profile Updated",2800:"EAC Posture Signer SET",2801:"EAC Enabled",2802:"EAC Disabled",2803:"EAC Posture State",2804:"EAC Set Options",2900:"KVM Opt-in Enabled",2901:"KVM Opt-in Disabled",2902:"KVM Password Changed",2903:"KVM Consent Succeeded",2904:"KVM Consent Failed",3000:"Opt-In Policy Change",3001:"Send Consent Code Event",3002:"Start Opt-In Blocked Event"};J.GetAuditLogExtendedDataStr=function(T,S){if((T==1602||T==1604)&&S[0]==0){return w(S).splice(2,2+S[1]).toString()}if(T==1603){if(S[1]==0){return w(S).splice(3).toString()}return null}if(T==1605){return["Invalid ME access","Invalid MEBx access"][S[0]]}if(T==1606){var U=["Disabled","Enabled"][S[0]];if(S[1]==0){U+=", "+S[3]}return U}if(T==1607){return"Remote "+["NoAuth","ServerAuth","MutualAuth"][S[0]]+", Local "+["NoAuth","ServerAuth","MutualAuth"][S[1]]}if(T==1617){return J.RealmNames[L(S,0)]+", "+["NoAuth","Auth","Disabled"][S[4]]}if(T==1619){return["BIOS","MEBx","Local MEI","Local WSMAN","Remote WSAMN"][S[0]]}if(T==1900){return"From "+N(S,0)+"."+N(S,2)+"."+N(S,4)+"."+N(S,6)+" to "+N(S,8)+"."+N(S,10)+"."+N(S,12)+"."+N(S,14)}if(T==2100){var V=new Date();V.setTime(L(S,0)*1000+(new Date().getTimezoneOffset()*60000));return V.toLocaleString()}if(T==3000){return"From "+["None","KVM","All"][S[0]]+" to "+["None","KVM","All"][S[1]]}if(T==3001){return["Success","Failed 3 times"][S[0]]}return null};J.GetAuditLog=function(S){J.AMT_AuditLog_ReadRecords(1,i,[S,[]])};function I(S){if(!S||S==null||typeof S=="object"){return S}return[S]}function N(T,S){return(T[S]<<8)+T[S+1]}function L(T,S){return(T[S]*16777216)+(T[S+1]<<16)+(T[S+2]<<8)+T[S+3]}function M(T,S){return(T[S+3]*16777216)+(T[S+2]<<16)+(T[S+1]<<8)+T[S]}function v(S){return Buffer.from(S).toString("base64")}function u(T){var U=null;try{U=Buffer.from(T,"base64").toString()}catch(S){console.log(S)}return U}function w(S){var U=[];for(var T in S){U.push(S[T])}return U}function i(ab,W,aa,ac,ae){if(ac!=200){ae[0](J,[],ac);return}var Y,V,S,ah,Z=ae[1],ad=new Date(),af;if(aa.Body.RecordsReturned>0){aa.Body.EventRecords=I(aa.Body.EventRecords);for(V in aa.Body.EventRecords){S=null;try{S=Buffer.from(aa.Body.EventRecords[V],"base64")}catch(T){console.log(T+" "+aa.Body.EventRecords[V])}ah={AuditAppID:N(S,0),EventID:N(S,2),InitiatorType:S[4]};ah.AuditApp=a[ah.AuditAppID];ah.Event=a[(ah.AuditAppID*100)+ah.EventID];if(!ah.Event){ah.Event="#"+ah.EventID}if(ah.InitiatorType==0){var ag=S[5];ah.Initiator=S.slice(6,6+ag).toString();Y=6+ag}if(ah.InitiatorType==1){ah.KerberosUserInDomain=L(S,5);var ag=S[9];ah.Initiator=G(S.slice(10,10+ag));Y=10+ag}if(ah.InitiatorType==2){ah.Initiator="Local";Y=5}if(ah.InitiatorType==3){ah.Initiator="KVM Default Port";Y=5}af=L(S,Y);ah.Time=new Date((af+(ad.getTimezoneOffset()*60))*1000);Y+=4;ah.MCLocationType=S[Y++];var X=S[Y++];ah.NetAddress=S.slice(Y,Y+X).toString();Y+=X;var U=S[Y++];ah.Ex=S.slice(Y,Y+U);ah.ExStr=J.GetAuditLogExtendedDataStr((ah.AuditAppID*100)+ah.EventID,ah.Ex);Z.push(ah)}}if(aa.Body.TotalRecordCount>Z.length){J.AMT_AuditLog_ReadRecords(Z.length+1,i,[ae[0],Z])}else{ae[0](J,Z,ac)}}function C(U){if(U===undefined||U===null){return null}var V="";for(var T in U){var S=U[T];if(!S){continue}if(S.__parameterType==="reference"){V+=O(T,S)}else{V+=H(T,S)}}return V}function H(V,U){if(U===undefined||U===null){return null}var T=!!U.__namespace;var Z=T?"";for(var X in U){if(!U.hasOwnProperty(X)||X.indexOf("__")===0){continue}if(typeof U[X]==="function"||Array.isArray(U[X])){continue}if(typeof U[X]==="object"){console.error("only convert one level down...")}else{Y+=Z+X+">"+U[X].toString()+S+X+">"}}Y+="";return Y}function O(T,S){if(S===undefined||S===null){return null}var U="/wsman"+S.__resourceUri+"";for(var V in S){if(!S.hasOwnProperty(V)||V.indexOf("__")===0){continue}if(typeof S[V]==="function"||typeof S[V]==="object"||Array.isArray(S[V])){continue}U+=''+S[V].toString()+""}U+="";return U}function G(U){var T="S-"+U.charCodeAt(0)+"-"+U.charCodeAt(7);for(var S=2;S<(U.length/4);S++){T+="-"+M(U,S*4)}return T}function F(V){if(!V||V==null){return null}var U=V.split("-");if(U.length<4||(U[0]!="s"&&U[0]!="S")){return null}for(var S=1;S0?this[this.length-1]:undefined)}})}catch(e){}function dbus(a,b){this._ObjectID="linux-dbus";require("events").EventEmitter.call(this,true).createEvent("signal");Object.defineProperty(this,"uid",{value:b});this._child=require("child_process").execFile("/bin/sh",["sh"],{type:require("child_process").SpawnTypes.TERM,uid:b==null?-1:b});this._child.stdin.write("dbus-monitor --session \"type='signal', interface='"+a+'\'" | ( while read X; do echo "$X"; done )\n');this._child.stdout.dbus=this;this._child.stdout.on("data",function(c){if(!this.ready){this.ready=true;return}var f=[];var g=c.toString().split("\r\n");for(var d in g){if(g[d]==""){this.dbus.preParseRecords(f);f=[]}else{f.push(g[d])}}});this.preParseRecords=function(d){var f=[];for(var c in d){if(d[c].startsWith("signal ")){if(f.length>0){this.parseRecords(f)}f=[]}f.push(d[c])}if(f.length>0){this.parseRecords(f)}};this.parseRecords=function(d){if(d[0].startsWith("signal ")){var g={};var h=d[0].split(" ");h.shift();for(var c in h){var f=h[c].split("=");if(f.length==2){g[f[0]]=f[1]}}d.shift();g.data=d;this.parseSignal(g)}};this.parseSignal=function(f){var c=f.data;f.data=[];for(var d=0;d0?this[this.length-1]:undefined)}})}catch(e){}try{Object.defineProperty(String.prototype,"replaceAll",{value:function replaceAll(b,a){return(this.split(b).join(a))}})}catch(e){}var RSMB=1381190978;var memoryLocation={1:"Other",2:"Unknown",3:"System Board",4:"ISA",5:"EISA",6:"PCI",7:"MCA",8:"PCMCIA",9:"Proprietary",10:"NuBus",160:"PC-98/C20",161:"PC-98/C24",162:"PC-98/E",163:"PC-98/LB"};var wakeReason=["Reserved","Other","Unknown","APM Timer","Modem Ring","LAN","Power Switch","PCI","AC Power"];function zeroLeftPad(c,b){if((b==null)&&(typeof(b)!="number")){return null}if(c==null){c=""}var d="";for(var a=0;a1){var r=v[1].split("\x0A\x0A")[0].split("\x0A");var s=[];for(var t in r){var u=r[t].trim().replaceAll(" ","").replaceAll("\x09","");if(!(u[0]=='"')){s.push(u)}}p.write(Buffer.from(s.join(""),"hex"));p.write(Buffer.from("00","hex"))}else{p.write(Buffer.from("0000","hex"))}}var q=p.buffer;q.ms=p;return(q)}}this._parse=function b(o){var n={};var m;var l=0;var o;var s=0;while(o&&l0){var n=l[4].pop();var o=n[20]&64;var s=n[20]&7;if(o){var m={_ObjectID:"SMBiosTables.processorInfo"};m.Processor=q[n[1]];m.MaxSpeed=n.readUInt16LE(16)+" Mhz";if(n[31]){m.Cores=n[31]}if(n[33]){m.Threads=n[33]}m.Populated=1;m.Status=t[s];m.Socket=n._strings[n[0]-1];m.Manufacturer=n._strings[n[3]-1];m.Version=n._strings[n[12]-1];r.push(m)}}return(r)};this.memoryInfo=function f(k){if(!k){throw ("no data")}var n={_ObjectID:"SMBiosTables.memoryInfo"};if(k[16]){var l=k[16].peek();n.location=memoryLocation[l[0]];if((n.maxCapacityKb=l.readUInt32LE(3))==2147483648){n.maxCapacityKb="A really big number"}}return(n)};this.systemInfo=function i(k){if(!k){throw ("no data")}var l={_ObjectID:"SMBiosTables.systemInfo"};if(k[1]){var m=k[1].peek();var n=m.slice(4,20);l.uuid=[zeroLeftPad(n.readUInt32LE(0).toString(16),8),zeroLeftPad(n.readUInt16LE(4).toString(16),4),zeroLeftPad(n.readUInt16LE(6).toString(16),4),zeroLeftPad(n.readUInt16BE(8).toString(16),4),zeroLeftPad(n.slice(10).toString("hex").toLowerCase(),12)].join("-");l.wakeReason=wakeReason[m[20]]}return(l)};this.systemSlots=function j(k){if(!k){throw ("no data")}var l=[];if(k[9]){while(k[9].length>0){var m=k[9].pop();l.push({name:m._strings[m[0]-1]})}}return(l)};this.amtInfo=function c(l){if(!l){throw ("no data")}var n={AMT:false};if(l[130]&&l[130].peek().slice(0,4).toString()=="$AMT"){var k=l[130].peek();n.AMT=k[4]?true:false;if(n.AMT){n.enabled=k[5]?true:false;n.storageRedirection=k[6]?true:false;n.serialOverLan=k[7]?true:false;n.kvm=k[14]?true:false;if(l[131].peek()&&l[131].peek().slice(52,56).toString()=="vPro"){var o=l[131].peek();if(o[0]&4){n.TXT=(o[0]&8)?true:false}if(o[0]&16){n.VMX=(o[0]&32)?true:false}n.MEBX=o.readUInt16LE(10).toString()+"."+o.readUInt16LE(8).toString()+"."+o.readUInt16LE(6).toString()+"."+o.readUInt16LE(4).toString();var m=o.slice(20,32);n.ManagementEngine=m.readUInt16LE(6).toString()+"."+m.readUInt16LE(4).toString()+"."+m.readUInt16LE(2).toString()+"."+m.readUInt16LE(0).toString()}}}return(n)};this.smTableTypes={0:"BIOS information",1:"System information",2:"Baseboard (or Module) information",4:"Processor information",5:"memory controller information",6:"Memory module information",7:"Cache information",8:"Port connector information",9:"System slots",10:"On board devices information",11:"OEM strings",12:"System configuration options",13:"BIOS language information",14:"Group associations",15:"System event log",16:"Physical memory array",17:"Memory device",18:"32bit memory error information",19:"Memory array mapped address",20:"Memory device mapped address",21:"Built-in pointing device",22:"Portable battery",23:"System reset",24:"Hardware security",25:"System power controls",26:"Voltage probe",27:"Cooling device",28:"Temperature probe",29:"Electrical current probe",30:"Out-of-band remote access",31:"Boot integrity services (BIS) entry point",32:"System boot information",33:"64bit memory error information",34:"Management device",35:"Management device component",36:"Management device threshold data",37:"Memory channel",38:"IPMI device information",39:"System power supply",40:"Additional information",41:"Onboard devices extended information",42:"Management controller host interface",126:"Inactive",127:"End-of-table"}}module.exports=new SMBiosTables(); \ No newline at end of file diff --git a/agents/modules_meshcore_min/wifi-scanner-windows.min.js b/agents/modules_meshcore_min/wifi-scanner-windows.min.js new file mode 100644 index 00000000..752e15ac --- /dev/null +++ b/agents/modules_meshcore_min/wifi-scanner-windows.min.js @@ -0,0 +1 @@ +function _Scan(){var f=this.Marshal.CreatePointer();this.Native.WlanEnumInterfaces(this.Handle,0,f);var a=f.Deref().Deref(0,4).toBuffer().readUInt32LE(0);var d=f.Deref().Deref(8,532);var c=d.Deref(16,512).AnsiString;var e;switch(d.Deref(528,4).toBuffer().readUInt32LE(0)){case 0:e="NOT READY";break;case 1:e="CONNECTED";break;case 2:e="AD-HOC";break;case 3:e="DISCONNECTING";break;case 4:e="DISCONNECTED";break;case 5:e="ASSOCIATING";break;case 6:e="DISCOVERING";break;case 7:e="AUTHENTICATING";break;default:e="UNKNOWN";break}var b=d.Deref(0,16);if(this.Native.WlanScan(this.Handle,b,0,0,0).Val==0){return(true)}else{return(false)}}function AccessPoint(d,a,c,b){this.ssid=d;this.bssid=a;this.rssi=c;this.lq=b}AccessPoint.prototype.toString=function(){return(this.ssid+" ["+this.bssid+"]: "+this.lq)};function OnNotify(g){var h=g.Deref(0,4).toBuffer().readUInt32LE(0);var f=g.Deref(4,4).toBuffer().readUInt32LE(0);var c=g.Deref(8,16);if((h&8)&&(f==7)){var a=this.Parent.Marshal.CreatePointer();var k=this.Parent.Native.GetBSSList(this.Parent.Handle,c,0,3,0,0,a).Val;if(k==0){var n=a.Deref().Deref(0,4).toBuffer().readUInt32LE(0);var j=a.Deref().Deref(4,4).toBuffer().readUInt32LE(0);for(i=0;i"){g=""}}if(j.startsWith("Signal level=")){f=j.slice(13,j.length-4)}else{if(j.startsWith("Quality=")){f=j.slice(8,10);var k=j.slice(11,13)}}}this.parent.parent.emit("accessPoint",new AccessPoint(g,e,f))}})}}}}}module.exports=WiFiScanner; \ No newline at end of file diff --git a/agents/modules_meshcore_min/win-console.min.js b/agents/modules_meshcore_min/win-console.min.js new file mode 100644 index 00000000..e2197744 --- /dev/null +++ b/agents/modules_meshcore_min/win-console.min.js @@ -0,0 +1 @@ +var TrayIconFlags={NIF_MESSAGE:1,NIF_ICON:2,NIF_TIP:4,NIF_STATE:8,NIF_INFO:16,NIF_GUID:32,NIF_REALTIME:64,NIF_SHOWTIP:128,NIM_ADD:0,NIM_MODIFY:1,NIM_DELETE:2,NIM_SETFOCUS:3,NIM_SETVERSION:4};var NOTIFYICON_VERSION_4=4;var MessageTypes={WM_APP:32768,WM_USER:1024};function WindowsConsole(){if(process.platform=="win32"){this._ObjectID="win-console";this._Marshal=require("_GenericMarshal");this._kernel32=this._Marshal.CreateNativeProxy("kernel32.dll");this._user32=this._Marshal.CreateNativeProxy("user32.dll");this._kernel32.CreateMethod("GetConsoleWindow");this._kernel32.CreateMethod("GetCurrentThread");this._user32.CreateMethod("ShowWindow");this._user32.CreateMethod("LoadImageA");this._user32.CreateMethod({method:"GetMessageA",threadDispatch:1});this._shell32=this._Marshal.CreateNativeProxy("Shell32.dll");this._shell32.CreateMethod("Shell_NotifyIconA");this._handle=this._kernel32.GetConsoleWindow();this.minimize=function(){this._user32.ShowWindow(this._handle,6)};this.restore=function(){this._user32.ShowWindow(this._handle,9)};this.hide=function(){this._user32.ShowWindow(this._handle,0)};this.show=function(){this._user32.ShowWindow(this._handle,5)};this._loadicon=function(c){var b=this._user32.LoadImageA(0,this._Marshal.CreateVariable(c),1,0,0,16|32768|64);return(b)};this.SetTrayIcon=function a(h){var b=this._Marshal.CreateVariable(this._Marshal.PointerSize==4?508:528);b.toBuffer().writeUInt32LE(b._size,0);var n=TrayIconFlags.NIF_TIP|TrayIconFlags.NIF_MESSAGE;h.filter=MessageTypes.WM_APP+1;b.Deref(this._Marshal.PointerSize==4?16:24,4).toBuffer().writeUInt32LE(h.filter);if(!h.noBalloon){n|=TrayIconFlags.NIF_INFO}if(h.icon){n|=TrayIconFlags.NIF_ICON;var c=b.Deref(this._Marshal.PointerSize==4?20:32,this._Marshal.PointerSize);h.icon.pointerBuffer().copy(c.toBuffer())}b.Deref(this._Marshal.PointerSize*2,4).toBuffer().writeUInt32LE(1);b.Deref(this._Marshal.PointerSize==4?12:20,4).toBuffer().writeUInt32LE(n);b.Deref(this._Marshal.PointerSize==4?416:432,4).toBuffer().writeUInt32LE(NOTIFYICON_VERSION_4);var m=b.Deref(this._Marshal.PointerSize==4?24:40,128);var k=b.Deref(this._Marshal.PointerSize==4?160:176,256);var l=b.Deref(this._Marshal.PointerSize==4?420:436,64);if(h.szTip){Buffer.from(h.szTip).copy(m.toBuffer())}if(h.szInfo){Buffer.from(h.szInfo).copy(k.toBuffer())}if(h.szInfoTitle){Buffer.from(h.szInfoTitle).copy(l.toBuffer())}var d=require("win-message-pump");retVal={_ObjectID:"WindowsConsole.TrayIcon",MessagePump:new d(h)};var j=require("events").inherits(retVal);j.createEvent("ToastClicked");j.createEvent("IconHover");j.createEvent("ToastDismissed");retVal.Options=h;retVal.MessagePump.TrayIcon=retVal;retVal.MessagePump.NotifyData=b;retVal.MessagePump.WindowsConsole=this;retVal.MessagePump.on("exit",function e(o){console.log("Pump Exited");if(this.TrayIcon){this.TrayIcon.remove()}});retVal.MessagePump.on("hwnd",function f(o){h.hwnd=o;o.pointerBuffer().copy(this.NotifyData.Deref(this.WindowsConsole._Marshal.PointerSize,this.WindowsConsole._Marshal.PointerSize).toBuffer());if(this.WindowsConsole._shell32.Shell_NotifyIconA(TrayIconFlags.NIM_ADD,this.NotifyData).Val==0){}});retVal.MessagePump.on("message",function g(p){if(p.message==this.TrayIcon.Options.filter){var o=false;if(p.wparam==1&&p.lparam==1029){this.TrayIcon.emit("ToastClicked");o=true}if(p.wparam==1&&p.lparam==512){this.TrayIcon.emit("IconHover");o=true}if(this.TrayIcon.Options.balloonOnly&&p.wparam==1&&(p.lparam==1028||p.lparam==1029)){this.TrayIcon.emit("ToastDismissed");this.TrayIcon.remove();o=true}}});retVal.remove=function i(){this.MessagePump.WindowsConsole._shell32.Shell_NotifyIconA(TrayIconFlags.NIM_DELETE,this.MessagePump.NotifyData);this.MessagePump.stop();delete this.MessagePump.TrayIcon;delete this.MessagePump};return(retVal)}}}module.exports=new WindowsConsole(); \ No newline at end of file diff --git a/agents/modules_meshcore_min/win-terminal.min.js b/agents/modules_meshcore_min/win-terminal.min.js new file mode 100644 index 00000000..a954e934 --- /dev/null +++ b/agents/modules_meshcore_min/win-terminal.min.js @@ -0,0 +1 @@ +var promise=require("promise");var duplex=require("stream").Duplex;var SW_HIDE=0;var SW_MINIMIZE=6;var STARTF_USESHOWWINDOW=1;var STD_INPUT_HANDLE=-10;var STD_OUTPUT_HANDLE=-11;var EVENT_CONSOLE_CARET=16385;var EVENT_CONSOLE_END_APPLICATION=16391;var WINEVENT_OUTOFCONTEXT=0;var WINEVENT_SKIPOWNPROCESS=2;var CREATE_NEW_PROCESS_GROUP=512;var EVENT_CONSOLE_UPDATE_REGION=16386;var EVENT_CONSOLE_UPDATE_SIMPLE=16387;var EVENT_CONSOLE_UPDATE_SCROLL=16388;var EVENT_CONSOLE_LAYOUT=16389;var EVENT_CONSOLE_START_APPLICATION=16390;var KEY_EVENT=1;var MAPVK_VK_TO_VSC=0;var WM_QUIT=18;var GM=require("_GenericMarshal");var si=GM.CreateVariable(GM.PointerSize==4?68:104);var pi=GM.CreateVariable(GM.PointerSize==4?16:24);si.Deref(0,4).toBuffer().writeUInt32LE(GM.PointerSize==4?68:104);si.Deref(GM.PointerSize==4?48:64,2).toBuffer().writeUInt16LE(SW_HIDE|SW_MINIMIZE);si.Deref(GM.PointerSize==4?44:60,4).toBuffer().writeUInt32LE(STARTF_USESHOWWINDOW);var MSG=GM.CreateVariable(GM.PointerSize==4?28:48);function windows_terminal(){this._ObjectID="windows_terminal";this._user32=GM.CreateNativeProxy("User32.dll");this._user32.CreateMethod("DispatchMessageA");this._user32.CreateMethod("GetMessageA");this._user32.CreateMethod("MapVirtualKeyA");this._user32.CreateMethod("PostThreadMessageA");this._user32.CreateMethod("SetWinEventHook");this._user32.CreateMethod("ShowWindow");this._user32.CreateMethod("TranslateMessage");this._user32.CreateMethod("UnhookWinEvent");this._user32.CreateMethod("VkKeyScanA");this._user32.terminal=this;this._kernel32=GM.CreateNativeProxy("Kernel32.dll");this._kernel32.CreateMethod("AllocConsole");this._kernel32.CreateMethod("CreateProcessA");this._kernel32.CreateMethod("CloseHandle");this._kernel32.CreateMethod("FillConsoleOutputAttribute");this._kernel32.CreateMethod("FillConsoleOutputCharacterA");this._kernel32.CreateMethod("GetConsoleScreenBufferInfo");this._kernel32.CreateMethod("GetConsoleWindow");this._kernel32.CreateMethod("GetLastError");this._kernel32.CreateMethod("GetStdHandle");this._kernel32.CreateMethod("GetThreadId");this._kernel32.CreateMethod("ReadConsoleOutputA");this._kernel32.CreateMethod("SetConsoleCursorPosition");this._kernel32.CreateMethod("SetConsoleScreenBufferSize");this._kernel32.CreateMethod("SetConsoleWindowInfo");this._kernel32.CreateMethod("TerminateProcess");this._kernel32.CreateMethod("WaitForSingleObject");this._kernel32.CreateMethod("WriteConsoleInputA");var b=0;var c=0;this._scrx=0;this._scry=0;this.SendCursorUpdate=function(){var f=GM.CreateVariable(22);if(this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput,f).Val==0){return}if(f.Deref(4,2).toBuffer().readUInt16LE()!=this.currentX||f.Deref(6,2).toBuffer().readUInt16LE()!=this.currentY){this.currentX=f.Deref(4,2).toBuffer().readUInt16LE();this.currentY=f.Deref(6,2).toBuffer().readUInt16LE()}};this.ClearScreen=function(){var g=GM.CreateVariable(22);if(this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput,g).Val==0){return}var h=GM.CreateVariable(4);var i=g.Deref(0,2).toBuffer().readUInt16LE(0)*g.Deref(2,2).toBuffer().readUInt16LE(0);var f=GM.CreateVariable(4);if(this._kernel32.FillConsoleOutputCharacterA(this._stdoutput,32,i,h.Deref(0,4).toBuffer().readUInt32LE(),f).Val==0){return}if(this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput,g).Val==0){return}if(this._kernel32.FillConsoleOutputAttribute(this._stdoutput,g.Deref(8,2).toBuffer().readUInt16LE(0),i,h.Deref(0,4).toBuffer().readUInt32LE(),f).Val==0){return}this._kernel32.SetConsoleCursorPosition(this._stdoutput,h.Deref(0,4).toBuffer().readUInt32LE());var j=GM.CreateVariable(8);var k=g.Deref(10,8).toBuffer();j.Deref(4,2).toBuffer().writeUInt16LE(k.readUInt16LE(4)-k.readUInt16LE(0));j.Deref(6,2).toBuffer().writeUInt16LE(k.readUInt16LE(6)-k.readUInt16LE(2));this._kernel32.SetConsoleWindowInfo(this._stdoutput,1,j)};this.Start=function d(g,f){this.stopping=null;if(this._kernel32.GetConsoleWindow().Val==0){if(this._kernel32.AllocConsole().Val==0){throw ("AllocConsole failed with: "+this._kernel32.GetLastError().Val)}}this._stdinput=this._kernel32.GetStdHandle(STD_INPUT_HANDLE);this._stdoutput=this._kernel32.GetStdHandle(STD_OUTPUT_HANDLE);this._connected=false;var h=GM.CreateVariable(4);h.Deref(0,2).toBuffer().writeUInt16LE(g);h.Deref(2,2).toBuffer().writeUInt16LE(f);var i=GM.CreateVariable(8);i.Deref(4,2).toBuffer().writeUInt16LE(g-1);i.Deref(6,2).toBuffer().writeUInt16LE(f-1);if(this._kernel32.SetConsoleWindowInfo(this._stdoutput,1,i).Val==0){throw ("Failed to set Console Screen Size")}if(this._kernel32.SetConsoleScreenBufferSize(this._stdoutput,h.Deref(0,4).toBuffer().readUInt32LE()).Val==0){throw ("Failed to set Console Buffer Size")}this._user32.ShowWindow(this._kernel32.GetConsoleWindow().Val,SW_HIDE);this.ClearScreen();this._hookThread().then(function(){this.terminal.StartCommand()},console.log);this._stream=new duplex({write:function(j,k){if(!this.terminal.connected){if(!this._promise.chunk){this._promise.chunk=[]}if(typeof(j)=="string"){this._promise.chunk.push(j)}else{this._promise.chunk.push(Buffer.alloc(j.length));j.copy(this._promise.chunk.peek())}this._promise.chunk.peek().flush=k;this._promise.then(function(){var l;while(this.chunk.length>0){l=this.chunk.shift();this.terminal._WriteBuffer(l);l.flush()}})}else{this.terminal._WriteBuffer(j);k()}return(true)},"final":function(j){var k=this.terminal._stop();k.__flush=j;k.then(function(){this.__flush()})}});this._stream.terminal=this;this._stream._promise=new promise(function(k,j){this._res=k;this._rej=j});this._stream._promise.terminal=this;return(this._stream)};this._stop=function(){if(this.stopping){return(this.stopping)}this._ConsoleWinEventProc.removeAllListeners("GlobalCallback");this.stopping=new promise(function(h,g){this._res=h;this._rej=g});var f=this._kernel32.GetThreadId(this._user32.SetWinEventHook.async.thread()).Val;this._user32.PostThreadMessageA(f,WM_QUIT,0,0);this._stream.emit("end");return(this.stopping)};this._hookThread=function(){var g=new promise(function(i,h){this._res=i;this._rej=h});g.terminal=this;this._ConsoleWinEventProc=GM.GetGenericGlobalCallback(7);this._ConsoleWinEventProc.terminal=this;var f=this._user32.SetWinEventHook.async(EVENT_CONSOLE_CARET,EVENT_CONSOLE_END_APPLICATION,0,this._ConsoleWinEventProc,0,0,WINEVENT_OUTOFCONTEXT|WINEVENT_SKIPOWNPROCESS);f.ready=g;f.terminal=this;f.then(function(h){if(h.Val==0){this.ready._rej("Error calling SetWinEventHook")}else{this.terminal.hwinEventHook=h;this.ready._res();this.terminal._GetMessage()}});this._ConsoleWinEventProc.on("GlobalCallback",function(j,i,k,n,l,m,p){if(!this.terminal.hwinEventHook||this.terminal.hwinEventHook.Val!=j.Val){return}var h=null;switch(i.Val){case EVENT_CONSOLE_CARET:break;case EVENT_CONSOLE_UPDATE_REGION:if(!this.terminal.connected){this.terminal.connected=true;this.terminal._stream._promise._res()}if(this.terminal._scrollTimer==null){h=this.terminal._GetScreenBuffer(LOWORD(n.Val),HIWORD(n.Val),LOWORD(l.Val),HIWORD(l.Val));this.terminal._SendDataBuffer(h)}break;case EVENT_CONSOLE_UPDATE_SIMPLE:var o={data:[Buffer.alloc(1,LOWORD(l.Val))],attributes:[HIWORD(l.Val)],width:1,height:1,x:LOWORD(n.Val),y:HIWORD(n.Val)};this.terminal._SendDataBuffer(o);break;case EVENT_CONSOLE_UPDATE_SCROLL:this.terminal._SendScroll(n.Val,l.Val);break;case EVENT_CONSOLE_LAYOUT:break;case EVENT_CONSOLE_START_APPLICATION:break;case EVENT_CONSOLE_END_APPLICATION:if(n.Val==this.terminal._hProcessID){this.terminal._hProcess=null;this.terminal._stop().then(function(){console.log("STOPPED")})}break;default:console.log("Unknown event: "+i.Val);break}});return(g)};this._GetMessage=function(){if(this._user32.abort){console.log("aborting loop");return}this._user32.GetMessageA.async(this._user32.SetWinEventHook.async,MSG,0,0,0).then(function(f){if(f.Val!=0){if(f.Val==-1){}else{this.nativeProxy._user32.TranslateMessage.async(this.nativeProxy.user32.SetWinEventHook.async,MSG).then(function(){this.nativeProxy._user32.DispatchMessageA.async(this.nativeProxy.user32.SetWinEventHook.async,MSG).then(function(){this.nativeProxy.terminal._GetMessage()},console.log)},console.log)}}else{this.nativeProxy.UnhookWinEvent.async(this.nativeProxy.terminal._user32.SetWinEventHook.async,this.nativeProxy.terminal.hwinEventHook).then(function(){if(this.nativeProxy.terminal._hProcess==null){return}this.nativeProxy.terminal.stopping._res();if(this.nativeProxy.terminal._kernel32.TerminateProcess(this.nativeProxy.terminal._hProcess,1067).Val==0){var g=this.nativeProxy.terminal._kernel32.GetLastError().Val;console.log("Unable to kill Terminal Process, error: "+g)}this.nativeProxy.terminal.stopping=null},function(g){console.log("REJECTED_UnhookWinEvent: "+g)})}},function(f){console.log("REJECTED_GETMessage: "+f)})};this._WriteBuffer=function(f){for(var g=0;gl;++j){this._stream.push(Buffer.from("\r\n"))}var f=this._GetScreenBuffer(0,0,m-1,l-1);this._SendDataBuffer(f);this._scrollTimer=setTimeout(function(p,o,n){var i=p._GetScreenBuffer(0,0,o-1,n-1);p._SendDataBuffer(i);p._scrollTimer=null},250,this,m,l)};this.StartCommand=function e(){if(this._kernel32.CreateProcessA(GM.CreateVariable(process.env.windir+"\\system32\\cmd.exe"),0,0,0,1,CREATE_NEW_PROCESS_GROUP,0,0,si,pi).Val==0){console.log("Error Spawning CMD");return}this._kernel32.CloseHandle(pi.Deref(GM.PointerSize,GM.PointerSize).Deref());this._hProcess=pi.Deref(0,GM.PointerSize).Deref();this._hProcessID=pi.Deref(GM.PointerSize==4?8:16,4).toBuffer().readUInt32LE()}}function LOWORD(a){return(a&65535)}function HIWORD(a){return((a>>16)&65535)}function GetEsc(b,a){return(Buffer.from("\x1B["+a.join(";")+b))}function MeshConsole(a){require("MeshAgent").SendCommand({action:"msg",type:"console",value:JSON.stringify(a)})}function TranslateLine(r,s,f,a){var m,l,e,q,j,c,n,k,d,p,h,b,g=[],o=[GetEsc("H",[s,r])];if(typeof a=="number"){a=[a]}for(m=0;m>2);d=(a[m]&112)>>4;d=((d&1)<<2)+(d&2)+((d&4)>>2);p=(a[m]&16384);h=(a[m]&8)>>3;b=(a[m]&128);if(p!=q){if(p!=0){g.push(7)}else{g.push(0);l=7;e=0;j=0;c=0}q=p}if(k!=l){g.push(k+30);l=k}if(d!=e){g.push(d+40);e=d}if(h!=j){g.push(2-h);j=h}if(b!=c){if(b==0){g.push(e+40)}else{g.push(e+100);c=b}}if(g.length>0){o.push(GetEsc("m",g));g=[]}n=a[m]}o.push(Buffer.from(String.fromCharCode(f[m])))}return Buffer.concat(o)}module.exports=new windows_terminal(); \ No newline at end of file diff --git a/views/default-min.handlebars b/views/default-min.handlebars index 5e2ea3bb..df77e03c 100644 --- a/views/default-min.handlebars +++ b/views/default-min.handlebars @@ -7350,6 +7350,7 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this } function onMessage(server, message) { + if (args.trace == 1) { console.log('MSG:', message); } switch (message.action) { case 'serverstats': { updateGeneralServerStats(message);